Fossil

Check-in [79bae86356]
Login

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

Overview
Comment:merge trunk
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | cleanX-no-clean-glob
Files: files | file ages | folders
SHA1: 79bae8635646a5e42ccc5bb2f21ccd28f216c165
User & Date: jan.nijtmans 2013-09-04 19:17:27.785
Context
2013-10-01
09:21
merge trunk check-in: 5724c62cf6 user: jan.nijtmans tags: cleanX-no-clean-glob
2013-09-04
19:17
merge trunk check-in: 79bae86356 user: jan.nijtmans tags: cleanX-no-clean-glob
18:43
New --close option to "fossil [/help?cmd=commit|commit]", which immediately closes the branch being committed. check-in: abf727105d user: jan.nijtmans tags: trunk
2013-07-21
16:29
rebase check-in: 54aef59916 user: jan.nijtmans tags: cleanX-no-clean-glob
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/add.c.
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
  capture_case_sensitive_option();
  db_must_be_within_tree();
  if( zIgnoreFlag==0 ){
    zIgnoreFlag = db_get("ignore-glob", 0);
  }
  vid = db_lget_int("checkout",0);
  if( vid==0 ){
    fossil_panic("no checkout to add to");
  }
  db_begin_transaction();
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
                filename_collation());
  pIgnore = glob_create(zIgnoreFlag);
  nRoot = strlen(g.zLocalRoot);
  







|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
  capture_case_sensitive_option();
  db_must_be_within_tree();
  if( zIgnoreFlag==0 ){
    zIgnoreFlag = db_get("ignore-glob", 0);
  }
  vid = db_lget_int("checkout",0);
  if( vid==0 ){
    fossil_fatal("no checkout to add to");
  }
  db_begin_transaction();
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
                filename_collation());
  pIgnore = glob_create(zIgnoreFlag);
  nRoot = strlen(g.zLocalRoot);
  
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  int vid;
  Stmt loop;

  capture_case_sensitive_option();
  db_must_be_within_tree();
  vid = db_lget_int("checkout", 0);
  if( vid==0 ){
    fossil_panic("no checkout to remove from");
  }
  db_begin_transaction();
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
                filename_collation());
  for(i=2; i<g.argc; i++){
    Blob treeName;
    char *zTreeName;







|







319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  int vid;
  Stmt loop;

  capture_case_sensitive_option();
  db_must_be_within_tree();
  vid = db_lget_int("checkout", 0);
  if( vid==0 ){
    fossil_fatal("no checkout to remove from");
  }
  db_begin_transaction();
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
                filename_collation());
  for(i=2; i<g.argc; i++){
    Blob treeName;
    char *zTreeName;
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
  capture_case_sensitive_option();
  db_must_be_within_tree();
  if( zIgnoreFlag==0 ){
    zIgnoreFlag = db_get("ignore-glob", 0);
  }
  vid = db_lget_int("checkout",0);
  if( vid==0 ){
    fossil_panic("no checkout to add to");
  }
  db_begin_transaction();

  /* step 1:  
  ** Populate the temp table "sfile" with the names of all unmanaged
  ** files currently in the check-out, except for files that match the
  ** --ignore or ignore-glob patterns and dot-files.  Then add all of







|







487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
  capture_case_sensitive_option();
  db_must_be_within_tree();
  if( zIgnoreFlag==0 ){
    zIgnoreFlag = db_get("ignore-glob", 0);
  }
  vid = db_lget_int("checkout",0);
  if( vid==0 ){
    fossil_fatal("no checkout to add to");
  }
  db_begin_transaction();

  /* step 1:  
  ** Populate the temp table "sfile" with the names of all unmanaged
  ** files currently in the check-out, except for files that match the
  ** --ignore or ignore-glob patterns and dot-files.  Then add all of
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
  Blob dest;
  Stmt q;

  capture_case_sensitive_option();
  db_must_be_within_tree();
  vid = db_lget_int("checkout", 0);
  if( vid==0 ){
    fossil_panic("no checkout rename files in");
  }
  if( g.argc<4 ){
    usage("OLDNAME NEWNAME");
  }
  zDest = g.argv[g.argc-1];
  db_begin_transaction();
  file_tree_name(zDest, &dest, 1);







|







590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
  Blob dest;
  Stmt q;

  capture_case_sensitive_option();
  db_must_be_within_tree();
  vid = db_lget_int("checkout", 0);
  if( vid==0 ){
    fossil_fatal("no checkout rename files in");
  }
  if( g.argc<4 ){
    usage("OLDNAME NEWNAME");
  }
  zDest = g.argv[g.argc-1];
  db_begin_transaction();
  file_tree_name(zDest, &dest, 1);
Changes to src/allrepo.c.
151
152
153
154
155
156
157

158
159
160
161
162
163
164
    collect_argument(&extra, "analyze",0);
    collect_argument(&extra, "wal",0);
    collect_argument(&extra, "stats",0);
  }else if( strncmp(zCmd, "sync", n)==0 ){
    zCmd = "sync -autourl -R";
    collect_argument(&extra, "verbose","v");
  }else if( strncmp(zCmd, "test-integrity", n)==0 ){

    zCmd = "test-integrity";
  }else if( strncmp(zCmd, "test-orphans", n)==0 ){
    zCmd = "test-orphans -R";
  }else if( strncmp(zCmd, "test-missing", n)==0 ){
    zCmd = "test-missing -q -R";
    collect_argument(&extra, "notshunned",0);
  }else if( strncmp(zCmd, "changes", n)==0 ){







>







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
    collect_argument(&extra, "analyze",0);
    collect_argument(&extra, "wal",0);
    collect_argument(&extra, "stats",0);
  }else if( strncmp(zCmd, "sync", n)==0 ){
    zCmd = "sync -autourl -R";
    collect_argument(&extra, "verbose","v");
  }else if( strncmp(zCmd, "test-integrity", n)==0 ){
    collect_argument(&extra, "parse", 0);
    zCmd = "test-integrity";
  }else if( strncmp(zCmd, "test-orphans", n)==0 ){
    zCmd = "test-orphans -R";
  }else if( strncmp(zCmd, "test-missing", n)==0 ){
    zCmd = "test-missing -q -R";
    collect_argument(&extra, "notshunned",0);
  }else if( strncmp(zCmd, "changes", n)==0 ){
Changes to src/attach.c.
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
    blob_appendf(&manifest, "A %F%s %F %s\n",
                 zName, addCompress ? ".gz" : "", zTarget, zUUID);
    zComment = PD("comment", "");
    while( fossil_isspace(zComment[0]) ) zComment++;
    n = strlen(zComment);
    while( n>0 && fossil_isspace(zComment[n-1]) ){ n--; }
    if( n>0 ){
      blob_appendf(&manifest, "C %F\n", zComment);
    }
    zDate = date_in_standard_format("now");
    blob_appendf(&manifest, "D %s\n", zDate);
    blob_appendf(&manifest, "U %F\n", g.zLogin ? g.zLogin : "nobody");
    md5sum_blob(&manifest, &cksum);
    blob_appendf(&manifest, "Z %b\n", &cksum);
    attach_put(&manifest, rid, needModerator);







|







303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
    blob_appendf(&manifest, "A %F%s %F %s\n",
                 zName, addCompress ? ".gz" : "", zTarget, zUUID);
    zComment = PD("comment", "");
    while( fossil_isspace(zComment[0]) ) zComment++;
    n = strlen(zComment);
    while( n>0 && fossil_isspace(zComment[n-1]) ){ n--; }
    if( n>0 ){
      blob_appendf(&manifest, "C %#F\n", n, zComment);
    }
    zDate = date_in_standard_format("now");
    blob_appendf(&manifest, "D %s\n", zDate);
    blob_appendf(&manifest, "U %F\n", g.zLogin ? g.zLogin : "nobody");
    md5sum_blob(&manifest, &cksum);
    blob_appendf(&manifest, "Z %b\n", &cksum);
    attach_put(&manifest, rid, needModerator);
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
  }else{
    @ <input type="hidden" name="page" value="%h(zPage)" />
  }
  @ <input type="hidden" name="from" value="%h(zFrom)" />
  @ <input type="submit" name="ok" value="Add Attachment" />
  @ <input type="submit" name="cancel" value="Cancel" />
  @ </div>
  captcha_generate();
  @ </form>
  style_footer();
}

/*
** WEBPAGE: ainfo
** URL: /ainfo?name=ARTIFACTID







|







335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
  }else{
    @ <input type="hidden" name="page" value="%h(zPage)" />
  }
  @ <input type="hidden" name="from" value="%h(zFrom)" />
  @ <input type="submit" name="ok" value="Add Attachment" />
  @ <input type="submit" name="cancel" value="Cancel" />
  @ </div>
  captcha_generate(0);
  @ </form>
  style_footer();
}

/*
** WEBPAGE: ainfo
** URL: /ainfo?name=ARTIFACTID
Changes to src/blob.c.
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733

/*
** Initialize a blob to be the content of a file.  If the filename
** is blank or "-" then read from standard input.
**
** Any prior content of the blob is discarded, not freed.
**
** Return the number of bytes read. Calls fossil_panic() error (i.e.
** it exit()s and does not return).
*/
int blob_read_from_file(Blob *pBlob, const char *zFilename){
  int size, got;
  FILE *in;
  if( zFilename==0 || zFilename[0]==0
        || (zFilename[0]=='-' && zFilename[1]==0) ){
    return blob_read_from_channel(pBlob, stdin, -1);
  }
  size = file_wd_size(zFilename);
  blob_zero(pBlob);
  if( size<0 ){
    fossil_fatal("no such file: %s", zFilename);
  }
  if( size==0 ){
    return 0;
  }
  blob_resize(pBlob, size);
  in = fossil_fopen(zFilename, "rb");
  if( in==0 ){
    fossil_panic("cannot open %s for reading", zFilename);
  }
  got = fread(blob_buffer(pBlob), 1, size, in);
  fclose(in);
  if( got<size ){
    blob_resize(pBlob, got);
  }
  return got;







|




















|







698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733

/*
** Initialize a blob to be the content of a file.  If the filename
** is blank or "-" then read from standard input.
**
** Any prior content of the blob is discarded, not freed.
**
** Return the number of bytes read. Calls fossil_fatal() error (i.e.
** it exit()s and does not return).
*/
int blob_read_from_file(Blob *pBlob, const char *zFilename){
  int size, got;
  FILE *in;
  if( zFilename==0 || zFilename[0]==0
        || (zFilename[0]=='-' && zFilename[1]==0) ){
    return blob_read_from_channel(pBlob, stdin, -1);
  }
  size = file_wd_size(zFilename);
  blob_zero(pBlob);
  if( size<0 ){
    fossil_fatal("no such file: %s", zFilename);
  }
  if( size==0 ){
    return 0;
  }
  blob_resize(pBlob, size);
  in = fossil_fopen(zFilename, "rb");
  if( in==0 ){
    fossil_fatal("cannot open %s for reading", zFilename);
  }
  got = fread(blob_buffer(pBlob), 1, size, in);
  fclose(in);
  if( got<size ){
    blob_resize(pBlob, got);
  }
  return got;
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
** On windows, zeros blob and returns 0.
*/
int blob_read_link(Blob *pBlob, const char *zFilename){
#if !defined(_WIN32)
  char zBuf[1024];
  ssize_t len = readlink(zFilename, zBuf, 1023);
  if( len < 0 ){
    fossil_panic("cannot read symbolic link %s", zFilename);
  }
  zBuf[len] = 0;   /* null-terminate */
  blob_zero(pBlob);
  blob_appendf(pBlob, "%s", zBuf);
  return len;
#else
  blob_zero(pBlob);







|







742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
** On windows, zeros blob and returns 0.
*/
int blob_read_link(Blob *pBlob, const char *zFilename){
#if !defined(_WIN32)
  char zBuf[1024];
  ssize_t len = readlink(zFilename, zBuf, 1023);
  if( len < 0 ){
    fossil_fatal("cannot read symbolic link %s", zFilename);
  }
  zBuf[len] = 0;   /* null-terminate */
  blob_zero(pBlob);
  blob_appendf(pBlob, "%s", zBuf);
  return len;
#else
  blob_zero(pBlob);
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
**
** If the filename is blank or "-" then write to standard output.
**
** Return the number of bytes written.
*/
int blob_write_to_file(Blob *pBlob, const char *zFilename){
  FILE *out;
  int wrote;

  if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){
    int n = blob_size(pBlob);
#if defined(_WIN32)
    if( fossil_utf8_to_console(blob_buffer(pBlob), n, 0) >= 0 ){
      return n;
    }
#endif
    fwrite(blob_buffer(pBlob), 1, n, stdout);
    return n;
  }else{
    int i, nName;
    char *zName, zBuf[1000];

    nName = strlen(zFilename);
    if( nName>=sizeof(zBuf) ){
      zName = mprintf("%s", zFilename);







|


|

|
|


|
<







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780

781
782
783
784
785
786
787
**
** If the filename is blank or "-" then write to standard output.
**
** Return the number of bytes written.
*/
int blob_write_to_file(Blob *pBlob, const char *zFilename){
  FILE *out;
  int nWrote;

  if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){
    nWrote = blob_size(pBlob);
#if defined(_WIN32)
    if( fossil_utf8_to_console(blob_buffer(pBlob), nWrote, 0) >= 0 ){
      return nWrote;
    }
#endif
    fwrite(blob_buffer(pBlob), 1, nWrote, stdout);

  }else{
    int i, nName;
    char *zName, zBuf[1000];

    nName = strlen(zFilename);
    if( nName>=sizeof(zBuf) ){
      zName = mprintf("%s", zFilename);
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836
    }
    out = fossil_fopen(zName, "wb");
    if( out==0 ){
      fossil_fatal_recursive("unable to open file \"%s\" for writing", zName);
      return 0;
    }
    if( zName!=zBuf ) free(zName);
  }
  blob_is_init(pBlob);
  wrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out);
  fclose(out);
  if( wrote!=blob_size(pBlob) && out!=stdout ){
    fossil_fatal_recursive("short write: %d of %d bytes to %s", wrote,
       blob_size(pBlob), zFilename);
  }

  return wrote;
}

/*
** Compress a blob pIn.  Store the result in pOut.  It is ok for pIn and
** pOut to be the same blob.
**
** pOut must either be the same as pIn or else uninitialized.







<
|
|
|
|
|
|
|
>
|







813
814
815
816
817
818
819

820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
    }
    out = fossil_fopen(zName, "wb");
    if( out==0 ){
      fossil_fatal_recursive("unable to open file \"%s\" for writing", zName);
      return 0;
    }
    if( zName!=zBuf ) free(zName);

    blob_is_init(pBlob);
    nWrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out);
    fclose(out);
    if( nWrote!=blob_size(pBlob) ){
      fossil_fatal_recursive("short write: %d of %d bytes to %s", nWrote,
         blob_size(pBlob), zFilename);
    }
  }
  return nWrote;
}

/*
** Compress a blob pIn.  Store the result in pOut.  It is ok for pIn and
** pOut to be the same blob.
**
** pOut must either be the same as pIn or else uninitialized.
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
  int i;
  Blob b1, b2, b3;
  for(i=2; i<g.argc; i++){
    blob_read_from_file(&b1, g.argv[i]);
    blob_compress(&b1, &b2);
    blob_uncompress(&b2, &b3);
    if( blob_compare(&b1, &b3) ){
      fossil_panic("compress/uncompress cycle failed for %s", g.argv[i]);
    }
    blob_reset(&b1);
    blob_reset(&b2);
    blob_reset(&b3);
  }
  fossil_print("ok\n");
}

#if defined(_WIN32)
/*
** Convert every \n character in the given blob into \r\n.
*/
void blob_add_cr(Blob *p){
  char *z = p->aData;
  int j   = p->nUsed;
  int i, n;







|








|







975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
  int i;
  Blob b1, b2, b3;
  for(i=2; i<g.argc; i++){
    blob_read_from_file(&b1, g.argv[i]);
    blob_compress(&b1, &b2);
    blob_uncompress(&b2, &b3);
    if( blob_compare(&b1, &b3) ){
      fossil_fatal("compress/uncompress cycle failed for %s", g.argv[i]);
    }
    blob_reset(&b1);
    blob_reset(&b2);
    blob_reset(&b3);
  }
  fossil_print("ok\n");
}

#if defined(_WIN32) || defined(__CYGWIN__)
/*
** Convert every \n character in the given blob into \r\n.
*/
void blob_add_cr(Blob *p){
  char *z = p->aData;
  int j   = p->nUsed;
  int i, n;
Changes to src/branch.c.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  }
  db_find_and_open_repository(0, 0);
  noSign = db_get_int("omitsign", 0)|noSign;

  /* fossil branch new name */
  zBranch = g.argv[3];
  if( zBranch==0 || zBranch[0]==0 ){
    fossil_panic("branch name cannot be empty");
  }
  if( db_exists(
        "SELECT 1 FROM tagxref"
        " WHERE tagtype>0"
        "   AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%q')",
        zBranch)!=0 ){
    fossil_fatal("branch \"%s\" already exists", zBranch);







|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  }
  db_find_and_open_repository(0, 0);
  noSign = db_get_int("omitsign", 0)|noSign;

  /* fossil branch new name */
  zBranch = g.argv[3];
  if( zBranch==0 || zBranch[0]==0 ){
    fossil_fatal("branch name cannot be empty");
  }
  if( db_exists(
        "SELECT 1 FROM tagxref"
        " WHERE tagtype>0"
        "   AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%q')",
        zBranch)!=0 ){
    fossil_fatal("branch \"%s\" already exists", zBranch);
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
      db_end_transaction(1);
      fossil_exit(1);
    }
  }

  brid = content_put_ex(&branch, 0, 0, 0, isPrivate);
  if( brid==0 ){
    fossil_panic("trouble committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
  if( manifest_crosslink(brid, &branch)==0 ){
    fossil_panic("unable to install new manifest");
  }
  assert( blob_is_reset(&branch) );
  content_deltify(rootid, brid, 0);
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
  fossil_print("New branch: %s\n", zUuid);
  if( g.argc==3 ){
    fossil_print(







|



|







148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
      db_end_transaction(1);
      fossil_exit(1);
    }
  }

  brid = content_put_ex(&branch, 0, 0, 0, isPrivate);
  if( brid==0 ){
    fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
  if( manifest_crosslink(brid, &branch)==0 ){
    fossil_fatal("unable to install new manifest");
  }
  assert( blob_is_reset(&branch) );
  content_deltify(rootid, brid, 0);
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
  fossil_print("New branch: %s\n", zUuid);
  if( g.argc==3 ){
    fossil_print(
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
    while( db_step(&q)==SQLITE_ROW ){
      const char *zBr = db_column_text(&q, 0);
      int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0;
      fossil_print("%s%s\n", (isCur ? "* " : "  "), zBr);
    }
    db_finalize(&q);
  }else{
    fossil_panic("branch subcommand should be one of: "
                 "new list ls");
  }
}

/*
** WEBPAGE: brlist
**







|







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
    while( db_step(&q)==SQLITE_ROW ){
      const char *zBr = db_column_text(&q, 0);
      int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0;
      fossil_print("%s%s\n", (isCur ? "* " : "  "), zBr);
    }
    db_finalize(&q);
  }else{
    fossil_fatal("branch subcommand should be one of: "
                 "new list ls");
  }
}

/*
** WEBPAGE: brlist
**
Changes to src/captcha.c.
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

/*
** Render an 8-character hexadecimal string as ascii art.
** Space to hold the result is obtained from malloc() and should be freed
** by the caller.
*/
char *captcha_render(const char *zPw){
  char *z = fossil_malloc( 500 );
  int i, j, k, m;

  k = 0;
  for(i=0; i<6; i++){
    for(j=0; j<8; j++){
      unsigned char v = hexValue(zPw[j]);
      v = (aFont1[v] >> ((5-i)*4)) & 0xf;
      for(m=8; m>=1; m = m>>1){
        if( v & m ){
          z[k++] = 'X';
          z[k++] = 'X';
        }else{







|




|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

/*
** Render an 8-character hexadecimal string as ascii art.
** Space to hold the result is obtained from malloc() and should be freed
** by the caller.
*/
char *captcha_render(const char *zPw){
  char *z = fossil_malloc( 9*6*strlen(zPw) + 7 );
  int i, j, k, m;

  k = 0;
  for(i=0; i<6; i++){
    for(j=0; zPw[j]; j++){
      unsigned char v = hexValue(zPw[j]);
      v = (aFont1[v] >> ((5-i)*4)) & 0xf;
      for(m=8; m>=1; m = m>>1){
        if( v & m ){
          z[k++] = 'X';
          z[k++] = 'X';
        }else{
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

/*
** Render an 8-digit hexadecimal string as ascii arg.
** Space to hold the result is obtained from malloc() and should be freed
** by the caller.
*/
char *captcha_render(const char *zPw){
  char *z = fossil_malloc( 300 );
  int i, j, k, m;
  const char *zChar;

  k = 0;
  for(i=0; i<4; i++){
    for(j=0; j<8; j++){
      unsigned char v = hexValue(zPw[j]);
      zChar = azFont2[4*v + i];
      for(m=0; zChar[m]; m++){
        z[k++] = zChar[m];
      }
    }
    z[k++] = '\n';







|





|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

/*
** Render an 8-digit hexadecimal string as ascii arg.
** Space to hold the result is obtained from malloc() and should be freed
** by the caller.
*/
char *captcha_render(const char *zPw){
  char *z = fossil_malloc( 7*4*strlen(zPw) + 5 );
  int i, j, k, m;
  const char *zChar;

  k = 0;
  for(i=0; i<4; i++){
    for(j=0; zPw[j]; j++){
      unsigned char v = hexValue(zPw[j]);
      zChar = azFont2[4*v + i];
      for(m=0; zChar[m]; m++){
        z[k++] = zChar[m];
      }
    }
    z[k++] = '\n';
357
358
359
360
361
362
363
364
365
366


367
368
369

370
371




























372


373
374
375
376
377
378
379

/*
** Render an 8-digit hexadecimal string as ascii arg.
** Space to hold the result is obtained from malloc() and should be freed
** by the caller.
*/
char *captcha_render(const char *zPw){
  char *z = fossil_malloc( 600 );
  int i, j, k, m;
  const char *zChar;



  k = 0;
  for(i=0; i<6; i++){

    for(j=0; j<8; j++){
      unsigned char v = hexValue(zPw[j]);




























      zChar = azFont3[6*v + i];


      for(m=0; zChar[m]; m++){
        z[k++] = zChar[m];
      }
    }
    z[k++] = '\n';
  }
  z[k] = 0;







|


>
>



>
|

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

>
>







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

/*
** Render an 8-digit hexadecimal string as ascii arg.
** Space to hold the result is obtained from malloc() and should be freed
** by the caller.
*/
char *captcha_render(const char *zPw){
  char *z = fossil_malloc( 10*6*strlen(zPw) + 7 );
  int i, j, k, m;
  const char *zChar;
  unsigned char x;
  int y;

  k = 0;
  for(i=0; i<6; i++){
    x = 0;
    for(j=0; zPw[j]; j++){
      unsigned char v = hexValue(zPw[j]);
      x = (x<<4) + v;
      switch( x ){
        case 0x7a:
        case 0xfa:
          y = 3;
          break;
        case 0x47:
          y = 2;
          break;
        case 0xf6:
        case 0xa9:
        case 0xa4:
        case 0xa1:
        case 0x9a:
        case 0x76:
        case 0x61:
        case 0x67:
        case 0x69:
        case 0x41:
        case 0x42:
        case 0x43:
        case 0x4a:
          y = 1;
          break;
        default:
          y = 0;
          break;
      }
      zChar = azFont3[6*v + i];
      while( y && zChar[0]==' ' ){ y--; zChar++; }
      while( y && z[k-1]==' ' ){ y--; k--; }
      for(m=0; zChar[m]; m++){
        z[k++] = zChar[m];
      }
    }
    z[k++] = '\n';
  }
  z[k] = 0;
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515



516
517























































/*
** Generate a captcha display together with the necessary hidden parameter
** for the seed and the entry box into which the user will type the text of
** the captcha.  This is typically done at the very bottom of a form.
**
** This routine is a no-op if no captcha is required.
*/
void captcha_generate(void){
  unsigned int uSeed;
  const char *zDecoded;
  char *zCaptcha;

  if( !captcha_needed() ) return;
  uSeed = captcha_seed();
  zDecoded = captcha_decode(uSeed);
  zCaptcha = captcha_render(zDecoded);
  @ <div class="captcha"><table class="captcha"><tr><td><pre>
  @ %h(zCaptcha)
  @ </pre>
  @ Enter security code shown above:
  @ <input type="hidden" name="captchaseed" value="%u(uSeed)" />
  @ <input type="text" name="captcha" size=8 />



  @ </td></tr></table></div>
}






























































|














>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
/*
** Generate a captcha display together with the necessary hidden parameter
** for the seed and the entry box into which the user will type the text of
** the captcha.  This is typically done at the very bottom of a form.
**
** This routine is a no-op if no captcha is required.
*/
void captcha_generate(int showButton){
  unsigned int uSeed;
  const char *zDecoded;
  char *zCaptcha;

  if( !captcha_needed() ) return;
  uSeed = captcha_seed();
  zDecoded = captcha_decode(uSeed);
  zCaptcha = captcha_render(zDecoded);
  @ <div class="captcha"><table class="captcha"><tr><td><pre>
  @ %h(zCaptcha)
  @ </pre>
  @ Enter security code shown above:
  @ <input type="hidden" name="captchaseed" value="%u(uSeed)" />
  @ <input type="text" name="captcha" size=8 />
  if( showButton ){
    @ <input type="submit" value="Submit">
  }
  @ </td></tr></table></div>
}

/*
** WEBPAGE: test-captcha
*/
void captcha_test(void){
  const char *zPw = P("name");
  if( zPw==0 || zPw[0]==0 ){
    u64 x;
    sqlite3_randomness(sizeof(x), &x);
    zPw = mprintf("%016llx", x);
  }
  style_header("Captcha Test");
  @ <pre>
  @ %s(captcha_render(zPw))
  @ </pre>
  style_footer();
}

/*
** Check to see if the current request is coming from an agent that might
** be a spider.  If the agent is not a spider, then return 0 without doing
** anything.  But if the user agent appears to be a spider, offer
** a captcha challenge to allow the user agent to prove that it is human
** and return non-zero.
*/
int exclude_spiders(const char *zPage){
  const char *zCookieValue;
  char *zCookieName;
  if( g.isHuman ) return 0;
#if 0
  {
    const char *zReferer = P("HTTP_REFERER");
    if( zReferer && strncmp(g.zBaseURL, zReferer, strlen(g.zBaseURL))==0 ){
      return 0;
    }
  }
#endif
  zCookieName = mprintf("fossil-cc-%.10s", db_get("project-code","x"));
  zCookieValue = P(zCookieName);
  if( zCookieValue && atoi(zCookieValue)==1 ) return 0;
  if( captcha_is_correct() ){
    cgi_set_cookie(zCookieName, "1", login_cookie_path(), 8*3600);
    return 0;
  }

  /* This appears to be a spider.  Offer the captcha */
  style_header("Verification");
  form_begin(0, "%s", zPage);
  cgi_query_parameters_to_hidden();
  @ <p>Please demonstrate that you are human, not a spider or robot</p>
  captcha_generate(1);
  @ </form>
  style_footer();
  return 1;
}
Changes to src/cgi.c.
402
403
404
405
406
407
408

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
static int nUsedQP = 0;  /* Space actually used in aParamQP[] */
static int sortQP = 0;   /* True if aParamQP[] needs sorting */
static int seqQP = 0;    /* Sequence numbers */
static struct QParam {   /* One entry for each query parameter or cookie */
  const char *zName;        /* Parameter or cookie name */
  const char *zValue;       /* Value of the query parameter or cookie */
  int seq;                  /* Order of insertion */

} *aParamQP;             /* An array of all parameters and cookies */

/*
** Add another query parameter or cookie to the parameter set.
** zName is the name of the query parameter or cookie and zValue
** is its fully decoded value.
**
** zName and zValue are not copied and must not change or be
** deallocated after this routine returns.
*/
void cgi_set_parameter_nocopy(const char *zName, const char *zValue){
  if( nAllocQP<=nUsedQP ){
    nAllocQP = nAllocQP*2 + 10;
    if( nAllocQP>1000 ){
      /* Prevent a DOS service attack against the framework */
      fossil_fatal("Too many query parameters");
    }
    aParamQP = fossil_realloc( aParamQP, nAllocQP*sizeof(aParamQP[0]) );
  }
  aParamQP[nUsedQP].zName = zName;
  aParamQP[nUsedQP].zValue = zValue;
  if( g.fHttpTrace ){
    fprintf(stderr, "# cgi: %s = [%s]\n", zName, zValue);
  }
  aParamQP[nUsedQP].seq = seqQP++;

  nUsedQP++;
  sortQP = 1;
}

/*
** Add another query parameter or cookie to the parameter set.
** zName is the name of the query parameter or cookie and zValue
** is its fully decoded value.
**
** Copies are made of both the zName and zValue parameters.
*/
void cgi_set_parameter(const char *zName, const char *zValue){
  cgi_set_parameter_nocopy(mprintf("%s",zName), mprintf("%s",zValue));
}

/*
** Replace a parameter with a new value.
*/
void cgi_replace_parameter(const char *zName, const char *zValue){
  int i;
  for(i=0; i<nUsedQP; i++){
    if( fossil_strcmp(aParamQP[i].zName,zName)==0 ){
      aParamQP[i].zValue = zValue;
      return;
    }
  }
  cgi_set_parameter_nocopy(zName, zValue);
}

/*
** Add a query parameter.  The zName portion is fixed but a copy
** must be made of zValue.
*/
void cgi_setenv(const char *zName, const char *zValue){
  cgi_set_parameter_nocopy(zName, mprintf("%s",zValue));
}
 

/*
** Add a list of query parameters or cookies to the parameter set.
**
** Each parameter is of the form NAME=VALUE.  Both the NAME and the







>










|














>












|













|







|







402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
static int nUsedQP = 0;  /* Space actually used in aParamQP[] */
static int sortQP = 0;   /* True if aParamQP[] needs sorting */
static int seqQP = 0;    /* Sequence numbers */
static struct QParam {   /* One entry for each query parameter or cookie */
  const char *zName;        /* Parameter or cookie name */
  const char *zValue;       /* Value of the query parameter or cookie */
  int seq;                  /* Order of insertion */
  int isQP;                 /* True for query parameters */
} *aParamQP;             /* An array of all parameters and cookies */

/*
** Add another query parameter or cookie to the parameter set.
** zName is the name of the query parameter or cookie and zValue
** is its fully decoded value.
**
** zName and zValue are not copied and must not change or be
** deallocated after this routine returns.
*/
void cgi_set_parameter_nocopy(const char *zName, const char *zValue, int isQP){
  if( nAllocQP<=nUsedQP ){
    nAllocQP = nAllocQP*2 + 10;
    if( nAllocQP>1000 ){
      /* Prevent a DOS service attack against the framework */
      fossil_fatal("Too many query parameters");
    }
    aParamQP = fossil_realloc( aParamQP, nAllocQP*sizeof(aParamQP[0]) );
  }
  aParamQP[nUsedQP].zName = zName;
  aParamQP[nUsedQP].zValue = zValue;
  if( g.fHttpTrace ){
    fprintf(stderr, "# cgi: %s = [%s]\n", zName, zValue);
  }
  aParamQP[nUsedQP].seq = seqQP++;
  aParamQP[nUsedQP].isQP = isQP;
  nUsedQP++;
  sortQP = 1;
}

/*
** Add another query parameter or cookie to the parameter set.
** zName is the name of the query parameter or cookie and zValue
** is its fully decoded value.
**
** Copies are made of both the zName and zValue parameters.
*/
void cgi_set_parameter(const char *zName, const char *zValue){
  cgi_set_parameter_nocopy(mprintf("%s",zName), mprintf("%s",zValue), 0);
}

/*
** Replace a parameter with a new value.
*/
void cgi_replace_parameter(const char *zName, const char *zValue){
  int i;
  for(i=0; i<nUsedQP; i++){
    if( fossil_strcmp(aParamQP[i].zName,zName)==0 ){
      aParamQP[i].zValue = zValue;
      return;
    }
  }
  cgi_set_parameter_nocopy(zName, zValue, 0);
}

/*
** Add a query parameter.  The zName portion is fixed but a copy
** must be made of zValue.
*/
void cgi_setenv(const char *zName, const char *zValue){
  cgi_set_parameter_nocopy(zName, mprintf("%s",zValue), 0);
}
 

/*
** Add a list of query parameters or cookies to the parameter set.
**
** Each parameter is of the form NAME=VALUE.  Both the NAME and the
491
492
493
494
495
496
497

498
499
500
501
502
503
504
** before the NAME is ignored.
**
** The input string "z" is modified but no copies is made.  "z"
** should not be deallocated or changed again after this routine
** returns or it will corrupt the parameter table.
*/
static void add_param_list(char *z, int terminator){

  while( *z ){
    char *zName;
    char *zValue;
    while( fossil_isspace(*z) ){ z++; }
    zName = z;
    while( *z && *z!='=' && *z!=terminator ){ z++; }
    if( *z=='=' ){







>







493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
** before the NAME is ignored.
**
** The input string "z" is modified but no copies is made.  "z"
** should not be deallocated or changed again after this routine
** returns or it will corrupt the parameter table.
*/
static void add_param_list(char *z, int terminator){
  int isQP = terminator=='&';
  while( *z ){
    char *zName;
    char *zValue;
    while( fossil_isspace(*z) ){ z++; }
    zName = z;
    while( *z && *z!='=' && *z!=terminator ){ z++; }
    if( *z=='=' ){
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
      }
      dehttpize(zValue);
    }else{
      if( *z ){ *z++ = 0; }
      zValue = "";
    }
    if( fossil_islower(zName[0]) ){
      cgi_set_parameter_nocopy(zName, zValue);
    }
#ifdef FOSSIL_ENABLE_JSON
    json_setenv( zName, cson_value_new_string(zValue,strlen(zValue)) );
#endif /* FOSSIL_ENABLE_JSON */
  }
}








|







515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
      }
      dehttpize(zValue);
    }else{
      if( *z ){ *z++ = 0; }
      zValue = "";
    }
    if( fossil_islower(zName[0]) ){
      cgi_set_parameter_nocopy(zName, zValue, isQP);
    }
#ifdef FOSSIL_ENABLE_JSON
    json_setenv( zName, cson_value_new_string(zValue,strlen(zValue)) );
#endif /* FOSSIL_ENABLE_JSON */
  }
}

656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
  zBoundry = get_line_from_string(&z, &len);
  if( zBoundry==0 ) return;
  while( (zLine = get_line_from_string(&z, &len))!=0 ){
    if( zLine[0]==0 ){
      int nContent = 0;
      zValue = get_bounded_content(&z, &len, zBoundry, &nContent);
      if( zName && zValue && fossil_islower(zName[0]) ){
        cgi_set_parameter_nocopy(zName, zValue);
        if( showBytes ){
          cgi_set_parameter_nocopy(mprintf("%s:bytes", zName),
               mprintf("%d",nContent));
        }
      }
      zName = 0;
      showBytes = 0;
    }else{
      nArg = tokenize_line(zLine, sizeof(azArg)/sizeof(azArg[0]), azArg);
      for(i=0; i<nArg; i++){
        int c = fossil_tolower(azArg[i][0]);
        int n = strlen(azArg[i]);
        if( c=='c' && sqlite3_strnicmp(azArg[i],"content-disposition:",n)==0 ){
          i++;
        }else if( c=='n' && sqlite3_strnicmp(azArg[i],"name=",n)==0 ){
          zName = azArg[++i];
        }else if( c=='f' && sqlite3_strnicmp(azArg[i],"filename=",n)==0 ){
          char *z = azArg[++i];
          if( zName && z && fossil_islower(zName[0]) ){
            cgi_set_parameter_nocopy(mprintf("%s:filename",zName), z);
          }
          showBytes = 1;
        }else if( c=='c' && sqlite3_strnicmp(azArg[i],"content-type:",n)==0 ){
          char *z = azArg[++i];
          if( zName && z && fossil_islower(zName[0]) ){
            cgi_set_parameter_nocopy(mprintf("%s:mimetype",zName), z);
          }
        }
      }
    }
  }        
}








|


|
















|





|







659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
  zBoundry = get_line_from_string(&z, &len);
  if( zBoundry==0 ) return;
  while( (zLine = get_line_from_string(&z, &len))!=0 ){
    if( zLine[0]==0 ){
      int nContent = 0;
      zValue = get_bounded_content(&z, &len, zBoundry, &nContent);
      if( zName && zValue && fossil_islower(zName[0]) ){
        cgi_set_parameter_nocopy(zName, zValue, 1);
        if( showBytes ){
          cgi_set_parameter_nocopy(mprintf("%s:bytes", zName),
               mprintf("%d",nContent), 1);
        }
      }
      zName = 0;
      showBytes = 0;
    }else{
      nArg = tokenize_line(zLine, sizeof(azArg)/sizeof(azArg[0]), azArg);
      for(i=0; i<nArg; i++){
        int c = fossil_tolower(azArg[i][0]);
        int n = strlen(azArg[i]);
        if( c=='c' && sqlite3_strnicmp(azArg[i],"content-disposition:",n)==0 ){
          i++;
        }else if( c=='n' && sqlite3_strnicmp(azArg[i],"name=",n)==0 ){
          zName = azArg[++i];
        }else if( c=='f' && sqlite3_strnicmp(azArg[i],"filename=",n)==0 ){
          char *z = azArg[++i];
          if( zName && z && fossil_islower(zName[0]) ){
            cgi_set_parameter_nocopy(mprintf("%s:filename",zName), z, 1);
          }
          showBytes = 1;
        }else if( c=='c' && sqlite3_strnicmp(azArg[i],"content-type:",n)==0 ){
          char *z = azArg[++i];
          if( zName && z && fossil_islower(zName[0]) ){
            cgi_set_parameter_nocopy(mprintf("%s:mimetype",zName), z, 1);
          }
        }
      }
    }
  }        
}

810
811
812
813
814
815
816


817
818
819
820
821
822
823
824
825
826



827
828
829
830
831








832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853

854
855
856
857
858
859
860
      fprintf(stderr, "# failed to open %s\n", zFile);
      return;
    }
  }
  fputs(z, pLog);
}




/*
** Initialize the query parameter database.  Information is pulled from
** the QUERY_STRING environment variable (if it exists), from standard
** input if there is POST data, and from HTTP_COOKIE.
*/
void cgi_init(void){
  char *z;
  const char *zType;
  int len;



#ifdef FOSSIL_ENABLE_JSON
  json_main_bootstrap();
#endif
  g.isHTTP = 1;
  cgi_destination(CGI_BODY);









  z = (char*)P("HTTP_COOKIE");
  if( z ){
    z = mprintf("%s",z);
    add_param_list(z, ';');
  }
  
  z = (char*)P("QUERY_STRING");
  if( z ){
    z = mprintf("%s",z);
    add_param_list(z, '&');
  }

  z = (char*)P("REMOTE_ADDR");
  if( z ){
    g.zIpAddr = mprintf("%s", z);
  }

  len = atoi(PD("CONTENT_LENGTH", "0"));
  g.zContentType = zType = P("CONTENT_TYPE");
  if( len>0 && zType ){
    blob_zero(&g.cgiIn);

    if( fossil_strcmp(zType,"application/x-www-form-urlencoded")==0 
         || strncmp(zType,"multipart/form-data",19)==0 ){
      z = fossil_malloc( len+1 );
      len = fread(z, 1, len, g.httpIn);
      z[len] = 0;
      cgi_trace(z);
      if( zType[0]=='a' ){







>
>










>
>
>





>
>
>
>
>
>
>
>




















<
|
>







813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867

868
869
870
871
872
873
874
875
876
      fprintf(stderr, "# failed to open %s\n", zFile);
      return;
    }
  }
  fputs(z, pLog);
}

/* Forward declaration */
static NORETURN void malformed_request(const char *zMsg);

/*
** Initialize the query parameter database.  Information is pulled from
** the QUERY_STRING environment variable (if it exists), from standard
** input if there is POST data, and from HTTP_COOKIE.
*/
void cgi_init(void){
  char *z;
  const char *zType;
  int len;
  const char *zRequestUri = cgi_parameter("REQUEST_URI",0);
  const char *zScriptName = cgi_parameter("SCRIPT_NAME",0);

#ifdef FOSSIL_ENABLE_JSON
  json_main_bootstrap();
#endif
  g.isHTTP = 1;
  cgi_destination(CGI_BODY);
  if( zRequestUri==0 ) malformed_request("missing REQUEST_URI");
  if( zScriptName==0 ) malformed_request("missing SCRIPT_NAME");
  if( cgi_parameter("PATH_INFO",0)==0 ){
    int i, j;
    for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){}
    for(j=i; zRequestUri[j] && zRequestUri[j]!='?'; j++){}
    cgi_set_parameter("PATH_INFO", mprintf("%.*s", j-i, zRequestUri+i));
  }

  z = (char*)P("HTTP_COOKIE");
  if( z ){
    z = mprintf("%s",z);
    add_param_list(z, ';');
  }
  
  z = (char*)P("QUERY_STRING");
  if( z ){
    z = mprintf("%s",z);
    add_param_list(z, '&');
  }

  z = (char*)P("REMOTE_ADDR");
  if( z ){
    g.zIpAddr = mprintf("%s", z);
  }

  len = atoi(PD("CONTENT_LENGTH", "0"));
  g.zContentType = zType = P("CONTENT_TYPE");

  blob_zero(&g.cgiIn);
  if( len>0 && zType ){
    if( fossil_strcmp(zType,"application/x-www-form-urlencoded")==0 
         || strncmp(zType,"multipart/form-data",19)==0 ){
      z = fossil_malloc( len+1 );
      len = fread(z, 1, len, g.httpIn);
      z[len] = 0;
      cgi_trace(z);
      if( zType[0]=='a' ){
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
  /* If no match is found and the name begins with an upper-case
  ** letter, then check to see if there is an environment variable
  ** with the given name.
  */
  if( fossil_isupper(zName[0]) ){
    const char *zValue = fossil_getenv(zName);
    if( zValue ){
      cgi_set_parameter_nocopy(zName, zValue);
      CGIDEBUG(("env-match [%s] = [%s]\n", zName, zValue));
      return zValue;
    }
  }
  CGIDEBUG(("no-match [%s]\n", zName));
  return zDefault;
}







|







981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
  /* If no match is found and the name begins with an upper-case
  ** letter, then check to see if there is an environment variable
  ** with the given name.
  */
  if( fossil_isupper(zName[0]) ){
    const char *zValue = fossil_getenv(zName);
    if( zValue ){
      cgi_set_parameter_nocopy(zName, zValue, 0);
      CGIDEBUG(("env-match [%s] = [%s]\n", zName, zValue));
      return zValue;
    }
  }
  CGIDEBUG(("no-match [%s]\n", zName));
  return zDefault;
}
1066
1067
1068
1069
1070
1071
1072















1073
1074
1075
1076
1077
1078
1079
    if( !showAll ){
      if( fossil_stricmp("HTTP_COOKIE",zName)==0 ) continue;
      if( fossil_strnicmp("fossil-",zName,7)==0 ) continue;
    }
    cgi_printf("%h = %h  <br />\n", zName, aParamQP[i].zValue);
  }
}
















/*
** This routine works like "printf" except that it has the
** extra formatting capabilities such as %h and %t.
*/
void cgi_printf(const char *zFormat, ...){
  va_list ap;







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







1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
    if( !showAll ){
      if( fossil_stricmp("HTTP_COOKIE",zName)==0 ) continue;
      if( fossil_strnicmp("fossil-",zName,7)==0 ) continue;
    }
    cgi_printf("%h = %h  <br />\n", zName, aParamQP[i].zValue);
  }
}

/*
** Export all query parameters (but not cookies or environment variables)
** as hidden values of a form.
*/
void cgi_query_parameters_to_hidden(void){
  int i;
  const char *zN, *zV;
  for(i=0; i<nUsedQP; i++){
    if( aParamQP[i].isQP==0 ) continue;
    zN = aParamQP[i].zName;
    zV = aParamQP[i].zValue;
    @ <input type="hidden" name="%h(zN)" value="%h(zV)">
  }
}

/*
** This routine works like "printf" except that it has the
** extra formatting capabilities such as %h and %t.
*/
void cgi_printf(const char *zFormat, ...){
  va_list ap;
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
  vxprintf(pContent,zFormat,ap);
}


/*
** Send a reply indicating that the HTTP request was malformed
*/
static NORETURN void malformed_request(void){
  cgi_set_status(501, "Not Implemented");
  cgi_printf(
    "<html><body>Unrecognized HTTP Request</body></html>\n"
  );
  cgi_reply();
  fossil_exit(0);
}

/*
** Panic and die while processing a webpage.







|


|







1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
  vxprintf(pContent,zFormat,ap);
}


/*
** Send a reply indicating that the HTTP request was malformed
*/
static NORETURN void malformed_request(const char *zMsg){
  cgi_set_status(501, "Not Implemented");
  cgi_printf(
    "<html><body><p>Bad Request: %s</p></body></html>\n", zMsg
  );
  cgi_reply();
  fossil_exit(0);
}

/*
** Panic and die while processing a webpage.
1129
1130
1131
1132
1133
1134
1135














1136
1137
1138
1139
1140
1141
1142
    va_start(ap, zFormat);
    vxprintf(pContent,zFormat,ap);
    va_end(ap);
    cgi_reply();
    fossil_exit(1);
  }
}















/*
** Remove the first space-delimited token from a string and return
** a pointer to it.  Add a NULL to the string to terminate the token.
** Make *zLeftOver point to the start of the next token.
*/
static char *extract_token(char *zInput, char **zLeftOver){







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







1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
    va_start(ap, zFormat);
    vxprintf(pContent,zFormat,ap);
    va_end(ap);
    cgi_reply();
    fossil_exit(1);
  }
}

/* z[] is the value of an X-FORWARDED-FOR: line in an HTTP header.
** Return a pointer to a string containing the real IP address, or a
** NULL pointer to stick with the IP address previously computed and
** loaded into g.zIpAddr.
*/
static const char *cgi_accept_forwarded_for(const char *z){
  int i;
  if( fossil_strcmp(g.zIpAddr, "127.0.0.1")!=0 ) return 0;
  
  i = strlen(z)-1;
  while( i>=0 && z[i]!=',' && !fossil_isspace(z[i]) ) i--;
  return &z[++i];
}

/*
** Remove the first space-delimited token from a string and return
** a pointer to it.  Add a NULL to the string to terminate the token.
** Make *zLeftOver point to the start of the next token.
*/
static char *extract_token(char *zInput, char **zLeftOver){
1171
1172
1173
1174
1175
1176
1177
1178
1179

1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195

1196
1197
1198
1199
1200
1201
1202
  char *z, *zToken;
  int i;
  struct sockaddr_in remoteName;
  socklen_t size = sizeof(struct sockaddr_in);
  char zLine[2000];     /* A single line of input. */
  g.fullHttpReply = 1;
  if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
    malformed_request();
  }

  cgi_trace(zLine);
  zToken = extract_token(zLine, &z);
  if( zToken==0 ){
    malformed_request();
  }
  if( fossil_strcmp(zToken,"GET")!=0 && fossil_strcmp(zToken,"POST")!=0
      && fossil_strcmp(zToken,"HEAD")!=0 ){
    malformed_request();
  }
  cgi_setenv("GATEWAY_INTERFACE","CGI/1.0");
  cgi_setenv("REQUEST_METHOD",zToken);
  zToken = extract_token(z, &z);
  if( zToken==0 ){
    malformed_request();
  }
  cgi_setenv("REQUEST_URI", zToken);

  for(i=0; zToken[i] && zToken[i]!='?'; i++){}
  if( zToken[i] ) zToken[i++] = 0;
  cgi_setenv("PATH_INFO", zToken);
  cgi_setenv("QUERY_STRING", &zToken[i]);
  if( zIpAddr==0 &&
        getpeername(fileno(g.httpIn), (struct sockaddr*)&remoteName, 
                                &size)>=0







|

>



|



|





|


>







1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
  char *z, *zToken;
  int i;
  struct sockaddr_in remoteName;
  socklen_t size = sizeof(struct sockaddr_in);
  char zLine[2000];     /* A single line of input. */
  g.fullHttpReply = 1;
  if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
    malformed_request("missing HTTP header");
  }
  blob_append(&g.httpHeader, zLine, -1);
  cgi_trace(zLine);
  zToken = extract_token(zLine, &z);
  if( zToken==0 ){
    malformed_request("malformed HTTP header");
  }
  if( fossil_strcmp(zToken,"GET")!=0 && fossil_strcmp(zToken,"POST")!=0
      && fossil_strcmp(zToken,"HEAD")!=0 ){
    malformed_request("unsupported HTTP method");
  }
  cgi_setenv("GATEWAY_INTERFACE","CGI/1.0");
  cgi_setenv("REQUEST_METHOD",zToken);
  zToken = extract_token(z, &z);
  if( zToken==0 ){
    malformed_request("malformed URL in HTTP header");
  }
  cgi_setenv("REQUEST_URI", zToken);
  cgi_setenv("SCRIPT_NAME", "");
  for(i=0; zToken[i] && zToken[i]!='?'; i++){}
  if( zToken[i] ) zToken[i++] = 0;
  cgi_setenv("PATH_INFO", zToken);
  cgi_setenv("QUERY_STRING", &zToken[i]);
  if( zIpAddr==0 &&
        getpeername(fileno(g.httpIn), (struct sockaddr*)&remoteName, 
                                &size)>=0
1211
1212
1213
1214
1215
1216
1217

1218
1219
1220
1221
1222
1223
1224
  /* Get all the optional fields that follow the first line.
  */
  while( fgets(zLine,sizeof(zLine),g.httpIn) ){
    char *zFieldName;
    char *zVal;

    cgi_trace(zLine);

    zFieldName = extract_token(zLine,&zVal);
    if( zFieldName==0 || *zFieldName==0 ) break;
    while( fossil_isspace(*zVal) ){ zVal++; }
    i = strlen(zVal);
    while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; }
    zVal[i] = 0;
    for(i=0; zFieldName[i]; i++){







>







1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
  /* Get all the optional fields that follow the first line.
  */
  while( fgets(zLine,sizeof(zLine),g.httpIn) ){
    char *zFieldName;
    char *zVal;

    cgi_trace(zLine);
    blob_append(&g.httpHeader, zLine, -1);
    zFieldName = extract_token(zLine,&zVal);
    if( zFieldName==0 || *zFieldName==0 ) break;
    while( fossil_isspace(*zVal) ){ zVal++; }
    i = strlen(zVal);
    while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; }
    zVal[i] = 0;
    for(i=0; zFieldName[i]; i++){
1240
1241
1242
1243
1244
1245
1246





1247
1248

1249
1250
1251








































1252
1253
1254
1255
1256
1257

1258
1259
1260
1261
1262
1263
1264
      cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
#if 0
    }else if( fossil_strcmp(zFieldName,"referer:")==0 ){
      cgi_setenv("HTTP_REFERER", zVal);
#endif
    }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
      cgi_setenv("HTTP_USER_AGENT", zVal);





    }
  }

  cgi_init();
  cgi_trace(0);
}









































#if INTERFACE
/* 
** Bitmap values for the flags parameter to cgi_http_server().
*/
#define HTTP_SERVER_LOCALHOST      0x0001     /* Bind to 127.0.0.1 only */


#endif /* INTERFACE */

/*
** Maximum number of child processes that we can have running
** at one time before we start slowing things down.
*/







>
>
>
>
>
|
|
>



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






>







1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
      cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
#if 0
    }else if( fossil_strcmp(zFieldName,"referer:")==0 ){
      cgi_setenv("HTTP_REFERER", zVal);
#endif
    }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
      cgi_setenv("HTTP_USER_AGENT", zVal);
    }else if( fossil_strcmp(zFieldName,"x-forwarded-for:")==0 ){
      const char *zIpAddr = cgi_accept_forwarded_for(zVal);
      if( zIpAddr!=0 ){
        g.zIpAddr = mprintf("%s", zIpAddr);
        cgi_replace_parameter("REMOTE_ADDR", g.zIpAddr);
      }
    }
  }
  cgi_init();
  cgi_trace(0);
}

/*
** This routine handles a single SCGI request which is coming in on
** g.httpIn and which replies on g.httpOut
**
** The SCGI request is read from g.httpIn and is used to initialize
** entries in the cgi_parameter() hash, as if those entries were
** environment variables.  A call to cgi_init() completes
** the setup.  Once all the setup is finished, this procedure returns
** and subsequent code handles the actual generation of the webpage.
*/
void cgi_handle_scgi_request(void){
  char *zHdr;
  char *zToFree;
  int nHdr = 0;
  int nRead;
  int n, m;
  char c;

  while( (c = fgetc(g.httpIn))!=EOF && fossil_isdigit(c) ){
    nHdr = nHdr*10 + c - '0';
  }
  if( nHdr<16 ) malformed_request("SCGI header too short");
  zToFree = zHdr = fossil_malloc(nHdr);
  nRead = (int)fread(zHdr, 1, nHdr, g.httpIn);
  if( nRead<nHdr ) malformed_request("cannot read entire SCGI header");
  nHdr = nRead;
  while( nHdr ){
    for(n=0; n<nHdr && zHdr[n]; n++){}
    for(m=n+1; m<nHdr && zHdr[m]; m++){}
    if( m>=nHdr ) malformed_request("SCGI header formatting error");
    cgi_set_parameter(zHdr, zHdr+n+1);
    zHdr += m+1;
    nHdr -= m+1;
  }
  fossil_free(zToFree);
  fgetc(g.httpIn);  /* Read past the "," separating header from content */
  cgi_init();
}


#if INTERFACE
/* 
** Bitmap values for the flags parameter to cgi_http_server().
*/
#define HTTP_SERVER_LOCALHOST      0x0001     /* Bind to 127.0.0.1 only */
#define HTTP_SERVER_SCGI           0x0002     /* SCGI instead of HTTP */

#endif /* INTERFACE */

/*
** Maximum number of child processes that we can have running
** at one time before we start slowing things down.
*/
1332
1333
1334
1335
1336
1337
1338
1339

1340
1341
1342
1343
1344
1345
1346
      fossil_fatal("unable to open listening socket on any"
                   " port in the range %d..%d", mnPort, mxPort);
    }
  }
  if( iPort>mxPort ) return 1;
  listen(listener,10);
  if( iPort>mnPort ){
    fossil_print("Listening for HTTP requests on TCP port %d\n", iPort);

    fflush(stdout);
  }
  if( zBrowser ){
    zBrowser = mprintf(zBrowser, iPort);
    if( system(zBrowser)<0 ){
      fossil_warning("cannot start browser: %s\n", zBrowser);
    }







|
>







1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
      fossil_fatal("unable to open listening socket on any"
                   " port in the range %d..%d", mnPort, mxPort);
    }
  }
  if( iPort>mxPort ) return 1;
  listen(listener,10);
  if( iPort>mnPort ){
    fossil_print("Listening for %s requests on TCP port %d\n",
       (flags & HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP",  iPort);
    fflush(stdout);
  }
  if( zBrowser ){
    zBrowser = mprintf(zBrowser, iPort);
    if( system(zBrowser)<0 ){
      fossil_warning("cannot start browser: %s\n", zBrowser);
    }
Changes to src/checkin.c.
101
102
103
104
105
106
107
108

109
110
111
112



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
          nErr++;
        }
      }
    }else if( isNew ){
      blob_appendf(report, "ADDED      %s\n", zDisplayName);
    }else if( isDeleted ){
      blob_appendf(report, "DELETED    %s\n", zDisplayName);
    }else if( isChnged==2 ){

      blob_appendf(report, "UPDATED_BY_MERGE %s\n", zDisplayName);
    }else if( isChnged==3 ){
      blob_appendf(report, "ADDED_BY_MERGE %s\n", zDisplayName);
    }else if( isChnged==1 ){



      if( file_contains_merge_marker(zFullName) ){
        blob_appendf(report, "CONFLICT   %s\n", zDisplayName);
      }else{
        blob_appendf(report, "EDITED     %s\n", zDisplayName);
      }
    }else if( isRenamed ){
      blob_appendf(report, "RENAMED    %s\n", zDisplayName);
    }else{
      report->nUsed -= nPrefix;
    }
    free(zFullName);
  }
  blob_reset(&rewrittenPathname);
  db_finalize(&q);
  db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
                 " WHERE id<=0");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zLabel = "MERGED_WITH";
    switch( db_column_int(&q, 1) ){
      case -1:  zLabel = "CHERRYPICK";  break;
      case -2:  zLabel = "BACKOUT   ";  break;

    }
    blob_append(report, zPrefix, nPrefix);
    blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
  }
  db_finalize(&q);
  if( nErr ){
    fossil_fatal("aborting due to prior errors");







|
>
|
|
|
|
>
>
>
|


















|
|
>







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
          nErr++;
        }
      }
    }else if( isNew ){
      blob_appendf(report, "ADDED      %s\n", zDisplayName);
    }else if( isDeleted ){
      blob_appendf(report, "DELETED    %s\n", zDisplayName);
    }else if( isChnged ){
      if( isChnged==2 ){
        blob_appendf(report, "UPDATED_BY_MERGE %s\n", zDisplayName);
      }else if( isChnged==3 ){
        blob_appendf(report, "ADDED_BY_MERGE %s\n", zDisplayName);
      }else if( isChnged==4 ){
        blob_appendf(report, "UPDATED_BY_INTEGRATE %s\n", zDisplayName);
      }else if( isChnged==5 ){
        blob_appendf(report, "ADDED_BY_INTEGRATE %s\n", zDisplayName);
      }else if( file_contains_merge_marker(zFullName) ){
        blob_appendf(report, "CONFLICT   %s\n", zDisplayName);
      }else{
        blob_appendf(report, "EDITED     %s\n", zDisplayName);
      }
    }else if( isRenamed ){
      blob_appendf(report, "RENAMED    %s\n", zDisplayName);
    }else{
      report->nUsed -= nPrefix;
    }
    free(zFullName);
  }
  blob_reset(&rewrittenPathname);
  db_finalize(&q);
  db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
                 " WHERE id<=0");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zLabel = "MERGED_WITH";
    switch( db_column_int(&q, 1) ){
      case -1:  zLabel = "CHERRYPICK ";  break;
      case -2:  zLabel = "BACKOUT    ";  break;
      case -4:  zLabel = "INTEGRATE  ";  break;
    }
    blob_append(report, zPrefix, nPrefix);
    blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
  }
  db_finalize(&q);
  if( nErr ){
    fossil_fatal("aborting due to prior errors");
326
327
328
329
330
331
332











333

334
335
336
337
338
339
340
      }else if( !file_wd_isfile_or_link(zFullName) ){
        if( file_access(zFullName, 0)==0 ){
          type = "NOT_A_FILE ";
        }else{
          type = "MISSING    ";
        }
      }else if( chnged ){











        type = "EDITED     ";

      }else if( renamed ){
        type = "RENAMED    ";
      }else{
        type = "UNCHANGED  ";
      }
    }
    if( showAge ){







>
>
>
>
>
>
>
>
>
>
>
|
>







331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
      }else if( !file_wd_isfile_or_link(zFullName) ){
        if( file_access(zFullName, 0)==0 ){
          type = "NOT_A_FILE ";
        }else{
          type = "MISSING    ";
        }
      }else if( chnged ){
        if( chnged==2 ){
          type = "UPDATED_BY_MERGE ";
        }else if( chnged==3 ){
          type = "ADDED_BY_MERGE ";
        }else if( chnged==4 ){
          type = "UPDATED_BY_INTEGRATE ";
        }else if( chnged==5 ){
          type = "ADDED_BY_INTEGRATE ";
        }else if( file_contains_merge_marker(zFullName) ){
          type = "CONFLICT   ";
        }else{
          type = "EDITED     ";
        }
      }else if( renamed ){
        type = "RENAMED    ";
      }else{
        type = "UNCHANGED  ";
      }
    }
    if( showAge ){
628
629
630
631
632
633
634
635
636
637




638
639
640
641
642
643
644
  zEditor = db_get("editor", 0);
  if( zEditor==0 ){
    zEditor = fossil_getenv("VISUAL");
  }
  if( zEditor==0 ){
    zEditor = fossil_getenv("EDITOR");
  }
#ifdef _WIN32
  if( zEditor==0 ){
    zEditor = mprintf("%s\\notepad.exe", fossil_getenv("SystemRoot"));




  }
#endif
  if( zEditor==0 ){
    blob_append(pPrompt,
       "#\n"
       "# Since no default text editor is set using EDITOR or VISUAL\n"
       "# environment variables or the \"fossil set editor\" command,\n"







|

|
>
>
>
>







645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
  zEditor = db_get("editor", 0);
  if( zEditor==0 ){
    zEditor = fossil_getenv("VISUAL");
  }
  if( zEditor==0 ){
    zEditor = fossil_getenv("EDITOR");
  }
#if defined(_WIN32) || defined(__CYGWIN__)
  if( zEditor==0 ){
    zEditor = mprintf("%s\\notepad.exe", fossil_getenv("SYSTEMROOT"));
#if defined(__CYGWIN__)
    zEditor = fossil_utf8_to_filename(zEditor);
    blob_add_cr(pPrompt);
#endif
  }
#endif
  if( zEditor==0 ){
    blob_append(pPrompt,
       "#\n"
       "# Since no default text editor is set using EDITOR or VISUAL\n"
       "# environment variables or the \"fossil set editor\" command,\n"
881
882
883
884
885
886
887

888
889
890
891
892
893
894
** The following structure holds some of the information needed to construct a
** check-in manifest.
*/
struct CheckinInfo {
  Blob *pComment;             /* Check-in comment text */
  const char *zMimetype;      /* Mimetype of check-in command.  May be NULL */
  int verifyDate;             /* Verify that child is younger */

  Blob *pCksum;               /* Repository checksum.  May be 0 */
  const char *zDateOvrd;      /* Date override.  If 0 then use 'now' */
  const char *zUserOvrd;      /* User override.  If 0 then use g.zLogin */
  const char *zBranch;        /* Branch name.  May be 0 */
  const char *zColor;         /* One-time background color.  May be 0 */
  const char *zBrClr;         /* Persistent branch color.  May be 0 */
  const char **azTag;         /* Tags to apply to this check-in */







>







902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
** The following structure holds some of the information needed to construct a
** check-in manifest.
*/
struct CheckinInfo {
  Blob *pComment;             /* Check-in comment text */
  const char *zMimetype;      /* Mimetype of check-in command.  May be NULL */
  int verifyDate;             /* Verify that child is younger */
  int closeFlag;              /* Close the branch being committed */
  Blob *pCksum;               /* Repository checksum.  May be 0 */
  const char *zDateOvrd;      /* Date override.  If 0 then use 'now' */
  const char *zUserOvrd;      /* User override.  If 0 then use g.zLogin */
  const char *zBranch;        /* Branch name.  May be 0 */
  const char *zColor;         /* One-time background color.  May be 0 */
  const char *zBrClr;         /* Persistent branch color.  May be 0 */
  const char **azTag;         /* Tags to apply to this check-in */
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932

933



934
935
936
937
938
939
940
  CheckinInfo *p,             /* Information about the check-in */
  int *pnFBcard               /* OUT: Number of generated B- and F-cards */
){
  char *zDate;                /* Date of the check-in */
  char *zParentUuid;          /* UUID of parent check-in */
  Blob filename;              /* A single filename */
  int nBasename;              /* Size of base filename */
  Stmt q;                     /* Query of files changed */
  Stmt q2;                    /* Query of merge parents */
  Blob mcksum;                /* Manifest checksum */
  ManifestFile *pFile;        /* File from the baseline */
  int nFBcard = 0;            /* Number of B-cards and F-cards */
  int i;                      /* Loop counter */
  const char *zColor;         /* Modified value of p->zColor */

  assert( pBaseline==0 || pBaseline->zBaseline==0 );
  assert( pBaseline==0 || zBaselineUuid!=0 );
  blob_zero(pOut);
  zParentUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
  if( pBaseline ){
    blob_appendf(pOut, "B %s\n", zBaselineUuid);
    manifest_file_rewind(pBaseline);
    pFile = manifest_file_next(pBaseline, 0);
    nFBcard++;
  }else{
    pFile = 0;
  }

  blob_appendf(pOut, "C %F\n", blob_str(p->pComment));



  zDate = date_in_standard_format(p->zDateOvrd ? p->zDateOvrd : "now");
  blob_appendf(pOut, "D %s\n", zDate);
  zDate[10] = ' ';
  db_prepare(&q,
    "SELECT pathname, uuid, origname, blob.rid, isexe, islink,"
    "       is_selected(vfile.id)"
    "  FROM vfile JOIN blob ON vfile.mrid=blob.rid"







|
<


















>
|
>
>
>







928
929
930
931
932
933
934
935

936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
  CheckinInfo *p,             /* Information about the check-in */
  int *pnFBcard               /* OUT: Number of generated B- and F-cards */
){
  char *zDate;                /* Date of the check-in */
  char *zParentUuid;          /* UUID of parent check-in */
  Blob filename;              /* A single filename */
  int nBasename;              /* Size of base filename */
  Stmt q;                     /* Various queries */

  Blob mcksum;                /* Manifest checksum */
  ManifestFile *pFile;        /* File from the baseline */
  int nFBcard = 0;            /* Number of B-cards and F-cards */
  int i;                      /* Loop counter */
  const char *zColor;         /* Modified value of p->zColor */

  assert( pBaseline==0 || pBaseline->zBaseline==0 );
  assert( pBaseline==0 || zBaselineUuid!=0 );
  blob_zero(pOut);
  zParentUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
  if( pBaseline ){
    blob_appendf(pOut, "B %s\n", zBaselineUuid);
    manifest_file_rewind(pBaseline);
    pFile = manifest_file_next(pBaseline, 0);
    nFBcard++;
  }else{
    pFile = 0;
  }
  if( blob_size(p->pComment)!=0 ){
    blob_appendf(pOut, "C %F\n", blob_str(p->pComment));
  }else{
    blob_append(pOut, "C (no\\scomment)\n", 16);
  }
  zDate = date_in_standard_format(p->zDateOvrd ? p->zDateOvrd : "now");
  blob_appendf(pOut, "D %s\n", zDate);
  zDate[10] = ' ';
  db_prepare(&q,
    "SELECT pathname, uuid, origname, blob.rid, isexe, islink,"
    "       is_selected(vfile.id)"
    "  FROM vfile JOIN blob ON vfile.mrid=blob.rid"
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041


1042
1043

1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060















1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
  }
  if( p->zMimetype && p->zMimetype[0] ){
    blob_appendf(pOut, "N %F\n", p->zMimetype);
  }
  blob_appendf(pOut, "P %s", zParentUuid);
  if( p->verifyDate ) checkin_verify_younger(vid, zParentUuid, zDate);
  free(zParentUuid);
  db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=0 OR id<-2");
  while( db_step(&q2)==SQLITE_ROW ){
    char *zMergeUuid;
    int mid = db_column_int(&q2, 0);
    if( !g.markPrivate && content_is_private(mid) ) continue;
    zMergeUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
    if( zMergeUuid ){
      blob_appendf(pOut, " %s", zMergeUuid);
      if( p->verifyDate ) checkin_verify_younger(mid, zMergeUuid, zDate);
      free(zMergeUuid);
    }
  }
  db_finalize(&q2);
  free(zDate);
  blob_appendf(pOut, "\n");

  db_prepare(&q2,
    "SELECT CASE vmerge.id WHEN -1 THEN '+' ELSE '-' END || blob.uuid"
    "  FROM vmerge, blob"
    " WHERE (vmerge.id=-1 OR vmerge.id=-2)"
    "   AND blob.rid=vmerge.merge"
    " ORDER BY 1");
  while( db_step(&q2)==SQLITE_ROW ){
    const char *zCherrypickUuid = db_column_text(&q2, 0);


    blob_appendf(pOut, "Q %s\n", zCherrypickUuid);
  }

  db_finalize(&q2);

  if( p->pCksum ) blob_appendf(pOut, "R %b\n", p->pCksum);
  zColor = p->zColor;
  if( p->zBranch && p->zBranch[0] ){
    /* Set tags for the new branch */
    if( p->zBrClr && p->zBrClr[0] ){
      zColor = 0;
      blob_appendf(pOut, "T *bgcolor * %F\n", p->zBrClr);
    }
    blob_appendf(pOut, "T *branch * %F\n", p->zBranch);
    blob_appendf(pOut, "T *sym-%F *\n", p->zBranch);
  }
  if( zColor && zColor[0] ){
    /* One-time background color */
    blob_appendf(pOut, "T +bgcolor * %F\n", zColor);
  }















  if( p->azTag ){
    for(i=0; p->azTag[i]; i++){
      /* Add a symbolic tag to this check-in.  The tag names have already
      ** been sorted and converted using the %F format */
      assert( i==0 || strcmp(p->azTag[i-1], p->azTag[i])<=0 );
      blob_appendf(pOut, "T +sym-%s *\n", p->azTag[i]);
    }
  }
  if( p->zBranch && p->zBranch[0] ){
    /* For a new branch, cancel all prior propagating tags */
    Stmt q;
    db_prepare(&q,
        "SELECT tagname FROM tagxref, tag"
        " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
        "   AND tagtype==2 AND tagname GLOB 'sym-*'"
        "   AND tagname!='sym-'||%Q"
        " ORDER BY tagname",
        vid, p->zBranch);







|
|

|
|







|



|
|




|
|
>
>
|
|
>
|
















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










<







1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113

1114
1115
1116
1117
1118
1119
1120
  }
  if( p->zMimetype && p->zMimetype[0] ){
    blob_appendf(pOut, "N %F\n", p->zMimetype);
  }
  blob_appendf(pOut, "P %s", zParentUuid);
  if( p->verifyDate ) checkin_verify_younger(vid, zParentUuid, zDate);
  free(zParentUuid);
  db_prepare(&q, "SELECT merge FROM vmerge WHERE id=0 OR id<-2");
  while( db_step(&q)==SQLITE_ROW ){
    char *zMergeUuid;
    int mid = db_column_int(&q, 0);
    if( (!g.markPrivate && content_is_private(mid)) || (mid == vid) ) continue;
    zMergeUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
    if( zMergeUuid ){
      blob_appendf(pOut, " %s", zMergeUuid);
      if( p->verifyDate ) checkin_verify_younger(mid, zMergeUuid, zDate);
      free(zMergeUuid);
    }
  }
  db_finalize(&q);
  free(zDate);
  blob_appendf(pOut, "\n");

  db_prepare(&q,
    "SELECT CASE vmerge.id WHEN -1 THEN '+' ELSE '-' END || blob.uuid, merge"
    "  FROM vmerge, blob"
    " WHERE (vmerge.id=-1 OR vmerge.id=-2)"
    "   AND blob.rid=vmerge.merge"
    " ORDER BY 1");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zCherrypickUuid = db_column_text(&q, 0);
    int mid = db_column_int(&q, 1);
    if( mid != vid ){
      blob_appendf(pOut, "Q %s\n", zCherrypickUuid);
    }
  }
  db_finalize(&q);

  if( p->pCksum ) blob_appendf(pOut, "R %b\n", p->pCksum);
  zColor = p->zColor;
  if( p->zBranch && p->zBranch[0] ){
    /* Set tags for the new branch */
    if( p->zBrClr && p->zBrClr[0] ){
      zColor = 0;
      blob_appendf(pOut, "T *bgcolor * %F\n", p->zBrClr);
    }
    blob_appendf(pOut, "T *branch * %F\n", p->zBranch);
    blob_appendf(pOut, "T *sym-%F *\n", p->zBranch);
  }
  if( zColor && zColor[0] ){
    /* One-time background color */
    blob_appendf(pOut, "T +bgcolor * %F\n", zColor);
  }
  if( p->closeFlag ){
    blob_appendf(pOut, "T +closed *\n");
  }
  db_prepare(&q, "SELECT uuid,merge FROM vmerge JOIN blob ON merge=rid"
                 " WHERE id=-4 ORDER BY 1");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zIntegrateUuid = db_column_text(&q, 0);
    int rid = db_column_int(&q, 1);
    if( is_a_leaf(rid) && !db_exists("SELECT 1 FROM tagxref "
        " WHERE tagid=%d AND rid=%d AND tagtype>0", TAG_CLOSED, rid)){
      blob_appendf(pOut, "T +closed %s\n", zIntegrateUuid);
    }
  }
  db_finalize(&q);

  if( p->azTag ){
    for(i=0; p->azTag[i]; i++){
      /* Add a symbolic tag to this check-in.  The tag names have already
      ** been sorted and converted using the %F format */
      assert( i==0 || strcmp(p->azTag[i-1], p->azTag[i])<=0 );
      blob_appendf(pOut, "T +sym-%s *\n", p->azTag[i]);
    }
  }
  if( p->zBranch && p->zBranch[0] ){
    /* For a new branch, cancel all prior propagating tags */

    db_prepare(&q,
        "SELECT tagname FROM tagxref, tag"
        " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
        "   AND tagtype==2 AND tagname GLOB 'sym-*'"
        "   AND tagname!='sym-'||%Q"
        " ORDER BY tagname",
        vid, p->zBranch);
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
**    --allow-empty              allow a commit with no changes
**    --allow-fork               allow the commit to fork
**    --allow-older              allow a commit older than its ancestor
**    --baseline                 use a baseline manifest in the commit process
**    --bgcolor COLOR            apply COLOR to this one check-in only
**    --branch NEW-BRANCH-NAME   check in to this new branch
**    --branchcolor COLOR        apply given COLOR to the branch

**    --delta                    use a delta manifest in the commit process
**    -m|--comment COMMENT-TEXT  use COMMENT-TEXT as commit comment
**    -M|--message-file FILE     read the commit comment from given file
**    --mimetype MIMETYPE        mimetype of check-in comment
**    -n|--dry-run               If given, display instead of run actions
**    --no-warnings              omit all warnings about file contents
**    --nosign                   do not attempt to sign this commit with gpg
**    --private                  do not sync changes and their descendants
**    --tag TAG-NAME             assign given tag TAG-NAME to the checkin
**
** See also: branch, changes, checkout, extra, sync
*/
void commit_cmd(void){
  int hasChanges;        /* True if unsaved changes exist */
  int vid;               /* blob-id of parent version */
  int nrid;              /* blob-id of a modified file */
  int nvid;              /* Blob-id of the new check-in */
  Blob comment;          /* Check-in comment */
  const char *zComment;  /* Check-in comment */
  Stmt q;                /* Query to find files that have been modified */
  char *zUuid;           /* UUID of the new check-in */
  int noSign = 0;        /* True to omit signing the manifest using GPG */
  int isAMerge = 0;      /* True if checking in a merge */
  int noWarningFlag = 0; /* True if skipping all warnings */
  int forceFlag = 0;     /* Undocumented: Disables all checks */
  int forceDelta = 0;    /* Force a delta-manifest */
  int forceBaseline = 0; /* Force a baseline-manifest */







>



















|







1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
**    --allow-empty              allow a commit with no changes
**    --allow-fork               allow the commit to fork
**    --allow-older              allow a commit older than its ancestor
**    --baseline                 use a baseline manifest in the commit process
**    --bgcolor COLOR            apply COLOR to this one check-in only
**    --branch NEW-BRANCH-NAME   check in to this new branch
**    --branchcolor COLOR        apply given COLOR to the branch
**    --close                    close the branch being committed
**    --delta                    use a delta manifest in the commit process
**    -m|--comment COMMENT-TEXT  use COMMENT-TEXT as commit comment
**    -M|--message-file FILE     read the commit comment from given file
**    --mimetype MIMETYPE        mimetype of check-in comment
**    -n|--dry-run               If given, display instead of run actions
**    --no-warnings              omit all warnings about file contents
**    --nosign                   do not attempt to sign this commit with gpg
**    --private                  do not sync changes and their descendants
**    --tag TAG-NAME             assign given tag TAG-NAME to the checkin
**
** See also: branch, changes, checkout, extra, sync
*/
void commit_cmd(void){
  int hasChanges;        /* True if unsaved changes exist */
  int vid;               /* blob-id of parent version */
  int nrid;              /* blob-id of a modified file */
  int nvid;              /* Blob-id of the new check-in */
  Blob comment;          /* Check-in comment */
  const char *zComment;  /* Check-in comment */
  Stmt q;                /* Various queries */
  char *zUuid;           /* UUID of the new check-in */
  int noSign = 0;        /* True to omit signing the manifest using GPG */
  int isAMerge = 0;      /* True if checking in a merge */
  int noWarningFlag = 0; /* True if skipping all warnings */
  int forceFlag = 0;     /* Undocumented: Disables all checks */
  int forceDelta = 0;    /* Force a delta-manifest */
  int forceBaseline = 0; /* Force a baseline-manifest */
1356
1357
1358
1359
1360
1361
1362

1363
1364
1365
1366
1367
1368
1369
  allowEmpty = find_option("allow-empty",0,0)!=0;
  allowFork = find_option("allow-fork",0,0)!=0;
  allowOlder = find_option("allow-older",0,0)!=0;
  noWarningFlag = find_option("no-warnings", 0, 0)!=0;
  sCiInfo.zBranch = find_option("branch","b",1);
  sCiInfo.zColor = find_option("bgcolor",0,1);
  sCiInfo.zBrClr = find_option("branchcolor",0,1);

  sCiInfo.zMimetype = find_option("mimetype",0,1);
  while( (zTag = find_option("tag",0,1))!=0 ){
    if( zTag[0]==0 ) continue;
    sCiInfo.azTag = fossil_realloc((void*)sCiInfo.azTag, sizeof(char*)*(nTag+2));
    sCiInfo.azTag[nTag++] = zTag;
    sCiInfo.azTag[nTag] = 0;
  }







>







1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
  allowEmpty = find_option("allow-empty",0,0)!=0;
  allowFork = find_option("allow-fork",0,0)!=0;
  allowOlder = find_option("allow-older",0,0)!=0;
  noWarningFlag = find_option("no-warnings", 0, 0)!=0;
  sCiInfo.zBranch = find_option("branch","b",1);
  sCiInfo.zColor = find_option("bgcolor",0,1);
  sCiInfo.zBrClr = find_option("branchcolor",0,1);
  sCiInfo.closeFlag = find_option("close",0,0)!=0;
  sCiInfo.zMimetype = find_option("mimetype",0,1);
  while( (zTag = find_option("tag",0,1))!=0 ){
    if( zTag[0]==0 ) continue;
    sCiInfo.azTag = fossil_realloc((void*)sCiInfo.azTag, sizeof(char*)*(nTag+2));
    sCiInfo.azTag[nTag++] = zTag;
    sCiInfo.azTag[nTag] = 0;
  }
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484

  /* Doing "fossil mv fileA fileB; fossil add fileA; fossil commit fileA"
  ** will generate a manifest that has two fileA entries, which is illegal.
  ** When you think about it, the sequence above makes no sense.  So detect
  ** it and disallow it.  Ticket [0ff64b0a5fc8].
  */
  if( g.aCommitFile ){
    Stmt qRename;
    db_prepare(&qRename,
       "SELECT v1.pathname, v2.pathname"
       "  FROM vfile AS v1, vfile AS v2"
       " WHERE is_selected(v1.id)"
       "   AND v2.origname IS NOT NULL"
       "   AND v2.origname=v1.pathname"
       "   AND NOT is_selected(v2.id)");
    if( db_step(&qRename)==SQLITE_ROW ){
      const char *zFrom = db_column_text(&qRename, 0);
      const char *zTo = db_column_text(&qRename, 1);
      fossil_fatal("cannot do a partial commit of '%s' without '%s' because "
                   "'%s' was renamed to '%s'", zFrom, zTo, zFrom, zTo);
    }
    db_finalize(&qRename);
  }

  user_select();
  /*
  ** Check that the user exists.
  */
  if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){







<
|






|
|
|



|







1500
1501
1502
1503
1504
1505
1506

1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527

  /* Doing "fossil mv fileA fileB; fossil add fileA; fossil commit fileA"
  ** will generate a manifest that has two fileA entries, which is illegal.
  ** When you think about it, the sequence above makes no sense.  So detect
  ** it and disallow it.  Ticket [0ff64b0a5fc8].
  */
  if( g.aCommitFile ){

    db_prepare(&q,
       "SELECT v1.pathname, v2.pathname"
       "  FROM vfile AS v1, vfile AS v2"
       " WHERE is_selected(v1.id)"
       "   AND v2.origname IS NOT NULL"
       "   AND v2.origname=v1.pathname"
       "   AND NOT is_selected(v2.id)");
    if( db_step(&q)==SQLITE_ROW ){
      const char *zFrom = db_column_text(&q, 0);
      const char *zTo = db_column_text(&q, 1);
      fossil_fatal("cannot do a partial commit of '%s' without '%s' because "
                   "'%s' was renamed to '%s'", zFrom, zTo, zFrom, zTo);
    }
    db_finalize(&q);
  }

  user_select();
  /*
  ** Check that the user exists.
  */
  if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
1531
1532
1533
1534
1535
1536
1537


1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549

1550
1551
1552
1553
1554

1555
1556
1557
1558
1559
1560
1561
  if( zComment ){
    blob_zero(&comment);
    blob_append(&comment, zComment, -1);
  }else if( zComFile ){
    blob_zero(&comment);
    blob_read_from_file(&comment, zComFile);
    blob_to_utf8_no_bom(&comment, 1);


  }else{
    char *zInit = db_text(0, "SELECT value FROM vvar WHERE name='ci-comment'");
    prepare_commit_comment(&comment, zInit, &sCiInfo, vid);
    if( zInit && zInit[0] && fossil_strcmp(zInit, blob_str(&comment))==0 ){
      blob_zero(&ans);
      prompt_user("unchanged check-in comment.  continue (y/N)? ", &ans);
      cReply = blob_str(&ans)[0];
      if( cReply!='y' && cReply!='Y' ) fossil_exit(1);;
    }
    free(zInit);
  }
  if( blob_size(&comment)==0 ){

    blob_zero(&ans);
    prompt_user("empty check-in comment.  continue (y/N)? ", &ans);
    cReply = blob_str(&ans)[0];
    if( cReply!='y' && cReply!='Y' ){
      fossil_exit(1);

    }
  }else{
    db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment);
    db_end_transaction(0);
    db_begin_transaction();
  }








>
>












>
|
|
|
|
|
>







1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
  if( zComment ){
    blob_zero(&comment);
    blob_append(&comment, zComment, -1);
  }else if( zComFile ){
    blob_zero(&comment);
    blob_read_from_file(&comment, zComFile);
    blob_to_utf8_no_bom(&comment, 1);
  }else if(dryRunFlag){
    blob_zero(&comment);
  }else{
    char *zInit = db_text(0, "SELECT value FROM vvar WHERE name='ci-comment'");
    prepare_commit_comment(&comment, zInit, &sCiInfo, vid);
    if( zInit && zInit[0] && fossil_strcmp(zInit, blob_str(&comment))==0 ){
      blob_zero(&ans);
      prompt_user("unchanged check-in comment.  continue (y/N)? ", &ans);
      cReply = blob_str(&ans)[0];
      if( cReply!='y' && cReply!='Y' ) fossil_exit(1);;
    }
    free(zInit);
  }
  if( blob_size(&comment)==0 ){
    if( !dryRunFlag ){
      blob_zero(&ans);
      prompt_user("empty check-in comment.  continue (y/N)? ", &ans);
      cReply = blob_str(&ans)[0];
      if( cReply!='y' && cReply!='Y' ){
        fossil_exit(1);
      }
    }
  }else{
    db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment);
    db_end_transaction(0);
    db_begin_transaction();
  }

1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
                 "use --allow-conflict to override");
  }else if( abortCommit ){
    fossil_fatal("one or more files were converted on your request; "
                 "please re-test before committing");
  }

  /* Create the new manifest */
  if( blob_size(&comment)==0 ){
    blob_append(&comment, "(no comment)", -1);
  }
  sCiInfo.pComment = &comment;
  sCiInfo.pCksum =  useCksum ? &cksum1 : 0;
  sCiInfo.verifyDate = !allowOlder && !forceFlag;
  if( forceDelta ){
    blob_zero(&manifest);
  }else{
    create_manifest(&manifest, 0, 0, vid, &sCiInfo, &szB);







<
<
<







1667
1668
1669
1670
1671
1672
1673



1674
1675
1676
1677
1678
1679
1680
                 "use --allow-conflict to override");
  }else if( abortCommit ){
    fossil_fatal("one or more files were converted on your request; "
                 "please re-test before committing");
  }

  /* Create the new manifest */



  sCiInfo.pComment = &comment;
  sCiInfo.pCksum =  useCksum ? &cksum1 : 0;
  sCiInfo.verifyDate = !allowOlder && !forceFlag;
  if( forceDelta ){
    blob_zero(&manifest);
  }else{
    create_manifest(&manifest, 0, 0, vid, &sCiInfo, &szB);
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706

1707
1708
1709
1710
1711
1712
1713
1714
1715













1716
1717
1718
1719
1720
1721
1722
      if( forceDelta || (szD*szD)<(szB*3-9) ){
        blob_reset(&manifest);
        manifest = delta;
      }else{
        blob_reset(&delta);
      }
    }else if( forceDelta ){
      fossil_panic("unable to find a baseline-manifest for the delta");
    }
  }
  if( !noSign && !g.markPrivate && clearsign(&manifest, &manifest) ){
    blob_zero(&ans);
    prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
    cReply = blob_str(&ans)[0];
    if( cReply!='y' && cReply!='Y' ){
      fossil_exit(1);
    }
  }

  /* If the -n|--dry-run option is specified, output the manifest file
  ** and rollback the transaction.
  */
  if( dryRunFlag ){
    blob_write_to_file(&manifest, "");
  }

  if( outputManifest ){
    zManifestFile = mprintf("%smanifest", g.zLocalRoot);
    blob_write_to_file(&manifest, zManifestFile);
    blob_reset(&manifest);
    blob_read_from_file(&manifest, zManifestFile);
    free(zManifestFile);
  }

  nvid = content_put(&manifest);
  if( nvid==0 ){
    fossil_panic("trouble committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
  manifest_crosslink(nvid, &manifest);
  assert( blob_is_reset(&manifest) );
  content_deltify(vid, nvid, 0);
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);













  fossil_print("New_Version: %s\n", zUuid);
  if( outputManifest ){
    zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
    blob_zero(&muuid);
    blob_appendf(&muuid, "%s\n", zUuid);
    blob_write_to_file(&muuid, zManifestFile);
    free(zManifestFile);







|

















<







>


|






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







1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742

1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
      if( forceDelta || (szD*szD)<(szB*3-9) ){
        blob_reset(&manifest);
        manifest = delta;
      }else{
        blob_reset(&delta);
      }
    }else if( forceDelta ){
      fossil_fatal("unable to find a baseline-manifest for the delta");
    }
  }
  if( !noSign && !g.markPrivate && clearsign(&manifest, &manifest) ){
    blob_zero(&ans);
    prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
    cReply = blob_str(&ans)[0];
    if( cReply!='y' && cReply!='Y' ){
      fossil_exit(1);
    }
  }

  /* If the -n|--dry-run option is specified, output the manifest file
  ** and rollback the transaction.
  */
  if( dryRunFlag ){
    blob_write_to_file(&manifest, "");
  }

  if( outputManifest ){
    zManifestFile = mprintf("%smanifest", g.zLocalRoot);
    blob_write_to_file(&manifest, zManifestFile);
    blob_reset(&manifest);
    blob_read_from_file(&manifest, zManifestFile);
    free(zManifestFile);
  }

  nvid = content_put(&manifest);
  if( nvid==0 ){
    fossil_fatal("trouble committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
  manifest_crosslink(nvid, &manifest);
  assert( blob_is_reset(&manifest) );
  content_deltify(vid, nvid, 0);
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);

  db_prepare(&q, "SELECT uuid,merge FROM vmerge JOIN blob ON merge=rid"
                 " WHERE id=-4");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zIntegrateUuid = db_column_text(&q, 0);
    if( is_a_leaf(db_column_int(&q, 1)) ){
      fossil_print("Closed: %s\n", zIntegrateUuid);
    }else{
      fossil_print("Not_Closed: %s (not a leaf any more)\n", zIntegrateUuid);
    }
  }
  db_finalize(&q);

  fossil_print("New_Version: %s\n", zUuid);
  if( outputManifest ){
    zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
    blob_zero(&muuid);
    blob_appendf(&muuid, "%s\n", zUuid);
    blob_write_to_file(&muuid, zManifestFile);
    free(zManifestFile);
Changes to src/checkout.c.
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
*/
int load_vfile(const char *zName){
  Blob uuid;
  int vid;

  blob_init(&uuid, zName, -1);
  if( name_to_uuid(&uuid, 1, "ci") ){
    fossil_panic(g.zErrMsg);
  }
  vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
  if( vid==0 ){
    fossil_fatal("no such check-in: %s", g.argv[2]);
  }
  if( !is_a_version(vid) ){
    fossil_fatal("object [%.10s] is not a check-in", blob_str(&uuid));







|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
*/
int load_vfile(const char *zName){
  Blob uuid;
  int vid;

  blob_init(&uuid, zName, -1);
  if( name_to_uuid(&uuid, 1, "ci") ){
    fossil_fatal(g.zErrMsg);
  }
  vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid);
  if( vid==0 ){
    fossil_fatal("no such check-in: %s", g.argv[2]);
  }
  if( !is_a_version(vid) ){
    fossil_fatal("object [%.10s] is not a check-in", blob_str(&uuid));
Changes to src/clone.c.
82
83
84
85
86
87
88














89
90
91
92
93
94
95
/*
** COMMAND: clone
**
** Usage: %fossil clone ?OPTIONS? URL FILENAME
**
** Make a clone of a repository specified by URL in the local
** file named FILENAME.  














**
** By default, your current login name is used to create the default
** admin user. This can be overridden using the -A|--admin-user
** parameter.
**
** Options:
**    --admin-user|-A USERNAME   Make USERNAME the administrator







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







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
** COMMAND: clone
**
** Usage: %fossil clone ?OPTIONS? URL FILENAME
**
** Make a clone of a repository specified by URL in the local
** file named FILENAME.  
**
** URL must be in one of the following form: ([...] mean optional)
**   HTTP/HTTPS protocol:
**     http[s]://[userid[:password]@]host[:port][/path]
**
**   SSH protocol:
**     ssh://[userid[:password]@]host[:port]/path/to/repo.fossil\\
**     [?fossil=path/to/fossil.exe]
**
**   Filesystem:
**     [file://]path/to/repo.fossil
**
**   Note: For ssh and filesystem, path must have an extra leading 
**         '/' to use an absolute path.
**
** By default, your current login name is used to create the default
** admin user. This can be overridden using the -A|--admin-user
** parameter.
**
** Options:
**    --admin-user|-A USERNAME   Make USERNAME the administrator
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
  url_proxy_options();
  if( g.argc < 4 ){
    usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
  }
  db_open_config(0);
  if( file_size(g.argv[3])>0 ){
    fossil_panic("file already exists: %s", g.argv[3]);
  }

  zDefaultUser = find_option("admin-user","A",1);

  url_parse(g.argv[2], URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
  if( g.urlIsFile ){
    file_copy(g.urlName, g.argv[3]);







|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
  url_proxy_options();
  if( g.argc < 4 ){
    usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
  }
  db_open_config(0);
  if( file_size(g.argv[3])>0 ){
    fossil_fatal("file already exists: %s", g.argv[3]);
  }

  zDefaultUser = find_option("admin-user","A",1);

  url_parse(g.argv[2], URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
  if( g.urlIsFile ){
    file_copy(g.urlName, g.argv[3]);
Changes to src/content.c.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
** The artifact retrieval cache
*/
static struct {
  i64 szTotal;         /* Total size of all entries in the cache */
  int n;               /* Current number of cache entries */
  int nAlloc;          /* Number of slots allocated in a[] */
  int nextAge;         /* Age counter for implementing LRU */
  int skipCnt;         /* Used to limit entries expelled from cache */
  struct cacheLine {   /* One instance of this for each cache entry */
    int rid;                  /* Artifact id */
    int age;                  /* Age.  Newer is larger */
    Blob content;             /* Content of the artifact */
  } *a;                /* The positive cache */
  Bag inCache;         /* Set of artifacts currently in cache */








<







25
26
27
28
29
30
31

32
33
34
35
36
37
38
** The artifact retrieval cache
*/
static struct {
  i64 szTotal;         /* Total size of all entries in the cache */
  int n;               /* Current number of cache entries */
  int nAlloc;          /* Number of slots allocated in a[] */
  int nextAge;         /* Age counter for implementing LRU */

  struct cacheLine {   /* One instance of this for each cache entry */
    int rid;                  /* Artifact id */
    int age;                  /* Age.  Newer is larger */
    Blob content;             /* Content of the artifact */
  } *a;                /* The positive cache */
  Bag inCache;         /* Set of artifacts currently in cache */

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
  int markAsUnclustered = 0;
  int isDephantomize = 0;
  
  assert( g.repositoryOpen );
  assert( pBlob!=0 );
  assert( srcId==0 || zUuid!=0 );
  if( zUuid==0 ){
    assert( pBlob!=0 );
    assert( nBlob==0 );
    sha1sum_blob(pBlob, &hash);
  }else{
    blob_init(&hash, zUuid, -1);
  }
  if( nBlob ){
    size = nBlob;







<







489
490
491
492
493
494
495

496
497
498
499
500
501
502
  int markAsUnclustered = 0;
  int isDephantomize = 0;
  
  assert( g.repositoryOpen );
  assert( pBlob!=0 );
  assert( srcId==0 || zUuid!=0 );
  if( zUuid==0 ){

    assert( nBlob==0 );
    sha1sum_blob(pBlob, &hash);
  }else{
    blob_init(&hash, zUuid, -1);
  }
  if( nBlob ){
    size = nBlob;
825
826
827
828
829
830
831













832
833
834
835
836





837
838
839
840
841
842
843
844
845



846

847
848
849
850
851
852
853
void test_content_deltify_cmd(void){
  if( g.argc!=5 ) usage("RID SRCID FORCE");
  db_must_be_within_tree();
  content_deltify(atoi(g.argv[2]), atoi(g.argv[3]), atoi(g.argv[4]));
}

/*













** COMMAND: test-integrity
**
** Verify that all content can be extracted from the BLOB table correctly.
** If the BLOB table is correct, then the repository can always be
** successfully reconstructed using "fossil rebuild".





*/
void test_integrity(void){
  Stmt q;
  Blob content;
  Blob cksum;
  int n1 = 0;
  int n2 = 0;
  int nErr = 0;
  int total;



  db_find_and_open_repository(OPEN_ANY_SCHEMA, 2);


  /* Make sure no public artifact is a delta from a private artifact */
  db_prepare(&q,
    "SELECT "
    "   rid, (SELECT uuid FROM blob WHERE rid=delta.rid),"
    "   srcid, (SELECT uuid FROM blob WHERE rid=delta.srcid)"
    "  FROM delta"







>
>
>
>
>
>
>
>
>
>
>
>
>
|




>
>
>
>
>









>
>
>

>







823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
void test_content_deltify_cmd(void){
  if( g.argc!=5 ) usage("RID SRCID FORCE");
  db_must_be_within_tree();
  content_deltify(atoi(g.argv[2]), atoi(g.argv[3]), atoi(g.argv[4]));
}

/*
** Return true if Blob p looks like it might be a parsable control artifact.
*/
static int looks_like_control_artifact(Blob *p){
  const char *z = blob_buffer(p);
  int n = blob_size(p);
  if( n<10 ) return 0;
  if( strncmp(z, "-----BEGIN PGP SIGNED MESSAGE-----", 34)==0 ) return 1;
  if( z[0]<'A' || z[0]>'Z' || z[1]!=' ' || z[0]=='I' ) return 0;
  if( z[n-1]!='\n' ) return 0;
  return 1;
}

/*
** COMMAND: test-integrity ?OPTIONS?
**
** Verify that all content can be extracted from the BLOB table correctly.
** If the BLOB table is correct, then the repository can always be
** successfully reconstructed using "fossil rebuild".
**
** Options:
**
**    --parse            Parse all manifests, wikis, tickets, events, and
**                       so forth, reporting any errors found.
*/
void test_integrity(void){
  Stmt q;
  Blob content;
  Blob cksum;
  int n1 = 0;
  int n2 = 0;
  int nErr = 0;
  int total;
  int nCA = 0;
  int anCA[10];
  int bParse = find_option("parse",0,0)!=0;
  db_find_and_open_repository(OPEN_ANY_SCHEMA, 2);
  memset(anCA, 0, sizeof(anCA));

  /* Make sure no public artifact is a delta from a private artifact */
  db_prepare(&q,
    "SELECT "
    "   rid, (SELECT uuid FROM blob WHERE rid=delta.rid),"
    "   srcid, (SELECT uuid FROM blob WHERE rid=delta.srcid)"
    "  FROM delta"
887
888
889
890
891
892
893

























894

895


896
897
898
899
900









901
902
903
904
905
906
907
    }
    sha1sum_blob(&content, &cksum);
    if( fossil_strcmp(blob_str(&cksum), zUuid)!=0 ){
      fossil_print("checksum mismatch on artifact %d: wanted %s but got %s\n",
                   rid, zUuid, blob_str(&cksum));
      nErr++;
    }

























    blob_reset(&cksum);

    blob_reset(&content);


    n2++;
  }
  db_finalize(&q);
  fossil_print("%d non-phantom blobs (out of %d total) checked:  %d errors\n",
               n2, n1, nErr);









}

/*
** COMMAND: test-orphans
**
** Search the repository for orphaned artifacts
*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>





>
>
>
>
>
>
>
>
>







907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
    }
    sha1sum_blob(&content, &cksum);
    if( fossil_strcmp(blob_str(&cksum), zUuid)!=0 ){
      fossil_print("checksum mismatch on artifact %d: wanted %s but got %s\n",
                   rid, zUuid, blob_str(&cksum));
      nErr++;
    }
    if( bParse && looks_like_control_artifact(&content) ){
      Blob err;
      int i, n;
      char *z;
      Manifest *p;
      char zFirstLine[400];
      blob_zero(&err);

      z = blob_buffer(&content);
      n = blob_size(&content);
      for(i=0; i<n && z[i] && z[i]!='\n' && i<sizeof(zFirstLine)-1; i++){}
      memcpy(zFirstLine, z, i);
      zFirstLine[i] = 0;
      p = manifest_parse(&content, 0, &err);
      if( p==0 ){
        fossil_print("manifest_parse failed for %s:\n%s\n",
               blob_str(&cksum), blob_str(&err));
        if( strncmp(blob_str(&err), "line 1:", 7)==0 ){
          fossil_print("\"%s\"\n", zFirstLine);
        }
      }else{
        anCA[p->type]++;
        manifest_destroy(p);
        nCA++;
      }
      blob_reset(&err);
    }else{
      blob_reset(&content);
    }
    blob_reset(&cksum);
    n2++;
  }
  db_finalize(&q);
  fossil_print("%d non-phantom blobs (out of %d total) checked:  %d errors\n",
               n2, n1, nErr);
  if( bParse ){
    const char *azType[] = { 0, "manifest", "cluster", "control", "wiki",
                             "ticket", "attachment", "event" };
    int i;
    fossil_print("%d total control artifacts\n", nCA);
    for(i=1; i<count(azType); i++){
      if( anCA[i] ) fossil_print("  %d %ss\n", anCA[i], azType[i]);
    }
  }
}

/*
** COMMAND: test-orphans
**
** Search the repository for orphaned artifacts
*/
Changes to src/db.c.
710
711
712
713
714
715
716



717
718
719
720
721
722
723
** connection.  An error results in process abort.
*/
LOCAL sqlite3 *db_open(const char *zDbName){
  int rc;
  const char *zVfs;
  sqlite3 *db;




  if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
  zVfs = fossil_getenv("FOSSIL_VFS");
  rc = sqlite3_open_v2(
       zDbName, &db,
       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
       zVfs
  );







>
>
>







710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
** connection.  An error results in process abort.
*/
LOCAL sqlite3 *db_open(const char *zDbName){
  int rc;
  const char *zVfs;
  sqlite3 *db;

#if defined(__CYGWIN__)
  zDbName = fossil_utf8_to_filename(zDbName);
#endif
  if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
  zVfs = fossil_getenv("FOSSIL_VFS");
  rc = sqlite3_open_v2(
       zDbName, &db,
       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
       zVfs
  );
1018
1019
1020
1021
1022
1023
1024





1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
    }else{
#ifdef FOSSIL_ENABLE_JSON
      g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
#endif
      fossil_panic("not a valid repository: %s", zDbName);
    }
  }





  db_open_or_attach(zDbName, "repository", 0);
  g.repositoryOpen = 1;
  g.zRepositoryName = mprintf("%s", zDbName);
  /* Cache "allow-symlinks" option, because we'll need it on every stat call */
  g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
}

/*
** Flags for the db_find_and_open_repository() function.
*/







>
>
>
>
>
|

<







1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041
    }else{
#ifdef FOSSIL_ENABLE_JSON
      g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
#endif
      fossil_panic("not a valid repository: %s", zDbName);
    }
  }
#if defined(__CYGWIN__)
  g.zRepositoryName = fossil_utf8_to_filename(zDbName);
#else
  g.zRepositoryName = mprintf("%s", zDbName);
#endif
  db_open_or_attach(g.zRepositoryName, "repository", 0);
  g.repositoryOpen = 1;

  /* Cache "allow-symlinks" option, because we'll need it on every stat call */
  g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
}

/*
** Flags for the db_find_and_open_repository() function.
*/
1391
1392
1393
1394
1395
1396
1397
1398
1399



1400
1401
1402
1403
1404
1405
1406

  if( zInitialDate ){
    int rid;
    blob_zero(&manifest);
    blob_appendf(&manifest, "C initial\\sempty\\scheck-in\n");
    zDate = date_in_standard_format(zInitialDate);
    blob_appendf(&manifest, "D %s\n", zDate);
    blob_appendf(&manifest, "P\n");
    md5sum_init();



    blob_appendf(&manifest, "R %s\n", md5sum_finish(0));
    blob_appendf(&manifest, "T *branch * trunk\n");
    blob_appendf(&manifest, "T *sym-trunk *\n");
    blob_appendf(&manifest, "U %F\n", g.zLogin);
    md5sum_blob(&manifest, &hash);
    blob_appendf(&manifest, "Z %b\n", &hash);
    blob_reset(&hash);







<

>
>
>







1398
1399
1400
1401
1402
1403
1404

1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415

  if( zInitialDate ){
    int rid;
    blob_zero(&manifest);
    blob_appendf(&manifest, "C initial\\sempty\\scheck-in\n");
    zDate = date_in_standard_format(zInitialDate);
    blob_appendf(&manifest, "D %s\n", zDate);

    md5sum_init();
    /* The R-card is necessary here because without it
     * fossil versions earlier than versions 1.27 would
     * interpret this artifact as a "control". */
    blob_appendf(&manifest, "R %s\n", md5sum_finish(0));
    blob_appendf(&manifest, "T *branch * trunk\n");
    blob_appendf(&manifest, "T *sym-trunk *\n");
    blob_appendf(&manifest, "U %F\n", g.zLogin);
    md5sum_blob(&manifest, &hash);
    blob_appendf(&manifest, "Z %b\n", &hash);
    blob_reset(&hash);
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
  url_proxy_options();
  keepFlag = find_option("keep",0,0)!=0;
  allowNested = find_option("nested",0,0)!=0;
  if( g.argc!=3 && g.argc!=4 ){
    usage("REPOSITORY-FILENAME ?VERSION?");
  }
  if( !allowNested && db_open_local(0) ){
    fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
  }
  db_open_repository(g.argv[2]);
#if defined(_WIN32) || defined(__CYGWIN__)
# define LOCALDB_NAME "./_FOSSIL_"
#else
# define LOCALDB_NAME "./.fslckout"
#endif







|







1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
  url_proxy_options();
  keepFlag = find_option("keep",0,0)!=0;
  allowNested = find_option("nested",0,0)!=0;
  if( g.argc!=3 && g.argc!=4 ){
    usage("REPOSITORY-FILENAME ?VERSION?");
  }
  if( !allowNested && db_open_local(0) ){
    fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot);
  }
  db_open_repository(g.argv[2]);
#if defined(_WIN32) || defined(__CYGWIN__)
# define LOCALDB_NAME "./_FOSSIL_"
#else
# define LOCALDB_NAME "./.fslckout"
#endif
Changes to src/deltacmd.c.
142
143
144
145
146
147
148
149
150
151
152
  blob_read_from_file(&f1, g.argv[2]);
  blob_read_from_file(&f2, g.argv[3]);
  blob_delta_create(&f1, &f2, &d12);
  blob_delta_create(&f2, &f1, &d21);
  blob_delta_apply(&f1, &d12, &a2);
  blob_delta_apply(&f2, &d21, &a1);
  if( blob_compare(&f1,&a1) || blob_compare(&f2, &a2) ){
    fossil_panic("delta test failed");
  }
  fossil_print("ok\n");
}







|



142
143
144
145
146
147
148
149
150
151
152
  blob_read_from_file(&f1, g.argv[2]);
  blob_read_from_file(&f2, g.argv[3]);
  blob_delta_create(&f1, &f2, &d12);
  blob_delta_create(&f2, &f1, &d21);
  blob_delta_apply(&f1, &d12, &a2);
  blob_delta_apply(&f2, &d21, &a1);
  if( blob_compare(&f1,&a1) || blob_compare(&f2, &a2) ){
    fossil_fatal("delta test failed");
  }
  fossil_print("ok\n");
}
Changes to src/diff.c.
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
  char cPrefix,       /* One of " ", "+",  or "-" */
  DLine *pLine,       /* The line to be output */
  int html,           /* True if generating HTML.  False for plain text */
  ReCompiled *pRe     /* Colorize only if line matches this Regex */
){
  blob_append(pOut, &cPrefix, 1);
  if( html ){
    char *zHtml;
    if( pRe && re_dline_match(pRe, pLine, 1)==0 ){
      cPrefix = ' ';
    }else if( cPrefix=='+' ){
      blob_append(pOut, "<span class=\"diffadd\">", -1);
    }else if( cPrefix=='-' ){
      blob_append(pOut, "<span class=\"diffrm\">", -1);
    }
    zHtml = htmlize(pLine->z, (pLine->h & LENGTH_MASK));
    blob_append(pOut, zHtml, -1);
    fossil_free(zHtml);
    if( cPrefix!=' ' ){
      blob_append(pOut, "</span>", -1);
    }
  }else{
    blob_append(pOut, pLine->z, pLine->h & LENGTH_MASK);
  }
  blob_append(pOut, "\n", 1);







<







|
<
<







212
213
214
215
216
217
218

219
220
221
222
223
224
225
226


227
228
229
230
231
232
233
  char cPrefix,       /* One of " ", "+",  or "-" */
  DLine *pLine,       /* The line to be output */
  int html,           /* True if generating HTML.  False for plain text */
  ReCompiled *pRe     /* Colorize only if line matches this Regex */
){
  blob_append(pOut, &cPrefix, 1);
  if( html ){

    if( pRe && re_dline_match(pRe, pLine, 1)==0 ){
      cPrefix = ' ';
    }else if( cPrefix=='+' ){
      blob_append(pOut, "<span class=\"diffadd\">", -1);
    }else if( cPrefix=='-' ){
      blob_append(pOut, "<span class=\"diffrm\">", -1);
    }
    htmlize_to_blob(pOut, pLine->z, (pLine->h & LENGTH_MASK));


    if( cPrefix!=' ' ){
      blob_append(pOut, "</span>", -1);
    }
  }else{
    blob_append(pOut, pLine->z, pLine->h & LENGTH_MASK);
  }
  blob_append(pOut, "\n", 1);
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
      sbsWriteMarker(&s, "   ", "");
      sbsWriteLineno(&s, b+j, SBS_LNB);
      sbsWriteText(&s, &B[b+j], SBS_TXTB);
    }
  }
  
  if( s.escHtml && blob_size(s.apCols[SBS_LNA])>0 ){
    blob_append(pOut, "<table class=\"sbsdiffcols\" width=\"90%\"><tr>\n", -1);
    for(i=SBS_LNA; i<=SBS_TXTB; i++){
      sbsWriteColumn(pOut, s.apCols[i], i);
      blob_reset(s.apCols[i]);
    }
    blob_append(pOut, "</tr></table>\n", -1);
  }
}







|







1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
      sbsWriteMarker(&s, "   ", "");
      sbsWriteLineno(&s, b+j, SBS_LNB);
      sbsWriteText(&s, &B[b+j], SBS_TXTB);
    }
  }
  
  if( s.escHtml && blob_size(s.apCols[SBS_LNA])>0 ){
    blob_append(pOut, "<table class=\"sbsdiffcols\"><tr>\n", -1);
    for(i=SBS_LNA; i<=SBS_TXTB; i++){
      sbsWriteColumn(pOut, s.apCols[i], i);
      blob_reset(s.apCols[i]);
    }
    blob_append(pOut, "</tr></table>\n", -1);
  }
}
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
  Stmt q;              /* Query returning all ancestor versions */
  Stmt ins;            /* Inserts into the temporary VSEEN table */
  int cnt = 0;         /* Number of versions examined */

  /* Initialize the annotation */
  rid = db_int(0, "SELECT fid FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid);
  if( rid==0 ){
    fossil_panic("file #%d is unchanged in manifest #%d", fnid, mid);
  }
  if( !content_get(rid, &toAnnotate) ){
    fossil_panic("unable to retrieve content of artifact #%d", rid);
  }
  if( iLimit<=0 ) iLimit = 1000000000;
  annotation_start(p, &toAnnotate);
  db_begin_transaction();
  db_multi_exec(
     "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);"
     "DELETE FROM vseen;"







|


|







2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
  Stmt q;              /* Query returning all ancestor versions */
  Stmt ins;            /* Inserts into the temporary VSEEN table */
  int cnt = 0;         /* Number of versions examined */

  /* Initialize the annotation */
  rid = db_int(0, "SELECT fid FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid);
  if( rid==0 ){
    fossil_fatal("file #%d is unchanged in manifest #%d", fnid, mid);
  }
  if( !content_get(rid, &toAnnotate) ){
    fossil_fatal("unable to retrieve content of artifact #%d", rid);
  }
  if( iLimit<=0 ) iLimit = 1000000000;
  annotation_start(p, &toAnnotate);
  db_begin_transaction();
  db_multi_exec(
     "CREATE TEMP TABLE IF NOT EXISTS vseen(rid INTEGER PRIMARY KEY);"
     "DELETE FROM vseen;"
2148
2149
2150
2151
2152
2153
2154

2155
2156
2157
2158
2159
2160
2161
  struct AnnVers *p;
  unsigned clr1, clr2, clr;

  /* Gather query parameters */
  showLog = atoi(PD("log","1"));
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }

  mid = name_to_typed_rid(PD("checkin","0"),"ci");
  zFilename = P("filename");
  fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
  if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
  iLimit = atoi(PD("limit","20"));
  if( P("filevers") ) annFlags |= ANN_FILE_VERS;
  if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){







>







2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
  struct AnnVers *p;
  unsigned clr1, clr2, clr;

  /* Gather query parameters */
  showLog = atoi(PD("log","1"));
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( exclude_spiders("annotate") ) return;
  mid = name_to_typed_rid(PD("checkin","0"),"ci");
  zFilename = P("filename");
  fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
  if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
  iLimit = atoi(PD("limit","20"));
  if( P("filevers") ) annFlags |= ANN_FILE_VERS;
  if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
  if( iLimit<=0 ) iLimit = 1000000000;
  compute_direct_ancestors(cid, 1000000);
  mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
          " WHERE mlink.fid=%d AND mlink.fnid=%d AND mlink.mid=ancestor.rid"
          " ORDER BY ancestor.generation ASC LIMIT 1",
          fid, fnid);
  if( mid==0 ){
    fossil_panic("unable to find manifest");
  }
  annFlags |= ANN_FILE_ANCEST;
  annotate_file(&ann, fnid, mid, iLimit, annFlags);
  if( showLog ){
    struct AnnVers *p;
    for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
      fossil_print("version %3d: %s %.10s file %.10s\n",







|







2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
  if( iLimit<=0 ) iLimit = 1000000000;
  compute_direct_ancestors(cid, 1000000);
  mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
          " WHERE mlink.fid=%d AND mlink.fnid=%d AND mlink.mid=ancestor.rid"
          " ORDER BY ancestor.generation ASC LIMIT 1",
          fid, fnid);
  if( mid==0 ){
    fossil_fatal("unable to find manifest");
  }
  annFlags |= ANN_FILE_ANCEST;
  annotate_file(&ann, fnid, mid, iLimit, annFlags);
  if( showLog ){
    struct AnnVers *p;
    for(p=ann.aVers, i=0; i<ann.nVers; i++, p++){
      fossil_print("version %3d: %s %.10s file %.10s\n",
Changes to src/diffcmd.c.
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
@   RM_BG      #ffc0c0
@   HR_FG      #888888
@   HR_PAD_TOP 4
@   HR_PAD_BTM 8
@   FN_BG      #444444
@   FN_FG      #ffffff
@   FN_PAD     5
@   FONTS      {{DejaVu Sans Mono} Consolas Monaco}
@   FONT_SIZE  9
@   PADX       5
@   WIDTH      80
@   HEIGHT     45
@   LB_HEIGHT  25
@ }
@ 
@ if {![namespace exists ttk]} {







<
<







615
616
617
618
619
620
621


622
623
624
625
626
627
628
@   RM_BG      #ffc0c0
@   HR_FG      #888888
@   HR_PAD_TOP 4
@   HR_PAD_BTM 8
@   FN_BG      #444444
@   FN_FG      #ffffff
@   FN_PAD     5


@   PADX       5
@   WIDTH      80
@   HEIGHT     45
@   LB_HEIGHT  25
@ }
@ 
@ if {![namespace exists ttk]} {
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881

882
883
884
885
886
887
888
889
890
@     $txt tag lower $tag
@   }
@   $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
@     -justify center
@ }
@ text .mkr
@ 
@ font create mono -family courier -size $CFG(FONT_SIZE)
@ foreach font $CFG(FONTS) {
@   if {[lsearch -exact [font families] $font] != -1} {
@      font config mono -family $font
@      break
@   }
@ }
@ foreach c [cols] {
@   set keyPrefix [string toupper [colType $c]]_COL_

@   $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \
@     -font mono -padx $CFG(PADX) -yscroll sync-y
@   $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \
@      -foreground $CFG(HR_FG)
@   $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD)
@   bindtags $c ". $c Text all"
@   bind $c <1> {focus %W}
@ }
@ 







<
<
<
<
<
<
<


>

|







864
865
866
867
868
869
870







871
872
873
874
875
876
877
878
879
880
881
882
@     $txt tag lower $tag
@   }
@   $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
@     -justify center
@ }
@ text .mkr
@ 







@ foreach c [cols] {
@   set keyPrefix [string toupper [colType $c]]_COL_
@   if {[tk windowingsystem] eq "win32"} {$c config -font {courier 9}}
@   $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \
@     -padx $CFG(PADX) -yscroll sync-y
@   $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \
@      -foreground $CFG(HR_FG)
@   $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD)
@   bindtags $c ". $c Text all"
@   bind $c <1> {focus %W}
@ }
@ 
Changes to src/encode.c.
159
160
161
162
163
164
165

166
167
168
169
170
171
172
      zOut[i++] = '%';
      zOut[i++] = "0123456789ABCDEF"[(c>>4)&0xf];
      zOut[i++] = "0123456789ABCDEF"[c&0xf];
    }
    zIn++;
  }
  zOut[i] = 0;

  return zOut;
}

/*
** Convert the input string into a form that is suitable for use as
** a token in the HTTP protocol.  Spaces are encoded as '+' and special
** characters are encoded as "%HH" where HH is a two-digit hexadecimal







>







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
      zOut[i++] = '%';
      zOut[i++] = "0123456789ABCDEF"[(c>>4)&0xf];
      zOut[i++] = "0123456789ABCDEF"[c&0xf];
    }
    zIn++;
  }
  zOut[i] = 0;
#undef IsSafeChar
  return zOut;
}

/*
** Convert the input string into a form that is suitable for use as
** a token in the HTTP protocol.  Spaces are encoded as '+' and special
** characters are encoded as "%HH" where HH is a two-digit hexadecimal
Changes to src/event.c.
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  }
  verboseFlag = (zVerbose!=0) && !is_false(zVerbose);

  /* Extract the event content.
  */
  pEvent = manifest_get(rid, CFTYPE_EVENT);
  if( pEvent==0 ){
    fossil_panic("Object #%d is not an event", rid);
  }
  blob_init(&fullbody, pEvent->zWiki, -1);
  if( wiki_find_title(&fullbody, &title, &tail) ){
    style_header(blob_str(&title));
  }else{
    style_header("Event %S", zEventId);
    tail = fullbody;







|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  }
  verboseFlag = (zVerbose!=0) && !is_false(zVerbose);

  /* Extract the event content.
  */
  pEvent = manifest_get(rid, CFTYPE_EVENT);
  if( pEvent==0 ){
    fossil_fatal("Object #%d is not an event", rid);
  }
  blob_init(&fullbody, pEvent->zWiki, -1);
  if( wiki_find_title(&fullbody, &title, &tail) ){
    style_header(blob_str(&title));
  }else{
    style_header("Event %S", zEventId);
    tail = fullbody;
278
279
280
281
282
283
284
285
286
287
288




289

290
291
292
293
294
295
296
      );
    }
  }
  zETime = db_text(0, "SELECT coalesce(datetime(%Q),datetime('now'))", zETime);
  if( P("submit")!=0 && (zBody!=0 && zComment!=0) ){
    char *zDate;
    Blob cksum;
    int nrid;
    blob_zero(&event);
    db_begin_transaction();
    login_verify_csrf_secret();




    blob_appendf(&event, "C %F\n", zComment);

    zDate = date_in_standard_format("now");
    blob_appendf(&event, "D %s\n", zDate);
    free(zDate);
    zETime[10] = 'T';
    blob_appendf(&event, "E %s %s\n", zETime, zEventId);
    zETime[10] = ' ';
    if( rid ){







|



>
>
>
>
|
>







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
      );
    }
  }
  zETime = db_text(0, "SELECT coalesce(datetime(%Q),datetime('now'))", zETime);
  if( P("submit")!=0 && (zBody!=0 && zComment!=0) ){
    char *zDate;
    Blob cksum;
    int nrid, n;
    blob_zero(&event);
    db_begin_transaction();
    login_verify_csrf_secret();
    while( fossil_isspace(zComment[0]) ) zComment++;
    n = strlen(zComment);
    while( n>0 && fossil_isspace(zComment[n-1]) ){ n--; }
    if( n>0 ){
      blob_appendf(&event, "C %#F\n", n, zComment);
    }
    zDate = date_in_standard_format("now");
    blob_appendf(&event, "D %s\n", zDate);
    free(zDate);
    zETime[10] = 'T';
    blob_appendf(&event, "E %s %s\n", zETime, zEventId);
    zETime[10] = ' ';
    if( rid ){
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
  if( n<20 ) n = 20;
  if( n>40 ) n = 40;
  @ <form method="post" action="%s(g.zTop)/eventedit"><div>
  login_insert_csrf_secret();
  @ <input type="hidden" name="name" value="%h(zEventId)" />
  @ <table border="0" cellspacing="10">

  @ <tr><td align="right" valign="top"><b>Event&nbsp;Time:</b></td>
  @ <td valign="top">
  @   <input type="text" name="t" size="25" value="%h(zETime)" />
  @ </td></tr>

  @ <tr><td align="right" valign="top"><b>Timeline&nbsp;Comment:</b></td>
  @ <td valign="top">
  @ <textarea name="c" class="eventedit" cols="80" 
  @  rows="3" wrap="virtual">%h(zComment)</textarea>
  @ </td></tr>

  @ <tr><td align="right" valign="top"><b>Background&nbsp;Color:</b></td>
  @ <td valign="top">
  render_color_chooser(0, zClr, 0, "clr", "cclr");
  @ </td></tr>
  
  @ <tr><td align="right" valign="top"><b>Tags:</b></td>
  @ <td valign="top">
  @   <input type="text" name="g" size="40" value="%h(zTags)" />
  @ </td></tr>
  
  @ <tr><td align="right" valign="top"><b>Page&nbsp;Content:</b></td>
  @ <td valign="top">
  @ <textarea name="w" class="eventedit" cols="80" 
  @  rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
  @ </td></tr>

  @ <tr><td colspan="2">
  @ <input type="submit" name="preview" value="Preview Your Changes" />
  @ <input type="submit" name="submit" value="Apply These Changes" />
  @ <input type="submit" name="cancel" value="Cancel" />
  @ </td></tr></table>
  @ </div></form>
  style_footer();
}







|




|





|




|




|













402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
  if( n<20 ) n = 20;
  if( n>40 ) n = 40;
  @ <form method="post" action="%s(g.zTop)/eventedit"><div>
  login_insert_csrf_secret();
  @ <input type="hidden" name="name" value="%h(zEventId)" />
  @ <table border="0" cellspacing="10">

  @ <tr><th align="right" valign="top">Event&nbsp;Time (UTC):</th>
  @ <td valign="top">
  @   <input type="text" name="t" size="25" value="%h(zETime)" />
  @ </td></tr>

  @ <tr><th align="right" valign="top">Timeline&nbsp;Comment:</th>
  @ <td valign="top">
  @ <textarea name="c" class="eventedit" cols="80" 
  @  rows="3" wrap="virtual">%h(zComment)</textarea>
  @ </td></tr>

  @ <tr><th align="right" valign="top">Background&nbsp;Color:</th>
  @ <td valign="top">
  render_color_chooser(0, zClr, 0, "clr", "cclr");
  @ </td></tr>
  
  @ <tr><th align="right" valign="top">Tags:</th>
  @ <td valign="top">
  @   <input type="text" name="g" size="40" value="%h(zTags)" />
  @ </td></tr>
  
  @ <tr><th align="right" valign="top">Page&nbsp;Content:</th>
  @ <td valign="top">
  @ <textarea name="w" class="eventedit" cols="80" 
  @  rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
  @ </td></tr>

  @ <tr><td colspan="2">
  @ <input type="submit" name="preview" value="Preview Your Changes" />
  @ <input type="submit" name="submit" value="Apply These Changes" />
  @ <input type="submit" name="cancel" value="Cancel" />
  @ </td></tr></table>
  @ </div></form>
  style_footer();
}
Changes to src/export.c.
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
  if( markfile_in!=0 ){
    Stmt qb,qc;
    char line[100];
    FILE *f;

    f = fossil_fopen(markfile_in, "r");
    if( f==0 ){
      fossil_panic("cannot open %s for reading", markfile_in);
    }
    db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)");
    db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)");
    while( fgets(line, sizeof(line), f)!=0 ){
      if( *line == 'b' ){
        db_bind_text(&qb, ":rid", line + 1);
        db_step(&qb);
        db_reset(&qb);
        bag_insert(&blobs, atoi(line + 1));
      }else if( *line == 'c' ){
        db_bind_text(&qc, ":rid", line + 1);
        db_step(&qc);
        db_reset(&qc);
        bag_insert(&vers, atoi(line + 1));
      }else{
        fossil_panic("bad input from %s: %s", markfile_in, line);
      }
    }
    db_finalize(&qb);
    db_finalize(&qc);
    fclose(f);
  }








|















|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
  if( markfile_in!=0 ){
    Stmt qb,qc;
    char line[100];
    FILE *f;

    f = fossil_fopen(markfile_in, "r");
    if( f==0 ){
      fossil_fatal("cannot open %s for reading", markfile_in);
    }
    db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)");
    db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)");
    while( fgets(line, sizeof(line), f)!=0 ){
      if( *line == 'b' ){
        db_bind_text(&qb, ":rid", line + 1);
        db_step(&qb);
        db_reset(&qb);
        bag_insert(&blobs, atoi(line + 1));
      }else if( *line == 'c' ){
        db_bind_text(&qc, ":rid", line + 1);
        db_step(&qc);
        db_reset(&qc);
        bag_insert(&vers, atoi(line + 1));
      }else{
        fossil_fatal("bad input from %s: %s", markfile_in, line);
      }
    }
    db_finalize(&qb);
    db_finalize(&qc);
    fclose(f);
  }

333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
  db_finalize(&q);
  bag_clear(&vers);

  if( markfile_out!=0 ){
    FILE *f;
    f = fossil_fopen(markfile_out, "w");
    if( f == 0 ){
      fossil_panic("cannot open %s for writing", markfile_out);
    }
    db_prepare(&q, "SELECT rid FROM oldblob");
    while( db_step(&q)==SQLITE_ROW ){
      fprintf(f, "b%d\n", db_column_int(&q, 0));
    }
    db_finalize(&q);
    db_prepare(&q, "SELECT rid FROM oldcommit");
    while( db_step(&q)==SQLITE_ROW ){
      fprintf(f, "c%d\n", db_column_int(&q, 0));
    }
    db_finalize(&q);
    if( ferror(f)!=0 || fclose(f)!=0 ) {
      fossil_panic("error while writing %s", markfile_out);
    }
  }
}







|












|



333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
  db_finalize(&q);
  bag_clear(&vers);

  if( markfile_out!=0 ){
    FILE *f;
    f = fossil_fopen(markfile_out, "w");
    if( f == 0 ){
      fossil_fatal("cannot open %s for writing", markfile_out);
    }
    db_prepare(&q, "SELECT rid FROM oldblob");
    while( db_step(&q)==SQLITE_ROW ){
      fprintf(f, "b%d\n", db_column_int(&q, 0));
    }
    db_finalize(&q);
    db_prepare(&q, "SELECT rid FROM oldcommit");
    while( db_step(&q)==SQLITE_ROW ){
      fprintf(f, "c%d\n", db_column_int(&q, 0));
    }
    db_finalize(&q);
    if( ferror(f)!=0 || fclose(f)!=0 ) {
      fossil_fatal("error while writing %s", markfile_out);
    }
  }
}
Changes to src/finfo.c.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    Blob line;
    Blob fname;
    int vid;

    if( g.argc!=3 ) usage("-s|--status FILENAME");
    vid = db_lget_int("checkout", 0);
    if( vid==0 ){
      fossil_panic("no checkout to finfo files in");
    }
    vfile_check_signature(vid, CKSIG_ENOTFILE);
    file_tree_name(g.argv[2], &fname, 1);
    db_prepare(&q,
        "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
        "  FROM vfile WHERE vfile.pathname=%B %s",
        &fname, filename_collation());







|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
    Blob line;
    Blob fname;
    int vid;

    if( g.argc!=3 ) usage("-s|--status FILENAME");
    vid = db_lget_int("checkout", 0);
    if( vid==0 ){
      fossil_fatal("no checkout to finfo files in");
    }
    vfile_check_signature(vid, CKSIG_ENOTFILE);
    file_tree_name(g.argv[2], &fname, 1);
    db_prepare(&q,
        "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
        "  FROM vfile WHERE vfile.pathname=%B %s",
        &fname, filename_collation());
Changes to src/glob.c.
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
**
** Usage:  %fossil test-glob PATTERN STRING...
**
** PATTERN is a comma- and whitespace-separated list of optionally
** quoted glob patterns.  Show which of the STRINGs that follow match
** the PATTERN.
**
** If PATTERN begins with "@" the the rest of the pattern is understood
** to be a setting name (such as binary-glob, crln-glob, or encoding-glob)
** and the value of that setting is used as the actually glob pattern.
*/
void glob_test_cmd(void){
  Glob *pGlob;
  int i;
  char *zPattern;







|







250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
**
** Usage:  %fossil test-glob PATTERN STRING...
**
** PATTERN is a comma- and whitespace-separated list of optionally
** quoted glob patterns.  Show which of the STRINGs that follow match
** the PATTERN.
**
** If PATTERN begins with "@" the rest of the pattern is understood
** to be a setting name (such as binary-glob, crln-glob, or encoding-glob)
** and the value of that setting is used as the actually glob pattern.
*/
void glob_test_cmd(void){
  Glob *pGlob;
  int i;
  char *zPattern;
Changes to src/graph.c.
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  pRow->rid = rid;
  pRow->nParent = nParent;
  pRow->zBranch = persistBranchName(p, zBranch);
  if( zUuid==0 ) zUuid = "";
  sqlite3_snprintf(sizeof(pRow->zUuid), pRow->zUuid, "%s", zUuid);
  pRow->isLeaf = isLeaf;
  memset(pRow->aiRiser, -1, sizeof(pRow->aiRiser));
  if( zBgClr==0 || zBgClr[0]==0 ) zBgClr = "white";
  pRow->zBgClr = persistBranchName(p, zBgClr);
  memcpy(pRow->aParent, aParent, sizeof(aParent[0])*nParent);
  if( p->pFirst==0 ){
    p->pFirst = pRow;
  }else{
    p->pLast->pNext = pRow;
  }







|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  pRow->rid = rid;
  pRow->nParent = nParent;
  pRow->zBranch = persistBranchName(p, zBranch);
  if( zUuid==0 ) zUuid = "";
  sqlite3_snprintf(sizeof(pRow->zUuid), pRow->zUuid, "%s", zUuid);
  pRow->isLeaf = isLeaf;
  memset(pRow->aiRiser, -1, sizeof(pRow->aiRiser));
  if( zBgClr==0 ) zBgClr = "";
  pRow->zBgClr = persistBranchName(p, zBgClr);
  memcpy(pRow->aParent, aParent, sizeof(aParent[0])*nParent);
  if( p->pFirst==0 ){
    p->pFirst = pRow;
  }else{
    p->pLast->pNext = pRow;
  }
Changes to src/http_transport.c.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  i64 nSent;              /* Number of bytes sent */
  i64 nRcvd;              /* Number of bytes received */
  FILE *pFile;            /* File I/O for FILE: */
  char *zOutFile;         /* Name of outbound file for FILE: */
  char *zInFile;          /* Name of inbound file for FILE: */
  FILE *pLog;             /* Log output here */
} transport = {
  0, 0, 0, 0, 0, 0, 0
};

/*
** Information about the connection to the SSH subprocess when
** using the ssh:// sync method.
*/
static int sshPid;             /* Process id of ssh subprocess */







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  i64 nSent;              /* Number of bytes sent */
  i64 nRcvd;              /* Number of bytes received */
  FILE *pFile;            /* File I/O for FILE: */
  char *zOutFile;         /* Name of outbound file for FILE: */
  char *zInFile;          /* Name of inbound file for FILE: */
  FILE *pLog;             /* Log output here */
} transport = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

/*
** Information about the connection to the SSH subprocess when
** using the ssh:// sync method.
*/
static int sshPid;             /* Process id of ssh subprocess */
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
      #else
      socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
      rc = 1;
      #endif
    }else if( g.urlIsFile ){
      sqlite3_uint64 iRandId;
      sqlite3_randomness(sizeof(iRandId), &iRandId);
      transport.zOutFile = mprintf("%s-%llu-out.http", 
                                       g.zRepositoryName, iRandId);
      transport.zInFile = mprintf("%s-%llu-in.http", 
                                       g.zRepositoryName, iRandId);
      transport.pFile = fossil_fopen(transport.zOutFile, "wb");
      if( transport.pFile==0 ){
        fossil_fatal("cannot output temporary file: %s", transport.zOutFile);
      }
      transport.isOpen = 1;
    }else{







|

|







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
      #else
      socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
      rc = 1;
      #endif
    }else if( g.urlIsFile ){
      sqlite3_uint64 iRandId;
      sqlite3_randomness(sizeof(iRandId), &iRandId);
      transport.zOutFile = mprintf("%s-%llu-out.http",
                                       g.zRepositoryName, iRandId);
      transport.zInFile = mprintf("%s-%llu-in.http",
                                       g.zRepositoryName, iRandId);
      transport.pFile = fossil_fopen(transport.zOutFile, "wb");
      if( transport.pFile==0 ){
        fossil_fatal("cannot output temporary file: %s", transport.zOutFile);
      }
      transport.isOpen = 1;
    }else{
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
    if( g.urlIsSsh ){
      /* No-op */
    }else if( g.urlIsHttps ){
      #ifdef FOSSIL_ENABLE_SSL
      ssl_close();
      #endif
    }else if( g.urlIsFile ){
      if( transport.pFile ){ 
        fclose(transport.pFile);
        transport.pFile = 0;
      }
      file_delete(transport.zInFile);
      file_delete(transport.zOutFile);
      free(transport.zInFile);
      free(transport.zOutFile);







|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
    if( g.urlIsSsh ){
      /* No-op */
    }else if( g.urlIsHttps ){
      #ifdef FOSSIL_ENABLE_SSL
      ssl_close();
      #endif
    }else if( g.urlIsFile ){
      if( transport.pFile ){
        fclose(transport.pFile);
        transport.pFile = 0;
      }
      file_delete(transport.zInFile);
      file_delete(transport.zOutFile);
      free(transport.zInFile);
      free(transport.zOutFile);
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
    #ifdef FOSSIL_ENABLE_SSL
    int sent;
    while( n>0 ){
      sent = ssl_send(0, z, n);
      /* printf("Sent %d of %d bytes\n", sent, n); fflush(stdout); */
      if( sent<=0 ) break;
      n -= sent;
    }    
    #endif
  }else if( g.urlIsFile ){
    fwrite(z, 1, n, transport.pFile);
  }else{
    int sent;
    while( n>0 ){
      sent = socket_send(0, z, n);







|







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
    #ifdef FOSSIL_ENABLE_SSL
    int sent;
    while( n>0 ){
      sent = ssl_send(0, z, n);
      /* printf("Sent %d of %d bytes\n", sent, n); fflush(stdout); */
      if( sent<=0 ) break;
      n -= sent;
    }
    #endif
  }else if( g.urlIsFile ){
    fwrite(z, 1, n, transport.pFile);
  }else{
    int sent;
    while( n>0 ){
      sent = socket_send(0, z, n);
Changes to src/info.c.
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    }
    fossil_print("checkins:     %d\n",
                 db_int(-1, "SELECT count(*) FROM event WHERE type='ci' /*scan*/"));
  }else{
    int rid;
    rid = name_to_rid(g.argv[2]);
    if( rid==0 ){
      fossil_panic("no such object: %s\n", g.argv[2]);
    }
    show_common_info(rid, "uuid:", 1, 1);
  }
}

/*
** Show information about all tags on a given node.







|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
    }
    fossil_print("checkins:     %d\n",
                 db_int(-1, "SELECT count(*) FROM event WHERE type='ci' /*scan*/"));
  }else{
    int rid;
    rid = name_to_rid(g.argv[2]);
    if( rid==0 ){
      fossil_fatal("no such object: %s\n", g.argv[2]);
    }
    show_common_info(rid, "uuid:", 1, 1);
  }
}

/*
** Show information about all tags on a given node.
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
** If the /ci page is used (instead of /vinfo or /info) then the
** default behavior is to show unified diffs of all file changes.
** With /vinfo and /info, only a list of the changed files are
** shown, without diffs.  This behavior is inverted if the
** "show-version-diffs" setting is turned on.
*/
void ci_page(void){
  Stmt q;
  int rid;
  int isLeaf;
  int verboseFlag;     /* True to show diffs */
  int sideBySide;      /* True for side-by-side diffs */
  u64 diffFlags;       /* Flag parameter for text_diff() */
  const char *zName;   /* Name of the checkin to be displayed */
  const char *zUuid;   /* UUID of zName */







|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
** If the /ci page is used (instead of /vinfo or /info) then the
** default behavior is to show unified diffs of all file changes.
** With /vinfo and /info, only a list of the changed files are
** shown, without diffs.  This behavior is inverted if the
** "show-version-diffs" setting is turned on.
*/
void ci_page(void){
  Stmt q1, q2, q3;
  int rid;
  int isLeaf;
  int verboseFlag;     /* True to show diffs */
  int sideBySide;      /* True for side-by-side diffs */
  u64 diffFlags;       /* Flag parameter for text_diff() */
  const char *zName;   /* Name of the checkin to be displayed */
  const char *zUuid;   /* UUID of zName */
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
  zParent = db_text(0,
    "SELECT uuid FROM plink, blob"
    " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim",
    rid
  );
  isLeaf = is_a_leaf(rid);
  db_prepare(&q,
     "SELECT uuid, datetime(mtime, 'localtime'), user, comment,"
     "       datetime(omtime, 'localtime'), mtime"
     "  FROM blob, event"
     " WHERE blob.rid=%d"
     "   AND event.objid=%d",
     rid, rid
  );
  sideBySide = !is_false(PD("sbs","1"));
  if( db_step(&q)==SQLITE_ROW ){
    const char *zUuid = db_column_text(&q, 0);
    char *zTitle = mprintf("Check-in [%.10s]", zUuid);
    char *zEUser, *zEComment;
    const char *zUser;
    const char *zComment;
    const char *zDate;
    const char *zOrigDate;

    style_header(zTitle);
    login_anonymous_available();
    free(zTitle);
    zEUser = db_text(0,
                   "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                    TAG_USER, rid);
    zEComment = db_text(0,
                   "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                   TAG_COMMENT, rid);
    zUser = db_column_text(&q, 2);
    zComment = db_column_text(&q, 3);
    zDate = db_column_text(&q,1);
    zOrigDate = db_column_text(&q, 4);
    @ <div class="section">Overview</div>
    @ <table class="label-value">
    @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
    if( g.perm.Setup ){
      @ (Record ID: %d(rid))
    }
    @ </td></tr>







|








|
|
















|
|
|
|







500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
  zParent = db_text(0,
    "SELECT uuid FROM plink, blob"
    " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim",
    rid
  );
  isLeaf = is_a_leaf(rid);
  db_prepare(&q1,
     "SELECT uuid, datetime(mtime, 'localtime'), user, comment,"
     "       datetime(omtime, 'localtime'), mtime"
     "  FROM blob, event"
     " WHERE blob.rid=%d"
     "   AND event.objid=%d",
     rid, rid
  );
  sideBySide = !is_false(PD("sbs","1"));
  if( db_step(&q1)==SQLITE_ROW ){
    const char *zUuid = db_column_text(&q1, 0);
    char *zTitle = mprintf("Check-in [%.10s]", zUuid);
    char *zEUser, *zEComment;
    const char *zUser;
    const char *zComment;
    const char *zDate;
    const char *zOrigDate;

    style_header(zTitle);
    login_anonymous_available();
    free(zTitle);
    zEUser = db_text(0,
                   "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                    TAG_USER, rid);
    zEComment = db_text(0,
                   "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                   TAG_COMMENT, rid);
    zUser = db_column_text(&q1, 2);
    zComment = db_column_text(&q1, 3);
    zDate = db_column_text(&q1,1);
    zOrigDate = db_column_text(&q1, 4);
    @ <div class="section">Overview</div>
    @ <table class="label-value">
    @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
    if( g.perm.Setup ){
      @ (Record ID: %d(rid))
    }
    @ </td></tr>
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
    if( zEComment ){
      @ <tr><th>Edited&nbsp;Comment:</th><td class="infoComment">%!w(zEComment)</td></tr>
      @ <tr><th>Original&nbsp;Comment:</th><td class="infoComment">%!w(zComment)</td></tr>
    }else{
      @ <tr><th>Comment:</th><td class="infoComment">%!w(zComment)</td></tr>
    }
    if( g.perm.Admin ){
      db_prepare(&q,
         "SELECT rcvfrom.ipaddr, user.login, datetime(rcvfrom.mtime)"
         "  FROM blob JOIN rcvfrom USING(rcvid) LEFT JOIN user USING(uid)"
         " WHERE blob.rid=%d",
         rid
      );
      if( db_step(&q)==SQLITE_ROW ){
        const char *zIpAddr = db_column_text(&q, 0);
        const char *zUser = db_column_text(&q, 1);
        const char *zDate = db_column_text(&q, 2);
        if( zUser==0 || zUser[0]==0 ) zUser = "unknown";
        @ <tr><th>Received&nbsp;From:</th>
        @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
      }
      db_finalize(&q);
    }
    if( g.perm.Hyperlink ){
      const char *zProjName = db_get("project-name", "unnamed");
      @ <tr><th>Timelines:</th><td>
      @   %z(href("%R/timeline?f=%S",zUuid))family</a>
      if( zParent ){
        @ | %z(href("%R/timeline?p=%S",zUuid))ancestors</a>
      }
      if( !isLeaf ){
        @ | %z(href("%R/timeline?d=%S",zUuid))descendants</a>
      }
      if( zParent && !isLeaf ){
        @ | %z(href("%R/timeline?dp=%S",zUuid))both</a>
      }
      db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
                     " WHERE rid=%d AND tagtype>0 "
                     "   AND tag.tagid=tagxref.tagid "
                     "   AND +tag.tagname GLOB 'sym-*'", rid);
      while( db_step(&q)==SQLITE_ROW ){
        const char *zTagName = db_column_text(&q, 0);
        @  | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a>
      }
      db_finalize(&q);


      /* The Download: line */
      if( g.perm.Zip ){
        char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s",
                             zProjName, zUuid, zUuid);
        @ </td></tr>







|





|
|
|
|




|














|



|
|


|







560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
    if( zEComment ){
      @ <tr><th>Edited&nbsp;Comment:</th><td class="infoComment">%!w(zEComment)</td></tr>
      @ <tr><th>Original&nbsp;Comment:</th><td class="infoComment">%!w(zComment)</td></tr>
    }else{
      @ <tr><th>Comment:</th><td class="infoComment">%!w(zComment)</td></tr>
    }
    if( g.perm.Admin ){
      db_prepare(&q2,
         "SELECT rcvfrom.ipaddr, user.login, datetime(rcvfrom.mtime)"
         "  FROM blob JOIN rcvfrom USING(rcvid) LEFT JOIN user USING(uid)"
         " WHERE blob.rid=%d",
         rid
      );
      if( db_step(&q2)==SQLITE_ROW ){
        const char *zIpAddr = db_column_text(&q2, 0);
        const char *zUser = db_column_text(&q2, 1);
        const char *zDate = db_column_text(&q2, 2);
        if( zUser==0 || zUser[0]==0 ) zUser = "unknown";
        @ <tr><th>Received&nbsp;From:</th>
        @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
      }
      db_finalize(&q2);
    }
    if( g.perm.Hyperlink ){
      const char *zProjName = db_get("project-name", "unnamed");
      @ <tr><th>Timelines:</th><td>
      @   %z(href("%R/timeline?f=%S",zUuid))family</a>
      if( zParent ){
        @ | %z(href("%R/timeline?p=%S",zUuid))ancestors</a>
      }
      if( !isLeaf ){
        @ | %z(href("%R/timeline?d=%S",zUuid))descendants</a>
      }
      if( zParent && !isLeaf ){
        @ | %z(href("%R/timeline?dp=%S",zUuid))both</a>
      }
      db_prepare(&q2,"SELECT substr(tag.tagname,5) FROM tagxref, tag "
                     " WHERE rid=%d AND tagtype>0 "
                     "   AND tag.tagid=tagxref.tagid "
                     "   AND +tag.tagname GLOB 'sym-*'", rid);
      while( db_step(&q2)==SQLITE_ROW ){
        const char *zTagName = db_column_text(&q2, 0);
        @  | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a>
      }
      db_finalize(&q2);


      /* The Download: line */
      if( g.perm.Zip ){
        char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s",
                             zProjName, zUuid, zUuid);
        @ </td></tr>
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
      @ </tr>
    }
    @ </table>
  }else{
    style_header("Check-in Information");
    login_anonymous_available();
  }
  db_finalize(&q);
  showTags(rid, "");
  if( zParent ){
    @ <div class="section">Changes</div>
    @ <div class="sectionmenu">
    verboseFlag = g.zPath[0]!='c';
    if( db_get_boolean("show-version-diffs", 0)==0 ){
      verboseFlag = !verboseFlag;







|







628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
      @ </tr>
    }
    @ </table>
  }else{
    style_header("Check-in Information");
    login_anonymous_available();
  }
  db_finalize(&q1);
  showTags(rid, "");
  if( zParent ){
    @ <div class="section">Changes</div>
    @ <div class="sectionmenu">
    verboseFlag = g.zPath[0]!='c';
    if( db_get_boolean("show-version-diffs", 0)==0 ){
      verboseFlag = !verboseFlag;
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
    }
    @ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid))
    @ patch</a></div>
    if( pRe ){
      @ <p><b>Only differences that match regular expression "%h(zRe)"
      @ are shown.</b></p>
    }
    db_prepare(&q,
       "SELECT name,"
       "       mperm,"
       "       (SELECT uuid FROM blob WHERE rid=mlink.pid),"
       "       (SELECT uuid FROM blob WHERE rid=mlink.fid),"
       "       (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)"
       "  FROM mlink JOIN filename ON filename.fnid=mlink.fnid"
       " WHERE mlink.mid=%d"
       "   AND (mlink.fid>0"
              " OR mlink.fnid NOT IN (SELECT pfnid FROM mlink WHERE mid=%d))"
       " ORDER BY name /*sort*/",
       rid, rid
    );
    diffFlags = construct_diff_flags(verboseFlag, sideBySide);
    while( db_step(&q)==SQLITE_ROW ){
      const char *zName = db_column_text(&q,0);
      int mperm = db_column_int(&q, 1);
      const char *zOld = db_column_text(&q,2);
      const char *zNew = db_column_text(&q,3);
      const char *zOldName = db_column_text(&q, 4);
      append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
    }
    db_finalize(&q);
  }
  append_diff_javascript(sideBySide);
  style_footer();
}

/*
** WEBPAGE: winfo







|













|
|
|
|
|
|


|







675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
    }
    @ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid))
    @ patch</a></div>
    if( pRe ){
      @ <p><b>Only differences that match regular expression "%h(zRe)"
      @ are shown.</b></p>
    }
    db_prepare(&q3,
       "SELECT name,"
       "       mperm,"
       "       (SELECT uuid FROM blob WHERE rid=mlink.pid),"
       "       (SELECT uuid FROM blob WHERE rid=mlink.fid),"
       "       (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)"
       "  FROM mlink JOIN filename ON filename.fnid=mlink.fnid"
       " WHERE mlink.mid=%d"
       "   AND (mlink.fid>0"
              " OR mlink.fnid NOT IN (SELECT pfnid FROM mlink WHERE mid=%d))"
       " ORDER BY name /*sort*/",
       rid, rid
    );
    diffFlags = construct_diff_flags(verboseFlag, sideBySide);
    while( db_step(&q3)==SQLITE_ROW ){
      const char *zName = db_column_text(&q3,0);
      int mperm = db_column_int(&q3, 1);
      const char *zOld = db_column_text(&q3,2);
      const char *zNew = db_column_text(&q3,3);
      const char *zOldName = db_column_text(&q3, 4);
      append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
    }
    db_finalize(&q3);
  }
  append_diff_javascript(sideBySide);
  style_footer();
}

/*
** WEBPAGE: winfo
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
  rid = name_to_rid_www("name");
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( rid==0 ) fossil_redirect_home();
  if( g.perm.Admin ){
    const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
  style_header("Hex Artifact Content");







|







1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
  rid = name_to_rid_www("name");
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( rid==0 ) fossil_redirect_home();
  if( g.perm.Admin ){
    const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
  style_header("Hex Artifact Content");
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( rid==0 ) fossil_redirect_home();
  if( g.perm.Admin ){
    const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
  style_header("Artifact Content");







|







1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  if( rid==0 ) fossil_redirect_home();
  if( g.perm.Admin ){
    const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
  style_header("Artifact Content");
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
  login_check_credentials();
  if( !g.perm.RdTkt ){ login_needed(); return; }
  rid = name_to_rid_www("name");
  if( rid==0 ){ fossil_redirect_home(); }
  zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
  if( g.perm.Admin ){
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
  pTktChng = manifest_get(rid, CFTYPE_TICKET);







|







1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
  login_check_credentials();
  if( !g.perm.RdTkt ){ login_needed(); return; }
  rid = name_to_rid_www("name");
  if( rid==0 ){ fossil_redirect_home(); }
  zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
  if( g.perm.Admin ){
    if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
      style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
            g.zTop, zUuid);
    }else{
      style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
            g.zTop, zUuid);
    }
  }
  pTktChng = manifest_get(rid, CFTYPE_TICKET);
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
  @ <p>Make changes to attributes of check-in
  @ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p>
  form_begin(0, "%R/ci_edit");
  login_insert_csrf_secret();
  @ <div><input type="hidden" name="r" value="%S(zUuid)" />
  @ <table border="0" cellspacing="10">

  @ <tr><td align="right" valign="top"><b>User:</b></td>
  @ <td valign="top">
  @   <input type="text" name="u" size="20" value="%h(zNewUser)" />
  @ </td></tr>

  @ <tr><td align="right" valign="top"><b>Comment:</b></td>
  @ <td valign="top">
  @ <textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea>
  @ </td></tr>

  @ <tr><td align="right" valign="top"><b>Check-in Time:</b></td>
  @ <td valign="top">
  @   <input type="text" name="dt" size="20" value="%h(zNewDate)" />
  @ </td></tr>

  if( zChngTime ){
    @ <tr><td align="right" valign="top"><b>Timestamp of this change:</b></td>
    @ <td valign="top">
    @   <input type="text" name="chngtime" size="20" value="%h(zChngTime)" />
    @ </td></tr>
  }

  @ <tr><td align="right" valign="top"><b>Background Color:</b></td>
  @ <td valign="top">
  render_color_chooser(fNewPropagateColor, zNewColor, "pclr", "clr", "clrcust");
  @ </td></tr>

  @ <tr><td align="right" valign="top"><b>Tags:</b></td>
  @ <td valign="top">
  @ <label><input type="checkbox" id="newtag" name="newtag"%s(zNewTagFlag) />
  @ Add the following new tag name to this check-in:</label>
  @ <input type="text" style="width:15;" name="tagname" value="%h(zNewTag)"
  @ onkeyup="gebi('newtag').checked=!!this.value" />
  db_prepare(&q,
     "SELECT tag.tagid, tagname FROM tagxref, tag"







|




|




|





|





|




|







2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
  @ <p>Make changes to attributes of check-in
  @ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p>
  form_begin(0, "%R/ci_edit");
  login_insert_csrf_secret();
  @ <div><input type="hidden" name="r" value="%S(zUuid)" />
  @ <table border="0" cellspacing="10">

  @ <tr><th align="right" valign="top">User:</th>
  @ <td valign="top">
  @   <input type="text" name="u" size="20" value="%h(zNewUser)" />
  @ </td></tr>

  @ <tr><th align="right" valign="top">Comment:</th>
  @ <td valign="top">
  @ <textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea>
  @ </td></tr>

  @ <tr><th align="right" valign="top">Check-in Time:</th>
  @ <td valign="top">
  @   <input type="text" name="dt" size="20" value="%h(zNewDate)" />
  @ </td></tr>

  if( zChngTime ){
    @ <tr><th align="right" valign="top">Timestamp of this change:</th>
    @ <td valign="top">
    @   <input type="text" name="chngtime" size="20" value="%h(zChngTime)" />
    @ </td></tr>
  }

  @ <tr><th align="right" valign="top">Background Color:</th>
  @ <td valign="top">
  render_color_chooser(fNewPropagateColor, zNewColor, "pclr", "clr", "clrcust");
  @ </td></tr>

  @ <tr><th align="right" valign="top">Tags:</th>
  @ <td valign="top">
  @ <label><input type="checkbox" id="newtag" name="newtag"%s(zNewTagFlag) />
  @ Add the following new tag name to this check-in:</label>
  @ <input type="text" style="width:15;" name="tagname" value="%h(zNewTag)"
  @ onkeyup="gebi('newtag').checked=!!this.value" />
  db_prepare(&q,
     "SELECT tag.tagid, tagname FROM tagxref, tag"
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
    }else{
      @ Cancel special tag <b>%h(zTagName)</b></label>
    }
  }
  db_finalize(&q);
  @ </td></tr>

  @ <tr><td align="right" valign="top"><b>Branching:</b></td>
  @ <td valign="top">
  @ <label><input id="newbr" type="checkbox" name="newbr"%s(zNewBrFlag) />
  @ Make this check-in the start of a new branch named:</label>
  @ <input type="text" style="width:15;" name="brname" value="%h(zNewBranch)"
  @ onkeyup="gebi('newbr').checked=!!this.value" />
  @ </td></tr>

  if( is_a_leaf(rid)
   && !db_exists("SELECT 1 FROM tagxref "
                 " WHERE tagid=%d AND rid=%d AND tagtype>0",
                 TAG_CLOSED, rid)
  ){
    @ <tr><td align="right" valign="top"><b>Leaf Closure:</b></td>
    @ <td valign="top">
    @ <label><input type="checkbox" name="close"%s(zCloseFlag) />
    @ Mark this leaf as "closed" so that it no longer appears on the
    @ "leaves" page and is no longer labeled as a "<b>Leaf</b>".</label>
    @ </td></tr>
  }








|












|







2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
    }else{
      @ Cancel special tag <b>%h(zTagName)</b></label>
    }
  }
  db_finalize(&q);
  @ </td></tr>

  @ <tr><th align="right" valign="top">Branching:</th>
  @ <td valign="top">
  @ <label><input id="newbr" type="checkbox" name="newbr"%s(zNewBrFlag) />
  @ Make this check-in the start of a new branch named:</label>
  @ <input type="text" style="width:15;" name="brname" value="%h(zNewBranch)"
  @ onkeyup="gebi('newbr').checked=!!this.value" />
  @ </td></tr>

  if( is_a_leaf(rid)
   && !db_exists("SELECT 1 FROM tagxref "
                 " WHERE tagid=%d AND rid=%d AND tagtype>0",
                 TAG_CLOSED, rid)
  ){
    @ <tr><th align="right" valign="top">Leaf Closure:</th>
    @ <td valign="top">
    @ <label><input type="checkbox" name="close"%s(zCloseFlag) />
    @ Mark this leaf as "closed" so that it no longer appears on the
    @ "leaves" page and is no longer labeled as a "<b>Leaf</b>".</label>
    @ </td></tr>
  }

Changes to src/json.c.
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
** Creates a comma-separated list of command names
** taken from zPages. zPages must be an array of objects
** whose final entry MUST have a NULL name value or results
** are undefined.
**
** The list is appended to pOut. The number of items (not bytes)
** appended are returned. If filterByMode is non-0 then the result
** list will contain only commands which are able to run in the the
** current run mode (CLI vs. HTTP).
*/
static int json_pagedefs_to_string(JsonPageDef const * zPages,
                                   Blob * pOut, int filterByMode){
  int i = 0;
  for( ; zPages->name; ++zPages, ++i ){
    if(filterByMode){







|







2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
** Creates a comma-separated list of command names
** taken from zPages. zPages must be an array of objects
** whose final entry MUST have a NULL name value or results
** are undefined.
**
** The list is appended to pOut. The number of items (not bytes)
** appended are returned. If filterByMode is non-0 then the result
** list will contain only commands which are able to run in the
** current run mode (CLI vs. HTTP).
*/
static int json_pagedefs_to_string(JsonPageDef const * zPages,
                                   Blob * pOut, int filterByMode){
  int i = 0;
  for( ; zPages->name; ++zPages, ++i ){
    if(filterByMode){
Changes to src/json_branch.c.
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
  
  blob_appendf(&branch, "U %F\n", g.zLogin);
  md5sum_blob(&branch, &mcksum);
  blob_appendf(&branch, "Z %b\n", &mcksum);

  brid = content_put(&branch);
  if( brid==0 ){
    fossil_panic("Problem committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
  if( manifest_crosslink(brid, &branch)==0 ){
    fossil_panic("unable to install new manifest");
  }
  assert( blob_is_reset(&branch) );
  content_deltify(rootid, brid, 0);
  if( zNewRid ){
    *zNewRid = brid;
  }








|



|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
  
  blob_appendf(&branch, "U %F\n", g.zLogin);
  md5sum_blob(&branch, &mcksum);
  blob_appendf(&branch, "Z %b\n", &mcksum);

  brid = content_put(&branch);
  if( brid==0 ){
    fossil_fatal("Problem committing manifest: %s", g.zErrMsg);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
  if( manifest_crosslink(brid, &branch)==0 ){
    fossil_fatal("unable to install new manifest");
  }
  assert( blob_is_reset(&branch) );
  content_deltify(rootid, brid, 0);
  if( zNewRid ){
    *zNewRid = brid;
  }

Changes to src/json_status.c.
124
125
126
127
128
129
130




131
132
133
134
135
136
137
        zStatus = "missing";
        ++nErr;
      }
    }else if( 2==isChnged ){
      zStatus = "updatedByMerge";
    }else if( 3==isChnged ){
      zStatus = "addedByMerge";




    }else if( 1==isChnged ){
      if( file_contains_merge_marker(zFullName) ){
        zStatus = "conflict";
      }else{
        zStatus = "edited";
      }
    }







>
>
>
>







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
        zStatus = "missing";
        ++nErr;
      }
    }else if( 2==isChnged ){
      zStatus = "updatedByMerge";
    }else if( 3==isChnged ){
      zStatus = "addedByMerge";
    }else if( 4==isChnged ){
      zStatus = "updatedByIntegrate";
    }else if( 5==isChnged ){
      zStatus = "addedByIntegrate";
    }else if( 1==isChnged ){
      if( file_contains_merge_marker(zFullName) ){
        zStatus = "conflict";
      }else{
        zStatus = "edited";
      }
    }
155
156
157
158
159
160
161

162
163
164
165
166
167
168
169
170
171
172
173
174
  db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
                 " WHERE id<=0");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zLabel = "MERGED_WITH";
    switch( db_column_int(&q, 1) ){
      case -1:  zLabel = "CHERRYPICK ";  break;
      case -2:  zLabel = "BACKOUT    ";  break;

    }
    blob_append(report, zPrefix, nPrefix);
    blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
  }
  db_finalize(&q);
  if( nErr ){
    fossil_fatal("aborting due to prior errors");
  }
#endif
  return cson_object_value( oPay );
}

#endif /* FOSSIL_ENABLE_JSON */







>













159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
                 " WHERE id<=0");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zLabel = "MERGED_WITH";
    switch( db_column_int(&q, 1) ){
      case -1:  zLabel = "CHERRYPICK ";  break;
      case -2:  zLabel = "BACKOUT    ";  break;
      case -4:  zLabel = "INTEGRATE  ";  break;
    }
    blob_append(report, zPrefix, nPrefix);
    blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
  }
  db_finalize(&q);
  if( nErr ){
    fossil_fatal("aborting due to prior errors");
  }
#endif
  return cson_object_value( oPay );
}

#endif /* FOSSIL_ENABLE_JSON */
Changes to src/json_timeline.c.
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  /* Field order MUST match that from json_timeline_temp_table()!!! */
  static const char zBaseSql[] =
    @ SELECT
    @   NULL,
    @   blob.rid,
    @   uuid,
    @   CAST(strftime('%%s',event.mtime) AS INTEGER),
    @   datetime(event.mtime,'utc'),
    @   coalesce(ecomment, comment),
    @   coalesce(euser, user),
    @   blob.rid IN leaf,
    @   bgcolor,
    @   event.type,
    @   (SELECT group_concat(substr(tagname,5), ',') FROM tag, tagxref
    @     WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid







|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  /* Field order MUST match that from json_timeline_temp_table()!!! */
  static const char zBaseSql[] =
    @ SELECT
    @   NULL,
    @   blob.rid,
    @   uuid,
    @   CAST(strftime('%%s',event.mtime) AS INTEGER),
    @   datetime(event.mtime),
    @   coalesce(ecomment, comment),
    @   coalesce(euser, user),
    @   blob.rid IN leaf,
    @   bgcolor,
    @   event.type,
    @   (SELECT group_concat(substr(tagname,5), ',') FROM tag, tagxref
    @     WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
Changes to src/login.c.
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

/*
** Return a path appropriate for setting a cookie.
**
** The path is g.zTop for single-repo cookies.  It is "/" for
** cookies of a login-group.
*/
static const char *login_cookie_path(void){
  if( login_group_name()==0 ){
    return g.zTop;
  }else{
    return "/";
  }
}








|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

/*
** Return a path appropriate for setting a cookie.
**
** The path is g.zTop for single-repo cookies.  It is "/" for
** cookies of a login-group.
*/
const char *login_cookie_path(void){
  if( login_group_name()==0 ){
    return g.zTop;
  }else{
    return "/";
  }
}

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
  int i;
  if( zAgent==0 ) return 0;  /* If no UserAgent, then probably a bot */
  for(i=0; zAgent[i]; i++){
    if( prefix_match("bot", zAgent+i) ) return 0;
    if( prefix_match("spider", zAgent+i) ) return 0;
    if( prefix_match("crawl", zAgent+i) ) return 0;
    /* If a URI appears in the User-Agent, it is probably a bot */
    if( memcmp("http", zAgent+i,4)==0 ) return 0;
  }
  if( memcmp(zAgent, "Mozilla/", 8)==0 ){
    if( atoi(&zAgent[8])<4 ) return 0;  /* Many bots advertise as Mozilla/3 */
    if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
    if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
    if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
    if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
    return 0;
  }
  if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
  if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
  if( memcmp(zAgent, "Lynx/", 5)==0 ) return 1;
  if( memcmp(zAgent, "NetSurf/", 8)==0 ) return 1;
  return 0;
}

/*
** COMMAND: test-ishuman
**
** Read lines of text from standard input.  Interpret each line of text







|

|







|
|
|
|







389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
  int i;
  if( zAgent==0 ) return 0;  /* If no UserAgent, then probably a bot */
  for(i=0; zAgent[i]; i++){
    if( prefix_match("bot", zAgent+i) ) return 0;
    if( prefix_match("spider", zAgent+i) ) return 0;
    if( prefix_match("crawl", zAgent+i) ) return 0;
    /* If a URI appears in the User-Agent, it is probably a bot */
    if( strncmp("http", zAgent+i,4)==0 ) return 0;
  }
  if( strncmp(zAgent, "Mozilla/", 8)==0 ){
    if( atoi(&zAgent[8])<4 ) return 0;  /* Many bots advertise as Mozilla/3 */
    if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
    if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
    if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
    if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
    return 0;
  }
  if( strncmp(zAgent, "Opera/", 6)==0 ) return 1;
  if( strncmp(zAgent, "Safari/", 7)==0 ) return 1;
  if( strncmp(zAgent, "Lynx/", 5)==0 ) return 1;
  if( strncmp(zAgent, "NetSurf/", 8)==0 ) return 1;
  return 0;
}

/*
** COMMAND: test-ishuman
**
** Read lines of text from standard input.  Interpret each line of text
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
  @        onClick="chngAction(this.form)" /></td>
  @ </tr>
  @ </table>
  @ <script type="text/JavaScript">
  @   gebi('u').focus()
  @   function chngAction(form){
  if( g.sslNotAvailable==0
   && memcmp(g.zBaseURL,"https:",6)!=0
   && db_get_boolean("https-login",0)
  ){
     char *zSSL = mprintf("https:%s", &g.zBaseURL[5]);
     @  if( form.u.value!="anonymous" ){
     @     form.action = "%h(zSSL)/login";
     @  }
  }







|







596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
  @        onClick="chngAction(this.form)" /></td>
  @ </tr>
  @ </table>
  @ <script type="text/JavaScript">
  @   gebi('u').focus()
  @   function chngAction(form){
  if( g.sslNotAvailable==0
   && strncmp(g.zBaseURL,"https:",6)!=0
   && db_get_boolean("https-login",0)
  ){
     char *zSSL = mprintf("https:%s", &g.zBaseURL[5]);
     @  if( form.u.value!="anonymous" ){
     @     form.action = "%h(zSSL)/login";
     @  }
  }
761
762
763
764
765
766
767
768
769
770




771
772
773
774
775
776
777
778
  );
  return uid;
}

/*
** This routine examines the login cookie to see if it exists and
** is valid.  If the login cookie checks out, it then sets global
** variables appropriately.  Global variables set include g.userUid
** and g.zLogin and the g.perm family of permission booleans.
**




** If the 
*/
void login_check_credentials(void){
  int uid = 0;                  /* User id */
  const char *zCookie;          /* Text of the login cookie */
  const char *zIpAddr;          /* Raw IP address of the requestor */
  char *zRemoteAddr;            /* Abbreviated IP address of the requestor */
  const char *zCap = 0;         /* Capability string */







|
<

>
>
>
>
|







761
762
763
764
765
766
767
768

769
770
771
772
773
774
775
776
777
778
779
780
781
  );
  return uid;
}

/*
** This routine examines the login cookie to see if it exists and
** is valid.  If the login cookie checks out, it then sets global
** variables appropriately.

**
**    g.userUid      Database USER.UID value.  Might be -1 for "nobody"
**    g.zLogin       Database USER.LOGIN value.  NULL for user "nobody"
**    g.perm         Permissions granted to this user
**    g.isHuman      True if the user is human, not a spider or robot
**
*/
void login_check_credentials(void){
  int uid = 0;                  /* User id */
  const char *zCookie;          /* Text of the login cookie */
  const char *zIpAddr;          /* Raw IP address of the requestor */
  char *zRemoteAddr;            /* Abbreviated IP address of the requestor */
  const char *zCap = 0;         /* Capability string */
797
798
799
800
801
802
803

804
805
806
807
808
809
810
   && db_get_int("localauth",0)==0
   && P("HTTPS")==0
  ){
    uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'");
    g.zLogin = db_text("?", "SELECT login FROM user WHERE uid=%d", uid);
    zCap = "sx";
    g.noPswd = 1;

    sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "localhost");
  }

  /* Check the login cookie to see if it matches a known valid user.
  */
  if( uid==0 && (zCookie = P(login_cookie_name()))!=0 ){
    /* Parse the cookie value up into HASH/ARG/USER */







>







800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
   && db_get_int("localauth",0)==0
   && P("HTTPS")==0
  ){
    uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'");
    g.zLogin = db_text("?", "SELECT login FROM user WHERE uid=%d", uid);
    zCap = "sx";
    g.noPswd = 1;
    g.isHuman = 1;
    sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "localhost");
  }

  /* Check the login cookie to see if it matches a known valid user.
  */
  if( uid==0 && (zCookie = P(login_cookie_name()))!=0 ){
    /* Parse the cookie value up into HASH/ARG/USER */
905
906
907
908
909
910
911

912
913
914
915
916
917
918
919
920
921
922

923

924
925
926
927
928
929
930
931
932
  /* Set the global variables recording the userid and login.  The
  ** "nobody" user is a special case in that g.zLogin==0.
  */
  g.userUid = uid;
  if( fossil_strcmp(g.zLogin,"nobody")==0 ){
    g.zLogin = 0;
  }


  /* Set the capabilities */
  login_replace_capabilities(zCap, 0);
  login_set_anon_nobody_capabilities();

  /* The auto-hyperlink setting allows hyperlinks to be displayed for users
  ** who do not have the "h" permission as long as their UserAgent string
  ** makes it appear that they are human.  Check to see if auto-hyperlink is
  ** enabled for this repository and make appropriate adjustments to the
  ** permission flags if it is.
  */

  if( zCap[0] && !g.perm.Hyperlink

   && db_get_boolean("auto-hyperlink",1)
   && isHuman(P("HTTP_USER_AGENT"))
  ){
    g.perm.Hyperlink = 1;
    g.javascriptHyperlink = 1;
  }

  /* If the public-pages glob pattern is defined and REQUEST_URI matches
  ** one of the globs in public-pages, then also add in all default-perms







>











>
|
>

<







909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931

932
933
934
935
936
937
938
  /* Set the global variables recording the userid and login.  The
  ** "nobody" user is a special case in that g.zLogin==0.
  */
  g.userUid = uid;
  if( fossil_strcmp(g.zLogin,"nobody")==0 ){
    g.zLogin = 0;
  }
  g.isHuman = g.zLogin==0 ? isHuman(P("HTTP_USER_AGENT")) : 1;

  /* Set the capabilities */
  login_replace_capabilities(zCap, 0);
  login_set_anon_nobody_capabilities();

  /* The auto-hyperlink setting allows hyperlinks to be displayed for users
  ** who do not have the "h" permission as long as their UserAgent string
  ** makes it appear that they are human.  Check to see if auto-hyperlink is
  ** enabled for this repository and make appropriate adjustments to the
  ** permission flags if it is.
  */
  if( zCap[0]
   && !g.perm.Hyperlink
   && g.isHuman
   && db_get_boolean("auto-hyperlink",1)

  ){
    g.perm.Hyperlink = 1;
    g.javascriptHyperlink = 1;
  }

  /* If the public-pages glob pattern is defined and REQUEST_URI matches
  ** one of the globs in public-pages, then also add in all default-perms
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057

/*
** Zeroes out g.perm and calls login_set_capabilities(zCap,flags).
*/
void login_replace_capabilities(const char *zCap, unsigned flags){
  memset(&g.perm, 0, sizeof(g.perm));
  login_set_capabilities(zCap, flags);

}

/*
** If the current login lacks any of the capabilities listed in
** the input, then return 0.  If all capabilities are present, then
** return 1.
*/







>







1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064

/*
** Zeroes out g.perm and calls login_set_capabilities(zCap,flags).
*/
void login_replace_capabilities(const char *zCap, unsigned flags){
  memset(&g.perm, 0, sizeof(g.perm));
  login_set_capabilities(zCap, flags);
  login_anon_once = 1;
}

/*
** If the current login lacks any of the capabilities listed in
** the input, then return 0.  If all capabilities are present, then
** return 1.
*/
Changes to src/main.c.
112
113
114
115
116
117
118

119
120
121
122
123
124
125

/*
** All global variables are in this structure.
*/
struct Global {
  int argc; char **argv;  /* Command-line arguments to the program */
  char *nameOfExe;        /* Full path of executable. */

  int isConst;            /* True if the output is unchanging */
  sqlite3 *db;            /* The connection to the databases */
  sqlite3 *dbConfig;      /* Separate connection for global_config table */
  int useAttach;          /* True if global_config is attached to repository */
  const char *zConfigDbName;/* Path of the config database. NULL if not open */
  sqlite3_int64 now;      /* Seconds since 1970 */
  int repositoryOpen;     /* True if the main repository database is open */







>







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

/*
** All global variables are in this structure.
*/
struct Global {
  int argc; char **argv;  /* Command-line arguments to the program */
  char *nameOfExe;        /* Full path of executable. */
  const char *zErrlog;    /* Log errors to this file, if not NULL */
  int isConst;            /* True if the output is unchanging */
  sqlite3 *db;            /* The connection to the databases */
  sqlite3 *dbConfig;      /* Separate connection for global_config table */
  int useAttach;          /* True if global_config is attached to repository */
  const char *zConfigDbName;/* Path of the config database. NULL if not open */
  sqlite3_int64 now;      /* Seconds since 1970 */
  int repositoryOpen;     /* True if the main repository database is open */
157
158
159
160
161
162
163

164
165
166
167
168
169
170
  int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
  int *aCommitFile;       /* Array of files to be committed */
  int markPrivate;        /* All new artifacts are private if true */
  int clockSkewSeen;      /* True if clocks on client and server out of sync */
  int wikiFlags;          /* Wiki conversion flags applied to %w and %W */
  char isHTTP;            /* True if server/CGI modes, else assume CLI. */
  char javascriptHyperlink; /* If true, set href= using script, not HTML */


  int urlIsFile;          /* True if a "file:" url */
  int urlIsHttps;         /* True if a "https:" url */
  int urlIsSsh;           /* True if an "ssh:" url */
  char *urlName;          /* Hostname for http: or filename for file: */
  char *urlHostname;      /* The HOST: parameter on http headers */
  char *urlProtocol;      /* "http" or "https" */







>







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
  int *aCommitFile;       /* Array of files to be committed */
  int markPrivate;        /* All new artifacts are private if true */
  int clockSkewSeen;      /* True if clocks on client and server out of sync */
  int wikiFlags;          /* Wiki conversion flags applied to %w and %W */
  char isHTTP;            /* True if server/CGI modes, else assume CLI. */
  char javascriptHyperlink; /* If true, set href= using script, not HTML */
  Blob httpHeader;        /* Complete text of the HTTP request header */

  int urlIsFile;          /* True if a "file:" url */
  int urlIsHttps;         /* True if a "https:" url */
  int urlIsSsh;           /* True if an "ssh:" url */
  char *urlName;          /* Hostname for http: or filename for file: */
  char *urlHostname;      /* The HOST: parameter on http headers */
  char *urlProtocol;      /* "http" or "https" */
181
182
183
184
185
186
187

188
189
190
191
192
193
194

  const char *zLogin;     /* Login name.  "" if not logged in. */
  const char *zSSLIdentity;  /* Value of --ssl-identity option, filename of
                             ** SSL client identity */
  int useLocalauth;       /* No login required if from 127.0.0.1 */
  int noPswd;             /* Logged in without password (on 127.0.0.1) */
  int userUid;            /* Integer user id */


  /* Information used to populate the RCVFROM table */
  int rcvid;              /* The rcvid.  0 if not yet defined. */
  char *zIpAddr;          /* The remote IP address */
  char *zNonce;           /* The nonce used for login */

  /* permissions used by the server */







>







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

  const char *zLogin;     /* Login name.  "" if not logged in. */
  const char *zSSLIdentity;  /* Value of --ssl-identity option, filename of
                             ** SSL client identity */
  int useLocalauth;       /* No login required if from 127.0.0.1 */
  int noPswd;             /* Logged in without password (on 127.0.0.1) */
  int userUid;            /* Integer user id */
  int isHuman;            /* True if access by a human, not a spider or bot */

  /* Information used to populate the RCVFROM table */
  int rcvid;              /* The rcvid.  0 if not yet defined. */
  char *zIpAddr;          /* The remote IP address */
  char *zNonce;           /* The nonce used for login */

  /* permissions used by the server */
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
  Blob line = empty_blob;   /* One line of the file */
  unsigned int nLine;       /* Number of lines in the file*/
  unsigned int i, j, k;     /* Loop counters */
  int n;                    /* Number of bytes in one line */
  char *z;                  /* General use string pointer */
  char **newArgv;           /* New expanded g.argv under construction */
  char const * zFileName;   /* input file name */
  FILE * zInFile;           /* input FILE */
#if defined(_WIN32)
  wchar_t buf[MAX_PATH];
#endif

  g.argc = argc;
  g.argv = argv;
  sqlite3_initialize();







|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
  Blob line = empty_blob;   /* One line of the file */
  unsigned int nLine;       /* Number of lines in the file*/
  unsigned int i, j, k;     /* Loop counters */
  int n;                    /* Number of bytes in one line */
  char *z;                  /* General use string pointer */
  char **newArgv;           /* New expanded g.argv under construction */
  char const * zFileName;   /* input file name */
  FILE *inFile;             /* input FILE */
#if defined(_WIN32)
  wchar_t buf[MAX_PATH];
#endif

  g.argc = argc;
  g.argv = argv;
  sqlite3_initialize();
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
    if( z[0]=='-' ) z++;
    if( z[0]==0 ) return;   /* Stop searching at "--" */
    if( fossil_strcmp(z, "args")==0 ) break;
  }
  if( i>=g.argc-1 ) return;

  zFileName = g.argv[i+1];
  zInFile = (0==strcmp("-",zFileName))
    ? stdin
    : fossil_fopen(zFileName,"rb");
  if(!zInFile){
    fossil_panic("Cannot open -args file [%s]", zFileName);
  }else{
    blob_read_from_channel(&file, zInFile, -1);
    if(stdin != zInFile){
      fclose(zInFile);
    }
    zInFile = NULL;
  }
  blob_to_utf8_no_bom(&file, 1);
  z = blob_str(&file);
  for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
  newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
  for(j=0; j<i; j++) newArgv[j] = g.argv[j];








|


|
|

|
|
|

|







401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
    if( z[0]=='-' ) z++;
    if( z[0]==0 ) return;   /* Stop searching at "--" */
    if( fossil_strcmp(z, "args")==0 ) break;
  }
  if( i>=g.argc-1 ) return;

  zFileName = g.argv[i+1];
  inFile = (0==strcmp("-",zFileName))
    ? stdin
    : fossil_fopen(zFileName,"rb");
  if(!inFile){
    fossil_fatal("Cannot open -args file [%s]", zFileName);
  }else{
    blob_read_from_channel(&file, inFile, -1);
    if(stdin != inFile){
      fclose(inFile);
    }
    inFile = NULL;
  }
  blob_to_utf8_no_bom(&file, 1);
  z = blob_str(&file);
  for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
  newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
  for(j=0; j<i; j++) newArgv[j] = g.argv[j];

508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533

534
535
536
537
538
539
540
/* Error logs from SQLite */
static void fossil_sqlite_log(void *notUsed, int iCode, const char *zErrmsg){
#ifdef __APPLE__
  /* Disable the file alias warning on apple products because Time Machine
  ** creates lots of aliases and the warning alarms people. */
  if( iCode==SQLITE_WARNING ) return;
#endif

  fossil_warning("%s: %s", sqlite_error_code_name(iCode), zErrmsg);
}

/*
** This procedure runs first.
*/
#if defined(_WIN32) && !defined(BROKEN_MINGW_CMDLINE)
int _dowildcard = -1; /* This turns on command-line globbing in MinGW-w64 */
int wmain(int argc, wchar_t **argv)
#else
int main(int argc, char **argv)
#endif
{
  const char *zCmdName = "unknown";
  int idx;
  int rc;
  sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
  memset(&g, 0, sizeof(g));
  g.now = time(0);

#ifdef FOSSIL_ENABLE_JSON
#if defined(NDEBUG)
  g.json.errorDetailParanoia = 2 /* FIXME: make configurable
                                    One problem we have here is that this
                                    code is needed before the db is opened,
                                    so we can't sql for it.*/;
#else







>



















>







511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
/* Error logs from SQLite */
static void fossil_sqlite_log(void *notUsed, int iCode, const char *zErrmsg){
#ifdef __APPLE__
  /* Disable the file alias warning on apple products because Time Machine
  ** creates lots of aliases and the warning alarms people. */
  if( iCode==SQLITE_WARNING ) return;
#endif
  if( iCode==SQLITE_SCHEMA ) return;
  fossil_warning("%s: %s", sqlite_error_code_name(iCode), zErrmsg);
}

/*
** This procedure runs first.
*/
#if defined(_WIN32) && !defined(BROKEN_MINGW_CMDLINE)
int _dowildcard = -1; /* This turns on command-line globbing in MinGW-w64 */
int wmain(int argc, wchar_t **argv)
#else
int main(int argc, char **argv)
#endif
{
  const char *zCmdName = "unknown";
  int idx;
  int rc;
  sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
  memset(&g, 0, sizeof(g));
  g.now = time(0);
  g.httpHeader = empty_blob;
#ifdef FOSSIL_ENABLE_JSON
#if defined(NDEBUG)
  g.json.errorDetailParanoia = 2 /* FIXME: make configurable
                                    One problem we have here is that this
                                    code is needed before the db is opened,
                                    so we can't sql for it.*/;
#else
581
582
583
584
585
586
587

588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606




607
608
609
610
611
612
613
    g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
    g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
    if( g.fSqlTrace ) g.fSqlStats = 1;
    g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
    g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
    g.zLogin = find_option("user", "U", 1);
    g.zSSLIdentity = find_option("ssl-identity", 0, 1);

    if( find_option("utc",0,0) ) g.fTimeFormat = 1;
    if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
    if( zChdir && file_chdir(zChdir, 0) ){
      fossil_fatal("unable to change directories to %s", zChdir);
    }
    if( find_option("help",0,0)!=0 ){
      /* --help anywhere on the command line is translated into
      ** "fossil help argv[1] argv[2]..." */
      int i;
      char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) );
      for(i=1; i<g.argc; i++) zNewArgv[i+1] = g.argv[i];
      zNewArgv[i+1] = 0;
      zNewArgv[0] = g.argv[0];
      zNewArgv[1] = "help";
      g.argc++;
      g.argv = zNewArgv;
    }
    zCmdName = g.argv[1];
  }




  rc = name_search(zCmdName, aCommand, count(aCommand), &idx);
  if( rc==1 ){
    fossil_fatal("%s: unknown command: %s\n"
                 "%s: use \"help\" for more information\n",
                   g.argv[0], zCmdName, g.argv[0]);
  }else if( rc==2 ){
    int i, n;







>



















>
>
>
>







586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
    g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
    g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
    if( g.fSqlTrace ) g.fSqlStats = 1;
    g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
    g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
    g.zLogin = find_option("user", "U", 1);
    g.zSSLIdentity = find_option("ssl-identity", 0, 1);
    g.zErrlog = find_option("errorlog", 0, 1);
    if( find_option("utc",0,0) ) g.fTimeFormat = 1;
    if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
    if( zChdir && file_chdir(zChdir, 0) ){
      fossil_fatal("unable to change directories to %s", zChdir);
    }
    if( find_option("help",0,0)!=0 ){
      /* --help anywhere on the command line is translated into
      ** "fossil help argv[1] argv[2]..." */
      int i;
      char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) );
      for(i=1; i<g.argc; i++) zNewArgv[i+1] = g.argv[i];
      zNewArgv[i+1] = 0;
      zNewArgv[0] = g.argv[0];
      zNewArgv[1] = "help";
      g.argc++;
      g.argv = zNewArgv;
    }
    zCmdName = g.argv[1];
  }
#ifndef _WIN32
  if( !is_valid_fd(2) ) fossil_panic("file descriptor 2 not open");
  /* if( is_valid_fd(3) ) fossil_warning("file descriptor 3 is open"); */
#endif
  rc = name_search(zCmdName, aCommand, count(aCommand), &idx);
  if( rc==1 ){
    fossil_fatal("%s: unknown command: %s\n"
                 "%s: use \"help\" for more information\n",
                   g.argv[0], zCmdName, g.argv[0]);
  }else if( rc==2 ){
    int i, n;
786
787
788
789
790
791
792

793
794
795
796
797
798
799
               MANIFEST_VERSION " " MANIFEST_DATE " UTC\n");
  if(!find_option("verbose","v",0)){
    return;
  }else{
    fossil_print("Compiled on %s %s using %s (%d-bit)\n",
                 __DATE__, __TIME__, COMPILER_NAME, sizeof(void*)*8);
    fossil_print("SQLite %s %.30s\n", SQLITE_VERSION, SQLITE_SOURCE_ID);

    fossil_print("zlib %s\n", ZLIB_VERSION);
#if defined(FOSSIL_ENABLE_SSL)
    fossil_print("SSL (%s)\n", OPENSSL_VERSION_TEXT);
#endif
#if defined(FOSSIL_ENABLE_TCL)
    fossil_print("TCL (Tcl %s)\n", TCL_PATCH_LEVEL);
#endif







>







796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
               MANIFEST_VERSION " " MANIFEST_DATE " UTC\n");
  if(!find_option("verbose","v",0)){
    return;
  }else{
    fossil_print("Compiled on %s %s using %s (%d-bit)\n",
                 __DATE__, __TIME__, COMPILER_NAME, sizeof(void*)*8);
    fossil_print("SQLite %s %.30s\n", SQLITE_VERSION, SQLITE_SOURCE_ID);
    fossil_print("Schema version %s\n", AUX_SCHEMA);
    fossil_print("zlib %s\n", ZLIB_VERSION);
#if defined(FOSSIL_ENABLE_SSL)
    fossil_print("SSL (%s)\n", OPENSSL_VERSION_TEXT);
#endif
#if defined(FOSSIL_ENABLE_TCL)
    fossil_print("TCL (Tcl %s)\n", TCL_PATCH_LEVEL);
#endif
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
    if( file_isdir(zDir)==1 ){
      if( file_chdir(zDir, 1) ){
        fossil_fatal("unable to chroot into %s", zDir);
      }
      zRepo = "/";
    }else{
      for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
      if( zDir[i]!='/' ) fossil_panic("bad repository name: %s", zRepo);
      if( i>0 ){
        zDir[i] = 0;
        if( file_chdir(zDir, 1) ){
          fossil_fatal("unable to chroot into %s", zDir);
        }
        zDir[i] = '/';
      }







|







1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
    if( file_isdir(zDir)==1 ){
      if( file_chdir(zDir, 1) ){
        fossil_fatal("unable to chroot into %s", zDir);
      }
      zRepo = "/";
    }else{
      for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
      if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo);
      if( i>0 ){
        zDir[i] = 0;
        if( file_chdir(zDir, 1) ){
          fossil_fatal("unable to chroot into %s", zDir);
        }
        zDir[i] = '/';
      }
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
    ** handling below, and by disabling it in JSON mode I can remove
    ** lots of special-case handling in several JSON handlers.
    */
#ifdef FOSSIL_ENABLE_JSON
    if(!g.json.isJsonMode){
#endif
      dehttpize(g.zExtra);
      cgi_set_parameter_nocopy("name", g.zExtra);
#ifdef FOSSIL_ENABLE_JSON
    }
#endif
  }

  /* Locate the method specified by the path and execute the function
  ** that implements that method.







|







1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
    ** handling below, and by disabling it in JSON mode I can remove
    ** lots of special-case handling in several JSON handlers.
    */
#ifdef FOSSIL_ENABLE_JSON
    if(!g.json.isJsonMode){
#endif
      dehttpize(g.zExtra);
      cgi_set_parameter_nocopy("name", g.zExtra, 1);
#ifdef FOSSIL_ENABLE_JSON
    }
#endif
  }

  /* Locate the method specified by the path and execute the function
  ** that implements that method.
1498
1499
1500
1501
1502
1503
1504




1505
1506
1507
1508
1509
1510
1511
  while( blob_line(&config, &line) ){
    if( !blob_token(&line, &key) ) continue;
    if( blob_buffer(&key)[0]=='#' ) continue;
    if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){
      g.fDebug = fossil_fopen(blob_str(&value), "ab");
      blob_reset(&value);
      continue;




    }
    if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
      cgi_setenv("HOME", blob_str(&value));
      blob_reset(&value);
      continue;
    }
    if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){







>
>
>
>







1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
  while( blob_line(&config, &line) ){
    if( !blob_token(&line, &key) ) continue;
    if( blob_buffer(&key)[0]=='#' ) continue;
    if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){
      g.fDebug = fossil_fopen(blob_str(&value), "ab");
      blob_reset(&value);
      continue;
    }
    if( blob_eq(&key, "errorlog:") && blob_token(&line, &value) ){
      g.zErrlog = mprintf("%s", blob_str(&value));
      continue;
    }
    if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
      cgi_setenv("HOME", blob_str(&value));
      blob_reset(&value);
      continue;
    }
    if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){
1631
1632
1633
1634
1635
1636
1637

1638
1639
1640
1641
1642
1643
1644
1645
1646

1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662

1663
1664
1665
1666
1667
1668
1669
**   --localauth      enable automatic login for local connections
**   --host NAME      specify hostname of the server
**   --https          signal a request coming in via https
**   --nossl          signal that no SSL connections are available
**   --notfound URL   use URL as "HTTP 404, object not found" page.
**   --files GLOB     comma-separate glob patterns for static file to serve
**   --baseurl URL    base URL (useful with reverse proxies)

**
** See also: cgi, server, winsrv
*/
void cmd_http(void){
  const char *zIpAddr;
  const char *zNotFound;
  const char *zHost;
  const char *zAltBase;
  const char *zFileGlob;


  /* The winhttp module passes the --files option as --files-urlenc with
  ** the argument being URL encoded, to avoid wildcard expansion in the
  ** shell.  This option is for internal use and is undocumented.
  */
  zFileGlob = find_option("files-urlenc",0,1);
  if( zFileGlob ){
    char *z = mprintf("%s", zFileGlob);
    dehttpize(z);
    zFileGlob = z;
  }else{
    zFileGlob = find_option("files",0,1);
  }
  zNotFound = find_option("notfound", 0, 1);
  g.useLocalauth = find_option("localauth", 0, 0)!=0;
  g.sslNotAvailable = find_option("nossl", 0, 0)!=0;

  zAltBase = find_option("baseurl", 0, 1);
  if( zAltBase ) set_base_url(zAltBase);
  if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on");
  zHost = find_option("host", 0, 1);
  if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
  g.cgiOutput = 1;
  if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){







>









>
















>







1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
**   --localauth      enable automatic login for local connections
**   --host NAME      specify hostname of the server
**   --https          signal a request coming in via https
**   --nossl          signal that no SSL connections are available
**   --notfound URL   use URL as "HTTP 404, object not found" page.
**   --files GLOB     comma-separate glob patterns for static file to serve
**   --baseurl URL    base URL (useful with reverse proxies)
**   --scgi           Interpret input as SCGI rather than HTTP
**
** See also: cgi, server, winsrv
*/
void cmd_http(void){
  const char *zIpAddr;
  const char *zNotFound;
  const char *zHost;
  const char *zAltBase;
  const char *zFileGlob;
  int useSCGI;

  /* The winhttp module passes the --files option as --files-urlenc with
  ** the argument being URL encoded, to avoid wildcard expansion in the
  ** shell.  This option is for internal use and is undocumented.
  */
  zFileGlob = find_option("files-urlenc",0,1);
  if( zFileGlob ){
    char *z = mprintf("%s", zFileGlob);
    dehttpize(z);
    zFileGlob = z;
  }else{
    zFileGlob = find_option("files",0,1);
  }
  zNotFound = find_option("notfound", 0, 1);
  g.useLocalauth = find_option("localauth", 0, 0)!=0;
  g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
  useSCGI = find_option("scgi", 0, 0)!=0;
  zAltBase = find_option("baseurl", 0, 1);
  if( zAltBase ) set_base_url(zAltBase);
  if( find_option("https",0,0)!=0 ) cgi_replace_parameter("HTTPS","on");
  zHost = find_option("host", 0, 1);
  if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
  g.cgiOutput = 1;
  if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
1677
1678
1679
1680
1681
1682
1683



1684

1685
1686
1687
1688
1689
1690
1691
  }else{
    g.httpIn = stdin;
    g.httpOut = stdout;
    zIpAddr = 0;
  }
  find_server_repository(0);
  g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);



  cgi_handle_http_request(zIpAddr);

  process_one_web_page(zNotFound, glob_create(zFileGlob));
}

/*
** Note that the following command is used by ssh:// processing.
**
** COMMAND: test-http







>
>
>
|
>







1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
  }else{
    g.httpIn = stdin;
    g.httpOut = stdout;
    zIpAddr = 0;
  }
  find_server_repository(0);
  g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);
  if( useSCGI ){
    cgi_handle_scgi_request();
  }else{
    cgi_handle_http_request(zIpAddr);
  }
  process_one_web_page(zNotFound, glob_create(zFileGlob));
}

/*
** Note that the following command is used by ssh:// processing.
**
** COMMAND: test-http
1773
1774
1775
1776
1777
1778
1779

1780
1781
1782
1783
1784
1785
1786
**   --localauth         enable automatic login for requests from localhost
**   --localhost         listen on 127.0.0.1 only (always true for "ui")
**   -P|--port TCPPORT   listen to request on port TCPPORT
**   --th-trace          trace TH1 execution (for debugging purposes)
**   --baseurl URL       Use URL as the base (useful for reverse proxies)
**   --notfound URL      Redirect
**   --files GLOBLIST    Comma-separated list of glob patterns for static files

**
** See also: cgi, http, winsrv
*/
void cmd_webserver(void){
  int iPort, mxPort;        /* Range of TCP ports allowed */
  const char *zPort;        /* Value of the --port option */
  const char *zBrowser;     /* Name of web browser program */







>







1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
**   --localauth         enable automatic login for requests from localhost
**   --localhost         listen on 127.0.0.1 only (always true for "ui")
**   -P|--port TCPPORT   listen to request on port TCPPORT
**   --th-trace          trace TH1 execution (for debugging purposes)
**   --baseurl URL       Use URL as the base (useful for reverse proxies)
**   --notfound URL      Redirect
**   --files GLOBLIST    Comma-separated list of glob patterns for static files
**   --scgi              Accept SCGI rather than HTTP
**
** See also: cgi, http, winsrv
*/
void cmd_webserver(void){
  int iPort, mxPort;        /* Range of TCP ports allowed */
  const char *zPort;        /* Value of the --port option */
  const char *zBrowser;     /* Name of web browser program */
1799
1800
1801
1802
1803
1804
1805

1806
1807
1808
1809
1810
1811
1812

  zFileGlob = find_option("files", 0, 1);
  g.useLocalauth = find_option("localauth", 0, 0)!=0;
  Th_InitTraceLog();
  zPort = find_option("port", "P", 1);
  zNotFound = find_option("notfound", 0, 1);
  zAltBase = find_option("baseurl", 0, 1);

  if( zAltBase ){
    set_base_url(zAltBase);
  }
  if ( find_option("localhost", 0, 0)!=0 ){
    flags |= HTTP_SERVER_LOCALHOST;
  }
  if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");







>







1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836

  zFileGlob = find_option("files", 0, 1);
  g.useLocalauth = find_option("localauth", 0, 0)!=0;
  Th_InitTraceLog();
  zPort = find_option("port", "P", 1);
  zNotFound = find_option("notfound", 0, 1);
  zAltBase = find_option("baseurl", 0, 1);
  if( find_option("scgi", 0, 0)!=0 ) flags |= HTTP_SERVER_SCGI;
  if( zAltBase ){
    set_base_url(zAltBase);
  }
  if ( find_option("localhost", 0, 0)!=0 ){
    flags |= HTTP_SERVER_LOCALHOST;
  }
  if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
1833
1834
1835
1836
1837
1838
1839
















1840

1841
1842
1843
1844
1845
1846
1847
  if( isUiCmd ){
#if !defined(__DARWIN__) && !defined(__APPLE__) && !defined(__HAIKU__)
    zBrowser = db_get("web-browser", 0);
    if( zBrowser==0 ){
      static const char *const azBrowserProg[] =
          { "xdg-open", "gnome-open", "firefox", "google-chrome" };
      int i;
















      zBrowser = "echo";

      for(i=0; i<sizeof(azBrowserProg)/sizeof(azBrowserProg[0]); i++){
        if( binaryOnPath(azBrowserProg[i]) ){
          zBrowser = azBrowserProg[i];
          break;
        }
      }
    }







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

>







1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
  if( isUiCmd ){
#if !defined(__DARWIN__) && !defined(__APPLE__) && !defined(__HAIKU__)
    zBrowser = db_get("web-browser", 0);
    if( zBrowser==0 ){
      static const char *const azBrowserProg[] =
          { "xdg-open", "gnome-open", "firefox", "google-chrome" };
      int i;
#if defined(__CYGWIN__)
      const char *path = fossil_getenv("ProgramFiles(x86)");
      if( !path ){
        path = fossil_getenv("PROGRAMFILES");
      }
      path = fossil_utf8_to_filename(path);
      zBrowser = mprintf("%s/Google/Chrome/Application/chrome.exe", path);
      if( file_access(zBrowser, X_OK) ){
        zBrowser = mprintf("%s/Mozilla Firefox/firefox.exe", path);
      }
      if( file_access(zBrowser, X_OK) ){
        path = fossil_utf8_to_filename(fossil_getenv("PROGRAMFILES"));
        zBrowser = mprintf("%s/Internet Explorer/iexplore.exe", path);
      }
      zBrowser = mprintf("\"%s\"", zBrowser);
#else
      zBrowser = "echo";
#endif
      for(i=0; i<sizeof(azBrowserProg)/sizeof(azBrowserProg[0]); i++){
        if( binaryOnPath(azBrowserProg[i]) ){
          zBrowser = azBrowserProg[i];
          break;
        }
      }
    }
1863
1864
1865
1866
1867
1868
1869



1870

1871
1872
1873
1874
1875
1876
1877
  g.httpOut = stdout;
  if( g.fHttpTrace || g.fSqlTrace ){
    fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
  }
  g.cgiOutput = 1;
  find_server_repository(isUiCmd && zNotFound==0);
  g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);



  cgi_handle_http_request(0);

  process_one_web_page(zNotFound, glob_create(zFileGlob));
#else
  /* Win32 implementation */
  if( isUiCmd ){
    zBrowser = db_get("web-browser", "start");
    if( zIpAddr ){
      zBrowserCmd = mprintf("%s http://%s:%%d/ &", zBrowser, zIpAddr);







>
>
>
|
>







1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
  g.httpOut = stdout;
  if( g.fHttpTrace || g.fSqlTrace ){
    fprintf(stderr, "====== SERVER pid %d =======\n", getpid());
  }
  g.cgiOutput = 1;
  find_server_repository(isUiCmd && zNotFound==0);
  g.zRepositoryName = enter_chroot_jail(g.zRepositoryName);
  if( flags & HTTP_SERVER_SCGI ){
    cgi_handle_scgi_request();
  }else{
    cgi_handle_http_request(0);
  }
  process_one_web_page(zNotFound, glob_create(zFileGlob));
#else
  /* Win32 implementation */
  if( isUiCmd ){
    zBrowser = db_get("web-browser", "start");
    if( zIpAddr ){
      zBrowserCmd = mprintf("%s http://%s:%%d/ &", zBrowser, zIpAddr);
Changes to src/main.mk.
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
	$(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c

$(OBJDIR)/zip.h:	$(OBJDIR)/headers
$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c
	$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
	$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o








|







1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
	$(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c

$(OBJDIR)/zip.h:	$(OBJDIR)/headers
$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c
	$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
	$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -Dsqlite3_strglob=strglob -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o

Changes to src/makemake.tcl.
295
296
297
298
299
300
301

302
303
304
305
306
307
308
append opt " -DSQLITE_ENABLE_LOCKING_STYLE=0"
set SQLITE_OPTIONS $opt
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"

writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
set opt {-Dmain=sqlite3_shell}
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"

writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"

writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"

writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"







>







295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
append opt " -DSQLITE_ENABLE_LOCKING_STYLE=0"
set SQLITE_OPTIONS $opt
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"

writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
set opt {-Dmain=sqlite3_shell}
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
append opt " -Dsqlite3_strglob=strglob"
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"

writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"

writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"
Changes to src/manifest.c.
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    char *zCPBase;      /* UUID of cherry-pick baseline. NULL for singletons */
  } *aCherrypick;
  int nCChild;          /* Number of cluster children */
  int nCChildAlloc;     /* Number of closts allocated in azCChild[] */
  char **azCChild;      /* UUIDs of referenced objects in a cluster. M cards */
  int nTag;             /* Number of T Cards */
  int nTagAlloc;        /* Slots allocated in aTag[] */
  struct { 
    char *zName;           /* Name of the tag */
    char *zUuid;           /* UUID that the tag is applied to */
    char *zValue;          /* Value if the tag is really a property */
  } *aTag;              /* One for each T card */
  int nField;           /* Number of J cards */
  int nFieldAlloc;      /* Slots allocated in aField[] */
  struct { 







|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    char *zCPBase;      /* UUID of cherry-pick baseline. NULL for singletons */
  } *aCherrypick;
  int nCChild;          /* Number of cluster children */
  int nCChildAlloc;     /* Number of closts allocated in azCChild[] */
  char **azCChild;      /* UUIDs of referenced objects in a cluster. M cards */
  int nTag;             /* Number of T Cards */
  int nTagAlloc;        /* Slots allocated in aTag[] */
  struct TagType {
    char *zName;           /* Name of the tag */
    char *zUuid;           /* UUID that the tag is applied to */
    char *zValue;          /* Value if the tag is really a property */
  } *aTag;              /* One for each T card */
  int nField;           /* Number of J cards */
  int nFieldAlloc;      /* Slots allocated in aField[] */
  struct { 
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
  ManifestText x;
  char cPrevType = 0;
  char cType;
  char *z;
  int n;
  char *zUuid;
  int sz = 0;
  int isRepeat;
  static Bag seen;
  const char *zErr = 0;

  if( rid==0 ){
    isRepeat = 1;
  }else if( bag_find(&seen, rid) ){
    isRepeat = 1;







|







351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
  ManifestText x;
  char cPrevType = 0;
  char cType;
  char *z;
  int n;
  char *zUuid;
  int sz = 0;
  int isRepeat, hasSelfRefTag = 0;
  static Bag seen;
  const char *zErr = 0;

  if( rid==0 ){
    isRepeat = 1;
  }else if( bag_find(&seen, rid) ){
    isRepeat = 1;
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399







400
401
402
403
404
405
406
  n = blob_size(pContent);
  if( n<=0 || z[n-1]!='\n' ){
    blob_reset(pContent);
    blob_appendf(pErr, n ? "not terminated with \\n" : "zero-length");
    return 0;
  }

  /* Strip off the PGP signature if there is one.  Then verify the
  ** Z-card.
  */
  remove_pgp_signature(&z, &n);
  if( verify_z_card(z, n)==2 ){
    blob_reset(pContent);
    blob_appendf(pErr, "incorrect Z-card cksum");
    return 0;
  }

  /* Verify that the first few characters of the artifact look like
  ** a control artifact.
  */
  if( n<10 || z[0]<'A' || z[0]>'Z' || z[1]!=' ' ){
    blob_reset(pContent);
    blob_appendf(pErr, "line 1 not recognized");
    return 0;







  }

  /* Allocate a Manifest object to hold the parsed control artifact.
  */
  p = fossil_malloc( sizeof(*p) );
  memset(p, 0, sizeof(*p));
  memcpy(&p->content, pContent, sizeof(p->content));







|
<


<
<
<
<
<








>
>
>
>
>
>
>







376
377
378
379
380
381
382
383

384
385





386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
  n = blob_size(pContent);
  if( n<=0 || z[n-1]!='\n' ){
    blob_reset(pContent);
    blob_appendf(pErr, n ? "not terminated with \\n" : "zero-length");
    return 0;
  }

  /* Strip off the PGP signature if there is one.

  */
  remove_pgp_signature(&z, &n);






  /* Verify that the first few characters of the artifact look like
  ** a control artifact.
  */
  if( n<10 || z[0]<'A' || z[0]>'Z' || z[1]!=' ' ){
    blob_reset(pContent);
    blob_appendf(pErr, "line 1 not recognized");
    return 0;
  }
  /* Then verify the Z-card.
  */
  if( verify_z_card(z, n)==2 ){
    blob_reset(pContent);
    blob_appendf(pErr, "incorrect Z-card cksum");
    return 0;
  }

  /* Allocate a Manifest object to hold the parsed control artifact.
  */
  p = fossil_malloc( sizeof(*p) );
  memset(p, 0, sizeof(*p));
  memcpy(&p->content, pContent, sizeof(p->content));
466
467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
      }


      /*
      **     C <comment>
      **
      ** Comment text is fossil-encoded.  There may be no more than
      ** one C line.  C lines are required for manifests and are

      ** disallowed on all other control files.
      */
      case 'C': {
        if( p->zComment!=0 ) SYNTAX("more than one C-card");
        p->zComment = next_token(&x, 0);
        if( p->zComment==0 ) SYNTAX("missing comment text on C-card");
        defossilize(p->zComment);
        break;







|
>
|







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
      }


      /*
      **     C <comment>
      **
      ** Comment text is fossil-encoded.  There may be no more than
      ** one C line.  C lines are required for manifests, are optional
      ** for Events and Attachments, and are disallowed on all other
      ** control files.
      */
      case 'C': {
        if( p->zComment!=0 ) SYNTAX("more than one C-card");
        p->zComment = next_token(&x, 0);
        if( p->zComment==0 ) SYNTAX("missing comment text on C-card");
        defossilize(p->zComment);
        break;
658
659
660
661
662
663
664
665
666
667


668
669
670
671
672
673
674
        defossilize(p->zMimetype);
        break;
      }

      /*
      **     P <uuid> ...
      **
      ** Specify one or more other artifacts where are the parents of
      ** this artifact.  The first parent is the primary parent.  All
      ** others are parents by merge.


      */
      case 'P': {
        while( (zUuid = next_token(&x, &sz))!=0 ){
          if( sz!=UUID_SIZE ) SYNTAX("wrong size UUID on P-card");
          if( !validate16(zUuid, UUID_SIZE) )SYNTAX("invalid UUID on P-card");
          if( p->nParent>=p->nParentAlloc ){
            p->nParentAlloc = p->nParentAlloc*2 + 5;







|

|
>
>







660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
        defossilize(p->zMimetype);
        break;
      }

      /*
      **     P <uuid> ...
      **
      ** Specify one or more other artifacts which are the parents of
      ** this artifact.  The first parent is the primary parent.  All
      ** others are parents by merge. Note that the initial empty
      ** checkin historically has an empty P-card, so empty P-cards
      ** must be accepted.
      */
      case 'P': {
        while( (zUuid = next_token(&x, &sz))!=0 ){
          if( sz!=UUID_SIZE ) SYNTAX("wrong size UUID on P-card");
          if( !validate16(zUuid, UUID_SIZE) )SYNTAX("invalid UUID on P-card");
          if( p->nParent>=p->nParentAlloc ){
            p->nParentAlloc = p->nParentAlloc*2 + 5;
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
      /*
      **     R <md5sum>
      **
      ** Specify the MD5 checksum over the name and content of all files
      ** in the manifest.
      */
      case 'R': {
        if( p->zRepoCksum!=0 ) SYNTAX("more than on R-card");
        p->zRepoCksum = next_token(&x, &sz);
        if( sz!=32 ) SYNTAX("wrong size cksum on R-card");
        if( !validate16(p->zRepoCksum, 32) ) SYNTAX("malformed R-card cksum");
        break;
      }

      /*







|







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
      /*
      **     R <md5sum>
      **
      ** Specify the MD5 checksum over the name and content of all files
      ** in the manifest.
      */
      case 'R': {
        if( p->zRepoCksum!=0 ) SYNTAX("more than one R-card");
        p->zRepoCksum = next_token(&x, &sz);
        if( sz!=32 ) SYNTAX("wrong size cksum on R-card");
        if( !validate16(p->zRepoCksum, 32) ) SYNTAX("malformed R-card cksum");
        break;
      }

      /*
746
747
748
749
750
751
752

753
754




755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773

774

775

776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
        if( zName==0 ) SYNTAX("missing name on T-card");
        zUuid = next_token(&x, &sz);
        if( zUuid==0 ) SYNTAX("missing UUID on T-card");
        zValue = next_token(&x, 0);
        if( zValue ) defossilize(zValue);
        if( sz==UUID_SIZE && validate16(zUuid, UUID_SIZE) ){
          /* A valid uuid */

        }else if( sz==1 && zUuid[0]=='*' ){
          zUuid = 0;




        }else{
          SYNTAX("malformed UUID on T-card");
        }
        defossilize(zName);
        if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' ){
          SYNTAX("T-card name does not begin with '-', '+', or '*'");
        }
        if( validate16(&zName[1], strlen(&zName[1])) ){
          /* Do not allow tags whose names look like UUIDs */
          SYNTAX("T-card name looks like a UUID");
        }
        if( p->nTag>=p->nTagAlloc ){
          p->nTagAlloc = p->nTagAlloc*2 + 10;
          p->aTag = fossil_realloc(p->aTag, p->nTagAlloc*sizeof(p->aTag[0]) );
        }
        i = p->nTag++;
        p->aTag[i].zName = zName;
        p->aTag[i].zUuid = zUuid;
        p->aTag[i].zValue = zValue;

        if( i>0 && fossil_strcmp(p->aTag[i-1].zName, zName)>=0 ){

          SYNTAX("T-card in the wrong order");

        }
        break;
      }

      /*
      **     U ?<login>?
      **
      ** Identify the user who created this control file by their
      ** login.  Only one U line is allowed.  Prohibited in clusters.
      ** If the user name is omitted, take that to be "anonymous".
      */
      case 'U': {
        if( p->zUser!=0 ) SYNTAX("more than on U-card");
        p->zUser = next_token(&x, 0);
        if( p->zUser==0 ){
          p->zUser = "anonymous";
        }else{
          defossilize(p->zUser);
        }
        break;







>


>
>
>
>



















>
|
>
|
>












|







750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
        if( zName==0 ) SYNTAX("missing name on T-card");
        zUuid = next_token(&x, &sz);
        if( zUuid==0 ) SYNTAX("missing UUID on T-card");
        zValue = next_token(&x, 0);
        if( zValue ) defossilize(zValue);
        if( sz==UUID_SIZE && validate16(zUuid, UUID_SIZE) ){
          /* A valid uuid */
          if( p->zEventId ) SYNTAX("non-self-referential T-card in event");
        }else if( sz==1 && zUuid[0]=='*' ){
          zUuid = 0;
          hasSelfRefTag = 1;
          if( p->zEventId && zName[0]!='+' ){
            SYNTAX("propagating T-card in event");
          }
        }else{
          SYNTAX("malformed UUID on T-card");
        }
        defossilize(zName);
        if( zName[0]!='-' && zName[0]!='+' && zName[0]!='*' ){
          SYNTAX("T-card name does not begin with '-', '+', or '*'");
        }
        if( validate16(&zName[1], strlen(&zName[1])) ){
          /* Do not allow tags whose names look like UUIDs */
          SYNTAX("T-card name looks like a UUID");
        }
        if( p->nTag>=p->nTagAlloc ){
          p->nTagAlloc = p->nTagAlloc*2 + 10;
          p->aTag = fossil_realloc(p->aTag, p->nTagAlloc*sizeof(p->aTag[0]) );
        }
        i = p->nTag++;
        p->aTag[i].zName = zName;
        p->aTag[i].zUuid = zUuid;
        p->aTag[i].zValue = zValue;
        if( i>0 ){
          int c = fossil_strcmp(p->aTag[i-1].zName, zName);
          if( c>0 || (c==0 && fossil_strcmp(p->aTag[i-1].zUuid, zUuid)>=0) ){
            SYNTAX("T-card in the wrong order");
          }
        }
        break;
      }

      /*
      **     U ?<login>?
      **
      ** Identify the user who created this control file by their
      ** login.  Only one U line is allowed.  Prohibited in clusters.
      ** If the user name is omitted, take that to be "anonymous".
      */
      case 'U': {
        if( p->zUser!=0 ) SYNTAX("more than one U-card");
        p->zUser = next_token(&x, 0);
        if( p->zUser==0 ){
          p->zUser = "anonymous";
        }else{
          defossilize(p->zUser);
        }
        break;
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874


875

876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899

900
901
902






903
904
905
906


907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
      default: {
        SYNTAX("unrecognized card");
      }
    }
  }
  if( x.z<x.zEnd ) SYNTAX("extra characters at end of card");

  if( p->nFile>0 || p->zRepoCksum!=0 || p->zBaseline ){
    if( p->nCChild>0 ) SYNTAX("M-card in check-in");
    if( p->rDate<=0.0 ) SYNTAX("missing date for check-in");
    if( p->nField>0 ) SYNTAX("J-card in check-in");
    if( p->zTicketUuid ) SYNTAX("K-card in check-in");
    if( p->zWiki ) SYNTAX("W-card in check-in");
    if( p->zWikiTitle ) SYNTAX("L-card in check-in");
    if( p->zEventId ) SYNTAX("E-card in check-in");
    if( p->zTicketUuid ) SYNTAX("K-card in check-in");
    if( p->zAttachName ) SYNTAX("A-card in check-in");
    p->type = CFTYPE_MANIFEST;
  }else if( p->nCChild>0 ){
    if( p->rDate>0.0
     || p->zComment!=0
     || p->zUser!=0
     || p->nTag>0
     || p->nParent>0
     || p->nField>0
     || p->zTicketUuid
     || p->zWiki
     || p->zWikiTitle


     || p->zEventId

     || p->zAttachName
     || p->zMimetype
    ){
      SYNTAX("cluster contains a card other than M- or Z-");
    }
    if( !seenZ ) SYNTAX("missing Z-card on cluster");
    p->type = CFTYPE_CLUSTER;
  }else if( p->nField>0 ){
    if( p->rDate<=0.0 ) SYNTAX("missing date for ticket");
    if( p->zWiki ) SYNTAX("W-card in ticket");
    if( p->zWikiTitle ) SYNTAX("L-card in ticket");
    if( p->zEventId ) SYNTAX("E-card in ticket");
    if( p->nCChild>0 ) SYNTAX("M-card in ticket");
    if( p->nTag>0 ) SYNTAX("T-card in ticket");
    if( p->zTicketUuid==0 ) SYNTAX("missing K-card in ticket");
    if( p->zUser==0 ) SYNTAX("missing U-card in ticket");
    if( p->zAttachName ) SYNTAX("A-card in ticket");
    if( p->zMimetype) SYNTAX("N-card in ticket");
    if( !seenZ ) SYNTAX("missing Z-card in ticket");
    p->type = CFTYPE_TICKET;
  }else if( p->zEventId ){
    if( p->rDate<=0.0 ) SYNTAX("missing date for event");
    if( p->nCChild>0 ) SYNTAX("M-card in event");
    if( p->zTicketUuid!=0 ) SYNTAX("K-card in event");

    if( p->zWikiTitle!=0 ) SYNTAX("L-card in event");
    if( p->zWiki==0 ) SYNTAX("W-card in event");
    if( p->zAttachName ) SYNTAX("A-card in event");






    for(i=0; i<p->nTag; i++){
      if( p->aTag[i].zName[0]!='+' ) SYNTAX("propagating tag in event");
      if( p->aTag[i].zUuid!=0 ) SYNTAX("non-self-referential tag in event");
    }


    if( !seenZ ) SYNTAX("Z-card missing in event");
    p->type = CFTYPE_EVENT;
  }else if( p->zWiki!=0 ){
    if( p->rDate<=0.0 ) SYNTAX("date missing on wiki");
    if( p->nCChild>0 ) SYNTAX("M-card in wiki");
    if( p->nTag>0 ) SYNTAX("T-card in wiki");
    if( p->zTicketUuid!=0 ) SYNTAX("K-card in wiki");
    if( p->zWikiTitle==0 ) SYNTAX("L-card in wiki");
    if( p->zAttachName ) SYNTAX("A-card in wiki");
    if( !seenZ ) SYNTAX("missing Z-card on wiki");
    p->type = CFTYPE_WIKI;
  }else if( p->nTag>0 ){
    if( p->rDate<=0.0 ) SYNTAX("date missing on tag");
    if( p->nParent>0 ) SYNTAX("P-card on tag");
    if( p->zWikiTitle ) SYNTAX("L-card on tag");
    if( p->zTicketUuid ) SYNTAX("K-card in tag");
    if( p->zAttachName ) SYNTAX("A-card in tag");
    if( p->zMimetype ) SYNTAX("N-card in tag");
    if( !seenZ ) SYNTAX("missing Z-card on tag");
    p->type = CFTYPE_CONTROL;
  }else if( p->zAttachName ){
    if( p->nCChild>0 ) SYNTAX("M-card in attachment");
    if( p->rDate<=0.0 ) SYNTAX("missing date in attachment");
    if( p->zTicketUuid ) SYNTAX("K-card in attachment");
    if( p->zWikiTitle ) SYNTAX("L-card in attachment");
    if( !seenZ ) SYNTAX("missing Z-card on attachment");
    p->type = CFTYPE_ATTACHMENT;
  }else{
    if( p->nCChild>0 ) SYNTAX("M-card in check-in");
    if( p->rDate<=0.0 ) SYNTAX("missing date in check-in");
    if( p->nField>0 ) SYNTAX("J-card in check-in");
    if( p->zTicketUuid ) SYNTAX("K-card in check-in");
    if( p->zWikiTitle ) SYNTAX("L-card in check-in");
    p->type = CFTYPE_MANIFEST;
  }
  md5sum_init();
  if( !isRepeat ) g.parseCnt[p->type]++;
  return p;

manifest_syntax_error:
  if( zErr ){







<
|
<
<
<
<
<
<
<
|
<
<
|
|
|
|
|


|
|
>
>
|
>
|
|





|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
>
|
|
|
>
>
>
>
>
>
|
|
|
<
>
>
|
|
|
|
<

|
|



<
<
<
<
<
<
<
<
<

<
|
|
<



<
|
|
|
|
|







859
860
861
862
863
864
865

866







867


868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897

898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916

917
918
919
920
921
922

923
924
925
926
927
928









929

930
931

932
933
934

935
936
937
938
939
940
941
942
943
944
945
946
      default: {
        SYNTAX("unrecognized card");
      }
    }
  }
  if( x.z<x.zEnd ) SYNTAX("extra characters at end of card");


  if( p->nCChild>0 ){







    if( p->zAttachName


     || p->zBaseline
     || p->zComment
     || p->rDate>0.0
     || p->zEventId
     || p->nFile>0
     || p->nField>0
     || p->zTicketUuid
     || p->zWikiTitle
     || p->zMimetype
     || p->nParent>0
     || p->nCherrypick>0
     || p->zRepoCksum
     || p->nTag>0
     || p->zUser
     || p->zWiki
    ){
      SYNTAX("cluster contains a card other than M- or Z-");
    }
    if( !seenZ ) SYNTAX("missing Z-card on cluster");
    p->type = CFTYPE_CLUSTER;
  }else if( p->zEventId ){
    if( p->rDate<=0.0 ) SYNTAX("missing date on event");
    if( p->nFile>0 ) SYNTAX("F-card in event");
    if( p->zRepoCksum ) SYNTAX("R-card in event");
    if( p->zBaseline ) SYNTAX("B-card in event");
    if( p->nField>0 ) SYNTAX("J-card in event");
    if( p->zTicketUuid ) SYNTAX("K-card in event");
    if( p->zWikiTitle!=0 ) SYNTAX("L-card in event");
    if( p->zWiki==0 ) SYNTAX("missing W-card on event");
    if( p->zAttachName ) SYNTAX("A-card in event");

    if( !seenZ ) SYNTAX("missing Z-card on event");
    p->type = CFTYPE_EVENT;
  }else if( hasSelfRefTag || p->nFile>0 || p->zRepoCksum!=0 || p->zBaseline ){
    if( p->rDate<=0.0 ) SYNTAX("missing date on manifest");
    if( p->nField>0 ) SYNTAX("J-card in manifest");
    if( p->zTicketUuid ) SYNTAX("K-card in manifest");
    if( p->zWiki ) SYNTAX("W-card in manifest");
    if( p->zWikiTitle ) SYNTAX("L-card in manifest");
    if( p->zTicketUuid ) SYNTAX("K-card in manifest");
    if( p->zAttachName ) SYNTAX("A-card in manifest");
    p->type = CFTYPE_MANIFEST;
  }else if( p->nField>0 || p->zTicketUuid!=0 ){
    if( p->rDate<=0.0 ) SYNTAX("missing date on ticket");
    if( p->zWiki ) SYNTAX("W-card in ticket");
    if( p->zWikiTitle ) SYNTAX("L-card in ticket");
    if( p->nField==0 ) SYNTAX("missing J-card on ticket");
    if( p->nTag>0 ) SYNTAX("T-card in ticket");
    if( p->zTicketUuid==0 ) SYNTAX("missing K-card on ticket");
    if( p->zUser==0 ) SYNTAX("missing U-card on ticket");

    if( p->zAttachName ) SYNTAX("A-card in ticket");
    if( p->zMimetype) SYNTAX("N-card in ticket");
    if( !seenZ ) SYNTAX("missing Z-card on ticket");
    p->type = CFTYPE_TICKET;
  }else if( p->zWiki!=0 || p->zWikiTitle!=0 ){
    if( p->rDate<=0.0 ) SYNTAX("missing date on wiki");

    if( p->nTag>0 ) SYNTAX("T-card in wiki");
    if( p->zWiki==0 ) SYNTAX("missing W-card on wiki");
    if( p->zWikiTitle==0 ) SYNTAX("missing L-card on wiki");
    if( p->zAttachName ) SYNTAX("A-card in wiki");
    if( !seenZ ) SYNTAX("missing Z-card on wiki");
    p->type = CFTYPE_WIKI;









  }else if( p->zAttachName ){

    if( p->rDate<=0.0 ) SYNTAX("missing date on attachment");
    if( p->nTag>0 ) SYNTAX("T-card in attachment");

    if( !seenZ ) SYNTAX("missing Z-card on attachment");
    p->type = CFTYPE_ATTACHMENT;
  }else{

    if( p->rDate<=0.0 ) SYNTAX("missing date on control");
    if( p->nParent>0 ) SYNTAX("P-card in control");
    if( p->zMimetype ) SYNTAX("N-card in control");
    if( !seenZ ) SYNTAX("missing Z-card on control");
    p->type = CFTYPE_CONTROL;
  }
  md5sum_init();
  if( !isRepeat ) g.parseCnt[p->type]++;
  return p;

manifest_syntax_error:
  if( zErr ){
1608
1609
1610
1611
1612
1613
1614














1615
1616
1617
1618
1619
1620
1621
    "VALUES('t',%d,%.17g,%d,%Q,%Q,%Q)",
    tktTagId, pManifest->rDate, rid, pManifest->zUser,
    blob_str(&comment), blob_str(&brief)
  );
  blob_reset(&comment);
  blob_reset(&brief);
}















/*
** Scan artifact rid/pContent to see if it is a control artifact of
** any key:
**
**      *  Manifest
**      *  Control







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







1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
    "VALUES('t',%d,%.17g,%d,%Q,%Q,%Q)",
    tktTagId, pManifest->rDate, rid, pManifest->zUser,
    blob_str(&comment), blob_str(&brief)
  );
  blob_reset(&comment);
  blob_reset(&brief);
}

/*
** This is the comparison function used to sort the tag array.
*/
static int tag_compare(const void *a, const void *b){
  struct TagType *pA = (struct TagType*)a;
  struct TagType *pB = (struct TagType*)b;
  int c;
  c = fossil_strcmp(pA->zUuid, pB->zUuid);
  if( c==0 ){
    c = fossil_strcmp(pA->zName, pB->zName);
  }
  return c;
}

/*
** Scan artifact rid/pContent to see if it is a control artifact of
** any key:
**
**      *  Manifest
**      *  Control
1922
1923
1924
1925
1926
1927
1928





1929
1930

1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944

1945
1946
1947

1948
1949
1950

1951
1952
1953
1954

1955
1956

1957
1958

1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985






1986
1987
1988

1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
    Blob comment;
    int i;
    const char *zName;
    const char *zValue;
    const char *zUuid;
    int branchMove = 0;
    blob_zero(&comment);





    for(i=0; i<p->nTag; i++){
      zUuid = p->aTag[i].zUuid;

      if( i==0 || fossil_strcmp(zUuid, p->aTag[i-1].zUuid)!=0 ){
        if( i>0 ) blob_append(&comment, " ", 1);
        blob_appendf(&comment,
           "Edit [%S]:",
           zUuid);
        branchMove = 0;
      }
      zName = p->aTag[i].zName;
      zValue = p->aTag[i].zValue;
      if( strcmp(zName, "*branch")==0 ){
        blob_appendf(&comment,
           " Move to branch [/timeline?r=%h&nd&dp=%S | %h].",
           zValue, zUuid, zValue);
        branchMove = 1;

      }else if( strcmp(zName, "*bgcolor")==0 ){
        blob_appendf(&comment,
           " Change branch background color to \"%h\".", zValue);

      }else if( strcmp(zName, "+bgcolor")==0 ){
        blob_appendf(&comment,
           " Change background color to \"%h\".", zValue);

      }else if( strcmp(zName, "-bgcolor")==0 ){
        blob_appendf(&comment, " Cancel background color.");
      }else if( strcmp(zName, "+comment")==0 ){
        blob_appendf(&comment, " Edit check-in comment.");

      }else if( strcmp(zName, "+user")==0 ){
        blob_appendf(&comment, " Change user to \"%h\".", zValue);

      }else if( strcmp(zName, "+date")==0 ){
        blob_appendf(&comment, " Timestamp %h.", zValue);

      }else if( memcmp(zName, "-sym-",5)==0 ){
        if( !branchMove ) blob_appendf(&comment, " Cancel tag %h.", &zName[5]);
      }else if( memcmp(zName, "*sym-",5)==0 ){
        if( !branchMove ){
          blob_appendf(&comment, " Add propagating tag \"%h\".", &zName[5]);
        }
      }else if( memcmp(zName, "+sym-",5)==0 ){
        blob_appendf(&comment, " Add tag \"%h\".", &zName[5]);
      }else if( memcmp(zName, "-sym-",5)==0 ){
        blob_appendf(&comment, " Cancel tag \"%h\".", &zName[5]);
      }else if( strcmp(zName, "+closed")==0 ){
        blob_appendf(&comment, " Marked \"Closed\".");
      }else if( strcmp(zName, "-closed")==0 ){
        blob_appendf(&comment, " Removed the \"Closed\" mark.");
      }else {
        if( zName[0]=='-' ){
          blob_appendf(&comment, " Cancel \"%h\"", &zName[1]);
        }else if( zName[0]=='+' ){
          blob_appendf(&comment, " Add \"%h\"", &zName[1]);
        }else{
          blob_appendf(&comment, " Add propagating \"%h\"", &zName[1]);
        }
        if( zValue && zValue[0] ){
          blob_appendf(&comment, " with value \"%h\".", zValue);
        }else{
          blob_appendf(&comment, ".");
        }






      }
    }
    /*blob_appendf(&comment, " &#91;[/info/%S | details]&#93;");*/

    db_multi_exec(
      "REPLACE INTO event(type,mtime,objid,user,comment)"
      "VALUES('g',%.17g,%d,%Q,%Q)",
      p->rDate, rid, p->zUser, blob_str(&comment)
    );
    blob_reset(&comment);
  }
  db_end_transaction(0);
  if( p->type==CFTYPE_MANIFEST ){
    manifest_cache_insert(p);
  }else{







>
>
>
>
>


>

<

|










>



>



>

|


>


>


>

|


|


|
<
<

|

|













>
>
>
>
>
>



>



|







1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950

1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990


1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
    Blob comment;
    int i;
    const char *zName;
    const char *zValue;
    const char *zUuid;
    int branchMove = 0;
    blob_zero(&comment);
    if( p->zComment ){
      blob_appendf(&comment, " %s.", p->zComment);
    }
    /* Next loop expects tags to be sorted on UUID, so sort it. */
    qsort(p->aTag, p->nTag, sizeof(p->aTag[0]), tag_compare);
    for(i=0; i<p->nTag; i++){
      zUuid = p->aTag[i].zUuid;
      if( !zUuid ) continue;
      if( i==0 || fossil_strcmp(zUuid, p->aTag[i-1].zUuid)!=0 ){

        blob_appendf(&comment,
           " Edit [%S]:",
           zUuid);
        branchMove = 0;
      }
      zName = p->aTag[i].zName;
      zValue = p->aTag[i].zValue;
      if( strcmp(zName, "*branch")==0 ){
        blob_appendf(&comment,
           " Move to branch [/timeline?r=%h&nd&dp=%S | %h].",
           zValue, zUuid, zValue);
        branchMove = 1;
        continue;
      }else if( strcmp(zName, "*bgcolor")==0 ){
        blob_appendf(&comment,
           " Change branch background color to \"%h\".", zValue);
        continue;
      }else if( strcmp(zName, "+bgcolor")==0 ){
        blob_appendf(&comment,
           " Change background color to \"%h\".", zValue);
        continue;
      }else if( strcmp(zName, "-bgcolor")==0 ){
        blob_appendf(&comment, " Cancel background color");
      }else if( strcmp(zName, "+comment")==0 ){
        blob_appendf(&comment, " Edit check-in comment.");
        continue;
      }else if( strcmp(zName, "+user")==0 ){
        blob_appendf(&comment, " Change user to \"%h\".", zValue);
        continue;
      }else if( strcmp(zName, "+date")==0 ){
        blob_appendf(&comment, " Timestamp %h.", zValue);
        continue;
      }else if( memcmp(zName, "-sym-",5)==0 ){
        if( !branchMove ) blob_appendf(&comment, " Cancel tag \"%h\"", &zName[5]);
      }else if( memcmp(zName, "*sym-",5)==0 ){
        if( !branchMove ){
          blob_appendf(&comment, " Add propagating tag \"%h\"", &zName[5]);
        }
      }else if( memcmp(zName, "+sym-",5)==0 ){
        blob_appendf(&comment, " Add tag \"%h\"", &zName[5]);


      }else if( strcmp(zName, "+closed")==0 ){
        blob_append(&comment, " Marked \"Closed\"", -1);
      }else if( strcmp(zName, "-closed")==0 ){
        blob_append(&comment, " Removed the \"Closed\" mark", -1);
      }else {
        if( zName[0]=='-' ){
          blob_appendf(&comment, " Cancel \"%h\"", &zName[1]);
        }else if( zName[0]=='+' ){
          blob_appendf(&comment, " Add \"%h\"", &zName[1]);
        }else{
          blob_appendf(&comment, " Add propagating \"%h\"", &zName[1]);
        }
        if( zValue && zValue[0] ){
          blob_appendf(&comment, " with value \"%h\".", zValue);
        }else{
          blob_appendf(&comment, ".");
        }
        continue;
      }
      if( zValue && zValue[0] ){
        blob_appendf(&comment, " with note \"%h\".", zValue);
      }else{
        blob_appendf(&comment, ".");
      }
    }
    /*blob_appendf(&comment, " &#91;[/info/%S | details]&#93;");*/
    if( blob_size(&comment)==0 ) blob_append(&comment, " ", 1);
    db_multi_exec(
      "REPLACE INTO event(type,mtime,objid,user,comment)"
      "VALUES('g',%.17g,%d,%Q,%Q)",
      p->rDate, rid, p->zUser, blob_str(&comment)+1
    );
    blob_reset(&comment);
  }
  db_end_transaction(0);
  if( p->type==CFTYPE_MANIFEST ){
    manifest_cache_insert(p);
  }else{
Changes to src/merge.c.
89
90
91
92
93
94
95


96
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
**
**   --case-sensitive BOOL   Override the case-sensitive setting.  If false,
**                           files whose names differ only in case are taken
**                           to be the same file.
**
**   -f|--force              Force the merge even if it would be a no-op.
**


**   -n|--dry-run            If given, display instead of run actions
**
**   -v|--verbose            Show additional details of the merge
*/
void merge_cmd(void){
  int vid;              /* Current version "V" */
  int mid;              /* Version we are merging from "M" */
  int pid;              /* The pivot version - most recent common ancestor P */
  int verboseFlag;      /* True if the -v|--verbose option is present */

  int pickFlag;         /* True if the --cherrypick option is present */
  int backoutFlag;      /* True if the --backout option is present */
  int dryRunFlag;       /* True if the --dry-run or -n option is present */
  int forceFlag;        /* True if the --force or -f option is present */
  const char *zBinGlob; /* The value of --binary */
  const char *zPivot;   /* The value of --baseline */
  int debugFlag;        /* True if --debug is present */







>
>









>







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
**
**   --case-sensitive BOOL   Override the case-sensitive setting.  If false,
**                           files whose names differ only in case are taken
**                           to be the same file.
**
**   -f|--force              Force the merge even if it would be a no-op.
**
**   --integrate             Merged branch will be closed when committing.
**
**   -n|--dry-run            If given, display instead of run actions
**
**   -v|--verbose            Show additional details of the merge
*/
void merge_cmd(void){
  int vid;              /* Current version "V" */
  int mid;              /* Version we are merging from "M" */
  int pid;              /* The pivot version - most recent common ancestor P */
  int verboseFlag;      /* True if the -v|--verbose option is present */
  int integrateFlag;    /* True if the --integrate option is present */
  int pickFlag;         /* True if the --cherrypick option is present */
  int backoutFlag;      /* True if the --backout option is present */
  int dryRunFlag;       /* True if the --dry-run or -n option is present */
  int forceFlag;        /* True if the --force or -f option is present */
  const char *zBinGlob; /* The value of --binary */
  const char *zPivot;   /* The value of --baseline */
  int debugFlag;        /* True if --debug is present */
126
127
128
129
130
131
132

133
134
135
136
137
138
139

  undo_capture_command_line();
  verboseFlag = find_option("verbose","v",0)!=0;
  if( !verboseFlag ){
    verboseFlag = find_option("detail",0,0)!=0; /* deprecated */
  }
  pickFlag = find_option("cherrypick",0,0)!=0;

  backoutFlag = find_option("backout",0,0)!=0;
  debugFlag = find_option("debug",0,0)!=0;
  zBinGlob = find_option("binary",0,1);
  dryRunFlag = find_option("dry-run","n",0)!=0;
  if( !dryRunFlag ){
    dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */
  }







>







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

  undo_capture_command_line();
  verboseFlag = find_option("verbose","v",0)!=0;
  if( !verboseFlag ){
    verboseFlag = find_option("detail",0,0)!=0; /* deprecated */
  }
  pickFlag = find_option("cherrypick",0,0)!=0;
  integrateFlag = find_option("integrate",0,0)!=0;
  backoutFlag = find_option("backout",0,0)!=0;
  debugFlag = find_option("debug",0,0)!=0;
  zBinGlob = find_option("binary",0,1);
  dryRunFlag = find_option("dry-run","n",0)!=0;
  if( !dryRunFlag ){
    dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */
  }
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
    /* No version specified on the command-line so pick the most recent
    ** leaf that is (1) not the version currently checked out and (2)
    ** has not already been merged into the current checkout and (3)
    ** the leaf is not closed and (4) the leaf is in the same branch
    ** as the current checkout. 
    */
    Stmt q;
    if( pickFlag || backoutFlag ){
      fossil_fatal("cannot use --cherrypick or --backout with a fork merge");
    }
    mid = db_int(0,
      "SELECT leaf.rid"
      "  FROM leaf, event"
      " WHERE leaf.rid=event.objid"
      "   AND leaf.rid!=%d"                                /* Constraint (1) */
      "   AND leaf.rid NOT IN (SELECT merge FROM vmerge)"  /* Constraint (2) */







|
|







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    /* No version specified on the command-line so pick the most recent
    ** leaf that is (1) not the version currently checked out and (2)
    ** has not already been merged into the current checkout and (3)
    ** the leaf is not closed and (4) the leaf is in the same branch
    ** as the current checkout. 
    */
    Stmt q;
    if( pickFlag || backoutFlag || integrateFlag){
      fossil_fatal("cannot use --backout, --cherrypick or --integrate with a fork merge");
    }
    mid = db_int(0,
      "SELECT leaf.rid"
      "  FROM leaf, event"
      " WHERE leaf.rid=event.objid"
      "   AND leaf.rid!=%d"                                /* Constraint (1) */
      "   AND leaf.rid NOT IN (SELECT merge FROM vmerge)"  /* Constraint (2) */
218
219
220
221
222
223
224



225
226
227
228
229
230
231
    if( pid==0 || !is_a_version(pid) ){
      fossil_fatal("not a version: %s", zPivot);
    }
    if( pickFlag ){
      fossil_fatal("incompatible options: --cherrypick & --baseline");
    }
  }else if( pickFlag || backoutFlag ){



    pid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", mid);
    if( pid<=0 ){
      fossil_fatal("cannot find an ancestor for %s", g.argv[2]);
    }
  }else{
    pivot_set_primary(mid);
    pivot_set_secondary(vid);







>
>
>







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
    if( pid==0 || !is_a_version(pid) ){
      fossil_fatal("not a version: %s", zPivot);
    }
    if( pickFlag ){
      fossil_fatal("incompatible options: --cherrypick & --baseline");
    }
  }else if( pickFlag || backoutFlag ){
    if( integrateFlag ){
      fossil_fatal("incompatible options: --integrate & --cherrypick or --backout");
    }
    pid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", mid);
    if( pid<=0 ){
      fossil_fatal("cannot find an ancestor for %s", g.argv[2]);
    }
  }else{
    pivot_set_primary(mid);
    pivot_set_secondary(vid);
248
249
250
251
252
253
254
255












256
257
258
259
260
261
262
263
264
  if( !is_a_version(pid) ){
    fossil_fatal("not a version: record #%d", pid);
  }
  if( !forceFlag && mid==pid ){
    fossil_print("Merge skipped because it is a no-op. "
                 " Use --force to override.\n");
    return;
  }












  if( verboseFlag ){
    print_checkin_description(mid, 12, "merge-from:");
    print_checkin_description(pid, 12, "baseline:");
  }
  vfile_check_signature(vid, CKSIG_ENOTFILE);
  db_begin_transaction();
  if( !dryRunFlag ) undo_begin();
  load_vfile_from_rid(mid);
  load_vfile_from_rid(pid);








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

|







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  if( !is_a_version(pid) ){
    fossil_fatal("not a version: record #%d", pid);
  }
  if( !forceFlag && mid==pid ){
    fossil_print("Merge skipped because it is a no-op. "
                 " Use --force to override.\n");
    return;
  }
  if( integrateFlag ){
    if( db_exists("SELECT 1 FROM vmerge WHERE id=-4")) {
      /* Fossil earlier than [55cacfcace] cannot handle this,
       * therefore disallow it. */
      fossil_fatal("Integration of another branch already in progress."
        "  Commit or Undo needed first", g.argv[2]);
    }
    if( !is_a_leaf(mid) ){
      fossil_warning("ignoring --integrate: %s is not a leaf", g.argv[2]);
      integrateFlag = 0;
    }
  }
  if( verboseFlag ){
    print_checkin_description(mid, 12, integrateFlag?"integrate:":"merge-from:");
    print_checkin_description(pid, 12, "baseline:");
  }
  vfile_check_signature(vid, CKSIG_ENOTFILE);
  db_begin_transaction();
  if( !dryRunFlag ) undo_begin();
  load_vfile_from_rid(mid);
  load_vfile_from_rid(pid);
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
    int idm = db_column_int(&q, 0);
    int rowid = db_column_int(&q, 1);
    int idv;
    const char *zName;
    char *zFullName;
    db_multi_exec(
      "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)"
      "  SELECT %d,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
      vid, idm
    );
    idv = db_last_insert_rowid();
    db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
    zName = db_column_text(&q, 2);
    zFullName = mprintf("%s%s", g.zLocalRoot, zName);
    if( file_wd_isfile_or_link(zFullName) ){
      fossil_print("ADDED %s (overwrites an unmanaged file)\n", zName);







|
|







451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
    int idm = db_column_int(&q, 0);
    int rowid = db_column_int(&q, 1);
    int idv;
    const char *zName;
    char *zFullName;
    db_multi_exec(
      "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)"
      "  SELECT %d,%d,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
      vid, integrateFlag?5:3, idm
    );
    idv = db_last_insert_rowid();
    db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
    zName = db_column_text(&q, 2);
    zFullName = mprintf("%s%s", g.zLocalRoot, zName);
    if( file_wd_isfile_or_link(zFullName) ){
      fossil_print("ADDED %s (overwrites an unmanaged file)\n", zName);
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
    const char *zName = db_column_text(&q, 2);
    int islinkm = db_column_int(&q, 3);
    /* Copy content from idm over into idv.  Overwrite idv. */
    fossil_print("UPDATE %s\n", zName);
    if( !dryRunFlag ){
      undo_save(zName);
      db_multi_exec(
        "UPDATE vfile SET mtime=0, mrid=%d, chnged=2, islink=%d "
        " WHERE id=%d", ridm, islinkm, idv
      );
      vfile_to_disk(0, idv, 0, 0);
    }
  }
  db_finalize(&q);

  /*







|
|







491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
    const char *zName = db_column_text(&q, 2);
    int islinkm = db_column_int(&q, 3);
    /* Copy content from idm over into idv.  Overwrite idv. */
    fossil_print("UPDATE %s\n", zName);
    if( !dryRunFlag ){
      undo_save(zName);
      db_multi_exec(
        "UPDATE vfile SET mtime=0, mrid=%d, chnged=%d, islink=%d "
        " WHERE id=%d", ridm, integrateFlag?4:2, islinkm, idv
      );
      vfile_to_disk(0, idv, 0, 0);
    }
  }
  db_finalize(&q);

  /*
642
643
644
645
646
647
648


649
650
651
652
653
654
       "REPLACE INTO vvar(name,value)"
       " SELECT 'ci-comment', coalesce(ecomment,comment) FROM event"
       "  WHERE type='ci' AND objid=%d",
       mid
    );
  }else if( backoutFlag ){
    db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-2,%d)",pid);


  }else{
    db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid);
  }
  undo_finish();
  db_end_transaction(dryRunFlag);
}







>
>






661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
       "REPLACE INTO vvar(name,value)"
       " SELECT 'ci-comment', coalesce(ecomment,comment) FROM event"
       "  WHERE type='ci' AND objid=%d",
       mid
    );
  }else if( backoutFlag ){
    db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-2,%d)",pid);
  }else if( integrateFlag ){
    db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-4,%d)",mid);
  }else{
    db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid);
  }
  undo_finish();
  db_end_transaction(dryRunFlag);
}
Changes to src/name.c.
246
247
248
249
250
251
252


253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
    "   AND event.objid=tagxref.rid "
    "   AND event.type GLOB '%q'",
    zTag, zType
  );
  if( rid>0 ) return rid;

  /* Undocumented:  numeric tags get translated directly into the RID */


  for(i=0; fossil_isdigit(zTag[i]); i++){}
  if( zTag[i]==0 ){
    if( strcmp(zType,"*")==0 ){
      rid = atoi(zTag);
    }else{
      rid = db_int(0, 
        "SELECT event.objid"
        "  FROM event"
        " WHERE event.objid=%s"
        "   AND event.type GLOB '%q'", zTag, zType);

    }
  }
  return rid;
}


/*







>
>
|
|
|
|
|
|
|
|
|
|
>







246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    "   AND event.objid=tagxref.rid "
    "   AND event.type GLOB '%q'",
    zTag, zType
  );
  if( rid>0 ) return rid;

  /* Undocumented:  numeric tags get translated directly into the RID */
  if( memcmp(zTag, "rid:", 4)==0 ){
    zTag += 4;
    for(i=0; fossil_isdigit(zTag[i]); i++){}
    if( zTag[i]==0 ){
      if( strcmp(zType,"*")==0 ){
        rid = atoi(zTag);
      }else{
        rid = db_int(0, 
          "SELECT event.objid"
          "  FROM event"
          " WHERE event.objid=%s"
          "   AND event.type GLOB '%q'", zTag, zType);
      }
    }
  }
  return rid;
}


/*
Changes to src/pivot.c.
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
  Stmt q1, q2, u1, i1;
  int rid = 0;
  
  /* aqueue must contain at least one primary and one other.  Otherwise
  ** we abort early
  */
  if( db_int(0, "SELECT count(distinct src) FROM aqueue")<2 ){
    fossil_panic("lack both primary and secondary files");
  }

  /* Prepare queries we will be needing
  **
  ** The first query finds the oldest pending version on the aqueue.  This
  ** will be next one searched.
  */







|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
  Stmt q1, q2, u1, i1;
  int rid = 0;
  
  /* aqueue must contain at least one primary and one other.  Otherwise
  ** we abort early
  */
  if( db_int(0, "SELECT count(distinct src) FROM aqueue")<2 ){
    fossil_fatal("lack both primary and secondary files");
  }

  /* Prepare queries we will be needing
  **
  ** The first query finds the oldest pending version on the aqueue.  This
  ** will be next one searched.
  */
Changes to src/printf.c.
20
21
22
23
24
25
26

27
28
29
30
31
32
33
*/
#include "config.h"
#include "printf.h"
#if defined(_WIN32)
#   include <io.h>
#   include <fcntl.h>
#endif


/*
** Conversion types fall into various categories as defined by the
** following enumeration.
*/
#define etRADIX       1 /* Integer types.  %d, %x, %o, and so forth */
#define etFLOAT       2 /* Floating point.  %f */







>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
*/
#include "config.h"
#include "printf.h"
#if defined(_WIN32)
#   include <io.h>
#   include <fcntl.h>
#endif
#include <time.h>

/*
** Conversion types fall into various categories as defined by the
** following enumeration.
*/
#define etRADIX       1 /* Integer types.  %d, %x, %o, and so forth */
#define etFLOAT       2 /* Floating point.  %f */
904
905
906
907
908
909
910

































911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926

927



928

929
930
931

932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948


949
950
951
952
953
954
955
956
957
958
959
960
961
962
963

964
965
966
967
968
969
970
  b = empty_blob;
  vxprintf(&b, zFormat, ap);
  fossil_puts(blob_str(&b), 1);
  blob_reset(&b);
  va_end(ap);
}



































/*
** The following variable becomes true while processing a fatal error
** or a panic.  If additional "recursive-fatal" errors occur while
** shutting down, the recursive errors are silently ignored.
*/
static int mainInFatalError = 0;

/*
** Print an error message, rollback all databases, and quit.  These
** routines never return.
*/
NORETURN void fossil_panic(const char *zFormat, ...){
  char *z;
  va_list ap;
  int rc = 1;

  static int once = 1;



  mainInFatalError = 1;

  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);

#ifdef FOSSIL_ENABLE_JSON
  if( g.json.isJsonMode ){
    json_err( 0, z, 1 );
    if( g.isHTTP ){
      rc = 0 /* avoid HTTP 500 */;
    }
  }
  else
#endif
  {
    if( g.cgiOutput && once ){
      once = 0;
      cgi_printf("<p class=\"generalError\">%h</p>", z);
      cgi_reply();
    }else if( !g.fQuiet ){
      fossil_force_newline();
      fossil_trace("Fossil internal error: %s\n", z);


    }
  }
  free(z);
  db_force_rollback();
  fossil_exit(rc);
}

NORETURN void fossil_fatal(const char *zFormat, ...){
  char *z;
  int rc = 1;
  va_list ap;
  mainInFatalError = 1;
  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);

#ifdef FOSSIL_ENABLE_JSON
  if( g.json.isJsonMode ){
    json_err( g.json.resultCode, z, 1 );
    if( g.isHTTP ){
      rc = 0 /* avoid HTTP 500 */;
    }
  }







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













<


>
|
>
>
>

>

|

>










|
<




|
>
>


<
<
|










>







905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957

958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981

982
983
984
985
986
987
988
989
990


991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
  b = empty_blob;
  vxprintf(&b, zFormat, ap);
  fossil_puts(blob_str(&b), 1);
  blob_reset(&b);
  va_end(ap);
}

/*
** Write a message to the error log, if the error log filename is
** defined.
*/
static void fossil_errorlog(const char *zFormat, ...){
  struct tm *pNow;
  time_t now;
  FILE *out;
  const char *z;
  int i;
  va_list ap;
  static const char *azEnv[] = { "HTTP_HOST", "HTTP_USER_AGENT",
      "PATH_INFO", "QUERY_STRING", "REMOTE_ADDR", "REQUEST_METHOD",
      "REQUEST_URI", "SCRIPT_NAME" };
  if( g.zErrlog==0 ) return;
  out = fopen(g.zErrlog, "a");
  if( out==0 ) return;
  now = time(0);
  pNow = gmtime(&now);
  fprintf(out, "------------- %04d-%02d-%02d %02d:%02d:%02d UTC ------------\n",
          pNow->tm_year+1900, pNow->tm_mon+1, pNow->tm_mday+1,
          pNow->tm_hour, pNow->tm_min, pNow->tm_sec);
  va_start(ap, zFormat);
  vfprintf(out, zFormat, ap);
  fprintf(out, "\n");
  va_end(ap);
  for(i=0; i<sizeof(azEnv)/sizeof(azEnv[0]); i++){
    if( (z = getenv(azEnv[i]))!=0 || (z = P(azEnv[i]))!=0 ){
      fprintf(out, "%s=%s\n", azEnv[i], z);
    }
  }
  fclose(out);
}

/*
** The following variable becomes true while processing a fatal error
** or a panic.  If additional "recursive-fatal" errors occur while
** shutting down, the recursive errors are silently ignored.
*/
static int mainInFatalError = 0;

/*
** Print an error message, rollback all databases, and quit.  These
** routines never return.
*/
NORETURN void fossil_panic(const char *zFormat, ...){

  va_list ap;
  int rc = 1;
  char z[1000];
  static int once = 0;

  if( once ) exit(1);
  once = 1;
  mainInFatalError = 1;
  db_force_rollback();
  va_start(ap, zFormat);
  sqlite3_vsnprintf(sizeof(z),z,zFormat, ap);
  va_end(ap);
  fossil_errorlog("panic: %s", z);
#ifdef FOSSIL_ENABLE_JSON
  if( g.json.isJsonMode ){
    json_err( 0, z, 1 );
    if( g.isHTTP ){
      rc = 0 /* avoid HTTP 500 */;
    }
  }
  else
#endif
  {
    if( g.cgiOutput ){

      cgi_printf("<p class=\"generalError\">%h</p>", z);
      cgi_reply();
    }else if( !g.fQuiet ){
      fossil_force_newline();
      fossil_puts("Fossil internal error: ", 1);
      fossil_puts(z, 1);
      fossil_puts("\n", 1);
    }
  }


  exit(rc);
}

NORETURN void fossil_fatal(const char *zFormat, ...){
  char *z;
  int rc = 1;
  va_list ap;
  mainInFatalError = 1;
  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);
  fossil_errorlog("fatal: %s", z);
#ifdef FOSSIL_ENABLE_JSON
  if( g.json.isJsonMode ){
    json_err( g.json.resultCode, z, 1 );
    if( g.isHTTP ){
      rc = 0 /* avoid HTTP 500 */;
    }
  }
999
1000
1001
1002
1003
1004
1005

1006
1007
1008
1009
1010
1011
1012
  va_list ap;
  int rc = 1;
  if( mainInFatalError ) return;
  mainInFatalError = 1;
  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);

#ifdef FOSSIL_ENABLE_JSON
  if( g.json.isJsonMode ){
    json_err( g.json.resultCode, z, 1 );
    if( g.isHTTP ){
      rc = 0 /* avoid HTTP 500 */;
    }
  } else







>







1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
  va_list ap;
  int rc = 1;
  if( mainInFatalError ) return;
  mainInFatalError = 1;
  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);
  fossil_errorlog("fatal: %s", z);
#ifdef FOSSIL_ENABLE_JSON
  if( g.json.isJsonMode ){
    json_err( g.json.resultCode, z, 1 );
    if( g.isHTTP ){
      rc = 0 /* avoid HTTP 500 */;
    }
  } else
1029
1030
1031
1032
1033
1034
1035

1036
1037
1038
1039
1040
1041
1042
/* Print a warning message */
void fossil_warning(const char *zFormat, ...){
  char *z;
  va_list ap;
  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);

#ifdef FOSSIL_ENABLE_JSON
  if(g.json.isJsonMode){
    json_warn( FSL_JSON_W_UNKNOWN, z );
  }else
#endif
  {
    if( g.cgiOutput ){







>







1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
/* Print a warning message */
void fossil_warning(const char *zFormat, ...){
  char *z;
  va_list ap;
  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);
  fossil_errorlog("warning: %s", z);
#ifdef FOSSIL_ENABLE_JSON
  if(g.json.isJsonMode){
    json_warn( FSL_JSON_W_UNKNOWN, z );
  }else
#endif
  {
    if( g.cgiOutput ){
Changes to src/rebuild.c.
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
      fossil_filename_free(zUtf8Name);
      if( file_isdir(zSubpath)==1 ){
        recon_read_dir(zSubpath);
      }
      blob_init(&path, 0, 0);
      blob_appendf(&path, "%s", zSubpath);
      if( blob_read_from_file(&aContent, blob_str(&path))==-1 ){
        fossil_panic("some unknown error occurred while reading \"%s\"", 
                     blob_str(&path));
      }
      content_put(&aContent);
      blob_reset(&path);
      blob_reset(&aContent);
      free(zSubpath);
      fossil_print("\r%d", ++nFileRead);
      fflush(stdout);
    }
    closedir(d);
  }else {
    fossil_panic("encountered error %d while trying to open \"%s\".",
                  errno, g.argv[3]);
  }
  fossil_filename_free(zUnicodePath);
}

/*
** COMMAND: reconstruct*







|











|







860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
      fossil_filename_free(zUtf8Name);
      if( file_isdir(zSubpath)==1 ){
        recon_read_dir(zSubpath);
      }
      blob_init(&path, 0, 0);
      blob_appendf(&path, "%s", zSubpath);
      if( blob_read_from_file(&aContent, blob_str(&path))==-1 ){
        fossil_fatal("some unknown error occurred while reading \"%s\"", 
                     blob_str(&path));
      }
      content_put(&aContent);
      blob_reset(&path);
      blob_reset(&aContent);
      free(zSubpath);
      fossil_print("\r%d", ++nFileRead);
      fflush(stdout);
    }
    closedir(d);
  }else {
    fossil_fatal("encountered error %d while trying to open \"%s\".",
                  errno, g.argv[3]);
  }
  fossil_filename_free(zUnicodePath);
}

/*
** COMMAND: reconstruct*
Changes to src/report.c.
76
77
78
79
80
81
82

83
84
85
86
87
88
89
    }
    if( g.perm.TktFmt ){
      blob_appendf(&ril, "[%zsql</a>]",
                         href("%R/rptsql?rn=%d", rn));
    }
    blob_appendf(&ril, "</li>\n");
  }


  Th_Store("report_items", blob_str(&ril));
  
  Th_Render(zScript);
  
  blob_reset(&ril);
  if( g.thTrace ) Th_Trace("END_REPORTLIST<br />\n", -1);







>







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    }
    if( g.perm.TktFmt ){
      blob_appendf(&ril, "[%zsql</a>]",
                         href("%R/rptsql?rn=%d", rn));
    }
    blob_appendf(&ril, "</li>\n");
  }
  db_finalize(&q);

  Th_Store("report_items", blob_str(&ril));
  
  Th_Render(zScript);
  
  blob_reset(&ril);
  if( g.thTrace ) Th_Trace("END_REPORTLIST<br />\n", -1);
Changes to src/schema.c.
473
474
475
476
477
478
479
480
481
482

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
@ -- Each entry in the vfile table represents a single file in the
@ -- current checkout.
@ --
@ -- The file.rid field is 0 for files or folders that have been
@ -- added but not yet committed.
@ --
@ -- Vfile.chnged is 0 for unmodified files, 1 for files that have
@ -- been edited or which have been subjected to a 3-way merge.  
@ -- Vfile.chnged is 2 if the file has been replaced from a different
@ -- version by the merge and 3 if the file has been added by a merge.

@ -- The difference between vfile.chnged==2 and a regular add is that
@ -- with vfile.chnged==2 we know that the current version of the file
@ -- is already in the repository.
@ -- 
@ --
@ CREATE TABLE vfile(
@   id INTEGER PRIMARY KEY,           -- ID of the checked out file
@   vid INTEGER REFERENCES blob,      -- The baseline this file is part of.
@   chnged INT DEFAULT 0,             -- 0:unchnged 1:edited 2:m-chng 3:m-add
@   deleted BOOLEAN DEFAULT 0,        -- True if deleted 
@   isexe BOOLEAN,                    -- True if file should be executable
@   islink BOOLEAN,                    -- True if file should be symlink
@   rid INTEGER,                      -- Originally from this repository record
@   mrid INTEGER,                     -- Based on this record due to a merge
@   mtime INTEGER,                    -- Mtime of file on disk. sec since 1970
@   pathname TEXT,                    -- Full pathname relative to root
@   origname TEXT,                    -- Original pathname. NULL if unchanged
@   UNIQUE(pathname,vid)
@ );
@
@ -- This table holds a record of uncommitted merges in the local
@ -- file tree.  If a VFILE entry with id has merged with another
@ -- record, there is an entry in this table with (id,merge) where
@ -- merge is the RECORD table entry that the file merged against.
@ -- An id of 0 here means the version record itself.  When id==(-1)
@ -- that is a cherrypick merge and id==(-2) is a backout merge.

@
@ CREATE TABLE vmerge(
@   id INTEGER REFERENCES vfile,      -- VFILE entry that has been merged
@   merge INTEGER,                    -- Merged with this record
@   UNIQUE(id, merge)
@ );
@







|


>
|
|
|
<




|
|

|












|
|
>







473
474
475
476
477
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
@ -- Each entry in the vfile table represents a single file in the
@ -- current checkout.
@ --
@ -- The file.rid field is 0 for files or folders that have been
@ -- added but not yet committed.
@ --
@ -- Vfile.chnged is 0 for unmodified files, 1 for files that have
@ -- been edited or which have been subjected to a 3-way merge.
@ -- Vfile.chnged is 2 if the file has been replaced from a different
@ -- version by the merge and 3 if the file has been added by a merge.
@ -- Vfile.chnged is 4|5 is the same as 2|3, but the operation has been
@ -- done by an --integrate merge.  The difference between vfile.chnged==2|4
@ -- and a regular add is that with vfile.chnged==2|4 we know that the
@ -- current version of the file is already in the repository.

@ --
@ CREATE TABLE vfile(
@   id INTEGER PRIMARY KEY,           -- ID of the checked out file
@   vid INTEGER REFERENCES blob,      -- The baseline this file is part of.
@   chnged INT DEFAULT 0,             -- 0:unchnged 1:edited 2:m-chng 3:m-add 4:i-chng 5:i-add
@   deleted BOOLEAN DEFAULT 0,        -- True if deleted
@   isexe BOOLEAN,                    -- True if file should be executable
@   islink BOOLEAN,                   -- True if file should be symlink
@   rid INTEGER,                      -- Originally from this repository record
@   mrid INTEGER,                     -- Based on this record due to a merge
@   mtime INTEGER,                    -- Mtime of file on disk. sec since 1970
@   pathname TEXT,                    -- Full pathname relative to root
@   origname TEXT,                    -- Original pathname. NULL if unchanged
@   UNIQUE(pathname,vid)
@ );
@
@ -- This table holds a record of uncommitted merges in the local
@ -- file tree.  If a VFILE entry with id has merged with another
@ -- record, there is an entry in this table with (id,merge) where
@ -- merge is the RECORD table entry that the file merged against.
@ -- An id of 0 or <-3 here means the version record itself.  When
@ -- id==(-1) that is a cherrypick merge, id==(-2) that is a
@ -- backout merge and id==(-4) is a integrate merge.
@
@ CREATE TABLE vmerge(
@   id INTEGER REFERENCES vfile,      -- VFILE entry that has been merged
@   merge INTEGER,                    -- Merged with this record
@   UNIQUE(id, merge)
@ );
@
Changes to src/search.c.
164
165
166
167
168
169
170
171
172
173








174
175
176
177
178

179
180






181
182
183
184
185
186
187
     search_score_sqlfunc, 0, 0);
}

/*
** Testing the search function.
**
** COMMAND: search*
** %fossil search pattern...
**
** Search for timeline entries matching the pattern.








*/
void search_cmd(void){
  Search *p;
  Blob pattern;
  int i;

  Stmt q;
  int iBest;







  db_must_be_within_tree();
  if( g.argc<2 ) return;
  blob_init(&pattern, g.argv[2], -1);
  for(i=3; i<g.argc; i++){
    blob_appendf(&pattern, " %s", g.argv[i]);
  }







|

|
>
>
>
>
>
>
>
>





>


>
>
>
>
>
>







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
     search_score_sqlfunc, 0, 0);
}

/*
** Testing the search function.
**
** COMMAND: search*
** %fossil search [-all|-a] [-limit|-n #] pattern...
**
** Search for timeline entries matching all words
** provided on the command line. Whole-word matches
** scope more highly than partial matches.
**
** Outputs, by default, some top-N fraction of the
** results. The -all option can be used to output
** all matches, regardless of their search score.
** -limit can be used to limit the number of entries
** returned.
*/
void search_cmd(void){
  Search *p;
  Blob pattern;
  int i;
  Blob sql = empty_blob;
  Stmt q;
  int iBest;
  char fAll = NULL != find_option("all", "a", 0); /* If set, do not lop
                                                     off the end of the
                                                     results. */
  char const * zLimit = find_option("limit","n",1);
  int const nLimit = zLimit ? atoi(zLimit) : -1; /* Max number of entries
                                                    to list */

  db_must_be_within_tree();
  if( g.argc<2 ) return;
  blob_init(&pattern, g.argv[2], -1);
  for(i=3; i<g.argc; i++){
    blob_appendf(&pattern, " %s", g.argv[i]);
  }
196
197
198
199
200
201
202
203
204




205
206



207
208
209
210
     "   SELECT blob.rid, uuid, datetime(event.mtime, 'localtime'),"
     "          coalesce(ecomment,comment),"
     "          score(coalesce(ecomment,comment)) AS y"
     "     FROM event, blob"
     "    WHERE blob.rid=event.objid AND y>0;"
  );
  iBest = db_int(0, "SELECT max(x) FROM srch");
  db_prepare(&q, 
    "SELECT rid, uuid, date, comment, 0, 0 FROM srch"




    " WHERE x>%d ORDER BY x DESC, date DESC",
    iBest/3



  );
  print_timeline(&q, 1000, 0);
  db_finalize(&q);
}







|
|
>
>
>
>
|
|
>
>
>
|



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
     "   SELECT blob.rid, uuid, datetime(event.mtime, 'localtime'),"
     "          coalesce(ecomment,comment),"
     "          score(coalesce(ecomment,comment)) AS y"
     "     FROM event, blob"
     "    WHERE blob.rid=event.objid AND y>0;"
  );
  iBest = db_int(0, "SELECT max(x) FROM srch");
  blob_append(&sql,
              "SELECT rid, uuid, date, comment, 0, 0 FROM srch "
              "WHERE 1 ", -1);
  if(!fAll){
    blob_appendf(&sql,"AND x>%d ", iBest/3);
  }
  blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
  if(nLimit>0){
    blob_appendf(&sql, "LIMIT %d", nLimit);
  }
  db_prepare(&q, blob_str(&sql));
  blob_reset(&sql);
  print_timeline(&q, 1000, 0);
  db_finalize(&q);
}
Changes to src/setup.c.
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  }
  @ </table>
  @ </td><td class="usetupColumnLayout">
  @ <span class="note">Notes:</span>
  @ <ol>
  @ <li><p>The permission flags are as follows:</p>
  @ <table>
     @ <tr><td valign="top"><b>a</b></td>
     @   <td><i>Admin:</i> Create and delete users</td></tr>
     @ <tr><td valign="top"><b>b</b></td>
     @   <td><i>Attach:</i> Add attachments to wiki or tickets</td></tr>
     @ <tr><td valign="top"><b>c</b></td>
     @   <td><i>Append-Tkt:</i> Append to tickets</td></tr>
     @ <tr><td valign="top"><b>d</b></td>
     @   <td><i>Delete:</i> Delete wiki and tickets</td></tr>
     @ <tr><td valign="top"><b>e</b></td>
     @   <td><i>Email:</i> View sensitive data such as EMail addresses</td></tr>
     @ <tr><td valign="top"><b>f</b></td>
     @   <td><i>New-Wiki:</i> Create new wiki pages</td></tr>
     @ <tr><td valign="top"><b>g</b></td>
     @   <td><i>Clone:</i> Clone the repository</td></tr>
     @ <tr><td valign="top"><b>h</b></td>
     @   <td><i>Hyperlinks:</i> Show hyperlinks to detailed
     @   repository history</td></tr>
     @ <tr><td valign="top"><b>i</b></td>
     @   <td><i>Check-In:</i> Commit new versions in the repository</td></tr>
     @ <tr><td valign="top"><b>j</b></td>
     @   <td><i>Read-Wiki:</i> View wiki pages</td></tr>
     @ <tr><td valign="top"><b>k</b></td>
     @   <td><i>Write-Wiki:</i> Edit wiki pages</td></tr>
     @ <tr><td valign="top"><b>l</b></td>
     @   <td><i>Mod-Wiki:</i> Moderator for wiki pages</td></tr>
     @ <tr><td valign="top"><b>m</b></td>
     @   <td><i>Append-Wiki:</i> Append to wiki pages</td></tr>
     @ <tr><td valign="top"><b>n</b></td>
     @   <td><i>New-Tkt:</i> Create new tickets</td></tr>
     @ <tr><td valign="top"><b>o</b></td>
     @   <td><i>Check-Out:</i> Check out versions</td></tr>
     @ <tr><td valign="top"><b>p</b></td>
     @   <td><i>Password:</i> Change your own password</td></tr>
     @ <tr><td valign="top"><b>q</b></td>
     @   <td><i>Mod-Tkt:</i> Moderator for tickets</td></tr>
     @ <tr><td valign="top"><b>r</b></td>
     @   <td><i>Read-Tkt:</i> View tickets</td></tr>
     @ <tr><td valign="top"><b>s</b></td>
     @   <td><i>Setup/Super-user:</i> Setup and configure this website</td></tr>
     @ <tr><td valign="top"><b>t</b></td>
     @   <td><i>Tkt-Report:</i> Create new bug summary reports</td></tr>
     @ <tr><td valign="top"><b>u</b></td>
     @   <td><i>Reader:</i> Inherit privileges of
     @   user <tt>reader</tt></td></tr>
     @ <tr><td valign="top"><b>v</b></td>
     @   <td><i>Developer:</i> Inherit privileges of
     @   user <tt>developer</tt></td></tr>
     @ <tr><td valign="top"><b>w</b></td>
     @   <td><i>Write-Tkt:</i> Edit tickets</td></tr>
     @ <tr><td valign="top"><b>x</b></td>
     @   <td><i>Private:</i> Push and/or pull private branches</td></tr>
     @ <tr><td valign="top"><b>z</b></td>
     @   <td><i>Zip download:</i> Download a baseline via the
     @   <tt>/zip</tt> URL even without
     @    check<span class="capability">o</span>ut
     @    and <span class="capability">h</span>istory permissions</td></tr>
  @ </table>
  @ </li>
  @







|

|

|

|

|

|

|

|


|

|

|

|

|

|

|

|

|

|

|

|

|


|


|

|

|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  }
  @ </table>
  @ </td><td class="usetupColumnLayout">
  @ <span class="note">Notes:</span>
  @ <ol>
  @ <li><p>The permission flags are as follows:</p>
  @ <table>
     @ <tr><th valign="top">a</th>
     @   <td><i>Admin:</i> Create and delete users</td></tr>
     @ <tr><th valign="top">b</th>
     @   <td><i>Attach:</i> Add attachments to wiki or tickets</td></tr>
     @ <tr><th valign="top">c</th>
     @   <td><i>Append-Tkt:</i> Append to tickets</td></tr>
     @ <tr><th valign="top">d</th>
     @   <td><i>Delete:</i> Delete wiki and tickets</td></tr>
     @ <tr><th valign="top">e</th>
     @   <td><i>Email:</i> View sensitive data such as EMail addresses</td></tr>
     @ <tr><th valign="top">f</th>
     @   <td><i>New-Wiki:</i> Create new wiki pages</td></tr>
     @ <tr><th valign="top">g</th>
     @   <td><i>Clone:</i> Clone the repository</td></tr>
     @ <tr><th valign="top">h</th>
     @   <td><i>Hyperlinks:</i> Show hyperlinks to detailed
     @   repository history</td></tr>
     @ <tr><th valign="top">i</th>
     @   <td><i>Check-In:</i> Commit new versions in the repository</td></tr>
     @ <tr><th valign="top">j</th>
     @   <td><i>Read-Wiki:</i> View wiki pages</td></tr>
     @ <tr><th valign="top">k</th>
     @   <td><i>Write-Wiki:</i> Edit wiki pages</td></tr>
     @ <tr><th valign="top">l</th>
     @   <td><i>Mod-Wiki:</i> Moderator for wiki pages</td></tr>
     @ <tr><th valign="top">m</th>
     @   <td><i>Append-Wiki:</i> Append to wiki pages</td></tr>
     @ <tr><th valign="top">n</th>
     @   <td><i>New-Tkt:</i> Create new tickets</td></tr>
     @ <tr><th valign="top">o</th>
     @   <td><i>Check-Out:</i> Check out versions</td></tr>
     @ <tr><th valign="top">p</th>
     @   <td><i>Password:</i> Change your own password</td></tr>
     @ <tr><th valign="top">q</th>
     @   <td><i>Mod-Tkt:</i> Moderator for tickets</td></tr>
     @ <tr><th valign="top">r</th>
     @   <td><i>Read-Tkt:</i> View tickets</td></tr>
     @ <tr><th valign="top">s</th>
     @   <td><i>Setup/Super-user:</i> Setup and configure this website</td></tr>
     @ <tr><th valign="top">t</th>
     @   <td><i>Tkt-Report:</i> Create new bug summary reports</td></tr>
     @ <tr><th valign="top">u</th>
     @   <td><i>Reader:</i> Inherit privileges of
     @   user <tt>reader</tt></td></tr>
     @ <tr><th valign="top">v</th>
     @   <td><i>Developer:</i> Inherit privileges of
     @   user <tt>developer</tt></td></tr>
     @ <tr><th valign="top">w</th>
     @   <td><i>Write-Tkt:</i> Edit tickets</td></tr>
     @ <tr><th valign="top">x</th>
     @   <td><i>Private:</i> Push and/or pull private branches</td></tr>
     @ <tr><th valign="top">z</th>
     @   <td><i>Zip download:</i> Download a baseline via the
     @   <tt>/zip</tt> URL even without
     @    check<span class="capability">o</span>ut
     @    and <span class="capability">h</span>istory permissions</td></tr>
  @ </table>
  @ </li>
  @
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
    @ is not currently part of any login-group.
    @ To join a login group, fill out the form below.</p>
    @
    @ <form action="%s(g.zTop)/setup_login_group" method="post"><div>
    login_insert_csrf_secret();
    @ <blockquote><table border="0">
    @
    @ <tr><td align="right"><b>Repository filename in group to join:</b></td>
    @ <td width="5"></td><td>
    @ <input type="text" size="50" value="%h(zRepo)" name="repo"></td></tr>
    @
    @ <tr><td align="right"><b>Login on the above repo:</b></td>
    @ <td width="5"></td><td>
    @ <input type="text" size="20" value="%h(zLogin)" name="login"></td></tr>
    @
    @ <tr><td align="right"><b>Password:</b></td>
    @ <td width="5"></td><td>
    @ <input type="password" size="20" name="pw"></td></tr>
    @
    @ <tr><td align="right"><b>Name of login-group:</b></td>
    @ <td width="5"></td><td>
    @ <input type="text" size="30" value="%h(zNewName)" name="newname">
    @ (only used if creating a new login-group).</td></tr>
    @
    @ <tr><td colspan="3" align="center">
    @ <input type="submit" value="Join" name="join"></td></tr>
    @ </table></blockquote></div></form>







|



|



|



|







1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
    @ is not currently part of any login-group.
    @ To join a login group, fill out the form below.</p>
    @
    @ <form action="%s(g.zTop)/setup_login_group" method="post"><div>
    login_insert_csrf_secret();
    @ <blockquote><table border="0">
    @
    @ <tr><th align="right">Repository filename in group to join:</th>
    @ <td width="5"></td><td>
    @ <input type="text" size="50" value="%h(zRepo)" name="repo"></td></tr>
    @
    @ <tr><th align="right">Login on the above repo:</th>
    @ <td width="5"></td><td>
    @ <input type="text" size="20" value="%h(zLogin)" name="login"></td></tr>
    @
    @ <tr><th align="right">Password:</th>
    @ <td width="5"></td><td>
    @ <input type="password" size="20" name="pw"></td></tr>
    @
    @ <tr><th align="right">Name of login-group:</th>
    @ <td width="5"></td><td>
    @ <input type="text" size="30" value="%h(zNewName)" name="newname">
    @ (only used if creating a new login-group).</td></tr>
    @
    @ <tr><td colspan="3" align="center">
    @ <input type="submit" value="Join" name="join"></td></tr>
    @ </table></blockquote></div></form>
Changes to src/shell.c.
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74





75
76
77
78
79
80
81
# include <editline/editline.h>
#endif
#if defined(HAVE_READLINE) && HAVE_READLINE==1
# include <readline/readline.h>
# include <readline/history.h>
#endif
#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
# define readline(p) local_getline(p,stdin,0)
# define add_history(X)
# define read_history(X)
# define write_history(X)
# define stifle_history(X)
#endif

#if defined(_WIN32) || defined(WIN32)
# include <io.h>
#define isatty(h) _isatty(h)
#define access(f,m) _access((f),(m))
#undef popen
#define popen(a,b) _popen((a),(b))
#undef pclose
#define pclose _pclose
#else
/* Make sure isatty() has a prototype.
*/
extern int isatty(int);





#endif

#if defined(_WIN32_WCE)
/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
 * thus we always assume that we have a console. That can be
 * overridden with the -batch command line option.
 */







<











|






>
>
>
>
>







49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# include <editline/editline.h>
#endif
#if defined(HAVE_READLINE) && HAVE_READLINE==1
# include <readline/readline.h>
# include <readline/history.h>
#endif
#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)

# define add_history(X)
# define read_history(X)
# define write_history(X)
# define stifle_history(X)
#endif

#if defined(_WIN32) || defined(WIN32)
# include <io.h>
#define isatty(h) _isatty(h)
#define access(f,m) _access((f),(m))
#undef popen
#define popen _popen
#undef pclose
#define pclose _pclose
#else
/* Make sure isatty() has a prototype.
*/
extern int isatty(int);

/* popen and pclose are not C89 functions and so are sometimes omitted from
** the <stdio.h> header */
extern FILE *popen(const char*,const char*);
extern int pclose(FILE*);
#endif

#if defined(_WIN32_WCE)
/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
 * thus we always assume that we have a console. That can be
 * overridden with the -batch command line option.
 */
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385








386
387
388
389
390
391
392
393
394
395
396
397
398
399


400




401

402
403
404
405
406
407
408

/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**
** The interface is like "readline" but no command-line editing
** is done.
*/
static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
  char *zLine;
  int nLine;
  int n;
  int inQuote = 0;

  if( zPrompt && *zPrompt ){
    printf("%s",zPrompt);
    fflush(stdout);
  }
  nLine = 100;
  zLine = malloc( nLine );
  if( zLine==0 ) return 0;
  n = 0;
  while( 1 ){
    if( n+100>nLine ){
      nLine = nLine*2 + 100;
      zLine = realloc(zLine, nLine);
      if( zLine==0 ) return 0;
    }
    if( fgets(&zLine[n], nLine - n, in)==0 ){
      if( n==0 ){
        free(zLine);
        return 0;
      }
      zLine[n] = 0;
      break;
    }
    while( zLine[n] ){
      if( zLine[n]=='"' ) inQuote = !inQuote;
      n++;
    }
    if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
      n--;
      if( n>0 && zLine[n-1]=='\r' ) n--;
      zLine[n] = 0;
      break;
    }
  }
  zLine = realloc( zLine, n+1 );
  return zLine;
}

/*
** Retrieve a single line of input text.
**
** zPrior is a string of prior text retrieved.  If not the empty
** string, then issue a continuation prompt.








*/
static char *one_input_line(const char *zPrior, FILE *in){
  char *zPrompt;
  char *zResult;
  if( in!=0 ){
    return local_getline(0, in, 0);
  }
  if( zPrior && zPrior[0] ){
    zPrompt = continuePrompt;
  }else{
    zPrompt = mainPrompt;
  }
  zResult = readline(zPrompt);
#if defined(HAVE_READLINE) && HAVE_READLINE==1


  if( zResult && *zResult ) add_history(zResult);




#endif

  return zResult;
}

struct previous_mode_data {
  int valid;        /* Is there legit data in here? */
  int mode;
  int showHeader;







|
|

|
<
|
|
<

<
<
<
<
<
<
<
<














|
<
<
<
|






<






|
|
>
>
>
>
>
>
>
>

|



|
<
<
<

|
<
<

>
>
|
>
>
>
>

>







332
333
334
335
336
337
338
339
340
341
342

343
344

345








346
347
348
349
350
351
352
353
354
355
356
357
358
359
360



361
362
363
364
365
366
367

368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389



390
391


392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408

/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**
** If zLine is not NULL then it is a malloced buffer returned from
** a previous call to this routine that may be reused.
*/
static char *local_getline(char *zLine, FILE *in){

  int nLine = zLine==0 ? 0 : 100;
  int n = 0;










  while( 1 ){
    if( n+100>nLine ){
      nLine = nLine*2 + 100;
      zLine = realloc(zLine, nLine);
      if( zLine==0 ) return 0;
    }
    if( fgets(&zLine[n], nLine - n, in)==0 ){
      if( n==0 ){
        free(zLine);
        return 0;
      }
      zLine[n] = 0;
      break;
    }
    while( zLine[n] ) n++;



    if( n>0 && zLine[n-1]=='\n' ){
      n--;
      if( n>0 && zLine[n-1]=='\r' ) n--;
      zLine[n] = 0;
      break;
    }
  }

  return zLine;
}

/*
** Retrieve a single line of input text.
**
** If in==0 then read from standard input and prompt before each line.
** If isContinuation is true, then a continuation prompt is appropriate.
** If isContinuation is zero, then the main prompt should be used.
**
** If zPrior is not NULL then it is a buffer from a prior call to this
** routine that can be reused.
**
** The result is stored in space obtained from malloc() and must either
** be freed by the caller or else passed back into this routine via the
** zPrior argument for reuse.
*/
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
  char *zPrompt;
  char *zResult;
  if( in!=0 ){
    zResult = local_getline(zPrior, in);



  }else{
    zPrompt = isContinuation ? continuePrompt : mainPrompt;


#if defined(HAVE_READLINE) && HAVE_READLINE==1
    free(zPrior);
    zResult = readline(zPrompt);
    if( zResult && *zResult ) add_history(zResult);
#else
    printf("%s", zPrompt);
    fflush(stdout);
    zResult = local_getline(zPrior, stdin);
#endif
  }
  return zResult;
}

struct previous_mode_data {
  int valid;        /* Is there legit data in here? */
  int mode;
  int showHeader;
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
      fputc('t', out);
    }else if( c=='\n' ){
      fputc('\\', out);
      fputc('n', out);
    }else if( c=='\r' ){
      fputc('\\', out);
      fputc('r', out);
    }else if( !isprint(c) ){
      fprintf(out, "\\%03o", c&0xff);
    }else{
      fputc(c, out);
    }
  }
  fputc('"', out);
}







|







550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
      fputc('t', out);
    }else if( c=='\n' ){
      fputc('\\', out);
      fputc('n', out);
    }else if( c=='\r' ){
      fputc('\\', out);
      fputc('r', out);
    }else if( !isprint(c&0xff) ){
      fprintf(out, "\\%03o", c&0xff);
    }else{
      fputc(c, out);
    }
  }
  fputc('"', out);
}
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
  if( nArg!=3 ) return 1;
  zTable = azArg[0];
  zType = azArg[1];
  zSql = azArg[2];
  
  if( strcmp(zTable, "sqlite_sequence")==0 ){
    zPrepStmt = "DELETE FROM sqlite_sequence;\n";
  }else if( strcmp(zTable, "sqlite_stat1")==0 ){
    fprintf(p->out, "ANALYZE sqlite_master;\n");
  }else if( strncmp(zTable, "sqlite_", 7)==0 ){
    return 0;
  }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
    char *zIns;
    if( !p->writableSchema ){
      fprintf(p->out, "PRAGMA writable_schema=ON;\n");







|







1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
  if( nArg!=3 ) return 1;
  zTable = azArg[0];
  zType = azArg[1];
  zSql = azArg[2];
  
  if( strcmp(zTable, "sqlite_sequence")==0 ){
    zPrepStmt = "DELETE FROM sqlite_sequence;\n";
  }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
    fprintf(p->out, "ANALYZE sqlite_master;\n");
  }else if( strncmp(zTable, "sqlite_", 7)==0 ){
    return 0;
  }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
    char *zIns;
    if( !p->writableSchema ){
      fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
        if( pc==cQuote ){
          pc = 0;
          continue;
        }
      }
      if( (c==cSep && pc==cQuote)
       || (c=='\n' && pc==cQuote)
       || (c=='\n' && pc=='\r' && p->n>2 && p->z[p->n-2]==cQuote)
       || (c==EOF && pc==cQuote)
      ){
        do{ p->n--; }while( p->z[p->n]!=cQuote );
        p->cTerm = c;
        break;
      }
      if( pc==cQuote && c!='\r' ){







|







1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
        if( pc==cQuote ){
          pc = 0;
          continue;
        }
      }
      if( (c==cSep && pc==cQuote)
       || (c=='\n' && pc==cQuote)
       || (c=='\n' && pc=='\r' && p->n>=2 && p->z[p->n-2]==cQuote)
       || (c==EOF && pc==cQuote)
      ){
        do{ p->n--; }while( p->z[p->n]!=cQuote );
        p->cTerm = c;
        break;
      }
      if( pc==cQuote && c!='\r' ){
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
  */
  if( nArg==0 ) return 0; /* no tokens, no error */
  n = strlen30(azArg[0]);
  c = azArg[0][0];
  if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
    const char *zDestFile = 0;
    const char *zDb = 0;
    const char *zKey = 0;
    sqlite3 *pDest;
    sqlite3_backup *pBackup;
    int j;
    for(j=1; j<nArg; j++){
      const char *z = azArg[j];
      if( z[0]=='-' ){
        while( z[0]=='-' ) z++;
        if( strcmp(z,"key")==0 && j<nArg-1 ){
          zKey = azArg[++j];
        }else
        {
          fprintf(stderr, "unknown option: %s\n", azArg[j]);
          return 1;
        }
      }else if( zDestFile==0 ){
        zDestFile = azArg[j];
      }else if( zDb==0 ){







<







|
<
<







1793
1794
1795
1796
1797
1798
1799

1800
1801
1802
1803
1804
1805
1806
1807


1808
1809
1810
1811
1812
1813
1814
  */
  if( nArg==0 ) return 0; /* no tokens, no error */
  n = strlen30(azArg[0]);
  c = azArg[0][0];
  if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
    const char *zDestFile = 0;
    const char *zDb = 0;

    sqlite3 *pDest;
    sqlite3_backup *pBackup;
    int j;
    for(j=1; j<nArg; j++){
      const char *z = azArg[j];
      if( z[0]=='-' ){
        while( z[0]=='-' ) z++;
        /* No options to process at this time */


        {
          fprintf(stderr, "unknown option: %s\n", azArg[j]);
          return 1;
        }
      }else if( zDestFile==0 ){
        zDestFile = azArg[j];
      }else if( zDb==0 ){
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
    if( zDb==0 ) zDb = "main";
    rc = sqlite3_open(zDestFile, &pDest);
    if( rc!=SQLITE_OK ){
      fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
      sqlite3_close(pDest);
      return 1;
    }
#ifdef SQLITE_HAS_CODEC
    sqlite3_key(pDest, zKey, (int)strlen(zKey));
#else
    (void)zKey;
#endif
    open_db(p);
    pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
    if( pBackup==0 ){
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
      sqlite3_close(pDest);
      return 1;
    }







<
<
<
<
<







1826
1827
1828
1829
1830
1831
1832





1833
1834
1835
1836
1837
1838
1839
    if( zDb==0 ) zDb = "main";
    rc = sqlite3_open(zDestFile, &pDest);
    if( rc!=SQLITE_OK ){
      fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
      sqlite3_close(pDest);
      return 1;
    }





    open_db(p);
    pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
    if( pBackup==0 ){
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
      sqlite3_close(pDest);
      return 1;
    }
1994
1995
1996
1997
1998
1999
2000

2001
2002
2003
2004
2005
2006
2007
  if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
    char *zTable = azArg[2];    /* Insert data into this table */
    char *zFile = azArg[1];     /* Name of file to extra content from */
    sqlite3_stmt *pStmt = NULL; /* A statement */
    int nCol;                   /* Number of columns in the table */
    int nByte;                  /* Number of bytes in an SQL string */
    int i, j;                   /* Loop counters */

    int nSep;                   /* Number of bytes in p->separator[] */
    char *zSql;                 /* An SQL statement */
    CSVReader sCsv;             /* Reader context */
    int (*xCloser)(FILE*);      /* Procedure to close th3 connection */

    seenInterrupt = 0;
    memset(&sCsv, 0, sizeof(sCsv));







>







1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
  if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
    char *zTable = azArg[2];    /* Insert data into this table */
    char *zFile = azArg[1];     /* Name of file to extra content from */
    sqlite3_stmt *pStmt = NULL; /* A statement */
    int nCol;                   /* Number of columns in the table */
    int nByte;                  /* Number of bytes in an SQL string */
    int i, j;                   /* Loop counters */
    int needCommit;             /* True to COMMIT or ROLLBACK at end */
    int nSep;                   /* Number of bytes in p->separator[] */
    char *zSql;                 /* An SQL statement */
    CSVReader sCsv;             /* Reader context */
    int (*xCloser)(FILE*);      /* Procedure to close th3 connection */

    seenInterrupt = 0;
    memset(&sCsv, 0, sizeof(sCsv));
2095
2096
2097
2098
2099
2100
2101


2102
2103
2104
2105
2106
2107
2108
    sqlite3_free(zSql);
    if( rc ){
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
      if (pStmt) sqlite3_finalize(pStmt);
      xCloser(sCsv.in);
      return 1;
    }


    do{
      int startLine = sCsv.nLine;
      for(i=0; i<nCol; i++){
        char *z = csv_read_one_field(&sCsv);
        if( z==0 && i==0 ) break;
        sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
        if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){







>
>







2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
    sqlite3_free(zSql);
    if( rc ){
      fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
      if (pStmt) sqlite3_finalize(pStmt);
      xCloser(sCsv.in);
      return 1;
    }
    needCommit = sqlite3_get_autocommit(db);
    if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
    do{
      int startLine = sCsv.nLine;
      for(i=0; i<nCol; i++){
        char *z = csv_read_one_field(&sCsv);
        if( z==0 && i==0 ) break;
        sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
        if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
        }
      }
    }while( sCsv.cTerm!=EOF );

    xCloser(sCsv.in);
    sqlite3_free(sCsv.z);
    sqlite3_finalize(pStmt);
    sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
  }else

  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));







|







2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
        }
      }
    }while( sCsv.cTerm!=EOF );

    xCloser(sCsv.in);
    sqlite3_free(sCsv.z);
    sqlite3_finalize(pStmt);
    if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
  }else

  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
            fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
          }
          break;

        /* sqlite3_test_control(int, uint) */
        case SQLITE_TESTCTRL_PENDING_BYTE:        
          if( nArg==3 ){
            unsigned int opt = (unsigned int)integerValue(azArg[2]);        
            rc = sqlite3_test_control(testctrl, opt);
            fprintf(p->out, "%d (0x%08x)\n", rc, rc);
          } else {
            fprintf(stderr,"Error: testctrl %s takes a single unsigned"
                           " int option\n", azArg[1]);
          }
          break;







|







2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
            fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
          }
          break;

        /* sqlite3_test_control(int, uint) */
        case SQLITE_TESTCTRL_PENDING_BYTE:        
          if( nArg==3 ){
            unsigned int opt = (unsigned int)integerValue(azArg[2]);
            rc = sqlite3_test_control(testctrl, opt);
            fprintf(p->out, "%d (0x%08x)\n", rc, rc);
          } else {
            fprintf(stderr,"Error: testctrl %s takes a single unsigned"
                           " int option\n", azArg[1]);
          }
          break;
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
  return rc;
}

/*
** Return TRUE if a semicolon occurs anywhere in the first N characters
** of string z[].
*/
static int _contains_semicolon(const char *z, int N){
  int i;
  for(i=0; i<N; i++){  if( z[i]==';' ) return 1; }
  return 0;
}

/*
** Test to see if a line consists entirely of whitespace.







|







2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
  return rc;
}

/*
** Return TRUE if a semicolon occurs anywhere in the first N characters
** of string z[].
*/
static int line_contains_semicolon(const char *z, int N){
  int i;
  for(i=0; i<N; i++){  if( z[i]==';' ) return 1; }
  return 0;
}

/*
** Test to see if a line consists entirely of whitespace.
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859

2860

2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902


2903
2904
2905
2906






2907
2908
2909

2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
}

/*
** Return TRUE if the line typed in is an SQL command terminator other
** than a semi-colon.  The SQL Server style "go" command is understood
** as is the Oracle "/".
*/
static int _is_command_terminator(const char *zLine){
  while( IsSpace(zLine[0]) ){ zLine++; };
  if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
    return 1;  /* Oracle */
  }
  if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
         && _all_whitespace(&zLine[2]) ){
    return 1;  /* SQL Server */
  }
  return 0;
}

/*
** Return true if zSql is a complete SQL statement.  Return false if it
** ends in the middle of a string literal or C-style comment.
*/
static int _is_complete(char *zSql, int nSql){
  int rc;
  if( zSql==0 ) return 1;
  zSql[nSql] = ';';
  zSql[nSql+1] = 0;
  rc = sqlite3_complete(zSql);
  zSql[nSql] = 0;
  return rc;
}

/*
** Read input from *in and process it.  If *in==0 then input
** is interactive - the user is typing it it.  Otherwise, input
** is coming from a file or device.  A prompt is issued and history
** is saved only if input is interactive.  An interrupt signal will
** cause this routine to exit immediately, unless input is interactive.
**
** Return the number of errors.
*/
static int process_input(struct callback_data *p, FILE *in){
  char *zLine = 0;
  char *zSql = 0;

  int nSql = 0;

  int nSqlPrior = 0;
  char *zErrMsg;
  int rc;
  int errCnt = 0;
  int lineno = 0;
  int startline = 0;

  while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
    fflush(p->out);
    free(zLine);
    zLine = one_input_line(zSql, in);
    if( zLine==0 ){
      /* End of input */
      if( stdin_is_interactive ) printf("\n");
      break;
    }
    if( seenInterrupt ){
      if( in!=0 ) break;
      seenInterrupt = 0;
    }
    lineno++;
    if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
    if( zLine && zLine[0]=='.' && nSql==0 ){
      if( p->echoOn ) printf("%s\n", zLine);
      rc = do_meta_command(zLine, p);
      if( rc==2 ){ /* exit requested */
        break;
      }else if( rc ){
        errCnt++;
      }
      continue;
    }
    if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
      memcpy(zLine,";",2);
    }
    nSqlPrior = nSql;
    if( zSql==0 ){
      int i;
      for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
      if( zLine[i]!=0 ){
        nSql = strlen30(zLine);
        zSql = malloc( nSql+3 );


        if( zSql==0 ){
          fprintf(stderr, "Error: out of memory\n");
          exit(1);
        }






        memcpy(zSql, zLine, nSql+1);
        startline = lineno;
      }

    }else{
      int len = strlen30(zLine);
      zSql = realloc( zSql, nSql + len + 4 );
      if( zSql==0 ){
        fprintf(stderr,"Error: out of memory\n");
        exit(1);
      }
      zSql[nSql++] = '\n';
      memcpy(&zSql[nSql], zLine, len+1);
      nSql += len;
    }
    if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
                && sqlite3_complete(zSql) ){
      p->cnt = 0;
      open_db(p);
      BEGIN_TIMER;
      rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
      END_TIMER;
      if( rc || zErrMsg ){







|















|



















|
|
>
|
>
|
|
|
|
|
|



<
|










|










|


<
<
<
<
<
|
|
>
>
|
|
|
|
>
>
>
>
>
>
|
|
<
>

<
<
<
<
<
<

|
|

|







2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866

2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891





2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907

2908
2909






2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
}

/*
** Return TRUE if the line typed in is an SQL command terminator other
** than a semi-colon.  The SQL Server style "go" command is understood
** as is the Oracle "/".
*/
static int line_is_command_terminator(const char *zLine){
  while( IsSpace(zLine[0]) ){ zLine++; };
  if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
    return 1;  /* Oracle */
  }
  if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
         && _all_whitespace(&zLine[2]) ){
    return 1;  /* SQL Server */
  }
  return 0;
}

/*
** Return true if zSql is a complete SQL statement.  Return false if it
** ends in the middle of a string literal or C-style comment.
*/
static int line_is_complete(char *zSql, int nSql){
  int rc;
  if( zSql==0 ) return 1;
  zSql[nSql] = ';';
  zSql[nSql+1] = 0;
  rc = sqlite3_complete(zSql);
  zSql[nSql] = 0;
  return rc;
}

/*
** Read input from *in and process it.  If *in==0 then input
** is interactive - the user is typing it it.  Otherwise, input
** is coming from a file or device.  A prompt is issued and history
** is saved only if input is interactive.  An interrupt signal will
** cause this routine to exit immediately, unless input is interactive.
**
** Return the number of errors.
*/
static int process_input(struct callback_data *p, FILE *in){
  char *zLine = 0;          /* A single input line */
  char *zSql = 0;           /* Accumulated SQL text */
  int nLine;                /* Length of current line */
  int nSql = 0;             /* Bytes of zSql[] used */
  int nAlloc = 0;           /* Allocated zSql[] space */
  int nSqlPrior = 0;        /* Bytes of zSql[] used by prior line */
  char *zErrMsg;            /* Error message returned */
  int rc;                   /* Error code */
  int errCnt = 0;           /* Number of errors seen */
  int lineno = 0;           /* Current line number */
  int startline = 0;        /* Line number for start of current input */

  while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
    fflush(p->out);

    zLine = one_input_line(in, zLine, nSql>0);
    if( zLine==0 ){
      /* End of input */
      if( stdin_is_interactive ) printf("\n");
      break;
    }
    if( seenInterrupt ){
      if( in!=0 ) break;
      seenInterrupt = 0;
    }
    lineno++;
    if( nSql==0 && _all_whitespace(zLine) ) continue;
    if( zLine && zLine[0]=='.' && nSql==0 ){
      if( p->echoOn ) printf("%s\n", zLine);
      rc = do_meta_command(zLine, p);
      if( rc==2 ){ /* exit requested */
        break;
      }else if( rc ){
        errCnt++;
      }
      continue;
    }
    if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
      memcpy(zLine,";",2);
    }





    nLine = strlen30(zLine);
    if( nSql+nLine+2>=nAlloc ){
      nAlloc = nSql+nLine+100;
      zSql = realloc(zSql, nAlloc);
      if( zSql==0 ){
        fprintf(stderr, "Error: out of memory\n");
        exit(1);
      }
    }
    nSqlPrior = nSql;
    if( nSql==0 ){
      int i;
      for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
      assert( nAlloc>0 && zSql!=0 );
      memcpy(zSql, zLine+i, nLine+1-i);
      startline = lineno;

      nSql = nLine-i;
    }else{






      zSql[nSql++] = '\n';
      memcpy(zSql+nSql, zLine, nLine+1);
      nSql += nLine;
    }
    if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
                && sqlite3_complete(zSql) ){
      p->cnt = 0;
      open_db(p);
      BEGIN_TIMER;
      rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
      END_TIMER;
      if( rc || zErrMsg ){
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
          sqlite3_free(zErrMsg);
          zErrMsg = 0;
        }else{
          fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
        }
        errCnt++;
      }
      free(zSql);
      zSql = 0;
      nSql = 0;
    }else if( zSql && _all_whitespace(zSql) ){
      free(zSql);
      zSql = 0;
      nSql = 0;
    }
  }
  if( zSql ){
    if( !_all_whitespace(zSql) ){
      fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
    }
    free(zSql);
  }
  free(zLine);
  return errCnt>0;







<
<

|
<
<



|







2931
2932
2933
2934
2935
2936
2937


2938
2939


2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
          sqlite3_free(zErrMsg);
          zErrMsg = 0;
        }else{
          fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
        }
        errCnt++;
      }


      nSql = 0;
    }else if( nSql && _all_whitespace(zSql) ){


      nSql = 0;
    }
  }
  if( nSql ){
    if( !_all_whitespace(zSql) ){
      fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
    }
    free(zSql);
  }
  free(zLine);
  return errCnt>0;
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
      /* Need to check for batch mode here to so we can avoid printing
      ** informational messages (like from process_sqliterc) before 
      ** we do the actual processing of arguments later in a second pass.
      */
      stdin_is_interactive = 0;
    }else if( strcmp(z,"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
      int j, c;
      const char *zSize;
      sqlite3_int64 szHeap;

      zSize = cmdline_option_value(argc, argv, ++i);
      szHeap = integerValue(zSize);
      if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
      sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);







<







3184
3185
3186
3187
3188
3189
3190

3191
3192
3193
3194
3195
3196
3197
      /* Need to check for batch mode here to so we can avoid printing
      ** informational messages (like from process_sqliterc) before 
      ** we do the actual processing of arguments later in a second pass.
      */
      stdin_is_interactive = 0;
    }else if( strcmp(z,"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)

      const char *zSize;
      sqlite3_int64 szHeap;

      zSize = cmdline_option_value(argc, argv, ++i);
      szHeap = integerValue(zSize);
      if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
      sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
Changes to src/shun.c.
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
  @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
  login_insert_csrf_secret();
  @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" />
  @ <input type="submit" name="add" value="Shun" />
  @ </div></form>
  @ </blockquote>
  @

  @ <p>Enter the UUID of a previous shunned artifact to cause it to be
  @ accepted again in the repository.  The artifact content is not
  @ restored because the content is unknown.  The only change is that
  @ the formerly shunned artifact will be accepted on subsequent sync
  @ operations.</p>
  @
  @ <blockquote>
  @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
  login_insert_csrf_secret();
  @ <input type="text" name="uuid" size="50" />
  @ <input type="submit" name="sub" value="Accept" />
  @ </div></form>
  @ </blockquote>
  @
  @ <p>Press the Rebuild button below to rebuild the repository.  The
  @ content of newly shunned artifacts is not purged until the repository
  @ is rebuilt.  On larger repositories, the rebuild may take minute or







>









|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
  login_insert_csrf_secret();
  @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" />
  @ <input type="submit" name="add" value="Shun" />
  @ </div></form>
  @ </blockquote>
  @
  @ <a name="delshun"></a>
  @ <p>Enter the UUID of a previous shunned artifact to cause it to be
  @ accepted again in the repository.  The artifact content is not
  @ restored because the content is unknown.  The only change is that
  @ the formerly shunned artifact will be accepted on subsequent sync
  @ operations.</p>
  @
  @ <blockquote>
  @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
  login_insert_csrf_secret();
  @ <input type="text" name="uuid" value="%h(PD("accept", ""))" size="50" />
  @ <input type="submit" name="sub" value="Accept" />
  @ </div></form>
  @ </blockquote>
  @
  @ <p>Press the Rebuild button below to rebuild the repository.  The
  @ content of newly shunned artifacts is not purged until the repository
  @ is rebuilt.  On larger repositories, the rebuild may take minute or
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
  db_prepare(&q, 
    "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr"
    "  FROM rcvfrom LEFT JOIN user USING(uid)"
    " WHERE rcvid=%d",
    rcvid
  );
  @ <table cellspacing="15" cellpadding="0" border="0">
  @ <tr><td valign="top" align="right"><b>rcvid:</b></td>
  @ <td valign="top">%d(rcvid)</td></tr>
  if( db_step(&q)==SQLITE_ROW ){
    const char *zUser = db_column_text(&q, 0);
    const char *zDate = db_column_text(&q, 1);
    const char *zIpAddr = db_column_text(&q, 2);
    @ <tr><td valign="top" align="right"><b>User:</b></td>
    @ <td valign="top">%s(zUser)</td></tr>
    @ <tr><td valign="top" align="right"><b>Date:</b></td>
    @ <td valign="top">%s(zDate)</td></tr>
    @ <tr><td valign="top" align="right"><b>IP&nbsp;Address:</b></td>
    @ <td valign="top">%s(zIpAddr)</td></tr>
  }
  db_finalize(&q);
  db_prepare(&q,
    "SELECT rid, uuid, size FROM blob WHERE rcvid=%d", rcvid
  );
  @ <tr><td valign="top" align="right"><b>Artifacts:</b></td>
  @ <td valign="top">
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    const char *zUuid = db_column_text(&q, 1);
    int size = db_column_int(&q, 2);
    @ <a href="%s(g.zTop)/info/%s(zUuid)">%s(zUuid)</a>
    @ (rid: %d(rid), size: %d(size))<br />
  }
  @ </td></tr>
  @ </table>
  db_finalize(&q);
  style_footer();
}







|





|

|

|






|













292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
  db_prepare(&q, 
    "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr"
    "  FROM rcvfrom LEFT JOIN user USING(uid)"
    " WHERE rcvid=%d",
    rcvid
  );
  @ <table cellspacing="15" cellpadding="0" border="0">
  @ <tr><th valign="top" align="right">rcvid:</th>
  @ <td valign="top">%d(rcvid)</td></tr>
  if( db_step(&q)==SQLITE_ROW ){
    const char *zUser = db_column_text(&q, 0);
    const char *zDate = db_column_text(&q, 1);
    const char *zIpAddr = db_column_text(&q, 2);
    @ <tr><th valign="top" align="right">User:</th>
    @ <td valign="top">%s(zUser)</td></tr>
    @ <tr><th valign="top" align="right">Date:</th>
    @ <td valign="top">%s(zDate)</td></tr>
    @ <tr><th valign="top" align="right">IP&nbsp;Address:</th>
    @ <td valign="top">%s(zIpAddr)</td></tr>
  }
  db_finalize(&q);
  db_prepare(&q,
    "SELECT rid, uuid, size FROM blob WHERE rcvid=%d", rcvid
  );
  @ <tr><th valign="top" align="right">Artifacts:</th>
  @ <td valign="top">
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    const char *zUuid = db_column_text(&q, 1);
    int size = db_column_int(&q, 2);
    @ <a href="%s(g.zTop)/info/%s(zUuid)">%s(zUuid)</a>
    @ (rid: %d(rid), size: %d(size))<br />
  }
  @ </td></tr>
  @ </table>
  db_finalize(&q);
  style_footer();
}
Changes to src/sqlite3.c.
1
2
3
4
5
6
7
8
9
10
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
** version 3.8.0.  By combining all the individual C code files into this 
** single large file, the entire code can be compiled as a single translation
** unit.  This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately.  Performance improvements
** of 5% or more are commonly seen when SQLite is compiled as a single
** translation unit.
**
** This file is all you need to compile SQLite.  To use SQLite in other


|







1
2
3
4
5
6
7
8
9
10
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
** version 3.8.1.  By combining all the individual C code files into this 
** single large file, the entire code can be compiled as a single translation
** unit.  This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately.  Performance improvements
** of 5% or more are commonly seen when SQLite is compiled as a single
** translation unit.
**
** This file is all you need to compile SQLite.  To use SQLite in other
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
**     SQLITE_MEMDEBUG               // Debugging version of system malloc()
**
** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
** assert() macro is enabled, each call into the Win32 native heap subsystem
** will cause HeapValidate to be called.  If heap validation should fail, an
** assertion will be triggered.
**
** (Historical note:  There used to be several other options, but we've
** pared it down to just these three.)
**
** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
** the default.
*/
#if defined(SQLITE_SYSTEM_MALLOC) \
  + defined(SQLITE_WIN32_MALLOC) \
  + defined(SQLITE_ZERO_MALLOC) \
  + defined(SQLITE_MEMDEBUG)>1







<
<
<







397
398
399
400
401
402
403



404
405
406
407
408
409
410
**     SQLITE_MEMDEBUG               // Debugging version of system malloc()
**
** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
** assert() macro is enabled, each call into the Win32 native heap subsystem
** will cause HeapValidate to be called.  If heap validation should fail, an
** assertion will be triggered.
**



** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
** the default.
*/
#if defined(SQLITE_SYSTEM_MALLOC) \
  + defined(SQLITE_WIN32_MALLOC) \
  + defined(SQLITE_ZERO_MALLOC) \
  + defined(SQLITE_MEMDEBUG)>1
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit
** it.
*/
#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__)
#  define _XOPEN_SOURCE 600
#endif

/*
** The TCL headers are only needed when compiling the TCL bindings.
*/
#if defined(SQLITE_TCL) || defined(TCLSH)
# include <tcl.h>
#endif

/*
** NDEBUG and SQLITE_DEBUG are opposites.  It should always be true that
** defined(NDEBUG)==!defined(SQLITE_DEBUG).  If this is not currently true,
** make it true by defining or undefining NDEBUG.
**
** Setting NDEBUG makes the code smaller and run faster by disabling the
** number assert() statements in the code.  So we want the default action
** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
** is set.  Thus NDEBUG becomes an opt-in rather than an opt-out
** feature.
*/
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) 
# define NDEBUG 1
#endif







<
<
<
<
<
<
<





|
|







434
435
436
437
438
439
440







441
442
443
444
445
446
447
448
449
450
451
452
453
454
** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit
** it.
*/
#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__)
#  define _XOPEN_SOURCE 600
#endif








/*
** NDEBUG and SQLITE_DEBUG are opposites.  It should always be true that
** defined(NDEBUG)==!defined(SQLITE_DEBUG).  If this is not currently true,
** make it true by defining or undefining NDEBUG.
**
** Setting NDEBUG makes the code smaller and faster by disabling the
** assert() statements in the code.  So we want the default action
** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
** is set.  Thus NDEBUG becomes an opt-in rather than an opt-out
** feature.
*/
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) 
# define NDEBUG 1
#endif
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
** of SQLite to unexpected behavior - to make the code "self-healing"
** or "ductile" rather than being "brittle" and crashing at the first
** hint of unplanned behavior.
**
** In other words, ALWAYS and NEVER are added for defensive code.
**
** When doing coverage testing ALWAYS and NEVER are hard-coded to
** be true and false so that the unreachable code then specify will
** not be counted as untested code.
*/
#if defined(SQLITE_COVERAGE_TEST)
# define ALWAYS(X)      (1)
# define NEVER(X)       (0)
#elif !defined(NDEBUG)
# define ALWAYS(X)      ((X)?1:(assert(0),0))







|







510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
** of SQLite to unexpected behavior - to make the code "self-healing"
** or "ductile" rather than being "brittle" and crashing at the first
** hint of unplanned behavior.
**
** In other words, ALWAYS and NEVER are added for defensive code.
**
** When doing coverage testing ALWAYS and NEVER are hard-coded to
** be true and false so that the unreachable code they specify will
** not be counted as untested code.
*/
#if defined(SQLITE_COVERAGE_TEST)
# define ALWAYS(X)      (1)
# define NEVER(X)       (0)
#elif !defined(NDEBUG)
# define ALWAYS(X)      ((X)?1:(assert(0),0))
544
545
546
547
548
549
550
551
552

553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
** macros to verify that we have tested SQLite for large-file support.
*/
#define IS_BIG_INT(X)  (((X)&~(i64)0xffffffff)!=0)

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
** a boolean expression that is usually true.  GCC is able to
** use these hints to generate better code, sometimes.

*/
#if defined(__GNUC__) && 0
# define likely(X)    __builtin_expect((X),1)
# define unlikely(X)  __builtin_expect((X),0)
#else
# define likely(X)    !!(X)
# define unlikely(X)  !!(X)
#endif

/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
/************** Begin file sqlite3.h *****************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of







|
|
>

<
<
<
<
|
|
<







534
535
536
537
538
539
540
541
542
543
544




545
546

547
548
549
550
551
552
553
** macros to verify that we have tested SQLite for large-file support.
*/
#define IS_BIG_INT(X)  (((X)&~(i64)0xffffffff)!=0)

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
** a boolean expression that is usually true.  These hints could,
** in theory, be used by the compiler to generate better code, but
** currently they are just comments for human readers.
*/




#define likely(X)    (X)
#define unlikely(X)  (X)


/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
/************** Begin file sqlite3.h *****************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.0"
#define SQLITE_VERSION_NUMBER 3008000
#define SQLITE_SOURCE_ID      "2013-07-18 14:50:56 5dcffa671f592ae9355628afa439ae9a2d26f0cd"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|
|
|







652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.1"
#define SQLITE_VERSION_NUMBER 3008001
#define SQLITE_SOURCE_ID      "2013-09-04 04:04:08 8df95bb0b3f72222cf262174247a467c234f9939"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
1037
1038
1039
1040
1041
1042
1043


1044
1045
1046
1047
1048
1049

1050
1051
1052
1053
1054
1055
1056
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))


#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))

#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
#define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))







>
>






>







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
#define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
#define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
#define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))
3120
3121
3122
3123
3124
3125
3126
3127

3128
3129
3130
3131
3132
3133
3134
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
** database connection D.  An example use for this
** interface is to keep a GUI updated during a large query.
**
** ^The parameter P is passed through as the only parameter to the 
** callback function X.  ^The parameter N is the approximate number of 
** [virtual machine instructions] that are evaluated between successive
** invocations of the callback X.

**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
** old one.  ^Setting parameter X to NULL disables the progress handler.
** ^The progress handler is also disabled by setting N to a value less
** than 1.
**







|
>







3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
** database connection D.  An example use for this
** interface is to keep a GUI updated during a large query.
**
** ^The parameter P is passed through as the only parameter to the 
** callback function X.  ^The parameter N is the approximate number of 
** [virtual machine instructions] that are evaluated between successive
** invocations of the callback X.  ^If N is less than one then the progress
** handler is disabled.
**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
** old one.  ^Setting parameter X to NULL disables the progress handler.
** ^The progress handler is also disabled by setting N to a value less
** than 1.
**
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753

4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769

4770
4771

4772
4773
4774
4775

4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
** registered the application defined function.
*/
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);

/*
** CAPI3REF: Function Auxiliary Data
**
** The following two functions may be used by scalar SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved. This might
** be used, for example, in a regular-expression matching
** function. The compiled version of the regular expression is stored as
** metadata associated with the SQL value passed as the regular expression

** pattern.  The compiled regular expression can be reused on multiple
** invocations of the same function so that the original pattern string
** does not need to be recompiled on each invocation.
**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
** value to the application-defined function. ^If no metadata has been ever
** been set for the Nth argument of the function, or if the corresponding
** function parameter has changed since the meta-data was set,
** then sqlite3_get_auxdata() returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** argument of the application-defined function.  ^Subsequent
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
** sqlite3_set_auxdata(C,N,P,X) call if the data has not been dropped, or
** NULL if the data has been dropped.

** ^(If it is not NULL, SQLite will invoke the destructor
** function X passed to sqlite3_set_auxdata(C,N,P,X) when <ul>

** <li> the corresponding function parameter changes,
** <li> [sqlite3_reset()] or [sqlite3_finalize()] is called for the
**      SQL statement,
** <li> sqlite3_set_auxdata() is invoked again on the same parameter, or

** <li> a memory allocation error occurs. </ul>)^
**
** SQLite is free to call the destructor and drop metadata on any
** parameter of any function at any time.  ^The only guarantee is that
** the destructor will be called when the [prepared statement] is destroyed.
** Note in particular that the destructor X in the call to
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before
** the sqlite3_set_auxdata() call even returns.  Hence sqlite3_set_auxdata()
** should be called near the end of the function implementation and the
** implementation should not make any use of P after sqlite3_set_auxdata()
** has been called.
**
** ^(In practice, metadata is preserved between function calls for
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
** These routines must be called from the same thread in which
** the SQL function is running.







|


|
|
|
|
>
|
|
<



|
<
|
|




|
|
>
|
|
>
|
|
|
|
>
|

<
<
<
|
|
|

|
|







4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746

4747
4748
4749
4750

4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769



4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
** registered the application defined function.
*/
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);

/*
** CAPI3REF: Function Auxiliary Data
**
** These functions may be used by (non-aggregate) SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved.  An example
** of where this might be useful is in a regular-expression matching
** function. The compiled version of the regular expression can be stored as
** metadata associated with the pattern string.  
** Then as long as the pattern string remains the same,
** the compiled regular expression can be reused on multiple
** invocations of the same function.

**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
** value to the application-defined function. ^If there is no metadata

** associated with the function argument, this sqlite3_get_auxdata() interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** argument of the application-defined function.  ^Subsequent
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
** NULL if the metadata has been discarded.
** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
** SQLite will invoke the destructor function X with parameter P exactly
** once, when the metadata is discarded.
** SQLite is free to discard the metadata at any time, including: <ul>
** <li> when the corresponding function parameter changes, or
** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
**      SQL statement, or
** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
** <li> during the original sqlite3_set_auxdata() call when a memory 
**      allocation error occurs. </ul>)^
**



** Note the last bullet in particular.  The destructor X in 
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
** sqlite3_set_auxdata() interface even returns.  Hence sqlite3_set_auxdata()
** should be called near the end of the function implementation and the
** function implementation should not make any use of P after
** sqlite3_set_auxdata() has been called.
**
** ^(In practice, metadata is preserved between function calls for
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
** These routines must be called from the same thread in which
** the SQL function is running.
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
** transaction rollback or database recovery operations are not included.
** If an IO or other error occurs while writing a page to disk, the effect
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns the zero for the current value if and only if
** there all foreign key constraints (deferred or immediate) have been
** resolved.  The highwater mark is always 0.
** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED       0
#define SQLITE_DBSTATUS_CACHE_USED           1
#define SQLITE_DBSTATUS_SCHEMA_USED          2
#define SQLITE_DBSTATUS_STMT_USED            3







|
|
|







6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
** transaction rollback or database recovery operations are not included.
** If an IO or other error occurs while writing a page to disk, the effect
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns zero for the current value if and only if
** all foreign key constraints (deferred or immediate) have been
** resolved.)^  ^The highwater mark is always 0.
** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED       0
#define SQLITE_DBSTATUS_CACHE_USED           1
#define SQLITE_DBSTATUS_SCHEMA_USED          2
#define SQLITE_DBSTATUS_STMT_USED            3
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#if 0
}  /* End of the 'extern "C"' block */
#endif
#endif

/*
** 2010 August 30
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**







|







7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#if 0
}  /* End of the 'extern "C"' block */
#endif
#endif /* _SQLITE3_H_ */

/*
** 2010 August 30
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
8379
8380
8381
8382
8383
8384
8385














8386
8387
8388
8389
8390
8391
8392
# define SQLITE_DEFAULT_MMAP_SIZE_xc 1  /* Exclude from ctime.c */
#endif
#if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE
# undef SQLITE_DEFAULT_MMAP_SIZE
# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
#endif















/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle. 
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
** handle is passed a pointer to sqlite.busyHandler. The busy-handler







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







8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
# define SQLITE_DEFAULT_MMAP_SIZE_xc 1  /* Exclude from ctime.c */
#endif
#if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE
# undef SQLITE_DEFAULT_MMAP_SIZE
# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
#endif

/*
** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined.
** Priority is given to SQLITE_ENABLE_STAT4.  If either are defined, also
** define SQLITE_ENABLE_STAT3_OR_STAT4
*/
#ifdef SQLITE_ENABLE_STAT4
# undef SQLITE_ENABLE_STAT3
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3_OR_STAT4
# undef SQLITE_ENABLE_STAT3_OR_STAT4
#endif

/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle. 
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
** handle is passed a pointer to sqlite.busyHandler. The busy-handler
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
#define BTREE_MEMORY        2  /* This is an in-memory DB */
#define BTREE_SINGLE        4  /* The file contains at most 1 b-tree */
#define BTREE_UNORDERED     8  /* Use of a hash implementation is OK */

SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);







|







8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
#define BTREE_MEMORY        2  /* This is an in-memory DB */
#define BTREE_SINGLE        4  /* The file contains at most 1 b-tree */
#define BTREE_UNORDERED     8  /* Use of a hash implementation is OK */

SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
*/
typedef struct Vdbe Vdbe;

/*
** The names of the following types declared in vdbeInt.h are required
** for the VdbeOp definition.
*/
typedef struct VdbeFunc VdbeFunc;
typedef struct Mem Mem;
typedef struct SubProgram SubProgram;

/*
** A single instruction of the virtual machine has an opcode
** and as many as three operands.  The instruction is recorded
** as an instance of the following structure:







<







8825
8826
8827
8828
8829
8830
8831

8832
8833
8834
8835
8836
8837
8838
*/
typedef struct Vdbe Vdbe;

/*
** The names of the following types declared in vdbeInt.h are required
** for the VdbeOp definition.
*/

typedef struct Mem Mem;
typedef struct SubProgram SubProgram;

/*
** A single instruction of the virtual machine has an opcode
** and as many as three operands.  The instruction is recorded
** as an instance of the following structure:
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
  union {             /* fourth parameter */
    int i;                 /* Integer value if p4type==P4_INT32 */
    void *p;               /* Generic pointer */
    char *z;               /* Pointer to data for string (char array) types */
    i64 *pI64;             /* Used when p4type is P4_INT64 */
    double *pReal;         /* Used when p4type is P4_REAL */
    FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
    VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
    Mem *pMem;             /* Used when p4type is P4_MEM */
    VTable *pVtab;         /* Used when p4type is P4_VTAB */
    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
    int *ai;               /* Used when p4type is P4_INTARRAY */
    SubProgram *pProgram;  /* Used when p4type is P4_SUBPROGRAM */
    int (*xAdvance)(BtCursor *, int *);







<







8848
8849
8850
8851
8852
8853
8854

8855
8856
8857
8858
8859
8860
8861
  union {             /* fourth parameter */
    int i;                 /* Integer value if p4type==P4_INT32 */
    void *p;               /* Generic pointer */
    char *z;               /* Pointer to data for string (char array) types */
    i64 *pI64;             /* Used when p4type is P4_INT64 */
    double *pReal;         /* Used when p4type is P4_REAL */
    FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */

    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
    Mem *pMem;             /* Used when p4type is P4_MEM */
    VTable *pVtab;         /* Used when p4type is P4_VTAB */
    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
    int *ai;               /* Used when p4type is P4_INTARRAY */
    SubProgram *pProgram;  /* Used when p4type is P4_SUBPROGRAM */
    int (*xAdvance)(BtCursor *, int *);
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
*/
#define P4_NOTUSED    0   /* The P4 parameter is not used */
#define P4_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
#define P4_STATIC   (-2)  /* Pointer to a static string */
#define P4_COLLSEQ  (-4)  /* P4 is a pointer to a CollSeq structure */
#define P4_FUNCDEF  (-5)  /* P4 is a pointer to a FuncDef structure */
#define P4_KEYINFO  (-6)  /* P4 is a pointer to a KeyInfo structure */
#define P4_VDBEFUNC (-7)  /* P4 is a pointer to a VdbeFunc structure */
#define P4_MEM      (-8)  /* P4 is a pointer to a Mem*    structure */
#define P4_TRANSIENT  0   /* P4 is a pointer to a transient string */
#define P4_VTAB     (-10) /* P4 is a pointer to an sqlite3_vtab structure */
#define P4_MPRINTF  (-11) /* P4 is a string obtained from sqlite3_mprintf() */
#define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
#define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
#define P4_INT32    (-14) /* P4 is a 32-bit signed integer */







<







8901
8902
8903
8904
8905
8906
8907

8908
8909
8910
8911
8912
8913
8914
*/
#define P4_NOTUSED    0   /* The P4 parameter is not used */
#define P4_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
#define P4_STATIC   (-2)  /* Pointer to a static string */
#define P4_COLLSEQ  (-4)  /* P4 is a pointer to a CollSeq structure */
#define P4_FUNCDEF  (-5)  /* P4 is a pointer to a FuncDef structure */
#define P4_KEYINFO  (-6)  /* P4 is a pointer to a KeyInfo structure */

#define P4_MEM      (-8)  /* P4 is a pointer to a Mem*    structure */
#define P4_TRANSIENT  0   /* P4 is a pointer to a transient string */
#define P4_VTAB     (-10) /* P4 is a pointer to an sqlite3_vtab structure */
#define P4_MPRINTF  (-11) /* P4 is a string obtained from sqlite3_mprintf() */
#define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
#define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
#define P4_INT32    (-14) /* P4 is a 32-bit signed integer */
8957
8958
8959
8960
8961
8962
8963













8964
8965
8966
8967
8968

8969
8970
8971











8972
8973










8974




8975
8976
8977
8978
8979
8980
8981
8982



























8983
8984
8985
8986
8987
8988
8989
8990
8991



8992

8993





















8994
















8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127


9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139

9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
** header file that defines a number for each opcode used by the VDBE.
*/
/************** Include opcodes.h in the middle of vdbe.h ********************/
/************** Begin file opcodes.h *****************************************/
/* Automatically generated.  Do not edit */
/* See the mkopcodeh.awk script for details */













#define OP_Goto                                 1
#define OP_Gosub                                2
#define OP_Return                               3
#define OP_Yield                                4
#define OP_HaltIfNull                           5

#define OP_Halt                                 6
#define OP_Integer                              7
#define OP_Int64                                8











#define OP_Real                               130   /* same as TK_FLOAT    */
#define OP_String8                             94   /* same as TK_STRING   */










#define OP_String                               9




#define OP_Null                                10
#define OP_Blob                                11
#define OP_Variable                            12
#define OP_Move                                13
#define OP_Copy                                14
#define OP_SCopy                               15
#define OP_ResultRow                           16
#define OP_Concat                              91   /* same as TK_CONCAT   */



























#define OP_Add                                 86   /* same as TK_PLUS     */
#define OP_Subtract                            87   /* same as TK_MINUS    */
#define OP_Multiply                            88   /* same as TK_STAR     */
#define OP_Divide                              89   /* same as TK_SLASH    */
#define OP_Remainder                           90   /* same as TK_REM      */
#define OP_CollSeq                             17
#define OP_Function                            18
#define OP_BitAnd                              82   /* same as TK_BITAND   */
#define OP_BitOr                               83   /* same as TK_BITOR    */



#define OP_ShiftLeft                           84   /* same as TK_LSHIFT   */

#define OP_ShiftRight                          85   /* same as TK_RSHIFT   */





















#define OP_AddImm                              20
















#define OP_MustBeInt                           21
#define OP_RealAffinity                        22
#define OP_ToText                             141   /* same as TK_TO_TEXT  */
#define OP_ToBlob                             142   /* same as TK_TO_BLOB  */
#define OP_ToNumeric                          143   /* same as TK_TO_NUMERIC*/
#define OP_ToInt                              144   /* same as TK_TO_INT   */
#define OP_ToReal                             145   /* same as TK_TO_REAL  */
#define OP_Eq                                  76   /* same as TK_EQ       */
#define OP_Ne                                  75   /* same as TK_NE       */
#define OP_Lt                                  79   /* same as TK_LT       */
#define OP_Le                                  78   /* same as TK_LE       */
#define OP_Gt                                  77   /* same as TK_GT       */
#define OP_Ge                                  80   /* same as TK_GE       */
#define OP_Permutation                         23
#define OP_Compare                             24
#define OP_Jump                                25
#define OP_And                                 69   /* same as TK_AND      */
#define OP_Or                                  68   /* same as TK_OR       */
#define OP_Not                                 19   /* same as TK_NOT      */
#define OP_BitNot                              93   /* same as TK_BITNOT   */
#define OP_Once                                26
#define OP_If                                  27
#define OP_IfNot                               28
#define OP_IsNull                              73   /* same as TK_ISNULL   */
#define OP_NotNull                             74   /* same as TK_NOTNULL  */
#define OP_Column                              29
#define OP_Affinity                            30
#define OP_MakeRecord                          31
#define OP_Count                               32
#define OP_Savepoint                           33
#define OP_AutoCommit                          34
#define OP_Transaction                         35
#define OP_ReadCookie                          36
#define OP_SetCookie                           37
#define OP_VerifyCookie                        38
#define OP_OpenRead                            39
#define OP_OpenWrite                           40
#define OP_OpenAutoindex                       41
#define OP_OpenEphemeral                       42
#define OP_SorterOpen                          43
#define OP_OpenPseudo                          44
#define OP_Close                               45
#define OP_SeekLt                              46
#define OP_SeekLe                              47
#define OP_SeekGe                              48
#define OP_SeekGt                              49
#define OP_Seek                                50
#define OP_NotFound                            51
#define OP_Found                               52
#define OP_IsUnique                            53
#define OP_NotExists                           54
#define OP_Sequence                            55
#define OP_NewRowid                            56
#define OP_Insert                              57
#define OP_InsertInt                           58
#define OP_Delete                              59
#define OP_ResetCount                          60
#define OP_SorterCompare                       61
#define OP_SorterData                          62
#define OP_RowKey                              63
#define OP_RowData                             64
#define OP_Rowid                               65
#define OP_NullRow                             66
#define OP_Last                                67
#define OP_SorterSort                          70
#define OP_Sort                                71
#define OP_Rewind                              72
#define OP_SorterNext                          81
#define OP_Prev                                92
#define OP_Next                                95
#define OP_SorterInsert                        96
#define OP_IdxInsert                           97
#define OP_IdxDelete                           98
#define OP_IdxRowid                            99
#define OP_IdxLT                              100
#define OP_IdxGE                              101
#define OP_Destroy                            102
#define OP_Clear                              103
#define OP_CreateIndex                        104
#define OP_CreateTable                        105
#define OP_ParseSchema                        106
#define OP_LoadAnalysis                       107
#define OP_DropTable                          108
#define OP_DropIndex                          109
#define OP_DropTrigger                        110
#define OP_IntegrityCk                        111
#define OP_RowSetAdd                          112
#define OP_RowSetRead                         113
#define OP_RowSetTest                         114
#define OP_Program                            115
#define OP_Param                              116
#define OP_FkCounter                          117
#define OP_FkIfZero                           118
#define OP_MemMax                             119
#define OP_IfPos                              120
#define OP_IfNeg                              121
#define OP_IfZero                             122
#define OP_AggStep                            123
#define OP_AggFinal                           124
#define OP_Checkpoint                         125
#define OP_JournalMode                        126
#define OP_Vacuum                             127
#define OP_IncrVacuum                         128
#define OP_Expire                             129
#define OP_TableLock                          131
#define OP_VBegin                             132
#define OP_VCreate                            133
#define OP_VDestroy                           134
#define OP_VOpen                              135
#define OP_VFilter                            136
#define OP_VColumn                            137
#define OP_VNext                              138
#define OP_VRename                            139
#define OP_VUpdate                            140
#define OP_Pagecount                          146
#define OP_MaxPgcnt                           147
#define OP_Trace                              148
#define OP_Noop                               149
#define OP_Explain                            150


/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
** are encoded into bitvectors as follows:
*/
#define OPFLG_JUMP            0x0001  /* jump:  P2 holds jmp target */
#define OPFLG_OUT2_PRERELEASE 0x0002  /* out2-prerelease: */
#define OPFLG_IN1             0x0004  /* in1:   P1 is an input */
#define OPFLG_IN2             0x0008  /* in2:   P2 is an input */
#define OPFLG_IN3             0x0010  /* in3:   P3 is an input */
#define OPFLG_OUT2            0x0020  /* out2:  P2 is an output */
#define OPFLG_OUT3            0x0040  /* out3:  P3 is an output */
#define OPFLG_INITIALIZER {\


/*   0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\
/*   8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x24,\
/*  16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\
/*  24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\
/*  32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\
/*  40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\
/*  48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\
/*  56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/*  64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\
/*  72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
/*  80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
/*  88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\

/*  96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
/* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\
/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\
/* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\
/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,}

/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/

/*
** Prototypes for the VDBE interface.  See comments on the implementation







>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
|
|
|
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



















>
>
|
|
|
<
|
|
|
<
|
|
|
|
>
|
|
|
|
|
<







8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108











































































































9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132

9133
9134
9135

9136
9137
9138
9139
9140
9141
9142
9143
9144
9145

9146
9147
9148
9149
9150
9151
9152
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
** header file that defines a number for each opcode used by the VDBE.
*/
/************** Include opcodes.h in the middle of vdbe.h ********************/
/************** Begin file opcodes.h *****************************************/
/* Automatically generated.  Do not edit */
/* See the mkopcodeh.awk script for details */
#define OP_Function                             1
#define OP_Savepoint                            2
#define OP_AutoCommit                           3
#define OP_Transaction                          4
#define OP_SorterNext                           5
#define OP_Prev                                 6
#define OP_Next                                 7
#define OP_AggStep                              8
#define OP_Checkpoint                           9
#define OP_JournalMode                         10
#define OP_Vacuum                              11
#define OP_VFilter                             12
#define OP_VUpdate                             13
#define OP_Goto                                14
#define OP_Gosub                               15
#define OP_Return                              16
#define OP_Yield                               17
#define OP_HaltIfNull                          18
#define OP_Not                                 19   /* same as TK_NOT      */
#define OP_Halt                                20
#define OP_Integer                             21
#define OP_Int64                               22
#define OP_String                              23
#define OP_Null                                24
#define OP_Blob                                25
#define OP_Variable                            26
#define OP_Move                                27
#define OP_Copy                                28
#define OP_SCopy                               29
#define OP_ResultRow                           30
#define OP_CollSeq                             31
#define OP_AddImm                              32
#define OP_MustBeInt                           33
#define OP_RealAffinity                        34
#define OP_Permutation                         35
#define OP_Compare                             36
#define OP_Jump                                37
#define OP_Once                                38
#define OP_If                                  39
#define OP_IfNot                               40
#define OP_Column                              41
#define OP_Affinity                            42
#define OP_MakeRecord                          43
#define OP_Count                               44
#define OP_ReadCookie                          45
#define OP_SetCookie                           46
#define OP_VerifyCookie                        47
#define OP_OpenRead                            48
#define OP_OpenWrite                           49
#define OP_OpenAutoindex                       50
#define OP_OpenEphemeral                       51
#define OP_SorterOpen                          52
#define OP_OpenPseudo                          53
#define OP_Close                               54
#define OP_SeekLt                              55
#define OP_SeekLe                              56
#define OP_SeekGe                              57
#define OP_SeekGt                              58
#define OP_Seek                                59
#define OP_NotFound                            60
#define OP_Found                               61
#define OP_IsUnique                            62
#define OP_NotExists                           63
#define OP_Sequence                            64
#define OP_NewRowid                            65
#define OP_Insert                              66
#define OP_InsertInt                           67
#define OP_Or                                  68   /* same as TK_OR       */
#define OP_And                                 69   /* same as TK_AND      */
#define OP_Delete                              70
#define OP_ResetCount                          71
#define OP_SorterCompare                       72
#define OP_IsNull                              73   /* same as TK_ISNULL   */
#define OP_NotNull                             74   /* same as TK_NOTNULL  */
#define OP_Ne                                  75   /* same as TK_NE       */
#define OP_Eq                                  76   /* same as TK_EQ       */
#define OP_Gt                                  77   /* same as TK_GT       */
#define OP_Le                                  78   /* same as TK_LE       */
#define OP_Lt                                  79   /* same as TK_LT       */
#define OP_Ge                                  80   /* same as TK_GE       */
#define OP_SorterData                          81
#define OP_BitAnd                              82   /* same as TK_BITAND   */
#define OP_BitOr                               83   /* same as TK_BITOR    */
#define OP_ShiftLeft                           84   /* same as TK_LSHIFT   */
#define OP_ShiftRight                          85   /* same as TK_RSHIFT   */
#define OP_Add                                 86   /* same as TK_PLUS     */
#define OP_Subtract                            87   /* same as TK_MINUS    */
#define OP_Multiply                            88   /* same as TK_STAR     */
#define OP_Divide                              89   /* same as TK_SLASH    */
#define OP_Remainder                           90   /* same as TK_REM      */
#define OP_Concat                              91   /* same as TK_CONCAT   */
#define OP_RowKey                              92
#define OP_BitNot                              93   /* same as TK_BITNOT   */
#define OP_String8                             94   /* same as TK_STRING   */
#define OP_RowData                             95
#define OP_Rowid                               96
#define OP_NullRow                             97
#define OP_Last                                98
#define OP_SorterSort                          99
#define OP_Sort                               100
#define OP_Rewind                             101
#define OP_SorterInsert                       102
#define OP_IdxInsert                          103
#define OP_IdxDelete                          104
#define OP_IdxRowid                           105
#define OP_IdxLT                              106
#define OP_IdxGE                              107
#define OP_Destroy                            108
#define OP_Clear                              109
#define OP_CreateIndex                        110
#define OP_CreateTable                        111
#define OP_ParseSchema                        112
#define OP_LoadAnalysis                       113
#define OP_DropTable                          114
#define OP_DropIndex                          115
#define OP_DropTrigger                        116
#define OP_IntegrityCk                        117
#define OP_RowSetAdd                          118
#define OP_RowSetRead                         119
#define OP_RowSetTest                         120
#define OP_Program                            121
#define OP_Param                              122
#define OP_FkCounter                          123
#define OP_FkIfZero                           124
#define OP_MemMax                             125
#define OP_IfPos                              126
#define OP_IfNeg                              127
#define OP_IfZero                             128
#define OP_AggFinal                           129
#define OP_Real                               130   /* same as TK_FLOAT    */
#define OP_IncrVacuum                         131
#define OP_Expire                             132
#define OP_TableLock                          133
#define OP_VBegin                             134
#define OP_VCreate                            135
#define OP_VDestroy                           136
#define OP_VOpen                              137
#define OP_VColumn                            138
#define OP_VNext                              139
#define OP_VRename                            140
#define OP_ToText                             141   /* same as TK_TO_TEXT  */
#define OP_ToBlob                             142   /* same as TK_TO_BLOB  */
#define OP_ToNumeric                          143   /* same as TK_TO_NUMERIC*/
#define OP_ToInt                              144   /* same as TK_TO_INT   */
#define OP_ToReal                             145   /* same as TK_TO_REAL  */











































































































#define OP_Pagecount                          146
#define OP_MaxPgcnt                           147
#define OP_Trace                              148
#define OP_Noop                               149
#define OP_Explain                            150


/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
** are encoded into bitvectors as follows:
*/
#define OPFLG_JUMP            0x0001  /* jump:  P2 holds jmp target */
#define OPFLG_OUT2_PRERELEASE 0x0002  /* out2-prerelease: */
#define OPFLG_IN1             0x0004  /* in1:   P1 is an input */
#define OPFLG_IN2             0x0008  /* in2:   P2 is an input */
#define OPFLG_IN3             0x0010  /* in3:   P3 is an input */
#define OPFLG_OUT2            0x0020  /* out2:  P2 is an output */
#define OPFLG_OUT3            0x0040  /* out3:  P3 is an output */
#define OPFLG_INITIALIZER {\
/*   0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
/*   8 */ 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x01,\
/*  16 */ 0x04, 0x04, 0x10, 0x24, 0x00, 0x02, 0x02, 0x02,\
/*  24 */ 0x02, 0x02, 0x02, 0x00, 0x00, 0x24, 0x00, 0x00,\
/*  32 */ 0x04, 0x05, 0x04, 0x00, 0x00, 0x01, 0x01, 0x05,\

/*  40 */ 0x05, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\
/*  48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,\
/*  56 */ 0x11, 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11,\

/*  64 */ 0x02, 0x02, 0x00, 0x00, 0x4c, 0x4c, 0x00, 0x00,\
/*  72 */ 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
/*  80 */ 0x15, 0x00, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
/*  88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x00, 0x24, 0x02, 0x00,\
/*  96 */ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08,\
/* 104 */ 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x02, 0x02,\
/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\
/* 120 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x08, 0x05, 0x05,\
/* 128 */ 0x05, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,\
/* 136 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x04, 0x04,\

/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,}

/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/

/*
** Prototypes for the VDBE interface.  See comments on the implementation
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8);
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
#ifndef SQLITE_OMIT_TRACE
SQLITE_PRIVATE   char *sqlite3VdbeExpandSql(Vdbe*, const char*);
#endif

SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);







|







9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
#ifndef SQLITE_OMIT_TRACE
SQLITE_PRIVATE   char *sqlite3VdbeExpandSql(Vdbe*, const char*);
#endif

SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
9302
9303
9304
9305
9306
9307
9308
9309
9310












9311
9312
9313
9314
9315
9316
9317
#define PAGER_JOURNALMODE_TRUNCATE    3   /* Commit by truncating journal */
#define PAGER_JOURNALMODE_MEMORY      4   /* In-memory journal file */
#define PAGER_JOURNALMODE_WAL         5   /* Use write-ahead logging */

/*
** Flags that make up the mask passed to sqlite3PagerAcquire().
*/
#define PAGER_ACQUIRE_NOCONTENT     0x01  /* Do not load data from disk */
#define PAGER_ACQUIRE_READONLY      0x02  /* Read-only page is acceptable */













/*
** The remainder of this file contains the declarations of the functions
** that make up the Pager sub-system API. See source code comments for 
** a detailed description of each routine.
*/








|
|
>
>
>
>
>
>
>
>
>
>
>
>







9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
#define PAGER_JOURNALMODE_TRUNCATE    3   /* Commit by truncating journal */
#define PAGER_JOURNALMODE_MEMORY      4   /* In-memory journal file */
#define PAGER_JOURNALMODE_WAL         5   /* Use write-ahead logging */

/*
** Flags that make up the mask passed to sqlite3PagerAcquire().
*/
#define PAGER_GET_NOCONTENT     0x01  /* Do not load data from disk */
#define PAGER_GET_READONLY      0x02  /* Read-only page is acceptable */

/*
** Flags for sqlite3PagerSetFlags()
*/
#define PAGER_SYNCHRONOUS_OFF       0x01  /* PRAGMA synchronous=OFF */
#define PAGER_SYNCHRONOUS_NORMAL    0x02  /* PRAGMA synchronous=NORMAL */
#define PAGER_SYNCHRONOUS_FULL      0x03  /* PRAGMA synchronous=FULL */
#define PAGER_SYNCHRONOUS_MASK      0x03  /* Mask for three values above */
#define PAGER_FULLFSYNC             0x04  /* PRAGMA fullfsync=ON */
#define PAGER_CKPT_FULLFSYNC        0x08  /* PRAGMA checkpoint_fullfsync=ON */
#define PAGER_CACHESPILL            0x10  /* PRAGMA cache_spill=ON */
#define PAGER_FLAGS_MASK            0x1c  /* All above except SYNCHRONOUS */

/*
** The remainder of this file contains the declarations of the functions
** that make up the Pager sub-system API. See source code comments for 
** a detailed description of each routine.
*/

9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
/* Functions used to configure a Pager object. */
SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
SQLITE_PRIVATE void sqlite3PagerShrink(Pager*);
SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int);
SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*);
SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*);
SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*);








|







9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
/* Functions used to configure a Pager object. */
SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
SQLITE_PRIVATE void sqlite3PagerShrink(Pager*);
SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned);
SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int);
SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*);
SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*);
SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*);

10194
10195
10196
10197
10198
10199
10200



10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
#define ENC(db) ((db)->aDb[0].pSchema->enc)

/*
** Possible values for the sqlite3.flags.
*/
#define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
#define SQLITE_InternChanges  0x00000002  /* Uncommitted Hash table changes */



#define SQLITE_FullColNames   0x00000004  /* Show full column names on SELECT */
#define SQLITE_ShortColNames  0x00000008  /* Show short columns names */
#define SQLITE_CountRows      0x00000010  /* Count rows changed by INSERT, */
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000020  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_SqlTrace       0x00000040  /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    0x00000080  /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema    0x00000100  /* OK to update SQLITE_MASTER */
#define SQLITE_VdbeAddopTrace 0x00000200  /* Trace sqlite3VdbeAddOp() calls */
#define SQLITE_IgnoreChecks   0x00000400  /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0000800  /* For shared-cache mode */
#define SQLITE_LegacyFileFmt  0x00001000  /* Create new databases in format 1 */
#define SQLITE_FullFSync      0x00002000  /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync  0x00004000  /* Use full fsync for checkpoint */
#define SQLITE_RecoveryMode   0x00008000  /* Ignore schema errors */
#define SQLITE_ReverseOrder   0x00010000  /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers    0x00020000  /* Enable recursive triggers */
#define SQLITE_ForeignKeys    0x00040000  /* Enforce foreign key constraints  */
#define SQLITE_AutoIndex      0x00080000  /* Enable automatic indexes */
#define SQLITE_PreferBuiltin  0x00100000  /* Preference to built-in funcs */
#define SQLITE_LoadExtension  0x00200000  /* Enable load_extension */
#define SQLITE_EnableTrigger  0x00400000  /* True to enable triggers */
#define SQLITE_DeferFKs       0x00800000  /* Defer all FK constraints */
#define SQLITE_QueryOnly      0x01000000  /* Disable database changes */


/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/







>
>
>
|
|
|


|

|
|
|
|
|
|
|
<
<
|
|
|
|
|
|
|
|
|
|







10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229


10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
#define ENC(db) ((db)->aDb[0].pSchema->enc)

/*
** Possible values for the sqlite3.flags.
*/
#define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
#define SQLITE_InternChanges  0x00000002  /* Uncommitted Hash table changes */
#define SQLITE_FullFSync      0x00000004  /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync  0x00000008  /* Use full fsync for checkpoint */
#define SQLITE_CacheSpill     0x00000010  /* OK to spill pager cache */
#define SQLITE_FullColNames   0x00000020  /* Show full column names on SELECT */
#define SQLITE_ShortColNames  0x00000040  /* Show short columns names */
#define SQLITE_CountRows      0x00000080  /* Count rows changed by INSERT, */
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000100  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_SqlTrace       0x00000200  /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    0x00000400  /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema    0x00000800  /* OK to update SQLITE_MASTER */
#define SQLITE_VdbeAddopTrace 0x00001000  /* Trace sqlite3VdbeAddOp() calls */
#define SQLITE_IgnoreChecks   0x00002000  /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0004000  /* For shared-cache mode */
#define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */


#define SQLITE_RecoveryMode   0x00010000  /* Ignore schema errors */
#define SQLITE_ReverseOrder   0x00020000  /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers    0x00040000  /* Enable recursive triggers */
#define SQLITE_ForeignKeys    0x00080000  /* Enforce foreign key constraints  */
#define SQLITE_AutoIndex      0x00100000  /* Enable automatic indexes */
#define SQLITE_PreferBuiltin  0x00200000  /* Preference to built-in funcs */
#define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
#define SQLITE_EnableTrigger  0x00800000  /* True to enable triggers */
#define SQLITE_DeferFKs       0x01000000  /* Defer all FK constraints */
#define SQLITE_QueryOnly      0x02000000  /* Disable database changes */


/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
10686
10687
10688
10689
10690
10691
10692




10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
#define OE_Default  99  /* Do whatever the default action is */


/*
** An instance of the following structure is passed as the first
** argument to sqlite3VdbeKeyCompare and is used to control the 
** comparison of the two index keys.




*/
struct KeyInfo {
  sqlite3 *db;        /* The database connection */
  u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
  u16 nField;         /* Number of entries in aColl[] */
  u8 *aSortOrder;     /* Sort order for each column.  May be NULL */
  CollSeq *aColl[1];  /* Collating sequence for each term of the key */
};

/*
** An instance of the following structure holds information about a
** single index record that has already been parsed out into individual
** values.







>
>
>
>




|
|







10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
#define OE_Default  99  /* Do whatever the default action is */


/*
** An instance of the following structure is passed as the first
** argument to sqlite3VdbeKeyCompare and is used to control the 
** comparison of the two index keys.
**
** Note that aSortOrder[] and aColl[] have nField+1 slots.  There
** are nField slots for the columns of an index then one extra slot
** for the rowid at the end.
*/
struct KeyInfo {
  sqlite3 *db;        /* The database connection */
  u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
  u16 nField;         /* Maximum index for aColl[] and aSortOrder[] */
  u8 *aSortOrder;     /* Sort order for each column. */
  CollSeq *aColl[1];  /* Collating sequence for each term of the key */
};

/*
** An instance of the following structure holds information about a
** single index record that has already been parsed out into individual
** values.
10760
10761
10762
10763
10764
10765
10766

10767
10768
10769
10770
10771
10772
10773
10774

10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
  tRowcnt *aiRowEst;       /* From ANALYZE: Est. rows selected by each column */
  Table *pTable;           /* The SQL table being indexed */
  char *zColAff;           /* String defining the affinity of each column */
  Index *pNext;            /* The next index associated with the same table */
  Schema *pSchema;         /* Schema containing this index */
  u8 *aSortOrder;          /* for each column: True==DESC, False==ASC */
  char **azColl;           /* Array of collation sequence names for index */

  int tnum;                /* DB Page containing root of this index */
  u16 nColumn;             /* Number of columns in table used by this index */
  u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  unsigned autoIndex:2;    /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
  unsigned bUnordered:1;   /* Use this index for == or IN queries only */
  unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
#ifdef SQLITE_ENABLE_STAT3
  int nSample;             /* Number of elements in aSample[] */

  tRowcnt avgEq;           /* Average nEq value for key values not in aSample */
  IndexSample *aSample;    /* Samples of the left-most key */
#endif
};

/*
** Each sample stored in the sqlite_stat3 table is represented in memory 
** using a structure of this type.  See documentation at the top of the
** analyze.c source file for additional information.
*/
struct IndexSample {
  union {
    char *z;        /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */
    double r;       /* Value if eType is SQLITE_FLOAT */
    i64 i;          /* Value if eType is SQLITE_INTEGER */
  } u;
  u8 eType;         /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
  int nByte;        /* Size in byte of text or blob. */
  tRowcnt nEq;      /* Est. number of rows where the key equals this sample */
  tRowcnt nLt;      /* Est. number of rows where key is less than this sample */
  tRowcnt nDLt;     /* Est. number of distinct keys less than this sample */
};

/*
** Each token coming out of the lexer is an instance of
** this structure.  Tokens are also used as part of an expression.
**
** Note if Token.z==0 then Token.dyn and Token.n are undefined and







>






|

>
|










<
<
<
|
<
|
<
|
|
|







10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804



10805

10806

10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
  tRowcnt *aiRowEst;       /* From ANALYZE: Est. rows selected by each column */
  Table *pTable;           /* The SQL table being indexed */
  char *zColAff;           /* String defining the affinity of each column */
  Index *pNext;            /* The next index associated with the same table */
  Schema *pSchema;         /* Schema containing this index */
  u8 *aSortOrder;          /* for each column: True==DESC, False==ASC */
  char **azColl;           /* Array of collation sequence names for index */
  Expr *pPartIdxWhere;     /* WHERE clause for partial indices */
  int tnum;                /* DB Page containing root of this index */
  u16 nColumn;             /* Number of columns in table used by this index */
  u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  unsigned autoIndex:2;    /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
  unsigned bUnordered:1;   /* Use this index for == or IN queries only */
  unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  int nSample;             /* Number of elements in aSample[] */
  int nSampleCol;          /* Size of IndexSample.anEq[] and so on */
  tRowcnt *aAvgEq;         /* Average nEq values for keys not in aSample */
  IndexSample *aSample;    /* Samples of the left-most key */
#endif
};

/*
** Each sample stored in the sqlite_stat3 table is represented in memory 
** using a structure of this type.  See documentation at the top of the
** analyze.c source file for additional information.
*/
struct IndexSample {



  void *p;          /* Pointer to sampled record */

  int n;            /* Size of record in bytes */

  tRowcnt *anEq;    /* Est. number of rows where the key equals this sample */
  tRowcnt *anLt;    /* Est. number of rows where key is less than this sample */
  tRowcnt *anDLt;   /* Est. number of distinct keys less than this sample */
};

/*
** Each token coming out of the lexer is an instance of
** this structure.  Tokens are also used as part of an expression.
**
** Note if Token.z==0 then Token.dyn and Token.n are undefined and
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
** NameContext in the parent query.  Thus the process of scanning the
** NameContext list corresponds to searching through successively outer
** subqueries looking for a match.
*/
struct NameContext {
  Parse *pParse;       /* The parser */
  SrcList *pSrcList;   /* One or more tables used to resolve names */
  ExprList *pEList;    /* Optional list of named expressions */
  AggInfo *pAggInfo;   /* Information about aggregates at this level */
  NameContext *pNext;  /* Next outer name context.  NULL for outermost */
  int nRef;            /* Number of names resolved by this context */
  int nErr;            /* Number of errors encountered while resolving names */
  u8 ncFlags;          /* Zero or more NC_* flags defined below */
};

/*
** Allowed values for the NameContext, ncFlags field.
*/
#define NC_AllowAgg  0x01    /* Aggregate functions are allowed here */
#define NC_HasAgg    0x02    /* One or more aggregate functions seen */
#define NC_IsCheck   0x04    /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x08    /* True if analyzing arguments to an agg func */
#define NC_AsMaybe   0x10    /* Resolve to AS terms of the result set only
                             ** if no other resolution is available */

/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause.  nOffset is set to 0.
** If there is a LIMIT clause, the parser sets nLimit to the value of the







|














|
<







11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259

11260
11261
11262
11263
11264
11265
11266
** NameContext in the parent query.  Thus the process of scanning the
** NameContext list corresponds to searching through successively outer
** subqueries looking for a match.
*/
struct NameContext {
  Parse *pParse;       /* The parser */
  SrcList *pSrcList;   /* One or more tables used to resolve names */
  ExprList *pEList;    /* Optional list of result-set columns */
  AggInfo *pAggInfo;   /* Information about aggregates at this level */
  NameContext *pNext;  /* Next outer name context.  NULL for outermost */
  int nRef;            /* Number of names resolved by this context */
  int nErr;            /* Number of errors encountered while resolving names */
  u8 ncFlags;          /* Zero or more NC_* flags defined below */
};

/*
** Allowed values for the NameContext, ncFlags field.
*/
#define NC_AllowAgg  0x01    /* Aggregate functions are allowed here */
#define NC_HasAgg    0x02    /* One or more aggregate functions seen */
#define NC_IsCheck   0x04    /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x08    /* True if analyzing arguments to an agg func */
#define NC_PartIdx   0x10    /* True if resolving a partial index WHERE */


/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause.  nOffset is set to 0.
** If there is a LIMIT clause, the parser sets nLimit to the value of the
11294
11295
11296
11297
11298
11299
11300

11301
11302
11303
11304
11305
11306
11307
#define SF_UsesEphemeral   0x0008  /* Uses the OpenEphemeral opcode */
#define SF_Expanded        0x0010  /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
#define SF_UseSorter       0x0040  /* Sort using a sorter */
#define SF_Values          0x0080  /* Synthesized from VALUES clause */
#define SF_Materialize     0x0100  /* Force materialization of views */
#define SF_NestedFrom      0x0200  /* Part of a parenthesized FROM clause */



/*
** The results of a select can be distributed in several ways.  The
** "SRT" prefix means "SELECT Result Type".
*/
#define SRT_Union        1  /* Store result as keys in an index */







>







11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
#define SF_UsesEphemeral   0x0008  /* Uses the OpenEphemeral opcode */
#define SF_Expanded        0x0010  /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
#define SF_UseSorter       0x0040  /* Sort using a sorter */
#define SF_Values          0x0080  /* Synthesized from VALUES clause */
#define SF_Materialize     0x0100  /* Force materialization of views */
#define SF_NestedFrom      0x0200  /* Part of a parenthesized FROM clause */
#define SF_MaybeConvert    0x0400  /* Need convertCompoundSelectToSubquery() */


/*
** The results of a select can be distributed in several ways.  The
** "SRT" prefix means "SELECT Result Type".
*/
#define SRT_Union        1  /* Store result as keys in an index */
11415
11416
11417
11418
11419
11420
11421

11422
11423
11424
11425
11426
11427
11428
11429
11430

11431
11432
11433
11434
11435
11436
11437
  u8 nested;           /* Number of nested calls to the parser/code generator */
  u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  u8 nTempInUse;       /* Number of aTempReg[] currently checked out */
  u8 nColCache;        /* Number of entries in aColCache[] */
  u8 iColCache;        /* Next entry in aColCache[] to replace */
  u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */

  int aTempReg[8];     /* Holding area for temporary registers */
  int nRangeReg;       /* Size of the temporary register block */
  int iRangeReg;       /* First register in temporary register block */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int nOnce;           /* Number of OP_Once instructions so far */
  int ckBase;          /* Base register of data during check constraints */

  int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
  int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
  struct yColCache {
    int iTable;           /* Table cursor number */
    int iColumn;          /* Table column number */
    u8 tempReg;           /* iReg is a temp register that needs to be freed */
    int iLevel;           /* Nesting level */







>









>







11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
  u8 nested;           /* Number of nested calls to the parser/code generator */
  u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  u8 nTempInUse;       /* Number of aTempReg[] currently checked out */
  u8 nColCache;        /* Number of entries in aColCache[] */
  u8 iColCache;        /* Next entry in aColCache[] to replace */
  u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */
  u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
  int aTempReg[8];     /* Holding area for temporary registers */
  int nRangeReg;       /* Size of the temporary register block */
  int iRangeReg;       /* First register in temporary register block */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int nOnce;           /* Number of OP_Once instructions so far */
  int ckBase;          /* Base register of data during check constraints */
  int iPartIdxTab;     /* Table corresponding to a partial index */
  int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
  int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
  struct yColCache {
    int iTable;           /* Table cursor number */
    int iColumn;          /* Table column number */
    u8 tempReg;           /* iReg is a temp register that needs to be freed */
    int iLevel;           /* Nesting level */
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649


11650
11651
11652
11653
11654
11655
11656
struct StrAccum {
  sqlite3 *db;         /* Optional database for lookaside.  Can be NULL */
  char *zBase;         /* A base allocation.  Not from malloc. */
  char *zText;         /* The string collected so far */
  int  nChar;          /* Length of the string so far */
  int  nAlloc;         /* Amount of space allocated in zText */
  int  mxAlloc;        /* Maximum allowed string length */
  u8   mallocFailed;   /* Becomes true if any memory allocation fails */
  u8   useMalloc;      /* 0: none,  1: sqlite3DbMalloc,  2: sqlite3_malloc */
  u8   tooBig;         /* Becomes true if string size exceeds limits */
};



/*
** A pointer to this structure is used to communicate information
** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
*/
typedef struct {
  sqlite3 *db;        /* The database being initialized */







<

|

>
>







11655
11656
11657
11658
11659
11660
11661

11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
struct StrAccum {
  sqlite3 *db;         /* Optional database for lookaside.  Can be NULL */
  char *zBase;         /* A base allocation.  Not from malloc. */
  char *zText;         /* The string collected so far */
  int  nChar;          /* Length of the string so far */
  int  nAlloc;         /* Amount of space allocated in zText */
  int  mxAlloc;        /* Maximum allowed string length */

  u8   useMalloc;      /* 0: none,  1: sqlite3DbMalloc,  2: sqlite3_malloc */
  u8   accError;       /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
};
#define STRACCUM_NOMEM   1
#define STRACCUM_TOOBIG  2

/*
** A pointer to this structure is used to communicate information
** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
*/
typedef struct {
  sqlite3 *db;        /* The database being initialized */
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                        Token*, int, int);
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                         Expr*,ExprList*,u16,Expr*,Expr*);
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);







|







12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                          Expr*, int, int);
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                         Expr*,ExprList*,u16,Expr*,Expr*);
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
12053
12054
12055
12056
12057
12058
12059
12060
12061

12062
12063
12064
12065
12066
12067
12068
SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*);

SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
SQLITE_PRIVATE void sqlite3PrngResetState(void);







|
|
>







12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
SQLITE_PRIVATE void sqlite3PrngResetState(void);
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
                                     int*,int,int,int,int,int*);
SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
SQLITE_PRIVATE void sqlite3MayAbort(Parse*);







|







12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
                                     int*,int,int,int,int,int*);
SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
SQLITE_PRIVATE void sqlite3MayAbort(Parse*);
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, 
                        void(*)(void*));
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
#ifdef SQLITE_ENABLE_STAT3
SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *);
#endif
SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[];
SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
SQLITE_PRIVATE const Token sqlite3IntTokens[];







<
<
<







12274
12275
12276
12277
12278
12279
12280



12281
12282
12283
12284
12285
12286
12287
SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, 
                        void(*)(void*));
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);



SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[];
SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
SQLITE_PRIVATE const Token sqlite3IntTokens[];
12284
12285
12286
12287
12288
12289
12290

12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309

12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328






12329
12330
12331
12332
12333
12334
12335
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);

SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
SQLITE_PRIVATE char sqlite3AffinityType(const char*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*);
SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int);
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
SQLITE_PRIVATE void sqlite3SchemaClear(void *);
SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);

SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
  void (*)(sqlite3_context*,int,sqlite3_value **),
  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
  FuncDestructor *pDestructor
);
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);

SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum*,int);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);

SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);







/*
** The interface to the LEMON-generated parser
*/
SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t));
SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);







>



















>



















>
>
>
>
>
>







12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
SQLITE_PRIVATE char sqlite3AffinityType(const char*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*);
SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int);
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
SQLITE_PRIVATE void sqlite3SchemaClear(void *);
SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int);
SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
  void (*)(sqlite3_context*,int,sqlite3_value **),
  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
  FuncDestructor *pDestructor
);
SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);

SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum*,int);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);

SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void);
SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*);
#endif

/*
** The interface to the LEMON-generated parser
*/
SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t));
SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377

12378
12379
12380
12381
12382
12383
12384
#  define sqlite3VtabUnlock(X)
#  define sqlite3VtabUnlockList(X)
#  define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
#  define sqlite3GetVTable(X,Y)  ((VTable*)0)
#else
SQLITE_PRIVATE    void sqlite3VtabClear(sqlite3 *db, Table*);
SQLITE_PRIVATE    void sqlite3VtabDisconnect(sqlite3 *db, Table *p);
SQLITE_PRIVATE    int sqlite3VtabSync(sqlite3 *db, char **);
SQLITE_PRIVATE    int sqlite3VtabRollback(sqlite3 *db);
SQLITE_PRIVATE    int sqlite3VtabCommit(sqlite3 *db);
SQLITE_PRIVATE    void sqlite3VtabLock(VTable *);
SQLITE_PRIVATE    void sqlite3VtabUnlock(VTable *);
SQLITE_PRIVATE    void sqlite3VtabUnlockList(sqlite3*);
SQLITE_PRIVATE    int sqlite3VtabSavepoint(sqlite3 *, int, int);

SQLITE_PRIVATE    VTable *sqlite3GetVTable(sqlite3*, Table*);
#  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*);







|






>







12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
#  define sqlite3VtabUnlock(X)
#  define sqlite3VtabUnlockList(X)
#  define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
#  define sqlite3GetVTable(X,Y)  ((VTable*)0)
#else
SQLITE_PRIVATE    void sqlite3VtabClear(sqlite3 *db, Table*);
SQLITE_PRIVATE    void sqlite3VtabDisconnect(sqlite3 *db, Table *p);
SQLITE_PRIVATE    int sqlite3VtabSync(sqlite3 *db, Vdbe*);
SQLITE_PRIVATE    int sqlite3VtabRollback(sqlite3 *db);
SQLITE_PRIVATE    int sqlite3VtabCommit(sqlite3 *db);
SQLITE_PRIVATE    void sqlite3VtabLock(VTable *);
SQLITE_PRIVATE    void sqlite3VtabUnlock(VTable *);
SQLITE_PRIVATE    void sqlite3VtabUnlockList(sqlite3*);
SQLITE_PRIVATE    int sqlite3VtabSavepoint(sqlite3 *, int, int);
SQLITE_PRIVATE    void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
SQLITE_PRIVATE    VTable *sqlite3GetVTable(sqlite3*, Table*);
#  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*);
12905
12906
12907
12908
12909
12910
12911


12912
12913
12914
12915
12916
12917
12918
12919
#endif
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
  "ENABLE_OVERSIZE_CELL_CHECK",
#endif
#ifdef SQLITE_ENABLE_RTREE
  "ENABLE_RTREE",
#endif


#ifdef SQLITE_ENABLE_STAT3
  "ENABLE_STAT3",
#endif
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
  "ENABLE_UNLOCK_NOTIFY",
#endif
#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  "ENABLE_UPDATE_DELETE_LIMIT",







>
>
|







12929
12930
12931
12932
12933
12934
12935
12936
12937
12938
12939
12940
12941
12942
12943
12944
12945
#endif
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
  "ENABLE_OVERSIZE_CELL_CHECK",
#endif
#ifdef SQLITE_ENABLE_RTREE
  "ENABLE_RTREE",
#endif
#if defined(SQLITE_ENABLE_STAT4)
  "ENABLE_STAT4",
#elif defined(SQLITE_ENABLE_STAT3)
  "ENABLE_STAT3",
#endif
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
  "ENABLE_UNLOCK_NOTIFY",
#endif
#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  "ENABLE_UPDATE_DELETE_LIMIT",
13255
13256
13257
13258
13259
13260
13261



13262
13263
13264
13265
13266
13267
13268

/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;

/* Opaque type used by the explainer */
typedef struct Explain Explain;




/*
** A cursor is a pointer into a single BTree within a database file.
** The cursor can seek to a BTree entry with a particular key, or
** loop over all entries of the Btree.  You can also insert new BTree
** entries or retrieve the key or data from the entry that the cursor
** is currently pointing to.
** 







>
>
>







13281
13282
13283
13284
13285
13286
13287
13288
13289
13290
13291
13292
13293
13294
13295
13296
13297

/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;

/* Opaque type used by the explainer */
typedef struct Explain Explain;

/* Elements of the linked list at Vdbe.pAuxData */
typedef struct AuxData AuxData;

/*
** A cursor is a pointer into a single BTree within a database file.
** The cursor can seek to a BTree entry with a particular key, or
** loop over all entries of the Btree.  You can also insert new BTree
** entries or retrieve the key or data from the entry that the cursor
** is currently pointing to.
** 
13441
13442
13443
13444
13445
13446
13447
13448
13449
13450
13451
13452
13453
13454
13455

13456
13457
13458
13459
13460
13461


13462
13463
13464
13465
13466
13467
13468
13469
13470
13471
13472
13473
13474
13475
13476
13477
13478
13479
13480
13481
13482
13483
13484
13485


13486
13487

13488
13489
13490
13491
13492
13493
13494
** Return true if a memory cell is not marked as invalid.  This macro
** is for use inside assert() statements only.
*/
#ifdef SQLITE_DEBUG
#define memIsValid(M)  ((M)->flags & MEM_Invalid)==0
#endif


/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
** additional information about auxiliary information bound to arguments
** of the function.  This is used to implement the sqlite3_get_auxdata()
** and sqlite3_set_auxdata() APIs.  The "auxdata" is some auxiliary data
** that can be associated with a constant argument to a function.  This
** allows functions such as "regexp" to compile their constant regular
** expression argument once and reused the compiled code for multiple

** invocations.
*/
struct VdbeFunc {
  FuncDef *pFunc;               /* The definition of the function */
  int nAux;                     /* Number of entries allocated for apAux[] */
  struct AuxData {


    void *pAux;                   /* Aux data for the i-th argument */
    void (*xDelete)(void *);      /* Destructor for the aux data */
  } apAux[1];                   /* One slot for each function argument */
};

/*
** The "context" argument for a installable function.  A pointer to an
** instance of this structure is the first argument to the routines used
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h.  So all routines,
** even the public interface to SQLite, can use a pointer to this structure.
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbeInt.h because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
  FuncDef *pFunc;       /* Pointer to function information.  MUST BE FIRST */
  VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
  Mem s;                /* The return value is stored here */
  Mem *pMem;            /* Memory cell used to store aggregate context */
  CollSeq *pColl;       /* Collating sequence */


  int isError;          /* Error code returned by the function. */
  int skipFlag;         /* Skip skip accumulator loading if true */

};

/*
** An Explain object accumulates indented output which is helpful
** in describing recursive data structures.
*/
struct Explain {







|
|
<
<
|
|
<
<
>
|

<
<
<
|
>
>
|
|
|

















<



>
>

|
>







13470
13471
13472
13473
13474
13475
13476
13477
13478


13479
13480


13481
13482
13483



13484
13485
13486
13487
13488
13489
13490
13491
13492
13493
13494
13495
13496
13497
13498
13499
13500
13501
13502
13503
13504
13505
13506

13507
13508
13509
13510
13511
13512
13513
13514
13515
13516
13517
13518
13519
13520
13521
** Return true if a memory cell is not marked as invalid.  This macro
** is for use inside assert() statements only.
*/
#ifdef SQLITE_DEBUG
#define memIsValid(M)  ((M)->flags & MEM_Invalid)==0
#endif

/*
** Each auxilliary data pointer stored by a user defined function 


** implementation calling sqlite3_set_auxdata() is stored in an instance
** of this structure. All such structures associated with a single VM


** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
** when the VM is halted (if not before).
*/



struct AuxData {
  int iOp;                        /* Instruction number of OP_Function opcode */
  int iArg;                       /* Index of function argument. */
  void *pAux;                     /* Aux data pointer */
  void (*xDelete)(void *);        /* Destructor for the aux data */
  AuxData *pNext;                 /* Next element in list */
};

/*
** The "context" argument for a installable function.  A pointer to an
** instance of this structure is the first argument to the routines used
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h.  So all routines,
** even the public interface to SQLite, can use a pointer to this structure.
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbeInt.h because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
  FuncDef *pFunc;       /* Pointer to function information.  MUST BE FIRST */

  Mem s;                /* The return value is stored here */
  Mem *pMem;            /* Memory cell used to store aggregate context */
  CollSeq *pColl;       /* Collating sequence */
  Vdbe *pVdbe;          /* The VM that owns this context */
  int iOp;              /* Instruction number of OP_Function */
  int isError;          /* Error code returned by the function. */
  u8 skipFlag;          /* Skip skip accumulator loading if true */
  u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
};

/*
** An Explain object accumulates indented output which is helpful
** in describing recursive data structures.
*/
struct Explain {
13556
13557
13558
13559
13560
13561
13562
13563
13564
13565
13566
13567
13568
13569
13570
  bft bIsReader:1;        /* True for statements that read */
  bft isPrepareV2:1;      /* True if prepared with prepare_v2() */
  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
  int nChange;            /* Number of db changes made since last reset */
  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
  int aCounter[4];        /* Counters used by sqlite3_stmt_status() */
#ifndef SQLITE_OMIT_TRACE
  i64 startTime;          /* Time when query started - used for profiling */
#endif
  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
  char *zSql;             /* Text of the SQL statement that generated this */







|







13583
13584
13585
13586
13587
13588
13589
13590
13591
13592
13593
13594
13595
13596
13597
  bft bIsReader:1;        /* True for statements that read */
  bft isPrepareV2:1;      /* True if prepared with prepare_v2() */
  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
  int nChange;            /* Number of db changes made since last reset */
  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
  u32 aCounter[5];        /* Counters used by sqlite3_stmt_status() */
#ifndef SQLITE_OMIT_TRACE
  i64 startTime;          /* Time when query started - used for profiling */
#endif
  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
  char *zSql;             /* Text of the SQL statement that generated this */
13579
13580
13581
13582
13583
13584
13585

13586
13587
13588
13589
13590
13591
13592
  VdbeFrame *pFrame;      /* Parent frame */
  VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
  int nFrame;             /* Number of frames in pFrame list */
  u32 expmask;            /* Binding to these vars invalidates VM */
  SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
  int nOnceFlag;          /* Size of array aOnceFlag[] */
  u8 *aOnceFlag;          /* Flags for OP_Once */

};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */







>







13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
  VdbeFrame *pFrame;      /* Parent frame */
  VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
  int nFrame;             /* Number of frames in pFrame list */
  u32 expmask;            /* Binding to these vars invalidates VM */
  SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
  int nOnceFlag;          /* Size of array aOnceFlag[] */
  u8 *aOnceFlag;          /* Flags for OP_Once */
  AuxData *pAuxData;      /* Linked list of auxdata allocations */
};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);

int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);







|







13630
13631
13632
13633
13634
13635
13636
13637
13638
13639
13640
13641
13642
13643
13644
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);

int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
16062
16063
16064
16065
16066
16067
16068
16069
16070
16071
16072
16073
16074
16075
16076
*/
static int sqlite3MemSize(void *p){
  struct MemBlockHdr *pHdr;
  if( !p ){
    return 0;
  }
  pHdr = sqlite3MemsysGetHeader(p);
  return pHdr->iSize;
}

/*
** Initialize the memory allocation subsystem.
*/
static int sqlite3MemInit(void *NotUsed){
  UNUSED_PARAMETER(NotUsed);







|







16090
16091
16092
16093
16094
16095
16096
16097
16098
16099
16100
16101
16102
16103
16104
*/
static int sqlite3MemSize(void *p){
  struct MemBlockHdr *pHdr;
  if( !p ){
    return 0;
  }
  pHdr = sqlite3MemsysGetHeader(p);
  return (int)pHdr->iSize;
}

/*
** Initialize the memory allocation subsystem.
*/
static int sqlite3MemInit(void *NotUsed){
  UNUSED_PARAMETER(NotUsed);
16104
16105
16106
16107
16108
16109
16110
16111
16112
16113
16114
16115
16116
16117
16118
16119
16120
16121
16122
16123
16124
16125
16126
** to clear the content of a freed allocation to unpredictable values.
*/
static void randomFill(char *pBuf, int nByte){
  unsigned int x, y, r;
  x = SQLITE_PTR_TO_INT(pBuf);
  y = nByte | 1;
  while( nByte >= 4 ){
    x = (x>>1) ^ (-(x&1) & 0xd0000001);
    y = y*1103515245 + 12345;
    r = x ^ y;
    *(int*)pBuf = r;
    pBuf += 4;
    nByte -= 4;
  }
  while( nByte-- > 0 ){
    x = (x>>1) ^ (-(x&1) & 0xd0000001);
    y = y*1103515245 + 12345;
    r = x ^ y;
    *(pBuf++) = r & 0xff;
  }
}

/*







|







|







16132
16133
16134
16135
16136
16137
16138
16139
16140
16141
16142
16143
16144
16145
16146
16147
16148
16149
16150
16151
16152
16153
16154
** to clear the content of a freed allocation to unpredictable values.
*/
static void randomFill(char *pBuf, int nByte){
  unsigned int x, y, r;
  x = SQLITE_PTR_TO_INT(pBuf);
  y = nByte | 1;
  while( nByte >= 4 ){
    x = (x>>1) ^ (-(int)(x&1) & 0xd0000001);
    y = y*1103515245 + 12345;
    r = x ^ y;
    *(int*)pBuf = r;
    pBuf += 4;
    nByte -= 4;
  }
  while( nByte-- > 0 ){
    x = (x>>1) ^ (-(int)(x&1) & 0xd0000001);
    y = y*1103515245 + 12345;
    r = x ^ y;
    *(pBuf++) = r & 0xff;
  }
}

/*
16207
16208
16209
16210
16211
16212
16213
16214
16215
16216
16217
16218
16219
16220
16221
16222
16223
    pHdr->pNext->pPrev = pHdr->pPrev;
  }else{
    assert( mem.pLast==pHdr );
    mem.pLast = pHdr->pPrev;
  }
  z = (char*)pBt;
  z -= pHdr->nTitle;
  adjustStats(pHdr->iSize, -1);
  randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
                pHdr->iSize + sizeof(int) + pHdr->nTitle);
  free(z);
  sqlite3_mutex_leave(mem.mutex);  
}

/*
** Change the size of an existing memory allocation.
**







|

|







16235
16236
16237
16238
16239
16240
16241
16242
16243
16244
16245
16246
16247
16248
16249
16250
16251
    pHdr->pNext->pPrev = pHdr->pPrev;
  }else{
    assert( mem.pLast==pHdr );
    mem.pLast = pHdr->pPrev;
  }
  z = (char*)pBt;
  z -= pHdr->nTitle;
  adjustStats((int)pHdr->iSize, -1);
  randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
                (int)pHdr->iSize + sizeof(int) + pHdr->nTitle);
  free(z);
  sqlite3_mutex_leave(mem.mutex);  
}

/*
** Change the size of an existing memory allocation.
**
16231
16232
16233
16234
16235
16236
16237
16238
16239
16240
16241
16242
16243
16244
16245
16246
16247
  struct MemBlockHdr *pOldHdr;
  void *pNew;
  assert( mem.disallow==0 );
  assert( (nByte & 7)==0 );     /* EV: R-46199-30249 */
  pOldHdr = sqlite3MemsysGetHeader(pPrior);
  pNew = sqlite3MemMalloc(nByte);
  if( pNew ){
    memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
    if( nByte>pOldHdr->iSize ){
      randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize);
    }
    sqlite3MemFree(pPrior);
  }
  return pNew;
}

/*







|

|







16259
16260
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272
16273
16274
16275
  struct MemBlockHdr *pOldHdr;
  void *pNew;
  assert( mem.disallow==0 );
  assert( (nByte & 7)==0 );     /* EV: R-46199-30249 */
  pOldHdr = sqlite3MemsysGetHeader(pPrior);
  pNew = sqlite3MemMalloc(nByte);
  if( pNew ){
    memcpy(pNew, pPrior, (int)(nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize));
    if( nByte>pOldHdr->iSize ){
      randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize);
    }
    sqlite3MemFree(pPrior);
  }
  return pNew;
}

/*
16348
16349
16350
16351
16352
16353
16354
16355
16356
16357
16358
16359
16360
16361
16362
}

SQLITE_PRIVATE void sqlite3MemdebugSync(){
  struct MemBlockHdr *pHdr;
  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
    void **pBt = (void**)pHdr;
    pBt -= pHdr->nBacktraceSlots;
    mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
  }
}

/*
** Open the file indicated and write a log of all unfreed memory 
** allocations into that log.
*/







|







16376
16377
16378
16379
16380
16381
16382
16383
16384
16385
16386
16387
16388
16389
16390
}

SQLITE_PRIVATE void sqlite3MemdebugSync(){
  struct MemBlockHdr *pHdr;
  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
    void **pBt = (void**)pHdr;
    pBt -= pHdr->nBacktraceSlots;
    mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
  }
}

/*
** Open the file indicated and write a log of all unfreed memory 
** allocations into that log.
*/
17232
17233
17234
17235
17236
17237
17238
17239
17240
17241
17242
17243
17244
17245
17246
17247
17248
17249
17250
17251
17252
  ** of each block.  One byte per block.
  */
  u8 *aCtrl;

} mem5;

/*
** Access the static variable through a macro for SQLITE_OMIT_WSD
*/
#define mem5 GLOBAL(struct Mem5Global, mem5)

/*
** Assuming mem5.zPool is divided up into an array of Mem5Link
** structures, return a pointer to the idx-th such lik.
*/
#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))

/*
** Unlink the chunk at mem5.aPool[i] from list it is currently
** on.  It should be found on mem5.aiFreelist[iLogsize].
*/







|





|







17260
17261
17262
17263
17264
17265
17266
17267
17268
17269
17270
17271
17272
17273
17274
17275
17276
17277
17278
17279
17280
  ** of each block.  One byte per block.
  */
  u8 *aCtrl;

} mem5;

/*
** Access the static variable through a macro for SQLITE_OMIT_WSD.
*/
#define mem5 GLOBAL(struct Mem5Global, mem5)

/*
** Assuming mem5.zPool is divided up into an array of Mem5Link
** structures, return a pointer to the idx-th such link.
*/
#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))

/*
** Unlink the chunk at mem5.aPool[i] from list it is currently
** on.  It should be found on mem5.aiFreelist[iLogsize].
*/
17334
17335
17336
17337
17338
17339
17340
17341
17342
17343
17344
17345
17346
17347
17348
  return iFirst;
}

/*
** Return a block of memory of at least nBytes in size.
** Return NULL if unable.  Return NULL if nBytes==0.
**
** The caller guarantees that nByte positive.
**
** The caller has obtained a mutex prior to invoking this
** routine so there is never any chance that two or more
** threads can be in this routine at the same time.
*/
static void *memsys5MallocUnsafe(int nByte){
  int i;           /* Index of a mem5.aPool[] slot */







|







17362
17363
17364
17365
17366
17367
17368
17369
17370
17371
17372
17373
17374
17375
17376
  return iFirst;
}

/*
** Return a block of memory of at least nBytes in size.
** Return NULL if unable.  Return NULL if nBytes==0.
**
** The caller guarantees that nByte is positive.
**
** The caller has obtained a mutex prior to invoking this
** routine so there is never any chance that two or more
** threads can be in this routine at the same time.
*/
static void *memsys5MallocUnsafe(int nByte){
  int i;           /* Index of a mem5.aPool[] slot */
17456
17457
17458
17459
17460
17461
17462
17463
17464
17465
17466
17467
17468
17469
17470
    }
    size *= 2;
  }
  memsys5Link(iBlock, iLogsize);
}

/*
** Allocate nBytes of memory
*/
static void *memsys5Malloc(int nBytes){
  sqlite3_int64 *p = 0;
  if( nBytes>0 ){
    memsys5Enter();
    p = memsys5MallocUnsafe(nBytes);
    memsys5Leave();







|







17484
17485
17486
17487
17488
17489
17490
17491
17492
17493
17494
17495
17496
17497
17498
    }
    size *= 2;
  }
  memsys5Link(iBlock, iLogsize);
}

/*
** Allocate nBytes of memory.
*/
static void *memsys5Malloc(int nBytes){
  sqlite3_int64 *p = 0;
  if( nBytes>0 ){
    memsys5Enter();
    p = memsys5MallocUnsafe(nBytes);
    memsys5Leave();
18470
18471
18472
18473
18474
18475
18476
18477
18478
18479
18480
18481
18482
18483
18484
      OSVERSIONINFO sInfo;
      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
      GetVersionEx(&sInfo);
      osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
    }
    return osType==2;
  }
#endif /* SQLITE_OS_WINCE */
#endif

#ifdef SQLITE_DEBUG
/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use only inside assert() statements.
*/







|







18498
18499
18500
18501
18502
18503
18504
18505
18506
18507
18508
18509
18510
18511
18512
      OSVERSIONINFO sInfo;
      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
      GetVersionEx(&sInfo);
      osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
    }
    return osType==2;
  }
#endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */
#endif

#ifdef SQLITE_DEBUG
/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use only inside assert() statements.
*/
18508
18509
18510
18511
18512
18513
18514
18515
18516
18517
18518
18519
18520
18521
18522
};
static int winMutex_isInit = 0;
/* As winMutexInit() and winMutexEnd() are called as part
** of the sqlite3_initialize and sqlite3_shutdown()
** processing, the "interlocked" magic is probably not
** strictly necessary.
*/
static long winMutex_lock = 0;

SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */

static int winMutexInit(void){ 
  /* The first to increment to 1 does actual initialization */
  if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
    int i;







|







18536
18537
18538
18539
18540
18541
18542
18543
18544
18545
18546
18547
18548
18549
18550
};
static int winMutex_isInit = 0;
/* As winMutexInit() and winMutexEnd() are called as part
** of the sqlite3_initialize and sqlite3_shutdown()
** processing, the "interlocked" magic is probably not
** strictly necessary.
*/
static LONG winMutex_lock = 0;

SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */

static int winMutexInit(void){ 
  /* The first to increment to 1 does actual initialization */
  if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
    int i;
19888
19889
19890
19891
19892
19893
19894
19895
19896
19897
19898
19899
19900
19901
19902
        if( precision<etBUFSIZE-10 ){
          nOut = etBUFSIZE;
          zOut = buf;
        }else{
          nOut = precision + 10;
          zOut = zExtra = sqlite3Malloc( nOut );
          if( zOut==0 ){
            pAccum->mallocFailed = 1;
            return;
          }
        }
        bufpt = &zOut[nOut-1];
        if( xtype==etORDINAL ){
          static const char zOrd[] = "thstndrd";
          int x = (int)(longvalue % 10);







|







19916
19917
19918
19919
19920
19921
19922
19923
19924
19925
19926
19927
19928
19929
19930
        if( precision<etBUFSIZE-10 ){
          nOut = etBUFSIZE;
          zOut = buf;
        }else{
          nOut = precision + 10;
          zOut = zExtra = sqlite3Malloc( nOut );
          if( zOut==0 ){
            pAccum->accError = STRACCUM_NOMEM;
            return;
          }
        }
        bufpt = &zOut[nOut-1];
        if( xtype==etORDINAL ){
          static const char zOrd[] = "thstndrd";
          int x = (int)(longvalue % 10);
20000
20001
20002
20003
20004
20005
20006
20007
20008
20009
20010
20011
20012
20013
20014
          e2 = 0;
        }else{
          e2 = exp;
        }
        if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
          bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
          if( bufpt==0 ){
            pAccum->mallocFailed = 1;
            return;
          }
        }
        zOut = bufpt;
        nsd = 16 + flag_altform2*10;
        flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
        /* The sign in front of the number */







|







20028
20029
20030
20031
20032
20033
20034
20035
20036
20037
20038
20039
20040
20041
20042
          e2 = 0;
        }else{
          e2 = exp;
        }
        if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
          bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
          if( bufpt==0 ){
            pAccum->accError = STRACCUM_NOMEM;
            return;
          }
        }
        zOut = bufpt;
        nsd = 16 + flag_altform2*10;
        flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
        /* The sign in front of the number */
20135
20136
20137
20138
20139
20140
20141
20142
20143
20144
20145
20146
20147
20148
20149
          if( ch==q )  n++;
        }
        needQuote = !isnull && xtype==etSQLESCAPE2;
        n += i + 1 + needQuote*2;
        if( n>etBUFSIZE ){
          bufpt = zExtra = sqlite3Malloc( n );
          if( bufpt==0 ){
            pAccum->mallocFailed = 1;
            return;
          }
        }else{
          bufpt = buf;
        }
        j = 0;
        if( needQuote ) bufpt[j++] = q;







|







20163
20164
20165
20166
20167
20168
20169
20170
20171
20172
20173
20174
20175
20176
20177
          if( ch==q )  n++;
        }
        needQuote = !isnull && xtype==etSQLESCAPE2;
        n += i + 1 + needQuote*2;
        if( n>etBUFSIZE ){
          bufpt = zExtra = sqlite3Malloc( n );
          if( bufpt==0 ){
            pAccum->accError = STRACCUM_NOMEM;
            return;
          }
        }else{
          bufpt = buf;
        }
        j = 0;
        if( needQuote ) bufpt[j++] = q;
20213
20214
20215
20216
20217
20218
20219
20220
20221
20222
20223
20224
20225
20226

20227
20228
20229
20230
20231
20232
20233
20234
20235
20236
20237
20238
20239
20240
20241
20242
20243
20244
20245
20246
20247
20248
20249
20250
20251
20252
20253
20254
20255
20256
20257
20258
20259
20260
20261
20262
20263
20264
20265
20266
20267
} /* End of function */

/*
** Append N bytes of text from z to the StrAccum object.
*/
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
  assert( z!=0 || N==0 );
  if( p->tooBig | p->mallocFailed ){
    testcase(p->tooBig);
    testcase(p->mallocFailed);
    return;
  }
  assert( p->zText!=0 || p->nChar==0 );
  if( N<0 ){

    N = sqlite3Strlen30(z);
  }
  if( N==0 || NEVER(z==0) ){
    return;
  }
  if( p->nChar+N >= p->nAlloc ){
    char *zNew;
    if( !p->useMalloc ){
      p->tooBig = 1;
      N = p->nAlloc - p->nChar - 1;
      if( N<=0 ){
        return;
      }
    }else{
      char *zOld = (p->zText==p->zBase ? 0 : p->zText);
      i64 szNew = p->nChar;
      szNew += N + 1;
      if( szNew > p->mxAlloc ){
        sqlite3StrAccumReset(p);
        p->tooBig = 1;
        return;
      }else{
        p->nAlloc = (int)szNew;
      }
      if( p->useMalloc==1 ){
        zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
      }else{
        zNew = sqlite3_realloc(zOld, p->nAlloc);
      }
      if( zNew ){
        if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
        p->zText = zNew;
      }else{
        p->mallocFailed = 1;
        sqlite3StrAccumReset(p);
        return;
      }
    }
  }
  assert( p->zText );
  memcpy(&p->zText[p->nChar], z, N);







|
|
|



|
>


<
<
<



|










|













|







20241
20242
20243
20244
20245
20246
20247
20248
20249
20250
20251
20252
20253
20254
20255
20256
20257



20258
20259
20260
20261
20262
20263
20264
20265
20266
20267
20268
20269
20270
20271
20272
20273
20274
20275
20276
20277
20278
20279
20280
20281
20282
20283
20284
20285
20286
20287
20288
20289
20290
20291
20292
20293
} /* End of function */

/*
** Append N bytes of text from z to the StrAccum object.
*/
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
  assert( z!=0 || N==0 );
  if( p->accError ){
    testcase(p->accError==STRACCUM_TOOBIG);
    testcase(p->accError==STRACCUM_NOMEM);
    return;
  }
  assert( p->zText!=0 || p->nChar==0 );
  if( N<=0 ){
    if( N==0 || z[0]==0 ) return;
    N = sqlite3Strlen30(z);
  }



  if( p->nChar+N >= p->nAlloc ){
    char *zNew;
    if( !p->useMalloc ){
      p->accError = STRACCUM_TOOBIG;
      N = p->nAlloc - p->nChar - 1;
      if( N<=0 ){
        return;
      }
    }else{
      char *zOld = (p->zText==p->zBase ? 0 : p->zText);
      i64 szNew = p->nChar;
      szNew += N + 1;
      if( szNew > p->mxAlloc ){
        sqlite3StrAccumReset(p);
        p->accError = STRACCUM_TOOBIG;
        return;
      }else{
        p->nAlloc = (int)szNew;
      }
      if( p->useMalloc==1 ){
        zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
      }else{
        zNew = sqlite3_realloc(zOld, p->nAlloc);
      }
      if( zNew ){
        if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
        p->zText = zNew;
      }else{
        p->accError = STRACCUM_NOMEM;
        sqlite3StrAccumReset(p);
        return;
      }
    }
  }
  assert( p->zText );
  memcpy(&p->zText[p->nChar], z, N);
20281
20282
20283
20284
20285
20286
20287
20288
20289
20290
20291
20292
20293
20294
20295
        p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
      }else{
        p->zText = sqlite3_malloc(p->nChar+1);
      }
      if( p->zText ){
        memcpy(p->zText, p->zBase, p->nChar+1);
      }else{
        p->mallocFailed = 1;
      }
    }
  }
  return p->zText;
}

/*







|







20307
20308
20309
20310
20311
20312
20313
20314
20315
20316
20317
20318
20319
20320
20321
        p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
      }else{
        p->zText = sqlite3_malloc(p->nChar+1);
      }
      if( p->zText ){
        memcpy(p->zText, p->zBase, p->nChar+1);
      }else{
        p->accError = STRACCUM_NOMEM;
      }
    }
  }
  return p->zText;
}

/*
20312
20313
20314
20315
20316
20317
20318
20319
20320
20321
20322
20323
20324
20325
20326
20327
20328
20329
20330
20331
20332
20333
20334
20335
20336
20337
20338
20339
20340
20341
20342
20343
20344
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
  p->zText = p->zBase = zBase;
  p->db = 0;
  p->nChar = 0;
  p->nAlloc = n;
  p->mxAlloc = mx;
  p->useMalloc = 1;
  p->tooBig = 0;
  p->mallocFailed = 0;
}

/*
** Print into memory obtained from sqliteMalloc().  Use the internal
** %-conversion extensions.
*/
SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
  char *z;
  char zBase[SQLITE_PRINT_BUF_SIZE];
  StrAccum acc;
  assert( db!=0 );
  sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
                      db->aLimit[SQLITE_LIMIT_LENGTH]);
  acc.db = db;
  sqlite3VXPrintf(&acc, 1, zFormat, ap);
  z = sqlite3StrAccumFinish(&acc);
  if( acc.mallocFailed ){
    db->mallocFailed = 1;
  }
  return z;
}

/*
** Print into memory obtained from sqliteMalloc().  Use the internal







|
<
















|







20338
20339
20340
20341
20342
20343
20344
20345

20346
20347
20348
20349
20350
20351
20352
20353
20354
20355
20356
20357
20358
20359
20360
20361
20362
20363
20364
20365
20366
20367
20368
20369
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
  p->zText = p->zBase = zBase;
  p->db = 0;
  p->nChar = 0;
  p->nAlloc = n;
  p->mxAlloc = mx;
  p->useMalloc = 1;
  p->accError = 0;

}

/*
** Print into memory obtained from sqliteMalloc().  Use the internal
** %-conversion extensions.
*/
SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
  char *z;
  char zBase[SQLITE_PRINT_BUF_SIZE];
  StrAccum acc;
  assert( db!=0 );
  sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
                      db->aLimit[SQLITE_LIMIT_LENGTH]);
  acc.db = db;
  sqlite3VXPrintf(&acc, 1, zFormat, ap);
  z = sqlite3StrAccumFinish(&acc);
  if( acc.accError==STRACCUM_NOMEM ){
    db->mallocFailed = 1;
  }
  return z;
}

/*
** Print into memory obtained from sqliteMalloc().  Use the internal
20527
20528
20529
20530
20531
20532
20533
20534
20535
20536
20537
20538
20539
20540
20541
20542
20543
20544
20545
20546
20547
20548
20549
20550
20551
20552
20553
20554
20555
20556
20557
20558
20559
20560
20561
20562
20563
20564
20565




20566
20567
20568
20569
20570
20571
20572
static SQLITE_WSD struct sqlite3PrngType {
  unsigned char isInit;          /* True if initialized */
  unsigned char i, j;            /* State variables */
  unsigned char s[256];          /* State variables */
} sqlite3Prng;

/*
** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
** must be held while executing this routine.
**
** Why not just use a library random generator like lrand48() for this?
** Because the OP_NewRowid opcode in the VDBE depends on having a very
** good source of random numbers.  The lrand48() library function may
** well be good enough.  But maybe not.  Or maybe lrand48() has some
** subtle problems on some systems that could cause problems.  It is hard
** to know.  To minimize the risk of problems due to bad lrand48()
** implementations, SQLite uses this random number generator based
** on RC4, which we know works very well.
**
** (Later):  Actually, OP_NewRowid does not depend on a good source of
** randomness any more.  But we will leave this code in all the same.
*/
static u8 randomByte(void){
  unsigned char t;


  /* The "wsdPrng" macro will resolve to the pseudo-random number generator
  ** state vector.  If writable static data is unsupported on the target,
  ** we have to locate the state vector at run-time.  In the more common
  ** case where writable static data is supported, wsdPrng can refer directly
  ** to the "sqlite3Prng" state vector declared above.
  */
#ifdef SQLITE_OMIT_WSD
  struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
# define wsdPrng p[0]
#else
# define wsdPrng sqlite3Prng
#endif






  /* Initialize the state of the random number generator once,
  ** the first time this routine is called.  The seed value does
  ** not need to contain a lot of randomness since we are not
  ** trying to do secure encryption or anything like that...
  **
  ** Nothing in this file or anywhere else in SQLite does any kind of







<
<
|
<
<
<
<
<
<
<
<
<
<
<

|

|














>
>
>
>







20552
20553
20554
20555
20556
20557
20558


20559











20560
20561
20562
20563
20564
20565
20566
20567
20568
20569
20570
20571
20572
20573
20574
20575
20576
20577
20578
20579
20580
20581
20582
20583
20584
20585
20586
20587
20588
static SQLITE_WSD struct sqlite3PrngType {
  unsigned char isInit;          /* True if initialized */
  unsigned char i, j;            /* State variables */
  unsigned char s[256];          /* State variables */
} sqlite3Prng;

/*


** Return N random bytes.











*/
SQLITE_API void sqlite3_randomness(int N, void *pBuf){
  unsigned char t;
  unsigned char *zBuf = pBuf;

  /* The "wsdPrng" macro will resolve to the pseudo-random number generator
  ** state vector.  If writable static data is unsupported on the target,
  ** we have to locate the state vector at run-time.  In the more common
  ** case where writable static data is supported, wsdPrng can refer directly
  ** to the "sqlite3Prng" state vector declared above.
  */
#ifdef SQLITE_OMIT_WSD
  struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
# define wsdPrng p[0]
#else
# define wsdPrng sqlite3Prng
#endif

#if SQLITE_THREADSAFE
  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
  sqlite3_mutex_enter(mutex);
#endif

  /* Initialize the state of the random number generator once,
  ** the first time this routine is called.  The seed value does
  ** not need to contain a lot of randomness since we are not
  ** trying to do secure encryption or anything like that...
  **
  ** Nothing in this file or anywhere else in SQLite does any kind of
20587
20588
20589
20590
20591
20592
20593
20594
20595
20596
20597
20598
20599
20600
20601
20602
20603
20604
20605
20606
20607
20608
20609
20610
20611
20612
20613
20614
20615
20616
20617
20618
20619
20620
20621
20622
      t = wsdPrng.s[wsdPrng.j];
      wsdPrng.s[wsdPrng.j] = wsdPrng.s[i];
      wsdPrng.s[i] = t;
    }
    wsdPrng.isInit = 1;
  }

  /* Generate and return single random byte
  */
  wsdPrng.i++;
  t = wsdPrng.s[wsdPrng.i];
  wsdPrng.j += t;
  wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
  wsdPrng.s[wsdPrng.j] = t;
  t += wsdPrng.s[wsdPrng.i];
  return wsdPrng.s[t];
}

/*
** Return N random bytes.
*/
SQLITE_API void sqlite3_randomness(int N, void *pBuf){
  unsigned char *zBuf = pBuf;
#if SQLITE_THREADSAFE
  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
#endif
  sqlite3_mutex_enter(mutex);
  while( N-- ){
    *(zBuf++) = randomByte();
  }
  sqlite3_mutex_leave(mutex);
}

#ifndef SQLITE_OMIT_BUILTIN_TEST
/*
** For testing purposes, we sometimes want to preserve the state of







|
<
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<







20603
20604
20605
20606
20607
20608
20609
20610

20611
20612
20613
20614
20615
20616
20617













20618
20619
20620
20621
20622
20623
20624
      t = wsdPrng.s[wsdPrng.j];
      wsdPrng.s[wsdPrng.j] = wsdPrng.s[i];
      wsdPrng.s[i] = t;
    }
    wsdPrng.isInit = 1;
  }

  while( N-- ){

    wsdPrng.i++;
    t = wsdPrng.s[wsdPrng.i];
    wsdPrng.j += t;
    wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
    wsdPrng.s[wsdPrng.j] = t;
    t += wsdPrng.s[wsdPrng.i];
    *(zBuf++) = wsdPrng.s[t];













  }
  sqlite3_mutex_leave(mutex);
}

#ifndef SQLITE_OMIT_BUILTIN_TEST
/*
** For testing purposes, we sometimes want to preserve the state of
21095
21096
21097
21098
21099
21100
21101
21102
21103
21104
21105
21106
21107
21108
21109
21110
21111
21112
21113
21114
21115
21116
21117
21118
21119
21120
21121
21122
21123
21124
21125
21126
21127
21128
21129
21130
21131
21132
21133
21134
  assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
  assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
  assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed );
  assert( m.z || db->mallocFailed );
  return m.z;
}

/*
** Convert a UTF-8 string to the UTF-16 encoding specified by parameter
** enc. A pointer to the new string is returned, and the value of *pnOut
** is set to the length of the returned string in bytes. The call should
** arrange to call sqlite3DbFree() on the returned pointer when it is
** no longer required.
** 
** If a malloc failure occurs, NULL is returned and the db.mallocFailed
** flag set.
*/
#ifdef SQLITE_ENABLE_STAT3
SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
  Mem m;
  memset(&m, 0, sizeof(m));
  m.db = db;
  sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
  if( sqlite3VdbeMemTranslate(&m, enc) ){
    assert( db->mallocFailed );
    return 0;
  }
  assert( m.z==m.zMalloc );
  *pnOut = m.n;
  return m.z;
}
#endif

/*
** zIn is a UTF-16 encoded unicode string at least nChar characters long.
** Return the number of bytes in the first nChar unicode characters
** in pZ.  nChar must be non-negative.
*/
SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){
  int c;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







21097
21098
21099
21100
21101
21102
21103


























21104
21105
21106
21107
21108
21109
21110
  assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
  assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
  assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed );
  assert( m.z || db->mallocFailed );
  return m.z;
}



























/*
** zIn is a UTF-16 encoded unicode string at least nChar characters long.
** Return the number of bytes in the first nChar unicode characters
** in pZ.  nChar must be non-negative.
*/
SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){
  int c;
22701
22702
22703
22704
22705
22706
22707
22708
22709
22710
22711
22712
22713
22714
22715
22716
22717
22718
22719
22720
22721
22722
22723
22724
22725
22726
22727
22728
22729
22730
22731
22732
22733
22734
22735
22736
22737
22738
22739
22740
22741
22742
22743
22744
22745
22746
22747
22748
22749
22750
22751
22752
22753
22754
22755
22756
22757
22758
22759
22760
22761
22762
22763
22764
22765
22766
22767
22768
22769
22770
22771
22772
22773
22774
22775
22776
22777
22778
22779
22780
22781
22782
22783
22784
22785
22786
22787
22788
22789
22790
22791
22792
22793
22794
22795
22796
22797
22798
22799
22800
22801
22802
22803
22804
22805
22806
22807
22808
22809
22810
22811
22812
22813
22814
22815
22816
22817
22818
22819
22820
22821
22822
22823
22824
22825
22826
22827
22828
22829
22830
22831
22832
22833
22834
22835
22836
22837
22838
22839
22840
22841
22842
22843
22844
22845
22846
22847
22848
22849
22850
22851
22852
22853
22854
/************** End of hash.c ************************************************/
/************** Begin file opcodes.c *****************************************/
/* Automatically generated.  Do not edit */
/* See the mkopcodec.awk script for details. */
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
 static const char *const azName[] = { "?",
     /*   1 */ "Goto",
     /*   2 */ "Gosub",
     /*   3 */ "Return",
     /*   4 */ "Yield",
     /*   5 */ "HaltIfNull",
     /*   6 */ "Halt",
     /*   7 */ "Integer",
     /*   8 */ "Int64",
     /*   9 */ "String",
     /*  10 */ "Null",
     /*  11 */ "Blob",
     /*  12 */ "Variable",
     /*  13 */ "Move",
     /*  14 */ "Copy",
     /*  15 */ "SCopy",
     /*  16 */ "ResultRow",
     /*  17 */ "CollSeq",
     /*  18 */ "Function",
     /*  19 */ "Not",
     /*  20 */ "AddImm",
     /*  21 */ "MustBeInt",
     /*  22 */ "RealAffinity",
     /*  23 */ "Permutation",
     /*  24 */ "Compare",
     /*  25 */ "Jump",
     /*  26 */ "Once",
     /*  27 */ "If",
     /*  28 */ "IfNot",
     /*  29 */ "Column",
     /*  30 */ "Affinity",
     /*  31 */ "MakeRecord",
     /*  32 */ "Count",
     /*  33 */ "Savepoint",
     /*  34 */ "AutoCommit",
     /*  35 */ "Transaction",
     /*  36 */ "ReadCookie",
     /*  37 */ "SetCookie",
     /*  38 */ "VerifyCookie",
     /*  39 */ "OpenRead",
     /*  40 */ "OpenWrite",
     /*  41 */ "OpenAutoindex",
     /*  42 */ "OpenEphemeral",
     /*  43 */ "SorterOpen",
     /*  44 */ "OpenPseudo",
     /*  45 */ "Close",
     /*  46 */ "SeekLt",
     /*  47 */ "SeekLe",
     /*  48 */ "SeekGe",
     /*  49 */ "SeekGt",
     /*  50 */ "Seek",
     /*  51 */ "NotFound",
     /*  52 */ "Found",
     /*  53 */ "IsUnique",
     /*  54 */ "NotExists",
     /*  55 */ "Sequence",
     /*  56 */ "NewRowid",
     /*  57 */ "Insert",
     /*  58 */ "InsertInt",
     /*  59 */ "Delete",
     /*  60 */ "ResetCount",
     /*  61 */ "SorterCompare",
     /*  62 */ "SorterData",
     /*  63 */ "RowKey",
     /*  64 */ "RowData",
     /*  65 */ "Rowid",
     /*  66 */ "NullRow",
     /*  67 */ "Last",
     /*  68 */ "Or",
     /*  69 */ "And",
     /*  70 */ "SorterSort",
     /*  71 */ "Sort",
     /*  72 */ "Rewind",
     /*  73 */ "IsNull",
     /*  74 */ "NotNull",
     /*  75 */ "Ne",
     /*  76 */ "Eq",
     /*  77 */ "Gt",
     /*  78 */ "Le",
     /*  79 */ "Lt",
     /*  80 */ "Ge",
     /*  81 */ "SorterNext",
     /*  82 */ "BitAnd",
     /*  83 */ "BitOr",
     /*  84 */ "ShiftLeft",
     /*  85 */ "ShiftRight",
     /*  86 */ "Add",
     /*  87 */ "Subtract",
     /*  88 */ "Multiply",
     /*  89 */ "Divide",
     /*  90 */ "Remainder",
     /*  91 */ "Concat",
     /*  92 */ "Prev",
     /*  93 */ "BitNot",
     /*  94 */ "String8",
     /*  95 */ "Next",
     /*  96 */ "SorterInsert",
     /*  97 */ "IdxInsert",
     /*  98 */ "IdxDelete",
     /*  99 */ "IdxRowid",
     /* 100 */ "IdxLT",
     /* 101 */ "IdxGE",
     /* 102 */ "Destroy",
     /* 103 */ "Clear",
     /* 104 */ "CreateIndex",
     /* 105 */ "CreateTable",
     /* 106 */ "ParseSchema",
     /* 107 */ "LoadAnalysis",
     /* 108 */ "DropTable",
     /* 109 */ "DropIndex",
     /* 110 */ "DropTrigger",
     /* 111 */ "IntegrityCk",
     /* 112 */ "RowSetAdd",
     /* 113 */ "RowSetRead",
     /* 114 */ "RowSetTest",
     /* 115 */ "Program",
     /* 116 */ "Param",
     /* 117 */ "FkCounter",
     /* 118 */ "FkIfZero",
     /* 119 */ "MemMax",
     /* 120 */ "IfPos",
     /* 121 */ "IfNeg",
     /* 122 */ "IfZero",
     /* 123 */ "AggStep",
     /* 124 */ "AggFinal",
     /* 125 */ "Checkpoint",
     /* 126 */ "JournalMode",
     /* 127 */ "Vacuum",
     /* 128 */ "IncrVacuum",
     /* 129 */ "Expire",
     /* 130 */ "Real",
     /* 131 */ "TableLock",
     /* 132 */ "VBegin",
     /* 133 */ "VCreate",
     /* 134 */ "VDestroy",
     /* 135 */ "VOpen",
     /* 136 */ "VFilter",
     /* 137 */ "VColumn",
     /* 138 */ "VNext",
     /* 139 */ "VRename",
     /* 140 */ "VUpdate",
     /* 141 */ "ToText",
     /* 142 */ "ToBlob",
     /* 143 */ "ToNumeric",
     /* 144 */ "ToInt",
     /* 145 */ "ToReal",
     /* 146 */ "Pagecount",
     /* 147 */ "MaxPgcnt",







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|
|
|








|










|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|







22677
22678
22679
22680
22681
22682
22683
22684
22685
22686
22687
22688
22689
22690
22691
22692
22693
22694
22695
22696
22697
22698
22699
22700
22701
22702
22703
22704
22705
22706
22707
22708
22709
22710
22711
22712
22713
22714
22715
22716
22717
22718
22719
22720
22721
22722
22723
22724
22725
22726
22727
22728
22729
22730
22731
22732
22733
22734
22735
22736
22737
22738
22739
22740
22741
22742
22743
22744
22745
22746
22747
22748
22749
22750
22751
22752
22753
22754
22755
22756
22757
22758
22759
22760
22761
22762
22763
22764
22765
22766
22767
22768
22769
22770
22771
22772
22773
22774
22775
22776
22777
22778
22779
22780
22781
22782
22783
22784
22785
22786
22787
22788
22789
22790
22791
22792
22793
22794
22795
22796
22797
22798
22799
22800
22801
22802
22803
22804
22805
22806
22807
22808
22809
22810
22811
22812
22813
22814
22815
22816
22817
22818
22819
22820
22821
22822
22823
22824
22825
22826
22827
22828
22829
22830
/************** End of hash.c ************************************************/
/************** Begin file opcodes.c *****************************************/
/* Automatically generated.  Do not edit */
/* See the mkopcodec.awk script for details. */
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
 static const char *const azName[] = { "?",
     /*   1 */ "Function",
     /*   2 */ "Savepoint",
     /*   3 */ "AutoCommit",
     /*   4 */ "Transaction",
     /*   5 */ "SorterNext",
     /*   6 */ "Prev",
     /*   7 */ "Next",
     /*   8 */ "AggStep",
     /*   9 */ "Checkpoint",
     /*  10 */ "JournalMode",
     /*  11 */ "Vacuum",
     /*  12 */ "VFilter",
     /*  13 */ "VUpdate",
     /*  14 */ "Goto",
     /*  15 */ "Gosub",
     /*  16 */ "Return",
     /*  17 */ "Yield",
     /*  18 */ "HaltIfNull",
     /*  19 */ "Not",
     /*  20 */ "Halt",
     /*  21 */ "Integer",
     /*  22 */ "Int64",
     /*  23 */ "String",
     /*  24 */ "Null",
     /*  25 */ "Blob",
     /*  26 */ "Variable",
     /*  27 */ "Move",
     /*  28 */ "Copy",
     /*  29 */ "SCopy",
     /*  30 */ "ResultRow",
     /*  31 */ "CollSeq",
     /*  32 */ "AddImm",
     /*  33 */ "MustBeInt",
     /*  34 */ "RealAffinity",
     /*  35 */ "Permutation",
     /*  36 */ "Compare",
     /*  37 */ "Jump",
     /*  38 */ "Once",
     /*  39 */ "If",
     /*  40 */ "IfNot",
     /*  41 */ "Column",
     /*  42 */ "Affinity",
     /*  43 */ "MakeRecord",
     /*  44 */ "Count",
     /*  45 */ "ReadCookie",
     /*  46 */ "SetCookie",
     /*  47 */ "VerifyCookie",
     /*  48 */ "OpenRead",
     /*  49 */ "OpenWrite",
     /*  50 */ "OpenAutoindex",
     /*  51 */ "OpenEphemeral",
     /*  52 */ "SorterOpen",
     /*  53 */ "OpenPseudo",
     /*  54 */ "Close",
     /*  55 */ "SeekLt",
     /*  56 */ "SeekLe",
     /*  57 */ "SeekGe",
     /*  58 */ "SeekGt",
     /*  59 */ "Seek",
     /*  60 */ "NotFound",
     /*  61 */ "Found",
     /*  62 */ "IsUnique",
     /*  63 */ "NotExists",
     /*  64 */ "Sequence",
     /*  65 */ "NewRowid",
     /*  66 */ "Insert",
     /*  67 */ "InsertInt",
     /*  68 */ "Or",
     /*  69 */ "And",
     /*  70 */ "Delete",
     /*  71 */ "ResetCount",
     /*  72 */ "SorterCompare",
     /*  73 */ "IsNull",
     /*  74 */ "NotNull",
     /*  75 */ "Ne",
     /*  76 */ "Eq",
     /*  77 */ "Gt",
     /*  78 */ "Le",
     /*  79 */ "Lt",
     /*  80 */ "Ge",
     /*  81 */ "SorterData",
     /*  82 */ "BitAnd",
     /*  83 */ "BitOr",
     /*  84 */ "ShiftLeft",
     /*  85 */ "ShiftRight",
     /*  86 */ "Add",
     /*  87 */ "Subtract",
     /*  88 */ "Multiply",
     /*  89 */ "Divide",
     /*  90 */ "Remainder",
     /*  91 */ "Concat",
     /*  92 */ "RowKey",
     /*  93 */ "BitNot",
     /*  94 */ "String8",
     /*  95 */ "RowData",
     /*  96 */ "Rowid",
     /*  97 */ "NullRow",
     /*  98 */ "Last",
     /*  99 */ "SorterSort",
     /* 100 */ "Sort",
     /* 101 */ "Rewind",
     /* 102 */ "SorterInsert",
     /* 103 */ "IdxInsert",
     /* 104 */ "IdxDelete",
     /* 105 */ "IdxRowid",
     /* 106 */ "IdxLT",
     /* 107 */ "IdxGE",
     /* 108 */ "Destroy",
     /* 109 */ "Clear",
     /* 110 */ "CreateIndex",
     /* 111 */ "CreateTable",
     /* 112 */ "ParseSchema",
     /* 113 */ "LoadAnalysis",
     /* 114 */ "DropTable",
     /* 115 */ "DropIndex",
     /* 116 */ "DropTrigger",
     /* 117 */ "IntegrityCk",
     /* 118 */ "RowSetAdd",
     /* 119 */ "RowSetRead",
     /* 120 */ "RowSetTest",
     /* 121 */ "Program",
     /* 122 */ "Param",
     /* 123 */ "FkCounter",
     /* 124 */ "FkIfZero",
     /* 125 */ "MemMax",
     /* 126 */ "IfPos",
     /* 127 */ "IfNeg",
     /* 128 */ "IfZero",
     /* 129 */ "AggFinal",
     /* 130 */ "Real",
     /* 131 */ "IncrVacuum",
     /* 132 */ "Expire",
     /* 133 */ "TableLock",
     /* 134 */ "VBegin",
     /* 135 */ "VCreate",
     /* 136 */ "VDestroy",
     /* 137 */ "VOpen",
     /* 138 */ "VColumn",
     /* 139 */ "VNext",
     /* 140 */ "VRename",
     /* 141 */ "ToText",
     /* 142 */ "ToBlob",
     /* 143 */ "ToNumeric",
     /* 144 */ "ToInt",
     /* 145 */ "ToReal",
     /* 146 */ "Pagecount",
     /* 147 */ "MaxPgcnt",
23077
23078
23079
23080
23081
23082
23083

23084
23085
23086
23087
23088

23089
23090
23091
23092
23093
23094
23095
  unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
  int lastErrno;                      /* The unix errno from last I/O error */
  void *lockingContext;               /* Locking style specific state */
  UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
  const char *zPath;                  /* Name of the file */
  unixShm *pShm;                      /* Shared memory segment information */
  int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */

  int nFetchOut;                      /* Number of outstanding xFetch refs */
  sqlite3_int64 mmapSize;             /* Usable size of mapping at pMapRegion */
  sqlite3_int64 mmapSizeActual;       /* Actual size of mapping at pMapRegion */
  sqlite3_int64 mmapSizeMax;          /* Configured FCNTL_MMAP_SIZE value */
  void *pMapRegion;                   /* Memory mapped region */

#ifdef __QNXNTO__
  int sectorSize;                     /* Device sector size */
  int deviceCharacteristics;          /* Precomputed device characteristics */
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
  int openFlags;                      /* The flags specified at open() */
#endif







>





>







23053
23054
23055
23056
23057
23058
23059
23060
23061
23062
23063
23064
23065
23066
23067
23068
23069
23070
23071
23072
23073
  unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
  int lastErrno;                      /* The unix errno from last I/O error */
  void *lockingContext;               /* Locking style specific state */
  UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
  const char *zPath;                  /* Name of the file */
  unixShm *pShm;                      /* Shared memory segment information */
  int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
#if SQLITE_MAX_MMAP_SIZE>0
  int nFetchOut;                      /* Number of outstanding xFetch refs */
  sqlite3_int64 mmapSize;             /* Usable size of mapping at pMapRegion */
  sqlite3_int64 mmapSizeActual;       /* Actual size of mapping at pMapRegion */
  sqlite3_int64 mmapSizeMax;          /* Configured FCNTL_MMAP_SIZE value */
  void *pMapRegion;                   /* Memory mapped region */
#endif
#ifdef __QNXNTO__
  int sectorSize;                     /* Device sector size */
  int deviceCharacteristics;          /* Precomputed device characteristics */
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
  int openFlags;                      /* The flags specified at open() */
#endif
23516
23517
23518
23519
23520
23521
23522

23523
23524
23525
23526
23527
23528
23529
23530
23531
23532
23533
23534

23535
23536
23537
23538
23539
23540
23541

  { "rmdir",        (sqlite3_syscall_ptr)rmdir,           0 },
#define osRmdir     ((int(*)(const char*))aSyscall[19].pCurrent)

  { "fchown",       (sqlite3_syscall_ptr)posixFchown,     0 },
#define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)


  { "mmap",       (sqlite3_syscall_ptr)mmap,     0 },
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)

  { "munmap",       (sqlite3_syscall_ptr)munmap,          0 },
#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)

#if HAVE_MREMAP
  { "mremap",       (sqlite3_syscall_ptr)mremap,          0 },
#else
  { "mremap",       (sqlite3_syscall_ptr)0,               0 },
#endif
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)


}; /* End of the overrideable system calls */

/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable







>












>







23494
23495
23496
23497
23498
23499
23500
23501
23502
23503
23504
23505
23506
23507
23508
23509
23510
23511
23512
23513
23514
23515
23516
23517
23518
23519
23520
23521

  { "rmdir",        (sqlite3_syscall_ptr)rmdir,           0 },
#define osRmdir     ((int(*)(const char*))aSyscall[19].pCurrent)

  { "fchown",       (sqlite3_syscall_ptr)posixFchown,     0 },
#define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)

#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
  { "mmap",       (sqlite3_syscall_ptr)mmap,     0 },
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)

  { "munmap",       (sqlite3_syscall_ptr)munmap,          0 },
#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)

#if HAVE_MREMAP
  { "mremap",       (sqlite3_syscall_ptr)mremap,          0 },
#else
  { "mremap",       (sqlite3_syscall_ptr)0,               0 },
#endif
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
#endif

}; /* End of the overrideable system calls */

/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "unix" VFSes.  Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
23614
23615
23616
23617
23618
23619
23620









23621
23622
23623
23624
23625
23626
23627
23628
23629
23630
23631
23632
23633
23634
23635
23636
23637
23638
23639
23640
23641

23642
23643
23644
23645
23646

23647









23648
23649
23650
23651
23652
23653
23654
  }
  for(i++; i<ArraySize(aSyscall); i++){
    if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
  }
  return 0;
}










/*
** Invoke open().  Do so multiple times, until it either succeeds or
** fails for some reason other than EINTR.
**
** If the file creation mode "m" is 0 then set it to the default for
** SQLite.  The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
** 0644) as modified by the system umask.  If m is not 0, then
** make the file creation mode be exactly m ignoring the umask.
**
** The m parameter will be non-zero only when creating -wal, -journal,
** and -shm files.  We want those files to have *exactly* the same
** permissions as their original database, unadulterated by the umask.
** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
** transaction crashes and leaves behind hot journals, then any
** process that is able to write to the database will also be able to
** recover the hot journals.
*/
static int robust_open(const char *z, int f, mode_t m){
  int fd;
  mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
  do{

#if defined(O_CLOEXEC)
    fd = osOpen(z,f|O_CLOEXEC,m2);
#else
    fd = osOpen(z,f,m2);
#endif

  }while( fd<0 && errno==EINTR );









  if( fd>=0 ){
    if( m!=0 ){
      struct stat statbuf;
      if( osFstat(fd, &statbuf)==0 
       && statbuf.st_size==0
       && (statbuf.st_mode&0777)!=m 
      ){







>
>
>
>
>
>
>
>
>




















<
>





>
|
>
>
>
>
>
>
>
>
>







23594
23595
23596
23597
23598
23599
23600
23601
23602
23603
23604
23605
23606
23607
23608
23609
23610
23611
23612
23613
23614
23615
23616
23617
23618
23619
23620
23621
23622
23623
23624
23625
23626
23627
23628
23629

23630
23631
23632
23633
23634
23635
23636
23637
23638
23639
23640
23641
23642
23643
23644
23645
23646
23647
23648
23649
23650
23651
23652
23653
  }
  for(i++; i<ArraySize(aSyscall); i++){
    if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
  }
  return 0;
}

/*
** Do not accept any file descriptor less than this value, in order to avoid
** opening database file using file descriptors that are commonly used for 
** standard input, output, and error.
*/
#ifndef SQLITE_MINIMUM_FILE_DESCRIPTOR
# define SQLITE_MINIMUM_FILE_DESCRIPTOR 3
#endif

/*
** Invoke open().  Do so multiple times, until it either succeeds or
** fails for some reason other than EINTR.
**
** If the file creation mode "m" is 0 then set it to the default for
** SQLite.  The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
** 0644) as modified by the system umask.  If m is not 0, then
** make the file creation mode be exactly m ignoring the umask.
**
** The m parameter will be non-zero only when creating -wal, -journal,
** and -shm files.  We want those files to have *exactly* the same
** permissions as their original database, unadulterated by the umask.
** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
** transaction crashes and leaves behind hot journals, then any
** process that is able to write to the database will also be able to
** recover the hot journals.
*/
static int robust_open(const char *z, int f, mode_t m){
  int fd;
  mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;

  while(1){
#if defined(O_CLOEXEC)
    fd = osOpen(z,f|O_CLOEXEC,m2);
#else
    fd = osOpen(z,f,m2);
#endif
    if( fd<0 ){
      if( errno==EINTR ) continue;
      break;
    }
    if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break;
    osClose(fd);
    sqlite3_log(SQLITE_WARNING, 
                "attempt to open \"%s\" as file descriptor %d", z, fd);
    fd = -1;
    if( osOpen("/dev/null", f, m)<0 ) break;
  }
  if( fd>=0 ){
    if( m!=0 ){
      struct stat statbuf;
      if( osFstat(fd, &statbuf)==0 
       && statbuf.st_size==0
       && (statbuf.st_mode&0777)!=m 
      ){
24938
24939
24940
24941
24942
24943
24944

24945
24946

24947
24948
24949
24950
24951
24952
24953
24954
24955
24956
24957
24958
24959

24960

24961
24962
24963
24964
24965
24966
24967
** the requested locking level, this routine is a no-op.
*/
static int unixUnlock(sqlite3_file *id, int eFileLock){
  assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 );
  return posixUnlock(id, eFileLock, 0);
}


static int unixMapfile(unixFile *pFd, i64 nByte);
static void unixUnmapfile(unixFile *pFd);


/*
** This function performs the parts of the "close file" operation 
** common to all locking schemes. It closes the directory and file
** handles, if they are valid, and sets all fields of the unixFile
** structure to 0.
**
** It is *not* necessary to hold the mutex when this routine is called,
** even on VxWorks.  A mutex will be acquired on VxWorks by the
** vxworksReleaseFileId() routine.
*/
static int closeUnixFile(sqlite3_file *id){
  unixFile *pFile = (unixFile*)id;

  unixUnmapfile(pFile);

  if( pFile->h>=0 ){
    robust_close(pFile, pFile->h, __LINE__);
    pFile->h = -1;
  }
#if OS_VXWORKS
  if( pFile->pId ){
    if( pFile->ctrlFlags & UNIXFILE_DELETE ){







>


>













>

>







24937
24938
24939
24940
24941
24942
24943
24944
24945
24946
24947
24948
24949
24950
24951
24952
24953
24954
24955
24956
24957
24958
24959
24960
24961
24962
24963
24964
24965
24966
24967
24968
24969
24970
** the requested locking level, this routine is a no-op.
*/
static int unixUnlock(sqlite3_file *id, int eFileLock){
  assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 );
  return posixUnlock(id, eFileLock, 0);
}

#if SQLITE_MAX_MMAP_SIZE>0
static int unixMapfile(unixFile *pFd, i64 nByte);
static void unixUnmapfile(unixFile *pFd);
#endif

/*
** This function performs the parts of the "close file" operation 
** common to all locking schemes. It closes the directory and file
** handles, if they are valid, and sets all fields of the unixFile
** structure to 0.
**
** It is *not* necessary to hold the mutex when this routine is called,
** even on VxWorks.  A mutex will be acquired on VxWorks by the
** vxworksReleaseFileId() routine.
*/
static int closeUnixFile(sqlite3_file *id){
  unixFile *pFile = (unixFile*)id;
#if SQLITE_MAX_MMAP_SIZE>0
  unixUnmapfile(pFile);
#endif
  if( pFile->h>=0 ){
    robust_close(pFile, pFile->h, __LINE__);
    pFile->h = -1;
  }
#if OS_VXWORKS
  if( pFile->pId ){
    if( pFile->ctrlFlags & UNIXFILE_DELETE ){
26158
26159
26160
26161
26162
26163
26164

26165
26166
26167
26168
26169
26170
26171
  int got;
  int prior = 0;
#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
  i64 newOffset;
#endif
  TIMER_START;
  assert( cnt==(cnt&0x1ffff) );

  cnt &= 0x1ffff;
  do{
#if defined(USE_PREAD)
    got = osPread(id->h, pBuf, cnt, offset);
    SimulateIOError( got = -1 );
#elif defined(USE_PREAD64)
    got = osPread64(id->h, pBuf, cnt, offset);







>







26161
26162
26163
26164
26165
26166
26167
26168
26169
26170
26171
26172
26173
26174
26175
  int got;
  int prior = 0;
#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
  i64 newOffset;
#endif
  TIMER_START;
  assert( cnt==(cnt&0x1ffff) );
  assert( id->h>2 );
  cnt &= 0x1ffff;
  do{
#if defined(USE_PREAD)
    got = osPread(id->h, pBuf, cnt, offset);
    SimulateIOError( got = -1 );
#elif defined(USE_PREAD64)
    got = osPread64(id->h, pBuf, cnt, offset);
26272
26273
26274
26275
26276
26277
26278

26279
26280
26281
26282
26283
26284
26285
  const void *pBuf,               /* Copy data from this buffer to the file */
  int nBuf,                       /* Size of buffer pBuf in bytes */
  int *piErrno                    /* OUT: Error number if error occurs */
){
  int rc = 0;                     /* Value returned by system call */

  assert( nBuf==(nBuf&0x1ffff) );

  nBuf &= 0x1ffff;
  TIMER_START;

#if defined(USE_PREAD)
  do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
#elif defined(USE_PREAD64)
  do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);







>







26276
26277
26278
26279
26280
26281
26282
26283
26284
26285
26286
26287
26288
26289
26290
  const void *pBuf,               /* Copy data from this buffer to the file */
  int nBuf,                       /* Size of buffer pBuf in bytes */
  int *piErrno                    /* OUT: Error number if error occurs */
){
  int rc = 0;                     /* Value returned by system call */

  assert( nBuf==(nBuf&0x1ffff) );
  assert( fd>2 );
  nBuf &= 0x1ffff;
  TIMER_START;

#if defined(USE_PREAD)
  do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
#elif defined(USE_PREAD64)
  do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
26657
26658
26659
26660
26661
26662
26663

26664
26665
26666
26667
26668
26669
26670

26671
26672
26673
26674
26675
26676
26677
    ** source.
    */
    if( pFile->inNormalWrite && nByte==0 ){
      pFile->transCntrChng = 1;
    }
#endif


    /* If the file was just truncated to a size smaller than the currently
    ** mapped region, reduce the effective mapping size as well. SQLite will
    ** use read() and write() to access data beyond this point from now on.  
    */
    if( nByte<pFile->mmapSize ){
      pFile->mmapSize = nByte;
    }


    return SQLITE_OK;
  }
}

/*
** Determine the current size of a file in bytes







>







>







26662
26663
26664
26665
26666
26667
26668
26669
26670
26671
26672
26673
26674
26675
26676
26677
26678
26679
26680
26681
26682
26683
26684
    ** source.
    */
    if( pFile->inNormalWrite && nByte==0 ){
      pFile->transCntrChng = 1;
    }
#endif

#if SQLITE_MAX_MMAP_SIZE>0
    /* If the file was just truncated to a size smaller than the currently
    ** mapped region, reduce the effective mapping size as well. SQLite will
    ** use read() and write() to access data beyond this point from now on.  
    */
    if( nByte<pFile->mmapSize ){
      pFile->mmapSize = nByte;
    }
#endif

    return SQLITE_OK;
  }
}

/*
** Determine the current size of a file in bytes
26753
26754
26755
26756
26757
26758
26759

26760
26761
26762
26763
26764
26765
26766
26767
26768
26769
26770
26771

26772
26773
26774
26775
26776
26777
26778
        if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
        iWrite += nBlk;
      }
#endif
    }
  }


  if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){
    int rc;
    if( pFile->szChunk<=0 ){
      if( robust_ftruncate(pFile->h, nByte) ){
        pFile->lastErrno = errno;
        return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
      }
    }

    rc = unixMapfile(pFile, nByte);
    return rc;
  }


  return SQLITE_OK;
}

/*
** If *pArg is inititially negative then this is a query.  Set *pArg to
** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.







>












>







26760
26761
26762
26763
26764
26765
26766
26767
26768
26769
26770
26771
26772
26773
26774
26775
26776
26777
26778
26779
26780
26781
26782
26783
26784
26785
26786
26787
        if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
        iWrite += nBlk;
      }
#endif
    }
  }

#if SQLITE_MAX_MMAP_SIZE>0
  if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){
    int rc;
    if( pFile->szChunk<=0 ){
      if( robust_ftruncate(pFile->h, nByte) ){
        pFile->lastErrno = errno;
        return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
      }
    }

    rc = unixMapfile(pFile, nByte);
    return rc;
  }
#endif

  return SQLITE_OK;
}

/*
** If *pArg is inititially negative then this is a query.  Set *pArg to
** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
26833
26834
26835
26836
26837
26838
26839

26840
26841
26842
26843
26844
26845
26846
26847
26848
26849
26850
26851
26852
26853
26854
26855

26856
26857
26858
26859
26860
26861
26862
      char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
      if( zTFile ){
        unixGetTempname(pFile->pVfs->mxPathname, zTFile);
        *(char**)pArg = zTFile;
      }
      return SQLITE_OK;
    }

    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;
      int rc = SQLITE_OK;
      if( newLimit>sqlite3GlobalConfig.mxMmap ){
        newLimit = sqlite3GlobalConfig.mxMmap;
      }
      *(i64*)pArg = pFile->mmapSizeMax;
      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
        pFile->mmapSizeMax = newLimit;
        if( pFile->mmapSize>0 ){
          unixUnmapfile(pFile);
          rc = unixMapfile(pFile, -1);
        }
      }
      return rc;
    }

#ifdef SQLITE_DEBUG
    /* The pager calls this method to signal that it has done
    ** a rollback and that the database is therefore unchanged and
    ** it hence it is OK for the transaction change counter to be
    ** unchanged.
    */
    case SQLITE_FCNTL_DB_UNCHANGED: {







>
















>







26842
26843
26844
26845
26846
26847
26848
26849
26850
26851
26852
26853
26854
26855
26856
26857
26858
26859
26860
26861
26862
26863
26864
26865
26866
26867
26868
26869
26870
26871
26872
26873
      char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
      if( zTFile ){
        unixGetTempname(pFile->pVfs->mxPathname, zTFile);
        *(char**)pArg = zTFile;
      }
      return SQLITE_OK;
    }
#if SQLITE_MAX_MMAP_SIZE>0
    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;
      int rc = SQLITE_OK;
      if( newLimit>sqlite3GlobalConfig.mxMmap ){
        newLimit = sqlite3GlobalConfig.mxMmap;
      }
      *(i64*)pArg = pFile->mmapSizeMax;
      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
        pFile->mmapSizeMax = newLimit;
        if( pFile->mmapSize>0 ){
          unixUnmapfile(pFile);
          rc = unixMapfile(pFile, -1);
        }
      }
      return rc;
    }
#endif
#ifdef SQLITE_DEBUG
    /* The pager calls this method to signal that it has done
    ** a rollback and that the database is therefore unchanged and
    ** it hence it is OK for the transaction change counter to be
    ** unchanged.
    */
    case SQLITE_FCNTL_DB_UNCHANGED: {
27659
27660
27661
27662
27663
27664
27665

27666
27667
27668
27669
27670
27671
27672
27673
27674
27675
27676
27677
27678
27679
27680
27681
27682
27683
27684
27685
27686
27687
27688
27689
27690
27691
27692
27693
27694
27695
27696
27697
27698
27699
27700
27701
27702
27703
#else
# define unixShmMap     0
# define unixShmLock    0
# define unixShmBarrier 0
# define unixShmUnmap   0
#endif /* #ifndef SQLITE_OMIT_WAL */


/*
** If it is currently memory mapped, unmap file pFd.
*/
static void unixUnmapfile(unixFile *pFd){
  assert( pFd->nFetchOut==0 );
#if SQLITE_MAX_MMAP_SIZE>0
  if( pFd->pMapRegion ){
    osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
    pFd->pMapRegion = 0;
    pFd->mmapSize = 0;
    pFd->mmapSizeActual = 0;
  }
#endif
}

#if SQLITE_MAX_MMAP_SIZE>0
/*
** Return the system page size.
*/
static int unixGetPagesize(void){
#if HAVE_MREMAP
  return 512;
#elif defined(_BSD_SOURCE)
  return getpagesize();
#else
  return (int)sysconf(_SC_PAGESIZE);
#endif
}
#endif /* SQLITE_MAX_MMAP_SIZE>0 */

#if SQLITE_MAX_MMAP_SIZE>0
/*
** Attempt to set the size of the memory mapping maintained by file 
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
**
** If successful, this function sets the following variables:
**
**       unixFile.pMapRegion







>





<






<


<












<

<







27670
27671
27672
27673
27674
27675
27676
27677
27678
27679
27680
27681
27682

27683
27684
27685
27686
27687
27688

27689
27690

27691
27692
27693
27694
27695
27696
27697
27698
27699
27700
27701
27702

27703

27704
27705
27706
27707
27708
27709
27710
#else
# define unixShmMap     0
# define unixShmLock    0
# define unixShmBarrier 0
# define unixShmUnmap   0
#endif /* #ifndef SQLITE_OMIT_WAL */

#if SQLITE_MAX_MMAP_SIZE>0
/*
** If it is currently memory mapped, unmap file pFd.
*/
static void unixUnmapfile(unixFile *pFd){
  assert( pFd->nFetchOut==0 );

  if( pFd->pMapRegion ){
    osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
    pFd->pMapRegion = 0;
    pFd->mmapSize = 0;
    pFd->mmapSizeActual = 0;
  }

}


/*
** Return the system page size.
*/
static int unixGetPagesize(void){
#if HAVE_MREMAP
  return 512;
#elif defined(_BSD_SOURCE)
  return getpagesize();
#else
  return (int)sysconf(_SC_PAGESIZE);
#endif
}



/*
** Attempt to set the size of the memory mapping maintained by file 
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
**
** If successful, this function sets the following variables:
**
**       unixFile.pMapRegion
27774
27775
27776
27777
27778
27779
27780
27781
27782
27783
27784
27785
27786
27787
27788
27789
27790
27791
27792
27793
27794
27795
27796
27797
27798
27799
27800
27801
27802
27803
27804
27805
27806
27807
    ** will probably fail too. Fall back to using xRead/xWrite exclusively
    ** in this case.  */
    pFd->mmapSizeMax = 0;
  }
  pFd->pMapRegion = (void *)pNew;
  pFd->mmapSize = pFd->mmapSizeActual = nNew;
}
#endif

/*
** Memory map or remap the file opened by file-descriptor pFd (if the file
** is already mapped, the existing mapping is replaced by the new). Or, if 
** there already exists a mapping for this file, and there are still 
** outstanding xFetch() references to it, this function is a no-op.
**
** If parameter nByte is non-negative, then it is the requested size of 
** the mapping to create. Otherwise, if nByte is less than zero, then the 
** requested size is the size of the file on disk. The actual size of the
** created mapping is either the requested size or the value configured 
** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
**
** SQLITE_OK is returned if no error occurs (even if the mapping is not
** recreated as a result of outstanding references) or an SQLite error
** code otherwise.
*/
static int unixMapfile(unixFile *pFd, i64 nByte){
#if SQLITE_MAX_MMAP_SIZE>0
  i64 nMap = nByte;
  int rc;

  assert( nMap>=0 || pFd->nFetchOut==0 );
  if( pFd->nFetchOut>0 ) return SQLITE_OK;

  if( nMap<0 ){







<


















<







27781
27782
27783
27784
27785
27786
27787

27788
27789
27790
27791
27792
27793
27794
27795
27796
27797
27798
27799
27800
27801
27802
27803
27804
27805

27806
27807
27808
27809
27810
27811
27812
    ** will probably fail too. Fall back to using xRead/xWrite exclusively
    ** in this case.  */
    pFd->mmapSizeMax = 0;
  }
  pFd->pMapRegion = (void *)pNew;
  pFd->mmapSize = pFd->mmapSizeActual = nNew;
}


/*
** Memory map or remap the file opened by file-descriptor pFd (if the file
** is already mapped, the existing mapping is replaced by the new). Or, if 
** there already exists a mapping for this file, and there are still 
** outstanding xFetch() references to it, this function is a no-op.
**
** If parameter nByte is non-negative, then it is the requested size of 
** the mapping to create. Otherwise, if nByte is less than zero, then the 
** requested size is the size of the file on disk. The actual size of the
** created mapping is either the requested size or the value configured 
** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
**
** SQLITE_OK is returned if no error occurs (even if the mapping is not
** recreated as a result of outstanding references) or an SQLite error
** code otherwise.
*/
static int unixMapfile(unixFile *pFd, i64 nByte){

  i64 nMap = nByte;
  int rc;

  assert( nMap>=0 || pFd->nFetchOut==0 );
  if( pFd->nFetchOut>0 ) return SQLITE_OK;

  if( nMap<0 ){
27819
27820
27821
27822
27823
27824
27825
27826
27827
27828
27829

27830
27831
27832
27833
27834
27835
27836
  if( nMap!=pFd->mmapSize ){
    if( nMap>0 ){
      unixRemapfile(pFd, nMap);
    }else{
      unixUnmapfile(pFd);
    }
  }
#endif

  return SQLITE_OK;
}


/*
** If possible, return a pointer to a mapping of file fd starting at offset
** iOff. The mapping must be valid for at least nAmt bytes.
**
** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.







<



>







27824
27825
27826
27827
27828
27829
27830

27831
27832
27833
27834
27835
27836
27837
27838
27839
27840
27841
  if( nMap!=pFd->mmapSize ){
    if( nMap>0 ){
      unixRemapfile(pFd, nMap);
    }else{
      unixUnmapfile(pFd);
    }
  }


  return SQLITE_OK;
}
#endif /* SQLITE_MAX_MMAP_SIZE>0 */

/*
** If possible, return a pointer to a mapping of file fd starting at offset
** iOff. The mapping must be valid for at least nAmt bytes.
**
** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
27871
27872
27873
27874
27875
27876
27877

27878
27879
27880
27881
27882
27883
27884
27885
27886
27887
27888
27889
27890
27891
27892

27893
27894
27895
27896
27897
27898
27899
** to inform the VFS layer that, according to POSIX, any existing mapping 
** may now be invalid and should be unmapped.
*/
static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */
  UNUSED_PARAMETER(iOff);


  /* If p==0 (unmap the entire file) then there must be no outstanding 
  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
  ** then there must be at least one outstanding.  */
  assert( (p==0)==(pFd->nFetchOut==0) );

  /* If p!=0, it must match the iOff value. */
  assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );

  if( p ){
    pFd->nFetchOut--;
  }else{
    unixUnmapfile(pFd);
  }

  assert( pFd->nFetchOut>=0 );

  return SQLITE_OK;
}

/*
** Here ends the implementation of all sqlite3_file methods.
**
********************** End sqlite3_file Methods *******************************







>















>







27876
27877
27878
27879
27880
27881
27882
27883
27884
27885
27886
27887
27888
27889
27890
27891
27892
27893
27894
27895
27896
27897
27898
27899
27900
27901
27902
27903
27904
27905
27906
** to inform the VFS layer that, according to POSIX, any existing mapping 
** may now be invalid and should be unmapped.
*/
static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */
  UNUSED_PARAMETER(iOff);

#if SQLITE_MAX_MMAP_SIZE>0
  /* If p==0 (unmap the entire file) then there must be no outstanding 
  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
  ** then there must be at least one outstanding.  */
  assert( (p==0)==(pFd->nFetchOut==0) );

  /* If p!=0, it must match the iOff value. */
  assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );

  if( p ){
    pFd->nFetchOut--;
  }else{
    unixUnmapfile(pFd);
  }

  assert( pFd->nFetchOut>=0 );
#endif
  return SQLITE_OK;
}

/*
** Here ends the implementation of all sqlite3_file methods.
**
********************** End sqlite3_file Methods *******************************
28217
28218
28219
28220
28221
28222
28223

28224

28225
28226
28227
28228
28229
28230
28231
  assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );

  OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
  pNew->h = h;
  pNew->pVfs = pVfs;
  pNew->zPath = zFilename;
  pNew->ctrlFlags = (u8)ctrlFlags;

  pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;

  if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
                           "psow", SQLITE_POWERSAFE_OVERWRITE) ){
    pNew->ctrlFlags |= UNIXFILE_PSOW;
  }
  if( strcmp(pVfs->zName,"unix-excl")==0 ){
    pNew->ctrlFlags |= UNIXFILE_EXCL;
  }







>

>







28224
28225
28226
28227
28228
28229
28230
28231
28232
28233
28234
28235
28236
28237
28238
28239
28240
  assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );

  OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
  pNew->h = h;
  pNew->pVfs = pVfs;
  pNew->zPath = zFilename;
  pNew->ctrlFlags = (u8)ctrlFlags;
#if SQLITE_MAX_MMAP_SIZE>0
  pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif
  if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
                           "psow", SQLITE_POWERSAFE_OVERWRITE) ){
    pNew->ctrlFlags |= UNIXFILE_PSOW;
  }
  if( strcmp(pVfs->zName,"unix-excl")==0 ){
    pNew->ctrlFlags |= UNIXFILE_EXCL;
  }
28373
28374
28375
28376
28377
28378
28379

28380
28381
28382
28383
28384
28385
28386
28387
28388
28389
28390
28391

28392
28393
28394
28395
28396
28397
28398
/*
** Return the name of a directory in which to put temporary files.
** If no suitable temporary file directory can be found, return NULL.
*/
static const char *unixTempFileDir(void){
  static const char *azDirs[] = {
     0,

     0,
     "/var/tmp",
     "/usr/tmp",
     "/tmp",
     0        /* List terminator */
  };
  unsigned int i;
  struct stat buf;
  const char *zDir = 0;

  azDirs[0] = sqlite3_temp_directory;
  if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");

  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
    if( zDir==0 ) continue;
    if( osStat(zDir, &buf) ) continue;
    if( !S_ISDIR(buf.st_mode) ) continue;
    if( osAccess(zDir, 07) ) continue;
    break;
  }







>











|
>







28382
28383
28384
28385
28386
28387
28388
28389
28390
28391
28392
28393
28394
28395
28396
28397
28398
28399
28400
28401
28402
28403
28404
28405
28406
28407
28408
28409
/*
** Return the name of a directory in which to put temporary files.
** If no suitable temporary file directory can be found, return NULL.
*/
static const char *unixTempFileDir(void){
  static const char *azDirs[] = {
     0,
     0,
     0,
     "/var/tmp",
     "/usr/tmp",
     "/tmp",
     0        /* List terminator */
  };
  unsigned int i;
  struct stat buf;
  const char *zDir = 0;

  azDirs[0] = sqlite3_temp_directory;
  if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR");
  if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR");
  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
    if( zDir==0 ) continue;
    if( osStat(zDir, &buf) ) continue;
    if( !S_ISDIR(buf.st_mode) ) continue;
    if( osAccess(zDir, 07) ) continue;
    break;
  }
30497
30498
30499
30500
30501
30502
30503

30504
30505
30506
30507
30508
30509
30510
**
** This file contains code that is specific to Windows.
*/
#if SQLITE_OS_WIN               /* This file is used for Windows only */

#ifdef __CYGWIN__
# include <sys/cygwin.h>

#endif

/*
** Include code that is common to all os_*.c files
*/
/************** Include os_common.h in the middle of os_win.c ****************/
/************** Begin file os_common.h ***************************************/







>







30508
30509
30510
30511
30512
30513
30514
30515
30516
30517
30518
30519
30520
30521
30522
**
** This file contains code that is specific to Windows.
*/
#if SQLITE_OS_WIN               /* This file is used for Windows only */

#ifdef __CYGWIN__
# include <sys/cygwin.h>
# include <errno.h> /* amalgamator: keep */
#endif

/*
** Include code that is common to all os_*.c files
*/
/************** Include os_common.h in the middle of os_win.c ****************/
/************** Begin file os_common.h ***************************************/
30717
30718
30719
30720
30721
30722
30723
30724
30725
30726
30727
30728
30729
30730
30731
30732
30733
30734
30735
30736
30737
30738
30739
30740

30741
30742
30743




































































30744
30745
30746
30747
30748
30749
30750
/************** Continuing where we left off in os_win.c *********************/

/*
** Compiling and using WAL mode requires several APIs that are only
** available in Windows platforms based on the NT kernel.
*/
#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
# error "WAL mode requires support from the Windows NT kernel, compile\
 with SQLITE_OMIT_WAL."
#endif

/*
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
#  define SQLITE_WIN32_HAS_ANSI
#endif

/*
** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT

#  define SQLITE_WIN32_HAS_WIDE
#endif





































































/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
** are not present in the header file)?
*/
#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
/*







|







|







|
>



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







30729
30730
30731
30732
30733
30734
30735
30736
30737
30738
30739
30740
30741
30742
30743
30744
30745
30746
30747
30748
30749
30750
30751
30752
30753
30754
30755
30756
30757
30758
30759
30760
30761
30762
30763
30764
30765
30766
30767
30768
30769
30770
30771
30772
30773
30774
30775
30776
30777
30778
30779
30780
30781
30782
30783
30784
30785
30786
30787
30788
30789
30790
30791
30792
30793
30794
30795
30796
30797
30798
30799
30800
30801
30802
30803
30804
30805
30806
30807
30808
30809
30810
30811
30812
30813
30814
30815
30816
30817
30818
30819
30820
30821
30822
30823
30824
30825
30826
30827
30828
30829
30830
30831
/************** Continuing where we left off in os_win.c *********************/

/*
** Compiling and using WAL mode requires several APIs that are only
** available in Windows platforms based on the NT kernel.
*/
#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
#  error "WAL mode requires support from the Windows NT kernel, compile\
 with SQLITE_OMIT_WAL."
#endif

/*
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI)
#  define SQLITE_WIN32_HAS_ANSI
#endif

/*
** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \
    !defined(SQLITE_WIN32_NO_WIDE)
#  define SQLITE_WIN32_HAS_WIDE
#endif

/*
** Make sure at least one set of Win32 APIs is available.
*/
#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE)
#  error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\
 must be defined."
#endif

/*
** Maximum pathname length (in chars) for Win32.  This should normally be
** MAX_PATH.
*/
#ifndef SQLITE_WIN32_MAX_PATH_CHARS
#  define SQLITE_WIN32_MAX_PATH_CHARS   (MAX_PATH)
#endif

/*
** Maximum pathname length (in chars) for WinNT.  This should normally be
** 32767.
*/
#ifndef SQLITE_WINNT_MAX_PATH_CHARS
#  define SQLITE_WINNT_MAX_PATH_CHARS   (32767)
#endif

/*
** Maximum pathname length (in bytes) for Win32.  The MAX_PATH macro is in
** characters, so we allocate 3 bytes per character assuming worst-case of
** 4-bytes-per-character for UTF8.
*/
#ifndef SQLITE_WIN32_MAX_PATH_BYTES
#  define SQLITE_WIN32_MAX_PATH_BYTES   (SQLITE_WIN32_MAX_PATH_CHARS*4)
#endif

/*
** Maximum pathname length (in bytes) for WinNT.  This should normally be
** 32767 * sizeof(WCHAR).
*/
#ifndef SQLITE_WINNT_MAX_PATH_BYTES
#  define SQLITE_WINNT_MAX_PATH_BYTES   \
                            (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS)
#endif

/*
** Maximum error message length (in chars) for WinRT.
*/
#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS
#  define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024)
#endif

/*
** Returns non-zero if the character should be treated as a directory
** separator.
*/
#ifndef winIsDirSep
#  define winIsDirSep(a)                (((a) == '/') || ((a) == '\\'))
#endif

/*
** Returns the string that should be used as the directory separator.
*/
#ifndef winGetDirDep
#  ifdef __CYGWIN__
#    define winGetDirDep()              "/"
#  else
#    define winGetDirDep()              "\\"
#  endif
#endif

/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
** are not present in the header file)?
*/
#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
/*
30788
30789
30790
30791
30792
30793
30794
30795
30796
30797
30798
30799
30800
30801
30802
#endif

#ifndef FILE_ATTRIBUTE_MASK
# define FILE_ATTRIBUTE_MASK     (0x0003FFF7)
#endif

#ifndef SQLITE_OMIT_WAL
/* Forward references */
typedef struct winShm winShm;           /* A connection to shared-memory */
typedef struct winShmNode winShmNode;   /* A region of shared-memory */
#endif

/*
** WinCE lacks native support for file locking so we have to fake it
** with some code of our own.







|







30869
30870
30871
30872
30873
30874
30875
30876
30877
30878
30879
30880
30881
30882
30883
#endif

#ifndef FILE_ATTRIBUTE_MASK
# define FILE_ATTRIBUTE_MASK     (0x0003FFF7)
#endif

#ifndef SQLITE_OMIT_WAL
/* Forward references to structures used for WAL */
typedef struct winShm winShm;           /* A connection to shared-memory */
typedef struct winShmNode winShmNode;   /* A region of shared-memory */
#endif

/*
** WinCE lacks native support for file locking so we have to fake it
** with some code of our own.
30917
30918
30919
30920
30921
30922
30923

30924
30925
30926
30927
30928
30929
30930
/*
 * The extra flags to use in calls to the Win32 heap APIs.  This value may be
 * zero for the default behavior.
 */
#ifndef SQLITE_WIN32_HEAP_FLAGS
#  define SQLITE_WIN32_HEAP_FLAGS     (0)
#endif


/*
** The winMemData structure stores information required by the Win32-specific
** sqlite3_mem_methods implementation.
*/
typedef struct winMemData winMemData;
struct winMemData {







>







30998
30999
31000
31001
31002
31003
31004
31005
31006
31007
31008
31009
31010
31011
31012
/*
 * The extra flags to use in calls to the Win32 heap APIs.  This value may be
 * zero for the default behavior.
 */
#ifndef SQLITE_WIN32_HEAP_FLAGS
#  define SQLITE_WIN32_HEAP_FLAGS     (0)
#endif


/*
** The winMemData structure stores information required by the Win32-specific
** sqlite3_mem_methods implementation.
*/
typedef struct winMemData winMemData;
struct winMemData {
31742
31743
31744
31745
31746
31747
31748
31749
31750
31751
31752
31753
31754
31755
31756
31757
31758
31759
31760
31761
** Here is an interesting observation:  Win95, Win98, and WinME lack
** the LockFileEx() API.  But we can still statically link against that
** API as long as we don't call it when running Win95/98/ME.  A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
# define isNT()  (1)
#elif !defined(SQLITE_WIN32_HAS_WIDE)
# define isNT()  (0)
#else
  static int isNT(void){
    if( sqlite3_os_type==0 ){
      OSVERSIONINFOA sInfo;
      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
      osGetVersionExA(&sInfo);
      sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
    }
    return sqlite3_os_type==2;







|
|

|

|







31824
31825
31826
31827
31828
31829
31830
31831
31832
31833
31834
31835
31836
31837
31838
31839
31840
31841
31842
31843
** Here is an interesting observation:  Win95, Win98, and WinME lack
** the LockFileEx() API.  But we can still statically link against that
** API as long as we don't call it when running Win95/98/ME.  A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
# define osIsNT()  (1)
#elif !defined(SQLITE_WIN32_HAS_WIDE)
# define osIsNT()  (0)
#else
  static int osIsNT(void){
    if( sqlite3_os_type==0 ){
      OSVERSIONINFOA sInfo;
      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
      osGetVersionExA(&sInfo);
      sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
    }
    return sqlite3_os_type==2;
31958
31959
31960
31961
31962
31963
31964
31965
31966
31967
31968
31969
31970
31971
31972
#endif /* SQLITE_WIN32_MALLOC */

/*
** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). 
**
** Space to hold the returned string is obtained from malloc.
*/
static LPWSTR utf8ToUnicode(const char *zFilename){
  int nChar;
  LPWSTR zWideFilename;

  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
  if( nChar==0 ){
    return 0;
  }







|







32040
32041
32042
32043
32044
32045
32046
32047
32048
32049
32050
32051
32052
32053
32054
#endif /* SQLITE_WIN32_MALLOC */

/*
** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). 
**
** Space to hold the returned string is obtained from malloc.
*/
static LPWSTR winUtf8ToUnicode(const char *zFilename){
  int nChar;
  LPWSTR zWideFilename;

  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
  if( nChar==0 ){
    return 0;
  }
31983
31984
31985
31986
31987
31988
31989
31990
31991
31992
31993
31994
31995
31996
31997
  return zWideFilename;
}

/*
** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
** obtained from sqlite3_malloc().
*/
static char *unicodeToUtf8(LPCWSTR zWideFilename){
  int nByte;
  char *zFilename;

  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
  if( nByte == 0 ){
    return 0;
  }







|







32065
32066
32067
32068
32069
32070
32071
32072
32073
32074
32075
32076
32077
32078
32079
  return zWideFilename;
}

/*
** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
** obtained from sqlite3_malloc().
*/
static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
  int nByte;
  char *zFilename;

  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
  if( nByte == 0 ){
    return 0;
  }
32011
32012
32013
32014
32015
32016
32017
32018
32019
32020
32021
32022
32023
32024
32025
/*
** Convert an ANSI string to Microsoft Unicode, based on the
** current codepage settings for file apis.
** 
** Space to hold the returned string is obtained
** from sqlite3_malloc.
*/
static LPWSTR mbcsToUnicode(const char *zFilename){
  int nByte;
  LPWSTR zMbcsFilename;
  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;

  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
                                0)*sizeof(WCHAR);
  if( nByte==0 ){







|







32093
32094
32095
32096
32097
32098
32099
32100
32101
32102
32103
32104
32105
32106
32107
/*
** Convert an ANSI string to Microsoft Unicode, based on the
** current codepage settings for file apis.
** 
** Space to hold the returned string is obtained
** from sqlite3_malloc.
*/
static LPWSTR winMbcsToUnicode(const char *zFilename){
  int nByte;
  LPWSTR zMbcsFilename;
  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;

  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
                                0)*sizeof(WCHAR);
  if( nByte==0 ){
32041
32042
32043
32044
32045
32046
32047
32048
32049
32050
32051
32052
32053
32054
32055
/*
** Convert Microsoft Unicode to multi-byte character string, based on the
** user's ANSI codepage.
**
** Space to hold the returned string is obtained from
** sqlite3_malloc().
*/
static char *unicodeToMbcs(LPCWSTR zWideFilename){
  int nByte;
  char *zFilename;
  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;

  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
  if( nByte == 0 ){
    return 0;







|







32123
32124
32125
32126
32127
32128
32129
32130
32131
32132
32133
32134
32135
32136
32137
/*
** Convert Microsoft Unicode to multi-byte character string, based on the
** user's ANSI codepage.
**
** Space to hold the returned string is obtained from
** sqlite3_malloc().
*/
static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
  int nByte;
  char *zFilename;
  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;

  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
  if( nByte == 0 ){
    return 0;
32071
32072
32073
32074
32075
32076
32077
32078
32079
32080
32081
32082
32083
32084
32085
32086
32087
32088
32089
32090
32091
32092
32093
32094
32095
32096
32097
32098
32099
32100
32101
32102
32103
32104
32105
32106
** Convert multibyte character string to UTF-8.  Space to hold the
** returned string is obtained from sqlite3_malloc().
*/
SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
  char *zFilenameUtf8;
  LPWSTR zTmpWide;

  zTmpWide = mbcsToUnicode(zFilename);
  if( zTmpWide==0 ){
    return 0;
  }
  zFilenameUtf8 = unicodeToUtf8(zTmpWide);
  sqlite3_free(zTmpWide);
  return zFilenameUtf8;
}

/*
** Convert UTF-8 to multibyte character string.  Space to hold the 
** returned string is obtained from sqlite3_malloc().
*/
SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
  char *zFilenameMbcs;
  LPWSTR zTmpWide;

  zTmpWide = utf8ToUnicode(zFilename);
  if( zTmpWide==0 ){
    return 0;
  }
  zFilenameMbcs = unicodeToMbcs(zTmpWide);
  sqlite3_free(zTmpWide);
  return zFilenameMbcs;
}

/*
** This function sets the data directory or the temporary directory based on
** the provided arguments.  The type argument must be 1 in order to set the







|



|












|



|







32153
32154
32155
32156
32157
32158
32159
32160
32161
32162
32163
32164
32165
32166
32167
32168
32169
32170
32171
32172
32173
32174
32175
32176
32177
32178
32179
32180
32181
32182
32183
32184
32185
32186
32187
32188
** Convert multibyte character string to UTF-8.  Space to hold the
** returned string is obtained from sqlite3_malloc().
*/
SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
  char *zFilenameUtf8;
  LPWSTR zTmpWide;

  zTmpWide = winMbcsToUnicode(zFilename);
  if( zTmpWide==0 ){
    return 0;
  }
  zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
  sqlite3_free(zTmpWide);
  return zFilenameUtf8;
}

/*
** Convert UTF-8 to multibyte character string.  Space to hold the 
** returned string is obtained from sqlite3_malloc().
*/
SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
  char *zFilenameMbcs;
  LPWSTR zTmpWide;

  zTmpWide = winUtf8ToUnicode(zFilename);
  if( zTmpWide==0 ){
    return 0;
  }
  zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
  sqlite3_free(zTmpWide);
  return zFilenameMbcs;
}

/*
** This function sets the data directory or the temporary directory based on
** the provided arguments.  The type argument must be 1 in order to set the
32122
32123
32124
32125
32126
32127
32128
32129
32130
32131
32132
32133
32134
32135
32136
32137
32138
32139
32140
32141
32142
32143
32144
32145
32146
32147
32148
32149
32150
32151
32152
32153
32154
32155
32156
32157
32158
32159
32160
32161
32162
32163
32164
32165
32166
32167
32168
32169
32170
32171
32172
32173
32174
32175
32176
32177
32178
32179
32180
32181
32182
32183
32184
32185
32186
32187
  assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE
          || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE
  );
  assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
  if( ppDirectory ){
    char *zValueUtf8 = 0;
    if( zValue && zValue[0] ){
      zValueUtf8 = unicodeToUtf8(zValue);
      if ( zValueUtf8==0 ){
        return SQLITE_NOMEM;
      }
    }
    sqlite3_free(*ppDirectory);
    *ppDirectory = zValueUtf8;
    return SQLITE_OK;
  }
  return SQLITE_ERROR;
}

/*
** The return value of getLastErrorMsg
** is zero if the error message fits in the buffer, or non-zero
** otherwise (if the message was truncated).
*/
static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
  /* FormatMessage returns 0 on failure.  Otherwise it
  ** returns the number of TCHARs written to the output
  ** buffer, excluding the terminating null char.
  */
  DWORD dwLen = 0;
  char *zOut = 0;

  if( isNT() ){
#if SQLITE_OS_WINRT
    WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */
    dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
                             FORMAT_MESSAGE_IGNORE_INSERTS,
                             NULL,
                             lastErrno,
                             0,
                             zTempWide,
                             MAX_PATH,
                             0);
#else
    LPWSTR zTempWide = NULL;
    dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                             FORMAT_MESSAGE_FROM_SYSTEM |
                             FORMAT_MESSAGE_IGNORE_INSERTS,
                             NULL,
                             lastErrno,
                             0,
                             (LPWSTR) &zTempWide,
                             0,
                             0);
#endif
    if( dwLen > 0 ){
      /* allocate a buffer and convert to UTF8 */
      sqlite3BeginBenignMalloc();
      zOut = unicodeToUtf8(zTempWide);
      sqlite3EndBenignMalloc();
#if !SQLITE_OS_WINRT
      /* free the system buffer allocated by FormatMessage */
      osLocalFree(zTempWide);
#endif
    }
  }







|












|



|







|

|






|
















|







32204
32205
32206
32207
32208
32209
32210
32211
32212
32213
32214
32215
32216
32217
32218
32219
32220
32221
32222
32223
32224
32225
32226
32227
32228
32229
32230
32231
32232
32233
32234
32235
32236
32237
32238
32239
32240
32241
32242
32243
32244
32245
32246
32247
32248
32249
32250
32251
32252
32253
32254
32255
32256
32257
32258
32259
32260
32261
32262
32263
32264
32265
32266
32267
32268
32269
  assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE
          || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE
  );
  assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
  if( ppDirectory ){
    char *zValueUtf8 = 0;
    if( zValue && zValue[0] ){
      zValueUtf8 = winUnicodeToUtf8(zValue);
      if ( zValueUtf8==0 ){
        return SQLITE_NOMEM;
      }
    }
    sqlite3_free(*ppDirectory);
    *ppDirectory = zValueUtf8;
    return SQLITE_OK;
  }
  return SQLITE_ERROR;
}

/*
** The return value of winGetLastErrorMsg
** is zero if the error message fits in the buffer, or non-zero
** otherwise (if the message was truncated).
*/
static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
  /* FormatMessage returns 0 on failure.  Otherwise it
  ** returns the number of TCHARs written to the output
  ** buffer, excluding the terminating null char.
  */
  DWORD dwLen = 0;
  char *zOut = 0;

  if( osIsNT() ){
#if SQLITE_OS_WINRT
    WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1];
    dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
                             FORMAT_MESSAGE_IGNORE_INSERTS,
                             NULL,
                             lastErrno,
                             0,
                             zTempWide,
                             SQLITE_WIN32_MAX_ERRMSG_CHARS,
                             0);
#else
    LPWSTR zTempWide = NULL;
    dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                             FORMAT_MESSAGE_FROM_SYSTEM |
                             FORMAT_MESSAGE_IGNORE_INSERTS,
                             NULL,
                             lastErrno,
                             0,
                             (LPWSTR) &zTempWide,
                             0,
                             0);
#endif
    if( dwLen > 0 ){
      /* allocate a buffer and convert to UTF8 */
      sqlite3BeginBenignMalloc();
      zOut = winUnicodeToUtf8(zTempWide);
      sqlite3EndBenignMalloc();
#if !SQLITE_OS_WINRT
      /* free the system buffer allocated by FormatMessage */
      osLocalFree(zTempWide);
#endif
    }
  }
32241
32242
32243
32244
32245
32246
32247
32248
32249
32250
32251
32252
32253
32254
32255
  const char *zPath,              /* File path associated with error */
  int iLine                       /* Source line number where error occurred */
){
  char zMsg[500];                 /* Human readable error text */
  int i;                          /* Loop counter */

  zMsg[0] = 0;
  getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
  assert( errcode!=SQLITE_OK );
  if( zPath==0 ) zPath = "";
  for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
  zMsg[i] = 0;
  sqlite3_log(errcode,
      "os_win.c:%d: (%lu) %s(%s) - %s",
      iLine, lastErrno, zFunc, zPath, zMsg







|







32323
32324
32325
32326
32327
32328
32329
32330
32331
32332
32333
32334
32335
32336
32337
  const char *zPath,              /* File path associated with error */
  int iLine                       /* Source line number where error occurred */
){
  char zMsg[500];                 /* Human readable error text */
  int i;                          /* Loop counter */

  zMsg[0] = 0;
  winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
  assert( errcode!=SQLITE_OK );
  if( zPath==0 ) zPath = "";
  for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
  zMsg[i] = 0;
  sqlite3_log(errcode,
      "os_win.c:%d: (%lu) %s(%s) - %s",
      iLine, lastErrno, zFunc, zPath, zMsg
32266
32267
32268
32269
32270
32271
32272
32273
32274
32275
32276
32277
32278
32279
32280
32281
32282
32283
32284
32285
32286
32287
32288
32289
32290
32291
32292
32293
32294
32295
32296
32297
32298
32299
32300
32301
32302
32303
32304
32305
32306
32307
32308
32309
32310
32311
32312
32313
32314
32315
32316
*/
#ifndef SQLITE_WIN32_IOERR_RETRY
# define SQLITE_WIN32_IOERR_RETRY 10
#endif
#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
# define SQLITE_WIN32_IOERR_RETRY_DELAY 25
#endif
static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY;
static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;

/*
** If a ReadFile() or WriteFile() error occurs, invoke this routine
** to see if it should be retried.  Return TRUE to retry.  Return FALSE
** to give up with an error.
*/
static int retryIoerr(int *pnRetry, DWORD *pError){
  DWORD e = osGetLastError();
  if( *pnRetry>=win32IoerrRetry ){
    if( pError ){
      *pError = e;
    }
    return 0;
  }
  if( e==ERROR_ACCESS_DENIED ||
      e==ERROR_LOCK_VIOLATION ||
      e==ERROR_SHARING_VIOLATION ){
    sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry));
    ++*pnRetry;
    return 1;
  }
  if( pError ){
    *pError = e;
  }
  return 0;
}

/*
** Log a I/O error retry episode.
*/
static void logIoerr(int nRetry){
  if( nRetry ){
    sqlite3_log(SQLITE_IOERR, 
      "delayed %dms for lock/sharing conflict",
      win32IoerrRetryDelay*nRetry*(nRetry+1)/2
    );
  }
}

#if SQLITE_OS_WINCE
/*************************************************************************
** This section contains code for WinCE only.







|
|






|

|








|












|



|







32348
32349
32350
32351
32352
32353
32354
32355
32356
32357
32358
32359
32360
32361
32362
32363
32364
32365
32366
32367
32368
32369
32370
32371
32372
32373
32374
32375
32376
32377
32378
32379
32380
32381
32382
32383
32384
32385
32386
32387
32388
32389
32390
32391
32392
32393
32394
32395
32396
32397
32398
*/
#ifndef SQLITE_WIN32_IOERR_RETRY
# define SQLITE_WIN32_IOERR_RETRY 10
#endif
#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
# define SQLITE_WIN32_IOERR_RETRY_DELAY 25
#endif
static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;

/*
** If a ReadFile() or WriteFile() error occurs, invoke this routine
** to see if it should be retried.  Return TRUE to retry.  Return FALSE
** to give up with an error.
*/
static int winRetryIoerr(int *pnRetry, DWORD *pError){
  DWORD e = osGetLastError();
  if( *pnRetry>=winIoerrRetry ){
    if( pError ){
      *pError = e;
    }
    return 0;
  }
  if( e==ERROR_ACCESS_DENIED ||
      e==ERROR_LOCK_VIOLATION ||
      e==ERROR_SHARING_VIOLATION ){
    sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
    ++*pnRetry;
    return 1;
  }
  if( pError ){
    *pError = e;
  }
  return 0;
}

/*
** Log a I/O error retry episode.
*/
static void winLogIoerr(int nRetry){
  if( nRetry ){
    sqlite3_log(SQLITE_IOERR, 
      "delayed %dms for lock/sharing conflict",
      winIoerrRetryDelay*nRetry*(nRetry+1)/2
    );
  }
}

#if SQLITE_OS_WINCE
/*************************************************************************
** This section contains code for WinCE only.
32367
32368
32369
32370
32371
32372
32373
32374
32375
32376
32377
32378
32379
32380
32381
32382
32383
32384
32385
32386
32387
32388
32389
32390
32391
32392
32393

32394
32395
32396
32397
32398
32399
32400
32401
32402
32403
32404
static int winceCreateLock(const char *zFilename, winFile *pFile){
  LPWSTR zTok;
  LPWSTR zName;
  DWORD lastErrno;
  BOOL bLogged = FALSE;
  BOOL bInit = TRUE;

  zName = utf8ToUnicode(zFilename);
  if( zName==0 ){
    /* out of memory */
    return SQLITE_IOERR_NOMEM;
  }

  /* Initialize the local lockdata */
  memset(&pFile->local, 0, sizeof(pFile->local));

  /* Replace the backslashes from the filename and lowercase it
  ** to derive a mutex name. */
  zTok = osCharLowerW(zName);
  for (;*zTok;zTok++){
    if (*zTok == '\\') *zTok = '_';
  }

  /* Create/open the named mutex */
  pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
  if (!pFile->hMutex){
    pFile->lastErrno = osGetLastError();

    winLogError(SQLITE_IOERR, pFile->lastErrno,
                "winceCreateLock1", zFilename);
    sqlite3_free(zName);
    return SQLITE_IOERR;
  }

  /* Acquire the mutex before continuing */
  winceMutexAcquire(pFile->hMutex);
  
  /* Since the names of named mutexes, semaphores, file mappings etc are 
  ** case-sensitive, take advantage of that by uppercasing the mutex name







|



















>
|
|
<
<







32449
32450
32451
32452
32453
32454
32455
32456
32457
32458
32459
32460
32461
32462
32463
32464
32465
32466
32467
32468
32469
32470
32471
32472
32473
32474
32475
32476
32477
32478


32479
32480
32481
32482
32483
32484
32485
static int winceCreateLock(const char *zFilename, winFile *pFile){
  LPWSTR zTok;
  LPWSTR zName;
  DWORD lastErrno;
  BOOL bLogged = FALSE;
  BOOL bInit = TRUE;

  zName = winUtf8ToUnicode(zFilename);
  if( zName==0 ){
    /* out of memory */
    return SQLITE_IOERR_NOMEM;
  }

  /* Initialize the local lockdata */
  memset(&pFile->local, 0, sizeof(pFile->local));

  /* Replace the backslashes from the filename and lowercase it
  ** to derive a mutex name. */
  zTok = osCharLowerW(zName);
  for (;*zTok;zTok++){
    if (*zTok == '\\') *zTok = '_';
  }

  /* Create/open the named mutex */
  pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
  if (!pFile->hMutex){
    pFile->lastErrno = osGetLastError();
    sqlite3_free(zName);
    return winLogError(SQLITE_IOERR, pFile->lastErrno,
                       "winceCreateLock1", zFilename);


  }

  /* Acquire the mutex before continuing */
  winceMutexAcquire(pFile->hMutex);
  
  /* Since the names of named mutexes, semaphores, file mappings etc are 
  ** case-sensitive, take advantage of that by uppercasing the mutex name
32640
32641
32642
32643
32644
32645
32646
32647
32648
32649
32650
32651
32652
32653
32654
  /*
  ** NOTE: Windows CE is handled differently here due its lack of the Win32
  **       API LockFile.
  */
  return winceLockFile(phFile, offsetLow, offsetHigh,
                       numBytesLow, numBytesHigh);
#else
  if( isNT() ){
    OVERLAPPED ovlp;
    memset(&ovlp, 0, sizeof(OVERLAPPED));
    ovlp.Offset = offsetLow;
    ovlp.OffsetHigh = offsetHigh;
    return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
  }else{
    return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,







|







32721
32722
32723
32724
32725
32726
32727
32728
32729
32730
32731
32732
32733
32734
32735
  /*
  ** NOTE: Windows CE is handled differently here due its lack of the Win32
  **       API LockFile.
  */
  return winceLockFile(phFile, offsetLow, offsetHigh,
                       numBytesLow, numBytesHigh);
#else
  if( osIsNT() ){
    OVERLAPPED ovlp;
    memset(&ovlp, 0, sizeof(OVERLAPPED));
    ovlp.Offset = offsetLow;
    ovlp.OffsetHigh = offsetHigh;
    return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
  }else{
    return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
32671
32672
32673
32674
32675
32676
32677
32678
32679
32680
32681
32682
32683
32684
32685
  /*
  ** NOTE: Windows CE is handled differently here due its lack of the Win32
  **       API UnlockFile.
  */
  return winceUnlockFile(phFile, offsetLow, offsetHigh,
                         numBytesLow, numBytesHigh);
#else
  if( isNT() ){
    OVERLAPPED ovlp;
    memset(&ovlp, 0, sizeof(OVERLAPPED));
    ovlp.Offset = offsetLow;
    ovlp.OffsetHigh = offsetHigh;
    return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
  }else{
    return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,







|







32752
32753
32754
32755
32756
32757
32758
32759
32760
32761
32762
32763
32764
32765
32766
  /*
  ** NOTE: Windows CE is handled differently here due its lack of the Win32
  **       API UnlockFile.
  */
  return winceUnlockFile(phFile, offsetLow, offsetHigh,
                         numBytesLow, numBytesHigh);
#else
  if( osIsNT() ){
    OVERLAPPED ovlp;
    memset(&ovlp, 0, sizeof(OVERLAPPED));
    ovlp.Offset = offsetLow;
    ovlp.OffsetHigh = offsetHigh;
    return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
  }else{
    return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
32701
32702
32703
32704
32705
32706
32707
32708
32709
32710
32711
32712
32713
32714
32715
#endif

/*
** Move the current position of the file handle passed as the first 
** argument to offset iOffset within the file. If successful, return 0. 
** Otherwise, set pFile->lastErrno and return non-zero.
*/
static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
#if !SQLITE_OS_WINRT
  LONG upperBits;                 /* Most sig. 32 bits of new offset */
  LONG lowerBits;                 /* Least sig. 32 bits of new offset */
  DWORD dwRet;                    /* Value returned by SetFilePointer() */
  DWORD lastErrno;                /* Value returned by GetLastError() */

  OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset));







|







32782
32783
32784
32785
32786
32787
32788
32789
32790
32791
32792
32793
32794
32795
32796
#endif

/*
** Move the current position of the file handle passed as the first 
** argument to offset iOffset within the file. If successful, return 0. 
** Otherwise, set pFile->lastErrno and return non-zero.
*/
static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){
#if !SQLITE_OS_WINRT
  LONG upperBits;                 /* Most sig. 32 bits of new offset */
  LONG lowerBits;                 /* Least sig. 32 bits of new offset */
  DWORD dwRet;                    /* Value returned by SetFilePointer() */
  DWORD lastErrno;                /* Value returned by GetLastError() */

  OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset));
32726
32727
32728
32729
32730
32731
32732
32733
32734
32735
32736
32737
32738
32739
32740
32741
32742
32743
32744
32745
32746
32747
32748
32749
32750
32751
32752
32753
32754
32755
32756
32757
32758
32759
32760
32761
32762
32763
32764
32765

32766
32767
32768
32769
32770
32771
32772
  */
  dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);

  if( (dwRet==INVALID_SET_FILE_POINTER
      && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
    pFile->lastErrno = lastErrno;
    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
             "seekWinFile", pFile->zPath);
    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
    return 1;
  }

  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
  return 0;
#else
  /*
  ** Same as above, except that this implementation works for WinRT.
  */

  LARGE_INTEGER x;                /* The new offset */
  BOOL bRet;                      /* Value returned by SetFilePointerEx() */

  x.QuadPart = iOffset;
  bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);

  if(!bRet){
    pFile->lastErrno = osGetLastError();
    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
             "seekWinFile", pFile->zPath);
    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
    return 1;
  }

  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
  return 0;
#endif
}

#if SQLITE_MAX_MMAP_SIZE>0
/* Forward references to VFS methods */

static int winUnmapfile(winFile*);
#endif

/*
** Close a file.
**
** It is reported that an attempt to close a handle might sometimes







|




















|










|
>







32807
32808
32809
32810
32811
32812
32813
32814
32815
32816
32817
32818
32819
32820
32821
32822
32823
32824
32825
32826
32827
32828
32829
32830
32831
32832
32833
32834
32835
32836
32837
32838
32839
32840
32841
32842
32843
32844
32845
32846
32847
32848
32849
32850
32851
32852
32853
32854
  */
  dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);

  if( (dwRet==INVALID_SET_FILE_POINTER
      && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
    pFile->lastErrno = lastErrno;
    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
                "winSeekFile", pFile->zPath);
    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
    return 1;
  }

  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
  return 0;
#else
  /*
  ** Same as above, except that this implementation works for WinRT.
  */

  LARGE_INTEGER x;                /* The new offset */
  BOOL bRet;                      /* Value returned by SetFilePointerEx() */

  x.QuadPart = iOffset;
  bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);

  if(!bRet){
    pFile->lastErrno = osGetLastError();
    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
                "winSeekFile", pFile->zPath);
    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
    return 1;
  }

  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
  return 0;
#endif
}

#if SQLITE_MAX_MMAP_SIZE>0
/* Forward references to VFS helper methods used for memory mapped files */
static int winMapfile(winFile*, sqlite3_int64);
static int winUnmapfile(winFile*);
#endif

/*
** Close a file.
**
** It is reported that an attempt to close a handle might sometimes
32862
32863
32864
32865
32866
32867
32868
32869
32870
32871
32872
32873
32874
32875
32876
32877
32878
32879
32880
32881
32882
32883
32884
32885
32886
32887
32888
32889
32890
32891
32892
32893
32894
32895
      amt -= nCopy;
      offset += nCopy;
    }
  }
#endif

#if SQLITE_OS_WINCE
  if( seekWinFile(pFile, offset) ){
    OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
    return SQLITE_FULL;
  }
  while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
#else
  memset(&overlapped, 0, sizeof(OVERLAPPED));
  overlapped.Offset = (LONG)(offset & 0xffffffff);
  overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
  while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
         osGetLastError()!=ERROR_HANDLE_EOF ){
#endif
    DWORD lastErrno;
    if( retryIoerr(&nRetry, &lastErrno) ) continue;
    pFile->lastErrno = lastErrno;
    OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h));
    return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
             "winRead", pFile->zPath);
  }
  logIoerr(nRetry);
  if( nRead<(DWORD)amt ){
    /* Unread parts of the buffer must be zero-filled */
    memset(&((char*)pBuf)[nRead], 0, amt-nRead);
    OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h));
    return SQLITE_IOERR_SHORT_READ;
  }








|












|



|

|







32944
32945
32946
32947
32948
32949
32950
32951
32952
32953
32954
32955
32956
32957
32958
32959
32960
32961
32962
32963
32964
32965
32966
32967
32968
32969
32970
32971
32972
32973
32974
32975
32976
32977
      amt -= nCopy;
      offset += nCopy;
    }
  }
#endif

#if SQLITE_OS_WINCE
  if( winSeekFile(pFile, offset) ){
    OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
    return SQLITE_FULL;
  }
  while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
#else
  memset(&overlapped, 0, sizeof(OVERLAPPED));
  overlapped.Offset = (LONG)(offset & 0xffffffff);
  overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
  while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
         osGetLastError()!=ERROR_HANDLE_EOF ){
#endif
    DWORD lastErrno;
    if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
    pFile->lastErrno = lastErrno;
    OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h));
    return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
                       "winRead", pFile->zPath);
  }
  winLogIoerr(nRetry);
  if( nRead<(DWORD)amt ){
    /* Unread parts of the buffer must be zero-filled */
    memset(&((char*)pBuf)[nRead], 0, amt-nRead);
    OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h));
    return SQLITE_IOERR_SHORT_READ;
  }

32934
32935
32936
32937
32938
32939
32940
32941
32942
32943
32944
32945
32946
32947
32948
      amt -= nCopy;
      offset += nCopy;
    }
  }
#endif

#if SQLITE_OS_WINCE
  rc = seekWinFile(pFile, offset);
  if( rc==0 ){
#else
  {
#endif
#if !SQLITE_OS_WINCE
    OVERLAPPED overlapped;        /* The offset for WriteFile. */
#endif







|







33016
33017
33018
33019
33020
33021
33022
33023
33024
33025
33026
33027
33028
33029
33030
      amt -= nCopy;
      offset += nCopy;
    }
  }
#endif

#if SQLITE_OS_WINCE
  rc = winSeekFile(pFile, offset);
  if( rc==0 ){
#else
  {
#endif
#if !SQLITE_OS_WINCE
    OVERLAPPED overlapped;        /* The offset for WriteFile. */
#endif
32959
32960
32961
32962
32963
32964
32965
32966
32967
32968
32969
32970
32971
32972
32973

    while( nRem>0 ){
#if SQLITE_OS_WINCE
      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
#else
      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
#endif
        if( retryIoerr(&nRetry, &lastErrno) ) continue;
        break;
      }
      assert( nWrite==0 || nWrite<=(DWORD)nRem );
      if( nWrite==0 || nWrite>(DWORD)nRem ){
        lastErrno = osGetLastError();
        break;
      }







|







33041
33042
33043
33044
33045
33046
33047
33048
33049
33050
33051
33052
33053
33054
33055

    while( nRem>0 ){
#if SQLITE_OS_WINCE
      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
#else
      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
#endif
        if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
        break;
      }
      assert( nWrite==0 || nWrite<=(DWORD)nRem );
      if( nWrite==0 || nWrite>(DWORD)nRem ){
        lastErrno = osGetLastError();
        break;
      }
32985
32986
32987
32988
32989
32990
32991
32992

32993
32994
32995
32996
32997
32998
32999
33000
33001
33002
33003
33004
33005
    }
  }

  if( rc ){
    if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
       || ( pFile->lastErrno==ERROR_DISK_FULL )){
      OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h));
      return SQLITE_FULL;

    }
    OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h));
    return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
             "winWrite", pFile->zPath);
  }else{
    logIoerr(nRetry);
  }
  OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h));
  return SQLITE_OK;
}

/*
** Truncate an open file to a specified size







|
>



|

|







33067
33068
33069
33070
33071
33072
33073
33074
33075
33076
33077
33078
33079
33080
33081
33082
33083
33084
33085
33086
33087
33088
    }
  }

  if( rc ){
    if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
       || ( pFile->lastErrno==ERROR_DISK_FULL )){
      OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h));
      return winLogError(SQLITE_FULL, pFile->lastErrno,
                         "winWrite1", pFile->zPath);
    }
    OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h));
    return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
                       "winWrite2", pFile->zPath);
  }else{
    winLogIoerr(nRetry);
  }
  OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h));
  return SQLITE_OK;
}

/*
** Truncate an open file to a specified size
33020
33021
33022
33023
33024
33025
33026
33027
33028
33029
33030
33031
33032
33033
33034
  ** size).
  */
  if( pFile->szChunk>0 ){
    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
  }

  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
  if( seekWinFile(pFile, nByte) ){
    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
                     "winTruncate1", pFile->zPath);
  }else if( 0==osSetEndOfFile(pFile->h) &&
            ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){
    pFile->lastErrno = lastErrno;
    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
                     "winTruncate2", pFile->zPath);







|







33103
33104
33105
33106
33107
33108
33109
33110
33111
33112
33113
33114
33115
33116
33117
  ** size).
  */
  if( pFile->szChunk>0 ){
    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
  }

  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
  if( winSeekFile(pFile, nByte) ){
    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
                     "winTruncate1", pFile->zPath);
  }else if( 0==osSetEndOfFile(pFile->h) &&
            ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){
    pFile->lastErrno = lastErrno;
    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
                     "winTruncate2", pFile->zPath);
33101
33102
33103
33104
33105
33106
33107

33108
33109
33110
33111
33112
33113
33114
33115
33116
33117
33118
33119
33120
33121
33122
33123
33124
33125
33126
  sqlite3_sync_count++;
#endif

  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
  ** no-op
  */
#ifdef SQLITE_NO_SYNC

  return SQLITE_OK;
#else
  rc = osFlushFileBuffers(pFile->h);
  SimulateIOError( rc=FALSE );
  if( rc ){
    OSTRACE(("SYNC file=%p, rc=SQLITE_OK\n", pFile->h));
    return SQLITE_OK;
  }else{
    pFile->lastErrno = osGetLastError();
    OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h));
    return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
             "winSync", pFile->zPath);
  }
#endif
}

/*
** Determine the current size of a file in bytes
*/







>











|







33184
33185
33186
33187
33188
33189
33190
33191
33192
33193
33194
33195
33196
33197
33198
33199
33200
33201
33202
33203
33204
33205
33206
33207
33208
33209
33210
  sqlite3_sync_count++;
#endif

  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
  ** no-op
  */
#ifdef SQLITE_NO_SYNC
  OSTRACE(("SYNC-NOP file=%p, rc=SQLITE_OK\n", pFile->h));
  return SQLITE_OK;
#else
  rc = osFlushFileBuffers(pFile->h);
  SimulateIOError( rc=FALSE );
  if( rc ){
    OSTRACE(("SYNC file=%p, rc=SQLITE_OK\n", pFile->h));
    return SQLITE_OK;
  }else{
    pFile->lastErrno = osGetLastError();
    OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h));
    return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
                       "winSync", pFile->zPath);
  }
#endif
}

/*
** Determine the current size of a file in bytes
*/
33153
33154
33155
33156
33157
33158
33159
33160
33161
33162
33163
33164
33165
33166
33167

    lowerBits = osGetFileSize(pFile->h, &upperBits);
    *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
    if(   (lowerBits == INVALID_FILE_SIZE)
       && ((lastErrno = osGetLastError())!=NO_ERROR) ){
      pFile->lastErrno = lastErrno;
      rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
             "winFileSize", pFile->zPath);
    }
  }
#endif
  OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
           pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
  return rc;
}







|







33237
33238
33239
33240
33241
33242
33243
33244
33245
33246
33247
33248
33249
33250
33251

    lowerBits = osGetFileSize(pFile->h, &upperBits);
    *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
    if(   (lowerBits == INVALID_FILE_SIZE)
       && ((lastErrno = osGetLastError())!=NO_ERROR) ){
      pFile->lastErrno = lastErrno;
      rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
                       "winFileSize", pFile->zPath);
    }
  }
#endif
  OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
           pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
  return rc;
}
33198
33199
33200
33201
33202
33203
33204
33205
33206
33207
33208
33209
33210
33211
33212
33213
33214
33215
#endif

/*
** Acquire a reader lock.
** Different API routines are called depending on whether or not this
** is Win9x or WinNT.
*/
static int getReadLock(winFile *pFile){
  int res;
  OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
  if( isNT() ){
#if SQLITE_OS_WINCE
    /*
    ** NOTE: Windows CE is handled differently here due its lack of the Win32
    **       API LockFileEx.
    */
    res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
#else







|


|







33282
33283
33284
33285
33286
33287
33288
33289
33290
33291
33292
33293
33294
33295
33296
33297
33298
33299
#endif

/*
** Acquire a reader lock.
** Different API routines are called depending on whether or not this
** is Win9x or WinNT.
*/
static int winGetReadLock(winFile *pFile){
  int res;
  OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
  if( osIsNT() ){
#if SQLITE_OS_WINCE
    /*
    ** NOTE: Windows CE is handled differently here due its lack of the Win32
    **       API LockFileEx.
    */
    res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
#else
33233
33234
33235
33236
33237
33238
33239
33240
33241
33242
33243
33244
33245
33246
33247
33248
33249
33250
33251
33252
33253
33254
33255
33256
33257
33258
33259
33260
33261
33262
  OSTRACE(("READ-LOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
  return res;
}

/*
** Undo a readlock
*/
static int unlockReadLock(winFile *pFile){
  int res;
  DWORD lastErrno;
  OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
  if( isNT() ){
    res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
  }
#endif
  if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
    pFile->lastErrno = lastErrno;
    winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
             "unlockReadLock", pFile->zPath);
  }
  OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
  return res;
}

/*
** Lock the file with the lock specified by parameter locktype - one







|



|










|







33317
33318
33319
33320
33321
33322
33323
33324
33325
33326
33327
33328
33329
33330
33331
33332
33333
33334
33335
33336
33337
33338
33339
33340
33341
33342
33343
33344
33345
33346
  OSTRACE(("READ-LOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
  return res;
}

/*
** Undo a readlock
*/
static int winUnlockReadLock(winFile *pFile){
  int res;
  DWORD lastErrno;
  OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
  if( osIsNT() ){
    res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
  }
#endif
  if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
    pFile->lastErrno = lastErrno;
    winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
                "winUnlockReadLock", pFile->zPath);
  }
  OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
  return res;
}

/*
** Lock the file with the lock specified by parameter locktype - one
33339
33340
33341
33342
33343
33344
33345
33346
33347
33348
33349
33350
33351
33352
33353
    }
  }

  /* Acquire a shared lock
  */
  if( locktype==SHARED_LOCK && res ){
    assert( pFile->locktype==NO_LOCK );
    res = getReadLock(pFile);
    if( res ){
      newLocktype = SHARED_LOCK;
    }else{
      lastErrno = osGetLastError();
    }
  }








|







33423
33424
33425
33426
33427
33428
33429
33430
33431
33432
33433
33434
33435
33436
33437
    }
  }

  /* Acquire a shared lock
  */
  if( locktype==SHARED_LOCK && res ){
    assert( pFile->locktype==NO_LOCK );
    res = winGetReadLock(pFile);
    if( res ){
      newLocktype = SHARED_LOCK;
    }else{
      lastErrno = osGetLastError();
    }
  }

33370
33371
33372
33373
33374
33375
33376
33377
33378
33379
33380
33381
33382
33383
33384
33385
33386
33387
33388
33389
33390
33391
33392
33393
33394
33395
33396
33397
33398
33399
33400
33401
33402
33403
33404


33405
33406
33407
33408
33409
33410
33411
    gotPendingLock = 0;
  }

  /* Acquire an EXCLUSIVE lock
  */
  if( locktype==EXCLUSIVE_LOCK && res ){
    assert( pFile->locktype>=SHARED_LOCK );
    res = unlockReadLock(pFile);
    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
                      SHARED_SIZE, 0);
    if( res ){
      newLocktype = EXCLUSIVE_LOCK;
    }else{
      lastErrno = osGetLastError();
      getReadLock(pFile);
    }
  }

  /* If we are holding a PENDING lock that ought to be released, then
  ** release it now.
  */
  if( gotPendingLock && locktype==SHARED_LOCK ){
    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
  }

  /* Update the state of the lock has held in the file descriptor then
  ** return the appropriate result code.
  */
  if( res ){
    rc = SQLITE_OK;
  }else{
    OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
             pFile->h, locktype, newLocktype));
    pFile->lastErrno = lastErrno;
    rc = SQLITE_BUSY;


  }
  pFile->locktype = (u8)newLocktype;
  OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
  return rc;
}








|






|
















<
<


>
>







33454
33455
33456
33457
33458
33459
33460
33461
33462
33463
33464
33465
33466
33467
33468
33469
33470
33471
33472
33473
33474
33475
33476
33477
33478
33479
33480
33481
33482
33483
33484


33485
33486
33487
33488
33489
33490
33491
33492
33493
33494
33495
    gotPendingLock = 0;
  }

  /* Acquire an EXCLUSIVE lock
  */
  if( locktype==EXCLUSIVE_LOCK && res ){
    assert( pFile->locktype>=SHARED_LOCK );
    res = winUnlockReadLock(pFile);
    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
                      SHARED_SIZE, 0);
    if( res ){
      newLocktype = EXCLUSIVE_LOCK;
    }else{
      lastErrno = osGetLastError();
      winGetReadLock(pFile);
    }
  }

  /* If we are holding a PENDING lock that ought to be released, then
  ** release it now.
  */
  if( gotPendingLock && locktype==SHARED_LOCK ){
    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
  }

  /* Update the state of the lock has held in the file descriptor then
  ** return the appropriate result code.
  */
  if( res ){
    rc = SQLITE_OK;
  }else{


    pFile->lastErrno = lastErrno;
    rc = SQLITE_BUSY;
    OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
             pFile->h, locktype, newLocktype));
  }
  pFile->locktype = (u8)newLocktype;
  OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
  return rc;
}

33457
33458
33459
33460
33461
33462
33463
33464
33465
33466
33467
33468
33469
33470
33471
33472
33473
33474
33475
33476
33477
33478
33479
33480
33481
33482
  assert( pFile!=0 );
  assert( locktype<=SHARED_LOCK );
  OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n",
           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
  type = pFile->locktype;
  if( type>=EXCLUSIVE_LOCK ){
    winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
    if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
      /* This should never happen.  We should always be able to
      ** reacquire the read lock */
      rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
               "winUnlock", pFile->zPath);
    }
  }
  if( type>=RESERVED_LOCK ){
    winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
  }
  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
    unlockReadLock(pFile);
  }
  if( type>=PENDING_LOCK ){
    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
  }
  pFile->locktype = (u8)locktype;
  OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n",
           pFile->h, pFile->locktype, sqlite3ErrName(rc)));







|



|






|







33541
33542
33543
33544
33545
33546
33547
33548
33549
33550
33551
33552
33553
33554
33555
33556
33557
33558
33559
33560
33561
33562
33563
33564
33565
33566
  assert( pFile!=0 );
  assert( locktype<=SHARED_LOCK );
  OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n",
           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
  type = pFile->locktype;
  if( type>=EXCLUSIVE_LOCK ){
    winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
    if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){
      /* This should never happen.  We should always be able to
      ** reacquire the read lock */
      rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
                       "winUnlock", pFile->zPath);
    }
  }
  if( type>=RESERVED_LOCK ){
    winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
  }
  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
    winUnlockReadLock(pFile);
  }
  if( type>=PENDING_LOCK ){
    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
  }
  pFile->locktype = (u8)locktype;
  OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n",
           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
33495
33496
33497
33498
33499
33500
33501
33502
33503
33504
33505
33506

33507
33508
33509
33510
33511
33512
33513
  }else if( (*pArg)==0 ){
    pFile->ctrlFlags &= ~mask;
  }else{
    pFile->ctrlFlags |= mask;
  }
}

/* Forward declaration */
static int getTempname(int nBuf, char *zBuf);
#if SQLITE_MAX_MMAP_SIZE>0
static int winMapfile(winFile*, sqlite3_int64);
#endif


/*
** Control and query of the open file handle.
*/
static int winFileControl(sqlite3_file *id, int op, void *pArg){
  winFile *pFile = (winFile*)id;
  OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));







|
|
<
|
<
>







33579
33580
33581
33582
33583
33584
33585
33586
33587

33588

33589
33590
33591
33592
33593
33594
33595
33596
  }else if( (*pArg)==0 ){
    pFile->ctrlFlags &= ~mask;
  }else{
    pFile->ctrlFlags |= mask;
  }
}

/* Forward references to VFS helper methods used for temporary files */
static int winGetTempname(sqlite3_vfs *, char **);

static int winIsDir(const void *);

static BOOL winIsDriveLetterAndColon(const char *);

/*
** Control and query of the open file handle.
*/
static int winFileControl(sqlite3_file *id, int op, void *pArg){
  winFile *pFile = (winFile*)id;
  OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));
33559
33560
33561
33562
33563
33564
33565
33566
33567
33568
33569
33570
33571
33572
33573
33574
33575
33576
33577
33578
33579
33580
33581

33582
33583
33584
33585
33586
33587
33588
33589
33590
33591
33592
33593
33594
33595
33596
33597
33598
33599
33600
33601
33602
33603
33604
33605
33606
33607
33608
33609
      *(char**)pArg = sqlite3_mprintf("win32");
      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_WIN32_AV_RETRY: {
      int *a = (int*)pArg;
      if( a[0]>0 ){
        win32IoerrRetry = a[0];
      }else{
        a[0] = win32IoerrRetry;
      }
      if( a[1]>0 ){
        win32IoerrRetryDelay = a[1];
      }else{
        a[1] = win32IoerrRetryDelay;
      }
      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_TEMPFILENAME: {
      char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname );
      if( zTFile ){
        getTempname(pFile->pVfs->mxPathname, zTFile);

        *(char**)pArg = zTFile;
      }
      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
      return SQLITE_OK;
    }
#if SQLITE_MAX_MMAP_SIZE>0
    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;
      int rc = SQLITE_OK;
      if( newLimit>sqlite3GlobalConfig.mxMmap ){
        newLimit = sqlite3GlobalConfig.mxMmap;
      }
      *(i64*)pArg = pFile->mmapSizeMax;
      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
        pFile->mmapSizeMax = newLimit;
        if( pFile->mmapSize>0 ){
          (void)winUnmapfile(pFile);
          rc = winMapfile(pFile, -1);
        }
      }
      OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc));
      return rc;
    }
#endif
  }
  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
  return SQLITE_NOTFOUND;
}







|

|


|

|





|
<
|
>


|
|
















|







33642
33643
33644
33645
33646
33647
33648
33649
33650
33651
33652
33653
33654
33655
33656
33657
33658
33659
33660
33661
33662

33663
33664
33665
33666
33667
33668
33669
33670
33671
33672
33673
33674
33675
33676
33677
33678
33679
33680
33681
33682
33683
33684
33685
33686
33687
33688
33689
33690
33691
33692
      *(char**)pArg = sqlite3_mprintf("win32");
      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_WIN32_AV_RETRY: {
      int *a = (int*)pArg;
      if( a[0]>0 ){
        winIoerrRetry = a[0];
      }else{
        a[0] = winIoerrRetry;
      }
      if( a[1]>0 ){
        winIoerrRetryDelay = a[1];
      }else{
        a[1] = winIoerrRetryDelay;
      }
      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_TEMPFILENAME: {
      char *zTFile = 0;

      int rc = winGetTempname(pFile->pVfs, &zTFile);
      if( rc==SQLITE_OK ){
        *(char**)pArg = zTFile;
      }
      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
      return rc;
    }
#if SQLITE_MAX_MMAP_SIZE>0
    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;
      int rc = SQLITE_OK;
      if( newLimit>sqlite3GlobalConfig.mxMmap ){
        newLimit = sqlite3GlobalConfig.mxMmap;
      }
      *(i64*)pArg = pFile->mmapSizeMax;
      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
        pFile->mmapSizeMax = newLimit;
        if( pFile->mmapSize>0 ){
          (void)winUnmapfile(pFile);
          rc = winMapfile(pFile, -1);
        }
      }
      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
      return rc;
    }
#endif
  }
  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
  return SQLITE_NOTFOUND;
}
33911
33912
33913
33914
33915
33916
33917
33918
33919
33920
33921
33922
33923
33924
33925
    /* Check to see if another process is holding the dead-man switch.
    ** If not, truncate the file to zero length. 
    */
    if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
      if( rc!=SQLITE_OK ){
        rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
                 "winOpenShm", pDbFd->zPath);
      }
    }
    if( rc==SQLITE_OK ){
      winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
      rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
    }
    if( rc ) goto shm_open_err;







|







33994
33995
33996
33997
33998
33999
34000
34001
34002
34003
34004
34005
34006
34007
34008
    /* Check to see if another process is holding the dead-man switch.
    ** If not, truncate the file to zero length. 
    */
    if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
      if( rc!=SQLITE_OK ){
        rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
                         "winOpenShm", pDbFd->zPath);
      }
    }
    if( rc==SQLITE_OK ){
      winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
      rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
    }
    if( rc ) goto shm_open_err;
34171
34172
34173
34174
34175
34176
34177
34178
34179
34180
34181
34182
34183
34184
34185
34186
34187
34188
34189
34190
34191
34192
34193
34194
34195
34196
34197
34198
34199
34200
    /* The requested region is not mapped into this processes address space.
    ** Check to see if it has been allocated (i.e. if the wal-index file is
    ** large enough to contain the requested region).
    */
    rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
    if( rc!=SQLITE_OK ){
      rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
               "winShmMap1", pDbFd->zPath);
      goto shmpage_out;
    }

    if( sz<nByte ){
      /* The requested memory region does not exist. If isWrite is set to
      ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
      **
      ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
      ** the requested memory region.
      */
      if( !isWrite ) goto shmpage_out;
      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
      if( rc!=SQLITE_OK ){
        rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
                 "winShmMap2", pDbFd->zPath);
        goto shmpage_out;
      }
    }

    /* Map the requested memory region into this processes address space. */
    apNew = (struct ShmRegion *)sqlite3_realloc(
        pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])







|














|







34254
34255
34256
34257
34258
34259
34260
34261
34262
34263
34264
34265
34266
34267
34268
34269
34270
34271
34272
34273
34274
34275
34276
34277
34278
34279
34280
34281
34282
34283
    /* The requested region is not mapped into this processes address space.
    ** Check to see if it has been allocated (i.e. if the wal-index file is
    ** large enough to contain the requested region).
    */
    rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
    if( rc!=SQLITE_OK ){
      rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
                       "winShmMap1", pDbFd->zPath);
      goto shmpage_out;
    }

    if( sz<nByte ){
      /* The requested memory region does not exist. If isWrite is set to
      ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
      **
      ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
      ** the requested memory region.
      */
      if( !isWrite ) goto shmpage_out;
      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
      if( rc!=SQLITE_OK ){
        rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
                         "winShmMap2", pDbFd->zPath);
        goto shmpage_out;
      }
    }

    /* Map the requested memory region into this processes address space. */
    apNew = (struct ShmRegion *)sqlite3_realloc(
        pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
34240
34241
34242
34243
34244
34245
34246
34247
34248
34249
34250
34251
34252
34253
34254
        OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n",
                 osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
                 szRegion, pMap ? "ok" : "failed"));
      }
      if( !pMap ){
        pShmNode->lastErrno = osGetLastError();
        rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
                 "winShmMap3", pDbFd->zPath);
        if( hMap ) osCloseHandle(hMap);
        goto shmpage_out;
      }

      pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
      pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
      pShmNode->nRegion++;







|







34323
34324
34325
34326
34327
34328
34329
34330
34331
34332
34333
34334
34335
34336
34337
        OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n",
                 osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
                 szRegion, pMap ? "ok" : "failed"));
      }
      if( !pMap ){
        pShmNode->lastErrno = osGetLastError();
        rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
                         "winShmMap3", pDbFd->zPath);
        if( hMap ) osCloseHandle(hMap);
        goto shmpage_out;
      }

      pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
      pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
      pShmNode->nRegion++;
34288
34289
34290
34291
34292
34293
34294
34295
34296
34297
34298
34299
34300
34301
34302
34303
34304
34305
34306
34307
34308
34309
34310
34311
34312
34313
34314
  if( pFile->pMapRegion ){
    if( !osUnmapViewOfFile(pFile->pMapRegion) ){
      pFile->lastErrno = osGetLastError();
      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
               pFile->pMapRegion));
      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
                         "winUnmap1", pFile->zPath);
    }
    pFile->pMapRegion = 0;
    pFile->mmapSize = 0;
    pFile->mmapSizeActual = 0;
  }
  if( pFile->hMap!=NULL ){
    if( !osCloseHandle(pFile->hMap) ){
      pFile->lastErrno = osGetLastError();
      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
               osGetCurrentProcessId(), pFile, pFile->hMap));
      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
                         "winUnmap2", pFile->zPath);
    }
    pFile->hMap = NULL;
  }
  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
           osGetCurrentProcessId(), pFile));
  return SQLITE_OK;
}







|











|







34371
34372
34373
34374
34375
34376
34377
34378
34379
34380
34381
34382
34383
34384
34385
34386
34387
34388
34389
34390
34391
34392
34393
34394
34395
34396
34397
  if( pFile->pMapRegion ){
    if( !osUnmapViewOfFile(pFile->pMapRegion) ){
      pFile->lastErrno = osGetLastError();
      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
               pFile->pMapRegion));
      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
                         "winUnmapfile1", pFile->zPath);
    }
    pFile->pMapRegion = 0;
    pFile->mmapSize = 0;
    pFile->mmapSizeActual = 0;
  }
  if( pFile->hMap!=NULL ){
    if( !osCloseHandle(pFile->hMap) ){
      pFile->lastErrno = osGetLastError();
      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
               osGetCurrentProcessId(), pFile, pFile->hMap));
      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
                         "winUnmapfile2", pFile->zPath);
    }
    pFile->hMap = NULL;
  }
  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
           osGetCurrentProcessId(), pFile));
  return SQLITE_OK;
}
34375
34376
34377
34378
34379
34380
34381
34382
34383
34384
34385
34386
34387
34388

34389
34390
34391
34392
34393
34394
34395
34396
34397
34398
34399
34400

34401
34402
34403
34404
34405
34406
34407
34408
34409
    pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
                                (DWORD)((nMap>>32) & 0xffffffff),
                                (DWORD)(nMap & 0xffffffff), NULL);
#endif
    if( pFd->hMap==NULL ){
      pFd->lastErrno = osGetLastError();
      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
                       "winMapfile", pFd->zPath);
      /* Log the error, but continue normal operation using xRead/xWrite */
      OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
               osGetCurrentProcessId(), pFd));
      return SQLITE_OK;
    }
    assert( (nMap % winSysInfo.dwPageSize)==0 );

#if SQLITE_OS_WINRT
    pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap);
#else
    assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
    pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
#endif
    if( pNew==NULL ){
      osCloseHandle(pFd->hMap);
      pFd->hMap = NULL;
      pFd->lastErrno = osGetLastError();
      winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
                  "winMapfile", pFd->zPath);

      OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
               osGetCurrentProcessId(), pFd));
      return SQLITE_OK;
    }
    pFd->pMapRegion = pNew;
    pFd->mmapSize = nMap;
    pFd->mmapSizeActual = nMap;
  }








|

|
|



>

|

<






|
|
>
|
|







34458
34459
34460
34461
34462
34463
34464
34465
34466
34467
34468
34469
34470
34471
34472
34473
34474
34475

34476
34477
34478
34479
34480
34481
34482
34483
34484
34485
34486
34487
34488
34489
34490
34491
34492
34493
    pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
                                (DWORD)((nMap>>32) & 0xffffffff),
                                (DWORD)(nMap & 0xffffffff), NULL);
#endif
    if( pFd->hMap==NULL ){
      pFd->lastErrno = osGetLastError();
      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
                       "winMapfile1", pFd->zPath);
      /* Log the error, but continue normal operation using xRead/xWrite */
      OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n",
               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
      return SQLITE_OK;
    }
    assert( (nMap % winSysInfo.dwPageSize)==0 );
    assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
#if SQLITE_OS_WINRT
    pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
#else

    pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
#endif
    if( pNew==NULL ){
      osCloseHandle(pFd->hMap);
      pFd->hMap = NULL;
      pFd->lastErrno = osGetLastError();
      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
                       "winMapfile2", pFd->zPath);
      /* Log the error, but continue normal operation using xRead/xWrite */
      OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n",
               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
      return SQLITE_OK;
    }
    pFd->pMapRegion = pNew;
    pFd->mmapSize = nMap;
    pFd->mmapSizeActual = nMap;
  }

34533
34534
34535
34536
34537
34538
34539



















34540
34541
34542
34543
34544
34545
34546
34547
34548
34549
34550
34551
34552
34553
34554
34555
34556
34557
34558
34559
34560
34561




34562





34563



34564
34565
34566
34567
34568
34569
34570
34571
34572
34573
34574
34575
34576
34577
34578
34579



34580




34581






34582

34583

34584



















































































34585
34586
34587

34588




34589






34590
34591
34592
34593

34594


34595
34596
34597
34598
34599
34600
34601

34602




34603





34604
34605
34606
34607
34608

34609
34610
34611
34612
34613
34614
34615
34616
34617
34618
34619
34620
34621

34622
34623
34624
34625
34626
34627
34628
34629
34630
34631
34632
34633
34634
34635
34636
34637
34638

34639
34640
34641
34642
34643
34644
34645
34646
34647
34648
34649
34650
34651
34652
34653
34654
34655
34656
34657
34658
34659
34660
34661
34662
34663
34664
34665
34666
34667
34668
34669
34670
34671
34672
34673
34674
34675
34676
34677
34678
34679
34680
34681
34682
34683
34684

/****************************************************************************
**************************** sqlite3_vfs methods ****************************
**
** This division contains the implementation of methods on the
** sqlite3_vfs object.
*/




















/*
** Convert a UTF-8 filename into whatever form the underlying
** operating system wants filenames in.  Space to hold the result
** is obtained from malloc and must be freed by the calling
** function.
*/
static void *convertUtf8Filename(const char *zFilename){
  void *zConverted = 0;
  if( isNT() ){
    zConverted = utf8ToUnicode(zFilename);
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
  }
#endif
  /* caller will handle out of memory */
  return zConverted;
}

/*




** Create a temporary file name in zBuf.  zBuf must be big enough to





** hold at pVfs->mxPathname characters.



*/
static int getTempname(int nBuf, char *zBuf){
  static char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  size_t i, j;
  int nTempPath;
  char zTempPath[MAX_PATH+2];

  /* It's odd to simulate an io-error here, but really this is just
  ** using the io-error infrastructure to test that SQLite handles this
  ** function failing. 
  */
  SimulateIOError( return SQLITE_IOERR );




  memset(zTempPath, 0, MAX_PATH+2);











  if( sqlite3_temp_directory ){

    sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);

  }



















































































#if !SQLITE_OS_WINRT
  else if( isNT() ){
    char *zMulti;

    WCHAR zWidePath[MAX_PATH];




    osGetTempPathW(MAX_PATH-30, zWidePath);






    zMulti = unicodeToUtf8(zWidePath);
    if( zMulti ){
      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
      sqlite3_free(zMulti);

    }else{


      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
      return SQLITE_IOERR_NOMEM;
    }
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    char *zUtf8;

    char zMbcsPath[MAX_PATH];




    osGetTempPathA(MAX_PATH-30, zMbcsPath);





    zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
    if( zUtf8 ){
      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
      sqlite3_free(zUtf8);
    }else{

      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
      return SQLITE_IOERR_NOMEM;
    }
  }
#endif
#endif

  /* Check that the output buffer is large enough for the temporary file 
  ** name. If it is not, return SQLITE_ERROR.
  */
  nTempPath = sqlite3Strlen30(zTempPath);

  if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){

    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
    return SQLITE_ERROR;
  }

  for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){}
  zTempPath[i] = 0;

  sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ?
                       "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX,
                   zTempPath);
  j = sqlite3Strlen30(zBuf);
  sqlite3_randomness(15, &zBuf[j]);
  for(i=0; i<15; i++, j++){
    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
  }
  zBuf[j] = 0;
  zBuf[j+1] = 0;


  OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
  return SQLITE_OK;
}

/*
** Return TRUE if the named file is really a directory.  Return false if
** it is something other than a directory, or if there is any kind of memory
** allocation failure.
*/
static int winIsDir(const void *zConverted){
  DWORD attr;
  int rc = 0;
  DWORD lastErrno;

  if( isNT() ){
    int cnt = 0;
    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
    memset(&sAttrData, 0, sizeof(sAttrData));
    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
                             GetFileExInfoStandard,
                             &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
    if( !rc ){
      return 0; /* Invalid name? */
    }
    attr = sAttrData.dwFileAttributes;
#if SQLITE_OS_WINCE==0
  }else{
    attr = osGetFileAttributesA((char*)zConverted);
#endif
  }
  return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
}

/*
** Open a file.
*/
static int winOpen(
  sqlite3_vfs *pVfs,        /* Not used */
  const char *zName,        /* Name of the file (UTF-8) */
  sqlite3_file *id,         /* Write the SQLite file handle here */
  int flags,                /* Open mode flags */
  int *pOutFlags            /* Status return flags */
){
  HANDLE h;
  DWORD lastErrno;







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







|

|
|











>
>
>
>
|
>
>
>
>
>
|
>
>
>

|





|
|







>
>
>
|
>
>
>
>
|
>
>
>
>
>
>

>
|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

>
|
>
>
>
>
|
>
>
>
>
>
>
|

|

>

>
>







>
|
>
>
>
>
|
>
>
>
>
>


|


>




|
|




|

|
>

|


<
|

<
<
<







>















|





|
















|







34617
34618
34619
34620
34621
34622
34623
34624
34625
34626
34627
34628
34629
34630
34631
34632
34633
34634
34635
34636
34637
34638
34639
34640
34641
34642
34643
34644
34645
34646
34647
34648
34649
34650
34651
34652
34653
34654
34655
34656
34657
34658
34659
34660
34661
34662
34663
34664
34665
34666
34667
34668
34669
34670
34671
34672
34673
34674
34675
34676
34677
34678
34679
34680
34681
34682
34683
34684
34685
34686
34687
34688
34689
34690
34691
34692
34693
34694
34695
34696
34697
34698
34699
34700
34701
34702
34703
34704
34705
34706
34707
34708
34709
34710
34711
34712
34713
34714
34715
34716
34717
34718
34719
34720
34721
34722
34723
34724
34725
34726
34727
34728
34729
34730
34731
34732
34733
34734
34735
34736
34737
34738
34739
34740
34741
34742
34743
34744
34745
34746
34747
34748
34749
34750
34751
34752
34753
34754
34755
34756
34757
34758
34759
34760
34761
34762
34763
34764
34765
34766
34767
34768
34769
34770
34771
34772
34773
34774
34775
34776
34777
34778
34779
34780
34781
34782
34783
34784
34785
34786
34787
34788
34789
34790
34791
34792
34793
34794
34795
34796
34797
34798
34799
34800
34801
34802
34803
34804
34805
34806
34807
34808
34809
34810
34811
34812
34813
34814
34815
34816
34817
34818
34819
34820
34821
34822
34823
34824
34825
34826
34827
34828
34829
34830
34831
34832
34833
34834
34835
34836
34837
34838
34839
34840
34841
34842
34843
34844
34845
34846
34847
34848
34849
34850
34851
34852
34853
34854
34855
34856
34857
34858
34859
34860
34861
34862
34863
34864

34865
34866



34867
34868
34869
34870
34871
34872
34873
34874
34875
34876
34877
34878
34879
34880
34881
34882
34883
34884
34885
34886
34887
34888
34889
34890
34891
34892
34893
34894
34895
34896
34897
34898
34899
34900
34901
34902
34903
34904
34905
34906
34907
34908
34909
34910
34911
34912
34913
34914
34915
34916
34917
34918
34919
34920

/****************************************************************************
**************************** sqlite3_vfs methods ****************************
**
** This division contains the implementation of methods on the
** sqlite3_vfs object.
*/

/*
** Convert a filename from whatever the underlying operating system
** supports for filenames into UTF-8.  Space to hold the result is
** obtained from malloc and must be freed by the calling function.
*/
static char *winConvertToUtf8Filename(const void *zFilename){
  char *zConverted = 0;
  if( osIsNT() ){
    zConverted = winUnicodeToUtf8(zFilename);
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
  }
#endif
  /* caller will handle out of memory */
  return zConverted;
}

/*
** Convert a UTF-8 filename into whatever form the underlying
** operating system wants filenames in.  Space to hold the result
** is obtained from malloc and must be freed by the calling
** function.
*/
static void *winConvertFromUtf8Filename(const char *zFilename){
  void *zConverted = 0;
  if( osIsNT() ){
    zConverted = winUtf8ToUnicode(zFilename);
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
  }
#endif
  /* caller will handle out of memory */
  return zConverted;
}

/*
** This function returns non-zero if the specified UTF-8 string buffer
** ends with a directory separator character.
*/
static int winEndsInDirSep(char *zBuf){
  if( zBuf ){
    int nLen = sqlite3Strlen30(zBuf);
    return nLen>0 && winIsDirSep(zBuf[nLen-1]);
  }
  return 0;
}

/*
** Create a temporary file name and store the resulting pointer into pzBuf.
** The pointer returned in pzBuf must be freed via sqlite3_free().
*/
static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
  static char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  size_t i, j;
  int nBuf, nLen;
  char *zBuf;

  /* It's odd to simulate an io-error here, but really this is just
  ** using the io-error infrastructure to test that SQLite handles this
  ** function failing. 
  */
  SimulateIOError( return SQLITE_IOERR );

  /* Allocate a temporary buffer to store the fully qualified file
  ** name for the temporary file.  If this fails, we cannot continue.
  */
  nBuf = pVfs->mxPathname;
  zBuf = sqlite3MallocZero( nBuf+2 );
  if( !zBuf ){
    OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
    return SQLITE_IOERR_NOMEM;
  }

  /* Figure out the effective temporary directory.  First, check if one
  ** has been explicitly set by the application; otherwise, use the one
  ** configured by the operating system.
  */
  assert( nBuf>30 );
  if( sqlite3_temp_directory ){
    sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory,
                     winEndsInDirSep(sqlite3_temp_directory) ? "" :
                     winGetDirDep());
  }
#if defined(__CYGWIN__)
  else{
    static const char *azDirs[] = {
       0, /* getenv("SQLITE_TMPDIR") */
       0, /* getenv("TMPDIR") */
       0, /* getenv("TMP") */
       0, /* getenv("TEMP") */
       0, /* getenv("USERPROFILE") */
       "/var/tmp",
       "/usr/tmp",
       "/tmp",
       ".",
       0        /* List terminator */
    };
    unsigned int i;
    const char *zDir = 0;

    if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
    if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
    if( !azDirs[2] ) azDirs[2] = getenv("TMP");
    if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
    if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
    for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
      void *zConverted;
      if( zDir==0 ) continue;
      /* If the path starts with a drive letter followed by the colon
      ** character, assume it is already a native Win32 path; otherwise,
      ** it must be converted to a native Win32 path prior via the Cygwin
      ** API prior to using it.
      */
      if( winIsDriveLetterAndColon(zDir) ){
        zConverted = winConvertFromUtf8Filename(zDir);
        if( !zConverted ){
          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
          return SQLITE_IOERR_NOMEM;
        }
        if( winIsDir(zConverted) ){
          sqlite3_snprintf(nBuf-30, zBuf, "%s", zDir);
          sqlite3_free(zConverted);
          break;
        }
        sqlite3_free(zConverted);
      }else{
        zConverted = sqlite3MallocZero( nBuf+1 );
        if( !zConverted ){
          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
          return SQLITE_IOERR_NOMEM;
        }
        if( cygwin_conv_path(
                osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
                zConverted, nBuf+1)<0 ){
          sqlite3_free(zConverted);
          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
          return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
                             "winGetTempname1", zDir);
        }
        if( winIsDir(zConverted) ){
          /* At this point, we know the candidate directory exists and should
          ** be used.  However, we may need to convert the string containing
          ** its name into UTF-8 (i.e. if it is UTF-16 right now).
          */
          if( osIsNT() ){
            char *zUtf8 = winUnicodeToUtf8(zConverted);
            if( !zUtf8 ){
              sqlite3_free(zConverted);
              OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
              return SQLITE_IOERR_NOMEM;
            }
            sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
            sqlite3_free(zUtf8);
            sqlite3_free(zConverted);
            break;
          }else{
            sqlite3_snprintf(nBuf-30, zBuf, "%s", zConverted);
            sqlite3_free(zConverted);
            break;
          }
        }
        sqlite3_free(zConverted);
      }
      break;
    }
  }
#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
  else if( osIsNT() ){
    char *zMulti;
    LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) );
    if( !zWidePath ){
      sqlite3_free(zBuf);
      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
      return SQLITE_IOERR_NOMEM;
    }
    if( osGetTempPathW(nBuf, zWidePath)==0 ){
      sqlite3_free(zWidePath);
      sqlite3_free(zBuf);
      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
                         "winGetTempname1", 0);
    }
    zMulti = winUnicodeToUtf8(zWidePath);
    if( zMulti ){
      sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti);
      sqlite3_free(zMulti);
      sqlite3_free(zWidePath);
    }else{
      sqlite3_free(zWidePath);
      sqlite3_free(zBuf);
      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
      return SQLITE_IOERR_NOMEM;
    }
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    char *zUtf8;
    char *zMbcsPath = sqlite3MallocZero( nBuf );
    if( !zMbcsPath ){
      sqlite3_free(zBuf);
      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
      return SQLITE_IOERR_NOMEM;
    }
    if( osGetTempPathA(nBuf, zMbcsPath)==0 ){
      sqlite3_free(zBuf);
      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
                         "winGetTempname2", 0);
    }
    zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
    if( zUtf8 ){
      sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8);
      sqlite3_free(zUtf8);
    }else{
      sqlite3_free(zBuf);
      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
      return SQLITE_IOERR_NOMEM;
    }
  }
#endif /* SQLITE_WIN32_HAS_ANSI */
#endif /* !SQLITE_OS_WINRT */

  /* Check that the output buffer is large enough for the temporary file 
  ** name. If it is not, return SQLITE_ERROR.
  */
  nLen = sqlite3Strlen30(zBuf);

  if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
    sqlite3_free(zBuf);
    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
    return winLogError(SQLITE_ERROR, 0, "winGetTempname3", 0);
  }


  sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);




  j = sqlite3Strlen30(zBuf);
  sqlite3_randomness(15, &zBuf[j]);
  for(i=0; i<15; i++, j++){
    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
  }
  zBuf[j] = 0;
  zBuf[j+1] = 0;
  *pzBuf = zBuf;

  OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
  return SQLITE_OK;
}

/*
** Return TRUE if the named file is really a directory.  Return false if
** it is something other than a directory, or if there is any kind of memory
** allocation failure.
*/
static int winIsDir(const void *zConverted){
  DWORD attr;
  int rc = 0;
  DWORD lastErrno;

  if( osIsNT() ){
    int cnt = 0;
    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
    memset(&sAttrData, 0, sizeof(sAttrData));
    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
                             GetFileExInfoStandard,
                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
    if( !rc ){
      return 0; /* Invalid name? */
    }
    attr = sAttrData.dwFileAttributes;
#if SQLITE_OS_WINCE==0
  }else{
    attr = osGetFileAttributesA((char*)zConverted);
#endif
  }
  return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
}

/*
** Open a file.
*/
static int winOpen(
  sqlite3_vfs *pVfs,        /* Used to get maximum path name length */
  const char *zName,        /* Name of the file (UTF-8) */
  sqlite3_file *id,         /* Write the SQLite file handle here */
  int flags,                /* Open mode flags */
  int *pOutFlags            /* Status return flags */
){
  HANDLE h;
  DWORD lastErrno;
34693
34694
34695
34696
34697
34698
34699
34700
34701
34702
34703
34704
34705
34706
34707
  void *zConverted;              /* Filename in OS encoding */
  const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
  int cnt = 0;

  /* If argument zPath is a NULL pointer, this function is required to open
  ** a temporary file. Use this buffer to store the file name in.
  */
  char zTmpname[MAX_PATH+2];     /* Buffer used to create temp filename */

  int rc = SQLITE_OK;            /* Function Return Code */
#if !defined(NDEBUG) || SQLITE_OS_WINCE
  int eType = flags&0xFFFFFF00;  /* Type of file to open */
#endif

  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);







|







34929
34930
34931
34932
34933
34934
34935
34936
34937
34938
34939
34940
34941
34942
34943
  void *zConverted;              /* Filename in OS encoding */
  const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
  int cnt = 0;

  /* If argument zPath is a NULL pointer, this function is required to open
  ** a temporary file. Use this buffer to store the file name in.
  */
  char *zTmpname = 0; /* For temporary filename, if necessary. */

  int rc = SQLITE_OK;            /* Function Return Code */
#if !defined(NDEBUG) || SQLITE_OS_WINCE
  int eType = flags&0xFFFFFF00;  /* Type of file to open */
#endif

  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
34748
34749
34750
34751
34752
34753
34754
34755
34756
34757
34758
34759
34760
34761
34762
34763
34764
34765
34766
34767
34768
34769
34770
34771
34772
34773
34774
34775
34776
34777
34778
34779
34780
34781
34782
34783
34784

34785
34786
34787
34788
34789
34790

34791
34792
34793
34794
34795
34796
34797
  );

  assert( pFile!=0 );
  memset(pFile, 0, sizeof(winFile));
  pFile->h = INVALID_HANDLE_VALUE;

#if SQLITE_OS_WINRT
  if( !sqlite3_temp_directory ){
    sqlite3_log(SQLITE_ERROR,
        "sqlite3_temp_directory variable should be set for WinRT");
  }
#endif

  /* If the second argument to this function is NULL, generate a 
  ** temporary file name to use 
  */
  if( !zUtf8Name ){
    assert(isDelete && !isOpenJournal);
    memset(zTmpname, 0, MAX_PATH+2);
    rc = getTempname(MAX_PATH+2, zTmpname);
    if( rc!=SQLITE_OK ){
      OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
      return rc;
    }
    zUtf8Name = zTmpname;
  }

  /* Database filenames are double-zero terminated if they are not
  ** URIs with parameters.  Hence, they can always be passed into
  ** sqlite3_uri_parameter().
  */
  assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
        zUtf8Name[strlen(zUtf8Name)+1]==0 );

  /* Convert the filename to the system encoding. */
  zConverted = convertUtf8Filename(zUtf8Name);
  if( zConverted==0 ){

    OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
    return SQLITE_IOERR_NOMEM;
  }

  if( winIsDir(zConverted) ){
    sqlite3_free(zConverted);

    OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
    return SQLITE_CANTOPEN_ISDIR;
  }

  if( isReadWrite ){
    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
  }else{







|









|
<
|












|


|

>






>







34984
34985
34986
34987
34988
34989
34990
34991
34992
34993
34994
34995
34996
34997
34998
34999
35000
35001

35002
35003
35004
35005
35006
35007
35008
35009
35010
35011
35012
35013
35014
35015
35016
35017
35018
35019
35020
35021
35022
35023
35024
35025
35026
35027
35028
35029
35030
35031
35032
35033
35034
  );

  assert( pFile!=0 );
  memset(pFile, 0, sizeof(winFile));
  pFile->h = INVALID_HANDLE_VALUE;

#if SQLITE_OS_WINRT
  if( !zUtf8Name && !sqlite3_temp_directory ){
    sqlite3_log(SQLITE_ERROR,
        "sqlite3_temp_directory variable should be set for WinRT");
  }
#endif

  /* If the second argument to this function is NULL, generate a 
  ** temporary file name to use 
  */
  if( !zUtf8Name ){
    assert( isDelete && !isOpenJournal );

    rc = winGetTempname(pVfs, &zTmpname);
    if( rc!=SQLITE_OK ){
      OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
      return rc;
    }
    zUtf8Name = zTmpname;
  }

  /* Database filenames are double-zero terminated if they are not
  ** URIs with parameters.  Hence, they can always be passed into
  ** sqlite3_uri_parameter().
  */
  assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
       zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );

  /* Convert the filename to the system encoding. */
  zConverted = winConvertFromUtf8Filename(zUtf8Name);
  if( zConverted==0 ){
    sqlite3_free(zTmpname);
    OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
    return SQLITE_IOERR_NOMEM;
  }

  if( winIsDir(zConverted) ){
    sqlite3_free(zConverted);
    sqlite3_free(zTmpname);
    OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
    return SQLITE_CANTOPEN_ISDIR;
  }

  if( isReadWrite ){
    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
  }else{
34830
34831
34832
34833
34834
34835
34836
34837
34838
34839
34840
34841
34842
34843
34844
34845
34846
34847
34848
34849
34850
34851
34852
34853
34854
34855
34856
34857
34858
34859
34860
34861
34862
34863
34864
34865
34866
34867
34868
34869
34870
34871
34872
34873
34874
34875
34876
34877
34878
34879
34880
34881
34882
34883
34884
34885
34886
34887
34888

34889
34890
34891
34892
34893
34894
34895
  }
  /* Reports from the internet are that performance is always
  ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
#if SQLITE_OS_WINCE
  dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
#endif

  if( isNT() ){
#if SQLITE_OS_WINRT
    CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
    extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
    extendedParameters.dwFileAttributes =
            dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK;
    extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK;
    extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
    extendedParameters.lpSecurityAttributes = NULL;
    extendedParameters.hTemplateFile = NULL;
    while( (h = osCreateFile2((LPCWSTR)zConverted,
                              dwDesiredAccess,
                              dwShareMode,
                              dwCreationDisposition,
                              &extendedParameters))==INVALID_HANDLE_VALUE &&
                              retryIoerr(&cnt, &lastErrno) ){
               /* Noop */
    }
#else
    while( (h = osCreateFileW((LPCWSTR)zConverted,
                              dwDesiredAccess,
                              dwShareMode, NULL,
                              dwCreationDisposition,
                              dwFlagsAndAttributes,
                              NULL))==INVALID_HANDLE_VALUE &&
                              retryIoerr(&cnt, &lastErrno) ){
               /* Noop */
    }
#endif
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    while( (h = osCreateFileA((LPCSTR)zConverted,
                              dwDesiredAccess,
                              dwShareMode, NULL,
                              dwCreationDisposition,
                              dwFlagsAndAttributes,
                              NULL))==INVALID_HANDLE_VALUE &&
                              retryIoerr(&cnt, &lastErrno) ){
               /* Noop */
    }
  }
#endif
  logIoerr(cnt);

  OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
           dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));

  if( h==INVALID_HANDLE_VALUE ){
    pFile->lastErrno = lastErrno;
    winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
    sqlite3_free(zConverted);

    if( isReadWrite && !isExclusive ){
      return winOpen(pVfs, zName, id, 
         ((flags|SQLITE_OPEN_READONLY) &
                     ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
         pOutFlags);
    }else{
      return SQLITE_CANTOPEN_BKPT;







|














|









|












|




|








>







35067
35068
35069
35070
35071
35072
35073
35074
35075
35076
35077
35078
35079
35080
35081
35082
35083
35084
35085
35086
35087
35088
35089
35090
35091
35092
35093
35094
35095
35096
35097
35098
35099
35100
35101
35102
35103
35104
35105
35106
35107
35108
35109
35110
35111
35112
35113
35114
35115
35116
35117
35118
35119
35120
35121
35122
35123
35124
35125
35126
35127
35128
35129
35130
35131
35132
35133
  }
  /* Reports from the internet are that performance is always
  ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
#if SQLITE_OS_WINCE
  dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
#endif

  if( osIsNT() ){
#if SQLITE_OS_WINRT
    CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
    extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
    extendedParameters.dwFileAttributes =
            dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK;
    extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK;
    extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
    extendedParameters.lpSecurityAttributes = NULL;
    extendedParameters.hTemplateFile = NULL;
    while( (h = osCreateFile2((LPCWSTR)zConverted,
                              dwDesiredAccess,
                              dwShareMode,
                              dwCreationDisposition,
                              &extendedParameters))==INVALID_HANDLE_VALUE &&
                              winRetryIoerr(&cnt, &lastErrno) ){
               /* Noop */
    }
#else
    while( (h = osCreateFileW((LPCWSTR)zConverted,
                              dwDesiredAccess,
                              dwShareMode, NULL,
                              dwCreationDisposition,
                              dwFlagsAndAttributes,
                              NULL))==INVALID_HANDLE_VALUE &&
                              winRetryIoerr(&cnt, &lastErrno) ){
               /* Noop */
    }
#endif
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    while( (h = osCreateFileA((LPCSTR)zConverted,
                              dwDesiredAccess,
                              dwShareMode, NULL,
                              dwCreationDisposition,
                              dwFlagsAndAttributes,
                              NULL))==INVALID_HANDLE_VALUE &&
                              winRetryIoerr(&cnt, &lastErrno) ){
               /* Noop */
    }
  }
#endif
  winLogIoerr(cnt);

  OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
           dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));

  if( h==INVALID_HANDLE_VALUE ){
    pFile->lastErrno = lastErrno;
    winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
    sqlite3_free(zConverted);
    sqlite3_free(zTmpname);
    if( isReadWrite && !isExclusive ){
      return winOpen(pVfs, zName, id, 
         ((flags|SQLITE_OPEN_READONLY) &
                     ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
         pOutFlags);
    }else{
      return SQLITE_CANTOPEN_BKPT;
34910
34911
34912
34913
34914
34915
34916

34917
34918
34919
34920
34921
34922
34923
34924
34925

34926
34927
34928
34929
34930
34931
34932

#if SQLITE_OS_WINCE
  if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
       && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
  ){
    osCloseHandle(h);
    sqlite3_free(zConverted);

    OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
    return rc;
  }
  if( isTemp ){
    pFile->zDeleteOnClose = zConverted;
  }else
#endif
  {
    sqlite3_free(zConverted);

  }

  pFile->pMethod = &winIoMethod;
  pFile->pVfs = pVfs;
  pFile->h = h;
  if( isReadonly ){
    pFile->ctrlFlags |= WINFILE_RDONLY;







>









>







35148
35149
35150
35151
35152
35153
35154
35155
35156
35157
35158
35159
35160
35161
35162
35163
35164
35165
35166
35167
35168
35169
35170
35171
35172

#if SQLITE_OS_WINCE
  if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
       && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
  ){
    osCloseHandle(h);
    sqlite3_free(zConverted);
    sqlite3_free(zTmpname);
    OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
    return rc;
  }
  if( isTemp ){
    pFile->zDeleteOnClose = zConverted;
  }else
#endif
  {
    sqlite3_free(zConverted);
    sqlite3_free(zTmpname);
  }

  pFile->pMethod = &winIoMethod;
  pFile->pVfs = pVfs;
  pFile->h = h;
  if( isReadonly ){
    pFile->ctrlFlags |= WINFILE_RDONLY;
34972
34973
34974
34975
34976
34977
34978
34979
34980

34981
34982
34983
34984
34985
34986
34987
34988
34989
34990
  void *zConverted;
  UNUSED_PARAMETER(pVfs);
  UNUSED_PARAMETER(syncDir);

  SimulateIOError(return SQLITE_IOERR_DELETE);
  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));

  zConverted = convertUtf8Filename(zFilename);
  if( zConverted==0 ){

    return SQLITE_IOERR_NOMEM;
  }
  if( isNT() ){
    do {
#if SQLITE_OS_WINRT
      WIN32_FILE_ATTRIBUTE_DATA sAttrData;
      memset(&sAttrData, 0, sizeof(sAttrData));
      if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
                                  &sAttrData) ){
        attr = sAttrData.dwFileAttributes;







|

>


|







35212
35213
35214
35215
35216
35217
35218
35219
35220
35221
35222
35223
35224
35225
35226
35227
35228
35229
35230
35231
  void *zConverted;
  UNUSED_PARAMETER(pVfs);
  UNUSED_PARAMETER(syncDir);

  SimulateIOError(return SQLITE_IOERR_DELETE);
  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));

  zConverted = winConvertFromUtf8Filename(zFilename);
  if( zConverted==0 ){
    OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
    return SQLITE_IOERR_NOMEM;
  }
  if( osIsNT() ){
    do {
#if SQLITE_OS_WINRT
      WIN32_FILE_ATTRIBUTE_DATA sAttrData;
      memset(&sAttrData, 0, sizeof(sAttrData));
      if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
                                  &sAttrData) ){
        attr = sAttrData.dwFileAttributes;
35015
35016
35017
35018
35019
35020
35021
35022
35023
35024
35025
35026
35027
35028
35029
        rc = SQLITE_ERROR; /* Files only. */
        break;
      }
      if ( osDeleteFileW(zConverted) ){
        rc = SQLITE_OK; /* Deleted OK. */
        break;
      }
      if ( !retryIoerr(&cnt, &lastErrno) ){
        rc = SQLITE_ERROR; /* No more retries. */
        break;
      }
    } while(1);
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{







|







35256
35257
35258
35259
35260
35261
35262
35263
35264
35265
35266
35267
35268
35269
35270
        rc = SQLITE_ERROR; /* Files only. */
        break;
      }
      if ( osDeleteFileW(zConverted) ){
        rc = SQLITE_OK; /* Deleted OK. */
        break;
      }
      if ( !winRetryIoerr(&cnt, &lastErrno) ){
        rc = SQLITE_ERROR; /* No more retries. */
        break;
      }
    } while(1);
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
35043
35044
35045
35046
35047
35048
35049
35050
35051
35052
35053
35054
35055
35056
35057
35058
35059
35060
35061
35062
35063
35064
35065
35066
35067
35068
        rc = SQLITE_ERROR; /* Files only. */
        break;
      }
      if ( osDeleteFileA(zConverted) ){
        rc = SQLITE_OK; /* Deleted OK. */
        break;
      }
      if ( !retryIoerr(&cnt, &lastErrno) ){
        rc = SQLITE_ERROR; /* No more retries. */
        break;
      }
    } while(1);
  }
#endif
  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
             "winDelete", zFilename);
  }else{
    logIoerr(cnt);
  }
  sqlite3_free(zConverted);
  OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
  return rc;
}

/*







|







|
<

|







35284
35285
35286
35287
35288
35289
35290
35291
35292
35293
35294
35295
35296
35297
35298
35299

35300
35301
35302
35303
35304
35305
35306
35307
35308
        rc = SQLITE_ERROR; /* Files only. */
        break;
      }
      if ( osDeleteFileA(zConverted) ){
        rc = SQLITE_OK; /* Deleted OK. */
        break;
      }
      if ( !winRetryIoerr(&cnt, &lastErrno) ){
        rc = SQLITE_ERROR; /* No more retries. */
        break;
      }
    } while(1);
  }
#endif
  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);

  }else{
    winLogIoerr(cnt);
  }
  sqlite3_free(zConverted);
  OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
  return rc;
}

/*
35080
35081
35082
35083
35084
35085
35086
35087
35088
35089
35090
35091
35092
35093
35094
35095
35096
35097
35098
35099
35100
35101
35102
35103
35104
35105
35106
35107
35108
35109
35110
35111
35112
35113
35114
35115

35116
35117
35118
35119
35120
35121
35122
  void *zConverted;
  UNUSED_PARAMETER(pVfs);

  SimulateIOError( return SQLITE_IOERR_ACCESS; );
  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
           zFilename, flags, pResOut));

  zConverted = convertUtf8Filename(zFilename);
  if( zConverted==0 ){
    OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
    return SQLITE_IOERR_NOMEM;
  }
  if( isNT() ){
    int cnt = 0;
    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
    memset(&sAttrData, 0, sizeof(sAttrData));
    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
                             GetFileExInfoStandard, 
                             &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
    if( rc ){
      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
      ** as if it does not exist.
      */
      if(    flags==SQLITE_ACCESS_EXISTS
          && sAttrData.nFileSizeHigh==0 
          && sAttrData.nFileSizeLow==0 ){
        attr = INVALID_FILE_ATTRIBUTES;
      }else{
        attr = sAttrData.dwFileAttributes;
      }
    }else{
      logIoerr(cnt);
      if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
        winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
        sqlite3_free(zConverted);
        return SQLITE_IOERR_ACCESS;

      }else{
        attr = INVALID_FILE_ATTRIBUTES;
      }
    }
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{







|




|





|












|

<

|
>







35320
35321
35322
35323
35324
35325
35326
35327
35328
35329
35330
35331
35332
35333
35334
35335
35336
35337
35338
35339
35340
35341
35342
35343
35344
35345
35346
35347
35348
35349
35350
35351
35352

35353
35354
35355
35356
35357
35358
35359
35360
35361
35362
  void *zConverted;
  UNUSED_PARAMETER(pVfs);

  SimulateIOError( return SQLITE_IOERR_ACCESS; );
  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
           zFilename, flags, pResOut));

  zConverted = winConvertFromUtf8Filename(zFilename);
  if( zConverted==0 ){
    OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
    return SQLITE_IOERR_NOMEM;
  }
  if( osIsNT() ){
    int cnt = 0;
    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
    memset(&sAttrData, 0, sizeof(sAttrData));
    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
                             GetFileExInfoStandard, 
                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
    if( rc ){
      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
      ** as if it does not exist.
      */
      if(    flags==SQLITE_ACCESS_EXISTS
          && sAttrData.nFileSizeHigh==0 
          && sAttrData.nFileSizeLow==0 ){
        attr = INVALID_FILE_ATTRIBUTES;
      }else{
        attr = sAttrData.dwFileAttributes;
      }
    }else{
      winLogIoerr(cnt);
      if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){

        sqlite3_free(zConverted);
        return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
                           zFilename);
      }else{
        attr = INVALID_FILE_ATTRIBUTES;
      }
    }
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
35138
35139
35140
35141
35142
35143
35144









35145
35146
35147
35148
35149
35150
35151
35152
35153
35154
35155
35156
35157
35158
35159
35160
35161
35162
35163
35164
35165
35166
35167
35168
35169
35170
35171
35172
35173
35174
35175
35176
35177
35178
35179
  }
  *pResOut = rc;
  OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
           zFilename, pResOut, *pResOut));
  return SQLITE_OK;
}











/*
** Returns non-zero if the specified path name should be used verbatim.  If
** non-zero is returned from this function, the calling function must simply
** use the provided path name verbatim -OR- resolve it into a full path name
** using the GetFullPathName Win32 API function (if available).
*/
static BOOL winIsVerbatimPathname(
  const char *zPathname
){
  /*
  ** If the path name starts with a forward slash or a backslash, it is either
  ** a legal UNC name, a volume relative path, or an absolute path name in the
  ** "Unix" format on Windows.  There is no easy way to differentiate between
  ** the final two cases; therefore, we return the safer return value of TRUE
  ** so that callers of this function will simply use it verbatim.
  */
  if ( zPathname[0]=='/' || zPathname[0]=='\\' ){
    return TRUE;
  }

  /*
  ** If the path name starts with a letter and a colon it is either a volume
  ** relative path or an absolute path.  Callers of this function must not
  ** attempt to treat it as a relative path name (i.e. they should simply use
  ** it verbatim).
  */
  if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
    return TRUE;
  }

  /*
  ** If we get to this point, the path name should almost certainly be a purely
  ** relative one (i.e. not a UNC name, not absolute, and not volume relative).
  */







>
>
>
>
>
>
>
>
>

















|









|







35378
35379
35380
35381
35382
35383
35384
35385
35386
35387
35388
35389
35390
35391
35392
35393
35394
35395
35396
35397
35398
35399
35400
35401
35402
35403
35404
35405
35406
35407
35408
35409
35410
35411
35412
35413
35414
35415
35416
35417
35418
35419
35420
35421
35422
35423
35424
35425
35426
35427
35428
  }
  *pResOut = rc;
  OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
           zFilename, pResOut, *pResOut));
  return SQLITE_OK;
}

/*
** Returns non-zero if the specified path name starts with a drive letter
** followed by a colon character.
*/
static BOOL winIsDriveLetterAndColon(
  const char *zPathname
){
  return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
}

/*
** Returns non-zero if the specified path name should be used verbatim.  If
** non-zero is returned from this function, the calling function must simply
** use the provided path name verbatim -OR- resolve it into a full path name
** using the GetFullPathName Win32 API function (if available).
*/
static BOOL winIsVerbatimPathname(
  const char *zPathname
){
  /*
  ** If the path name starts with a forward slash or a backslash, it is either
  ** a legal UNC name, a volume relative path, or an absolute path name in the
  ** "Unix" format on Windows.  There is no easy way to differentiate between
  ** the final two cases; therefore, we return the safer return value of TRUE
  ** so that callers of this function will simply use it verbatim.
  */
  if ( winIsDirSep(zPathname[0]) ){
    return TRUE;
  }

  /*
  ** If the path name starts with a letter and a colon it is either a volume
  ** relative path or an absolute path.  Callers of this function must not
  ** attempt to treat it as a relative path name (i.e. they should simply use
  ** it verbatim).
  */
  if ( winIsDriveLetterAndColon(zPathname) ){
    return TRUE;
  }

  /*
  ** If we get to this point, the path name should almost certainly be a purely
  ** relative one (i.e. not a UNC name, not absolute, and not volume relative).
  */
35191
35192
35193
35194
35195
35196
35197
35198
35199
35200
35201
35202
35203
35204
35205
35206
35207
35208


35209
35210




35211
35212

35213
35214



35215
35216
35217
35218
35219
35220
35221
35222
35223
35224
35225
35226
35227
35228
35229
35230
35231
35232
35233
35234
35235
35236
35237
35238
35239
35240
35241
35242
35243
35244
35245
35246
35247
35248
35249
35250
35251
35252
35253
35254
35255
35256
35257
35258
35259
35260
35261
35262
35263
35264
35265
35266
35267
35268
35269
35270
35271
35272
35273
35274
35275
35276
35277
35278

35279
35280
35281
35282
35283
35284
35285
35286
35287
35288
35289
35290
35291
35292

35293
35294
35295
35296
35297
35298
35299
35300
35301
35302
35303
35304
35305
35306

35307
35308
35309
35310
35311
35312
35313
35314
35315
35316
35317
35318
35319
35320

35321
35322
35323
35324
35325
35326
35327
  int nFull,                    /* Size of output buffer in bytes */
  char *zFull                   /* Output buffer */
){
  
#if defined(__CYGWIN__)
  SimulateIOError( return SQLITE_ERROR );
  UNUSED_PARAMETER(nFull);
  assert( pVfs->mxPathname>=MAX_PATH );
  assert( nFull>=pVfs->mxPathname );
  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
    /*
    ** NOTE: We are dealing with a relative path name and the data
    **       directory has been set.  Therefore, use it as the basis
    **       for converting the relative path name to an absolute
    **       one by prepending the data directory and a slash.
    */
    char zOut[MAX_PATH+1];
    memset(zOut, 0, MAX_PATH+1);


    cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
                     MAX_PATH+1);




    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
                     sqlite3_data_directory, zOut);

  }else{
    cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);



  }
  return SQLITE_OK;
#endif

#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
  SimulateIOError( return SQLITE_ERROR );
  /* WinCE has no concept of a relative pathname, or so I am told. */
  /* WinRT has no way to convert a relative path to an absolute one. */
  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
    /*
    ** NOTE: We are dealing with a relative path name and the data
    **       directory has been set.  Therefore, use it as the basis
    **       for converting the relative path name to an absolute
    **       one by prepending the data directory and a backslash.
    */
    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
                     sqlite3_data_directory, zRelative);
  }else{
    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
  }
  return SQLITE_OK;
#endif

#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
  DWORD nByte;
  void *zConverted;
  char *zOut;

  /* If this path name begins with "/X:", where "X" is any alphabetic
  ** character, discard the initial "/" from the pathname.
  */
  if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){
    zRelative++;
  }

  /* It's odd to simulate an io-error here, but really this is just
  ** using the io-error infrastructure to test that SQLite handles this
  ** function failing. This function could fail if, for example, the
  ** current working directory has been unlinked.
  */
  SimulateIOError( return SQLITE_ERROR );
  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
    /*
    ** NOTE: We are dealing with a relative path name and the data
    **       directory has been set.  Therefore, use it as the basis
    **       for converting the relative path name to an absolute
    **       one by prepending the data directory and a backslash.
    */
    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
                     sqlite3_data_directory, zRelative);
    return SQLITE_OK;
  }
  zConverted = convertUtf8Filename(zRelative);
  if( zConverted==0 ){
    return SQLITE_IOERR_NOMEM;
  }
  if( isNT() ){
    LPWSTR zTemp;
    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
    if( nByte==0 ){
      winLogError(SQLITE_ERROR, osGetLastError(),
                  "GetFullPathNameW1", zConverted);
      sqlite3_free(zConverted);
      return SQLITE_CANTOPEN_FULLPATH;

    }
    nByte += 3;
    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
    if( zTemp==0 ){
      sqlite3_free(zConverted);
      return SQLITE_IOERR_NOMEM;
    }
    nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
    if( nByte==0 ){
      winLogError(SQLITE_ERROR, osGetLastError(),
                  "GetFullPathNameW2", zConverted);
      sqlite3_free(zConverted);
      sqlite3_free(zTemp);
      return SQLITE_CANTOPEN_FULLPATH;

    }
    sqlite3_free(zConverted);
    zOut = unicodeToUtf8(zTemp);
    sqlite3_free(zTemp);
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    char *zTemp;
    nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
    if( nByte==0 ){
      winLogError(SQLITE_ERROR, osGetLastError(),
                  "GetFullPathNameA1", zConverted);
      sqlite3_free(zConverted);
      return SQLITE_CANTOPEN_FULLPATH;

    }
    nByte += 3;
    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
    if( zTemp==0 ){
      sqlite3_free(zConverted);
      return SQLITE_IOERR_NOMEM;
    }
    nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
    if( nByte==0 ){
      winLogError(SQLITE_ERROR, osGetLastError(),
                  "GetFullPathNameA2", zConverted);
      sqlite3_free(zConverted);
      sqlite3_free(zTemp);
      return SQLITE_CANTOPEN_FULLPATH;

    }
    sqlite3_free(zConverted);
    zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
    sqlite3_free(zTemp);
  }
#endif
  if( zOut ){







<








|
|
>
>
|
|
>
>
>
>
|
|
>

|
>
>
>















|
|














|
















|
|


|



|



<
<

|
>









<
<


|
>


|







<
<

|
>









<
<


|
>







35440
35441
35442
35443
35444
35445
35446

35447
35448
35449
35450
35451
35452
35453
35454
35455
35456
35457
35458
35459
35460
35461
35462
35463
35464
35465
35466
35467
35468
35469
35470
35471
35472
35473
35474
35475
35476
35477
35478
35479
35480
35481
35482
35483
35484
35485
35486
35487
35488
35489
35490
35491
35492
35493
35494
35495
35496
35497
35498
35499
35500
35501
35502
35503
35504
35505
35506
35507
35508
35509
35510
35511
35512
35513
35514
35515
35516
35517
35518
35519
35520
35521
35522
35523
35524
35525
35526
35527
35528
35529
35530
35531
35532


35533
35534
35535
35536
35537
35538
35539
35540
35541
35542
35543
35544


35545
35546
35547
35548
35549
35550
35551
35552
35553
35554
35555
35556
35557
35558


35559
35560
35561
35562
35563
35564
35565
35566
35567
35568
35569
35570


35571
35572
35573
35574
35575
35576
35577
35578
35579
35580
35581
  int nFull,                    /* Size of output buffer in bytes */
  char *zFull                   /* Output buffer */
){
  
#if defined(__CYGWIN__)
  SimulateIOError( return SQLITE_ERROR );
  UNUSED_PARAMETER(nFull);

  assert( nFull>=pVfs->mxPathname );
  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
    /*
    ** NOTE: We are dealing with a relative path name and the data
    **       directory has been set.  Therefore, use it as the basis
    **       for converting the relative path name to an absolute
    **       one by prepending the data directory and a slash.
    */
    char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
    if( !zOut ){
      return SQLITE_IOERR_NOMEM;
    }
    if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
                         pVfs->mxPathname+1)<0 ){
      sqlite3_free(zOut);
      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
                         "winFullPathname1", zRelative);
    }
    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
                     sqlite3_data_directory, winGetDirDep(), zOut);
    sqlite3_free(zOut);
  }else{
    if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
                         "winFullPathname2", zRelative);
    }
  }
  return SQLITE_OK;
#endif

#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
  SimulateIOError( return SQLITE_ERROR );
  /* WinCE has no concept of a relative pathname, or so I am told. */
  /* WinRT has no way to convert a relative path to an absolute one. */
  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
    /*
    ** NOTE: We are dealing with a relative path name and the data
    **       directory has been set.  Therefore, use it as the basis
    **       for converting the relative path name to an absolute
    **       one by prepending the data directory and a backslash.
    */
    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
                     sqlite3_data_directory, winGetDirDep(), zRelative);
  }else{
    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
  }
  return SQLITE_OK;
#endif

#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
  DWORD nByte;
  void *zConverted;
  char *zOut;

  /* If this path name begins with "/X:", where "X" is any alphabetic
  ** character, discard the initial "/" from the pathname.
  */
  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
    zRelative++;
  }

  /* It's odd to simulate an io-error here, but really this is just
  ** using the io-error infrastructure to test that SQLite handles this
  ** function failing. This function could fail if, for example, the
  ** current working directory has been unlinked.
  */
  SimulateIOError( return SQLITE_ERROR );
  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
    /*
    ** NOTE: We are dealing with a relative path name and the data
    **       directory has been set.  Therefore, use it as the basis
    **       for converting the relative path name to an absolute
    **       one by prepending the data directory and a backslash.
    */
    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
                     sqlite3_data_directory, winGetDirDep(), zRelative);
    return SQLITE_OK;
  }
  zConverted = winConvertFromUtf8Filename(zRelative);
  if( zConverted==0 ){
    return SQLITE_IOERR_NOMEM;
  }
  if( osIsNT() ){
    LPWSTR zTemp;
    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
    if( nByte==0 ){


      sqlite3_free(zConverted);
      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
                         "winFullPathname1", zRelative);
    }
    nByte += 3;
    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
    if( zTemp==0 ){
      sqlite3_free(zConverted);
      return SQLITE_IOERR_NOMEM;
    }
    nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
    if( nByte==0 ){


      sqlite3_free(zConverted);
      sqlite3_free(zTemp);
      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
                         "winFullPathname2", zRelative);
    }
    sqlite3_free(zConverted);
    zOut = winUnicodeToUtf8(zTemp);
    sqlite3_free(zTemp);
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    char *zTemp;
    nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
    if( nByte==0 ){


      sqlite3_free(zConverted);
      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
                         "winFullPathname3", zRelative);
    }
    nByte += 3;
    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
    if( zTemp==0 ){
      sqlite3_free(zConverted);
      return SQLITE_IOERR_NOMEM;
    }
    nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
    if( nByte==0 ){


      sqlite3_free(zConverted);
      sqlite3_free(zTemp);
      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
                         "winFullPathname4", zRelative);
    }
    sqlite3_free(zConverted);
    zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
    sqlite3_free(zTemp);
  }
#endif
  if( zOut ){
35341
35342
35343
35344
35345
35346
35347
35348
35349
35350
35351
35352
35353
35354
35355
35356
35357
35358
35359
35360
35361
35362
35363
35364
35365
35366
35367
35368
35369
35370
35371
35372
35373
35374
35375
35376
35377
*/
/*
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
  HANDLE h;
  void *zConverted = convertUtf8Filename(zFilename);
  UNUSED_PARAMETER(pVfs);
  if( zConverted==0 ){
    return 0;
  }
  if( isNT() ){
#if SQLITE_OS_WINRT
    h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
#else
    h = osLoadLibraryW((LPCWSTR)zConverted);
#endif
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    h = osLoadLibraryA((char*)zConverted);
  }
#endif
  sqlite3_free(zConverted);
  return (void*)h;
}
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
  UNUSED_PARAMETER(pVfs);
  getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
}
static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
  UNUSED_PARAMETER(pVfs);
  return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
}
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
  UNUSED_PARAMETER(pVfs);







|




|
















|







35595
35596
35597
35598
35599
35600
35601
35602
35603
35604
35605
35606
35607
35608
35609
35610
35611
35612
35613
35614
35615
35616
35617
35618
35619
35620
35621
35622
35623
35624
35625
35626
35627
35628
35629
35630
35631
*/
/*
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
  HANDLE h;
  void *zConverted = winConvertFromUtf8Filename(zFilename);
  UNUSED_PARAMETER(pVfs);
  if( zConverted==0 ){
    return 0;
  }
  if( osIsNT() ){
#if SQLITE_OS_WINRT
    h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
#else
    h = osLoadLibraryW((LPCWSTR)zConverted);
#endif
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    h = osLoadLibraryA((char*)zConverted);
  }
#endif
  sqlite3_free(zConverted);
  return (void*)h;
}
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
  UNUSED_PARAMETER(pVfs);
  winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
}
static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
  UNUSED_PARAMETER(pVfs);
  return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
}
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
  UNUSED_PARAMETER(pVfs);
35539
35540
35541
35542
35543
35544
35545
35546
35547
35548
35549
35550
35551
35552
35553
35554
35555
35556
35557
35558
35559
35560
35561
35562
35563
35564
35565
35566
35567
35568
35569
35570
35571
35572
35573
35574
35575
35576


























35577
35578
35579
35580
35581
35582
35583
35584
35585
35586
35587
35588
35589
35590
35591
35592





35593
35594
35595
35596
35597
35598
35599
**
** However if an error message is supplied, it will be incorporated
** by sqlite into the error message available to the user using
** sqlite3_errmsg(), possibly making IO errors easier to debug.
*/
static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
  UNUSED_PARAMETER(pVfs);
  return getLastErrorMsg(osGetLastError(), nBuf, zBuf);
}

/*
** Initialize and deinitialize the operating system interface.
*/
SQLITE_API int sqlite3_os_init(void){
  static sqlite3_vfs winVfs = {
    3,                   /* iVersion */
    sizeof(winFile),     /* szOsFile */
    MAX_PATH,            /* mxPathname */
    0,                   /* pNext */
    "win32",             /* zName */
    0,                   /* pAppData */
    winOpen,             /* xOpen */
    winDelete,           /* xDelete */
    winAccess,           /* xAccess */
    winFullPathname,     /* xFullPathname */
    winDlOpen,           /* xDlOpen */
    winDlError,          /* xDlError */
    winDlSym,            /* xDlSym */
    winDlClose,          /* xDlClose */
    winRandomness,       /* xRandomness */
    winSleep,            /* xSleep */
    winCurrentTime,      /* xCurrentTime */
    winGetLastError,     /* xGetLastError */
    winCurrentTimeInt64, /* xCurrentTimeInt64 */
    winSetSystemCall,    /* xSetSystemCall */
    winGetSystemCall,    /* xGetSystemCall */
    winNextSystemCall,   /* xNextSystemCall */
  };



























  /* Double-check that the aSyscall[] array has been constructed
  ** correctly.  See ticket [bb3a86e890c8e96ab] */
  assert( ArraySize(aSyscall)==74 );

  /* get memory map allocation granularity */
  memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
#if SQLITE_OS_WINRT
  osGetNativeSystemInfo(&winSysInfo);
#else
  osGetSystemInfo(&winSysInfo);
#endif
  assert( winSysInfo.dwAllocationGranularity>0 );
  assert( winSysInfo.dwPageSize>0 );

  sqlite3_vfs_register(&winVfs, 1);





  return SQLITE_OK; 
}

SQLITE_API int sqlite3_os_end(void){ 
#if SQLITE_OS_WINRT
  if( sleepObj!=NULL ){
    osCloseHandle(sleepObj);







|









|




















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
















>
>
>
>
>







35793
35794
35795
35796
35797
35798
35799
35800
35801
35802
35803
35804
35805
35806
35807
35808
35809
35810
35811
35812
35813
35814
35815
35816
35817
35818
35819
35820
35821
35822
35823
35824
35825
35826
35827
35828
35829
35830
35831
35832
35833
35834
35835
35836
35837
35838
35839
35840
35841
35842
35843
35844
35845
35846
35847
35848
35849
35850
35851
35852
35853
35854
35855
35856
35857
35858
35859
35860
35861
35862
35863
35864
35865
35866
35867
35868
35869
35870
35871
35872
35873
35874
35875
35876
35877
35878
35879
35880
35881
35882
35883
35884
**
** However if an error message is supplied, it will be incorporated
** by sqlite into the error message available to the user using
** sqlite3_errmsg(), possibly making IO errors easier to debug.
*/
static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
  UNUSED_PARAMETER(pVfs);
  return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
}

/*
** Initialize and deinitialize the operating system interface.
*/
SQLITE_API int sqlite3_os_init(void){
  static sqlite3_vfs winVfs = {
    3,                   /* iVersion */
    sizeof(winFile),     /* szOsFile */
    SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
    0,                   /* pNext */
    "win32",             /* zName */
    0,                   /* pAppData */
    winOpen,             /* xOpen */
    winDelete,           /* xDelete */
    winAccess,           /* xAccess */
    winFullPathname,     /* xFullPathname */
    winDlOpen,           /* xDlOpen */
    winDlError,          /* xDlError */
    winDlSym,            /* xDlSym */
    winDlClose,          /* xDlClose */
    winRandomness,       /* xRandomness */
    winSleep,            /* xSleep */
    winCurrentTime,      /* xCurrentTime */
    winGetLastError,     /* xGetLastError */
    winCurrentTimeInt64, /* xCurrentTimeInt64 */
    winSetSystemCall,    /* xSetSystemCall */
    winGetSystemCall,    /* xGetSystemCall */
    winNextSystemCall,   /* xNextSystemCall */
  };
#if defined(SQLITE_WIN32_HAS_WIDE)
  static sqlite3_vfs winLongPathVfs = {
    3,                   /* iVersion */
    sizeof(winFile),     /* szOsFile */
    SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
    0,                   /* pNext */
    "win32-longpath",    /* zName */
    0,                   /* pAppData */
    winOpen,             /* xOpen */
    winDelete,           /* xDelete */
    winAccess,           /* xAccess */
    winFullPathname,     /* xFullPathname */
    winDlOpen,           /* xDlOpen */
    winDlError,          /* xDlError */
    winDlSym,            /* xDlSym */
    winDlClose,          /* xDlClose */
    winRandomness,       /* xRandomness */
    winSleep,            /* xSleep */
    winCurrentTime,      /* xCurrentTime */
    winGetLastError,     /* xGetLastError */
    winCurrentTimeInt64, /* xCurrentTimeInt64 */
    winSetSystemCall,    /* xSetSystemCall */
    winGetSystemCall,    /* xGetSystemCall */
    winNextSystemCall,   /* xNextSystemCall */
  };
#endif

  /* Double-check that the aSyscall[] array has been constructed
  ** correctly.  See ticket [bb3a86e890c8e96ab] */
  assert( ArraySize(aSyscall)==74 );

  /* get memory map allocation granularity */
  memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
#if SQLITE_OS_WINRT
  osGetNativeSystemInfo(&winSysInfo);
#else
  osGetSystemInfo(&winSysInfo);
#endif
  assert( winSysInfo.dwAllocationGranularity>0 );
  assert( winSysInfo.dwPageSize>0 );

  sqlite3_vfs_register(&winVfs, 1);

#if defined(SQLITE_WIN32_HAS_WIDE)
  sqlite3_vfs_register(&winLongPathVfs, 0);
#endif

  return SQLITE_OK; 
}

SQLITE_API int sqlite3_os_end(void){ 
#if SQLITE_OS_WINRT
  if( sleepObj!=NULL ){
    osCloseHandle(sleepObj);
37399
37400
37401
37402
37403
37404
37405

37406
37407
37408
37409
37410
37411
37412
  )){
    goto fetch_out;
  }

  if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
    goto fetch_out;
  }


  /* Step 4. Try to recycle a page. */
  if( pCache->bPurgeable && pGroup->pLruTail && (
         (pCache->nPage+1>=pCache->nMax)
      || pGroup->nCurrentPage>=pGroup->nMaxPage
      || pcache1UnderMemoryPressure(pCache)
  )){







>







37684
37685
37686
37687
37688
37689
37690
37691
37692
37693
37694
37695
37696
37697
37698
  )){
    goto fetch_out;
  }

  if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
    goto fetch_out;
  }
  assert( pCache->nHash>0 && pCache->apHash );

  /* Step 4. Try to recycle a page. */
  if( pCache->bPurgeable && pGroup->pLruTail && (
         (pCache->nPage+1>=pCache->nMax)
      || pGroup->nCurrentPage>=pGroup->nMaxPage
      || pcache1UnderMemoryPressure(pCache)
  )){
38759
38760
38761
38762
38763
38764
38765







38766
38767
38768
38769
38770
38771
38772
  Pgno nOrig;                  /* Original number of pages in file */
  Pgno iSubRec;                /* Index of first record in sub-journal */
#ifndef SQLITE_OMIT_WAL
  u32 aWalData[WAL_SAVEPOINT_NDATA];        /* WAL savepoint context */
#endif
};








/*
** A open page cache is an instance of struct Pager. A description of
** some of the more important member variables follows:
**
** eState
**
**   The current 'state' of the pager object. See the comment and state







>
>
>
>
>
>
>







39045
39046
39047
39048
39049
39050
39051
39052
39053
39054
39055
39056
39057
39058
39059
39060
39061
39062
39063
39064
39065
  Pgno nOrig;                  /* Original number of pages in file */
  Pgno iSubRec;                /* Index of first record in sub-journal */
#ifndef SQLITE_OMIT_WAL
  u32 aWalData[WAL_SAVEPOINT_NDATA];        /* WAL savepoint context */
#endif
};

/*
** Bits of the Pager.doNotSpill flag.  See further description below.
*/
#define SPILLFLAG_OFF         0x01      /* Never spill cache.  Set via pragma */
#define SPILLFLAG_ROLLBACK    0x02      /* Current rolling back, so do not spill */
#define SPILLFLAG_NOSYNC      0x04      /* Spill is ok, but do not sync */

/*
** A open page cache is an instance of struct Pager. A description of
** some of the more important member variables follows:
**
** eState
**
**   The current 'state' of the pager object. See the comment and state
38825
38826
38827
38828
38829
38830
38831
38832
38833
38834
38835
38836
38837

38838
38839
38840
38841
38842

38843
38844
38845
38846
38847
38848
38849
38850
38851
**   subsequently interrupted transaction that reuses the journal file.
**
**   The flag is cleared as soon as the journal file is finalized (either
**   by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the
**   journal file from being successfully finalized, the setMaster flag
**   is cleared anyway (and the pager will move to ERROR state).
**
** doNotSpill, doNotSyncSpill
**
**   These two boolean variables control the behavior of cache-spills
**   (calls made by the pcache module to the pagerStress() routine to
**   write cached data to the file-system in order to free up memory).
**

**   When doNotSpill is non-zero, writing to the database from pagerStress()
**   is disabled altogether. This is done in a very obscure case that
**   comes up during savepoint rollback that requires the pcache module
**   to allocate a new page to prevent the journal file from being written
**   while it is being traversed by code in pager_playback().

** 
**   If doNotSyncSpill is non-zero, writing to the database from pagerStress()
**   is permitted, but syncing the journal file is not. This flag is set
**   by sqlite3PagerWrite() when the file-system sector-size is larger than
**   the database page-size in order to prevent a journal sync from happening 
**   in between the journalling of two pages on the same sector. 
**
** subjInMemory
**







|

|
|
|

>
|
|


|
>

|







39118
39119
39120
39121
39122
39123
39124
39125
39126
39127
39128
39129
39130
39131
39132
39133
39134
39135
39136
39137
39138
39139
39140
39141
39142
39143
39144
39145
39146
**   subsequently interrupted transaction that reuses the journal file.
**
**   The flag is cleared as soon as the journal file is finalized (either
**   by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the
**   journal file from being successfully finalized, the setMaster flag
**   is cleared anyway (and the pager will move to ERROR state).
**
** doNotSpill
**
**   This variables control the behavior of cache-spills  (calls made by
**   the pcache module to the pagerStress() routine to write cached data
**   to the file-system in order to free up memory).
**
**   When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set,
**   writing to the database from pagerStress() is disabled altogether.
**   The SPILLFLAG_ROLLBACK case is done in a very obscure case that
**   comes up during savepoint rollback that requires the pcache module
**   to allocate a new page to prevent the journal file from being written
**   while it is being traversed by code in pager_playback().  The SPILLFLAG_OFF
**   case is a user preference.
** 
**   If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress()
**   is permitted, but syncing the journal file is not. This flag is set
**   by sqlite3PagerWrite() when the file-system sector-size is larger than
**   the database page-size in order to prevent a journal sync from happening 
**   in between the journalling of two pages on the same sector. 
**
** subjInMemory
**
38941
38942
38943
38944
38945
38946
38947
38948
38949
38950
38951
38952
38953
38954
38955
  ** "configuration" of the pager.
  */
  u8 eState;                  /* Pager state (OPEN, READER, WRITER_LOCKED..) */
  u8 eLock;                   /* Current lock held on database file */
  u8 changeCountDone;         /* Set after incrementing the change-counter */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  u8 doNotSpill;              /* Do not spill the cache when non-zero */
  u8 doNotSyncSpill;          /* Do not do a spill that requires jrnl sync */
  u8 subjInMemory;            /* True to use in-memory sub-journals */
  Pgno dbSize;                /* Number of pages in the database */
  Pgno dbOrigSize;            /* dbSize before the current transaction */
  Pgno dbFileSize;            /* Number of pages in the database file */
  Pgno dbHintSize;            /* Value passed to FCNTL_SIZE_HINT call */
  int errCode;                /* One of several kinds of errors */
  int nRec;                   /* Pages journalled since last j-header written */







<







39236
39237
39238
39239
39240
39241
39242

39243
39244
39245
39246
39247
39248
39249
  ** "configuration" of the pager.
  */
  u8 eState;                  /* Pager state (OPEN, READER, WRITER_LOCKED..) */
  u8 eLock;                   /* Current lock held on database file */
  u8 changeCountDone;         /* Set after incrementing the change-counter */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  u8 doNotSpill;              /* Do not spill the cache when non-zero */

  u8 subjInMemory;            /* True to use in-memory sub-journals */
  Pgno dbSize;                /* Number of pages in the database */
  Pgno dbOrigSize;            /* dbSize before the current transaction */
  Pgno dbFileSize;            /* Number of pages in the database file */
  Pgno dbHintSize;            /* Value passed to FCNTL_SIZE_HINT call */
  int errCode;                /* One of several kinds of errors */
  int nRec;                   /* Pages journalled since last j-header written */
39320
39321
39322
39323
39324
39325
39326
39327
39328


39329


39330
39331
39332
39333

39334
39335
39336
39337
39338
39339
39340
** or more open savepoints for which:
**
**   * The page-number is less than or equal to PagerSavepoint.nOrig, and
**   * The bit corresponding to the page-number is not set in
**     PagerSavepoint.pInSavepoint.
*/
static int subjRequiresPage(PgHdr *pPg){
  Pgno pgno = pPg->pgno;
  Pager *pPager = pPg->pPager;


  int i;


  for(i=0; i<pPager->nSavepoint; i++){
    PagerSavepoint *p = &pPager->aSavepoint[i];
    if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
      return 1;

    }
  }
  return 0;
}

/*
** Return true if the page is already in the journal file.







<

>
>

>
>
|
|
|
|
>







39614
39615
39616
39617
39618
39619
39620

39621
39622
39623
39624
39625
39626
39627
39628
39629
39630
39631
39632
39633
39634
39635
39636
39637
39638
** or more open savepoints for which:
**
**   * The page-number is less than or equal to PagerSavepoint.nOrig, and
**   * The bit corresponding to the page-number is not set in
**     PagerSavepoint.pInSavepoint.
*/
static int subjRequiresPage(PgHdr *pPg){

  Pager *pPager = pPg->pPager;
  PagerSavepoint *p;
  Pgno pgno;
  int i;
  if( pPager->nSavepoint ){
    pgno = pPg->pgno;
    for(i=0; i<pPager->nSavepoint; i++){
      p = &pPager->aSavepoint[i];
      if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
        return 1;
      }
    }
  }
  return 0;
}

/*
** Return true if the page is already in the journal file.
40601
40602
40603
40604
40605
40606
40607
40608
40609
40610
40611
40612
40613
40614
40615
40616
40617
40618
40619
    **
    ** The solution is to add an in-memory page to the cache containing
    ** the data just read from the sub-journal. Mark the page as dirty 
    ** and if the pager requires a journal-sync, then mark the page as 
    ** requiring a journal-sync before it is written.
    */
    assert( isSavepnt );
    assert( pPager->doNotSpill==0 );
    pPager->doNotSpill++;
    rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
    assert( pPager->doNotSpill==1 );
    pPager->doNotSpill--;
    if( rc!=SQLITE_OK ) return rc;
    pPg->flags &= ~PGHDR_NEED_READ;
    sqlite3PcacheMakeDirty(pPg);
  }
  if( pPg ){
    /* No page should ever be explicitly rolled back that is in use, except
    ** for page 1 which is held in use in order to keep the lock on the







|
|

|
|







40899
40900
40901
40902
40903
40904
40905
40906
40907
40908
40909
40910
40911
40912
40913
40914
40915
40916
40917
    **
    ** The solution is to add an in-memory page to the cache containing
    ** the data just read from the sub-journal. Mark the page as dirty 
    ** and if the pager requires a journal-sync, then mark the page as 
    ** requiring a journal-sync before it is written.
    */
    assert( isSavepnt );
    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
    pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
    rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
    pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
    if( rc!=SQLITE_OK ) return rc;
    pPg->flags &= ~PGHDR_NEED_READ;
    sqlite3PcacheMakeDirty(pPg);
  }
  if( pPg ){
    /* No page should ever be explicitly rolled back that is in use, except
    ** for page 1 which is held in use in order to keep the lock on the
41172
41173
41174
41175
41176
41177
41178
41179
41180
41181
41182
41183
41184
41185
41186
41187
41188
41189
41190
41191
  Pgno pgno = pPg->pgno;       /* Page number to read */
  int rc = SQLITE_OK;          /* Return code */
  int pgsz = pPager->pageSize; /* Number of bytes to read */

  assert( pPager->eState>=PAGER_READER && !MEMDB );
  assert( isOpen(pPager->fd) );

  if( NEVER(!isOpen(pPager->fd)) ){
    assert( pPager->tempFile );
    memset(pPg->pData, 0, pPager->pageSize);
    return SQLITE_OK;
  }

#ifndef SQLITE_OMIT_WAL
  if( iFrame ){
    /* Try to pull the page from the write-ahead log. */
    rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
  }else
#endif
  {







<
<
<
<
<
<







41470
41471
41472
41473
41474
41475
41476






41477
41478
41479
41480
41481
41482
41483
  Pgno pgno = pPg->pgno;       /* Page number to read */
  int rc = SQLITE_OK;          /* Return code */
  int pgsz = pPager->pageSize; /* Number of bytes to read */

  assert( pPager->eState>=PAGER_READER && !MEMDB );
  assert( isOpen(pPager->fd) );







#ifndef SQLITE_OMIT_WAL
  if( iFrame ){
    /* Try to pull the page from the write-ahead log. */
    rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
  }else
#endif
  {
41710
41711
41712
41713
41714
41715
41716



41717
41718
41719
41720
41721
41722
41723
41724
41725
41726
** Free as much memory as possible from the pager.
*/
SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
  sqlite3PcacheShrink(pPager->pPCache);
}

/*



** Adjust the robustness of the database to damage due to OS crashes
** or power failures by changing the number of syncs()s when writing
** the rollback journal.  There are three levels:
**
**    OFF       sqlite3OsSync() is never called.  This is the default
**              for temporary and transient files.
**
**    NORMAL    The journal is synced once before writes begin on the
**              database.  This is normally adequate protection, but
**              it is theoretically possible, though very unlikely,







>
>
>
|
|
|







42002
42003
42004
42005
42006
42007
42008
42009
42010
42011
42012
42013
42014
42015
42016
42017
42018
42019
42020
42021
** Free as much memory as possible from the pager.
*/
SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
  sqlite3PcacheShrink(pPager->pPCache);
}

/*
** Adjust settings of the pager to those specified in the pgFlags parameter.
**
** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
** of the database to damage due to OS crashes or power failures by
** changing the number of syncs()s when writing the journals.
** There are three levels:
**
**    OFF       sqlite3OsSync() is never called.  This is the default
**              for temporary and transient files.
**
**    NORMAL    The journal is synced once before writes begin on the
**              database.  This is normally adequate protection, but
**              it is theoretically possible, though very unlikely,
41753
41754
41755
41756
41757
41758
41759
41760
41761
41762
41763
41764
41765

41766
41767
41768
41769
41770
41771
41772
41773
41774
41775
41776
41777
41778
41779
41780
41781
41782
41783
41784
41785





41786
41787
41788
41789
41790
41791
41792
** synchronous=FULL versus synchronous=NORMAL setting determines when
** the xSync primitive is called and is relevant to all platforms.
**
** Numeric values associated with these states are OFF==1, NORMAL=2,
** and FULL=3.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(
  Pager *pPager,        /* The pager to set safety level for */
  int level,            /* PRAGMA synchronous.  1=OFF, 2=NORMAL, 3=FULL */  
  int bFullFsync,       /* PRAGMA fullfsync */
  int bCkptFullFsync    /* PRAGMA checkpoint_fullfsync */
){

  assert( level>=1 && level<=3 );
  pPager->noSync =  (level==1 || pPager->tempFile) ?1:0;
  pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
  if( pPager->noSync ){
    pPager->syncFlags = 0;
    pPager->ckptSyncFlags = 0;
  }else if( bFullFsync ){
    pPager->syncFlags = SQLITE_SYNC_FULL;
    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
  }else if( bCkptFullFsync ){
    pPager->syncFlags = SQLITE_SYNC_NORMAL;
    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
  }else{
    pPager->syncFlags = SQLITE_SYNC_NORMAL;
    pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
  }
  pPager->walSyncFlags = pPager->syncFlags;
  if( pPager->fullSync ){
    pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
  }





}
#endif

/*
** The following global variable is incremented whenever the library
** attempts to open a temporary file.  This information is used for
** testing and analysis only.  







|

<
|
<

>






|


|










>
>
>
>
>







42048
42049
42050
42051
42052
42053
42054
42055
42056

42057

42058
42059
42060
42061
42062
42063
42064
42065
42066
42067
42068
42069
42070
42071
42072
42073
42074
42075
42076
42077
42078
42079
42080
42081
42082
42083
42084
42085
42086
42087
42088
42089
42090
42091
** synchronous=FULL versus synchronous=NORMAL setting determines when
** the xSync primitive is called and is relevant to all platforms.
**
** Numeric values associated with these states are OFF==1, NORMAL=2,
** and FULL=3.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
SQLITE_PRIVATE void sqlite3PagerSetFlags(
  Pager *pPager,        /* The pager to set safety level for */

  unsigned pgFlags      /* Various flags */

){
  unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
  assert( level>=1 && level<=3 );
  pPager->noSync =  (level==1 || pPager->tempFile) ?1:0;
  pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
  if( pPager->noSync ){
    pPager->syncFlags = 0;
    pPager->ckptSyncFlags = 0;
  }else if( pgFlags & PAGER_FULLFSYNC ){
    pPager->syncFlags = SQLITE_SYNC_FULL;
    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
  }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
    pPager->syncFlags = SQLITE_SYNC_NORMAL;
    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
  }else{
    pPager->syncFlags = SQLITE_SYNC_NORMAL;
    pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
  }
  pPager->walSyncFlags = pPager->syncFlags;
  if( pPager->fullSync ){
    pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
  }
  if( pgFlags & PAGER_CACHESPILL ){
    pPager->doNotSpill &= ~SPILLFLAG_OFF;
  }else{
    pPager->doNotSpill |= SPILLFLAG_OFF;
  }
}
#endif

/*
** The following global variable is incremented whenever the library
** attempts to open a temporary file.  This information is used for
** testing and analysis only.  
42679
42680
42681
42682
42683
42684
42685
42686
42687
42688
42689
42690
42691
42692

42693
42694
42695
42696
42697
42698
42699
42700
42701



42702

42703

42704
42705
42706
42707
42708
42709
42710
static int pagerStress(void *p, PgHdr *pPg){
  Pager *pPager = (Pager *)p;
  int rc = SQLITE_OK;

  assert( pPg->pPager==pPager );
  assert( pPg->flags&PGHDR_DIRTY );

  /* The doNotSyncSpill flag is set during times when doing a sync of
  ** journal (and adding a new header) is not allowed.  This occurs
  ** during calls to sqlite3PagerWrite() while trying to journal multiple
  ** pages belonging to the same sector.
  **
  ** The doNotSpill flag inhibits all cache spilling regardless of whether
  ** or not a sync is required.  This is set during a rollback.

  **
  ** Spilling is also prohibited when in an error state since that could
  ** lead to database corruption.   In the current implementaton it 
  ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1
  ** while in the error state, hence it is impossible for this routine to
  ** be called in the error state.  Nevertheless, we include a NEVER()
  ** test for the error state as a safeguard against future changes.
  */
  if( NEVER(pPager->errCode) ) return SQLITE_OK;



  if( pPager->doNotSpill ) return SQLITE_OK;

  if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){

    return SQLITE_OK;
  }

  pPg->pDirty = 0;
  if( pagerUseWal(pPager) ){
    /* Write a single frame for this page to the log. */
    if( subjRequiresPage(pPg) ){ 







|




|
|
>









>
>
>
|
>
|
>







42978
42979
42980
42981
42982
42983
42984
42985
42986
42987
42988
42989
42990
42991
42992
42993
42994
42995
42996
42997
42998
42999
43000
43001
43002
43003
43004
43005
43006
43007
43008
43009
43010
43011
43012
43013
43014
43015
static int pagerStress(void *p, PgHdr *pPg){
  Pager *pPager = (Pager *)p;
  int rc = SQLITE_OK;

  assert( pPg->pPager==pPager );
  assert( pPg->flags&PGHDR_DIRTY );

  /* The doNotSpill NOSYNC bit is set during times when doing a sync of
  ** journal (and adding a new header) is not allowed.  This occurs
  ** during calls to sqlite3PagerWrite() while trying to journal multiple
  ** pages belonging to the same sector.
  **
  ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling
  ** regardless of whether or not a sync is required.  This is set during
  ** a rollback or by user request, respectively.
  **
  ** Spilling is also prohibited when in an error state since that could
  ** lead to database corruption.   In the current implementaton it 
  ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1
  ** while in the error state, hence it is impossible for this routine to
  ** be called in the error state.  Nevertheless, we include a NEVER()
  ** test for the error state as a safeguard against future changes.
  */
  if( NEVER(pPager->errCode) ) return SQLITE_OK;
  testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK );
  testcase( pPager->doNotSpill & SPILLFLAG_OFF );
  testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC );
  if( pPager->doNotSpill
   && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0
      || (pPg->flags & PGHDR_NEED_SYNC)!=0)
  ){
    return SQLITE_OK;
  }

  pPg->pDirty = 0;
  if( pagerUseWal(pPager) ){
    /* Write a single frame for this page to the log. */
    if( subjRequiresPage(pPg) ){ 
43518
43519
43520
43521
43522
43523
43524
43525
43526
43527
43528
43529
43530
43531
43532
43533
43534
43535
43536
43537
43538
43539
43540
43541
43542
43543
43544
** Since Lookup() never goes to disk, it never has to deal with locks
** or journal files.
*/
SQLITE_PRIVATE int sqlite3PagerAcquire(
  Pager *pPager,      /* The pager open on the database file */
  Pgno pgno,          /* Page number to fetch */
  DbPage **ppPage,    /* Write a pointer to the page here */
  int flags           /* PAGER_ACQUIRE_XXX flags */
){
  int rc = SQLITE_OK;
  PgHdr *pPg = 0;
  u32 iFrame = 0;                 /* Frame to read from WAL file */
  const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT);

  /* It is acceptable to use a read-only (mmap) page for any page except
  ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
  ** flag was specified by the caller. And so long as the db is not a 
  ** temporary or in-memory database.  */
  const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
   && (pPager->eState==PAGER_READER || (flags & PAGER_ACQUIRE_READONLY))
#ifdef SQLITE_HAS_CODEC
   && pPager->xCodec==0
#endif
  );

  assert( pPager->eState>=PAGER_READER );
  assert( assert_pager_state(pPager) );







|




|






|







43823
43824
43825
43826
43827
43828
43829
43830
43831
43832
43833
43834
43835
43836
43837
43838
43839
43840
43841
43842
43843
43844
43845
43846
43847
43848
43849
** Since Lookup() never goes to disk, it never has to deal with locks
** or journal files.
*/
SQLITE_PRIVATE int sqlite3PagerAcquire(
  Pager *pPager,      /* The pager open on the database file */
  Pgno pgno,          /* Page number to fetch */
  DbPage **ppPage,    /* Write a pointer to the page here */
  int flags           /* PAGER_GET_XXX flags */
){
  int rc = SQLITE_OK;
  PgHdr *pPg = 0;
  u32 iFrame = 0;                 /* Frame to read from WAL file */
  const int noContent = (flags & PAGER_GET_NOCONTENT);

  /* It is acceptable to use a read-only (mmap) page for any page except
  ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
  ** flag was specified by the caller. And so long as the db is not a 
  ** temporary or in-memory database.  */
  const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
   && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
#ifdef SQLITE_HAS_CODEC
   && pPager->xCodec==0
#endif
  );

  assert( pPager->eState>=PAGER_READER );
  assert( assert_pager_state(pPager) );
44050
44051
44052
44053
44054
44055
44056
44057
44058
44059
44060
44061
44062
44063
44064
44065
44066
44067
44068
44069
44070
  if( nPagePerSector>1 ){
    Pgno nPageCount;          /* Total number of pages in database file */
    Pgno pg1;                 /* First page of the sector pPg is located on. */
    int nPage = 0;            /* Number of pages starting at pg1 to journal */
    int ii;                   /* Loop counter */
    int needSync = 0;         /* True if any page has PGHDR_NEED_SYNC */

    /* Set the doNotSyncSpill flag to 1. This is because we cannot allow
    ** a journal header to be written between the pages journaled by
    ** this function.
    */
    assert( !MEMDB );
    assert( pPager->doNotSyncSpill==0 );
    pPager->doNotSyncSpill++;

    /* This trick assumes that both the page-size and sector-size are
    ** an integer power of 2. It sets variable pg1 to the identifier
    ** of the first page of the sector pPg is located on.
    */
    pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;








|




|
|







44355
44356
44357
44358
44359
44360
44361
44362
44363
44364
44365
44366
44367
44368
44369
44370
44371
44372
44373
44374
44375
  if( nPagePerSector>1 ){
    Pgno nPageCount;          /* Total number of pages in database file */
    Pgno pg1;                 /* First page of the sector pPg is located on. */
    int nPage = 0;            /* Number of pages starting at pg1 to journal */
    int ii;                   /* Loop counter */
    int needSync = 0;         /* True if any page has PGHDR_NEED_SYNC */

    /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
    ** a journal header to be written between the pages journaled by
    ** this function.
    */
    assert( !MEMDB );
    assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
    pPager->doNotSpill |= SPILLFLAG_NOSYNC;

    /* This trick assumes that both the page-size and sector-size are
    ** an integer power of 2. It sets variable pg1 to the identifier
    ** of the first page of the sector pPg is located on.
    */
    pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;

44115
44116
44117
44118
44119
44120
44121
44122
44123
44124
44125
44126
44127
44128
44129
44130
        if( pPage ){
          pPage->flags |= PGHDR_NEED_SYNC;
          sqlite3PagerUnref(pPage);
        }
      }
    }

    assert( pPager->doNotSyncSpill==1 );
    pPager->doNotSyncSpill--;
  }else{
    rc = pager_write(pDbPage);
  }
  return rc;
}

/*







|
|







44420
44421
44422
44423
44424
44425
44426
44427
44428
44429
44430
44431
44432
44433
44434
44435
        if( pPage ){
          pPage->flags |= PGHDR_NEED_SYNC;
          sqlite3PagerUnref(pPage);
        }
      }
    }

    assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
    pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
  }else{
    rc = pager_write(pDbPage);
  }
  return rc;
}

/*
49112
49113
49114
49115
49116
49117
49118
49119
49120
49121
49122
49123
49124
49125
49126








49127
49128
49129
49130
49131
49132
49133
49134
49135
49136
49137
49138
49139
49140
49141
49142

49143
49144
49145
49146
49147
49148
49149
49150
49151
  u16 aiIdx[BTCURSOR_MAX_DEPTH];        /* Current index in apPage[i] */
  MemPage *apPage[BTCURSOR_MAX_DEPTH];  /* Pages from root to current page */
};

/*
** Potential values for BtCursor.eState.
**
** CURSOR_VALID:
**   Cursor points to a valid entry. getPayload() etc. may be called.
**
** CURSOR_INVALID:
**   Cursor does not point to a valid entry. This can happen (for example) 
**   because the table is empty or because BtreeCursorFirst() has not been
**   called.
**








** CURSOR_REQUIRESEEK:
**   The table that this cursor was opened on still exists, but has been 
**   modified since the cursor was last used. The cursor position is saved
**   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
**   this state, restoreCursorPosition() can be called to attempt to
**   seek the cursor to the saved position.
**
** CURSOR_FAULT:
**   A unrecoverable error (an I/O error or a malloc failure) has occurred
**   on a different connection that shares the BtShared cache with this
**   cursor.  The error has left the cache in an inconsistent state.
**   Do nothing else with this cursor.  Any attempt to use the cursor
**   should return the error code stored in BtCursor.skip
*/
#define CURSOR_INVALID           0
#define CURSOR_VALID             1

#define CURSOR_REQUIRESEEK       2
#define CURSOR_FAULT             3

/* 
** The database page the PENDING_BYTE occupies. This page is never used.
*/
# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)

/*







<
<
<





>
>
>
>
>
>
>
>
















>
|
|







49417
49418
49419
49420
49421
49422
49423



49424
49425
49426
49427
49428
49429
49430
49431
49432
49433
49434
49435
49436
49437
49438
49439
49440
49441
49442
49443
49444
49445
49446
49447
49448
49449
49450
49451
49452
49453
49454
49455
49456
49457
49458
49459
49460
49461
49462
  u16 aiIdx[BTCURSOR_MAX_DEPTH];        /* Current index in apPage[i] */
  MemPage *apPage[BTCURSOR_MAX_DEPTH];  /* Pages from root to current page */
};

/*
** Potential values for BtCursor.eState.
**



** CURSOR_INVALID:
**   Cursor does not point to a valid entry. This can happen (for example) 
**   because the table is empty or because BtreeCursorFirst() has not been
**   called.
**
** CURSOR_VALID:
**   Cursor points to a valid entry. getPayload() etc. may be called.
**
** CURSOR_SKIPNEXT:
**   Cursor is valid except that the Cursor.skipNext field is non-zero
**   indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
**   operation should be a no-op.
**
** CURSOR_REQUIRESEEK:
**   The table that this cursor was opened on still exists, but has been 
**   modified since the cursor was last used. The cursor position is saved
**   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
**   this state, restoreCursorPosition() can be called to attempt to
**   seek the cursor to the saved position.
**
** CURSOR_FAULT:
**   A unrecoverable error (an I/O error or a malloc failure) has occurred
**   on a different connection that shares the BtShared cache with this
**   cursor.  The error has left the cache in an inconsistent state.
**   Do nothing else with this cursor.  Any attempt to use the cursor
**   should return the error code stored in BtCursor.skip
*/
#define CURSOR_INVALID           0
#define CURSOR_VALID             1
#define CURSOR_SKIPNEXT          2
#define CURSOR_REQUIRESEEK       3
#define CURSOR_FAULT             4

/* 
** The database page the PENDING_BYTE occupies. This page is never used.
*/
# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)

/*
50251
50252
50253
50254
50255
50256
50257



50258
50259
50260
50261
50262
50263
50264
  }
  pCur->eState = CURSOR_INVALID;
  rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext);
  if( rc==SQLITE_OK ){
    sqlite3_free(pCur->pKey);
    pCur->pKey = 0;
    assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );



  }
  return rc;
}

#define restoreCursorPosition(p) \
  (p->eState>=CURSOR_REQUIRESEEK ? \
         btreeRestoreCursorPosition(p) : \







>
>
>







50562
50563
50564
50565
50566
50567
50568
50569
50570
50571
50572
50573
50574
50575
50576
50577
50578
  }
  pCur->eState = CURSOR_INVALID;
  rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext);
  if( rc==SQLITE_OK ){
    sqlite3_free(pCur->pKey);
    pCur->pKey = 0;
    assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
    if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
      pCur->eState = CURSOR_SKIPNEXT;
    }
  }
  return rc;
}

#define restoreCursorPosition(p) \
  (p->eState>=CURSOR_REQUIRESEEK ? \
         btreeRestoreCursorPosition(p) : \
50276
50277
50278
50279
50280
50281
50282
50283
50284
50285
50286
50287
50288
50289
50290
  int rc;

  rc = restoreCursorPosition(pCur);
  if( rc ){
    *pHasMoved = 1;
    return rc;
  }
  if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){
    *pHasMoved = 1;
  }else{
    *pHasMoved = 0;
  }
  return SQLITE_OK;
}








|







50590
50591
50592
50593
50594
50595
50596
50597
50598
50599
50600
50601
50602
50603
50604
  int rc;

  rc = restoreCursorPosition(pCur);
  if( rc ){
    *pHasMoved = 1;
    return rc;
  }
  if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
    *pHasMoved = 1;
  }else{
    *pHasMoved = 0;
  }
  return SQLITE_OK;
}

50464
50465
50466
50467
50468
50469
50470

50471
50472
50473
50474
50475
50476
50477
50478

  pInfo->pCell = pCell;
  assert( pPage->leaf==0 || pPage->leaf==1 );
  n = pPage->childPtrSize;
  assert( n==4-4*pPage->leaf );
  if( pPage->intKey ){
    if( pPage->hasData ){

      n += getVarint32(&pCell[n], nPayload);
    }else{
      nPayload = 0;
    }
    n += getVarint(&pCell[n], (u64*)&pInfo->nKey);
    pInfo->nData = nPayload;
  }else{
    pInfo->nData = 0;







>
|







50778
50779
50780
50781
50782
50783
50784
50785
50786
50787
50788
50789
50790
50791
50792
50793

  pInfo->pCell = pCell;
  assert( pPage->leaf==0 || pPage->leaf==1 );
  n = pPage->childPtrSize;
  assert( n==4-4*pPage->leaf );
  if( pPage->intKey ){
    if( pPage->hasData ){
      assert( n==0 );
      n = getVarint32(pCell, nPayload);
    }else{
      nPayload = 0;
    }
    n += getVarint(&pCell[n], (u64*)&pInfo->nKey);
    pInfo->nData = nPayload;
  }else{
    pInfo->nData = 0;
51108
51109
51110
51111
51112
51113
51114
51115
51116
51117
51118
51119
51120
51121
51122
51123
51124
51125
51126
51127
51128
51129
51130
** means we have started to be concerned about content and the disk
** read should occur at that point.
*/
static int btreeGetPage(
  BtShared *pBt,       /* The btree */
  Pgno pgno,           /* Number of the page to fetch */
  MemPage **ppPage,    /* Return the page in this parameter */
  int noContent,       /* Do not load page content if true */
  int bReadonly        /* True if a read-only (mmap) page is ok */
){
  int rc;
  DbPage *pDbPage;
  int flags = (noContent ? PAGER_ACQUIRE_NOCONTENT : 0) 
            | (bReadonly ? PAGER_ACQUIRE_READONLY : 0);

  assert( noContent==0 || bReadonly==0 );
  assert( sqlite3_mutex_held(pBt->mutex) );
  rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
  if( rc ) return rc;
  *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
  return SQLITE_OK;
}








|
<



<
<

|







51423
51424
51425
51426
51427
51428
51429
51430

51431
51432
51433


51434
51435
51436
51437
51438
51439
51440
51441
51442
** means we have started to be concerned about content and the disk
** read should occur at that point.
*/
static int btreeGetPage(
  BtShared *pBt,       /* The btree */
  Pgno pgno,           /* Number of the page to fetch */
  MemPage **ppPage,    /* Return the page in this parameter */
  int flags            /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */

){
  int rc;
  DbPage *pDbPage;



  assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY );
  assert( sqlite3_mutex_held(pBt->mutex) );
  rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
  if( rc ) return rc;
  *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
  return SQLITE_OK;
}

51164
51165
51166
51167
51168
51169
51170
51171
51172
51173
51174

51175
51176
51177
51178
51179
51180
51181
51182
51183
51184
51185
51186
** If an error occurs, then the value *ppPage is set to is undefined. It
** may remain unchanged, or it may be set to an invalid value.
*/
static int getAndInitPage(
  BtShared *pBt,                  /* The database file */
  Pgno pgno,                      /* Number of the page to get */
  MemPage **ppPage,               /* Write the page pointer here */
  int bReadonly                   /* True if a read-only (mmap) page is ok */
){
  int rc;
  assert( sqlite3_mutex_held(pBt->mutex) );


  if( pgno>btreePagecount(pBt) ){
    rc = SQLITE_CORRUPT_BKPT;
  }else{
    rc = btreeGetPage(pBt, pgno, ppPage, 0, bReadonly);
    if( rc==SQLITE_OK ){
      rc = btreeInitPage(*ppPage);
      if( rc!=SQLITE_OK ){
        releasePage(*ppPage);
      }
    }
  }







|



>




|







51476
51477
51478
51479
51480
51481
51482
51483
51484
51485
51486
51487
51488
51489
51490
51491
51492
51493
51494
51495
51496
51497
51498
51499
** If an error occurs, then the value *ppPage is set to is undefined. It
** may remain unchanged, or it may be set to an invalid value.
*/
static int getAndInitPage(
  BtShared *pBt,                  /* The database file */
  Pgno pgno,                      /* Number of the page to get */
  MemPage **ppPage,               /* Write the page pointer here */
  int bReadonly                   /* PAGER_GET_READONLY or 0 */
){
  int rc;
  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( bReadonly==PAGER_GET_READONLY || bReadonly==0 );

  if( pgno>btreePagecount(pBt) ){
    rc = SQLITE_CORRUPT_BKPT;
  }else{
    rc = btreeGetPage(pBt, pgno, ppPage, bReadonly);
    if( rc==SQLITE_OK ){
      rc = btreeInitPage(*ppPage);
      if( rc!=SQLITE_OK ){
        releasePage(*ppPage);
      }
    }
  }
51692
51693
51694
51695
51696
51697
51698
51699
51700
51701
51702
51703
51704
51705
51706
51707
51708
51709
51710
51711
51712
51713
51714
51715
51716
** how well the database resists damage due to OS crashes and power
** failures.  Level 1 is the same as asynchronous (no syncs() occur and
** there is a high probability of damage)  Level 2 is the default.  There
** is a very low but non-zero probability of damage.  Level 3 reduces the
** probability of damage to near zero but with a write performance reduction.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(
  Btree *p,              /* The btree to set the safety level on */
  int level,             /* PRAGMA synchronous.  1=OFF, 2=NORMAL, 3=FULL */
  int fullSync,          /* PRAGMA fullfsync. */
  int ckptFullSync       /* PRAGMA checkpoint_fullfync */
){
  BtShared *pBt = p->pBt;
  assert( sqlite3_mutex_held(p->db->mutex) );
  assert( level>=1 && level<=3 );
  sqlite3BtreeEnter(p);
  sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync, ckptFullSync);
  sqlite3BtreeLeave(p);
  return SQLITE_OK;
}
#endif

/*
** Return TRUE if the given btree is set to safety level 1.  In other







|

<
<
|



<

|







52005
52006
52007
52008
52009
52010
52011
52012
52013


52014
52015
52016
52017

52018
52019
52020
52021
52022
52023
52024
52025
52026
** how well the database resists damage due to OS crashes and power
** failures.  Level 1 is the same as asynchronous (no syncs() occur and
** there is a high probability of damage)  Level 2 is the default.  There
** is a very low but non-zero probability of damage.  Level 3 reduces the
** probability of damage to near zero but with a write performance reduction.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(
  Btree *p,              /* The btree to set the safety level on */


  unsigned pgFlags       /* Various PAGER_* flags */
){
  BtShared *pBt = p->pBt;
  assert( sqlite3_mutex_held(p->db->mutex) );

  sqlite3BtreeEnter(p);
  sqlite3PagerSetFlags(pBt->pPager, pgFlags);
  sqlite3BtreeLeave(p);
  return SQLITE_OK;
}
#endif

/*
** Return TRUE if the given btree is set to safety level 1.  In other
51908
51909
51910
51911
51912
51913
51914
51915
51916
51917
51918
51919
51920
51921
51922
  int nPageFile = 0;   /* Number of pages in the database file */
  int nPageHeader;     /* Number of pages in the database according to hdr */

  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( pBt->pPage1==0 );
  rc = sqlite3PagerSharedLock(pBt->pPager);
  if( rc!=SQLITE_OK ) return rc;
  rc = btreeGetPage(pBt, 1, &pPage1, 0, 0);
  if( rc!=SQLITE_OK ) return rc;

  /* Do some checking to help insure the file we opened really is
  ** a valid database file. 
  */
  nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
  sqlite3PagerPagecount(pBt->pPager, &nPageFile);







|







52218
52219
52220
52221
52222
52223
52224
52225
52226
52227
52228
52229
52230
52231
52232
  int nPageFile = 0;   /* Number of pages in the database file */
  int nPageHeader;     /* Number of pages in the database according to hdr */

  assert( sqlite3_mutex_held(pBt->mutex) );
  assert( pBt->pPage1==0 );
  rc = sqlite3PagerSharedLock(pBt->pPager);
  if( rc!=SQLITE_OK ) return rc;
  rc = btreeGetPage(pBt, 1, &pPage1, 0);
  if( rc!=SQLITE_OK ) return rc;

  /* Do some checking to help insure the file we opened really is
  ** a valid database file. 
  */
  nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
  sqlite3PagerPagecount(pBt->pPager, &nPageFile);
52036
52037
52038
52039
52040
52041
52042

52043
52044
52045
52046
52047
52048
52049
    pBt->max1bytePayload = 127;
  }else{
    pBt->max1bytePayload = (u8)pBt->maxLocal;
  }
  assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
  pBt->pPage1 = pPage1;
  pBt->nPage = nPage;

  return SQLITE_OK;

page1_init_failed:
  releasePage(pPage1);
  pBt->pPage1 = 0;
  return rc;
}







>







52346
52347
52348
52349
52350
52351
52352
52353
52354
52355
52356
52357
52358
52359
52360
    pBt->max1bytePayload = 127;
  }else{
    pBt->max1bytePayload = (u8)pBt->maxLocal;
  }
  assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
  pBt->pPage1 = pPage1;
  pBt->nPage = nPage;
assert( pPage1->leaf==0 || pPage1->leaf==1 );
  return SQLITE_OK;

page1_init_failed:
  releasePage(pPage1);
  pBt->pPage1 = 0;
  return rc;
}
52490
52491
52492
52493
52494
52495
52496
52497
52498
52499
52500
52501
52502
52503
52504
  }

  /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
  ** that it points at iFreePage. Also fix the pointer map entry for
  ** iPtrPage.
  */
  if( eType!=PTRMAP_ROOTPAGE ){
    rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0, 0);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    rc = sqlite3PagerWrite(pPtrPage->pDbPage);
    if( rc!=SQLITE_OK ){
      releasePage(pPtrPage);
      return rc;







|







52801
52802
52803
52804
52805
52806
52807
52808
52809
52810
52811
52812
52813
52814
52815
  }

  /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
  ** that it points at iFreePage. Also fix the pointer map entry for
  ** iPtrPage.
  */
  if( eType!=PTRMAP_ROOTPAGE ){
    rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    rc = sqlite3PagerWrite(pPtrPage->pDbPage);
    if( rc!=SQLITE_OK ){
      releasePage(pPtrPage);
      return rc;
52574
52575
52576
52577
52578
52579
52580
52581
52582
52583
52584
52585
52586
52587
52588
      }
    } else {
      Pgno iFreePg;             /* Index of free page to move pLastPg to */
      MemPage *pLastPg;
      u8 eMode = BTALLOC_ANY;   /* Mode parameter for allocateBtreePage() */
      Pgno iNear = 0;           /* nearby parameter for allocateBtreePage() */

      rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0, 0);
      if( rc!=SQLITE_OK ){
        return rc;
      }

      /* If bCommit is zero, this loop runs exactly once and page pLastPg
      ** is swapped with the first free page pulled off the free list.
      **







|







52885
52886
52887
52888
52889
52890
52891
52892
52893
52894
52895
52896
52897
52898
52899
      }
    } else {
      Pgno iFreePg;             /* Index of free page to move pLastPg to */
      MemPage *pLastPg;
      u8 eMode = BTALLOC_ANY;   /* Mode parameter for allocateBtreePage() */
      Pgno iNear = 0;           /* nearby parameter for allocateBtreePage() */

      rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
      if( rc!=SQLITE_OK ){
        return rc;
      }

      /* If bCommit is zero, this loop runs exactly once and page pLastPg
      ** is swapped with the first free page pulled off the free list.
      **
52973
52974
52975
52976
52977
52978
52979
52980
52981
52982
52983
52984
52985
52986
52987
    if( rc2!=SQLITE_OK ){
      rc = rc2;
    }

    /* The rollback may have destroyed the pPage1->aData value.  So
    ** call btreeGetPage() on page 1 again to make
    ** sure pPage1->aData is set correctly. */
    if( btreeGetPage(pBt, 1, &pPage1, 0, 0)==SQLITE_OK ){
      int nPage = get4byte(28+(u8*)pPage1->aData);
      testcase( nPage==0 );
      if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
      testcase( pBt->nPage!=nPage );
      pBt->nPage = nPage;
      releasePage(pPage1);
    }







|







53284
53285
53286
53287
53288
53289
53290
53291
53292
53293
53294
53295
53296
53297
53298
    if( rc2!=SQLITE_OK ){
      rc = rc2;
    }

    /* The rollback may have destroyed the pPage1->aData value.  So
    ** call btreeGetPage() on page 1 again to make
    ** sure pPage1->aData is set correctly. */
    if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
      int nPage = get4byte(28+(u8*)pPage1->aData);
      testcase( nPage==0 );
      if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
      testcase( pBt->nPage!=nPage );
      pBt->nPage = nPage;
      releasePage(pPage1);
    }
53408
53409
53410
53411
53412
53413
53414
53415
53416
53417
53418
53419
53420
53421
53422
      }
    }
  }
#endif

  assert( next==0 || rc==SQLITE_DONE );
  if( rc==SQLITE_OK ){
    rc = btreeGetPage(pBt, ovfl, &pPage, 0, (ppPage==0));
    assert( rc==SQLITE_OK || pPage==0 );
    if( rc==SQLITE_OK ){
      next = get4byte(pPage->aData);
    }
  }

  *pPgnoNext = next;







|







53719
53720
53721
53722
53723
53724
53725
53726
53727
53728
53729
53730
53731
53732
53733
      }
    }
  }
#endif

  assert( next==0 || rc==SQLITE_DONE );
  if( rc==SQLITE_OK ){
    rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0);
    assert( rc==SQLITE_OK || pPage==0 );
    if( rc==SQLITE_OK ){
      next = get4byte(pPage->aData);
    }
  }

  *pPgnoNext = next;
53630
53631
53632
53633
53634
53635
53636
53637
53638
53639
53640
53641
53642
53643
53644
          memcpy(aWrite, aSave, 4);
        }else
#endif

        {
          DbPage *pDbPage;
          rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
              (eOp==0 ? PAGER_ACQUIRE_READONLY : 0)
          );
          if( rc==SQLITE_OK ){
            aPayload = sqlite3PagerGetData(pDbPage);
            nextPage = get4byte(aPayload);
            rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
            sqlite3PagerUnref(pDbPage);
            offset = 0;







|







53941
53942
53943
53944
53945
53946
53947
53948
53949
53950
53951
53952
53953
53954
53955
          memcpy(aWrite, aSave, 4);
        }else
#endif

        {
          DbPage *pDbPage;
          rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
              (eOp==0 ? PAGER_GET_READONLY : 0)
          );
          if( rc==SQLITE_OK ){
            aPayload = sqlite3PagerGetData(pDbPage);
            nextPage = get4byte(aPayload);
            rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
            sqlite3PagerUnref(pDbPage);
            offset = 0;
53814
53815
53816
53817
53818
53819
53820
53821

53822
53823
53824
53825
53826
53827
53828
  assert( cursorHoldsMutex(pCur) );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
  assert( pCur->iPage>=0 );
  if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
    return SQLITE_CORRUPT_BKPT;
  }
  rc = getAndInitPage(pBt, newPgno, &pNewPage, (pCur->wrFlag==0));

  if( rc ) return rc;
  pCur->apPage[i+1] = pNewPage;
  pCur->aiIdx[i+1] = 0;
  pCur->iPage++;

  pCur->info.nSize = 0;
  pCur->validNKey = 0;







|
>







54125
54126
54127
54128
54129
54130
54131
54132
54133
54134
54135
54136
54137
54138
54139
54140
  assert( cursorHoldsMutex(pCur) );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
  assert( pCur->iPage>=0 );
  if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
    return SQLITE_CORRUPT_BKPT;
  }
  rc = getAndInitPage(pBt, newPgno, &pNewPage,
               pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
  if( rc ) return rc;
  pCur->apPage[i+1] = pNewPage;
  pCur->aiIdx[i+1] = 0;
  pCur->iPage++;

  pCur->info.nSize = 0;
  pCur->validNKey = 0;
53931
53932
53933
53934
53935
53936
53937
53938

53939
53940
53941
53942
53943
53944
53945
      releasePage(pCur->apPage[i]);
    }
    pCur->iPage = 0;
  }else if( pCur->pgnoRoot==0 ){
    pCur->eState = CURSOR_INVALID;
    return SQLITE_OK;
  }else{
    rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0);

    if( rc!=SQLITE_OK ){
      pCur->eState = CURSOR_INVALID;
      return rc;
    }
    pCur->iPage = 0;

    /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor







|
>







54243
54244
54245
54246
54247
54248
54249
54250
54251
54252
54253
54254
54255
54256
54257
54258
      releasePage(pCur->apPage[i]);
    }
    pCur->iPage = 0;
  }else if( pCur->pgnoRoot==0 ){
    pCur->eState = CURSOR_INVALID;
    return SQLITE_OK;
  }else{
    rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0],
                        pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
    if( rc!=SQLITE_OK ){
      pCur->eState = CURSOR_INVALID;
      return rc;
    }
    pCur->iPage = 0;

    /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
54326
54327
54328
54329
54330
54331
54332



54333
54334

54335
54336
54337
54338
54339
54340
54341



54342
54343
54344
54345
54346
54347


54348
54349
54350
54351
54352
54353
54354
54355
54356
54357
54358
54359
54360
54361
54362
54363
54364
54365



54366
54367
54368
54369
54370
54371
54372
*/
SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
  int rc;
  int idx;
  MemPage *pPage;

  assert( cursorHoldsMutex(pCur) );



  rc = restoreCursorPosition(pCur);
  if( rc!=SQLITE_OK ){

    return rc;
  }
  assert( pRes!=0 );
  if( CURSOR_INVALID==pCur->eState ){
    *pRes = 1;
    return SQLITE_OK;
  }



  if( pCur->skipNext>0 ){
    pCur->skipNext = 0;
    *pRes = 0;
    return SQLITE_OK;
  }
  pCur->skipNext = 0;



  pPage = pCur->apPage[pCur->iPage];
  idx = ++pCur->aiIdx[pCur->iPage];
  assert( pPage->isInit );

  /* If the database file is corrupt, it is possible for the value of idx 
  ** to be invalid here. This can only occur if a second cursor modifies
  ** the page while cursor pCur is holding a reference to it. Which can
  ** only happen if the database is corrupt in such a way as to link the
  ** page into more than one b-tree structure. */
  testcase( idx>pPage->nCell );

  pCur->info.nSize = 0;
  pCur->validNKey = 0;
  if( idx>=pPage->nCell ){
    if( !pPage->leaf ){
      rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
      if( rc ) return rc;



      rc = moveToLeftmost(pCur);
      *pRes = 0;
      return rc;
    }
    do{
      if( pCur->iPage==0 ){
        *pRes = 1;







>
>
>
|
|
>
|
|
<
|
|
|
|
>
>
>
|
|
|
|
|
|
>
>

















|
>
>
>







54639
54640
54641
54642
54643
54644
54645
54646
54647
54648
54649
54650
54651
54652
54653

54654
54655
54656
54657
54658
54659
54660
54661
54662
54663
54664
54665
54666
54667
54668
54669
54670
54671
54672
54673
54674
54675
54676
54677
54678
54679
54680
54681
54682
54683
54684
54685
54686
54687
54688
54689
54690
54691
54692
54693
54694
54695
54696
*/
SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
  int rc;
  int idx;
  MemPage *pPage;

  assert( cursorHoldsMutex(pCur) );
  assert( pRes!=0 );
  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  if( pCur->eState!=CURSOR_VALID ){
    rc = restoreCursorPosition(pCur);
    if( rc!=SQLITE_OK ){
      *pRes = 0;
      return rc;
    }

    if( CURSOR_INVALID==pCur->eState ){
      *pRes = 1;
      return SQLITE_OK;
    }
    if( pCur->skipNext ){
      assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
      pCur->eState = CURSOR_VALID;
      if( pCur->skipNext>0 ){
        pCur->skipNext = 0;
        *pRes = 0;
        return SQLITE_OK;
      }
      pCur->skipNext = 0;
    }
  }

  pPage = pCur->apPage[pCur->iPage];
  idx = ++pCur->aiIdx[pCur->iPage];
  assert( pPage->isInit );

  /* If the database file is corrupt, it is possible for the value of idx 
  ** to be invalid here. This can only occur if a second cursor modifies
  ** the page while cursor pCur is holding a reference to it. Which can
  ** only happen if the database is corrupt in such a way as to link the
  ** page into more than one b-tree structure. */
  testcase( idx>pPage->nCell );

  pCur->info.nSize = 0;
  pCur->validNKey = 0;
  if( idx>=pPage->nCell ){
    if( !pPage->leaf ){
      rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
      if( rc ){
        *pRes = 0;
        return rc;
      }
      rc = moveToLeftmost(pCur);
      *pRes = 0;
      return rc;
    }
    do{
      if( pCur->iPage==0 ){
        *pRes = 1;
54400
54401
54402
54403
54404
54405
54406





54407
54408

54409
54410
54411

54412
54413
54414
54415



54416
54417
54418
54419
54420
54421


54422
54423
54424
54425
54426
54427
54428

54429
54430
54431
54432
54433
54434
54435
** this routine was called, then set *pRes=1.
*/
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
  int rc;
  MemPage *pPage;

  assert( cursorHoldsMutex(pCur) );





  rc = restoreCursorPosition(pCur);
  if( rc!=SQLITE_OK ){

    return rc;
  }
  pCur->atLast = 0;

  if( CURSOR_INVALID==pCur->eState ){
    *pRes = 1;
    return SQLITE_OK;
  }



  if( pCur->skipNext<0 ){
    pCur->skipNext = 0;
    *pRes = 0;
    return SQLITE_OK;
  }
  pCur->skipNext = 0;



  pPage = pCur->apPage[pCur->iPage];
  assert( pPage->isInit );
  if( !pPage->leaf ){
    int idx = pCur->aiIdx[pCur->iPage];
    rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
    if( rc ){

      return rc;
    }
    rc = moveToRightmost(pCur);
  }else{
    while( pCur->aiIdx[pCur->iPage]==0 ){
      if( pCur->iPage==0 ){
        pCur->eState = CURSOR_INVALID;







>
>
>
>
>
|
|
>
|
|
<
>
|
|
|
|
>
>
>
|
|
|
|
|
|
>
>







>







54724
54725
54726
54727
54728
54729
54730
54731
54732
54733
54734
54735
54736
54737
54738
54739
54740

54741
54742
54743
54744
54745
54746
54747
54748
54749
54750
54751
54752
54753
54754
54755
54756
54757
54758
54759
54760
54761
54762
54763
54764
54765
54766
54767
54768
54769
54770
54771
** this routine was called, then set *pRes=1.
*/
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
  int rc;
  MemPage *pPage;

  assert( cursorHoldsMutex(pCur) );
  assert( pRes!=0 );
  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
  pCur->atLast = 0;
  if( pCur->eState!=CURSOR_VALID ){
    if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){
      rc = btreeRestoreCursorPosition(pCur);
      if( rc!=SQLITE_OK ){
        *pRes = 0;
        return rc;
      }

    }
    if( CURSOR_INVALID==pCur->eState ){
      *pRes = 1;
      return SQLITE_OK;
    }
    if( pCur->skipNext ){
      assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
      pCur->eState = CURSOR_VALID;
      if( pCur->skipNext<0 ){
        pCur->skipNext = 0;
        *pRes = 0;
        return SQLITE_OK;
      }
      pCur->skipNext = 0;
    }
  }

  pPage = pCur->apPage[pCur->iPage];
  assert( pPage->isInit );
  if( !pPage->leaf ){
    int idx = pCur->aiIdx[pCur->iPage];
    rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
    if( rc ){
      *pRes = 0;
      return rc;
    }
    rc = moveToRightmost(pCur);
  }else{
    while( pCur->aiIdx[pCur->iPage]==0 ){
      if( pCur->iPage==0 ){
        pCur->eState = CURSOR_INVALID;
54545
54546
54547
54548
54549
54550
54551
54552
54553
54554
54555
54556
54557
54558
54559
      }else{
        iTrunk = get4byte(&pPage1->aData[32]);
      }
      testcase( iTrunk==mxPage );
      if( iTrunk>mxPage ){
        rc = SQLITE_CORRUPT_BKPT;
      }else{
        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
      }
      if( rc ){
        pTrunk = 0;
        goto end_allocate_page;
      }
      assert( pTrunk!=0 );
      assert( pTrunk->aData!=0 );







|







54881
54882
54883
54884
54885
54886
54887
54888
54889
54890
54891
54892
54893
54894
54895
      }else{
        iTrunk = get4byte(&pPage1->aData[32]);
      }
      testcase( iTrunk==mxPage );
      if( iTrunk>mxPage ){
        rc = SQLITE_CORRUPT_BKPT;
      }else{
        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
      }
      if( rc ){
        pTrunk = 0;
        goto end_allocate_page;
      }
      assert( pTrunk!=0 );
      assert( pTrunk->aData!=0 );
54609
54610
54611
54612
54613
54614
54615
54616
54617
54618
54619
54620
54621
54622
54623
          MemPage *pNewTrunk;
          Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
          if( iNewTrunk>mxPage ){ 
            rc = SQLITE_CORRUPT_BKPT;
            goto end_allocate_page;
          }
          testcase( iNewTrunk==mxPage );
          rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0, 0);
          if( rc!=SQLITE_OK ){
            goto end_allocate_page;
          }
          rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
          if( rc!=SQLITE_OK ){
            releasePage(pNewTrunk);
            goto end_allocate_page;







|







54945
54946
54947
54948
54949
54950
54951
54952
54953
54954
54955
54956
54957
54958
54959
          MemPage *pNewTrunk;
          Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
          if( iNewTrunk>mxPage ){ 
            rc = SQLITE_CORRUPT_BKPT;
            goto end_allocate_page;
          }
          testcase( iNewTrunk==mxPage );
          rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
          if( rc!=SQLITE_OK ){
            goto end_allocate_page;
          }
          rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
          if( rc!=SQLITE_OK ){
            releasePage(pNewTrunk);
            goto end_allocate_page;
54688
54689
54690
54691
54692
54693
54694
54695
54696
54697
54698
54699
54700
54701
54702
54703
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          rc = sqlite3PagerWrite(pTrunk->pDbPage);
          if( rc ) goto end_allocate_page;
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
          put4byte(&aData[4], k-1);
          noContent = !btreeGetHasContent(pBt, *pPgno);
          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent, 0);
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
            if( rc!=SQLITE_OK ){
              releasePage(*ppPage);
            }
          }
          searchList = 0;







|
|







55024
55025
55026
55027
55028
55029
55030
55031
55032
55033
55034
55035
55036
55037
55038
55039
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          rc = sqlite3PagerWrite(pTrunk->pDbPage);
          if( rc ) goto end_allocate_page;
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
          put4byte(&aData[4], k-1);
          noContent = !btreeGetHasContent(pBt, *pPgno) ? PAGER_GET_NOCONTENT : 0;
          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
          if( rc==SQLITE_OK ){
            rc = sqlite3PagerWrite((*ppPage)->pDbPage);
            if( rc!=SQLITE_OK ){
              releasePage(*ppPage);
            }
          }
          searchList = 0;
54721
54722
54723
54724
54725
54726
54727
54728
54729
54730
54731
54732
54733
54734
54735
54736
54737
54738
54739
54740
54741
54742
54743
54744
54745
54746
54747
54748
54749
54750
54751
54752
54753
54754
54755
54756
54757
54758
54759
54760
54761
54762
54763
54764
54765
    **
    ** Note that the pager will not actually attempt to load or journal 
    ** content for any page that really does lie past the end of the database
    ** file on disk. So the effects of disabling the no-content optimization
    ** here are confined to those pages that lie between the end of the
    ** database image and the end of the database file.
    */
    int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate));

    rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
    if( rc ) return rc;
    pBt->nPage++;
    if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;

#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){
      /* If *pPgno refers to a pointer-map page, allocate two new pages
      ** at the end of the file instead of one. The first allocated page
      ** becomes a new pointer-map page, the second is used by the caller.
      */
      MemPage *pPg = 0;
      TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
      assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
      rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent, 0);
      if( rc==SQLITE_OK ){
        rc = sqlite3PagerWrite(pPg->pDbPage);
        releasePage(pPg);
      }
      if( rc ) return rc;
      pBt->nPage++;
      if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; }
    }
#endif
    put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
    *pPgno = pBt->nPage;

    assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
    rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent, 0);
    if( rc ) return rc;
    rc = sqlite3PagerWrite((*ppPage)->pDbPage);
    if( rc!=SQLITE_OK ){
      releasePage(*ppPage);
    }
    TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
  }







|















|













|







55057
55058
55059
55060
55061
55062
55063
55064
55065
55066
55067
55068
55069
55070
55071
55072
55073
55074
55075
55076
55077
55078
55079
55080
55081
55082
55083
55084
55085
55086
55087
55088
55089
55090
55091
55092
55093
55094
55095
55096
55097
55098
55099
55100
55101
    **
    ** Note that the pager will not actually attempt to load or journal 
    ** content for any page that really does lie past the end of the database
    ** file on disk. So the effects of disabling the no-content optimization
    ** here are confined to those pages that lie between the end of the
    ** database image and the end of the database file.
    */
    int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)) ? PAGER_GET_NOCONTENT : 0;

    rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
    if( rc ) return rc;
    pBt->nPage++;
    if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;

#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){
      /* If *pPgno refers to a pointer-map page, allocate two new pages
      ** at the end of the file instead of one. The first allocated page
      ** becomes a new pointer-map page, the second is used by the caller.
      */
      MemPage *pPg = 0;
      TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
      assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
      rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
      if( rc==SQLITE_OK ){
        rc = sqlite3PagerWrite(pPg->pDbPage);
        releasePage(pPg);
      }
      if( rc ) return rc;
      pBt->nPage++;
      if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; }
    }
#endif
    put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
    *pPgno = pBt->nPage;

    assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
    rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
    if( rc ) return rc;
    rc = sqlite3PagerWrite((*ppPage)->pDbPage);
    if( rc!=SQLITE_OK ){
      releasePage(*ppPage);
    }
    TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
  }
54819
54820
54821
54822
54823
54824
54825
54826
54827
54828
54829
54830
54831
54832
54833
  nFree = get4byte(&pPage1->aData[36]);
  put4byte(&pPage1->aData[36], nFree+1);

  if( pBt->btsFlags & BTS_SECURE_DELETE ){
    /* If the secure_delete option is enabled, then
    ** always fully overwrite deleted information with zeros.
    */
    if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0, 0))!=0) )
     ||            ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
    ){
      goto freepage_out;
    }
    memset(pPage->aData, 0, pPage->pBt->pageSize);
  }








|







55155
55156
55157
55158
55159
55160
55161
55162
55163
55164
55165
55166
55167
55168
55169
  nFree = get4byte(&pPage1->aData[36]);
  put4byte(&pPage1->aData[36], nFree+1);

  if( pBt->btsFlags & BTS_SECURE_DELETE ){
    /* If the secure_delete option is enabled, then
    ** always fully overwrite deleted information with zeros.
    */
    if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) )
     ||            ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
    ){
      goto freepage_out;
    }
    memset(pPage->aData, 0, pPage->pBt->pageSize);
  }

54846
54847
54848
54849
54850
54851
54852
54853
54854
54855
54856
54857
54858
54859
54860
  ** first trunk page in the current free-list. This block tests if it
  ** is possible to add the page as a new free-list leaf.
  */
  if( nFree!=0 ){
    u32 nLeaf;                /* Initial number of leaf cells on trunk page */

    iTrunk = get4byte(&pPage1->aData[32]);
    rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
    if( rc!=SQLITE_OK ){
      goto freepage_out;
    }

    nLeaf = get4byte(&pTrunk->aData[4]);
    assert( pBt->usableSize>32 );
    if( nLeaf > (u32)pBt->usableSize/4 - 2 ){







|







55182
55183
55184
55185
55186
55187
55188
55189
55190
55191
55192
55193
55194
55195
55196
  ** first trunk page in the current free-list. This block tests if it
  ** is possible to add the page as a new free-list leaf.
  */
  if( nFree!=0 ){
    u32 nLeaf;                /* Initial number of leaf cells on trunk page */

    iTrunk = get4byte(&pPage1->aData[32]);
    rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
    if( rc!=SQLITE_OK ){
      goto freepage_out;
    }

    nLeaf = get4byte(&pTrunk->aData[4]);
    assert( pBt->usableSize>32 );
    if( nLeaf > (u32)pBt->usableSize/4 - 2 ){
54892
54893
54894
54895
54896
54897
54898
54899
54900
54901
54902
54903
54904
54905
54906

  /* If control flows to this point, then it was not possible to add the
  ** the page being freed as a leaf page of the first trunk in the free-list.
  ** Possibly because the free-list is empty, or possibly because the 
  ** first trunk in the free-list is full. Either way, the page being freed
  ** will become the new first trunk page in the free-list.
  */
  if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0, 0)) ){
    goto freepage_out;
  }
  rc = sqlite3PagerWrite(pPage->pDbPage);
  if( rc!=SQLITE_OK ){
    goto freepage_out;
  }
  put4byte(pPage->aData, iTrunk);







|







55228
55229
55230
55231
55232
55233
55234
55235
55236
55237
55238
55239
55240
55241
55242

  /* If control flows to this point, then it was not possible to add the
  ** the page being freed as a leaf page of the first trunk in the free-list.
  ** Possibly because the free-list is empty, or possibly because the 
  ** first trunk in the free-list is full. Either way, the page being freed
  ** will become the new first trunk page in the free-list.
  */
  if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
    goto freepage_out;
  }
  rc = sqlite3PagerWrite(pPage->pDbPage);
  if( rc!=SQLITE_OK ){
    goto freepage_out;
  }
  put4byte(pPage->aData, iTrunk);
56791
56792
56793
56794
56795
56796
56797
56798
56799
56800
56801
56802
56803
56804
56805
56806
56807
56808
56809
56810
56811
56812
56813
56814
56815
56816
56817
56818
56819
56820
56821
56822
56823
56824
56825
56826
      rc = saveAllCursors(pBt, 0, 0);
      releasePage(pPageMove);
      if( rc!=SQLITE_OK ){
        return rc;
      }

      /* Move the page currently at pgnoRoot to pgnoMove. */
      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
      if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
        rc = SQLITE_CORRUPT_BKPT;
      }
      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;
      }
      assert( eType!=PTRMAP_ROOTPAGE );
      assert( eType!=PTRMAP_FREEPAGE );
      rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0);
      releasePage(pRoot);

      /* Obtain the page at pgnoRoot */
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = sqlite3PagerWrite(pRoot->pDbPage);
      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;







|




















|







57127
57128
57129
57130
57131
57132
57133
57134
57135
57136
57137
57138
57139
57140
57141
57142
57143
57144
57145
57146
57147
57148
57149
57150
57151
57152
57153
57154
57155
57156
57157
57158
57159
57160
57161
57162
      rc = saveAllCursors(pBt, 0, 0);
      releasePage(pPageMove);
      if( rc!=SQLITE_OK ){
        return rc;
      }

      /* Move the page currently at pgnoRoot to pgnoMove. */
      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
      if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
        rc = SQLITE_CORRUPT_BKPT;
      }
      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;
      }
      assert( eType!=PTRMAP_ROOTPAGE );
      assert( eType!=PTRMAP_FREEPAGE );
      rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0);
      releasePage(pRoot);

      /* Obtain the page at pgnoRoot */
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = sqlite3PagerWrite(pRoot->pDbPage);
      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;
56990
56991
56992
56993
56994
56995
56996
56997
56998
56999
57000
57001
57002
57003
57004
  ** This error is caught long before control reaches this point.
  */
  if( NEVER(pBt->pCursor) ){
    sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db);
    return SQLITE_LOCKED_SHAREDCACHE;
  }

  rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0, 0);
  if( rc ) return rc;
  rc = sqlite3BtreeClearTable(p, iTable, 0);
  if( rc ){
    releasePage(pPage);
    return rc;
  }








|







57326
57327
57328
57329
57330
57331
57332
57333
57334
57335
57336
57337
57338
57339
57340
  ** This error is caught long before control reaches this point.
  */
  if( NEVER(pBt->pCursor) ){
    sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db);
    return SQLITE_LOCKED_SHAREDCACHE;
  }

  rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
  if( rc ) return rc;
  rc = sqlite3BtreeClearTable(p, iTable, 0);
  if( rc ){
    releasePage(pPage);
    return rc;
  }

57025
57026
57027
57028
57029
57030
57031
57032
57033
57034
57035
57036
57037
57038
57039
57040
57041
57042
57043
57044
57045
57046
57047
57048
57049
      }else{
        /* The table being dropped does not have the largest root-page
        ** number in the database. So move the page that does into the 
        ** gap left by the deleted root-page.
        */
        MemPage *pMove;
        releasePage(pPage);
        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
        releasePage(pMove);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        pMove = 0;
        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
        freePage(pMove, &rc);
        releasePage(pMove);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        *piMoved = maxRootPgno;
      }







|









|







57361
57362
57363
57364
57365
57366
57367
57368
57369
57370
57371
57372
57373
57374
57375
57376
57377
57378
57379
57380
57381
57382
57383
57384
57385
      }else{
        /* The table being dropped does not have the largest root-page
        ** number in the database. So move the page that does into the 
        ** gap left by the deleted root-page.
        */
        MemPage *pMove;
        releasePage(pPage);
        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
        releasePage(pMove);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        pMove = 0;
        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
        freePage(pMove, &rc);
        releasePage(pMove);
        if( rc!=SQLITE_OK ){
          return rc;
        }
        *piMoved = maxRootPgno;
      }
57250
57251
57252
57253
57254
57255
57256
57257
57258
57259
57260
57261
57262
57263
57264
    sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
  }
  if( zMsg1 ){
    sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1);
  }
  sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
  va_end(ap);
  if( pCheck->errMsg.mallocFailed ){
    pCheck->mallocFailed = 1;
  }
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_INTEGRITY_CHECK








|







57586
57587
57588
57589
57590
57591
57592
57593
57594
57595
57596
57597
57598
57599
57600
    sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
  }
  if( zMsg1 ){
    sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1);
  }
  sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
  va_end(ap);
  if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
    pCheck->mallocFailed = 1;
  }
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_INTEGRITY_CHECK

57447
57448
57449
57450
57451
57452
57453
57454
57455
57456
57457
57458
57459
57460
57461

  /* Check that the page exists
  */
  pBt = pCheck->pBt;
  usableSize = pBt->usableSize;
  if( iPage==0 ) return 0;
  if( checkRef(pCheck, iPage, zParentContext) ) return 0;
  if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0, 0))!=0 ){
    checkAppendMsg(pCheck, zContext,
       "unable to get the page. error code=%d", rc);
    return 0;
  }

  /* Clear MemPage.isInit to make sure the corruption detection code in
  ** btreeInitPage() is executed.  */







|







57783
57784
57785
57786
57787
57788
57789
57790
57791
57792
57793
57794
57795
57796
57797

  /* Check that the page exists
  */
  pBt = pCheck->pBt;
  usableSize = pBt->usableSize;
  if( iPage==0 ) return 0;
  if( checkRef(pCheck, iPage, zParentContext) ) return 0;
  if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
    checkAppendMsg(pCheck, zContext,
       "unable to get the page. error code=%d", rc);
    return 0;
  }

  /* Clear MemPage.isInit to make sure the corruption detection code in
  ** btreeInitPage() is executed.  */
58406
58407
58408
58409
58410
58411
58412
58413
58414
58415
58416
58417
58418
58419
58420
    nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc);
    assert( nSrcPage>=0 );
    for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
      const Pgno iSrcPg = p->iNext;                 /* Source page number */
      if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
        DbPage *pSrcPg;                             /* Source page object */
        rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
                                 PAGER_ACQUIRE_READONLY);
        if( rc==SQLITE_OK ){
          rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
          sqlite3PagerUnref(pSrcPg);
        }
      }
      p->iNext++;
    }







|







58742
58743
58744
58745
58746
58747
58748
58749
58750
58751
58752
58753
58754
58755
58756
    nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc);
    assert( nSrcPage>=0 );
    for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
      const Pgno iSrcPg = p->iNext;                 /* Source page number */
      if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
        DbPage *pSrcPg;                             /* Source page object */
        rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
                                 PAGER_GET_READONLY);
        if( rc==SQLITE_OK ){
          rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
          sqlite3PagerUnref(pSrcPg);
        }
      }
      p->iNext++;
    }
59561
59562
59563
59564
59565
59566
59567

59568
59569
59570
59571
59572
59573
59574
59575
59576


59577
59578
59579
59580
59581


59582
59583
59584

59585
59586
59587
59588
59589
59590
59591
59592
59593
59594
59595
59596
59597
59598
59599
59600
59601
59602
  }

  /* If one value is a number and the other is not, the number is less.
  ** If both are numbers, compare as reals if one is a real, or as integers
  ** if both values are integers.
  */
  if( combined_flags&(MEM_Int|MEM_Real) ){

    if( !(f1&(MEM_Int|MEM_Real)) ){
      return 1;
    }
    if( !(f2&(MEM_Int|MEM_Real)) ){
      return -1;
    }
    if( (f1 & f2 & MEM_Int)==0 ){
      double r1, r2;
      if( (f1&MEM_Real)==0 ){


        r1 = (double)pMem1->u.i;
      }else{
        r1 = pMem1->r;
      }
      if( (f2&MEM_Real)==0 ){


        r2 = (double)pMem2->u.i;
      }else{
        r2 = pMem2->r;

      }
      if( r1<r2 ) return -1;
      if( r1>r2 ) return 1;
      return 0;
    }else{
      assert( f1&MEM_Int );
      assert( f2&MEM_Int );
      if( pMem1->u.i < pMem2->u.i ) return -1;
      if( pMem1->u.i > pMem2->u.i ) return 1;
      return 0;
    }
  }

  /* If one value is a string and the other is a blob, the string is less.
  ** If both are strings, compare using the collating functions.
  */
  if( combined_flags&MEM_Str ){
    if( (f1 & MEM_Str)==0 ){







>
|
|
<
|
|

<
<
|
>
>
|
|
|
|
|
>
>
|
|
<
>
|
|
|
|
<
<
<
<
<
<
<







59897
59898
59899
59900
59901
59902
59903
59904
59905
59906

59907
59908
59909


59910
59911
59912
59913
59914
59915
59916
59917
59918
59919
59920
59921

59922
59923
59924
59925
59926







59927
59928
59929
59930
59931
59932
59933
  }

  /* If one value is a number and the other is not, the number is less.
  ** If both are numbers, compare as reals if one is a real, or as integers
  ** if both values are integers.
  */
  if( combined_flags&(MEM_Int|MEM_Real) ){
    double r1, r2;
    if( (f1 & f2 & MEM_Int)!=0 ){
      if( pMem1->u.i < pMem2->u.i ) return -1;

      if( pMem1->u.i > pMem2->u.i ) return 1;
      return 0;
    }


    if( (f1&MEM_Real)!=0 ){
      r1 = pMem1->r;
    }else if( (f1&MEM_Int)!=0 ){
      r1 = (double)pMem1->u.i;
    }else{
      return 1;
    }
    if( (f2&MEM_Real)!=0 ){
      r2 = pMem2->r;
    }else if( (f2&MEM_Int)!=0 ){
      r2 = (double)pMem2->u.i;
    }else{

      return -1;
    }
    if( r1<r2 ) return -1;
    if( r1>r2 ) return 1;
    return 0;







  }

  /* If one value is a string and the other is a blob, the string is less.
  ** If both are strings, compare using the collating functions.
  */
  if( combined_flags&MEM_Str ){
    if( (f1 & MEM_Str)==0 ){
59768
59769
59770
59771
59772
59773
59774









59775




59776










59777





59778






















59779






59780


59781
59782





59783
59784
59785
59786
59787
59788
59789

59790
59791
59792
59793
59794
59795

59796
59797
59798
59799
59800
59801
59802
59803
59804
59805
59806
59807
59808
59809
59810
59811
59812
59813
59814
59815
59816
59817
59818
59819
59820
59821
59822
59823
59824
59825
59826
59827
59828
59829
59830
59831
59832
59833
59834
59835
59836
59837
59838
59839
59840
59841
59842
59843
59844
59845
59846


59847
59848
59849
59850
59851
59852
59853
59854
59855
59856
59857
59858
59859
59860
59861
59862
59863
59864
59865
59866
59867
59868
59869
59870
59871
59872
59873
59874
59875
59876
59877
59878
59879
59880
59881
59882
59883
59884
59885


59886

59887

59888
59889
59890






















































































































































































59891
59892
59893
59894
59895
59896
59897
    p->type = SQLITE_NULL;
    p->db = db;
  }
  return p;
}

/*









** Create a new sqlite3_value object, containing the value of pExpr.




**










** This only works for very simple expressions that consist of one constant





** token (i.e. "5", "5.1", "'a string'"). If the expression can






















** be converted directly into a value, then the value is allocated and






** a pointer written to *ppVal. The caller is responsible for deallocating


** the value by passing it to sqlite3ValueFree() later on. If the expression
** cannot be converted to a value, then *ppVal is set to NULL.





*/
SQLITE_PRIVATE int sqlite3ValueFromExpr(
  sqlite3 *db,              /* The database connection */
  Expr *pExpr,              /* The expression to evaluate */
  u8 enc,                   /* Encoding to use */
  u8 affinity,              /* Affinity to use */
  sqlite3_value **ppVal     /* Write the new value here */

){
  int op;
  char *zVal = 0;
  sqlite3_value *pVal = 0;
  int negInt = 1;
  const char *zNeg = "";


  if( !pExpr ){
    *ppVal = 0;
    return SQLITE_OK;
  }
  op = pExpr->op;

  /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3.
  ** The ifdef here is to enable us to achieve 100% branch test coverage even
  ** when SQLITE_ENABLE_STAT3 is omitted.
  */
#ifdef SQLITE_ENABLE_STAT3
  if( op==TK_REGISTER ) op = pExpr->op2;
#else
  if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
#endif

  /* Handle negative integers in a single step.  This is needed in the
  ** case when the value is -9223372036854775808.
  */
  if( op==TK_UMINUS
   && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){
    pExpr = pExpr->pLeft;
    op = pExpr->op;
    negInt = -1;
    zNeg = "-";
  }

  if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
    pVal = sqlite3ValueNew(db);
    if( pVal==0 ) goto no_mem;
    if( ExprHasProperty(pExpr, EP_IntValue) ){
      sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt);
    }else{
      zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken);
      if( zVal==0 ) goto no_mem;
      sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
      if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT;
    }
    if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
      sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
    }else{
      sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
    }
    if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
    if( enc!=SQLITE_UTF8 ){
      sqlite3VdbeChangeEncoding(pVal, enc);
    }
  }else if( op==TK_UMINUS ) {
    /* This branch happens for multiple negative signs.  Ex: -(-5) */
    if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){


      sqlite3VdbeMemNumerify(pVal);
      if( pVal->u.i==SMALLEST_INT64 ){
        pVal->flags &= MEM_Int;
        pVal->flags |= MEM_Real;
        pVal->r = (double)LARGEST_INT64;
      }else{
        pVal->u.i = -pVal->u.i;
      }
      pVal->r = -pVal->r;
      sqlite3ValueApplyAffinity(pVal, affinity, enc);
    }
  }else if( op==TK_NULL ){
    pVal = sqlite3ValueNew(db);
    if( pVal==0 ) goto no_mem;
  }
#ifndef SQLITE_OMIT_BLOB_LITERAL
  else if( op==TK_BLOB ){
    int nVal;
    assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
    assert( pExpr->u.zToken[1]=='\'' );
    pVal = sqlite3ValueNew(db);
    if( !pVal ) goto no_mem;
    zVal = &pExpr->u.zToken[2];
    nVal = sqlite3Strlen30(zVal)-1;
    assert( zVal[nVal]=='\'' );
    sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
                         0, SQLITE_DYNAMIC);
  }
#endif

  if( pVal ){
    sqlite3VdbeMemStoreType(pVal);
  }
  *ppVal = pVal;
  return SQLITE_OK;

no_mem:
  db->mallocFailed = 1;
  sqlite3DbFree(db, zVal);


  sqlite3ValueFree(pVal);

  *ppVal = 0;

  return SQLITE_NOMEM;
}























































































































































































/*
** Change the string value of an sqlite3_value object
*/
SQLITE_PRIVATE void sqlite3ValueSetStr(
  sqlite3_value *v,     /* Value to be set */
  int n,                /* Length of string z */
  const void *z,        /* Text of the new string */







>
>
>
>
>
>
>
>
>
|
>
>
>
>

>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
|
|
>
>
>
>
>

|
|
|
|
|
|
>






>







|

|

|

















|
















|



|
>
>












|







|













|




>
>
|
>
|
>



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







60099
60100
60101
60102
60103
60104
60105
60106
60107
60108
60109
60110
60111
60112
60113
60114
60115
60116
60117
60118
60119
60120
60121
60122
60123
60124
60125
60126
60127
60128
60129
60130
60131
60132
60133
60134
60135
60136
60137
60138
60139
60140
60141
60142
60143
60144
60145
60146
60147
60148
60149
60150
60151
60152
60153
60154
60155
60156
60157
60158
60159
60160
60161
60162
60163
60164
60165
60166
60167
60168
60169
60170
60171
60172
60173
60174
60175
60176
60177
60178
60179
60180
60181
60182
60183
60184
60185
60186
60187
60188
60189
60190
60191
60192
60193
60194
60195
60196
60197
60198
60199
60200
60201
60202
60203
60204
60205
60206
60207
60208
60209
60210
60211
60212
60213
60214
60215
60216
60217
60218
60219
60220
60221
60222
60223
60224
60225
60226
60227
60228
60229
60230
60231
60232
60233
60234
60235
60236
60237
60238
60239
60240
60241
60242
60243
60244
60245
60246
60247
60248
60249
60250
60251
60252
60253
60254
60255
60256
60257
60258
60259
60260
60261
60262
60263
60264
60265
60266
60267
60268
60269
60270
60271
60272
60273
60274
60275
60276
60277
60278
60279
60280
60281
60282
60283
60284
60285
60286
60287
60288
60289
60290
60291
60292
60293
60294
60295
60296
60297
60298
60299
60300
60301
60302
60303
60304
60305
60306
60307
60308
60309
60310
60311
60312
60313
60314
60315
60316
60317
60318
60319
60320
60321
60322
60323
60324
60325
60326
60327
60328
60329
60330
60331
60332
60333
60334
60335
60336
60337
60338
60339
60340
60341
60342
60343
60344
60345
60346
60347
60348
60349
60350
60351
60352
60353
60354
60355
60356
60357
60358
60359
60360
60361
60362
60363
60364
60365
60366
60367
60368
60369
60370
60371
60372
60373
60374
60375
60376
60377
60378
60379
60380
60381
60382
60383
60384
60385
60386
60387
60388
60389
60390
60391
60392
60393
60394
60395
60396
60397
60398
60399
60400
60401
60402
60403
60404
60405
60406
60407
60408
60409
60410
60411
60412
60413
60414
60415
60416
60417
60418
60419
60420
60421
60422
60423
60424
60425
60426
60427
60428
60429
60430
60431
60432
60433
60434
60435
60436
60437
60438
60439
60440
60441
60442
60443
60444
60445
60446
60447
60448
60449
60450
60451
60452
60453
60454
60455
60456
60457
60458
60459
60460
60461
60462
60463
60464
60465
60466
60467
60468
60469
60470
60471
60472
60473
60474
60475
60476
60477
60478
60479
60480
60481
    p->type = SQLITE_NULL;
    p->db = db;
  }
  return p;
}

/*
** Context object passed by sqlite3Stat4ProbeSetValue() through to 
** valueNew(). See comments above valueNew() for details.
*/
struct ValueNewStat4Ctx {
  Parse *pParse;
  Index *pIdx;
  UnpackedRecord **ppRec;
  int iVal;
};

/*
** Allocate and return a pointer to a new sqlite3_value object. If
** the second argument to this function is NULL, the object is allocated
** by calling sqlite3ValueNew().
**
** Otherwise, if the second argument is non-zero, then this function is 
** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
** already been allocated, allocate the UnpackedRecord structure that 
** that function will return to its caller here. Then return a pointer 
** an sqlite3_value within the UnpackedRecord.a[] array.
*/
static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( p ){
    UnpackedRecord *pRec = p->ppRec[0];

    if( pRec==0 ){
      Index *pIdx = p->pIdx;      /* Index being probed */
      int nByte;                  /* Bytes of space to allocate */
      int i;                      /* Counter variable */
      int nCol = pIdx->nColumn+1; /* Number of index columns including rowid */
  
      nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord);
      pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte);
      if( pRec ){
        pRec->pKeyInfo = sqlite3IndexKeyinfo(p->pParse, pIdx);
        if( pRec->pKeyInfo ){
          assert( pRec->pKeyInfo->nField+1==nCol );
          pRec->pKeyInfo->enc = ENC(db);
          pRec->flags = UNPACKED_PREFIX_MATCH;
          pRec->aMem = (Mem *)&pRec[1];
          for(i=0; i<nCol; i++){
            pRec->aMem[i].flags = MEM_Null;
            pRec->aMem[i].type = SQLITE_NULL;
            pRec->aMem[i].db = db;
          }
        }else{
          sqlite3DbFree(db, pRec);
          pRec = 0;
        }
      }
      if( pRec==0 ) return 0;
      p->ppRec[0] = pRec;
    }
  
    pRec->nField = p->iVal+1;
    return &pRec->aMem[p->iVal];
  }
#endif
  return sqlite3ValueNew(db);
}

/*
** Extract a value from the supplied expression in the manner described
** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
** using valueNew().
**
** If pCtx is NULL and an error occurs after the sqlite3_value object
** has been allocated, it is freed before returning. Or, if pCtx is not
** NULL, it is assumed that the caller will free any allocated object
** in all cases.
*/
int valueFromExpr(
  sqlite3 *db,                    /* The database connection */
  Expr *pExpr,                    /* The expression to evaluate */
  u8 enc,                         /* Encoding to use */
  u8 affinity,                    /* Affinity to use */
  sqlite3_value **ppVal,          /* Write the new value here */
  struct ValueNewStat4Ctx *pCtx   /* Second argument for valueNew() */
){
  int op;
  char *zVal = 0;
  sqlite3_value *pVal = 0;
  int negInt = 1;
  const char *zNeg = "";
  int rc = SQLITE_OK;

  if( !pExpr ){
    *ppVal = 0;
    return SQLITE_OK;
  }
  op = pExpr->op;

  /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT4.
  ** The ifdef here is to enable us to achieve 100% branch test coverage even
  ** when SQLITE_ENABLE_STAT4 is omitted.
  */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( op==TK_REGISTER ) op = pExpr->op2;
#else
  if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
#endif

  /* Handle negative integers in a single step.  This is needed in the
  ** case when the value is -9223372036854775808.
  */
  if( op==TK_UMINUS
   && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){
    pExpr = pExpr->pLeft;
    op = pExpr->op;
    negInt = -1;
    zNeg = "-";
  }

  if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
    pVal = valueNew(db, pCtx);
    if( pVal==0 ) goto no_mem;
    if( ExprHasProperty(pExpr, EP_IntValue) ){
      sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt);
    }else{
      zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken);
      if( zVal==0 ) goto no_mem;
      sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
      if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT;
    }
    if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
      sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
    }else{
      sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
    }
    if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
    if( enc!=SQLITE_UTF8 ){
      rc = sqlite3VdbeChangeEncoding(pVal, enc);
    }
  }else if( op==TK_UMINUS ) {
    /* This branch happens for multiple negative signs.  Ex: -(-5) */
    if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) 
     && pVal!=0
    ){
      sqlite3VdbeMemNumerify(pVal);
      if( pVal->u.i==SMALLEST_INT64 ){
        pVal->flags &= MEM_Int;
        pVal->flags |= MEM_Real;
        pVal->r = (double)LARGEST_INT64;
      }else{
        pVal->u.i = -pVal->u.i;
      }
      pVal->r = -pVal->r;
      sqlite3ValueApplyAffinity(pVal, affinity, enc);
    }
  }else if( op==TK_NULL ){
    pVal = valueNew(db, pCtx);
    if( pVal==0 ) goto no_mem;
  }
#ifndef SQLITE_OMIT_BLOB_LITERAL
  else if( op==TK_BLOB ){
    int nVal;
    assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
    assert( pExpr->u.zToken[1]=='\'' );
    pVal = valueNew(db, pCtx);
    if( !pVal ) goto no_mem;
    zVal = &pExpr->u.zToken[2];
    nVal = sqlite3Strlen30(zVal)-1;
    assert( zVal[nVal]=='\'' );
    sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
                         0, SQLITE_DYNAMIC);
  }
#endif

  if( pVal ){
    sqlite3VdbeMemStoreType(pVal);
  }
  *ppVal = pVal;
  return rc;

no_mem:
  db->mallocFailed = 1;
  sqlite3DbFree(db, zVal);
  assert( *ppVal==0 );
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( pCtx==0 ) sqlite3ValueFree(pVal);
#else
  assert( pCtx==0 ); sqlite3ValueFree(pVal);
#endif
  return SQLITE_NOMEM;
}

/*
** Create a new sqlite3_value object, containing the value of pExpr.
**
** This only works for very simple expressions that consist of one constant
** token (i.e. "5", "5.1", "'a string'"). If the expression can
** be converted directly into a value, then the value is allocated and
** a pointer written to *ppVal. The caller is responsible for deallocating
** the value by passing it to sqlite3ValueFree() later on. If the expression
** cannot be converted to a value, then *ppVal is set to NULL.
*/
SQLITE_PRIVATE int sqlite3ValueFromExpr(
  sqlite3 *db,              /* The database connection */
  Expr *pExpr,              /* The expression to evaluate */
  u8 enc,                   /* Encoding to use */
  u8 affinity,              /* Affinity to use */
  sqlite3_value **ppVal     /* Write the new value here */
){
  return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
}

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** The implementation of the sqlite_record() function. This function accepts
** a single argument of any type. The return value is a formatted database 
** record (a blob) containing the argument value.
**
** This is used to convert the value stored in the 'sample' column of the
** sqlite_stat3 table to the record format SQLite uses internally.
*/
static void recordFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const int file_format = 1;
  int iSerial;                    /* Serial type */
  int nSerial;                    /* Bytes of space for iSerial as varint */
  int nVal;                       /* Bytes of space required for argv[0] */
  int nRet;
  sqlite3 *db;
  u8 *aRet;

  iSerial = sqlite3VdbeSerialType(argv[0], file_format);
  nSerial = sqlite3VarintLen(iSerial);
  nVal = sqlite3VdbeSerialTypeLen(iSerial);
  db = sqlite3_context_db_handle(context);

  nRet = 1 + nSerial + nVal;
  aRet = sqlite3DbMallocRaw(db, nRet);
  if( aRet==0 ){
    sqlite3_result_error_nomem(context);
  }else{
    aRet[0] = nSerial+1;
    sqlite3PutVarint(&aRet[1], iSerial);
    sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format);
    sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
    sqlite3DbFree(db, aRet);
  }
}

/*
** Register built-in functions used to help read ANALYZE data.
*/
SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){
  static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = {
    FUNCTION(sqlite_record,   1, 0, 0, recordFunc),
  };
  int i;
  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs);
  for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){
    sqlite3FuncDefInsert(pHash, &aFunc[i]);
  }
}

/*
** This function is used to allocate and populate UnpackedRecord 
** structures intended to be compared against sample index keys stored 
** in the sqlite_stat4 table.
**
** A single call to this function attempts to populates field iVal (leftmost 
** is 0 etc.) of the unpacked record with a value extracted from expression
** pExpr. Extraction of values is possible if:
**
**  * (pExpr==0). In this case the value is assumed to be an SQL NULL,
**
**  * The expression is a bound variable, and this is a reprepare, or
**
**  * The sqlite3ValueFromExpr() function is able to extract a value 
**    from the expression (i.e. the expression is a literal value).
**
** If a value can be extracted, the affinity passed as the 5th argument
** is applied to it before it is copied into the UnpackedRecord. Output
** parameter *pbOk is set to true if a value is extracted, or false 
** otherwise.
**
** When this function is called, *ppRec must either point to an object
** allocated by an earlier call to this function, or must be NULL. If it
** is NULL and a value can be successfully extracted, a new UnpackedRecord
** is allocated (and *ppRec set to point to it) before returning.
**
** Unless an error is encountered, SQLITE_OK is returned. It is not an
** error if a value cannot be extracted from pExpr. If an error does
** occur, an SQLite error code is returned.
*/
SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
  Parse *pParse,                  /* Parse context */
  Index *pIdx,                    /* Index being probed */
  UnpackedRecord **ppRec,         /* IN/OUT: Probe record */
  Expr *pExpr,                    /* The expression to extract a value from */
  u8 affinity,                    /* Affinity to use */
  int iVal,                       /* Array element to populate */
  int *pbOk                       /* OUT: True if value was extracted */
){
  int rc = SQLITE_OK;
  sqlite3_value *pVal = 0;

  struct ValueNewStat4Ctx alloc;
  alloc.pParse = pParse;
  alloc.pIdx = pIdx;
  alloc.ppRec = ppRec;
  alloc.iVal = iVal;

  /* Skip over any TK_COLLATE nodes */
  pExpr = sqlite3ExprSkipCollate(pExpr);

  if( !pExpr ){
    pVal = valueNew(pParse->db, &alloc);
    if( pVal ){
      sqlite3VdbeMemSetNull((Mem*)pVal);
      *pbOk = 1;
    }
  }else if( pExpr->op==TK_VARIABLE
        || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
  ){
    Vdbe *v;
    int iBindVar = pExpr->iColumn;
    sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
    if( (v = pParse->pReprepare)!=0 ){
      pVal = valueNew(pParse->db, &alloc);
      if( pVal ){
        rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
        if( rc==SQLITE_OK ){
          sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
        }
        pVal->db = pParse->db;
        *pbOk = 1;
        sqlite3VdbeMemStoreType((Mem*)pVal);
      }
    }else{
      *pbOk = 0;
    }
  }else{
    sqlite3 *db = pParse->db;
    rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc);
    *pbOk = (pVal!=0);
  }

  assert( pVal==0 || pVal->db==pParse->db );
  return rc;
}

/*
** Unless it is NULL, the argument must be an UnpackedRecord object returned
** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes
** the object.
*/
SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
  if( pRec ){
    int i;
    int nCol = pRec->pKeyInfo->nField+1;
    Mem *aMem = pRec->aMem;
    sqlite3 *db = aMem[0].db;
    for(i=0; i<nCol; i++){
      sqlite3DbFree(db, aMem[i].zMalloc);
    }
    sqlite3DbFree(db, pRec->pKeyInfo);
    sqlite3DbFree(db, pRec);
  }
}
#endif /* ifdef SQLITE_ENABLE_STAT4 */

/*
** Change the string value of an sqlite3_value object
*/
SQLITE_PRIVATE void sqlite3ValueSetStr(
  sqlite3_value *v,     /* Value to be set */
  int n,                /* Length of string z */
  const void *z,        /* Text of the new string */
60174
60175
60176
60177
60178
60179
60180
60181
60182
60183
60184
60185
60186
60187
60188
60189
** Resolve label "x" to be the address of the next instruction to
** be inserted.  The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
  int j = -1-x;
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( j>=0 && j<p->nLabel );
  if( p->aLabel ){
    p->aLabel[j] = p->nOp;
  }
}

/*
** Mark the VDBE as one that can only be run one time.
*/







|
|







60758
60759
60760
60761
60762
60763
60764
60765
60766
60767
60768
60769
60770
60771
60772
60773
** Resolve label "x" to be the address of the next instruction to
** be inserted.  The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
  int j = -1-x;
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( j<p->nLabel );
  if( j>=0 && p->aLabel ){
    p->aLabel[j] = p->nOp;
  }
}

/*
** Mark the VDBE as one that can only be run one time.
*/
60331
60332
60333
60334
60335
60336
60337


60338
60339

60340


60341
60342
60343


60344

60345
60346
60347


60348
60349
60350
60351


60352
60353


60354
60355
60356


60357
60358
60359
60360
60361
60362


60363

60364
60365
60366


60367
60368
60369

60370
60371


60372
60373
60374
60375
60376
60377
60378
  Op *pOp;
  int *aLabel = p->aLabel;
  p->readOnly = 1;
  p->bIsReader = 0;
  for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
    u8 opcode = pOp->opcode;



    pOp->opflags = sqlite3OpcodeProperty[opcode];
    if( opcode==OP_Function || opcode==OP_AggStep ){

      if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;


    }else if( opcode==OP_Transaction ){
      if( pOp->p2!=0 ) p->readOnly = 0;
      p->bIsReader = 1;


    }else if( opcode==OP_AutoCommit || opcode==OP_Savepoint ){

      p->bIsReader = 1;
    }else if( opcode==OP_Vacuum
           || opcode==OP_JournalMode


#ifndef SQLITE_OMIT_WAL
           || opcode==OP_Checkpoint
#endif
    ){


      p->readOnly = 0;
      p->bIsReader = 1;


#ifndef SQLITE_OMIT_VIRTUALTABLE
    }else if( opcode==OP_VUpdate ){
      if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;


    }else if( opcode==OP_VFilter ){
      int n;
      assert( p->nOp - i >= 3 );
      assert( pOp[-1].opcode==OP_Integer );
      n = pOp[-1].p1;
      if( n>nMaxArgs ) nMaxArgs = n;


#endif

    }else if( opcode==OP_Next || opcode==OP_SorterNext ){
      pOp->p4.xAdvance = sqlite3BtreeNext;
      pOp->p4type = P4_ADVANCE;


    }else if( opcode==OP_Prev ){
      pOp->p4.xAdvance = sqlite3BtreePrevious;
      pOp->p4type = P4_ADVANCE;

    }



    if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
      assert( -1-pOp->p2<p->nLabel );
      pOp->p2 = aLabel[-1-pOp->p2];
    }
  }
  sqlite3DbFree(p->db, p->aLabel);
  p->aLabel = 0;







>
>
|
|
>
|
>
>
|
|
<
>
>
|
>
|
<
<
>
>

|

<
>
>
|
|
>
>

|
|
>
>
|
|
|
|
|
|
>
>

>
|
|
|
>
>
|
|
|
>
|
|
>
>







60915
60916
60917
60918
60919
60920
60921
60922
60923
60924
60925
60926
60927
60928
60929
60930
60931

60932
60933
60934
60935
60936


60937
60938
60939
60940
60941

60942
60943
60944
60945
60946
60947
60948
60949
60950
60951
60952
60953
60954
60955
60956
60957
60958
60959
60960
60961
60962
60963
60964
60965
60966
60967
60968
60969
60970
60971
60972
60973
60974
60975
60976
60977
60978
60979
60980
60981
60982
  Op *pOp;
  int *aLabel = p->aLabel;
  p->readOnly = 1;
  p->bIsReader = 0;
  for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
    u8 opcode = pOp->opcode;

    /* NOTE: Be sure to update mkopcodeh.awk when adding or removing
    ** cases from this switch! */
    switch( opcode ){
      case OP_Function:
      case OP_AggStep: {
        if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
        break;
      }
      case OP_Transaction: {
        if( pOp->p2!=0 ) p->readOnly = 0;

        /* fall thru */
      }
      case OP_AutoCommit:
      case OP_Savepoint: {
        p->bIsReader = 1;


        break;
      }
#ifndef SQLITE_OMIT_WAL
      case OP_Checkpoint:
#endif

      case OP_Vacuum:
      case OP_JournalMode: {
        p->readOnly = 0;
        p->bIsReader = 1;
        break;
      }
#ifndef SQLITE_OMIT_VIRTUALTABLE
      case OP_VUpdate: {
        if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
        break;
      }
      case OP_VFilter: {
        int n;
        assert( p->nOp - i >= 3 );
        assert( pOp[-1].opcode==OP_Integer );
        n = pOp[-1].p1;
        if( n>nMaxArgs ) nMaxArgs = n;
        break;
      }
#endif
      case OP_Next:
      case OP_SorterNext: {
        pOp->p4.xAdvance = sqlite3BtreeNext;
        pOp->p4type = P4_ADVANCE;
        break;
      }
      case OP_Prev: {
        pOp->p4.xAdvance = sqlite3BtreePrevious;
        pOp->p4type = P4_ADVANCE;
        break;
      }
    }

    pOp->opflags = sqlite3OpcodeProperty[opcode];
    if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
      assert( -1-pOp->p2<p->nLabel );
      pOp->p2 = aLabel[-1-pOp->p2];
    }
  }
  sqlite3DbFree(p->db, p->aLabel);
  p->aLabel = 0;
60499
60500
60501
60502
60503
60504
60505
60506
60507
60508
60509
60510
60511
60512
60513
60514
}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  assert( addr>=0 || p->db->mallocFailed );
  if( addr>=0 ) sqlite3VdbeChangeP2(p, addr, p->nOp);
}


/*
** If the input FuncDef structure is ephemeral, then free it.  If
** the FuncDef is not ephermal, then do nothing.
*/







<
|







61103
61104
61105
61106
61107
61108
61109

61110
61111
61112
61113
61114
61115
61116
61117
}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){

  if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp);
}


/*
** If the input FuncDef structure is ephemeral, then free it.  If
** the FuncDef is not ephermal, then do nothing.
*/
60536
60537
60538
60539
60540
60541
60542
60543
60544
60545
60546
60547
60548
60549
60550
60551
60552
60553
60554
60555
60556
        sqlite3DbFree(db, p4);
        break;
      }
      case P4_MPRINTF: {
        if( db->pnBytesFreed==0 ) sqlite3_free(p4);
        break;
      }
      case P4_VDBEFUNC: {
        VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
        freeEphemeralFunction(db, pVdbeFunc->pFunc);
        if( db->pnBytesFreed==0 ) sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
        sqlite3DbFree(db, pVdbeFunc);
        break;
      }
      case P4_FUNCDEF: {
        freeEphemeralFunction(db, (FuncDef*)p4);
        break;
      }
      case P4_MEM: {
        if( db->pnBytesFreed==0 ){
          sqlite3ValueFree((sqlite3_value*)p4);







<
<
<
<
<
<
<







61139
61140
61141
61142
61143
61144
61145







61146
61147
61148
61149
61150
61151
61152
        sqlite3DbFree(db, p4);
        break;
      }
      case P4_MPRINTF: {
        if( db->pnBytesFreed==0 ) sqlite3_free(p4);
        break;
      }







      case P4_FUNCDEF: {
        freeEphemeralFunction(db, (FuncDef*)p4);
        break;
      }
      case P4_MEM: {
        if( db->pnBytesFreed==0 ){
          sqlite3ValueFree((sqlite3_value*)p4);
60661
60662
60663
60664
60665
60666
60667
60668
60669
60670
60671
60672
60673
60674
60675
60676
60677
60678
60679
60680
60681
60682
60683
60684
60685
60686
60687
60688
    ** that was cast to a (const char *). */
    pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
    pOp->p4type = P4_INT32;
  }else if( zP4==0 ){
    pOp->p4.p = 0;
    pOp->p4type = P4_NOTUSED;
  }else if( n==P4_KEYINFO ){
    KeyInfo *pKeyInfo;
    int nField, nByte;

    nField = ((KeyInfo*)zP4)->nField;
    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
    pKeyInfo = sqlite3DbMallocRaw(0, nByte);
    pOp->p4.pKeyInfo = pKeyInfo;
    if( pKeyInfo ){
      u8 *aSortOrder;
      memcpy((char*)pKeyInfo, zP4, nByte - nField);
      aSortOrder = pKeyInfo->aSortOrder;
      assert( aSortOrder!=0 );
      pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
      memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
      pOp->p4type = P4_KEYINFO;
    }else{
      p->db->mallocFailed = 1;
      pOp->p4type = P4_NOTUSED;
    }
  }else if( n==P4_KEYINFO_HANDOFF ){
    pOp->p4.p = (void*)zP4;







|
<

|
<
<
|
|
<
|
|
<
<
<







61257
61258
61259
61260
61261
61262
61263
61264

61265
61266


61267
61268

61269
61270



61271
61272
61273
61274
61275
61276
61277
    ** that was cast to a (const char *). */
    pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
    pOp->p4type = P4_INT32;
  }else if( zP4==0 ){
    pOp->p4.p = 0;
    pOp->p4type = P4_NOTUSED;
  }else if( n==P4_KEYINFO ){
    KeyInfo *pOrig, *pNew;


    pOrig = (KeyInfo*)zP4;


    pOp->p4.pKeyInfo = pNew = sqlite3KeyInfoAlloc(db, pOrig->nField);
    if( pNew ){

      memcpy(pNew->aColl, pOrig->aColl, pOrig->nField*sizeof(pNew->aColl[0]));
      memcpy(pNew->aSortOrder, pOrig->aSortOrder, pOrig->nField);



      pOp->p4type = P4_KEYINFO;
    }else{
      p->db->mallocFailed = 1;
      pOp->p4type = P4_NOTUSED;
    }
  }else if( n==P4_KEYINFO_HANDOFF ){
    pOp->p4.p = (void*)zP4;
61572
61573
61574
61575
61576
61577
61578




61579
61580
61581
61582
61583
61584
61585
    releaseMemArray(&p->aMem[1], p->nMem);
  }
  while( p->pDelFrame ){
    VdbeFrame *pDel = p->pDelFrame;
    p->pDelFrame = pDel->pParent;
    sqlite3VdbeFrameDelete(pDel);
  }




}

/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.  It also deletes the values of







>
>
>
>







62161
62162
62163
62164
62165
62166
62167
62168
62169
62170
62171
62172
62173
62174
62175
62176
62177
62178
    releaseMemArray(&p->aMem[1], p->nMem);
  }
  while( p->pDelFrame ){
    VdbeFrame *pDel = p->pDelFrame;
    p->pDelFrame = pDel->pParent;
    sqlite3VdbeFrameDelete(pDel);
  }

  /* Delete any auxdata allocations made by the VM */
  sqlite3VdbeDeleteAuxData(p, -1, 0);
  assert( p->pAuxData==0 );
}

/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.  It also deletes the values of
61680
61681
61682
61683
61684
61685
61686
61687
61688
61689
61690
61691
61692
61693
61694

  /* Before doing anything else, call the xSync() callback for any
  ** virtual module tables written in this transaction. This has to
  ** be done before determining whether a master journal file is 
  ** required, as an xSync() callback may add an attached database
  ** to the transaction.
  */
  rc = sqlite3VtabSync(db, &p->zErrMsg);

  /* This loop determines (a) if the commit hook should be invoked and
  ** (b) how many database files have open write transactions, not 
  ** including the temp database. (b) is important because if more than 
  ** one database file has an open write transaction, a master journal
  ** file is required for an atomic commit.
  */ 







|







62273
62274
62275
62276
62277
62278
62279
62280
62281
62282
62283
62284
62285
62286
62287

  /* Before doing anything else, call the xSync() callback for any
  ** virtual module tables written in this transaction. This has to
  ** be done before determining whether a master journal file is 
  ** required, as an xSync() callback may add an attached database
  ** to the transaction.
  */
  rc = sqlite3VtabSync(db, p);

  /* This loop determines (a) if the commit hook should be invoked and
  ** (b) how many database files have open write transactions, not 
  ** including the temp database. (b) is important because if more than 
  ** one database file has an open write transaction, a master journal
  ** file is required for an atomic commit.
  */ 
62370
62371
62372
62373
62374
62375
62376
62377











62378
62379
62380

62381
62382
62383
62384

62385
62386


62387
62388
62389
62390



62391
62392
62393
62394
62395
62396
62397
    assert( (rc & p->db->errMask)==rc );
  }
  sqlite3VdbeDelete(p);
  return rc;
}

/*
** Call the destructor for each auxdata entry in pVdbeFunc for which











** the corresponding bit in mask is clear.  Auxdata entries beyond 31
** are always destroyed.  To destroy all auxdata entries, call this
** routine with mask==0.

*/
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
  int i;
  for(i=0; i<pVdbeFunc->nAux; i++){

    struct AuxData *pAux = &pVdbeFunc->apAux[i];
    if( (i>31 || !(mask&(((u32)1)<<i))) && pAux->pAux ){


      if( pAux->xDelete ){
        pAux->xDelete(pAux->pAux);
      }
      pAux->pAux = 0;



    }
  }
}

/*
** Free all memory associated with the Vdbe passed as the second argument,
** except for object itself, which is preserved.







|
>
>
>
>
>
>
>
>
>
>
>
|
<
<
>

|
<
|
>
|
|
>
>



|
>
>
>







62963
62964
62965
62966
62967
62968
62969
62970
62971
62972
62973
62974
62975
62976
62977
62978
62979
62980
62981
62982


62983
62984
62985

62986
62987
62988
62989
62990
62991
62992
62993
62994
62995
62996
62997
62998
62999
63000
63001
63002
63003
63004
63005
    assert( (rc & p->db->errMask)==rc );
  }
  sqlite3VdbeDelete(p);
  return rc;
}

/*
** If parameter iOp is less than zero, then invoke the destructor for
** all auxiliary data pointers currently cached by the VM passed as
** the first argument.
**
** Or, if iOp is greater than or equal to zero, then the destructor is
** only invoked for those auxiliary data pointers created by the user 
** function invoked by the OP_Function opcode at instruction iOp of 
** VM pVdbe, and only then if:
**
**    * the associated function parameter is the 32nd or later (counting
**      from left to right), or
**
**    * the corresponding bit in argument mask is clear (where the first


**      function parameter corrsponds to bit 0 etc.).
*/
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){

  AuxData **pp = &pVdbe->pAuxData;
  while( *pp ){
    AuxData *pAux = *pp;
    if( (iOp<0)
     || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<<pAux->iArg))))
    ){
      if( pAux->xDelete ){
        pAux->xDelete(pAux->pAux);
      }
      *pp = pAux->pNext;
      sqlite3DbFree(pVdbe->db, pAux);
    }else{
      pp= &pAux->pNext;
    }
  }
}

/*
** Free all memory associated with the Vdbe passed as the second argument,
** except for object itself, which is preserved.
62902
62903
62904
62905
62906
62907
62908
62909
62910
62911
62912
62913
62914
62915
62916
62917
62918
62919
62920
** equal, then the keys are considered to be equal and
** the parts beyond the common prefix are ignored.
*/
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
  int nKey1, const void *pKey1, /* Left key */
  UnpackedRecord *pPKey2        /* Right key */
){
  int d1;            /* Offset into aKey[] of next data element */
  u32 idx1;          /* Offset into aKey[] of next header element */
  u32 szHdr1;        /* Number of bytes in header */
  int i = 0;
  int nField;
  int rc = 0;
  const unsigned char *aKey1 = (const unsigned char *)pKey1;
  KeyInfo *pKeyInfo;
  Mem mem1;

  pKeyInfo = pPKey2->pKeyInfo;
  mem1.enc = pKeyInfo->enc;







|



<







63510
63511
63512
63513
63514
63515
63516
63517
63518
63519
63520

63521
63522
63523
63524
63525
63526
63527
** equal, then the keys are considered to be equal and
** the parts beyond the common prefix are ignored.
*/
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
  int nKey1, const void *pKey1, /* Left key */
  UnpackedRecord *pPKey2        /* Right key */
){
  u32 d1;            /* Offset into aKey[] of next data element */
  u32 idx1;          /* Offset into aKey[] of next header element */
  u32 szHdr1;        /* Number of bytes in header */
  int i = 0;

  int rc = 0;
  const unsigned char *aKey1 = (const unsigned char *)pKey1;
  KeyInfo *pKeyInfo;
  Mem mem1;

  pKeyInfo = pPKey2->pKeyInfo;
  mem1.enc = pKeyInfo->enc;
62929
62930
62931
62932
62933
62934
62935
62936
62937
62938
62939
62940
62941
62942








62943



62944
62945
62946
62947
62948
62949
62950
62951
62952
62953
62954
62955
62956
62957
62958
62959
62960
62961
62962
62963
62964
  ** impact, since this routine is a very high runner.  And so, we choose
  ** to ignore the compiler warnings and leave this variable uninitialized.
  */
  /*  mem1.u.i = 0;  // not needed, here to silence compiler warning */
  
  idx1 = getVarint32(aKey1, szHdr1);
  d1 = szHdr1;
  nField = pKeyInfo->nField;
  assert( pKeyInfo->aSortOrder!=0 );
  while( idx1<szHdr1 && i<pPKey2->nField ){
    u32 serial_type1;

    /* Read the serial types for the next element in each key. */
    idx1 += getVarint32( aKey1+idx1, serial_type1 );








    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;




    /* Extract the values to be compared.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);

    /* Do the comparison
    */
    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
                           i<nField ? pKeyInfo->aColl[i] : 0);
    if( rc!=0 ){
      assert( mem1.zMalloc==0 );  /* See comment below */

      /* Invert the result if we are using DESC sort order. */
      if( i<nField && pKeyInfo->aSortOrder[i] ){
        rc = -rc;
      }
    
      /* If the PREFIX_SEARCH flag is set and all fields except the final
      ** rowid field were equal, then clear the PREFIX_SEARCH flag and set 
      ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
      ** This is used by the OP_IsUnique opcode.







|






>
>
>
>
>
>
>
>
|
>
>
>







|
<




|







63536
63537
63538
63539
63540
63541
63542
63543
63544
63545
63546
63547
63548
63549
63550
63551
63552
63553
63554
63555
63556
63557
63558
63559
63560
63561
63562
63563
63564
63565
63566
63567
63568
63569

63570
63571
63572
63573
63574
63575
63576
63577
63578
63579
63580
63581
  ** impact, since this routine is a very high runner.  And so, we choose
  ** to ignore the compiler warnings and leave this variable uninitialized.
  */
  /*  mem1.u.i = 0;  // not needed, here to silence compiler warning */
  
  idx1 = getVarint32(aKey1, szHdr1);
  d1 = szHdr1;
  assert( pKeyInfo->nField+1>=pPKey2->nField );
  assert( pKeyInfo->aSortOrder!=0 );
  while( idx1<szHdr1 && i<pPKey2->nField ){
    u32 serial_type1;

    /* Read the serial types for the next element in each key. */
    idx1 += getVarint32( aKey1+idx1, serial_type1 );

    /* Verify that there is enough key space remaining to avoid
    ** a buffer overread.  The "d1+serial_type1+2" subexpression will
    ** always be greater than or equal to the amount of required key space.
    ** Use that approximation to avoid the more expensive call to
    ** sqlite3VdbeSerialTypeLen() in the common case.
    */
    if( d1+serial_type1+2>(u32)nKey1
     && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 
    ){
      break;
    }

    /* Extract the values to be compared.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);

    /* Do the comparison
    */
    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);

    if( rc!=0 ){
      assert( mem1.zMalloc==0 );  /* See comment below */

      /* Invert the result if we are using DESC sort order. */
      if( pKeyInfo->aSortOrder[i] ){
        rc = -rc;
      }
    
      /* If the PREFIX_SEARCH flag is set and all fields except the final
      ** rowid field were equal, then clear the PREFIX_SEARCH flag and set 
      ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
      ** This is used by the OP_IsUnique opcode.
63165
63166
63167
63168
63169
63170
63171
63172
63173
63174
63175
63176
63177
63178
63179
** Return a pointer to an sqlite3_value structure containing the value bound
** parameter iVar of VM v. Except, if the value is an SQL NULL, return 
** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
** constants) to the value before returning it.
**
** The returned value must be freed by the caller using sqlite3ValueFree().
*/
SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe *v, int iVar, u8 aff){
  assert( iVar>0 );
  if( v ){
    Mem *pMem = &v->aVar[iVar-1];
    if( 0==(pMem->flags & MEM_Null) ){
      sqlite3_value *pRet = sqlite3ValueNew(v->db);
      if( pRet ){
        sqlite3VdbeMemCopy((Mem *)pRet, pMem);







|







63782
63783
63784
63785
63786
63787
63788
63789
63790
63791
63792
63793
63794
63795
63796
** Return a pointer to an sqlite3_value structure containing the value bound
** parameter iVar of VM v. Except, if the value is an SQL NULL, return 
** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
** constants) to the value before returning it.
**
** The returned value must be freed by the caller using sqlite3ValueFree().
*/
SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
  assert( iVar>0 );
  if( v ){
    Mem *pMem = &v->aVar[iVar-1];
    if( 0==(pMem->flags & MEM_Null) ){
      sqlite3_value *pRet = sqlite3ValueNew(v->db);
      if( pRet ){
        sqlite3VdbeMemCopy((Mem *)pRet, pMem);
63196
63197
63198
63199
63200
63201
63202















63203
63204
63205
63206
63207
63208
63209
  if( iVar>32 ){
    v->expmask = 0xffffffff;
  }else{
    v->expmask |= ((u32)1 << (iVar-1));
  }
}
















/************** End of vdbeaux.c *********************************************/
/************** Begin file vdbeapi.c *****************************************/
/*
** 2004 May 26
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:







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







63813
63814
63815
63816
63817
63818
63819
63820
63821
63822
63823
63824
63825
63826
63827
63828
63829
63830
63831
63832
63833
63834
63835
63836
63837
63838
63839
63840
63841
  if( iVar>32 ){
    v->expmask = 0xffffffff;
  }else{
    v->expmask |= ((u32)1 << (iVar-1));
  }
}

#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
** in memory obtained from sqlite3DbMalloc).
*/
SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
  sqlite3 *db = p->db;
  sqlite3DbFree(db, p->zErrMsg);
  p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
  sqlite3_free(pVtab->zErrMsg);
  pVtab->zErrMsg = 0;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

/************** End of vdbeaux.c *********************************************/
/************** Begin file vdbeapi.c *****************************************/
/*
** 2004 May 26
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
63409
63410
63411
63412
63413
63414
63415

63416
63417
63418
63419
63420
63421

63422
63423
63424
63425
63426
63427
63428
SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
}
SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  pCtx->isError = SQLITE_ERROR;

  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  pCtx->isError = SQLITE_ERROR;

  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
}







>






>







64041
64042
64043
64044
64045
64046
64047
64048
64049
64050
64051
64052
64053
64054
64055
64056
64057
64058
64059
64060
64061
64062
SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
}
SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  pCtx->isError = SQLITE_ERROR;
  pCtx->fErrorOrAux = 1;
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  pCtx->isError = SQLITE_ERROR;
  pCtx->fErrorOrAux = 1;
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
}
63478
63479
63480
63481
63482
63483
63484

63485
63486
63487
63488
63489
63490
63491
63492
63493
63494

63495
63496
63497
63498
63499
63500
63501
63502
63503

63504
63505
63506
63507
63508
63509
63510
}
SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
}
SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
  pCtx->isError = errCode;

  if( pCtx->s.flags & MEM_Null ){
    sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1, 
                         SQLITE_UTF8, SQLITE_STATIC);
  }
}

/* Force an SQLITE_TOOBIG error. */
SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  pCtx->isError = SQLITE_TOOBIG;

  sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, 
                       SQLITE_UTF8, SQLITE_STATIC);
}

/* An SQLITE_NOMEM error. */
SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetNull(&pCtx->s);
  pCtx->isError = SQLITE_NOMEM;

  pCtx->s.db->mallocFailed = 1;
}

/*
** This function is called after a transaction has been committed. It 
** invokes callbacks registered with sqlite3_wal_hook() as required.
*/







>










>









>







64112
64113
64114
64115
64116
64117
64118
64119
64120
64121
64122
64123
64124
64125
64126
64127
64128
64129
64130
64131
64132
64133
64134
64135
64136
64137
64138
64139
64140
64141
64142
64143
64144
64145
64146
64147
}
SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
}
SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
  pCtx->isError = errCode;
  pCtx->fErrorOrAux = 1;
  if( pCtx->s.flags & MEM_Null ){
    sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1, 
                         SQLITE_UTF8, SQLITE_STATIC);
  }
}

/* Force an SQLITE_TOOBIG error. */
SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  pCtx->isError = SQLITE_TOOBIG;
  pCtx->fErrorOrAux = 1;
  sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, 
                       SQLITE_UTF8, SQLITE_STATIC);
}

/* An SQLITE_NOMEM error. */
SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  sqlite3VdbeMemSetNull(&pCtx->s);
  pCtx->isError = SQLITE_NOMEM;
  pCtx->fErrorOrAux = 1;
  pCtx->s.db->mallocFailed = 1;
}

/*
** This function is called after a transaction has been committed. It 
** invokes callbacks registered with sqlite3_wal_hook() as required.
*/
63782
63783
63784
63785
63786
63787
63788
63789
63790
63791
63792
63793
63794
63795
63796

63797
63798
63799
63800
63801
63802
63803
63804
63805
63806
63807
63808
63809
63810
63811
63812
63813
63814
63815
63816
63817
63818
63819
63820
63821
63822
63823
63824
63825
63826
63827










63828
63829
63830
63831
63832

63833
63834
63835
63836
63837
63838
63839
}

/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
  VdbeFunc *pVdbeFunc;

  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  pVdbeFunc = pCtx->pVdbeFunc;
  if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
    return 0;
  }
  return pVdbeFunc->apAux[iArg].pAux;

}

/*
** Set the auxilary data pointer and delete function, for the iArg'th
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
*/
SQLITE_API void sqlite3_set_auxdata(
  sqlite3_context *pCtx, 
  int iArg, 
  void *pAux, 
  void (*xDelete)(void*)
){
  struct AuxData *pAuxData;
  VdbeFunc *pVdbeFunc;
  if( iArg<0 ) goto failed;

  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  pVdbeFunc = pCtx->pVdbeFunc;
  if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
    int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0);
    int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
    pVdbeFunc = sqlite3DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc);
    if( !pVdbeFunc ){
      goto failed;
    }
    pCtx->pVdbeFunc = pVdbeFunc;
    memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux));
    pVdbeFunc->nAux = iArg+1;
    pVdbeFunc->pFunc = pCtx->pFunc;
  }











  pAuxData = &pVdbeFunc->apAux[iArg];
  if( pAuxData->pAux && pAuxData->xDelete ){
    pAuxData->xDelete(pAuxData->pAux);
  }

  pAuxData->pAux = pAux;
  pAuxData->xDelete = xDelete;
  return;

failed:
  if( xDelete ){
    xDelete(pAux);







|


|
|
<

|
>













|
|
<


<
<
<
<
<
<
|
|
<
<
|
|

>
>
>
>
>
>
>
>
>
>
|
<
|


>







64419
64420
64421
64422
64423
64424
64425
64426
64427
64428
64429
64430

64431
64432
64433
64434
64435
64436
64437
64438
64439
64440
64441
64442
64443
64444
64445
64446
64447
64448

64449
64450






64451
64452


64453
64454
64455
64456
64457
64458
64459
64460
64461
64462
64463
64464
64465
64466

64467
64468
64469
64470
64471
64472
64473
64474
64475
64476
64477
}

/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
  AuxData *pAuxData;

  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
  for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;

  }

  return (pAuxData ? pAuxData->pAux : 0);
}

/*
** Set the auxilary data pointer and delete function, for the iArg'th
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
*/
SQLITE_API void sqlite3_set_auxdata(
  sqlite3_context *pCtx, 
  int iArg, 
  void *pAux, 
  void (*xDelete)(void*)
){
  AuxData *pAuxData;
  Vdbe *pVdbe = pCtx->pVdbe;


  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );






  if( iArg<0 ) goto failed;



  for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
  }
  if( pAuxData==0 ){
    pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
    if( !pAuxData ) goto failed;
    pAuxData->iOp = pCtx->iOp;
    pAuxData->iArg = iArg;
    pAuxData->pNext = pVdbe->pAuxData;
    pVdbe->pAuxData = pAuxData;
    if( pCtx->fErrorOrAux==0 ){
      pCtx->isError = 0;
      pCtx->fErrorOrAux = 1;
    }

  }else if( pAuxData->xDelete ){
    pAuxData->xDelete(pAuxData->pAux);
  }

  pAuxData->pAux = pAux;
  pAuxData->xDelete = xDelete;
  return;

failed:
  if( xDelete ){
    xDelete(pAux);
64490
64491
64492
64493
64494
64495
64496
64497
64498
64499
64500
64501
64502
64503
64504
64505
64506
}

/*
** Return the value of a status counter for a prepared statement
*/
SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
  Vdbe *pVdbe = (Vdbe*)pStmt;
  int v = pVdbe->aCounter[op-1];
  if( resetFlag ) pVdbe->aCounter[op-1] = 0;
  return v;
}

/************** End of vdbeapi.c *********************************************/
/************** Begin file vdbetrace.c ***************************************/
/*
** 2009 November 25
**







|
|
|







65128
65129
65130
65131
65132
65133
65134
65135
65136
65137
65138
65139
65140
65141
65142
65143
65144
}

/*
** Return the value of a status counter for a prepared statement
*/
SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
  Vdbe *pVdbe = (Vdbe*)pStmt;
  u32 v = pVdbe->aCounter[op];
  if( resetFlag ) pVdbe->aCounter[op] = 0;
  return (int)v;
}

/************** End of vdbeapi.c *********************************************/
/************** Begin file vdbetrace.c ***************************************/
/*
** 2009 November 25
**
65379
65380
65381
65382
65383
65384
65385
65386
65387
65388
65389
65390
65391
65392
65393
65394
65395
65396
65397
65398
65399
65400
65401
65402
65403
65404
65405
  Savepoint *p;
  for(p=db->pSavepoint; p; p=p->pNext) n++;
  assert( n==(db->nSavepoint + db->isTransactionSavepoint) );
  return 1;
}
#endif

/*
** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
** in memory obtained from sqlite3DbMalloc).
*/
static void importVtabErrMsg(Vdbe *p, sqlite3_vtab *pVtab){
  sqlite3 *db = p->db;
  sqlite3DbFree(db, p->zErrMsg);
  p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
  sqlite3_free(pVtab->zErrMsg);
  pVtab->zErrMsg = 0;
}


/*
** Execute as much of a VDBE program as we can then return.
**
** sqlite3VdbeMakeReady() must be called before this routine in order to
** close the program with a final OP_Halt and to set up the callbacks
** and the error message pointer.







<
<
<
<
<
<
<
<
<
<
<
<
<







66017
66018
66019
66020
66021
66022
66023













66024
66025
66026
66027
66028
66029
66030
  Savepoint *p;
  for(p=db->pSavepoint; p; p=p->pNext) n++;
  assert( n==(db->nSavepoint + db->isTransactionSavepoint) );
  return 1;
}
#endif















/*
** Execute as much of a VDBE program as we can then return.
**
** sqlite3VdbeMakeReady() must be called before this routine in order to
** close the program with a final OP_Halt and to set up the callbacks
** and the error message pointer.
65437
65438
65439
65440
65441
65442
65443
65444
65445
65446
65447
65448
65449
65450
65451
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */
  u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
  u8 encoding = ENC(db);     /* The database encoding */
  int iCompare = 0;          /* Result of last OP_Compare operation */
  unsigned nVmStep = 0;      /* Number of virtual machine steps */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  unsigned nProgressOps = 0; /* nVmStep at last progress callback. */
#endif
  Mem *aMem = p->aMem;       /* Copy of p->aMem */
  Mem *pIn1 = 0;             /* 1st input operand */
  Mem *pIn2 = 0;             /* 2nd input operand */
  Mem *pIn3 = 0;             /* 3rd input operand */
  Mem *pOut = 0;             /* Output operand */
  int *aPermute = 0;         /* Permutation of columns for OP_Compare */







|







66062
66063
66064
66065
66066
66067
66068
66069
66070
66071
66072
66073
66074
66075
66076
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */
  u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
  u8 encoding = ENC(db);     /* The database encoding */
  int iCompare = 0;          /* Result of last OP_Compare operation */
  unsigned nVmStep = 0;      /* Number of virtual machine steps */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
#endif
  Mem *aMem = p->aMem;       /* Copy of p->aMem */
  Mem *pIn1 = 0;             /* 1st input operand */
  Mem *pIn2 = 0;             /* 2nd input operand */
  Mem *pIn3 = 0;             /* 3rd input operand */
  Mem *pOut = 0;             /* Output operand */
  int *aPermute = 0;         /* Permutation of columns for OP_Compare */
65896
65897
65898
65899
65900
65901
65902











65903
65904
65905
65906
65907
65908
65909
  assert( p->bIsReader || p->readOnly!=0 );
  p->rc = SQLITE_OK;
  assert( p->explain==0 );
  p->pResultSet = 0;
  db->busyHandler.nBusy = 0;
  CHECK_FOR_INTERRUPT;
  sqlite3VdbeIOTraceSql(p);











#ifdef SQLITE_DEBUG
  sqlite3BeginBenignMalloc();
  if( p->pc==0  && (p->db->flags & SQLITE_VdbeListing)!=0 ){
    int i;
    printf("VDBE Program Listing:\n");
    sqlite3VdbePrintSql(p);
    for(i=0; i<p->nOp; i++){







>
>
>
>
>
>
>
>
>
>
>







66521
66522
66523
66524
66525
66526
66527
66528
66529
66530
66531
66532
66533
66534
66535
66536
66537
66538
66539
66540
66541
66542
66543
66544
66545
  assert( p->bIsReader || p->readOnly!=0 );
  p->rc = SQLITE_OK;
  assert( p->explain==0 );
  p->pResultSet = 0;
  db->busyHandler.nBusy = 0;
  CHECK_FOR_INTERRUPT;
  sqlite3VdbeIOTraceSql(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  if( db->xProgress ){
    assert( 0 < db->nProgressOps );
    nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
    if( nProgressLimit==0 ){
      nProgressLimit = db->nProgressOps;
    }else{
      nProgressLimit %= (unsigned)db->nProgressOps;
    }
  }
#endif
#ifdef SQLITE_DEBUG
  sqlite3BeginBenignMalloc();
  if( p->pc==0  && (p->db->flags & SQLITE_VdbeListing)!=0 ){
    int i;
    printf("VDBE Program Listing:\n");
    sqlite3VdbePrintSql(p);
    for(i=0; i<p->nOp; i++){
65951
65952
65953
65954
65955
65956
65957
65958
65959
65960
65961
65962
65963
65964
65965
65966
65967
65968
65969
65970
65971
65972
65973
65974
65975
65976
65977
65978
65979
65980
65981
65982
65983
65984
65985
65986
65987
65988
65989
65990
65991
65992
65993
65994
65995
65996
65997
65998
65999
    ** external allocations out of mem[p2] and set mem[p2] to be
    ** an undefined integer.  Opcodes will either fill in the integer
    ** value or convert mem[p2] to a different type.
    */
    assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
    if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
      assert( pOp->p2>0 );
      assert( pOp->p2<=p->nMem );
      pOut = &aMem[pOp->p2];
      memAboutToChange(p, pOut);
      VdbeMemRelease(pOut);
      pOut->flags = MEM_Int;
    }

    /* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
    if( (pOp->opflags & OPFLG_IN1)!=0 ){
      assert( pOp->p1>0 );
      assert( pOp->p1<=p->nMem );
      assert( memIsValid(&aMem[pOp->p1]) );
      REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
    }
    if( (pOp->opflags & OPFLG_IN2)!=0 ){
      assert( pOp->p2>0 );
      assert( pOp->p2<=p->nMem );
      assert( memIsValid(&aMem[pOp->p2]) );
      REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
    }
    if( (pOp->opflags & OPFLG_IN3)!=0 ){
      assert( pOp->p3>0 );
      assert( pOp->p3<=p->nMem );
      assert( memIsValid(&aMem[pOp->p3]) );
      REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
    }
    if( (pOp->opflags & OPFLG_OUT2)!=0 ){
      assert( pOp->p2>0 );
      assert( pOp->p2<=p->nMem );
      memAboutToChange(p, &aMem[pOp->p2]);
    }
    if( (pOp->opflags & OPFLG_OUT3)!=0 ){
      assert( pOp->p3>0 );
      assert( pOp->p3<=p->nMem );
      memAboutToChange(p, &aMem[pOp->p3]);
    }
#endif
  
    switch( pOp->opcode ){

/*****************************************************************************







|










|





|





|





|




|







66587
66588
66589
66590
66591
66592
66593
66594
66595
66596
66597
66598
66599
66600
66601
66602
66603
66604
66605
66606
66607
66608
66609
66610
66611
66612
66613
66614
66615
66616
66617
66618
66619
66620
66621
66622
66623
66624
66625
66626
66627
66628
66629
66630
66631
66632
66633
66634
66635
    ** external allocations out of mem[p2] and set mem[p2] to be
    ** an undefined integer.  Opcodes will either fill in the integer
    ** value or convert mem[p2] to a different type.
    */
    assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
    if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
      assert( pOp->p2>0 );
      assert( pOp->p2<=(p->nMem-p->nCursor) );
      pOut = &aMem[pOp->p2];
      memAboutToChange(p, pOut);
      VdbeMemRelease(pOut);
      pOut->flags = MEM_Int;
    }

    /* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
    if( (pOp->opflags & OPFLG_IN1)!=0 ){
      assert( pOp->p1>0 );
      assert( pOp->p1<=(p->nMem-p->nCursor) );
      assert( memIsValid(&aMem[pOp->p1]) );
      REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
    }
    if( (pOp->opflags & OPFLG_IN2)!=0 ){
      assert( pOp->p2>0 );
      assert( pOp->p2<=(p->nMem-p->nCursor) );
      assert( memIsValid(&aMem[pOp->p2]) );
      REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
    }
    if( (pOp->opflags & OPFLG_IN3)!=0 ){
      assert( pOp->p3>0 );
      assert( pOp->p3<=(p->nMem-p->nCursor) );
      assert( memIsValid(&aMem[pOp->p3]) );
      REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
    }
    if( (pOp->opflags & OPFLG_OUT2)!=0 ){
      assert( pOp->p2>0 );
      assert( pOp->p2<=(p->nMem-p->nCursor) );
      memAboutToChange(p, &aMem[pOp->p2]);
    }
    if( (pOp->opflags & OPFLG_OUT3)!=0 ){
      assert( pOp->p3>0 );
      assert( pOp->p3<=(p->nMem-p->nCursor) );
      memAboutToChange(p, &aMem[pOp->p3]);
    }
#endif
  
    switch( pOp->opcode ){

/*****************************************************************************
66056
66057
66058
66059
66060
66061
66062
66063
66064
66065
66066
66067
66068
66069
66070


66071
66072
66073
66074
66075
66076
66077
66078
66079
66080
66081
66082
66083
66084
66085
66086
66087
66088
66089
66090
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  /* Call the progress callback if it is configured and the required number
  ** of VDBE ops have been executed (either since this invocation of
  ** sqlite3VdbeExec() or since last time the progress callback was called).
  ** If the progress callback returns non-zero, exit the virtual machine with
  ** a return code SQLITE_ABORT.
  */
  if( db->xProgress!=0 && (nVmStep - nProgressOps)>=db->nProgressOps ){
    int prc;
    prc = db->xProgress(db->pProgressArg);
    if( prc!=0 ){
      rc = SQLITE_INTERRUPT;
      goto vdbe_error_halt;
    }
    nProgressOps = nVmStep;


  }
#endif
  
  break;
}

/* Opcode:  Gosub P1 P2 * * *
**
** Write the current address onto register P1
** and then jump to address P2.
*/
case OP_Gosub: {            /* jump */
  assert( pOp->p1>0 && pOp->p1<=p->nMem );
  pIn1 = &aMem[pOp->p1];
  assert( (pIn1->flags & MEM_Dyn)==0 );
  memAboutToChange(p, pIn1);
  pIn1->flags = MEM_Int;
  pIn1->u.i = pc;
  REGISTER_TRACE(pOp->p1, pIn1);
  pc = pOp->p2 - 1;







|






|
>
>












|







66692
66693
66694
66695
66696
66697
66698
66699
66700
66701
66702
66703
66704
66705
66706
66707
66708
66709
66710
66711
66712
66713
66714
66715
66716
66717
66718
66719
66720
66721
66722
66723
66724
66725
66726
66727
66728
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  /* Call the progress callback if it is configured and the required number
  ** of VDBE ops have been executed (either since this invocation of
  ** sqlite3VdbeExec() or since last time the progress callback was called).
  ** If the progress callback returns non-zero, exit the virtual machine with
  ** a return code SQLITE_ABORT.
  */
  if( db->xProgress!=0 && nVmStep>=nProgressLimit ){
    int prc;
    prc = db->xProgress(db->pProgressArg);
    if( prc!=0 ){
      rc = SQLITE_INTERRUPT;
      goto vdbe_error_halt;
    }
    if( db->xProgress!=0 ){
      nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
    }
  }
#endif
  
  break;
}

/* Opcode:  Gosub P1 P2 * * *
**
** Write the current address onto register P1
** and then jump to address P2.
*/
case OP_Gosub: {            /* jump */
  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
  pIn1 = &aMem[pOp->p1];
  assert( (pIn1->flags & MEM_Dyn)==0 );
  memAboutToChange(p, pIn1);
  pIn1->flags = MEM_Int;
  pIn1->u.i = pc;
  REGISTER_TRACE(pOp->p1, pIn1);
  pc = pOp->p2 - 1;
66292
66293
66294
66295
66296
66297
66298
66299
66300
66301
66302
66303
66304
66305
66306
*/
case OP_Null: {           /* out2-prerelease */
#if 0  /* local variables moved into u.ab */
  int cnt;
  u16 nullFlag;
#endif /* local variables moved into u.ab */
  u.ab.cnt = pOp->p3-pOp->p2;
  assert( pOp->p3<=p->nMem );
  pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
  while( u.ab.cnt>0 ){
    pOut++;
    memAboutToChange(p, pOut);
    VdbeMemRelease(pOut);
    pOut->flags = u.ab.nullFlag;
    u.ab.cnt--;







|







66930
66931
66932
66933
66934
66935
66936
66937
66938
66939
66940
66941
66942
66943
66944
*/
case OP_Null: {           /* out2-prerelease */
#if 0  /* local variables moved into u.ab */
  int cnt;
  u16 nullFlag;
#endif /* local variables moved into u.ab */
  u.ab.cnt = pOp->p3-pOp->p2;
  assert( pOp->p3<=(p->nMem-p->nCursor) );
  pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
  while( u.ab.cnt>0 ){
    pOut++;
    memAboutToChange(p, pOut);
    VdbeMemRelease(pOut);
    pOut->flags = u.ab.nullFlag;
    u.ab.cnt--;
66365
66366
66367
66368
66369
66370
66371
66372
66373
66374
66375
66376
66377
66378
66379
66380
  u.ad.p2 = pOp->p2;
  assert( u.ad.n>0 && u.ad.p1>0 && u.ad.p2>0 );
  assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 );

  pIn1 = &aMem[u.ad.p1];
  pOut = &aMem[u.ad.p2];
  while( u.ad.n-- ){
    assert( pOut<=&aMem[p->nMem] );
    assert( pIn1<=&aMem[p->nMem] );
    assert( memIsValid(pIn1) );
    memAboutToChange(p, pOut);
    u.ad.zMalloc = pOut->zMalloc;
    pOut->zMalloc = 0;
    sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
    if( pOut->pScopyFrom>=&aMem[u.ad.p1] && pOut->pScopyFrom<&aMem[u.ad.p1+pOp->p3] ){







|
|







67003
67004
67005
67006
67007
67008
67009
67010
67011
67012
67013
67014
67015
67016
67017
67018
  u.ad.p2 = pOp->p2;
  assert( u.ad.n>0 && u.ad.p1>0 && u.ad.p2>0 );
  assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 );

  pIn1 = &aMem[u.ad.p1];
  pOut = &aMem[u.ad.p2];
  while( u.ad.n-- ){
    assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
    assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
    assert( memIsValid(pIn1) );
    memAboutToChange(p, pOut);
    u.ad.zMalloc = pOut->zMalloc;
    pOut->zMalloc = 0;
    sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
    if( pOut->pScopyFrom>=&aMem[u.ad.p1] && pOut->pScopyFrom<&aMem[u.ad.p1+pOp->p3] ){
66454
66455
66456
66457
66458
66459
66460
66461
66462
66463
66464
66465
66466
66467
66468
case OP_ResultRow: {
#if 0  /* local variables moved into u.af */
  Mem *pMem;
  int i;
#endif /* local variables moved into u.af */
  assert( p->nResColumn==pOp->p2 );
  assert( pOp->p1>0 );
  assert( pOp->p1+pOp->p2<=p->nMem+1 );

  /* If this statement has violated immediate foreign key constraints, do
  ** not return the number of rows modified. And do not RELEASE the statement
  ** transaction. It needs to be rolled back.  */
  if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){
    assert( db->flags&SQLITE_CountRows );
    assert( p->usesStmtJournal );







|







67092
67093
67094
67095
67096
67097
67098
67099
67100
67101
67102
67103
67104
67105
67106
case OP_ResultRow: {
#if 0  /* local variables moved into u.af */
  Mem *pMem;
  int i;
#endif /* local variables moved into u.af */
  assert( p->nResColumn==pOp->p2 );
  assert( pOp->p1>0 );
  assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 );

  /* If this statement has violated immediate foreign key constraints, do
  ** not return the number of rows modified. And do not RELEASE the statement
  ** transaction. It needs to be rolled back.  */
  if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){
    assert( db->flags&SQLITE_CountRows );
    assert( p->usesStmtJournal );
66734
66735
66736
66737
66738
66739
66740
66741
66742
66743
66744
66745
66746
66747
66748
66749
66750
66751
66752
66753
66754
66755
66756
66757
66758
66759
66760
66761
66762
66763
66764
66765
66766
66767
66768


66769
66770
66771
66772
66773
66774
66775
66776
66777
66778
66779
66780
66781
66782
66783
66784
66785
66786
66787
66788
66789
66790
66791
66792
66793
66794
66795
66796
66797
66798
66799
66800
66801
66802
66803
66804
66805
66806
66807

66808
66809
66810


66811
66812
66813
66814
66815
66816
66817
  sqlite3_value **apVal;
  int n;
#endif /* local variables moved into u.ai */

  u.ai.n = pOp->p5;
  u.ai.apVal = p->apArg;
  assert( u.ai.apVal || u.ai.n==0 );
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pOut = &aMem[pOp->p3];
  memAboutToChange(p, pOut);

  assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=p->nMem+1) );
  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n );
  u.ai.pArg = &aMem[pOp->p2];
  for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){
    assert( memIsValid(u.ai.pArg) );
    u.ai.apVal[u.ai.i] = u.ai.pArg;
    Deephemeralize(u.ai.pArg);
    sqlite3VdbeMemStoreType(u.ai.pArg);
    REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
  }

  assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
  if( pOp->p4type==P4_FUNCDEF ){
    u.ai.ctx.pFunc = pOp->p4.pFunc;
    u.ai.ctx.pVdbeFunc = 0;
  }else{
    u.ai.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
    u.ai.ctx.pFunc = u.ai.ctx.pVdbeFunc->pFunc;
  }

  u.ai.ctx.s.flags = MEM_Null;
  u.ai.ctx.s.db = db;
  u.ai.ctx.s.xDel = 0;
  u.ai.ctx.s.zMalloc = 0;



  /* The output cell may already have a buffer allocated. Move
  ** the pointer to u.ai.ctx.s so in case the user-function can use
  ** the already allocated buffer instead of allocating a new one.
  */
  sqlite3VdbeMemMove(&u.ai.ctx.s, pOut);
  MemSetTypeFlag(&u.ai.ctx.s, MEM_Null);

  u.ai.ctx.isError = 0;
  if( u.ai.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
    assert( pOp>aOp );
    assert( pOp[-1].p4type==P4_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    u.ai.ctx.pColl = pOp[-1].p4.pColl;
  }
  db->lastRowid = lastRowid;
  (*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */
  lastRowid = db->lastRowid;

  /* If any auxiliary data functions have been called by this user function,
  ** immediately call the destructor for any non-static values.
  */
  if( u.ai.ctx.pVdbeFunc ){
    sqlite3VdbeDeleteAuxData(u.ai.ctx.pVdbeFunc, pOp->p1);
    pOp->p4.pVdbeFunc = u.ai.ctx.pVdbeFunc;
    pOp->p4type = P4_VDBEFUNC;
  }

  if( db->mallocFailed ){
    /* Even though a malloc() has failed, the implementation of the
    ** user function may have called an sqlite3_result_XXX() function
    ** to return a value. The following call releases any resources
    ** associated with such a value.
    */
    sqlite3VdbeMemRelease(&u.ai.ctx.s);
    goto no_mem;
  }

  /* If the function returned an error, throw an exception */

  if( u.ai.ctx.isError ){
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s));
    rc = u.ai.ctx.isError;


  }

  /* Copy the result of the function into register P3 */
  sqlite3VdbeChangeEncoding(&u.ai.ctx.s, encoding);
  sqlite3VdbeMemMove(pOut, &u.ai.ctx.s);
  if( sqlite3VdbeMemTooBig(pOut) ){
    goto too_big;







|



|










|
<
|
<
<
<
<
<
<




>
>








|










<
<
<
<
<
<
<
<
<











>
|
|
|
>
>







67372
67373
67374
67375
67376
67377
67378
67379
67380
67381
67382
67383
67384
67385
67386
67387
67388
67389
67390
67391
67392
67393
67394

67395






67396
67397
67398
67399
67400
67401
67402
67403
67404
67405
67406
67407
67408
67409
67410
67411
67412
67413
67414
67415
67416
67417
67418
67419
67420









67421
67422
67423
67424
67425
67426
67427
67428
67429
67430
67431
67432
67433
67434
67435
67436
67437
67438
67439
67440
67441
67442
67443
67444
  sqlite3_value **apVal;
  int n;
#endif /* local variables moved into u.ai */

  u.ai.n = pOp->p5;
  u.ai.apVal = p->apArg;
  assert( u.ai.apVal || u.ai.n==0 );
  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  pOut = &aMem[pOp->p3];
  memAboutToChange(p, pOut);

  assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=(p->nMem-p->nCursor)+1) );
  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n );
  u.ai.pArg = &aMem[pOp->p2];
  for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){
    assert( memIsValid(u.ai.pArg) );
    u.ai.apVal[u.ai.i] = u.ai.pArg;
    Deephemeralize(u.ai.pArg);
    sqlite3VdbeMemStoreType(u.ai.pArg);
    REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
  }

  assert( pOp->p4type==P4_FUNCDEF );

  u.ai.ctx.pFunc = pOp->p4.pFunc;






  u.ai.ctx.s.flags = MEM_Null;
  u.ai.ctx.s.db = db;
  u.ai.ctx.s.xDel = 0;
  u.ai.ctx.s.zMalloc = 0;
  u.ai.ctx.iOp = pc;
  u.ai.ctx.pVdbe = p;

  /* The output cell may already have a buffer allocated. Move
  ** the pointer to u.ai.ctx.s so in case the user-function can use
  ** the already allocated buffer instead of allocating a new one.
  */
  sqlite3VdbeMemMove(&u.ai.ctx.s, pOut);
  MemSetTypeFlag(&u.ai.ctx.s, MEM_Null);

  u.ai.ctx.fErrorOrAux = 0;
  if( u.ai.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
    assert( pOp>aOp );
    assert( pOp[-1].p4type==P4_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    u.ai.ctx.pColl = pOp[-1].p4.pColl;
  }
  db->lastRowid = lastRowid;
  (*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */
  lastRowid = db->lastRowid;










  if( db->mallocFailed ){
    /* Even though a malloc() has failed, the implementation of the
    ** user function may have called an sqlite3_result_XXX() function
    ** to return a value. The following call releases any resources
    ** associated with such a value.
    */
    sqlite3VdbeMemRelease(&u.ai.ctx.s);
    goto no_mem;
  }

  /* If the function returned an error, throw an exception */
  if( u.ai.ctx.fErrorOrAux ){
    if( u.ai.ctx.isError ){
      sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s));
      rc = u.ai.ctx.isError;
    }
    sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
  }

  /* Copy the result of the function into register P3 */
  sqlite3VdbeChangeEncoding(&u.ai.ctx.s, encoding);
  sqlite3VdbeMemMove(pOut, &u.ai.ctx.s);
  if( sqlite3VdbeMemTooBig(pOut) ){
    goto too_big;
67179
67180
67181
67182
67183
67184
67185
67186


67187
67188
67189
67190
67191
67192
67193
67194
67195
67196
67197
67198
        u.ak.res = 1;  /* Results are not equal */
      }
    }else{
      /* SQLITE_NULLEQ is clear and at least one operand is NULL,
      ** then the result is always NULL.
      ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
      */
      if( pOp->p5 & SQLITE_STOREP2 ){


        pOut = &aMem[pOp->p2];
        MemSetTypeFlag(pOut, MEM_Null);
        REGISTER_TRACE(pOp->p2, pOut);
      }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
        pc = pOp->p2-1;
      }
      break;
    }
  }else{
    /* Neither operand is NULL.  Do a comparison. */
    u.ak.affinity = pOp->p5 & SQLITE_AFF_MASK;
    if( u.ak.affinity ){







|
>
>



<
<







67806
67807
67808
67809
67810
67811
67812
67813
67814
67815
67816
67817
67818


67819
67820
67821
67822
67823
67824
67825
        u.ak.res = 1;  /* Results are not equal */
      }
    }else{
      /* SQLITE_NULLEQ is clear and at least one operand is NULL,
      ** then the result is always NULL.
      ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
      */
      if( pOp->p5 & SQLITE_JUMPIFNULL ){
        pc = pOp->p2-1;
      }else if( pOp->p5 & SQLITE_STOREP2 ){
        pOut = &aMem[pOp->p2];
        MemSetTypeFlag(pOut, MEM_Null);
        REGISTER_TRACE(pOp->p2, pOut);


      }
      break;
    }
  }else{
    /* Neither operand is NULL.  Do a comparison. */
    u.ak.affinity = pOp->p5 & SQLITE_AFF_MASK;
    if( u.ak.affinity ){
67285
67286
67287
67288
67289
67290
67291
67292
67293
67294
67295
67296
67297
67298
67299
67300
67301
67302
67303
  assert( u.al.pKeyInfo!=0 );
  u.al.p1 = pOp->p1;
  u.al.p2 = pOp->p2;
#if SQLITE_DEBUG
  if( aPermute ){
    int k, mx = 0;
    for(k=0; k<u.al.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
    assert( u.al.p1>0 && u.al.p1+mx<=p->nMem+1 );
    assert( u.al.p2>0 && u.al.p2+mx<=p->nMem+1 );
  }else{
    assert( u.al.p1>0 && u.al.p1+u.al.n<=p->nMem+1 );
    assert( u.al.p2>0 && u.al.p2+u.al.n<=p->nMem+1 );
  }
#endif /* SQLITE_DEBUG */
  for(u.al.i=0; u.al.i<u.al.n; u.al.i++){
    u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i;
    assert( memIsValid(&aMem[u.al.p1+u.al.idx]) );
    assert( memIsValid(&aMem[u.al.p2+u.al.idx]) );
    REGISTER_TRACE(u.al.p1+u.al.idx, &aMem[u.al.p1+u.al.idx]);







|
|

|
|







67912
67913
67914
67915
67916
67917
67918
67919
67920
67921
67922
67923
67924
67925
67926
67927
67928
67929
67930
  assert( u.al.pKeyInfo!=0 );
  u.al.p1 = pOp->p1;
  u.al.p2 = pOp->p2;
#if SQLITE_DEBUG
  if( aPermute ){
    int k, mx = 0;
    for(k=0; k<u.al.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
    assert( u.al.p1>0 && u.al.p1+mx<=(p->nMem-p->nCursor)+1 );
    assert( u.al.p2>0 && u.al.p2+mx<=(p->nMem-p->nCursor)+1 );
  }else{
    assert( u.al.p1>0 && u.al.p1+u.al.n<=(p->nMem-p->nCursor)+1 );
    assert( u.al.p2>0 && u.al.p2+u.al.n<=(p->nMem-p->nCursor)+1 );
  }
#endif /* SQLITE_DEBUG */
  for(u.al.i=0; u.al.i<u.al.n; u.al.i++){
    u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i;
    assert( memIsValid(&aMem[u.al.p1+u.al.idx]) );
    assert( memIsValid(&aMem[u.al.p2+u.al.idx]) );
    REGISTER_TRACE(u.al.p1+u.al.idx, &aMem[u.al.p1+u.al.idx]);
67546
67547
67548
67549
67550
67551
67552
67553
67554
67555
67556
67557
67558
67559
67560


  u.ao.p1 = pOp->p1;
  u.ao.p2 = pOp->p2;
  u.ao.pC = 0;
  memset(&u.ao.sMem, 0, sizeof(u.ao.sMem));
  assert( u.ao.p1<p->nCursor );
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  u.ao.pDest = &aMem[pOp->p3];
  memAboutToChange(p, u.ao.pDest);
  u.ao.zRec = 0;

  /* This block sets the variable u.ao.payloadSize to be the total number of
  ** bytes in the record.
  **







|







68173
68174
68175
68176
68177
68178
68179
68180
68181
68182
68183
68184
68185
68186
68187


  u.ao.p1 = pOp->p1;
  u.ao.p2 = pOp->p2;
  u.ao.pC = 0;
  memset(&u.ao.sMem, 0, sizeof(u.ao.sMem));
  assert( u.ao.p1<p->nCursor );
  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  u.ao.pDest = &aMem[pOp->p3];
  memAboutToChange(p, u.ao.pDest);
  u.ao.zRec = 0;

  /* This block sets the variable u.ao.payloadSize to be the total number of
  ** bytes in the record.
  **
67846
67847
67848
67849
67850
67851
67852
67853
67854
67855
67856
67857
67858
67859
67860
#endif /* local variables moved into u.ap */

  u.ap.zAffinity = pOp->p4.z;
  assert( u.ap.zAffinity!=0 );
  assert( u.ap.zAffinity[pOp->p2]==0 );
  pIn1 = &aMem[pOp->p1];
  while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){
    assert( pIn1 <= &p->aMem[p->nMem] );
    assert( memIsValid(pIn1) );
    ExpandBlob(pIn1);
    applyAffinity(pIn1, u.ap.cAff, encoding);
    pIn1++;
  }
  break;
}







|







68473
68474
68475
68476
68477
68478
68479
68480
68481
68482
68483
68484
68485
68486
68487
#endif /* local variables moved into u.ap */

  u.ap.zAffinity = pOp->p4.z;
  assert( u.ap.zAffinity!=0 );
  assert( u.ap.zAffinity[pOp->p2]==0 );
  pIn1 = &aMem[pOp->p1];
  while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){
    assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] );
    assert( memIsValid(pIn1) );
    ExpandBlob(pIn1);
    applyAffinity(pIn1, u.ap.cAff, encoding);
    pIn1++;
  }
  break;
}
67909
67910
67911
67912
67913
67914
67915
67916
67917
67918
67919
67920
67921
67922
67923
  ** of the record to data0.
  */
  u.aq.nData = 0;         /* Number of bytes of data space */
  u.aq.nHdr = 0;          /* Number of bytes of header space */
  u.aq.nZero = 0;         /* Number of zero bytes at the end of the record */
  u.aq.nField = pOp->p1;
  u.aq.zAffinity = pOp->p4.z;
  assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=p->nMem+1 );
  u.aq.pData0 = &aMem[u.aq.nField];
  u.aq.nField = pOp->p2;
  u.aq.pLast = &u.aq.pData0[u.aq.nField-1];
  u.aq.file_format = p->minWriteFileFormat;

  /* Identify the output register */
  assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );







|







68536
68537
68538
68539
68540
68541
68542
68543
68544
68545
68546
68547
68548
68549
68550
  ** of the record to data0.
  */
  u.aq.nData = 0;         /* Number of bytes of data space */
  u.aq.nHdr = 0;          /* Number of bytes of header space */
  u.aq.nZero = 0;         /* Number of zero bytes at the end of the record */
  u.aq.nField = pOp->p1;
  u.aq.zAffinity = pOp->p4.z;
  assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=(p->nMem-p->nCursor)+1 );
  u.aq.pData0 = &aMem[u.aq.nField];
  u.aq.nField = pOp->p2;
  u.aq.pLast = &u.aq.pData0[u.aq.nField-1];
  u.aq.file_format = p->minWriteFileFormat;

  /* Identify the output register */
  assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
67975
67976
67977
67978
67979
67980
67981
67982
67983
67984
67985
67986
67987
67988
67989
    u.aq.i += putVarint32(&u.aq.zNewRecord[u.aq.i], u.aq.serial_type);      /* serial type */
  }
  for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){  /* serial data */
    u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format);
  }
  assert( u.aq.i==u.aq.nByte );

  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pOut->n = (int)u.aq.nByte;
  pOut->flags = MEM_Blob | MEM_Dyn;
  pOut->xDel = 0;
  if( u.aq.nZero ){
    pOut->u.nZero = u.aq.nZero;
    pOut->flags |= MEM_Zero;
  }







|







68602
68603
68604
68605
68606
68607
68608
68609
68610
68611
68612
68613
68614
68615
68616
    u.aq.i += putVarint32(&u.aq.zNewRecord[u.aq.i], u.aq.serial_type);      /* serial type */
  }
  for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){  /* serial data */
    u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format);
  }
  assert( u.aq.i==u.aq.nByte );

  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  pOut->n = (int)u.aq.nByte;
  pOut->flags = MEM_Blob | MEM_Dyn;
  pOut->xDel = 0;
  if( u.aq.nZero ){
    pOut->u.nZero = u.aq.nZero;
    pOut->flags |= MEM_Zero;
  }
68571
68572
68573
68574
68575
68576
68577
68578
68579
68580
68581
68582
68583
68584
68585
      p->minWriteFileFormat = u.ay.pDb->pSchema->file_format;
    }
  }else{
    u.ay.wrFlag = 0;
  }
  if( pOp->p5 & OPFLAG_P2ISREG ){
    assert( u.ay.p2>0 );
    assert( u.ay.p2<=p->nMem );
    pIn2 = &aMem[u.ay.p2];
    assert( memIsValid(pIn2) );
    assert( (pIn2->flags & MEM_Int)!=0 );
    sqlite3VdbeMemIntegerify(pIn2);
    u.ay.p2 = (int)pIn2->u.i;
    /* The u.ay.p2 value always comes from a prior OP_CreateTable opcode and
    ** that opcode will always set the u.ay.p2 value to 2 or more or else fail.







|







69198
69199
69200
69201
69202
69203
69204
69205
69206
69207
69208
69209
69210
69211
69212
      p->minWriteFileFormat = u.ay.pDb->pSchema->file_format;
    }
  }else{
    u.ay.wrFlag = 0;
  }
  if( pOp->p5 & OPFLAG_P2ISREG ){
    assert( u.ay.p2>0 );
    assert( u.ay.p2<=(p->nMem-p->nCursor) );
    pIn2 = &aMem[u.ay.p2];
    assert( memIsValid(pIn2) );
    assert( (pIn2->flags & MEM_Int)!=0 );
    sqlite3VdbeMemIntegerify(pIn2);
    u.ay.p2 = (int)pIn2->u.i;
    /* The u.ay.p2 value always comes from a prior OP_CreateTable opcode and
    ** that opcode will always set the u.ay.p2 value to 2 or more or else fail.
69122
69123
69124
69125
69126
69127
69128
69129
69130
69131
69132
69133
69134
69135
69136
  i64 R;                             /* Rowid stored in register P3 */
#endif /* local variables moved into u.bf */

  pIn3 = &aMem[pOp->p3];
  u.bf.aMx = &aMem[pOp->p4.i];
  /* Assert that the values of parameters P1 and P4 are in range. */
  assert( pOp->p4type==P4_INT32 );
  assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );

  /* Find the index cursor. */
  u.bf.pCx = p->apCsr[pOp->p1];
  assert( u.bf.pCx->deferredMoveto==0 );
  u.bf.pCx->seekResult = 0;
  u.bf.pCx->cacheStatus = CACHE_STALE;







|







69749
69750
69751
69752
69753
69754
69755
69756
69757
69758
69759
69760
69761
69762
69763
  i64 R;                             /* Rowid stored in register P3 */
#endif /* local variables moved into u.bf */

  pIn3 = &aMem[pOp->p3];
  u.bf.aMx = &aMem[pOp->p4.i];
  /* Assert that the values of parameters P1 and P4 are in range. */
  assert( pOp->p4type==P4_INT32 );
  assert( pOp->p4.i>0 && pOp->p4.i<=(p->nMem-p->nCursor) );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );

  /* Find the index cursor. */
  u.bf.pCx = p->apCsr[pOp->p1];
  assert( u.bf.pCx->deferredMoveto==0 );
  u.bf.pCx->seekResult = 0;
  u.bf.pCx->cacheStatus = CACHE_STALE;
69329
69330
69331
69332
69333
69334
69335
69336
69337
69338
69339
69340
69341
69342
69343
        if( p->pFrame ){
          for(u.bh.pFrame=p->pFrame; u.bh.pFrame->pParent; u.bh.pFrame=u.bh.pFrame->pParent);
          /* Assert that P3 is a valid memory cell. */
          assert( pOp->p3<=u.bh.pFrame->nMem );
          u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3];
        }else{
          /* Assert that P3 is a valid memory cell. */
          assert( pOp->p3<=p->nMem );
          u.bh.pMem = &aMem[pOp->p3];
          memAboutToChange(p, u.bh.pMem);
        }
        assert( memIsValid(u.bh.pMem) );

        REGISTER_TRACE(pOp->p3, u.bh.pMem);
        sqlite3VdbeMemIntegerify(u.bh.pMem);







|







69956
69957
69958
69959
69960
69961
69962
69963
69964
69965
69966
69967
69968
69969
69970
        if( p->pFrame ){
          for(u.bh.pFrame=p->pFrame; u.bh.pFrame->pParent; u.bh.pFrame=u.bh.pFrame->pParent);
          /* Assert that P3 is a valid memory cell. */
          assert( pOp->p3<=u.bh.pFrame->nMem );
          u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3];
        }else{
          /* Assert that P3 is a valid memory cell. */
          assert( pOp->p3<=(p->nMem-p->nCursor) );
          u.bh.pMem = &aMem[pOp->p3];
          memAboutToChange(p, u.bh.pMem);
        }
        assert( memIsValid(u.bh.pMem) );

        REGISTER_TRACE(pOp->p3, u.bh.pMem);
        sqlite3VdbeMemIntegerify(u.bh.pMem);
69739
69740
69741
69742
69743
69744
69745
69746
69747
69748
69749
69750
69751
69752
69753
    u.bn.v = u.bn.pC->movetoTarget;
#ifndef SQLITE_OMIT_VIRTUALTABLE
  }else if( u.bn.pC->pVtabCursor ){
    u.bn.pVtab = u.bn.pC->pVtabCursor->pVtab;
    u.bn.pModule = u.bn.pVtab->pModule;
    assert( u.bn.pModule->xRowid );
    rc = u.bn.pModule->xRowid(u.bn.pC->pVtabCursor, &u.bn.v);
    importVtabErrMsg(p, u.bn.pVtab);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
  }else{
    assert( u.bn.pC->pCursor!=0 );
    rc = sqlite3VdbeCursorMoveto(u.bn.pC);
    if( rc ) goto abort_due_to_error;
    if( u.bn.pC->rowidIsValid ){
      u.bn.v = u.bn.pC->lastRowid;







|







70366
70367
70368
70369
70370
70371
70372
70373
70374
70375
70376
70377
70378
70379
70380
    u.bn.v = u.bn.pC->movetoTarget;
#ifndef SQLITE_OMIT_VIRTUALTABLE
  }else if( u.bn.pC->pVtabCursor ){
    u.bn.pVtab = u.bn.pC->pVtabCursor->pVtab;
    u.bn.pModule = u.bn.pVtab->pModule;
    assert( u.bn.pModule->xRowid );
    rc = u.bn.pModule->xRowid(u.bn.pC->pVtabCursor, &u.bn.v);
    sqlite3VtabImportErrmsg(p, u.bn.pVtab);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
  }else{
    assert( u.bn.pC->pCursor!=0 );
    rc = sqlite3VdbeCursorMoveto(u.bn.pC);
    if( rc ) goto abort_due_to_error;
    if( u.bn.pC->rowidIsValid ){
      u.bn.v = u.bn.pC->lastRowid;
69831
69832
69833
69834
69835
69836
69837
69838
69839
69840
69841
69842
69843
69844
69845
*/
case OP_SorterSort:    /* jump */
case OP_Sort: {        /* jump */
#ifdef SQLITE_TEST
  sqlite3_sort_count++;
  sqlite3_search_count--;
#endif
  p->aCounter[SQLITE_STMTSTATUS_SORT-1]++;
  /* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.







|







70458
70459
70460
70461
70462
70463
70464
70465
70466
70467
70468
70469
70470
70471
70472
*/
case OP_SorterSort:    /* jump */
case OP_Sort: {        /* jump */
#ifdef SQLITE_TEST
  sqlite3_sort_count++;
  sqlite3_search_count--;
#endif
  p->aCounter[SQLITE_STMTSTATUS_SORT]++;
  /* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
69914
69915
69916
69917
69918
69919
69920
69921
69922
69923
69924
69925
69926
69927
69928
69929
69930
69931
69932
69933
69934
69935
69936
69937
69938
69939
69940
69941
69942
69943
69944
69945
69946
69947
69948
69949
case OP_Next: {        /* jump */
#if 0  /* local variables moved into u.br */
  VdbeCursor *pC;
  int res;
#endif /* local variables moved into u.br */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p5<=ArraySize(p->aCounter) );
  u.br.pC = p->apCsr[pOp->p1];
  if( u.br.pC==0 ){
    break;  /* See ticket #2273 */
  }
  assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterNext) );
  if( isSorter(u.br.pC) ){
    assert( pOp->opcode==OP_SorterNext );
    rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res);
  }else{
    u.br.res = 1;
    assert( u.br.pC->deferredMoveto==0 );
    assert( u.br.pC->pCursor );
    assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
    assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
    rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res);
  }
  u.br.pC->nullRow = (u8)u.br.res;
  u.br.pC->cacheStatus = CACHE_STALE;
  if( u.br.res==0 ){
    pc = pOp->p2 - 1;
    if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
#ifdef SQLITE_TEST
    sqlite3_search_count++;
#endif
  }
  u.br.pC->rowidIsValid = 0;
  goto check_for_interrupt;
}







|









|










|







70541
70542
70543
70544
70545
70546
70547
70548
70549
70550
70551
70552
70553
70554
70555
70556
70557
70558
70559
70560
70561
70562
70563
70564
70565
70566
70567
70568
70569
70570
70571
70572
70573
70574
70575
70576
case OP_Next: {        /* jump */
#if 0  /* local variables moved into u.br */
  VdbeCursor *pC;
  int res;
#endif /* local variables moved into u.br */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p5<ArraySize(p->aCounter) );
  u.br.pC = p->apCsr[pOp->p1];
  if( u.br.pC==0 ){
    break;  /* See ticket #2273 */
  }
  assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterNext) );
  if( isSorter(u.br.pC) ){
    assert( pOp->opcode==OP_SorterNext );
    rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res);
  }else{
    /* u.br.res = 1; // Always initialized by the xAdvance() call */
    assert( u.br.pC->deferredMoveto==0 );
    assert( u.br.pC->pCursor );
    assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
    assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
    rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res);
  }
  u.br.pC->nullRow = (u8)u.br.res;
  u.br.pC->cacheStatus = CACHE_STALE;
  if( u.br.res==0 ){
    pc = pOp->p2 - 1;
    p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
    sqlite3_search_count++;
#endif
  }
  u.br.pC->rowidIsValid = 0;
  goto check_for_interrupt;
}
70007
70008
70009
70010
70011
70012
70013
70014
70015
70016
70017
70018
70019
70020
70021
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
  UnpackedRecord r;
#endif /* local variables moved into u.bt */

  assert( pOp->p3>0 );
  assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bt.pC = p->apCsr[pOp->p1];
  assert( u.bt.pC!=0 );
  u.bt.pCrsr = u.bt.pC->pCursor;
  if( ALWAYS(u.bt.pCrsr!=0) ){
    u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
    u.bt.r.nField = (u16)pOp->p3;







|







70634
70635
70636
70637
70638
70639
70640
70641
70642
70643
70644
70645
70646
70647
70648
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
  UnpackedRecord r;
#endif /* local variables moved into u.bt */

  assert( pOp->p3>0 );
  assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bt.pC = p->apCsr[pOp->p1];
  assert( u.bt.pC!=0 );
  u.bt.pCrsr = u.bt.pC->pCursor;
  if( ALWAYS(u.bt.pCrsr!=0) ){
    u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
    u.bt.r.nField = (u16)pOp->p3;
70223
70224
70225
70226
70227
70228
70229

70230
70231
70232
70233
70234
70235
70236
case OP_Clear: {
#if 0  /* local variables moved into u.bx */
  int nChange;
#endif /* local variables moved into u.bx */

  u.bx.nChange = 0;
  assert( p->readOnly==0 );

  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
  rc = sqlite3BtreeClearTable(
      db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0)
  );
  if( pOp->p3 ){
    p->nChange += u.bx.nChange;
    if( pOp->p3>0 ){







>







70850
70851
70852
70853
70854
70855
70856
70857
70858
70859
70860
70861
70862
70863
70864
case OP_Clear: {
#if 0  /* local variables moved into u.bx */
  int nChange;
#endif /* local variables moved into u.bx */

  u.bx.nChange = 0;
  assert( p->readOnly==0 );
  assert( pOp->p1!=1 );
  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
  rc = sqlite3BtreeClearTable(
      db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0)
  );
  if( pOp->p3 ){
    p->nChange += u.bx.nChange;
    if( pOp->p3>0 ){
70429
70430
70431
70432
70433
70434
70435
70436
70437
70438
70439
70440
70441
70442
70443
#endif /* local variables moved into u.ca */

  assert( p->bIsReader );
  u.ca.nRoot = pOp->p2;
  assert( u.ca.nRoot>0 );
  u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) );
  if( u.ca.aRoot==0 ) goto no_mem;
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  u.ca.pnErr = &aMem[pOp->p3];
  assert( (u.ca.pnErr->flags & MEM_Int)!=0 );
  assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
  pIn1 = &aMem[pOp->p1];
  for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){
    u.ca.aRoot[u.ca.j] = (int)sqlite3VdbeIntValue(&pIn1[u.ca.j]);
  }







|







71057
71058
71059
71060
71061
71062
71063
71064
71065
71066
71067
71068
71069
71070
71071
#endif /* local variables moved into u.ca */

  assert( p->bIsReader );
  u.ca.nRoot = pOp->p2;
  assert( u.ca.nRoot>0 );
  u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) );
  if( u.ca.aRoot==0 ) goto no_mem;
  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  u.ca.pnErr = &aMem[pOp->p3];
  assert( (u.ca.pnErr->flags & MEM_Int)!=0 );
  assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
  pIn1 = &aMem[pOp->p1];
  for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){
    u.ca.aRoot[u.ca.j] = (int)sqlite3VdbeIntValue(&pIn1[u.ca.j]);
  }
70865
70866
70867
70868
70869
70870
70871
70872
70873
70874
70875
70876
70877
70878
70879
  for(u.cg.i=0; u.cg.i<u.cg.n; u.cg.i++, u.cg.pRec++){
    assert( memIsValid(u.cg.pRec) );
    u.cg.apVal[u.cg.i] = u.cg.pRec;
    memAboutToChange(p, u.cg.pRec);
    sqlite3VdbeMemStoreType(u.cg.pRec);
  }
  u.cg.ctx.pFunc = pOp->p4.pFunc;
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3];
  u.cg.pMem->n++;
  u.cg.ctx.s.flags = MEM_Null;
  u.cg.ctx.s.z = 0;
  u.cg.ctx.s.zMalloc = 0;
  u.cg.ctx.s.xDel = 0;
  u.cg.ctx.s.db = db;







|







71493
71494
71495
71496
71497
71498
71499
71500
71501
71502
71503
71504
71505
71506
71507
  for(u.cg.i=0; u.cg.i<u.cg.n; u.cg.i++, u.cg.pRec++){
    assert( memIsValid(u.cg.pRec) );
    u.cg.apVal[u.cg.i] = u.cg.pRec;
    memAboutToChange(p, u.cg.pRec);
    sqlite3VdbeMemStoreType(u.cg.pRec);
  }
  u.cg.ctx.pFunc = pOp->p4.pFunc;
  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3];
  u.cg.pMem->n++;
  u.cg.ctx.s.flags = MEM_Null;
  u.cg.ctx.s.z = 0;
  u.cg.ctx.s.zMalloc = 0;
  u.cg.ctx.s.xDel = 0;
  u.cg.ctx.s.db = db;
70914
70915
70916
70917
70918
70919
70920
70921
70922
70923
70924
70925
70926
70927
70928
** P4 argument is only needed for the degenerate case where
** the step function was not previously called.
*/
case OP_AggFinal: {
#if 0  /* local variables moved into u.ch */
  Mem *pMem;
#endif /* local variables moved into u.ch */
  assert( pOp->p1>0 && pOp->p1<=p->nMem );
  u.ch.pMem = &aMem[pOp->p1];
  assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
  rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc);
  if( rc ){
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem));
  }
  sqlite3VdbeChangeEncoding(u.ch.pMem, encoding);







|







71542
71543
71544
71545
71546
71547
71548
71549
71550
71551
71552
71553
71554
71555
71556
** P4 argument is only needed for the degenerate case where
** the step function was not previously called.
*/
case OP_AggFinal: {
#if 0  /* local variables moved into u.ch */
  Mem *pMem;
#endif /* local variables moved into u.ch */
  assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
  u.ch.pMem = &aMem[pOp->p1];
  assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
  rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc);
  if( rc ){
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem));
  }
  sqlite3VdbeChangeEncoding(u.ch.pMem, encoding);
71180
71181
71182
71183
71184
71185
71186
71187
71188
71189
71190
71191
71192
71193
71194
*/
case OP_VBegin: {
#if 0  /* local variables moved into u.cl */
  VTable *pVTab;
#endif /* local variables moved into u.cl */
  u.cl.pVTab = pOp->p4.pVtab;
  rc = sqlite3VtabBegin(db, u.cl.pVTab);
  if( u.cl.pVTab ) importVtabErrMsg(p, u.cl.pVTab->pVtab);
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VCreate P1 * * P4 *
**







|







71808
71809
71810
71811
71812
71813
71814
71815
71816
71817
71818
71819
71820
71821
71822
*/
case OP_VBegin: {
#if 0  /* local variables moved into u.cl */
  VTable *pVTab;
#endif /* local variables moved into u.cl */
  u.cl.pVTab = pOp->p4.pVtab;
  rc = sqlite3VtabBegin(db, u.cl.pVTab);
  if( u.cl.pVTab ) sqlite3VtabImportErrmsg(p, u.cl.pVTab->pVtab);
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VCreate P1 * * P4 *
**
71233
71234
71235
71236
71237
71238
71239
71240
71241
71242
71243
71244
71245
71246
71247
  assert( p->bIsReader );
  u.cm.pCur = 0;
  u.cm.pVtabCursor = 0;
  u.cm.pVtab = pOp->p4.pVtab->pVtab;
  u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule;
  assert(u.cm.pVtab && u.cm.pModule);
  rc = u.cm.pModule->xOpen(u.cm.pVtab, &u.cm.pVtabCursor);
  importVtabErrMsg(p, u.cm.pVtab);
  if( SQLITE_OK==rc ){
    /* Initialize sqlite3_vtab_cursor base class */
    u.cm.pVtabCursor->pVtab = u.cm.pVtab;

    /* Initialize vdbe cursor object */
    u.cm.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
    if( u.cm.pCur ){







|







71861
71862
71863
71864
71865
71866
71867
71868
71869
71870
71871
71872
71873
71874
71875
  assert( p->bIsReader );
  u.cm.pCur = 0;
  u.cm.pVtabCursor = 0;
  u.cm.pVtab = pOp->p4.pVtab->pVtab;
  u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule;
  assert(u.cm.pVtab && u.cm.pModule);
  rc = u.cm.pModule->xOpen(u.cm.pVtab, &u.cm.pVtabCursor);
  sqlite3VtabImportErrmsg(p, u.cm.pVtab);
  if( SQLITE_OK==rc ){
    /* Initialize sqlite3_vtab_cursor base class */
    u.cm.pVtabCursor->pVtab = u.cm.pVtab;

    /* Initialize vdbe cursor object */
    u.cm.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
    if( u.cm.pCur ){
71313
71314
71315
71316
71317
71318
71319
71320
71321
71322
71323
71324
71325
71326
71327
      u.cn.apArg[u.cn.i] = &u.cn.pArgc[u.cn.i+1];
      sqlite3VdbeMemStoreType(u.cn.apArg[u.cn.i]);
    }

    p->inVtabMethod = 1;
    rc = u.cn.pModule->xFilter(u.cn.pVtabCursor, u.cn.iQuery, pOp->p4.z, u.cn.nArg, u.cn.apArg);
    p->inVtabMethod = 0;
    importVtabErrMsg(p, u.cn.pVtab);
    if( rc==SQLITE_OK ){
      u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor);
    }

    if( u.cn.res ){
      pc = pOp->p2 - 1;
    }







|







71941
71942
71943
71944
71945
71946
71947
71948
71949
71950
71951
71952
71953
71954
71955
      u.cn.apArg[u.cn.i] = &u.cn.pArgc[u.cn.i+1];
      sqlite3VdbeMemStoreType(u.cn.apArg[u.cn.i]);
    }

    p->inVtabMethod = 1;
    rc = u.cn.pModule->xFilter(u.cn.pVtabCursor, u.cn.iQuery, pOp->p4.z, u.cn.nArg, u.cn.apArg);
    p->inVtabMethod = 0;
    sqlite3VtabImportErrmsg(p, u.cn.pVtab);
    if( rc==SQLITE_OK ){
      u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor);
    }

    if( u.cn.res ){
      pc = pOp->p2 - 1;
    }
71345
71346
71347
71348
71349
71350
71351
71352
71353
71354
71355
71356
71357
71358
71359
71360
71361
71362
71363
71364
71365
71366
71367
71368
71369
71370
71371
71372
71373
71374
71375
71376
71377
71378
71379
71380
  const sqlite3_module *pModule;
  Mem *pDest;
  sqlite3_context sContext;
#endif /* local variables moved into u.co */

  VdbeCursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  u.co.pDest = &aMem[pOp->p3];
  memAboutToChange(p, u.co.pDest);
  if( pCur->nullRow ){
    sqlite3VdbeMemSetNull(u.co.pDest);
    break;
  }
  u.co.pVtab = pCur->pVtabCursor->pVtab;
  u.co.pModule = u.co.pVtab->pModule;
  assert( u.co.pModule->xColumn );
  memset(&u.co.sContext, 0, sizeof(u.co.sContext));

  /* The output cell may already have a buffer allocated. Move
  ** the current contents to u.co.sContext.s so in case the user-function
  ** can use the already allocated buffer instead of allocating a
  ** new one.
  */
  sqlite3VdbeMemMove(&u.co.sContext.s, u.co.pDest);
  MemSetTypeFlag(&u.co.sContext.s, MEM_Null);

  rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2);
  importVtabErrMsg(p, u.co.pVtab);
  if( u.co.sContext.isError ){
    rc = u.co.sContext.isError;
  }

  /* Copy the result of the function to the P3 register. We
  ** do this regardless of whether or not an error occurred to ensure any
  ** dynamic allocation in u.co.sContext.s (a Mem struct) is  released.







|




















|







71973
71974
71975
71976
71977
71978
71979
71980
71981
71982
71983
71984
71985
71986
71987
71988
71989
71990
71991
71992
71993
71994
71995
71996
71997
71998
71999
72000
72001
72002
72003
72004
72005
72006
72007
72008
  const sqlite3_module *pModule;
  Mem *pDest;
  sqlite3_context sContext;
#endif /* local variables moved into u.co */

  VdbeCursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  u.co.pDest = &aMem[pOp->p3];
  memAboutToChange(p, u.co.pDest);
  if( pCur->nullRow ){
    sqlite3VdbeMemSetNull(u.co.pDest);
    break;
  }
  u.co.pVtab = pCur->pVtabCursor->pVtab;
  u.co.pModule = u.co.pVtab->pModule;
  assert( u.co.pModule->xColumn );
  memset(&u.co.sContext, 0, sizeof(u.co.sContext));

  /* The output cell may already have a buffer allocated. Move
  ** the current contents to u.co.sContext.s so in case the user-function
  ** can use the already allocated buffer instead of allocating a
  ** new one.
  */
  sqlite3VdbeMemMove(&u.co.sContext.s, u.co.pDest);
  MemSetTypeFlag(&u.co.sContext.s, MEM_Null);

  rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2);
  sqlite3VtabImportErrmsg(p, u.co.pVtab);
  if( u.co.sContext.isError ){
    rc = u.co.sContext.isError;
  }

  /* Copy the result of the function to the P3 register. We
  ** do this regardless of whether or not an error occurred to ensure any
  ** dynamic allocation in u.co.sContext.s (a Mem struct) is  released.
71421
71422
71423
71424
71425
71426
71427
71428
71429
71430
71431
71432
71433
71434
71435
  ** xNext(). Instead, if an error occurs, true is returned (indicating that
  ** data is available) and the error code returned when xColumn or
  ** some other method is next invoked on the save virtual table cursor.
  */
  p->inVtabMethod = 1;
  rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor);
  p->inVtabMethod = 0;
  importVtabErrMsg(p, u.cp.pVtab);
  if( rc==SQLITE_OK ){
    u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor);
  }

  if( !u.cp.res ){
    /* If there is data, jump to P2 */
    pc = pOp->p2 - 1;







|







72049
72050
72051
72052
72053
72054
72055
72056
72057
72058
72059
72060
72061
72062
72063
  ** xNext(). Instead, if an error occurs, true is returned (indicating that
  ** data is available) and the error code returned when xColumn or
  ** some other method is next invoked on the save virtual table cursor.
  */
  p->inVtabMethod = 1;
  rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor);
  p->inVtabMethod = 0;
  sqlite3VtabImportErrmsg(p, u.cp.pVtab);
  if( rc==SQLITE_OK ){
    u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor);
  }

  if( !u.cp.res ){
    /* If there is data, jump to P2 */
    pc = pOp->p2 - 1;
71460
71461
71462
71463
71464
71465
71466
71467
71468
71469
71470
71471
71472
71473
71474
  assert( u.cq.pName->flags & MEM_Str );
  testcase( u.cq.pName->enc==SQLITE_UTF8 );
  testcase( u.cq.pName->enc==SQLITE_UTF16BE );
  testcase( u.cq.pName->enc==SQLITE_UTF16LE );
  rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8);
  if( rc==SQLITE_OK ){
    rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z);
    importVtabErrMsg(p, u.cq.pVtab);
    p->expired = 0;
  }
  break;
}
#endif

#ifndef SQLITE_OMIT_VIRTUALTABLE







|







72088
72089
72090
72091
72092
72093
72094
72095
72096
72097
72098
72099
72100
72101
72102
  assert( u.cq.pName->flags & MEM_Str );
  testcase( u.cq.pName->enc==SQLITE_UTF8 );
  testcase( u.cq.pName->enc==SQLITE_UTF16BE );
  testcase( u.cq.pName->enc==SQLITE_UTF16LE );
  rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8);
  if( rc==SQLITE_OK ){
    rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z);
    sqlite3VtabImportErrmsg(p, u.cq.pVtab);
    p->expired = 0;
  }
  break;
}
#endif

#ifndef SQLITE_OMIT_VIRTUALTABLE
71524
71525
71526
71527
71528
71529
71530
71531
71532
71533
71534
71535
71536
71537
71538
      sqlite3VdbeMemStoreType(u.cr.pX);
      u.cr.apArg[u.cr.i] = u.cr.pX;
      u.cr.pX++;
    }
    db->vtabOnConflict = pOp->p5;
    rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid);
    db->vtabOnConflict = vtabOnConflict;
    importVtabErrMsg(p, u.cr.pVtab);
    if( rc==SQLITE_OK && pOp->p1 ){
      assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
      db->lastRowid = lastRowid = u.cr.rowid;
    }
    if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
      if( pOp->p5==OE_Ignore ){
        rc = SQLITE_OK;







|







72152
72153
72154
72155
72156
72157
72158
72159
72160
72161
72162
72163
72164
72165
72166
      sqlite3VdbeMemStoreType(u.cr.pX);
      u.cr.apArg[u.cr.i] = u.cr.pX;
      u.cr.pX++;
    }
    db->vtabOnConflict = pOp->p5;
    rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid);
    db->vtabOnConflict = vtabOnConflict;
    sqlite3VtabImportErrmsg(p, u.cr.pVtab);
    if( rc==SQLITE_OK && pOp->p1 ){
      assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
      db->lastRowid = lastRowid = u.cr.rowid;
    }
    if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
      if( pOp->p5==OE_Ignore ){
        rc = SQLITE_OK;
71691
71692
71693
71694
71695
71696
71697

71698
71699
71700
71701
71702
71703
71704
71705
  }

  /* This is the only way out of this procedure.  We have to
  ** release the mutexes on btrees that were acquired at the
  ** top. */
vdbe_return:
  db->lastRowid = lastRowid;

  p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1] += (int)nVmStep;
  sqlite3VdbeLeave(p);
  return rc;

  /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
  ** is encountered.
  */
too_big:







>
|







72319
72320
72321
72322
72323
72324
72325
72326
72327
72328
72329
72330
72331
72332
72333
72334
  }

  /* This is the only way out of this procedure.  We have to
  ** release the mutexes on btrees that were acquired at the
  ** top. */
vdbe_return:
  db->lastRowid = lastRowid;
  testcase( nVmStep>0 );
  p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
  sqlite3VdbeLeave(p);
  return rc;

  /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
  ** is encountered.
  */
too_big:
73970
73971
73972
73973
73974
73975
73976
73977
73978
73979
73980
73981
73982
73983
73984
73985
73986
73987
73988

73989
73990
73991
73992
73993
73994
73995
** TK_AS operator.  The TK_AS operator causes the expression to be
** evaluated just once and then reused for each alias.
**
** The reason for suppressing the TK_AS term when the expression is a simple
** column reference is so that the column reference will be recognized as
** usable by indices within the WHERE clause processing logic. 
**
** Hack:  The TK_AS operator is inhibited if zType[0]=='G'.  This means
** that in a GROUP BY clause, the expression is evaluated twice.  Hence:
**
**     SELECT random()%5 AS x, count(*) FROM tab GROUP BY x
**
** Is equivalent to:
**
**     SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
**
** The result of random()%5 in the GROUP BY clause is probably different
** from the result in the result-set.  We might fix this someday.  Or
** then again, we might not...

**
** If the reference is followed by a COLLATE operator, then make sure
** the COLLATE operator is preserved.  For example:
**
**     SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
**
** Should be transformed into:







|









|
|
>







74599
74600
74601
74602
74603
74604
74605
74606
74607
74608
74609
74610
74611
74612
74613
74614
74615
74616
74617
74618
74619
74620
74621
74622
74623
74624
74625
** TK_AS operator.  The TK_AS operator causes the expression to be
** evaluated just once and then reused for each alias.
**
** The reason for suppressing the TK_AS term when the expression is a simple
** column reference is so that the column reference will be recognized as
** usable by indices within the WHERE clause processing logic. 
**
** The TK_AS operator is inhibited if zType[0]=='G'.  This means
** that in a GROUP BY clause, the expression is evaluated twice.  Hence:
**
**     SELECT random()%5 AS x, count(*) FROM tab GROUP BY x
**
** Is equivalent to:
**
**     SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
**
** The result of random()%5 in the GROUP BY clause is probably different
** from the result in the result-set.  On the other hand Standard SQL does
** not allow the GROUP BY clause to contain references to result-set columns.
** So this should never come up in well-formed queries.
**
** If the reference is followed by a COLLATE operator, then make sure
** the COLLATE operator is preserved.  For example:
**
**     SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
**
** Should be transformed into:
74155
74156
74157
74158
74159
74160
74161








74162
74163
74164
74165
74166

74167
74168
74169
74170
74171
74172
74173
  ExprSetIrreducible(pExpr);

  /* Translate the schema name in zDb into a pointer to the corresponding
  ** schema.  If not found, pSchema will remain NULL and nothing will match
  ** resulting in an appropriate error message toward the end of this routine
  */
  if( zDb ){








    for(i=0; i<db->nDb; i++){
      assert( db->aDb[i].zName );
      if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
        pSchema = db->aDb[i].pSchema;
        break;

      }
    }
  }

  /* Start at the inner-most context and move outward until a match is found */
  while( pNC && cnt==0 ){
    ExprList *pEList;







>
>
>
>
>
>
>
>
|
|
|
|
|
>







74785
74786
74787
74788
74789
74790
74791
74792
74793
74794
74795
74796
74797
74798
74799
74800
74801
74802
74803
74804
74805
74806
74807
74808
74809
74810
74811
74812
  ExprSetIrreducible(pExpr);

  /* Translate the schema name in zDb into a pointer to the corresponding
  ** schema.  If not found, pSchema will remain NULL and nothing will match
  ** resulting in an appropriate error message toward the end of this routine
  */
  if( zDb ){
    testcase( pNC->ncFlags & NC_PartIdx );
    testcase( pNC->ncFlags & NC_IsCheck );
    if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
      /* Silently ignore database qualifiers inside CHECK constraints and partial
      ** indices.  Do not raise errors because that might break legacy and
      ** because it does not hurt anything to just ignore the database name. */
      zDb = 0;
    }else{
      for(i=0; i<db->nDb; i++){
        assert( db->aDb[i].zName );
        if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
          pSchema = db->aDb[i].pSchema;
          break;
        }
      }
    }
  }

  /* Start at the inner-most context and move outward until a match is found */
  while( pNC && cnt==0 ){
    ExprList *pEList;
74302
74303
74304
74305
74306
74307
74308






74309
74310
74311
74312
74313
74314
74315
74316
74317
74318
74319
    **
    **     SELECT a+b AS x FROM table WHERE x<10;
    **
    ** In cases like this, replace pExpr with a copy of the expression that
    ** forms the result set entry ("a+b" in the example) and return immediately.
    ** Note that the expression in the result set should have already been
    ** resolved by the time the WHERE clause is resolved.






    */
    if( (pEList = pNC->pEList)!=0
     && zTab==0
     && ((pNC->ncFlags & NC_AsMaybe)==0 || cnt==0)
    ){
      for(j=0; j<pEList->nExpr; j++){
        char *zAs = pEList->a[j].zName;
        if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
          Expr *pOrig;
          assert( pExpr->pLeft==0 && pExpr->pRight==0 );
          assert( pExpr->x.pList==0 );







>
>
>
>
>
>



|







74941
74942
74943
74944
74945
74946
74947
74948
74949
74950
74951
74952
74953
74954
74955
74956
74957
74958
74959
74960
74961
74962
74963
74964
    **
    **     SELECT a+b AS x FROM table WHERE x<10;
    **
    ** In cases like this, replace pExpr with a copy of the expression that
    ** forms the result set entry ("a+b" in the example) and return immediately.
    ** Note that the expression in the result set should have already been
    ** resolved by the time the WHERE clause is resolved.
    **
    ** The ability to use an output result-set column in the WHERE, GROUP BY,
    ** or HAVING clauses, or as part of a larger expression in the ORDRE BY
    ** clause is not standard SQL.  This is a (goofy) SQLite extension, that
    ** is supported for backwards compatibility only.  TO DO: Issue a warning
    ** on sqlite3_log() whenever the capability is used.
    */
    if( (pEList = pNC->pEList)!=0
     && zTab==0
     && cnt==0
    ){
      for(j=0; j<pEList->nExpr; j++){
        char *zAs = pEList->a[j].zName;
        if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
          Expr *pOrig;
          assert( pExpr->pLeft==0 && pExpr->pRight==0 );
          assert( pExpr->x.pList==0 );
74436
74437
74438
74439
74440
74441
74442

































74443
74444
74445
74446
74447
74448
74449
      testcase( iCol==BMS-1 );
      pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
    }
    ExprSetProperty(p, EP_Resolved);
  }
  return p;
}


































/*
** This routine is callback for sqlite3WalkExpr().
**
** Resolve symbolic names into TK_COLUMN operators for the current
** node in the expression tree.  Return 0 to continue the search down
** the tree or 2 to abort the tree walk.







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







75081
75082
75083
75084
75085
75086
75087
75088
75089
75090
75091
75092
75093
75094
75095
75096
75097
75098
75099
75100
75101
75102
75103
75104
75105
75106
75107
75108
75109
75110
75111
75112
75113
75114
75115
75116
75117
75118
75119
75120
75121
75122
75123
75124
75125
75126
75127
      testcase( iCol==BMS-1 );
      pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
    }
    ExprSetProperty(p, EP_Resolved);
  }
  return p;
}

/*
** Report an error that an expression is not valid for a partial index WHERE
** clause.
*/
static void notValidPartIdxWhere(
  Parse *pParse,       /* Leave error message here */
  NameContext *pNC,    /* The name context */
  const char *zMsg     /* Type of error */
){
  if( (pNC->ncFlags & NC_PartIdx)!=0 ){
    sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses",
                    zMsg);
  }
}

#ifndef SQLITE_OMIT_CHECK
/*
** Report an error that an expression is not valid for a CHECK constraint.
*/
static void notValidCheckConstraint(
  Parse *pParse,       /* Leave error message here */
  NameContext *pNC,    /* The name context */
  const char *zMsg     /* Type of error */
){
  if( (pNC->ncFlags & NC_IsCheck)!=0 ){
    sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg);
  }
}
#else
# define notValidCheckConstraint(P,N,M)
#endif


/*
** This routine is callback for sqlite3WalkExpr().
**
** Resolve symbolic names into TK_COLUMN operators for the current
** node in the expression tree.  Return 0 to continue the search down
** the tree or 2 to abort the tree walk.
74536
74537
74538
74539
74540
74541
74542

74543
74544
74545
74546
74547
74548
74549
      int nId;                    /* Number of characters in function name */
      const char *zId;            /* The function name. */
      FuncDef *pDef;              /* Information about the function */
      u8 enc = ENC(pParse->db);   /* The database encoding */

      testcase( pExpr->op==TK_CONST_FUNC );
      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );

      zId = pExpr->u.zToken;
      nId = sqlite3Strlen30(zId);
      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
      if( pDef==0 ){
        pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
        if( pDef==0 ){
          no_such_func = 1;







>







75214
75215
75216
75217
75218
75219
75220
75221
75222
75223
75224
75225
75226
75227
75228
      int nId;                    /* Number of characters in function name */
      const char *zId;            /* The function name. */
      FuncDef *pDef;              /* Information about the function */
      u8 enc = ENC(pParse->db);   /* The database encoding */

      testcase( pExpr->op==TK_CONST_FUNC );
      assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
      notValidPartIdxWhere(pParse, pNC, "functions");
      zId = pExpr->u.zToken;
      nId = sqlite3Strlen30(zId);
      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
      if( pDef==0 ){
        pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
        if( pDef==0 ){
          no_such_func = 1;
74601
74602
74603
74604
74605
74606
74607
74608
74609
74610
74611
74612
74613
74614
74615
74616
74617
74618
74619
74620
74621
74622
74623
74624
74625
74626
74627
74628
74629
74630
74631
74632
74633
74634
74635
    case TK_SELECT:
    case TK_EXISTS:  testcase( pExpr->op==TK_EXISTS );
#endif
    case TK_IN: {
      testcase( pExpr->op==TK_IN );
      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        int nRef = pNC->nRef;
#ifndef SQLITE_OMIT_CHECK
        if( (pNC->ncFlags & NC_IsCheck)!=0 ){
          sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
        }
#endif
        sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
        assert( pNC->nRef>=nRef );
        if( nRef!=pNC->nRef ){
          ExprSetProperty(pExpr, EP_VarSelect);
        }
      }
      break;
    }
#ifndef SQLITE_OMIT_CHECK
    case TK_VARIABLE: {
      if( (pNC->ncFlags & NC_IsCheck)!=0 ){
        sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
      }
      break;
    }
#endif
  }
  return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
}

/*
** pEList is a list of expressions which are really the result set of the
** a SELECT statement.  pE is a term in an ORDER BY or GROUP BY clause.







<
|
|
<
<








<

|
|
<


<







75280
75281
75282
75283
75284
75285
75286

75287
75288


75289
75290
75291
75292
75293
75294
75295
75296

75297
75298
75299

75300
75301

75302
75303
75304
75305
75306
75307
75308
    case TK_SELECT:
    case TK_EXISTS:  testcase( pExpr->op==TK_EXISTS );
#endif
    case TK_IN: {
      testcase( pExpr->op==TK_IN );
      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        int nRef = pNC->nRef;

        notValidCheckConstraint(pParse, pNC, "subqueries");
        notValidPartIdxWhere(pParse, pNC, "subqueries");


        sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
        assert( pNC->nRef>=nRef );
        if( nRef!=pNC->nRef ){
          ExprSetProperty(pExpr, EP_VarSelect);
        }
      }
      break;
    }

    case TK_VARIABLE: {
      notValidCheckConstraint(pParse, pNC, "parameters");
      notValidPartIdxWhere(pParse, pNC, "parameters");

      break;
    }

  }
  return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
}

/*
** pEList is a list of expressions which are really the result set of the
** a SELECT statement.  pE is a term in an ORDER BY or GROUP BY clause.
74712
74713
74714
74715
74716
74717
74718
74719
74720
74721
74722
74723
74724
74725
74726
  if( rc ) return 0;

  /* Try to match the ORDER BY expression against an expression
  ** in the result set.  Return an 1-based index of the matching
  ** result-set entry.
  */
  for(i=0; i<pEList->nExpr; i++){
    if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){
      return i+1;
    }
  }

  /* If no match, return 0. */
  return 0;
}







|







75385
75386
75387
75388
75389
75390
75391
75392
75393
75394
75395
75396
75397
75398
75399
  if( rc ) return 0;

  /* Try to match the ORDER BY expression against an expression
  ** in the result set.  Return an 1-based index of the matching
  ** result-set entry.
  */
  for(i=0; i<pEList->nExpr; i++){
    if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){
      return i+1;
    }
  }

  /* If no match, return 0. */
  return 0;
}
74839
74840
74841
74842
74843
74844
74845
74846
74847
74848
74849
74850
74851
74852
74853
  }
  return 0;
}

/*
** Check every term in the ORDER BY or GROUP BY clause pOrderBy of
** the SELECT statement pSelect.  If any term is reference to a
** result set expression (as determined by the ExprList.a.iCol field)
** then convert that term into a copy of the corresponding result set
** column.
**
** If any errors are detected, add an error message to pParse and
** return non-zero.  Return zero if no errors are seen.
*/
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(







|







75512
75513
75514
75515
75516
75517
75518
75519
75520
75521
75522
75523
75524
75525
75526
  }
  return 0;
}

/*
** Check every term in the ORDER BY or GROUP BY clause pOrderBy of
** the SELECT statement pSelect.  If any term is reference to a
** result set expression (as determined by the ExprList.a.iOrderByCol field)
** then convert that term into a copy of the corresponding result set
** column.
**
** If any errors are detected, add an error message to pParse and
** return non-zero.  Return zero if no errors are seen.
*/
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
74887
74888
74889
74890
74891
74892
74893
74894
74895
74896
74897
74898
74899
74900
74901
** The Name context of the SELECT statement is pNC.  zType is either
** "ORDER" or "GROUP" depending on which type of clause pOrderBy is.
**
** This routine resolves each term of the clause into an expression.
** If the order-by term is an integer I between 1 and N (where N is the
** number of columns in the result set of the SELECT) then the expression
** in the resolution is a copy of the I-th result-set expression.  If
** the order-by term is an identify that corresponds to the AS-name of
** a result-set expression, then the term resolves to a copy of the
** result-set expression.  Otherwise, the expression is resolved in
** the usual way - using sqlite3ResolveExprNames().
**
** This routine returns the number of errors.  If errors occur, then
** an appropriate error message might be left in pParse.  (OOM errors
** excepted.)







|







75560
75561
75562
75563
75564
75565
75566
75567
75568
75569
75570
75571
75572
75573
75574
** The Name context of the SELECT statement is pNC.  zType is either
** "ORDER" or "GROUP" depending on which type of clause pOrderBy is.
**
** This routine resolves each term of the clause into an expression.
** If the order-by term is an integer I between 1 and N (where N is the
** number of columns in the result set of the SELECT) then the expression
** in the resolution is a copy of the I-th result-set expression.  If
** the order-by term is an identifier that corresponds to the AS-name of
** a result-set expression, then the term resolves to a copy of the
** result-set expression.  Otherwise, the expression is resolved in
** the usual way - using sqlite3ResolveExprNames().
**
** This routine returns the number of errors.  If errors occur, then
** an appropriate error message might be left in pParse.  (OOM errors
** excepted.)
74913
74914
74915
74916
74917
74918
74919


74920
74921
74922
74923
74924
74925
74926
74927
74928

74929
74930
74931
74932
74933
74934
74935
74936
74937
74938
74939
74940
74941
74942
74943
74944
74945
74946
74947
74948
74949
74950
74951
74952
74953
74954
  int nResult;                   /* Number of terms in the result set */

  if( pOrderBy==0 ) return 0;
  nResult = pSelect->pEList->nExpr;
  pParse = pNC->pParse;
  for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
    Expr *pE = pItem->pExpr;


    iCol = resolveAsName(pParse, pSelect->pEList, pE);
    if( iCol>0 ){
      /* If an AS-name match is found, mark this ORDER BY column as being
      ** a copy of the iCol-th result-set column.  The subsequent call to
      ** sqlite3ResolveOrderGroupBy() will convert the expression to a
      ** copy of the iCol-th result-set expression. */
      pItem->iOrderByCol = (u16)iCol;
      continue;
    }

    if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
      /* The ORDER BY term is an integer constant.  Again, set the column
      ** number so that sqlite3ResolveOrderGroupBy() will convert the
      ** order-by term to a copy of the result-set expression */
      if( iCol<1 || iCol>0xffff ){
        resolveOutOfRangeError(pParse, zType, i+1, nResult);
        return 1;
      }
      pItem->iOrderByCol = (u16)iCol;
      continue;
    }

    /* Otherwise, treat the ORDER BY term as an ordinary expression */
    pItem->iOrderByCol = 0;
    if( sqlite3ResolveExprNames(pNC, pE) ){
      return 1;
    }
    for(j=0; j<pSelect->pEList->nExpr; j++){
      if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){
        pItem->iOrderByCol = j+1;
      }
    }
  }
  return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
}








>
>
|
|
|
|
|
|
|
|
|
>
|

















|







75586
75587
75588
75589
75590
75591
75592
75593
75594
75595
75596
75597
75598
75599
75600
75601
75602
75603
75604
75605
75606
75607
75608
75609
75610
75611
75612
75613
75614
75615
75616
75617
75618
75619
75620
75621
75622
75623
75624
75625
75626
75627
75628
75629
75630
  int nResult;                   /* Number of terms in the result set */

  if( pOrderBy==0 ) return 0;
  nResult = pSelect->pEList->nExpr;
  pParse = pNC->pParse;
  for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
    Expr *pE = pItem->pExpr;
    Expr *pE2 = sqlite3ExprSkipCollate(pE);
    if( zType[0]!='G' ){
      iCol = resolveAsName(pParse, pSelect->pEList, pE2);
      if( iCol>0 ){
        /* If an AS-name match is found, mark this ORDER BY column as being
        ** a copy of the iCol-th result-set column.  The subsequent call to
        ** sqlite3ResolveOrderGroupBy() will convert the expression to a
        ** copy of the iCol-th result-set expression. */
        pItem->iOrderByCol = (u16)iCol;
        continue;
      }
    }
    if( sqlite3ExprIsInteger(pE2, &iCol) ){
      /* The ORDER BY term is an integer constant.  Again, set the column
      ** number so that sqlite3ResolveOrderGroupBy() will convert the
      ** order-by term to a copy of the result-set expression */
      if( iCol<1 || iCol>0xffff ){
        resolveOutOfRangeError(pParse, zType, i+1, nResult);
        return 1;
      }
      pItem->iOrderByCol = (u16)iCol;
      continue;
    }

    /* Otherwise, treat the ORDER BY term as an ordinary expression */
    pItem->iOrderByCol = 0;
    if( sqlite3ResolveExprNames(pNC, pE) ){
      return 1;
    }
    for(j=0; j<pSelect->pEList->nExpr; j++){
      if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
        pItem->iOrderByCol = j+1;
      }
    }
  }
  return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
}

75065
75066
75067
75068
75069
75070
75071
75072
75073
75074
75075
75076
75077
75078
75079
75080
75081
75082
75083
75084
75085
75086
75087
75088
75089
75090
75091
    /* If a HAVING clause is present, then there must be a GROUP BY clause.
    */
    if( p->pHaving && !pGroupBy ){
      sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
      return WRC_Abort;
    }
  
    /* Add the expression list to the name-context before parsing the
    ** other expressions in the SELECT statement. This is so that
    ** expressions in the WHERE clause (etc.) can refer to expressions by
    ** aliases in the result set.
    **
    ** Minor point: If this is the case, then the expression will be
    ** re-evaluated for each reference to it.
    */
    sNC.pEList = p->pEList;
    sNC.ncFlags |= NC_AsMaybe;
    if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
    if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
    sNC.ncFlags &= ~NC_AsMaybe;

    /* The ORDER BY and GROUP BY clauses may not refer to terms in
    ** outer queries 
    */
    sNC.pNext = 0;
    sNC.ncFlags |= NC_AllowAgg;








|








<


<







75741
75742
75743
75744
75745
75746
75747
75748
75749
75750
75751
75752
75753
75754
75755
75756

75757
75758

75759
75760
75761
75762
75763
75764
75765
    /* If a HAVING clause is present, then there must be a GROUP BY clause.
    */
    if( p->pHaving && !pGroupBy ){
      sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
      return WRC_Abort;
    }
  
    /* Add the output column list to the name-context before parsing the
    ** other expressions in the SELECT statement. This is so that
    ** expressions in the WHERE clause (etc.) can refer to expressions by
    ** aliases in the result set.
    **
    ** Minor point: If this is the case, then the expression will be
    ** re-evaluated for each reference to it.
    */
    sNC.pEList = p->pEList;

    if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
    if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;


    /* The ORDER BY and GROUP BY clauses may not refer to terms in
    ** outer queries 
    */
    sNC.pNext = 0;
    sNC.ncFlags |= NC_AllowAgg;

75246
75247
75248
75249
75250
75251
75252










































75253
75254
75255
75256
75257
75258
75259
  memset(&w, 0, sizeof(w));
  w.xExprCallback = resolveExprStep;
  w.xSelectCallback = resolveSelectStep;
  w.pParse = pParse;
  w.u.pNC = pOuterNC;
  sqlite3WalkSelect(&w, p);
}











































/************** End of resolve.c *********************************************/
/************** Begin file expr.c ********************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of







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







75920
75921
75922
75923
75924
75925
75926
75927
75928
75929
75930
75931
75932
75933
75934
75935
75936
75937
75938
75939
75940
75941
75942
75943
75944
75945
75946
75947
75948
75949
75950
75951
75952
75953
75954
75955
75956
75957
75958
75959
75960
75961
75962
75963
75964
75965
75966
75967
75968
75969
75970
75971
75972
75973
75974
75975
  memset(&w, 0, sizeof(w));
  w.xExprCallback = resolveExprStep;
  w.xSelectCallback = resolveSelectStep;
  w.pParse = pParse;
  w.u.pNC = pOuterNC;
  sqlite3WalkSelect(&w, p);
}

/*
** Resolve names in expressions that can only reference a single table:
**
**    *   CHECK constraints
**    *   WHERE clauses on partial indices
**
** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
** is set to -1 and the Expr.iColumn value is set to the column number.
**
** Any errors cause an error message to be set in pParse.
*/
SQLITE_PRIVATE void sqlite3ResolveSelfReference(
  Parse *pParse,      /* Parsing context */
  Table *pTab,        /* The table being referenced */
  int type,           /* NC_IsCheck or NC_PartIdx */
  Expr *pExpr,        /* Expression to resolve.  May be NULL. */
  ExprList *pList     /* Expression list to resolve.  May be NUL. */
){
  SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
  NameContext sNC;                /* Name context for pParse->pNewTable */
  int i;                          /* Loop counter */

  assert( type==NC_IsCheck || type==NC_PartIdx );
  memset(&sNC, 0, sizeof(sNC));
  memset(&sSrc, 0, sizeof(sSrc));
  sSrc.nSrc = 1;
  sSrc.a[0].zName = pTab->zName;
  sSrc.a[0].pTab = pTab;
  sSrc.a[0].iCursor = -1;
  sNC.pParse = pParse;
  sNC.pSrcList = &sSrc;
  sNC.ncFlags = type;
  if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
  if( pList ){
    for(i=0; i<pList->nExpr; i++){
      if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
        return;
      }
    }
  }
}

/************** End of resolve.c *********************************************/
/************** Begin file expr.c ********************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
75364
75365
75366
75367
75368
75369
75370
75371
75372
75373
75374
75375
75376
75377
75378
75379
  Expr *p = pExpr;
  while( p ){
    int op = p->op;
    if( op==TK_CAST || op==TK_UPLUS ){
      p = p->pLeft;
      continue;
    }
    assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
    if( op==TK_COLLATE ){
      pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
      break;
    }
    if( p->pTab!=0
     && (op==TK_AGG_COLUMN || op==TK_COLUMN
          || op==TK_REGISTER || op==TK_TRIGGER)
    ){







<
|







76080
76081
76082
76083
76084
76085
76086

76087
76088
76089
76090
76091
76092
76093
76094
  Expr *p = pExpr;
  while( p ){
    int op = p->op;
    if( op==TK_CAST || op==TK_UPLUS ){
      p = p->pLeft;
      continue;
    }

    if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
      pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
      break;
    }
    if( p->pTab!=0
     && (op==TK_AGG_COLUMN || op==TK_COLUMN
          || op==TK_REGISTER || op==TK_TRIGGER)
    ){
76529
76530
76531
76532
76533
76534
76535

76536
76537
76538
76539
76540
76541
76542
    case TK_UPLUS: {
      rc = sqlite3ExprIsInteger(p->pLeft, pValue);
      break;
    }
    case TK_UMINUS: {
      int v;
      if( sqlite3ExprIsInteger(p->pLeft, &v) ){

        *pValue = -v;
        rc = 1;
      }
      break;
    }
    default: break;
  }







>







77244
77245
77246
77247
77248
77249
77250
77251
77252
77253
77254
77255
77256
77257
77258
    case TK_UPLUS: {
      rc = sqlite3ExprIsInteger(p->pLeft, pValue);
      break;
    }
    case TK_UMINUS: {
      int v;
      if( sqlite3ExprIsInteger(p->pLeft, &v) ){
        assert( v!=(-2147483647-1) );
        *pValue = -v;
        rc = 1;
      }
      break;
    }
    default: break;
  }
76942
76943
76944
76945
76946
76947
76948
76949
76950
76951
76952

76953
76954
76955
76956
76957
76958
76959
    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
  }
#endif

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;              /* Affinity of the LHS of the IN */
      KeyInfo keyInfo;            /* Keyinfo for the generated table */
      static u8 sortOrder = 0;    /* Fake aSortOrder for keyInfo */
      int addr;                   /* Address of OP_OpenEphemeral instruction */
      Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */


      if( rMayHaveNull ){
        sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
      }

      affinity = sqlite3ExprAffinity(pLeft);








<
<


>







77658
77659
77660
77661
77662
77663
77664


77665
77666
77667
77668
77669
77670
77671
77672
77673
77674
    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
  }
#endif

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;              /* Affinity of the LHS of the IN */


      int addr;                   /* Address of OP_OpenEphemeral instruction */
      Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
      KeyInfo *pKeyInfo = 0;      /* Key information */

      if( rMayHaveNull ){
        sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
      }

      affinity = sqlite3ExprAffinity(pLeft);

76969
76970
76971
76972
76973
76974
76975
76976
76977
76978
76979
76980
76981
76982
76983
76984
76985
76986
76987
76988
76989
76990
76991
76992
76993

76994

76995
76996
76997


76998
76999
77000
77001
77002
77003
77004
77005
77006
77007
77008
77009
77010
77011
77012
77013
77014
77015
77016
77017

77018
77019

77020
77021
77022
77023
77024
77025
77026
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
      if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
      memset(&keyInfo, 0, sizeof(keyInfo));
      keyInfo.nField = 1;
      keyInfo.aSortOrder = &sortOrder;

      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into the temporary
        ** table allocated and opened above.
        */
        SelectDest dest;
        ExprList *pEList;

        assert( !isRowid );
        sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
        dest.affSdst = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        pExpr->x.pSelect->iLimit = 0;

        if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){

          return 0;
        }
        pEList = pExpr->x.pSelect->pEList;


        if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){ 
          keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
              pEList->a[0].pExpr);
        }
      }else if( ALWAYS(pExpr->x.pList!=0) ){
        /* Case 2:     expr IN (exprlist)
        **
        ** For each expression, build an index key from the evaluation and
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        int i;
        ExprList *pList = pExpr->x.pList;
        struct ExprList_item *pItem;
        int r1, r2, r3;

        if( !affinity ){
          affinity = SQLITE_AFF_NONE;
        }

        keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
        keyInfo.aSortOrder = &sortOrder;


        /* Loop through each expression in <exprlist>. */
        r1 = sqlite3GetTempReg(pParse);
        r2 = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
        for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
          Expr *pE2 = pItem->pExpr;







<
|
<















>

>



>
>
|
|
|
<
















>
|
<
>







77684
77685
77686
77687
77688
77689
77690

77691

77692
77693
77694
77695
77696
77697
77698
77699
77700
77701
77702
77703
77704
77705
77706
77707
77708
77709
77710
77711
77712
77713
77714
77715
77716
77717

77718
77719
77720
77721
77722
77723
77724
77725
77726
77727
77728
77729
77730
77731
77732
77733
77734
77735

77736
77737
77738
77739
77740
77741
77742
77743
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
      if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);

      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1);


      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into the temporary
        ** table allocated and opened above.
        */
        SelectDest dest;
        ExprList *pEList;

        assert( !isRowid );
        sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
        dest.affSdst = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        pExpr->x.pSelect->iLimit = 0;
        testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
        if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
          sqlite3DbFree(pParse->db, pKeyInfo);
          return 0;
        }
        pEList = pExpr->x.pSelect->pEList;
        assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
        assert( pEList!=0 );
        assert( pEList->nExpr>0 );
        pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
                                                         pEList->a[0].pExpr);

      }else if( ALWAYS(pExpr->x.pList!=0) ){
        /* Case 2:     expr IN (exprlist)
        **
        ** For each expression, build an index key from the evaluation and
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        int i;
        ExprList *pList = pExpr->x.pList;
        struct ExprList_item *pItem;
        int r1, r2, r3;

        if( !affinity ){
          affinity = SQLITE_AFF_NONE;
        }
        if( pKeyInfo ){
          pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);

        }

        /* Loop through each expression in <exprlist>. */
        r1 = sqlite3GetTempReg(pParse);
        r2 = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
        for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
          Expr *pE2 = pItem->pExpr;
77051
77052
77053
77054
77055
77056
77057
77058
77059
77060
77061
77062
77063
77064
77065
77066
              sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
            }
          }
        }
        sqlite3ReleaseTempReg(pParse, r1);
        sqlite3ReleaseTempReg(pParse, r2);
      }
      if( !isRowid ){
        sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
      }
      break;
    }

    case TK_EXISTS:
    case TK_SELECT:
    default: {







|
|







77768
77769
77770
77771
77772
77773
77774
77775
77776
77777
77778
77779
77780
77781
77782
77783
              sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
            }
          }
        }
        sqlite3ReleaseTempReg(pParse, r1);
        sqlite3ReleaseTempReg(pParse, r2);
      }
      if( pKeyInfo ){
        sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO_HANDOFF);
      }
      break;
    }

    case TK_EXISTS:
    case TK_SELECT:
    default: {
77612
77613
77614
77615
77616
77617
77618
77619
77620
77621

77622

77623




77624
77625
77626
77627
77628
77629
77630
77631
77632
77633
77634
        sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
                              pCol->iSorterColumn, target);
        break;
      }
      /* Otherwise, fall thru into the TK_COLUMN case */
    }
    case TK_COLUMN: {
      if( pExpr->iTable<0 ){
        /* This only happens when coding check constraints */
        assert( pParse->ckBase>0 );

        inReg = pExpr->iColumn + pParse->ckBase;

      }else{




        inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
                                 pExpr->iColumn, pExpr->iTable, target,
                                 pExpr->op2);
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(pParse, pExpr, 0, target);
      break;
    }
#ifndef SQLITE_OMIT_FLOATING_POINT







|
|
|
>
|
>
|
>
>
>
>
|
|
|
<







78329
78330
78331
78332
78333
78334
78335
78336
78337
78338
78339
78340
78341
78342
78343
78344
78345
78346
78347
78348
78349

78350
78351
78352
78353
78354
78355
78356
        sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
                              pCol->iSorterColumn, target);
        break;
      }
      /* Otherwise, fall thru into the TK_COLUMN case */
    }
    case TK_COLUMN: {
      int iTab = pExpr->iTable;
      if( iTab<0 ){
        if( pParse->ckBase>0 ){
          /* Generating CHECK constraints or inserting into partial index */
          inReg = pExpr->iColumn + pParse->ckBase;
          break;
        }else{
          /* Deleting from a partial index */
          iTab = pParse->iPartIdxTab;
        }
      }
      inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
                               pExpr->iColumn, iTab, target,
                               pExpr->op2);

      break;
    }
    case TK_INTEGER: {
      codeInteger(pParse, pExpr, 0, target);
      break;
    }
#ifndef SQLITE_OMIT_FLOATING_POINT
78748
78749
78750
78751
78752
78753
78754

78755
78756
78757
78758
78759
78760
78761
  compLeft.op = TK_GE;
  compLeft.pLeft = &exprX;
  compLeft.pRight = pExpr->x.pList->a[0].pExpr;
  compRight.op = TK_LE;
  compRight.pLeft = &exprX;
  compRight.pRight = pExpr->x.pList->a[1].pExpr;
  exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, &regFree1);

  exprX.op = TK_REGISTER;
  if( jumpIfTrue ){
    sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
  }else{
    sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull);
  }
  sqlite3ReleaseTempReg(pParse, regFree1);







>







79470
79471
79472
79473
79474
79475
79476
79477
79478
79479
79480
79481
79482
79483
79484
  compLeft.op = TK_GE;
  compLeft.pLeft = &exprX;
  compLeft.pRight = pExpr->x.pList->a[0].pExpr;
  compRight.op = TK_LE;
  compRight.pLeft = &exprX;
  compRight.pRight = pExpr->x.pList->a[1].pExpr;
  exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, &regFree1);
  exprX.op2 = exprX.op;
  exprX.op = TK_REGISTER;
  if( jumpIfTrue ){
    sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
  }else{
    sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull);
  }
  sqlite3ReleaseTempReg(pParse, regFree1);
79043
79044
79045
79046
79047
79048
79049






79050
79051
79052
79053
79054
79055
79056
79057
79058
79059
79060
79061
79062
79063
79064
79065
79066
79067
79068
79069
79070
79071
79072
79073
79074
79075
79076
79077
79078
79079
79080
79081

79082


79083
79084
79085
79086
79087
79088
79089
79090
79091
79092
79093
79094
79095
79096
79097
79098
79099



79100
79101
79102
79103
79104
79105
79106
79107
79108
79109
79110
79111
79112
79113
79114
79115
79116
79117







































79118
79119
79120
79121
79122
79123
79124

/*
** Do a deep comparison of two expression trees.  Return 0 if the two
** expressions are completely identical.  Return 1 if they differ only
** by a COLLATE operator at the top level.  Return 2 if there are differences
** other than the top-level COLLATE operator.
**






** Sometimes this routine will return 2 even if the two expressions
** really are equivalent.  If we cannot prove that the expressions are
** identical, we return 2 just to be safe.  So if this routine
** returns 2, then you do not really know for certain if the two
** expressions are the same.  But if you get a 0 or 1 return, then you
** can be sure the expressions are the same.  In the places where
** this routine is used, it does not hurt to get an extra 2 - that
** just might result in some slightly slower code.  But returning
** an incorrect 0 or 1 could lead to a malfunction.
*/
SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
  if( pA==0||pB==0 ){
    return pB==pA ? 0 : 2;
  }
  assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
  assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
  if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
    return 2;
  }
  if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
  if( pA->op!=pB->op ){
    if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
      return 1;
    }
    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
      return 1;
    }
    return 2;
  }
  if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
  if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
  if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;

  if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;


  if( ExprHasProperty(pA, EP_IntValue) ){
    if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
      return 2;
    }
  }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
    if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
    if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
      return pA->op==TK_COLLATE ? 1 : 2;
    }
  }
  return 0;
}

/*
** Compare two ExprList objects.  Return 0 if they are identical and 
** non-zero if they differ in any way.
**



** This routine might return non-zero for equivalent ExprLists.  The
** only consequence will be disabled optimizations.  But this routine
** must never return 0 if the two ExprList objects are different, or
** a malfunction will result.
**
** Two NULL pointers are considered to be the same.  But a NULL pointer
** always differs from a non-NULL pointer.
*/
SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
  int i;
  if( pA==0 && pB==0 ) return 0;
  if( pA==0 || pB==0 ) return 1;
  if( pA->nExpr!=pB->nExpr ) return 1;
  for(i=0; i<pA->nExpr; i++){
    Expr *pExprA = pA->a[i].pExpr;
    Expr *pExprB = pB->a[i].pExpr;
    if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
    if( sqlite3ExprCompare(pExprA, pExprB) ) return 1;







































  }
  return 0;
}

/*
** An instance of the following structure is used by the tree walker
** to count references to table columns in the arguments of an 







>
>
>
>
>
>










|









|
|


|




|
|
|
>
|
>
>

















>
>
>








|








|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







79766
79767
79768
79769
79770
79771
79772
79773
79774
79775
79776
79777
79778
79779
79780
79781
79782
79783
79784
79785
79786
79787
79788
79789
79790
79791
79792
79793
79794
79795
79796
79797
79798
79799
79800
79801
79802
79803
79804
79805
79806
79807
79808
79809
79810
79811
79812
79813
79814
79815
79816
79817
79818
79819
79820
79821
79822
79823
79824
79825
79826
79827
79828
79829
79830
79831
79832
79833
79834
79835
79836
79837
79838
79839
79840
79841
79842
79843
79844
79845
79846
79847
79848
79849
79850
79851
79852
79853
79854
79855
79856
79857
79858
79859
79860
79861
79862
79863
79864
79865
79866
79867
79868
79869
79870
79871
79872
79873
79874
79875
79876
79877
79878
79879
79880
79881
79882
79883
79884
79885
79886
79887
79888
79889
79890
79891
79892
79893
79894
79895
79896
79897
79898

/*
** Do a deep comparison of two expression trees.  Return 0 if the two
** expressions are completely identical.  Return 1 if they differ only
** by a COLLATE operator at the top level.  Return 2 if there are differences
** other than the top-level COLLATE operator.
**
** If any subelement of pB has Expr.iTable==(-1) then it is allowed
** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
**
** The pA side might be using TK_REGISTER.  If that is the case and pB is
** not using TK_REGISTER but is otherwise equivalent, then still return 0.
**
** Sometimes this routine will return 2 even if the two expressions
** really are equivalent.  If we cannot prove that the expressions are
** identical, we return 2 just to be safe.  So if this routine
** returns 2, then you do not really know for certain if the two
** expressions are the same.  But if you get a 0 or 1 return, then you
** can be sure the expressions are the same.  In the places where
** this routine is used, it does not hurt to get an extra 2 - that
** just might result in some slightly slower code.  But returning
** an incorrect 0 or 1 could lead to a malfunction.
*/
SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
  if( pA==0||pB==0 ){
    return pB==pA ? 0 : 2;
  }
  assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
  assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
  if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
    return 2;
  }
  if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
  if( pA->op!=pB->op && (pA->op!=TK_REGISTER || pA->op2!=pB->op) ){
    if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
      return 1;
    }
    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){
      return 1;
    }
    return 2;
  }
  if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
  if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
  if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
  if( pA->iColumn!=pB->iColumn ) return 2;
  if( pA->iTable!=pB->iTable 
   && pA->op!=TK_REGISTER
   && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
  if( ExprHasProperty(pA, EP_IntValue) ){
    if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
      return 2;
    }
  }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
    if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
    if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
      return pA->op==TK_COLLATE ? 1 : 2;
    }
  }
  return 0;
}

/*
** Compare two ExprList objects.  Return 0 if they are identical and 
** non-zero if they differ in any way.
**
** If any subelement of pB has Expr.iTable==(-1) then it is allowed
** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
**
** This routine might return non-zero for equivalent ExprLists.  The
** only consequence will be disabled optimizations.  But this routine
** must never return 0 if the two ExprList objects are different, or
** a malfunction will result.
**
** Two NULL pointers are considered to be the same.  But a NULL pointer
** always differs from a non-NULL pointer.
*/
SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
  int i;
  if( pA==0 && pB==0 ) return 0;
  if( pA==0 || pB==0 ) return 1;
  if( pA->nExpr!=pB->nExpr ) return 1;
  for(i=0; i<pA->nExpr; i++){
    Expr *pExprA = pA->a[i].pExpr;
    Expr *pExprB = pB->a[i].pExpr;
    if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
    if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1;
  }
  return 0;
}

/*
** Return true if we can prove the pE2 will always be true if pE1 is
** true.  Return false if we cannot complete the proof or if pE2 might
** be false.  Examples:
**
**     pE1: x==5       pE2: x==5             Result: true
**     pE1: x>0        pE2: x==5             Result: false
**     pE1: x=21       pE2: x=21 OR y=43     Result: true
**     pE1: x!=123     pE2: x IS NOT NULL    Result: true
**     pE1: x!=?1      pE2: x IS NOT NULL    Result: true
**     pE1: x IS NULL  pE2: x IS NOT NULL    Result: false
**     pE1: x IS ?2    pE2: x IS NOT NULL    Reuslt: false
**
** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
** Expr.iTable<0 then assume a table number given by iTab.
**
** When in doubt, return false.  Returning true might give a performance
** improvement.  Returning false might cause a performance reduction, but
** it will always give the correct answer and is hence always safe.
*/
SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
  if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){
    return 1;
  }
  if( pE2->op==TK_OR
   && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
             || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
  ){
    return 1;
  }
  if( pE2->op==TK_NOTNULL
   && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
   && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
  ){
    return 1;
  }
  return 0;
}

/*
** An instance of the following structure is used by the tree walker
** to count references to table columns in the arguments of an 
79295
79296
79297
79298
79299
79300
79301
79302
79303
79304
79305
79306
79307
79308
79309
       && pWalker->walkerDepth==pExpr->op2
      ){
        /* Check to see if pExpr is a duplicate of another aggregate 
        ** function that is already in the pAggInfo structure
        */
        struct AggInfo_func *pItem = pAggInfo->aFunc;
        for(i=0; i<pAggInfo->nFunc; i++, pItem++){
          if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){
            break;
          }
        }
        if( i>=pAggInfo->nFunc ){
          /* pExpr is original.  Make a new entry in pAggInfo->aFunc[]
          */
          u8 enc = ENC(pParse->db);







|







80069
80070
80071
80072
80073
80074
80075
80076
80077
80078
80079
80080
80081
80082
80083
       && pWalker->walkerDepth==pExpr->op2
      ){
        /* Check to see if pExpr is a duplicate of another aggregate 
        ** function that is already in the pAggInfo structure
        */
        struct AggInfo_func *pItem = pAggInfo->aFunc;
        for(i=0; i<pAggInfo->nFunc; i++, pItem++){
          if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){
            break;
          }
        }
        if( i>=pAggInfo->nFunc ){
          /* pExpr is original.  Make a new entry in pAggInfo->aFunc[]
          */
          u8 enc = ENC(pParse->db);
80130
80131
80132
80133
80134
80135
80136
80137
80138
80139
80140
80141
80142
80143
80144
    return;
  }

  /* Ensure the default expression is something that sqlite3ValueFromExpr()
  ** can handle (i.e. not CURRENT_TIME etc.)
  */
  if( pDflt ){
    sqlite3_value *pVal;
    if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
      db->mallocFailed = 1;
      return;
    }
    if( !pVal ){
      sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
      return;







|







80904
80905
80906
80907
80908
80909
80910
80911
80912
80913
80914
80915
80916
80917
80918
    return;
  }

  /* Ensure the default expression is something that sqlite3ValueFromExpr()
  ** can handle (i.e. not CURRENT_TIME etc.)
  */
  if( pDflt ){
    sqlite3_value *pVal = 0;
    if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
      db->mallocFailed = 1;
      return;
    }
    if( !pVal ){
      sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
      return;
80271
80272
80273
80274
80275
80276
80277
80278
80279
80280
80281
80282
80283
80284
80285
80286
80287
80288
80289
80290
80291
80292
80293
80294
80295
80296
80297
80298

80299
80300
80301
80302
80303
80304
80305
80306
80307







80308
80309
80310
80311
80312
80313
80314
80315

80316
80317
80318
80319
80320
80321
80322
  return;
}
#endif  /* SQLITE_ALTER_TABLE */

/************** End of alter.c ***********************************************/
/************** Begin file analyze.c *****************************************/
/*
** 2005 July 8
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** The ANALYZE command gather statistics about the content of tables
** and indices.  These statistics are made available to the query planner
** to help it make better decisions about how to perform queries.
**
** The following system tables are or have been supported:
**
**    CREATE TABLE sqlite_stat1(tbl, idx, stat);
**    CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample);
**    CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample);

**
** Additional tables might be added in future releases of SQLite.
** The sqlite_stat2 table is not created or used unless the SQLite version
** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
** with SQLITE_ENABLE_STAT2.  The sqlite_stat2 table is deprecated.
** The sqlite_stat2 table is superseded by sqlite_stat3, which is only
** created and used by SQLite versions 3.7.9 and later and with
** SQLITE_ENABLE_STAT3 defined.  The fucntionality of sqlite_stat3
** is a superset of sqlite_stat2.  







**
** Format of sqlite_stat1:
**
** There is normally one row per index, with the index identified by the
** name in the idx column.  The tbl column is the name of the table to
** which the index belongs.  In each such row, the stat column will be
** a string consisting of a list of integers.  The first integer in this
** list is the number of rows in the index and in the table.  The second

** integer is the average number of rows in the index that have the same
** value in the first column of the index.  The third integer is the average
** number of rows in the index that have the same value for the first two
** columns.  The N-th integer (for N>1) is the average number of rows in 
** the index which have the same value for the first N-1 columns.  For
** a K-column index, there will be K+1 integers in the stat column.  If
** the index is unique, then the last integer will be 1.







|




















>







|
|
>
>
>
>
>
>
>







|
>







81045
81046
81047
81048
81049
81050
81051
81052
81053
81054
81055
81056
81057
81058
81059
81060
81061
81062
81063
81064
81065
81066
81067
81068
81069
81070
81071
81072
81073
81074
81075
81076
81077
81078
81079
81080
81081
81082
81083
81084
81085
81086
81087
81088
81089
81090
81091
81092
81093
81094
81095
81096
81097
81098
81099
81100
81101
81102
81103
81104
81105
  return;
}
#endif  /* SQLITE_ALTER_TABLE */

/************** End of alter.c ***********************************************/
/************** Begin file analyze.c *****************************************/
/*
** 2005-07-08
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** The ANALYZE command gather statistics about the content of tables
** and indices.  These statistics are made available to the query planner
** to help it make better decisions about how to perform queries.
**
** The following system tables are or have been supported:
**
**    CREATE TABLE sqlite_stat1(tbl, idx, stat);
**    CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample);
**    CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample);
**    CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample);
**
** Additional tables might be added in future releases of SQLite.
** The sqlite_stat2 table is not created or used unless the SQLite version
** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
** with SQLITE_ENABLE_STAT2.  The sqlite_stat2 table is deprecated.
** The sqlite_stat2 table is superseded by sqlite_stat3, which is only
** created and used by SQLite versions 3.7.9 and later and with
** SQLITE_ENABLE_STAT3 defined.  The functionality of sqlite_stat3
** is a superset of sqlite_stat2.  The sqlite_stat4 is an enhanced
** version of sqlite_stat3 and is only available when compiled with
** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later.  It is
** not possible to enable both STAT3 and STAT4 at the same time.  If they
** are both enabled, then STAT4 takes precedence.
**
** For most applications, sqlite_stat1 provides all the statisics required
** for the query planner to make good choices.
**
** Format of sqlite_stat1:
**
** There is normally one row per index, with the index identified by the
** name in the idx column.  The tbl column is the name of the table to
** which the index belongs.  In each such row, the stat column will be
** a string consisting of a list of integers.  The first integer in this
** list is the number of rows in the index.  (This is the same as the
** number of rows in the table, except for partial indices.)  The second
** integer is the average number of rows in the index that have the same
** value in the first column of the index.  The third integer is the average
** number of rows in the index that have the same value for the first two
** columns.  The N-th integer (for N>1) is the average number of rows in 
** the index which have the same value for the first N-1 columns.  For
** a K-column index, there will be K+1 integers in the stat column.  If
** the index is unique, then the last integer will be 1.
80355
80356
80357
80358
80359
80360
80361
80362
80363

80364
80365






80366
80367
80368
80369

80370

80371
80372







80373
80374
80375
80376
80377
80378
80379
80380
80381
80382
80383
80384
80385
80386
80387
80388
80389
80390










80391
80392
80393














80394
80395
80396
80397
80398

80399
80400
80401
80402
80403
80404
80405
80406
80407
80408
80409
80410
80411
80412
80413
80414
80415
80416
80417
80418
80419
80420
80421



80422
80423




80424
80425
80426
80427
80428
80429
80430
80431
80432
80433



80434
80435
80436
80437
80438
80439
80440
80441
80442
80443
80444
80445

80446
80447
80448
80449
80450
80451
80452
80453
80454

80455
80456
80457
80458
80459

80460
80461
80462
80463

80464
80465
80466
80467
80468
80469
80470
80471
80472

80473
80474
80475
80476
80477
80478
80479
80480
80481
80482
80483
80484
80485
80486
80487
80488
80489
80490
80491
80492

80493











80494
80495
80496
80497
80498
80499
80500
80501
80502
80503
80504
80505
80506
80507
80508
80509
80510
80511
80512
80513
80514

80515
80516
80517
80518

80519
80520
80521
80522
80523
80524
80525

80526


80527
80528
80529

80530
80531


80532

80533








80534
80535
80536
80537
80538
80539
80540










80541
80542

80543



















80544
80545
80546
80547
80548
80549
80550
80551
80552
80553
80554
80555
80556
80557
80558
80559























80560






80561
80562
80563
80564
80565
80566
80567

80568
80569

80570
80571
80572
80573
80574
80575
80576
80577
80578
80579
80580
80581




80582
80583
80584
80585
80586
80587
80588




80589



80590

80591






80592






80593
80594

80595




80596













80597
80598








80599

80600
80601



80602
80603
80604


80605
80606
80607

80608
80609

80610
80611
80612

80613
80614
80615
80616
80617
80618
80619
80620
80621
80622

80623
80624




80625
80626
80627
80628
80629
80630
80631
80632
80633
80634
80635

80636
80637
80638

80639
80640






80641

80642









80643








80644




80645






80646









80647


















80648



80649
80650

80651






80652





























































80653
80654
80655
80656
80657

80658



80659
80660
80661
80662
80663
80664
80665
80666
80667
80668



80669

































80670




80671








80672











80673
80674
80675

80676

80677




80678



80679
80680
80681
80682
80683
80684
80685
80686
80687
80688
80689
80690
80691
80692
80693

80694











80695
80696
80697



























80698
80699
80700
80701
80702
80703
80704
80705
80706
80707
80708

80709
80710
80711
80712

80713
80714
80715
80716
80717
80718

80719
80720
80721
80722
80723
80724
80725
80726
80727
80728
80729
80730
80731
80732
80733
80734
80735
80736
80737
80738
80739
80740
80741


80742

80743
80744
80745
80746
80747
80748
80749
** The format for sqlite_stat2 is recorded here for legacy reference.  This
** version of SQLite does not support sqlite_stat2.  It neither reads nor
** writes the sqlite_stat2 table.  This version of SQLite only supports
** sqlite_stat3.
**
** Format for sqlite_stat3:
**
** The sqlite_stat3 is an enhancement to sqlite_stat2.  A new name is
** used to avoid compatibility problems.  

**
** The format of the sqlite_stat3 table is similar to the format of






** the sqlite_stat2 table.  There are multiple entries for each index.
** The idx column names the index and the tbl column is the table of the
** index.  If the idx and tbl columns are the same, then the sample is
** of the INTEGER PRIMARY KEY.  The sample column is a value taken from

** the left-most column of the index.  The nEq column is the approximate

** number of entires in the index whose left-most column exactly matches
** the sample.  nLt is the approximate number of entires whose left-most







** column is less than the sample.  The nDLt column is the approximate
** number of distinct left-most entries in the index that are less than
** the sample.
**
** Future versions of SQLite might change to store a string containing
** multiple integers values in the nDLt column of sqlite_stat3.  The first
** integer will be the number of prior index entires that are distinct in
** the left-most column.  The second integer will be the number of prior index
** entries that are distinct in the first two columns.  The third integer
** will be the number of prior index entries that are distinct in the first
** three columns.  And so forth.  With that extension, the nDLt field is
** similar in function to the sqlite_stat1.stat field.
**
** There can be an arbitrary number of sqlite_stat3 entries per index.
** The ANALYZE command will typically generate sqlite_stat3 tables
** that contain between 10 and 40 samples which are distributed across
** the key space, though not uniformly, and which include samples with
** largest possible nEq values.










*/
#ifndef SQLITE_OMIT_ANALYZE















/*
** This routine generates code that opens the sqlite_stat1 table for
** writing with cursor iStatCur. If the library was built with the
** SQLITE_ENABLE_STAT3 macro defined, then the sqlite_stat3 table is
** opened for writing using cursor (iStatCur+1)

**
** If the sqlite_stat1 tables does not previously exist, it is created.
** Similarly, if the sqlite_stat3 table does not exist and the library
** is compiled with SQLITE_ENABLE_STAT3 defined, it is created. 
**
** Argument zWhere may be a pointer to a buffer containing a table name,
** or it may be a NULL pointer. If it is not NULL, then all entries in
** the sqlite_stat1 and (if applicable) sqlite_stat3 tables associated
** with the named table are deleted. If zWhere==0, then code is generated
** to delete all stat table entries.
*/
static void openStatTable(
  Parse *pParse,          /* Parsing context */
  int iDb,                /* The database we are looking in */
  int iStatCur,           /* Open the sqlite_stat1 table on this cursor */
  const char *zWhere,     /* Delete entries for this table or index */
  const char *zWhereType  /* Either "tbl" or "idx" */
){
  static const struct {
    const char *zName;
    const char *zCols;
  } aTable[] = {
    { "sqlite_stat1", "tbl,idx,stat" },



#ifdef SQLITE_ENABLE_STAT3
    { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },




#endif
  };

  int aRoot[] = {0, 0};
  u8 aCreateTbl[] = {0, 0};

  int i;
  sqlite3 *db = pParse->db;
  Db *pDb;
  Vdbe *v = sqlite3GetVdbe(pParse);



  if( v==0 ) return;
  assert( sqlite3BtreeHoldsAllMutexes(db) );
  assert( sqlite3VdbeDb(v)==db );
  pDb = &db->aDb[iDb];

  /* Create new statistic tables if they do not exist, or clear them
  ** if they do already exist.
  */
  for(i=0; i<ArraySize(aTable); i++){
    const char *zTab = aTable[i].zName;
    Table *pStat;
    if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){

      /* The sqlite_stat[12] table does not exist. Create it. Note that a 
      ** side-effect of the CREATE TABLE statement is to leave the rootpage 
      ** of the new table in register pParse->regRoot. This is important 
      ** because the OpenWrite opcode below will be needing it. */
      sqlite3NestedParse(pParse,
          "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
      );
      aRoot[i] = pParse->regRoot;
      aCreateTbl[i] = OPFLAG_P2ISREG;

    }else{
      /* The table already exists. If zWhere is not NULL, delete all entries 
      ** associated with the table zWhere. If zWhere is NULL, delete the
      ** entire contents of the table. */
      aRoot[i] = pStat->tnum;

      sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
      if( zWhere ){
        sqlite3NestedParse(pParse,
           "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere

        );
      }else{
        /* The sqlite_stat[12] table already exists.  Delete all rows. */
        sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
      }
    }
  }

  /* Open the sqlite_stat[13] tables for writing. */

  for(i=0; i<ArraySize(aTable); i++){
    sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
    sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
    sqlite3VdbeChangeP5(v, aCreateTbl[i]);
  }
}

/*
** Recommended number of samples for sqlite_stat3
*/
#ifndef SQLITE_STAT3_SAMPLES
# define SQLITE_STAT3_SAMPLES 24
#endif

/*
** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() -
** share an instance of the following structure to hold their state
** information.
*/
typedef struct Stat3Accum Stat3Accum;

struct Stat3Accum {











  tRowcnt nRow;             /* Number of rows in the entire table */
  tRowcnt nPSample;         /* How often to do a periodic sample */
  int iMin;                 /* Index of entry with minimum nEq and hash */
  int mxSample;             /* Maximum number of samples to accumulate */
  int nSample;              /* Current number of samples */
  u32 iPrn;                 /* Pseudo-random number used for sampling */
  struct Stat3Sample {
    i64 iRowid;                /* Rowid in main table of the key */
    tRowcnt nEq;               /* sqlite_stat3.nEq */
    tRowcnt nLt;               /* sqlite_stat3.nLt */
    tRowcnt nDLt;              /* sqlite_stat3.nDLt */
    u8 isPSample;              /* True if a periodic sample */
    u32 iHash;                 /* Tiebreaker hash */
  } *a;                     /* An array of samples */
};

#ifdef SQLITE_ENABLE_STAT3
/*
** Implementation of the stat3_init(C,S) SQL function.  The two parameters
** are the number of rows in the table or index (C) and the number of samples
** to accumulate (S).

**
** This routine allocates the Stat3Accum object.
**
** The return value is the Stat3Accum object (P).

*/
static void stat3Init(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Stat3Accum *p;

  tRowcnt nRow;


  int mxSample;
  int n;


  UNUSED_PARAMETER(argc);
  nRow = (tRowcnt)sqlite3_value_int64(argv[0]);


  mxSample = sqlite3_value_int(argv[1]);

  n = sizeof(*p) + sizeof(p->a[0])*mxSample;








  p = sqlite3MallocZero( n );
  if( p==0 ){
    sqlite3_result_error_nomem(context);
    return;
  }
  p->a = (struct Stat3Sample*)&p[1];
  p->nRow = nRow;










  p->mxSample = mxSample;
  p->nPSample = p->nRow/(mxSample/3+1) + 1;

  sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);



















  sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
}
static const FuncDef stat3InitFuncdef = {
  2,                /* nArg */
  SQLITE_UTF8,      /* iPrefEnc */
  0,                /* flags */
  0,                /* pUserData */
  0,                /* pNext */
  stat3Init,        /* xFunc */
  0,                /* xStep */
  0,                /* xFinalize */
  "stat3_init",     /* zName */
  0,                /* pHash */
  0                 /* pDestructor */
};































/*
** Implementation of the stat3_push(nEq,nLt,nDLt,rowid,P) SQL function.  The
** arguments describe a single key instance.  This routine makes the 
** decision about whether or not to retain this key for the sqlite_stat3
** table.
**
** The return value is NULL.

*/
static void stat3Push(

  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[4]);
  tRowcnt nEq = sqlite3_value_int64(argv[0]);
  tRowcnt nLt = sqlite3_value_int64(argv[1]);
  tRowcnt nDLt = sqlite3_value_int64(argv[2]);
  i64 rowid = sqlite3_value_int64(argv[3]);
  u8 isPSample = 0;
  u8 doInsert = 0;
  int iMin = p->iMin;




  struct Stat3Sample *pSample;
  int i;
  u32 h;

  UNUSED_PARAMETER(context);
  UNUSED_PARAMETER(argc);
  if( nEq==0 ) return;




  h = p->iPrn = p->iPrn*1103515245 + 12345;



  if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){

    doInsert = isPSample = 1;






  }else if( p->nSample<p->mxSample ){






    doInsert = 1;
  }else{

    if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){




      doInsert = 1;













    }
  }








  if( !doInsert ) return;

  if( p->nSample==p->mxSample ){
    assert( p->nSample - iMin - 1 >= 0 );



    memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1));
    pSample = &p->a[p->nSample-1];
  }else{


    pSample = &p->a[p->nSample++];
  }
  pSample->iRowid = rowid;

  pSample->nEq = nEq;
  pSample->nLt = nLt;

  pSample->nDLt = nDLt;
  pSample->iHash = h;
  pSample->isPSample = isPSample;


  /* Find the new minimum */
  if( p->nSample==p->mxSample ){
    pSample = p->a;
    i = 0;
    while( pSample->isPSample ){
      i++;
      pSample++;
      assert( i<p->nSample );
    }

    nEq = pSample->nEq;
    h = pSample->iHash;




    iMin = i;
    for(i++, pSample++; i<p->nSample; i++, pSample++){
      if( pSample->isPSample ) continue;
      if( pSample->nEq<nEq
       || (pSample->nEq==nEq && pSample->iHash<h)
      ){
        iMin = i;
        nEq = pSample->nEq;
        h = pSample->iHash;
      }
    }

    p->iMin = iMin;
  }
}

static const FuncDef stat3PushFuncdef = {
  5,                /* nArg */






  SQLITE_UTF8,      /* iPrefEnc */

  0,                /* flags */









  0,                /* pUserData */








  0,                /* pNext */




  stat3Push,        /* xFunc */






  0,                /* xStep */









  0,                /* xFinalize */


















  "stat3_push",     /* zName */



  0,                /* pHash */
  0                 /* pDestructor */

};




































































/*
** Implementation of the stat3_get(P,N,...) SQL function.  This routine is
** used to query the results.  Content is returned for the Nth sqlite_stat3
** row where N is between 0 and S-1 and S is the number of samples.  The
** value returned depends on the number of arguments.

**



**   argc==2    result:  rowid
**   argc==3    result:  nEq
**   argc==4    result:  nLt
**   argc==5    result:  nDLt
*/
static void stat3Get(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){



  int n = sqlite3_value_int(argv[1]);

































  Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]);













  assert( p!=0 );











  if( p->nSample<=n ) return;
  switch( argc ){
    case 2:  sqlite3_result_int64(context, p->a[n].iRowid); break;

    case 3:  sqlite3_result_int64(context, p->a[n].nEq);    break;

    case 4:  sqlite3_result_int64(context, p->a[n].nLt);    break;




    default: sqlite3_result_int64(context, p->a[n].nDLt);   break;



  }
}
static const FuncDef stat3GetFuncdef = {
  -1,               /* nArg */
  SQLITE_UTF8,      /* iPrefEnc */
  0,                /* flags */
  0,                /* pUserData */
  0,                /* pNext */
  stat3Get,         /* xFunc */
  0,                /* xStep */
  0,                /* xFinalize */
  "stat3_get",     /* zName */
  0,                /* pHash */
  0                 /* pDestructor */
};

#endif /* SQLITE_ENABLE_STAT3 */










































/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
static void analyzeOneTable(
  Parse *pParse,   /* Parser context */
  Table *pTab,     /* Table whose indices are to be analyzed */
  Index *pOnlyIdx, /* If not NULL, only analyze this one index */
  int iStatCur,    /* Index of VdbeCursor that writes the sqlite_stat1 table */
  int iMem         /* Available memory locations begin here */

){
  sqlite3 *db = pParse->db;    /* Database handle */
  Index *pIdx;                 /* An index to being analyzed */
  int iIdxCur;                 /* Cursor open on index being analyzed */

  Vdbe *v;                     /* The virtual machine being built up */
  int i;                       /* Loop counter */
  int topOfLoop;               /* The top of the loop */
  int endOfLoop;               /* The end of the loop */
  int jZeroRows = -1;          /* Jump from here if number of rows is zero */
  int iDb;                     /* Index of database containing pTab */

  int regTabname = iMem++;     /* Register containing table name */
  int regIdxname = iMem++;     /* Register containing index name */
  int regStat1 = iMem++;       /* The stat column of sqlite_stat1 */
#ifdef SQLITE_ENABLE_STAT3
  int regNumEq = regStat1;     /* Number of instances.  Same as regStat1 */
  int regNumLt = iMem++;       /* Number of keys less than regSample */
  int regNumDLt = iMem++;      /* Number of distinct keys less than regSample */
  int regSample = iMem++;      /* The next sample value */
  int regRowid = regSample;    /* Rowid of a sample */
  int regAccum = iMem++;       /* Register to hold Stat3Accum object */
  int regLoop = iMem++;        /* Loop counter */
  int regCount = iMem++;       /* Number of rows in the table or index */
  int regTemp1 = iMem++;       /* Intermediate register */
  int regTemp2 = iMem++;       /* Intermediate register */
  int once = 1;                /* One-time initialization */
  int shortJump = 0;           /* Instruction address */
  int iTabCur = pParse->nTab++; /* Table cursor */
#endif
  int regCol = iMem++;         /* Content of a column in analyzed table */
  int regRec = iMem++;         /* Register holding completed record */
  int regTemp = iMem++;        /* Temporary use register */
  int regNewRowid = iMem++;    /* Rowid for the inserted record */





  v = sqlite3GetVdbe(pParse);
  if( v==0 || NEVER(pTab==0) ){
    return;
  }
  if( pTab->tnum==0 ){
    /* Do not gather statistics on views or virtual tables */
    return;







|
|
>

|
>
>
>
>
>
>
|


|
>
|
>
|
|
>
>
>
>
>
>
>
|
|
|

<
<
<
<
<
<
<
<
<
|
|


|
>
>
>
>
>
>
>
>
>
>



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

|
<
|
|
>

|
<
<



<
|
|













>
>
>
|

>
>
>
>


<
<
<
<




>
>
>












>
|
|
|
|
|
|
|
|
|
>





>



|
>


|





|
>
|







|

|
|



|



|
>
|
>
>
>
>
>
>
>
>
>
>
>


|

|

<
<
|
|
<
|
|
|


<

|
|
<
>

|
<
|
>

|




|
>
|
>
>
|
|

>

|
>
>
|
>
|
>
>
>
>
>
>
>
>
|




|
|
>
>
>
>
>
>
>
>
>
>
|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|
|
|
|
|
|
|
|
|
|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>

<
<
<
|

|
>

|
>
|
<
|

<
|
|
|
<
|
|
|
>
>
>
>
|
<
<
|
<
<
|
>
>
>
>
|
>
>
>
|
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
|
|
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
|
>
|
|
>
>
>
|

|
>
>
|

|
>
|
|
>
|
|
<
>

|
<
|
<
|
<
|
<
|
>
|
|
>
>
>
>
|
|
|
|
<
<

<
<


>



>
|
|
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
|
>
|
>
>
>
>
>
>

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

|
|
<
<
>

>
>
>
|
<
<
<

|




>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
<
|
>
|
>
|
>
>
>
>
|
>
>
>
|
|
|
<
<
<
<
<
|
<
<
<
|
<
|
>
|
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










|
>




>


<
<


>
|
|
|
|
<
<
<
<
<
<
<
<
|
<
<
<
<

<
<

|
|
>
>

>







81138
81139
81140
81141
81142
81143
81144
81145
81146
81147
81148
81149
81150
81151
81152
81153
81154
81155
81156
81157
81158
81159
81160
81161
81162
81163
81164
81165
81166
81167
81168
81169
81170
81171
81172
81173
81174
81175









81176
81177
81178
81179
81180
81181
81182
81183
81184
81185
81186
81187
81188
81189
81190
81191
81192
81193
81194
81195
81196
81197
81198
81199
81200
81201
81202
81203
81204
81205
81206
81207
81208
81209

81210
81211
81212
81213
81214


81215
81216
81217

81218
81219
81220
81221
81222
81223
81224
81225
81226
81227
81228
81229
81230
81231
81232
81233
81234
81235
81236
81237
81238
81239
81240
81241
81242
81243




81244
81245
81246
81247
81248
81249
81250
81251
81252
81253
81254
81255
81256
81257
81258
81259
81260
81261
81262
81263
81264
81265
81266
81267
81268
81269
81270
81271
81272
81273
81274
81275
81276
81277
81278
81279
81280
81281
81282
81283
81284
81285
81286
81287
81288
81289
81290
81291
81292
81293
81294
81295
81296
81297
81298
81299
81300
81301
81302
81303
81304
81305
81306
81307
81308
81309
81310
81311
81312
81313
81314
81315
81316
81317
81318
81319
81320
81321
81322
81323
81324
81325
81326
81327
81328
81329
81330
81331
81332
81333


81334
81335

81336
81337
81338
81339
81340

81341
81342
81343

81344
81345
81346

81347
81348
81349
81350
81351
81352
81353
81354
81355
81356
81357
81358
81359
81360
81361
81362
81363
81364
81365
81366
81367
81368
81369
81370
81371
81372
81373
81374
81375
81376
81377
81378
81379
81380
81381
81382
81383
81384
81385
81386
81387
81388
81389
81390
81391
81392
81393
81394
81395
81396
81397
81398
81399
81400
81401
81402
81403
81404
81405
81406
81407
81408
81409
81410
81411
81412
81413
81414
81415
81416
81417
81418
81419
81420
81421
81422
81423
81424
81425
81426
81427
81428
81429
81430
81431
81432
81433
81434
81435
81436
81437
81438
81439
81440
81441
81442
81443
81444
81445
81446
81447
81448
81449
81450
81451
81452
81453
81454
81455
81456
81457
81458
81459
81460
81461
81462
81463
81464
81465



81466
81467
81468
81469
81470
81471
81472
81473

81474
81475

81476
81477
81478

81479
81480
81481
81482
81483
81484
81485
81486


81487


81488
81489
81490
81491
81492
81493
81494
81495
81496
81497
81498
81499
81500
81501
81502
81503
81504
81505
81506
81507
81508
81509
81510
81511
81512
81513
81514
81515
81516
81517
81518
81519
81520
81521
81522
81523
81524
81525
81526
81527
81528
81529
81530
81531
81532
81533
81534
81535
81536
81537
81538
81539
81540
81541
81542
81543
81544
81545
81546
81547
81548
81549
81550
81551
81552
81553
81554
81555
81556
81557
81558
81559
81560
81561
81562
81563
81564
81565

81566
81567
81568

81569

81570

81571

81572
81573
81574
81575
81576
81577
81578
81579
81580
81581
81582
81583


81584


81585
81586
81587
81588
81589
81590
81591
81592
81593
81594
81595
81596
81597
81598
81599
81600
81601
81602
81603
81604
81605
81606
81607
81608
81609
81610
81611
81612
81613
81614
81615
81616
81617
81618
81619
81620
81621
81622
81623
81624
81625
81626
81627
81628
81629
81630
81631
81632
81633
81634
81635
81636
81637
81638
81639
81640
81641
81642
81643
81644
81645
81646
81647
81648
81649
81650
81651
81652
81653
81654
81655
81656
81657
81658
81659
81660
81661
81662
81663
81664
81665
81666
81667
81668
81669
81670
81671
81672
81673
81674
81675
81676
81677
81678
81679
81680
81681
81682
81683
81684
81685
81686
81687
81688
81689
81690
81691
81692
81693
81694
81695
81696
81697
81698
81699
81700
81701
81702
81703
81704
81705
81706
81707
81708
81709
81710
81711
81712
81713
81714
81715
81716
81717
81718
81719
81720
81721
81722
81723
81724
81725
81726
81727
81728
81729
81730
81731
81732
81733
81734
81735
81736
81737
81738
81739
81740


81741
81742
81743
81744
81745
81746



81747
81748
81749
81750
81751
81752
81753
81754
81755
81756
81757
81758
81759
81760
81761
81762
81763
81764
81765
81766
81767
81768
81769
81770
81771
81772
81773
81774
81775
81776
81777
81778
81779
81780
81781
81782
81783
81784
81785
81786
81787
81788
81789
81790
81791
81792
81793
81794
81795
81796
81797
81798
81799
81800
81801
81802
81803
81804
81805
81806
81807
81808
81809
81810
81811
81812
81813
81814
81815
81816

81817
81818
81819
81820
81821
81822
81823
81824
81825
81826
81827
81828
81829
81830
81831
81832





81833



81834

81835
81836
81837
81838
81839
81840
81841
81842
81843
81844
81845
81846
81847
81848
81849
81850
81851
81852
81853
81854
81855
81856
81857
81858
81859
81860
81861
81862
81863
81864
81865
81866
81867
81868
81869
81870
81871
81872
81873
81874
81875
81876
81877
81878
81879
81880
81881
81882
81883
81884
81885
81886
81887
81888
81889
81890
81891
81892
81893
81894
81895
81896
81897


81898
81899
81900
81901
81902
81903
81904








81905




81906


81907
81908
81909
81910
81911
81912
81913
81914
81915
81916
81917
81918
81919
81920
** The format for sqlite_stat2 is recorded here for legacy reference.  This
** version of SQLite does not support sqlite_stat2.  It neither reads nor
** writes the sqlite_stat2 table.  This version of SQLite only supports
** sqlite_stat3.
**
** Format for sqlite_stat3:
**
** The sqlite_stat3 format is a subset of sqlite_stat4.  Hence, the
** sqlite_stat4 format will be described first.  Further information
** about sqlite_stat3 follows the sqlite_stat4 description.
**
** Format for sqlite_stat4:
**
** As with sqlite_stat2, the sqlite_stat4 table contains histogram data
** to aid the query planner in choosing good indices based on the values
** that indexed columns are compared against in the WHERE clauses of
** queries.
**
** The sqlite_stat4 table contains multiple entries for each index.
** The idx column names the index and the tbl column is the table of the
** index.  If the idx and tbl columns are the same, then the sample is
** of the INTEGER PRIMARY KEY.  The sample column is a blob which is the
** binary encoding of a key from the index, with the trailing rowid
** omitted.  The nEq column is a list of integers.  The first integer
** is the approximate number of entries in the index whose left-most 
** column exactly matches the left-most column of the sample.  The second
** integer in nEq is the approximate number of entries in the index where
** the first two columns match the first two columns of the sample.
** And so forth.  nLt is another list of integers that show the approximate
** number of entries that are strictly less than the sample.  The first
** integer in nLt contains the number of entries in the index where the
** left-most column is less than the left-most column of the sample.
** The K-th integer in the nLt entry is the number of index entries 
** where the first K columns are less than the first K columns of the
** sample.  The nDLt column is like nLt except that it contains the 
** number of distinct entries in the index that are less than the
** sample.
**









** There can be an arbitrary number of sqlite_stat4 entries per index.
** The ANALYZE command will typically generate sqlite_stat4 tables
** that contain between 10 and 40 samples which are distributed across
** the key space, though not uniformly, and which include samples with
** large nEq values.
**
** Format for sqlite_stat3 redux:
**
** The sqlite_stat3 table is like sqlite_stat4 except that it only
** looks at the left-most column of the index.  The sqlite_stat3.sample
** column contains the actual value of the left-most column instead
** of a blob encoding of the complete index key as is found in
** sqlite_stat4.sample.  The nEq, nLt, and nDLt entries of sqlite_stat3
** all contain just a single integer which is the same as the first
** integer in the equivalent columns in sqlite_stat4.
*/
#ifndef SQLITE_OMIT_ANALYZE

#if defined(SQLITE_ENABLE_STAT4)
# define IsStat4     1
# define IsStat3     0
#elif defined(SQLITE_ENABLE_STAT3)
# define IsStat4     0
# define IsStat3     1
#else
# define IsStat4     0
# define IsStat3     0
# undef SQLITE_STAT4_SAMPLES
# define SQLITE_STAT4_SAMPLES 1
#endif
#define IsStat34    (IsStat3+IsStat4)  /* 1 for STAT3 or STAT4. 0 otherwise */

/*
** This routine generates code that opens the sqlite_statN tables.

** The sqlite_stat1 table is always relevant.  sqlite_stat2 is now
** obsolete.  sqlite_stat3 and sqlite_stat4 are only opened when
** appropriate compile-time options are provided.
**
** If the sqlite_statN tables do not previously exist, it is created.


**
** Argument zWhere may be a pointer to a buffer containing a table name,
** or it may be a NULL pointer. If it is not NULL, then all entries in

** the sqlite_statN tables associated with the named table are deleted.
** If zWhere==0, then code is generated to delete all stat table entries.
*/
static void openStatTable(
  Parse *pParse,          /* Parsing context */
  int iDb,                /* The database we are looking in */
  int iStatCur,           /* Open the sqlite_stat1 table on this cursor */
  const char *zWhere,     /* Delete entries for this table or index */
  const char *zWhereType  /* Either "tbl" or "idx" */
){
  static const struct {
    const char *zName;
    const char *zCols;
  } aTable[] = {
    { "sqlite_stat1", "tbl,idx,stat" },
#if defined(SQLITE_ENABLE_STAT4)
    { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" },
    { "sqlite_stat3", 0 },
#elif defined(SQLITE_ENABLE_STAT3)
    { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
    { "sqlite_stat4", 0 },
#else
    { "sqlite_stat3", 0 },
    { "sqlite_stat4", 0 },
#endif
  };




  int i;
  sqlite3 *db = pParse->db;
  Db *pDb;
  Vdbe *v = sqlite3GetVdbe(pParse);
  int aRoot[ArraySize(aTable)];
  u8 aCreateTbl[ArraySize(aTable)];

  if( v==0 ) return;
  assert( sqlite3BtreeHoldsAllMutexes(db) );
  assert( sqlite3VdbeDb(v)==db );
  pDb = &db->aDb[iDb];

  /* Create new statistic tables if they do not exist, or clear them
  ** if they do already exist.
  */
  for(i=0; i<ArraySize(aTable); i++){
    const char *zTab = aTable[i].zName;
    Table *pStat;
    if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
      if( aTable[i].zCols ){
        /* The sqlite_statN table does not exist. Create it. Note that a 
        ** side-effect of the CREATE TABLE statement is to leave the rootpage 
        ** of the new table in register pParse->regRoot. This is important 
        ** because the OpenWrite opcode below will be needing it. */
        sqlite3NestedParse(pParse,
            "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
        );
        aRoot[i] = pParse->regRoot;
        aCreateTbl[i] = OPFLAG_P2ISREG;
      }
    }else{
      /* The table already exists. If zWhere is not NULL, delete all entries 
      ** associated with the table zWhere. If zWhere is NULL, delete the
      ** entire contents of the table. */
      aRoot[i] = pStat->tnum;
      aCreateTbl[i] = 0;
      sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
      if( zWhere ){
        sqlite3NestedParse(pParse,
           "DELETE FROM %Q.%s WHERE %s=%Q",
           pDb->zName, zTab, zWhereType, zWhere
        );
      }else{
        /* The sqlite_stat[134] table already exists.  Delete all rows. */
        sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
      }
    }
  }

  /* Open the sqlite_stat[134] tables for writing. */
  for(i=0; aTable[i].zCols; i++){
    assert( i<ArraySize(aTable) );
    sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
    sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
    sqlite3VdbeChangeP5(v, aCreateTbl[i]);
  }
}

/*
** Recommended number of samples for sqlite_stat4
*/
#ifndef SQLITE_STAT4_SAMPLES
# define SQLITE_STAT4_SAMPLES 24
#endif

/*
** Three SQL functions - stat_init(), stat_push(), and stat_get() -
** share an instance of the following structure to hold their state
** information.
*/
typedef struct Stat4Accum Stat4Accum;
typedef struct Stat4Sample Stat4Sample;
struct Stat4Sample {
  tRowcnt *anEq;                  /* sqlite_stat4.nEq */
  tRowcnt *anDLt;                 /* sqlite_stat4.nDLt */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  tRowcnt *anLt;                  /* sqlite_stat4.nLt */
  i64 iRowid;                     /* Rowid in main table of the key */
  u8 isPSample;                   /* True if a periodic sample */
  int iCol;                       /* If !isPSample, the reason for inclusion */
  u32 iHash;                      /* Tiebreaker hash */
#endif
};                                                    
struct Stat4Accum {
  tRowcnt nRow;             /* Number of rows in the entire table */
  tRowcnt nPSample;         /* How often to do a periodic sample */
  int nCol;                 /* Number of columns in index + rowid */
  int mxSample;             /* Maximum number of samples to accumulate */
  Stat4Sample current;      /* Current row as a Stat4Sample */
  u32 iPrn;                 /* Pseudo-random number used for sampling */


  Stat4Sample *aBest;       /* Array of (nCol-1) best samples */
  int iMin;                 /* Index in a[] of entry with minimum score */

  int nSample;              /* Current number of samples */
  int iGet;                 /* Index of current sample accessed by stat_get() */
  Stat4Sample *a;           /* Array of mxSample Stat4Sample objects */
};


/*
** Implementation of the stat_init(N,C) SQL function. The two parameters
** are the number of rows in the table or index (C) and the number of columns

** in the index (N).  The second argument (C) is only used for STAT3 and STAT4.
**
** This routine allocates the Stat4Accum object in heap memory. The return 

** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. 
** the size of the blob is sizeof(void*) bytes). 
*/
static void statInit(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Stat4Accum *p;
  int nCol;                       /* Number of columns in index being sampled */
  int nColUp;                     /* nCol rounded up for alignment */
  int n;                          /* Bytes of space to allocate */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  int mxSample = SQLITE_STAT4_SAMPLES;
#endif

  /* Decode the three function arguments */
  UNUSED_PARAMETER(argc);
  nCol = sqlite3_value_int(argv[0]);
  assert( nCol>1 );               /* >1 because it includes the rowid column */
  nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;

  /* Allocate the space required for the Stat4Accum object */
  n = sizeof(*p) 
    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anEq */
    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anDLt */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anLt */
    + sizeof(Stat4Sample)*(nCol+mxSample)   /* Stat4Accum.aBest[], a[] */
    + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
#endif
  ;
  p = sqlite3MallocZero(n);
  if( p==0 ){
    sqlite3_result_error_nomem(context);
    return;
  }

  p->nRow = 0;
  p->nCol = nCol;
  p->current.anDLt = (tRowcnt*)&p[1];
  p->current.anEq = &p->current.anDLt[nColUp];

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  {
    u8 *pSpace;                     /* Allocated space not yet assigned */
    int i;                          /* Used to iterate through p->aSample[] */

    p->iGet = -1;
    p->mxSample = mxSample;
    p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1);
    p->current.anLt = &p->current.anEq[nColUp];
    sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
  
    /* Set up the Stat4Accum.a[] and aBest[] arrays */
    p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
    p->aBest = &p->a[mxSample];
    pSpace = (u8*)(&p->a[mxSample+nCol]);
    for(i=0; i<(mxSample+nCol); i++){
      p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
      p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
      p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
    }
    assert( (pSpace - (u8*)p)==n );
  
    for(i=0; i<nCol; i++){
      p->aBest[i].iCol = i;
    }
  }
#endif

  /* Return a pointer to the allocated object to the caller */
  sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
}
static const FuncDef statInitFuncdef = {
  1+IsStat34,      /* nArg */
  SQLITE_UTF8,     /* iPrefEnc */
  0,               /* flags */
  0,               /* pUserData */
  0,               /* pNext */
  statInit,        /* xFunc */
  0,               /* xStep */
  0,               /* xFinalize */
  "stat_init",     /* zName */
  0,               /* pHash */
  0                /* pDestructor */
};

#ifdef SQLITE_ENABLE_STAT4
/*
** pNew and pOld are both candidate non-periodic samples selected for 
** the same column (pNew->iCol==pOld->iCol). Ignoring this column and 
** considering only any trailing columns and the sample hash value, this
** function returns true if sample pNew is to be preferred over pOld.
** In other words, if we assume that the cardinalities of the selected
** column for pNew and pOld are equal, is pNew to be preferred over pOld.
**
** This function assumes that for each argument sample, the contents of
** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid. 
*/
static int sampleIsBetterPost(
  Stat4Accum *pAccum, 
  Stat4Sample *pNew, 
  Stat4Sample *pOld
){
  int nCol = pAccum->nCol;
  int i;
  assert( pNew->iCol==pOld->iCol );
  for(i=pNew->iCol+1; i<nCol; i++){
    if( pNew->anEq[i]>pOld->anEq[i] ) return 1;
    if( pNew->anEq[i]<pOld->anEq[i] ) return 0;
  }
  if( pNew->iHash>pOld->iHash ) return 1;
  return 0;
}
#endif

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*



** Return true if pNew is to be preferred over pOld.
**
** This function assumes that for each argument sample, the contents of
** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. 
*/
static int sampleIsBetter(
  Stat4Accum *pAccum, 
  Stat4Sample *pNew, 

  Stat4Sample *pOld
){

  tRowcnt nEqNew = pNew->anEq[pNew->iCol];
  tRowcnt nEqOld = pOld->anEq[pOld->iCol];


  assert( pOld->isPSample==0 && pNew->isPSample==0 );
  assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) );

  if( (nEqNew>nEqOld) ) return 1;
#ifdef SQLITE_ENABLE_STAT4
  if( nEqNew==nEqOld ){
    if( pNew->iCol<pOld->iCol ) return 1;
    return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld));


  }


  return 0;
#else
  return (nEqNew==nEqOld && pNew->iHash>pOld->iHash);
#endif
}

/*
** Copy the contents of object (*pFrom) into (*pTo).
*/
void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
  pTo->iRowid = pFrom->iRowid;
  pTo->isPSample = pFrom->isPSample;
  pTo->iCol = pFrom->iCol;
  pTo->iHash = pFrom->iHash;
  memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol);
  memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol);
  memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol);
}

/*
** Copy the contents of sample *pNew into the p->a[] array. If necessary,
** remove the least desirable sample from p->a[] to make room.
*/
static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
  Stat4Sample *pSample;
  int i;

  assert( IsStat4 || nEqZero==0 );

#ifdef SQLITE_ENABLE_STAT4
  if( pNew->isPSample==0 ){
    Stat4Sample *pUpgrade = 0;
    assert( pNew->anEq[pNew->iCol]>0 );

    /* This sample is being added because the prefix that ends in column 
    ** iCol occurs many times in the table. However, if we have already
    ** added a sample that shares this prefix, there is no need to add
    ** this one. Instead, upgrade the priority of the highest priority
    ** existing sample that shares this prefix.  */
    for(i=p->nSample-1; i>=0; i--){
      Stat4Sample *pOld = &p->a[i];
      if( pOld->anEq[pNew->iCol]==0 ){
        if( pOld->isPSample ) return;
        assert( pOld->iCol>pNew->iCol );
        assert( sampleIsBetter(p, pNew, pOld) );
        if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){
          pUpgrade = pOld;
        }
      }
    }
    if( pUpgrade ){
      pUpgrade->iCol = pNew->iCol;
      pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol];
      goto find_new_min;
    }
  }
#endif

  /* If necessary, remove sample iMin to make room for the new sample. */
  if( p->nSample>=p->mxSample ){
    Stat4Sample *pMin = &p->a[p->iMin];
    tRowcnt *anEq = pMin->anEq;
    tRowcnt *anLt = pMin->anLt;
    tRowcnt *anDLt = pMin->anDLt;
    memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1));
    pSample = &p->a[p->nSample-1];
    pSample->anEq = anEq;
    pSample->anDLt = anDLt;
    pSample->anLt = anLt;
    p->nSample = p->mxSample-1;
  }

  /* The "rows less-than" for the rowid column must be greater than that
  ** for the last sample in the p->a[] array. Otherwise, the samples would
  ** be out of order. */
#ifdef SQLITE_ENABLE_STAT4
  assert( p->nSample==0 
       || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] );

#endif

  /* Insert the new sample */

  pSample = &p->a[p->nSample];

  sampleCopy(p, pSample, pNew);

  p->nSample++;


  /* Zero the first nEqZero entries in the anEq[] array. */
  memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero);

#ifdef SQLITE_ENABLE_STAT4
 find_new_min:
#endif
  if( p->nSample>=p->mxSample ){
    int iMin = -1;
    for(i=0; i<p->mxSample; i++){
      if( p->a[i].isPSample ) continue;
      if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){


        iMin = i;


      }
    }
    assert( iMin>=0 );
    p->iMin = iMin;
  }
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

/*
** Field iChng of the index being scanned has changed. So at this point
** p->current contains a sample that reflects the previous row of the
** index. The value of anEq[iChng] and subsequent anEq[] elements are
** correct at this point.
*/
static void samplePushPrevious(Stat4Accum *p, int iChng){
#ifdef SQLITE_ENABLE_STAT4
  int i;

  /* Check if any samples from the aBest[] array should be pushed
  ** into IndexSample.a[] at this point.  */
  for(i=(p->nCol-2); i>=iChng; i--){
    Stat4Sample *pBest = &p->aBest[i];
    pBest->anEq[i] = p->current.anEq[i];
    if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){
      sampleInsert(p, pBest, i);
    }
  }

  /* Update the anEq[] fields of any samples already collected. */
  for(i=p->nSample-1; i>=0; i--){
    int j;
    for(j=iChng; j<p->nCol; j++){
      if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
    }
  }
#endif

#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
  if( iChng==0 ){
    tRowcnt nLt = p->current.anLt[0];
    tRowcnt nEq = p->current.anEq[0];

    /* Check if this is to be a periodic sample. If so, add it. */
    if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){
      p->current.isPSample = 1;
      sampleInsert(p, &p->current, 0);
      p->current.isPSample = 0;
    }else 

    /* Or if it is a non-periodic sample. Add it in this case too. */
    if( p->nSample<p->mxSample 
     || sampleIsBetter(p, &p->current, &p->a[p->iMin]) 
    ){
      sampleInsert(p, &p->current, 0);
    }
  }
#endif
}

/*
** Implementation of the stat_push SQL function:  stat_push(P,R,C)
** Arguments:
**
**    P     Pointer to the Stat4Accum object created by stat_init()
**    C     Index of left-most column to differ from previous row
**    R     Rowid for the current row
**
** The SQL function always returns NULL.
**
** The R parameter is only used for STAT3 and STAT4.
*/
static void statPush(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int i;

  /* The three function arguments */
  Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
  int iChng = sqlite3_value_int(argv[1]);

  assert( p->nCol>1 );        /* Includes rowid field */
  assert( iChng<p->nCol );

  if( p->nRow==0 ){
    /* This is the first call to this function. Do initialization. */
    for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
  }else{
    /* Second and subsequent calls get processed here */
    samplePushPrevious(p, iChng);

    /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
    ** to the current row of the index. */
    for(i=0; i<iChng; i++){
      p->current.anEq[i]++;
    }
    for(i=iChng; i<p->nCol; i++){
      p->current.anDLt[i]++;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
      p->current.anLt[i] += p->current.anEq[i];
#endif
      p->current.anEq[i] = 1;
    }
  }
  p->nRow++;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  p->current.iRowid = sqlite3_value_int64(argv[2]);
  p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
#endif

#ifdef SQLITE_ENABLE_STAT4
  {
    tRowcnt nLt = p->current.anLt[p->nCol-1];

    /* Check if this is to be a periodic sample. If so, add it. */
    if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
      p->current.isPSample = 1;
      p->current.iCol = 0;
      sampleInsert(p, &p->current, p->nCol-1);
      p->current.isPSample = 0;
    }

    /* Update the aBest[] array. */
    for(i=0; i<(p->nCol-1); i++){
      p->current.iCol = i;
      if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){
        sampleCopy(p, &p->aBest[i], &p->current);
      }
    }
  }
#endif
}
static const FuncDef statPushFuncdef = {
  2+IsStat34,      /* nArg */
  SQLITE_UTF8,     /* iPrefEnc */
  0,               /* flags */
  0,               /* pUserData */
  0,               /* pNext */
  statPush,        /* xFunc */
  0,               /* xStep */
  0,               /* xFinalize */
  "stat_push",     /* zName */
  0,               /* pHash */
  0                /* pDestructor */
};

#define STAT_GET_STAT1 0          /* "stat" column of stat1 table */
#define STAT_GET_ROWID 1          /* "rowid" column of stat[34] entry */
#define STAT_GET_NEQ   2          /* "neq" column of stat[34] entry */
#define STAT_GET_NLT   3          /* "nlt" column of stat[34] entry */
#define STAT_GET_NDLT  4          /* "ndlt" column of stat[34] entry */

/*
** Implementation of the stat_get(P,J) SQL function.  This routine is
** used to query the results.  Content is returned for parameter J


** which is one of the STAT_GET_xxxx values defined above.
**
** If neither STAT3 nor STAT4 are enabled, then J is always
** STAT_GET_STAT1 and is hence omitted and this routine becomes
** a one-parameter function, stat_get(P), that always returns the
** stat1 table entry information.



*/
static void statGet(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  /* STAT3 and STAT4 have a parameter on this routine. */
  int eCall = sqlite3_value_int(argv[1]);
  assert( argc==2 );
  assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ 
       || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
       || eCall==STAT_GET_NDLT 
  );
  if( eCall==STAT_GET_STAT1 )
#else
  assert( argc==1 );
#endif
  {
    /* Return the value to store in the "stat" column of the sqlite_stat1
    ** table for this index.
    **
    ** The value is a string composed of a list of integers describing 
    ** the index. The first integer in the list is the total number of 
    ** entries in the index. There is one additional integer in the list 
    ** for each indexed column. This additional integer is an estimate of
    ** the number of rows matched by a stabbing query on the index using
    ** a key with the corresponding number of fields. In other words,
    ** if the index is on columns (a,b) and the sqlite_stat1 value is 
    ** "100 10 2", then SQLite estimates that:
    **
    **   * the index contains 100 rows,
    **   * "WHERE a=?" matches 10 rows, and
    **   * "WHERE a=? AND b=?" matches 2 rows.
    **
    ** If D is the count of distinct values and K is the total number of 
    ** rows, then each estimate is computed as:
    **
    **        I = (K+D-1)/D
    */
    char *z;
    int i;

    char *zRet = sqlite3MallocZero(p->nCol * 25);
    if( zRet==0 ){
      sqlite3_result_error_nomem(context);
      return;
    }

    sqlite3_snprintf(24, zRet, "%lld", p->nRow);
    z = zRet + sqlite3Strlen30(zRet);
    for(i=0; i<(p->nCol-1); i++){
      i64 nDistinct = p->current.anDLt[i] + 1;
      i64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
      sqlite3_snprintf(24, z, " %lld", iVal);
      z += sqlite3Strlen30(z);
      assert( p->current.anEq[i] );
    }
    assert( z[0]=='\0' && z>zRet );

    sqlite3_result_text(context, zRet, -1, sqlite3_free);
  }
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  else if( eCall==STAT_GET_ROWID ){
    if( p->iGet<0 ){
      samplePushPrevious(p, 0);
      p->iGet = 0;
    }
    if( p->iGet<p->nSample ){

      sqlite3_result_int64(context, p->a[p->iGet].iRowid);
    }
  }else{
    tRowcnt *aCnt = 0;

    assert( p->iGet<p->nSample );
    switch( eCall ){
      case STAT_GET_NEQ:  aCnt = p->a[p->iGet].anEq; break;
      case STAT_GET_NLT:  aCnt = p->a[p->iGet].anLt; break;
      default: {
        aCnt = p->a[p->iGet].anDLt; 
        p->iGet++;
        break;
      }
    }






    if( IsStat3 ){



      sqlite3_result_int64(context, (i64)aCnt[0]);

    }else{
      char *zRet = sqlite3MallocZero(p->nCol * 25);
      if( zRet==0 ){
        sqlite3_result_error_nomem(context);
      }else{
        int i;
        char *z = zRet;
        for(i=0; i<p->nCol; i++){
          sqlite3_snprintf(24, z, "%lld ", aCnt[i]);
          z += sqlite3Strlen30(z);
        }
        assert( z[0]=='\0' && z>zRet );
        z[-1] = '\0';
        sqlite3_result_text(context, zRet, -1, sqlite3_free);
      }
    }
  }
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
}
static const FuncDef statGetFuncdef = {
  1+IsStat34,      /* nArg */
  SQLITE_UTF8,     /* iPrefEnc */
  0,               /* flags */
  0,               /* pUserData */
  0,               /* pNext */
  statGet,         /* xFunc */
  0,               /* xStep */
  0,               /* xFinalize */
  "stat_get",      /* zName */
  0,               /* pHash */
  0                /* pDestructor */
};

static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
  assert( regOut!=regStat4 && regOut!=regStat4+1 );
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
#else
  assert( iParam==STAT_GET_STAT1 );
#endif
  sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut);
  sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF);
  sqlite3VdbeChangeP5(v, 1 + IsStat34);
}

/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
static void analyzeOneTable(
  Parse *pParse,   /* Parser context */
  Table *pTab,     /* Table whose indices are to be analyzed */
  Index *pOnlyIdx, /* If not NULL, only analyze this one index */
  int iStatCur,    /* Index of VdbeCursor that writes the sqlite_stat1 table */
  int iMem,        /* Available memory locations begin here */
  int iTab         /* Next available cursor */
){
  sqlite3 *db = pParse->db;    /* Database handle */
  Index *pIdx;                 /* An index to being analyzed */
  int iIdxCur;                 /* Cursor open on index being analyzed */
  int iTabCur;                 /* Table cursor */
  Vdbe *v;                     /* The virtual machine being built up */
  int i;                       /* Loop counter */


  int jZeroRows = -1;          /* Jump from here if number of rows is zero */
  int iDb;                     /* Index of database containing pTab */
  u8 needTableCnt = 1;         /* True to count the table */
  int regNewRowid = iMem++;    /* Rowid for the inserted record */
  int regStat4 = iMem++;       /* Register to hold Stat4Accum object */
  int regChng = iMem++;        /* Index of changed index field */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4








  int regRowid = iMem++;       /* Rowid argument passed to stat_push() */




#endif


  int regTemp = iMem++;        /* Temporary use register */
  int regTabname = iMem++;     /* Register containing table name */
  int regIdxname = iMem++;     /* Register containing index name */
  int regStat1 = iMem++;       /* Value for the stat column of sqlite_stat1 */
  int regPrev = iMem;          /* MUST BE LAST (see below) */

  pParse->nMem = MAX(pParse->nMem, iMem);
  v = sqlite3GetVdbe(pParse);
  if( v==0 || NEVER(pTab==0) ){
    return;
  }
  if( pTab->tnum==0 ){
    /* Do not gather statistics on views or virtual tables */
    return;
80759
80760
80761
80762
80763
80764
80765
80766



80767
80768
80769


80770

80771
80772
80773
80774
80775



80776
80777

80778
80779
80780
80781
80782
80783
80784
80785
80786
80787
80788
80789
80790
80791
80792
80793
80794
80795
80796

80797



80798
80799
80800
80801
80802
80803

80804
80805
80806
80807
80808
80809
80810
80811
80812
80813
80814



80815
80816
80817
80818
80819
80820
80821
80822
80823
80824
80825
80826
80827
80828



80829

80830
80831


80832


80833














80834
80835

80836






80837
80838
80839
80840
80841











80842
80843

80844
80845
80846
80847
80848
80849
80850
80851
80852
80853
80854
80855
80856
80857
80858
80859
80860
80861


80862







80863
80864
80865


80866







80867
80868
80869
80870
80871
80872
80873
80874
80875
80876
80877




80878
80879
80880
80881
80882
80883
80884
80885

80886
80887
80888
80889
80890
80891
80892



80893
80894






80895

80896
80897

80898



80899


80900


80901
80902
80903
80904

80905
80906
80907
80908
80909
80910

80911
80912
80913
80914
80915
80916
80917
80918
80919
80920
80921
80922
80923
80924
80925
80926
80927
80928
80929
80930
80931
80932
80933
80934
80935
80936
80937
80938
80939
80940
80941
80942
80943
80944
80945
80946
80947
80948
80949
80950
80951
80952
80953
80954
80955
80956
80957
80958
80959
80960
80961
80962
80963
80964
80965
80966
80967
80968
80969
80970
80971
80972
80973
80974

80975
80976
80977
80978
80979
80980
80981
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
      db->aDb[iDb].zName ) ){
    return;
  }
#endif

  /* Establish a read-lock on the table at the shared-cache level. */



  sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);

  iIdxCur = pParse->nTab++;


  sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);

  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    int nCol;
    KeyInfo *pKey;
    int addrIfNot = 0;           /* address of OP_IfNot */
    int *aChngAddr;              /* Array of jump instruction addresses */




    if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;

    VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
    nCol = pIdx->nColumn;
    aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
    if( aChngAddr==0 ) continue;
    pKey = sqlite3IndexKeyinfo(pParse, pIdx);
    if( iMem+1+(nCol*2)>pParse->nMem ){
      pParse->nMem = iMem+1+(nCol*2);
    }

    /* Open a cursor to the index to be analyzed. */
    assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
    sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
        (char *)pKey, P4_KEYINFO_HANDOFF);
    VdbeComment((v, "%s", pIdx->zName));

    /* Populate the register containing the index name. */
    sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);

#ifdef SQLITE_ENABLE_STAT3

    if( once ){



      once = 0;
      sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
    }
    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount);
    sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1);
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq);

    sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt);
    sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt);
    sqlite3VdbeAddOp3(v, OP_Null, 0, regSample, regAccum);
    sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum,
                      (char*)&stat3InitFuncdef, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, 2);
#endif /* SQLITE_ENABLE_STAT3 */

    /* The block of memory cells initialized here is used as follows.
    **
    **    iMem:                



    **        The total number of rows in the table.
    **
    **    iMem+1 .. iMem+nCol: 
    **        Number of distinct entries in index considering the 
    **        left-most N columns only, where N is between 1 and nCol, 
    **        inclusive.
    **
    **    iMem+nCol+1 .. Mem+2*nCol:  
    **        Previous value of indexed columns, from left to right.
    **
    ** Cells iMem through iMem+nCol are initialized to 0. The others are 
    ** initialized to contain an SQL NULL.
    */
    for(i=0; i<=nCol; i++){



      sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i);

    }
    for(i=0; i<nCol; i++){


      sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1);


    }















    /* Start the analysis loop. This loop runs through all the entries in

    ** the index b-tree.  */






    endOfLoop = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
    topOfLoop = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1);  /* Increment row counter */












    for(i=0; i<nCol; i++){
      CollSeq *pColl;

      sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
      if( i==0 ){
        /* Always record the very first row */
        addrIfNot = sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
      }
      assert( pIdx->azColl!=0 );
      assert( pIdx->azColl[i]!=0 );
      pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
      aChngAddr[i] = sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
                                      (char*)pColl, P4_COLLSEQ);
      sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
      VdbeComment((v, "jump if column %d changed", i));
#ifdef SQLITE_ENABLE_STAT3
      if( i==0 ){
        sqlite3VdbeAddOp2(v, OP_AddImm, regNumEq, 1);
        VdbeComment((v, "incr repeat count"));
      }
#endif


    }







    sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
    for(i=0; i<nCol; i++){
      sqlite3VdbeJumpHere(v, aChngAddr[i]);  /* Set jump dest for the OP_Ne */


      if( i==0 ){







        sqlite3VdbeJumpHere(v, addrIfNot);   /* Jump dest for OP_IfNot */
#ifdef SQLITE_ENABLE_STAT3
        sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
                          (char*)&stat3PushFuncdef, P4_FUNCDEF);
        sqlite3VdbeChangeP5(v, 5);
        sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, pIdx->nColumn, regRowid);
        sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt);
        sqlite3VdbeAddOp2(v, OP_AddImm, regNumDLt, 1);
        sqlite3VdbeAddOp2(v, OP_Integer, 1, regNumEq);
#endif        
      }




      sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
      sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
    }
    sqlite3DbFree(db, aChngAddr);

    /* Always jump here after updating the iMem+1...iMem+1+nCol counters */
    sqlite3VdbeResolveLabel(v, endOfLoop);


    sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
    sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
#ifdef SQLITE_ENABLE_STAT3
    sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
                      (char*)&stat3PushFuncdef, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, 5);
    sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop);



    shortJump = 
    sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1);






    sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regTemp1,

                      (char*)&stat3GetFuncdef, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, 2);

    sqlite3VdbeAddOp1(v, OP_IsNull, regTemp1);



    sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1);


    sqlite3VdbeAddOp3(v, OP_Column, iTabCur, pIdx->aiColumn[0], regSample);


    sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[0], regSample);
    sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumEq,
                      (char*)&stat3GetFuncdef, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, 3);

    sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt,
                      (char*)&stat3GetFuncdef, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, 4);
    sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumDLt,
                      (char*)&stat3GetFuncdef, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, 5);

    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regRec, "bbbbbb", 0);
    sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
    sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, shortJump);
    sqlite3VdbeJumpHere(v, shortJump+2);
#endif        

    /* Store the results in sqlite_stat1.
    **
    ** The result is a single row of the sqlite_stat1 table.  The first
    ** two columns are the names of the table and index.  The third column
    ** is a string composed of a list of integer statistics about the
    ** index.  The first integer in the list is the total number of entries
    ** in the index.  There is one additional integer in the list for each
    ** column of the table.  This additional integer is a guess of how many
    ** rows of the table the index will select.  If D is the count of distinct
    ** values and K is the total number of rows, then the integer is computed
    ** as:
    **
    **        I = (K+D-1)/D
    **
    ** If K==0 then no entry is made into the sqlite_stat1 table.  
    ** If K>0 then it is always the case the D>0 so division by zero
    ** is never possible.
    */
    sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
    if( jZeroRows<0 ){
      jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
    }
    for(i=0; i<nCol; i++){
      sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
      sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
      sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
      sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
      sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
      sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
      sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
    }
    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
    sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
    sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
  }

  /* If the table has no indices, create a single sqlite_stat1 entry
  ** containing NULL as the index name and the row count as the content.
  */
  if( pTab->pIndex==0 ){
    sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
    VdbeComment((v, "%s", pTab->zName));
    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
    sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
    jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
  }else{
    sqlite3VdbeJumpHere(v, jZeroRows);
    jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto);
  }
  sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
  sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
  sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
  sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
  sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
  if( pParse->nMem<regRec ) pParse->nMem = regRec;
  sqlite3VdbeJumpHere(v, jZeroRows);

}


/*
** Generate code that will cause the most recent index analysis to
** be loaded into internal hash tables where is can be used.
*/







|
>
>
>

|
|
>
>

>

|
|
<
|
>
>
>


>


|
|

<
<
<
<
<
<
<
<
<




<
>
|
>
>
>
|
<
<
<
|
<
>
|
|
|
|
|
|
|
|
<

|
>
>
>
|

|
|
<
|
|
|
<

<
|

|
>
>
>
|
>
|
<
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<
>
|
>
>
>
>
>
>
|
|
|
<

>
>
>
>
>
>
>
>
>
>
>

|
>
|
<
<
<
<
<
|
<
|
<

<
<
<
<
<
|
<
>
>
|
>
>
>
>
>
>
>
|

|
>
>
|
>
>
>
>
>
>
>
|
|
<
<
<
<
<
|
|
|
<
>
>
>
>
|
<
|
<
|
<
<
|
>
|
|
<
<
<
|
|
>
>
>
|
|
>
>
>
>
>
>
|
>
|
|
>
|
>
>
>
|
>
>
|
>
>
|
<
<
|
>
|
<
<
<
<
<
>
|
|
|
|
|
<
|
|
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
<
|
|
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
|

|
<

|
<

<
<
<
<
|
|
|
|
|
<
|
>







81930
81931
81932
81933
81934
81935
81936
81937
81938
81939
81940
81941
81942
81943
81944
81945
81946
81947
81948
81949
81950

81951
81952
81953
81954
81955
81956
81957
81958
81959
81960
81961
81962









81963
81964
81965
81966

81967
81968
81969
81970
81971
81972



81973

81974
81975
81976
81977
81978
81979
81980
81981
81982

81983
81984
81985
81986
81987
81988
81989
81990
81991

81992
81993
81994

81995

81996
81997
81998
81999
82000
82001
82002
82003
82004

82005
82006
82007
82008
82009
82010
82011
82012
82013
82014
82015
82016
82017
82018
82019
82020
82021
82022
82023
82024
82025

82026
82027
82028
82029
82030
82031
82032
82033
82034
82035
82036

82037
82038
82039
82040
82041
82042
82043
82044
82045
82046
82047
82048
82049
82050
82051
82052





82053

82054

82055





82056

82057
82058
82059
82060
82061
82062
82063
82064
82065
82066
82067
82068
82069
82070
82071
82072
82073
82074
82075
82076
82077
82078
82079
82080
82081





82082
82083
82084

82085
82086
82087
82088
82089

82090

82091


82092
82093
82094
82095



82096
82097
82098
82099
82100
82101
82102
82103
82104
82105
82106
82107
82108
82109
82110
82111
82112
82113
82114
82115
82116
82117
82118
82119
82120
82121
82122
82123
82124


82125
82126
82127





82128
82129
82130
82131
82132
82133

82134
82135
82136








82137







82138

82139
82140
82141







82142






82143
82144
82145
82146

82147
82148

82149




82150
82151
82152
82153
82154

82155
82156
82157
82158
82159
82160
82161
82162
82163
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
      db->aDb[iDb].zName ) ){
    return;
  }
#endif

  /* Establish a read-lock on the table at the shared-cache level. 
  ** Open a read-only cursor on the table. Also allocate a cursor number
  ** to use for scanning indexes (iIdxCur). No index cursor is opened at
  ** this time though.  */
  sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
  iTabCur = iTab++;
  iIdxCur = iTab++;
  pParse->nTab = MAX(pParse->nTab, iTab);
  sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
  sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);

  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    int nCol;                     /* Number of columns indexed by pIdx */
    KeyInfo *pKey;                /* KeyInfo structure for pIdx */

    int *aGotoChng;               /* Array of jump instruction addresses */
    int addrRewind;               /* Address of "OP_Rewind iIdxCur" */
    int addrGotoChng0;            /* Address of "Goto addr_chng_0" */
    int addrNextRow;              /* Address of "next_row:" */

    if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
    if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
    VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
    nCol = pIdx->nColumn;
    aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1));
    if( aGotoChng==0 ) continue;
    pKey = sqlite3IndexKeyinfo(pParse, pIdx);










    /* Populate the register containing the index name. */
    sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);


    /*
    ** Pseudo-code for loop that calls stat_push():
    **
    **   Rewind csr
    **   if eof(csr) goto end_of_scan;
    **   regChng = 0



    **   goto chng_addr_0;

    **
    **  next_row:
    **   regChng = 0
    **   if( idx(0) != regPrev(0) ) goto chng_addr_0
    **   regChng = 1
    **   if( idx(1) != regPrev(1) ) goto chng_addr_1
    **   ...
    **   regChng = N
    **   goto chng_addr_N

    **
    **  chng_addr_0:
    **   regPrev(0) = idx(0)
    **  chng_addr_1:
    **   regPrev(1) = idx(1)
    **  ...
    **
    **  chng_addr_N:
    **   regRowid = idx(rowid)

    **   stat_push(P, regChng, regRowid)
    **   Next csr
    **   if !eof(csr) goto next_row;

    **

    **  end_of_scan:
    */

    /* Make sure there are enough memory cells allocated to accommodate 
    ** the regPrev array and a trailing rowid (the rowid slot is required
    ** when building a record to insert into the sample column of 
    ** the sqlite_stat4 table.  */
    pParse->nMem = MAX(pParse->nMem, regPrev+nCol);


    /* Open a read-only cursor on the index being analyzed. */
    assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
    sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb);
    sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF); 
    VdbeComment((v, "%s", pIdx->zName));

    /* Invoke the stat_init() function. The arguments are:
    ** 
    **    (1) the number of columns in the index including the rowid,
    **    (2) the number of rows in the index,
    **
    ** The second argument is only used for STAT3 and STAT4
    */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2);
#endif
    sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1);
    sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4);
    sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, 1+IsStat34);


    /* Implementation of the following:
    **
    **   Rewind csr
    **   if eof(csr) goto end_of_scan;
    **   regChng = 0
    **   goto next_push_0;
    **
    */
    addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
    addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto);


    /*
    **  next_row:
    **   regChng = 0
    **   if( idx(0) != regPrev(0) ) goto chng_addr_0
    **   regChng = 1
    **   if( idx(1) != regPrev(1) ) goto chng_addr_1
    **   ...
    **   regChng = N
    **   goto chng_addr_N
    */
    addrNextRow = sqlite3VdbeCurrentAddr(v);
    for(i=0; i<nCol; i++){
      char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
      sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
      sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);





      aGotoChng[i] = 

      sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);

      sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);





    }

    sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng);
    aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto);

    /*
    **  chng_addr_0:
    **   regPrev(0) = idx(0)
    **  chng_addr_1:
    **   regPrev(1) = idx(1)
    **  ...
    */
    sqlite3VdbeJumpHere(v, addrGotoChng0);
    for(i=0; i<nCol; i++){
      sqlite3VdbeJumpHere(v, aGotoChng[i]);
      sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
    }

    /*
    **  chng_addr_N:
    **   regRowid = idx(rowid)            // STAT34 only
    **   stat_push(P, regChng, regRowid)  // 3rd parameter STAT34 only
    **   Next csr
    **   if !eof(csr) goto next_row;
    */
    sqlite3VdbeJumpHere(v, aGotoChng[nCol]);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4





    sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
    assert( regRowid==(regStat4+2) );
#endif

    assert( regChng==(regStat4+1) );
    sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
    sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, 2+IsStat34);
    sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow);



    /* Add the entry to the stat1 table. */


    callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
    sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
    sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);



    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);

    /* Add the entries to the stat3 or stat4 table. */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    {
      int regEq = regStat1;
      int regLt = regStat1+1;
      int regDLt = regStat1+2;
      int regSample = regStat1+3;
      int regCol = regStat1+4;
      int regSampleRowid = regCol + nCol;
      int addrNext;
      int addrIsNull;

      pParse->nMem = MAX(pParse->nMem, regCol+nCol+1);

      addrNext = sqlite3VdbeCurrentAddr(v);
      callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
      addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
      callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
      callStatGet(v, regStat4, STAT_GET_NLT, regLt);
      callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
      sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, addrNext, regSampleRowid);
#ifdef SQLITE_ENABLE_STAT3
      sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, 
                                      pIdx->aiColumn[0], regSample);
#else
      for(i=0; i<nCol; i++){
        int iCol = pIdx->aiColumn[i];


        sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
      }
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);





#endif
      sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0);
      sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
      sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
      sqlite3VdbeJumpHere(v, addrIsNull);

    }
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */









    /* End of analysis */







    sqlite3VdbeJumpHere(v, addrRewind);

    sqlite3DbFree(db, aGotoChng);
  }















  /* Create a single sqlite_stat1 entry containing NULL as the index
  ** name and the row count as the content.
  */
  if( pOnlyIdx==0 && needTableCnt ){

    VdbeComment((v, "%s", pTab->zName));
    sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1);

    jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);




    sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
    sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
    sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);

    sqlite3VdbeJumpHere(v, jZeroRows);
  }
}


/*
** Generate code that will cause the most recent index analysis to
** be loaded into internal hash tables where is can be used.
*/
80991
80992
80993
80994
80995
80996
80997

80998
80999
81000
81001
81002
81003

81004
81005
81006
81007
81008
81009
81010
81011
81012
81013
81014
*/
static void analyzeDatabase(Parse *pParse, int iDb){
  sqlite3 *db = pParse->db;
  Schema *pSchema = db->aDb[iDb].pSchema;    /* Schema of database iDb */
  HashElem *k;
  int iStatCur;
  int iMem;


  sqlite3BeginWriteOperation(pParse, 0, iDb);
  iStatCur = pParse->nTab;
  pParse->nTab += 3;
  openStatTable(pParse, iDb, iStatCur, 0, 0);
  iMem = pParse->nMem+1;

  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
    Table *pTab = (Table*)sqliteHashData(k);
    analyzeOneTable(pParse, pTab, 0, iStatCur, iMem);
  }
  loadAnalysis(pParse, iDb);
}

/*
** Generate code that will do an analysis of a single table in
** a database.  If pOnlyIdx is not NULL then it is a single index







>






>



|







82173
82174
82175
82176
82177
82178
82179
82180
82181
82182
82183
82184
82185
82186
82187
82188
82189
82190
82191
82192
82193
82194
82195
82196
82197
82198
*/
static void analyzeDatabase(Parse *pParse, int iDb){
  sqlite3 *db = pParse->db;
  Schema *pSchema = db->aDb[iDb].pSchema;    /* Schema of database iDb */
  HashElem *k;
  int iStatCur;
  int iMem;
  int iTab;

  sqlite3BeginWriteOperation(pParse, 0, iDb);
  iStatCur = pParse->nTab;
  pParse->nTab += 3;
  openStatTable(pParse, iDb, iStatCur, 0, 0);
  iMem = pParse->nMem+1;
  iTab = pParse->nTab;
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
    Table *pTab = (Table*)sqliteHashData(k);
    analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab);
  }
  loadAnalysis(pParse, iDb);
}

/*
** Generate code that will do an analysis of a single table in
** a database.  If pOnlyIdx is not NULL then it is a single index
81025
81026
81027
81028
81029
81030
81031
81032
81033
81034
81035
81036
81037
81038
81039
  iStatCur = pParse->nTab;
  pParse->nTab += 3;
  if( pOnlyIdx ){
    openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx");
  }else{
    openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
  }
  analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1);
  loadAnalysis(pParse, iDb);
}

/*
** Generate code for the ANALYZE command.  The parser calls this routine
** when it recognizes an ANALYZE command.
**







|







82209
82210
82211
82212
82213
82214
82215
82216
82217
82218
82219
82220
82221
82222
82223
  iStatCur = pParse->nTab;
  pParse->nTab += 3;
  if( pOnlyIdx ){
    openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx");
  }else{
    openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
  }
  analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab);
  loadAnalysis(pParse, iDb);
}

/*
** Generate code for the ANALYZE command.  The parser calls this routine
** when it recognizes an ANALYZE command.
**
81107
81108
81109
81110
81111
81112
81113





































81114
81115
81116
81117
81118
81119
81120
81121
81122
81123
81124
81125
81126
81127
81128
81129
81130
81131
81132
81133
81134
81135
81136
81137
81138
81139
81140
81141
81142
81143
81144
81145
81146
81147
81148
81149
81150
81151
81152
81153
81154
81155
81156
81157
81158

81159
81160
81161
81162
81163

81164
81165
81166
81167
81168
81169
81170
81171
81172
81173
81174
81175
81176
81177
81178
81179
81180
81181
81182
81183
81184
81185
81186
81187
81188
81189
81190
81191
81192
81193
81194
81195
81196














81197




















81198












81199
81200






81201
81202
81203
81204
81205
81206
81207
81208
81209
81210
81211
81212
81213
81214
81215
81216
81217
81218
81219
81220
81221
81222
81223
81224



81225
81226
81227



81228
81229
81230
81231
81232



81233


81234

81235




81236
81237
81238
81239
81240
81241
81242








81243
81244
81245
81246
81247
81248
81249
81250
81251
81252
81253
81254
81255
81256
81257
81258
81259
81260
81261
81262
81263
81264
81265




81266
81267
81268
81269
81270
81271
81272
81273
81274
81275
81276
81277








81278
81279
81280


81281
81282
81283
81284
81285
81286
81287
81288
81289
81290
81291
81292

81293
81294
81295
81296
81297


81298

81299
81300
81301

81302




81303
81304
81305
81306
81307
81308
81309
81310
81311
81312
81313
81314
81315
81316






81317
81318
81319
81320
81321
81322
81323
81324
81325
81326
81327
81328
81329
81330
81331
81332
81333
81334
81335
81336
81337
81338
81339
81340
81341
81342
81343
** callback routine.
*/
typedef struct analysisInfo analysisInfo;
struct analysisInfo {
  sqlite3 *db;
  const char *zDatabase;
};






































/*
** This callback is invoked once for each index when reading the
** sqlite_stat1 table.  
**
**     argv[0] = name of the table
**     argv[1] = name of the index (might be NULL)
**     argv[2] = results of analysis - on integer for each column
**
** Entries for which argv[1]==NULL simply record the number of rows in
** the table.
*/
static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
  analysisInfo *pInfo = (analysisInfo*)pData;
  Index *pIndex;
  Table *pTable;
  int i, c, n;
  tRowcnt v;
  const char *z;

  assert( argc==3 );
  UNUSED_PARAMETER2(NotUsed, argc);

  if( argv==0 || argv[0]==0 || argv[2]==0 ){
    return 0;
  }
  pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase);
  if( pTable==0 ){
    return 0;
  }
  if( argv[1] ){
    pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
  }else{
    pIndex = 0;
  }
  n = pIndex ? pIndex->nColumn : 0;
  z = argv[2];
  for(i=0; *z && i<=n; i++){
    v = 0;
    while( (c=z[0])>='0' && c<='9' ){
      v = v*10 + c - '0';
      z++;
    }
    if( i==0 ) pTable->nRowEst = v;
    if( pIndex==0 ) break;

    pIndex->aiRowEst[i] = v;
    if( *z==' ' ) z++;
    if( strcmp(z, "unordered")==0 ){
      pIndex->bUnordered = 1;
      break;

    }
  }
  return 0;
}

/*
** If the Index.aSample variable is not NULL, delete the aSample[] array
** and its contents.
*/
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
#ifdef SQLITE_ENABLE_STAT3
  if( pIdx->aSample ){
    int j;
    for(j=0; j<pIdx->nSample; j++){
      IndexSample *p = &pIdx->aSample[j];
      if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
        sqlite3DbFree(db, p->u.z);
      }
    }
    sqlite3DbFree(db, pIdx->aSample);
  }
  if( db && db->pnBytesFreed==0 ){
    pIdx->nSample = 0;
    pIdx->aSample = 0;
  }
#else
  UNUSED_PARAMETER(db);
  UNUSED_PARAMETER(pIdx);
#endif
}

#ifdef SQLITE_ENABLE_STAT3
/*














** Load content from the sqlite_stat3 table into the Index.aSample[]




















** arrays of all indices.












*/
static int loadStat3(sqlite3 *db, const char *zDb){






  int rc;                       /* Result codes from subroutines */
  sqlite3_stmt *pStmt = 0;      /* An SQL statement being run */
  char *zSql;                   /* Text of the SQL statement */
  Index *pPrevIdx = 0;          /* Previous index in the loop */
  int idx = 0;                  /* slot in pIdx->aSample[] for next sample */
  int eType;                    /* Datatype of a sample */
  IndexSample *pSample;         /* A slot in pIdx->aSample[] */

  assert( db->lookaside.bEnabled==0 );
  if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){
    return SQLITE_OK;
  }

  zSql = sqlite3MPrintf(db, 
      "SELECT idx,count(*) FROM %Q.sqlite_stat3"
      " GROUP BY idx", zDb);
  if( !zSql ){
    return SQLITE_NOMEM;
  }
  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
  sqlite3DbFree(db, zSql);
  if( rc ) return rc;

  while( sqlite3_step(pStmt)==SQLITE_ROW ){



    char *zIndex;   /* Index name */
    Index *pIdx;    /* Pointer to the index object */
    int nSample;    /* Number of samples */




    zIndex = (char *)sqlite3_column_text(pStmt, 0);
    if( zIndex==0 ) continue;
    nSample = sqlite3_column_int(pStmt, 1);
    pIdx = sqlite3FindIndex(db, zIndex, zDb);



    if( pIdx==0 ) continue;


    assert( pIdx->nSample==0 );

    pIdx->nSample = nSample;




    pIdx->aSample = sqlite3DbMallocZero(db, nSample*sizeof(IndexSample));
    pIdx->avgEq = pIdx->aiRowEst[1];
    if( pIdx->aSample==0 ){
      db->mallocFailed = 1;
      sqlite3_finalize(pStmt);
      return SQLITE_NOMEM;
    }








  }
  rc = sqlite3_finalize(pStmt);
  if( rc ) return rc;

  zSql = sqlite3MPrintf(db, 
      "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb);
  if( !zSql ){
    return SQLITE_NOMEM;
  }
  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
  sqlite3DbFree(db, zSql);
  if( rc ) return rc;

  while( sqlite3_step(pStmt)==SQLITE_ROW ){
    char *zIndex;   /* Index name */
    Index *pIdx;    /* Pointer to the index object */
    int i;          /* Loop counter */
    tRowcnt sumEq;  /* Sum of the nEq values */

    zIndex = (char *)sqlite3_column_text(pStmt, 0);
    if( zIndex==0 ) continue;
    pIdx = sqlite3FindIndex(db, zIndex, zDb);
    if( pIdx==0 ) continue;




    if( pIdx==pPrevIdx ){
      idx++;
    }else{
      pPrevIdx = pIdx;
      idx = 0;
    }
    assert( idx<pIdx->nSample );
    pSample = &pIdx->aSample[idx];
    pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 1);
    pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 2);
    pSample->nDLt = (tRowcnt)sqlite3_column_int64(pStmt, 3);
    if( idx==pIdx->nSample-1 ){








      if( pSample->nDLt>0 ){
        for(i=0, sumEq=0; i<=idx-1; i++) sumEq += pIdx->aSample[i].nEq;
        pIdx->avgEq = (pSample->nLt - sumEq)/pSample->nDLt;


      }
      if( pIdx->avgEq<=0 ) pIdx->avgEq = 1;
    }
    eType = sqlite3_column_type(pStmt, 4);
    pSample->eType = (u8)eType;
    switch( eType ){
      case SQLITE_INTEGER: {
        pSample->u.i = sqlite3_column_int64(pStmt, 4);
        break;
      }
      case SQLITE_FLOAT: {
        pSample->u.r = sqlite3_column_double(pStmt, 4);

        break;
      }
      case SQLITE_NULL: {
        break;
      }


      default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); {

        const char *z = (const char *)(
              (eType==SQLITE_BLOB) ?
              sqlite3_column_blob(pStmt, 4):

              sqlite3_column_text(pStmt, 4)




           );
        int n = z ? sqlite3_column_bytes(pStmt, 4) : 0;
        pSample->nByte = n;
        if( n < 1){
          pSample->u.z = 0;
        }else{
          pSample->u.z = sqlite3DbMallocRaw(db, n);
          if( pSample->u.z==0 ){
            db->mallocFailed = 1;
            sqlite3_finalize(pStmt);
            return SQLITE_NOMEM;
          }
          memcpy(pSample->u.z, z, n);
        }






      }
    }
  }
  return sqlite3_finalize(pStmt);
}
#endif /* SQLITE_ENABLE_STAT3 */

/*
** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The
** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
** arrays. The contents of sqlite_stat3 are used to populate the
** Index.aSample[] arrays.
**
** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
** is returned. In this case, even if SQLITE_ENABLE_STAT3 was defined 
** during compilation and the sqlite_stat3 table is present, no data is 
** read from it.
**
** If SQLITE_ENABLE_STAT3 was defined during compilation and the 
** sqlite_stat3 table is not present in the database, SQLITE_ERROR is
** returned. However, in this case, data is read from the sqlite_stat1
** table (if it is present) before returning.
**
** If an OOM error occurs, this function always sets db->mallocFailed.
** This means if the caller does not care about other errors, the return
** code may be ignored.
*/







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
















<
<

















<

<
<
<
<
<
|
<
|
>
|
<
|
|
|
>
|
|








|




<
|
<










|


|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>

|
>
>
>
>
>
>




<
<



<
<
<
<
|
<
<








>
>
>



>
>
>





>
>
>
|
>
>
|
>
|
>
>
>
>
|
<

<



>
>
>
>
>
>
>
>




|
<








|
|
|
<





>
>
>
>
|
|
<

<

<
|
|
|
|
|
>
>
>
>
>
>
>
>
|
<
<
>
>
|
<
<
|
|
<
<
<
<
|
<
|
>
|
|
<
<
|
>
>
|
>
|
|
|
>
|
>
>
>
>
|
<
<
<
<
<
<
<
<
<
<
|
<
|
>
>
>
>
>
>
|
|
<
|

|


|

|



|
|


|
|







82291
82292
82293
82294
82295
82296
82297
82298
82299
82300
82301
82302
82303
82304
82305
82306
82307
82308
82309
82310
82311
82312
82313
82314
82315
82316
82317
82318
82319
82320
82321
82322
82323
82324
82325
82326
82327
82328
82329
82330
82331
82332
82333
82334
82335
82336
82337
82338
82339
82340
82341
82342
82343
82344
82345
82346
82347
82348
82349
82350


82351
82352
82353
82354
82355
82356
82357
82358
82359
82360
82361
82362
82363
82364
82365
82366
82367

82368





82369

82370
82371
82372

82373
82374
82375
82376
82377
82378
82379
82380
82381
82382
82383
82384
82385
82386
82387
82388
82389
82390
82391

82392

82393
82394
82395
82396
82397
82398
82399
82400
82401
82402
82403
82404
82405
82406
82407
82408
82409
82410
82411
82412
82413
82414
82415
82416
82417
82418
82419
82420
82421
82422
82423
82424
82425
82426
82427
82428
82429
82430
82431
82432
82433
82434
82435
82436
82437
82438
82439
82440
82441
82442
82443
82444
82445
82446
82447
82448
82449
82450
82451
82452
82453
82454
82455
82456
82457
82458
82459
82460
82461
82462
82463
82464
82465
82466
82467


82468
82469
82470




82471


82472
82473
82474
82475
82476
82477
82478
82479
82480
82481
82482
82483
82484
82485
82486
82487
82488
82489
82490
82491
82492
82493
82494
82495
82496
82497
82498
82499
82500
82501
82502
82503
82504
82505
82506
82507

82508

82509
82510
82511
82512
82513
82514
82515
82516
82517
82518
82519
82520
82521
82522
82523
82524

82525
82526
82527
82528
82529
82530
82531
82532
82533
82534
82535

82536
82537
82538
82539
82540
82541
82542
82543
82544
82545
82546

82547

82548

82549
82550
82551
82552
82553
82554
82555
82556
82557
82558
82559
82560
82561
82562


82563
82564
82565


82566
82567




82568

82569
82570
82571
82572


82573
82574
82575
82576
82577
82578
82579
82580
82581
82582
82583
82584
82585
82586
82587










82588

82589
82590
82591
82592
82593
82594
82595
82596
82597

82598
82599
82600
82601
82602
82603
82604
82605
82606
82607
82608
82609
82610
82611
82612
82613
82614
82615
82616
82617
82618
82619
82620
82621
** callback routine.
*/
typedef struct analysisInfo analysisInfo;
struct analysisInfo {
  sqlite3 *db;
  const char *zDatabase;
};

/*
** The first argument points to a nul-terminated string containing a
** list of space separated integers. Read the first nOut of these into
** the array aOut[].
*/
static void decodeIntArray(
  char *zIntArray, 
  int nOut, 
  tRowcnt *aOut, 
  int *pbUnordered
){
  char *z = zIntArray;
  int c;
  int i;
  tRowcnt v;

  assert( pbUnordered==0 || *pbUnordered==0 );

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( z==0 ) z = "";
#else
  if( NEVER(z==0) ) z = "";
#endif
  for(i=0; *z && i<nOut; i++){
    v = 0;
    while( (c=z[0])>='0' && c<='9' ){
      v = v*10 + c - '0';
      z++;
    }
    aOut[i] = v;
    if( *z==' ' ) z++;
  }
  if( pbUnordered && strcmp(z, "unordered")==0 ){
    *pbUnordered = 1;
  }
}

/*
** This callback is invoked once for each index when reading the
** sqlite_stat1 table.  
**
**     argv[0] = name of the table
**     argv[1] = name of the index (might be NULL)
**     argv[2] = results of analysis - on integer for each column
**
** Entries for which argv[1]==NULL simply record the number of rows in
** the table.
*/
static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
  analysisInfo *pInfo = (analysisInfo*)pData;
  Index *pIndex;
  Table *pTable;


  const char *z;

  assert( argc==3 );
  UNUSED_PARAMETER2(NotUsed, argc);

  if( argv==0 || argv[0]==0 || argv[2]==0 ){
    return 0;
  }
  pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase);
  if( pTable==0 ){
    return 0;
  }
  if( argv[1] ){
    pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
  }else{
    pIndex = 0;
  }

  z = argv[2];







  if( pIndex ){
    int bUnordered = 0;
    decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst,&bUnordered);

    if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0];
    pIndex->bUnordered = bUnordered;
  }else{
    decodeIntArray((char*)z, 1, &pTable->nRowEst, 0);
  }

  return 0;
}

/*
** If the Index.aSample variable is not NULL, delete the aSample[] array
** and its contents.
*/
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( pIdx->aSample ){
    int j;
    for(j=0; j<pIdx->nSample; j++){
      IndexSample *p = &pIdx->aSample[j];

      sqlite3DbFree(db, p->p);

    }
    sqlite3DbFree(db, pIdx->aSample);
  }
  if( db && db->pnBytesFreed==0 ){
    pIdx->nSample = 0;
    pIdx->aSample = 0;
  }
#else
  UNUSED_PARAMETER(db);
  UNUSED_PARAMETER(pIdx);
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
}

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Populate the pIdx->aAvgEq[] array based on the samples currently
** stored in pIdx->aSample[]. 
*/
static void initAvgEq(Index *pIdx){
  if( pIdx ){
    IndexSample *aSample = pIdx->aSample;
    IndexSample *pFinal = &aSample[pIdx->nSample-1];
    int iCol;
    for(iCol=0; iCol<pIdx->nColumn; iCol++){
      int i;                    /* Used to iterate through samples */
      tRowcnt sumEq = 0;        /* Sum of the nEq values */
      tRowcnt nSum = 0;         /* Number of terms contributing to sumEq */
      tRowcnt avgEq = 0;
      tRowcnt nDLt = pFinal->anDLt[iCol];

      /* Set nSum to the number of distinct (iCol+1) field prefixes that
      ** occur in the stat4 table for this index before pFinal. Set
      ** sumEq to the sum of the nEq values for column iCol for the same
      ** set (adding the value only once where there exist dupicate 
      ** prefixes).  */
      for(i=0; i<(pIdx->nSample-1); i++){
        if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
          sumEq += aSample[i].anEq[iCol];
          nSum++;
        }
      }
      if( nDLt>nSum ){
        avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
      }
      if( avgEq==0 ) avgEq = 1;
      pIdx->aAvgEq[iCol] = avgEq;
      if( pIdx->nSampleCol==1 ) break;
    }
  }
}

/*
** Load the content from either the sqlite_stat4 or sqlite_stat3 table 
** into the relevant Index.aSample[] arrays.
**
** Arguments zSql1 and zSql2 must point to SQL statements that return
** data equivalent to the following (statements are different for stat3,
** see the caller of this function for details):
**
**    zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx
**    zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4
**
** where %Q is replaced with the database name before the SQL is executed.
*/
static int loadStatTbl(
  sqlite3 *db,                  /* Database handle */
  int bStat3,                   /* Assume single column records only */
  const char *zSql1,            /* SQL statement 1 (see above) */
  const char *zSql2,            /* SQL statement 2 (see above) */
  const char *zDb               /* Database name (e.g. "main") */
){
  int rc;                       /* Result codes from subroutines */
  sqlite3_stmt *pStmt = 0;      /* An SQL statement being run */
  char *zSql;                   /* Text of the SQL statement */
  Index *pPrevIdx = 0;          /* Previous index in the loop */


  IndexSample *pSample;         /* A slot in pIdx->aSample[] */

  assert( db->lookaside.bEnabled==0 );




  zSql = sqlite3MPrintf(db, zSql1, zDb);


  if( !zSql ){
    return SQLITE_NOMEM;
  }
  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
  sqlite3DbFree(db, zSql);
  if( rc ) return rc;

  while( sqlite3_step(pStmt)==SQLITE_ROW ){
    int nIdxCol = 1;              /* Number of columns in stat4 records */
    int nAvgCol = 1;              /* Number of entries in Index.aAvgEq */

    char *zIndex;   /* Index name */
    Index *pIdx;    /* Pointer to the index object */
    int nSample;    /* Number of samples */
    int nByte;      /* Bytes of space required */
    int i;          /* Bytes of space required */
    tRowcnt *pSpace;

    zIndex = (char *)sqlite3_column_text(pStmt, 0);
    if( zIndex==0 ) continue;
    nSample = sqlite3_column_int(pStmt, 1);
    pIdx = sqlite3FindIndex(db, zIndex, zDb);
    assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
    /* Index.nSample is non-zero at this point if data has already been
    ** loaded from the stat4 table. In this case ignore stat3 data.  */
    if( pIdx==0 || pIdx->nSample ) continue;
    if( bStat3==0 ){
      nIdxCol = pIdx->nColumn+1;
      nAvgCol = pIdx->nColumn;
    }
    pIdx->nSampleCol = nIdxCol;
    nByte = sizeof(IndexSample) * nSample;
    nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
    nByte += nAvgCol * sizeof(tRowcnt);     /* Space for Index.aAvgEq[] */

    pIdx->aSample = sqlite3DbMallocZero(db, nByte);

    if( pIdx->aSample==0 ){

      sqlite3_finalize(pStmt);
      return SQLITE_NOMEM;
    }
    pSpace = (tRowcnt*)&pIdx->aSample[nSample];
    pIdx->aAvgEq = pSpace; pSpace += nAvgCol;
    for(i=0; i<nSample; i++){
      pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
      pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
      pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
    }
    assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) );
  }
  rc = sqlite3_finalize(pStmt);
  if( rc ) return rc;

  zSql = sqlite3MPrintf(db, zSql2, zDb);

  if( !zSql ){
    return SQLITE_NOMEM;
  }
  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
  sqlite3DbFree(db, zSql);
  if( rc ) return rc;

  while( sqlite3_step(pStmt)==SQLITE_ROW ){
    char *zIndex;                 /* Index name */
    Index *pIdx;                  /* Pointer to the index object */
    int nCol = 1;                 /* Number of columns in index */


    zIndex = (char *)sqlite3_column_text(pStmt, 0);
    if( zIndex==0 ) continue;
    pIdx = sqlite3FindIndex(db, zIndex, zDb);
    if( pIdx==0 ) continue;
    /* This next condition is true if data has already been loaded from 
    ** the sqlite_stat4 table. In this case ignore stat3 data.  */
    nCol = pIdx->nSampleCol;
    if( bStat3 && nCol>1 ) continue;
    if( pIdx!=pPrevIdx ){
      initAvgEq(pPrevIdx);

      pPrevIdx = pIdx;

    }

    pSample = &pIdx->aSample[pIdx->nSample];
    decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0);
    decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0);
    decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0);

    /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer.
    ** This is in case the sample record is corrupted. In that case, the
    ** sqlite3VdbeRecordCompare() may read up to two varints past the
    ** end of the allocated buffer before it realizes it is dealing with
    ** a corrupt record. Adding the two 0x00 bytes prevents this from causing
    ** a buffer overread.  */
    pSample->n = sqlite3_column_bytes(pStmt, 4);
    pSample->p = sqlite3DbMallocZero(db, pSample->n + 2);
    if( pSample->p==0 ){


      sqlite3_finalize(pStmt);
      return SQLITE_NOMEM;
    }


    memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
    pIdx->nSample++;




  }

  rc = sqlite3_finalize(pStmt);
  if( rc==SQLITE_OK ) initAvgEq(pPrevIdx);
  return rc;
}



/*
** Load content from the sqlite_stat4 and sqlite_stat3 tables into 
** the Index.aSample[] arrays of all indices.
*/
static int loadStat4(sqlite3 *db, const char *zDb){
  int rc = SQLITE_OK;             /* Result codes from subroutines */

  assert( db->lookaside.bEnabled==0 );
  if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
    rc = loadStatTbl(db, 0,
      "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", 
      "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
      zDb
    );










  }


  if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){
    rc = loadStatTbl(db, 1,
      "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", 
      "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3",
      zDb
    );
  }


  return rc;
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

/*
** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The
** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
** arrays. The contents of sqlite_stat3/4 are used to populate the
** Index.aSample[] arrays.
**
** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined 
** during compilation and the sqlite_stat3/4 table is present, no data is 
** read from it.
**
** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the 
** sqlite_stat4 table is not present in the database, SQLITE_ERROR is
** returned. However, in this case, data is read from the sqlite_stat1
** table (if it is present) before returning.
**
** If an OOM error occurs, this function always sets db->mallocFailed.
** This means if the caller does not care about other errors, the return
** code may be ignored.
*/
81351
81352
81353
81354
81355
81356
81357
81358
81359
81360
81361
81362
81363
81364
81365
  assert( db->aDb[iDb].pBt!=0 );

  /* Clear any prior statistics */
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
    Index *pIdx = sqliteHashData(i);
    sqlite3DefaultRowEst(pIdx);
#ifdef SQLITE_ENABLE_STAT3
    sqlite3DeleteIndexSamples(db, pIdx);
    pIdx->aSample = 0;
#endif
  }

  /* Check to make sure the sqlite_stat1 table exists */
  sInfo.db = db;







|







82629
82630
82631
82632
82633
82634
82635
82636
82637
82638
82639
82640
82641
82642
82643
  assert( db->aDb[iDb].pBt!=0 );

  /* Clear any prior statistics */
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
    Index *pIdx = sqliteHashData(i);
    sqlite3DefaultRowEst(pIdx);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    sqlite3DeleteIndexSamples(db, pIdx);
    pIdx->aSample = 0;
#endif
  }

  /* Check to make sure the sqlite_stat1 table exists */
  sInfo.db = db;
81375
81376
81377
81378
81379
81380
81381
81382
81383
81384
81385
81386
81387
81388
81389
81390
81391
81392
81393
81394
    rc = SQLITE_NOMEM;
  }else{
    rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
    sqlite3DbFree(db, zSql);
  }


  /* Load the statistics from the sqlite_stat3 table. */
#ifdef SQLITE_ENABLE_STAT3
  if( rc==SQLITE_OK ){
    int lookasideEnabled = db->lookaside.bEnabled;
    db->lookaside.bEnabled = 0;
    rc = loadStat3(db, sInfo.zDatabase);
    db->lookaside.bEnabled = lookasideEnabled;
  }
#endif

  if( rc==SQLITE_NOMEM ){
    db->mallocFailed = 1;
  }







|
|



|







82653
82654
82655
82656
82657
82658
82659
82660
82661
82662
82663
82664
82665
82666
82667
82668
82669
82670
82671
82672
    rc = SQLITE_NOMEM;
  }else{
    rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
    sqlite3DbFree(db, zSql);
  }


  /* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  if( rc==SQLITE_OK ){
    int lookasideEnabled = db->lookaside.bEnabled;
    db->lookaside.bEnabled = 0;
    rc = loadStat4(db, sInfo.zDatabase);
    db->lookaside.bEnabled = lookasideEnabled;
  }
#endif

  if( rc==SQLITE_NOMEM ){
    db->mallocFailed = 1;
  }
81555
81556
81557
81558
81559
81560
81561



81562
81563
81564
81565
81566
81567
81568
        "attached databases must use the same text encoding as main database");
      rc = SQLITE_ERROR;
    }
    pPager = sqlite3BtreePager(aNew->pBt);
    sqlite3PagerLockingMode(pPager, db->dfltLockMode);
    sqlite3BtreeSecureDelete(aNew->pBt,
                             sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );



  }
  aNew->safety_level = 3;
  aNew->zName = sqlite3DbStrDup(db, zName);
  if( rc==SQLITE_OK && aNew->zName==0 ){
    rc = SQLITE_NOMEM;
  }








>
>
>







82833
82834
82835
82836
82837
82838
82839
82840
82841
82842
82843
82844
82845
82846
82847
82848
82849
        "attached databases must use the same text encoding as main database");
      rc = SQLITE_ERROR;
    }
    pPager = sqlite3BtreePager(aNew->pBt);
    sqlite3PagerLockingMode(pPager, db->dfltLockMode);
    sqlite3BtreeSecureDelete(aNew->pBt,
                             sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
    sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
#endif
  }
  aNew->safety_level = 3;
  aNew->zName = sqlite3DbStrDup(db, zName);
  if( rc==SQLITE_OK && aNew->zName==0 ){
    rc = SQLITE_NOMEM;
  }

82591
82592
82593
82594
82595
82596
82597

82598
82599
82600
82601
82602
82603
82604
/*
** Reclaim the memory used by an index
*/
static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
  sqlite3DeleteIndexSamples(db, p);
#endif

  sqlite3DbFree(db, p->zColAff);
  sqlite3DbFree(db, p);
}

/*
** For the index called zIdxName which is found in the database iDb,
** unlike that index from its Table then remove the index from







>







83872
83873
83874
83875
83876
83877
83878
83879
83880
83881
83882
83883
83884
83885
83886
/*
** Reclaim the memory used by an index
*/
static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
  sqlite3DeleteIndexSamples(db, p);
#endif
  sqlite3ExprDelete(db, p->pPartIdxWhere);
  sqlite3DbFree(db, p->zColAff);
  sqlite3DbFree(db, p);
}

/*
** For the index called zIdxName which is found in the database iDb,
** unlike that index from its Table then remove the index from
83434
83435
83436
83437
83438
83439
83440
83441

83442
83443
83444
83445
83446
83447
83448
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else{
    Index *p;
    p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);

    if( p ){
      p->autoIndex = 2;
    }
    pList = 0;
  }

primary_key_exit:







|
>







84716
84717
84718
84719
84720
84721
84722
84723
84724
84725
84726
84727
84728
84729
84730
84731
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else{
    Index *p;
    p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
                           0, sortOrder, 0);
    if( p ){
      p->autoIndex = 2;
    }
    pList = 0;
  }

primary_key_exit:
83729
83730
83731
83732
83733
83734
83735
83736
83737
83738
83739
83740
83741
83742
83743
83744
83745
83746
83747
83748
83749
83750
83751
83752
83753
83754
83755
83756
83757
83758
83759
83760
83761
83762

  iDb = sqlite3SchemaToIndex(db, p->pSchema);

#ifndef SQLITE_OMIT_CHECK
  /* Resolve names in all CHECK constraint expressions.
  */
  if( p->pCheck ){
    SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
    NameContext sNC;                /* Name context for pParse->pNewTable */
    ExprList *pList;                /* List of all CHECK constraints */
    int i;                          /* Loop counter */

    memset(&sNC, 0, sizeof(sNC));
    memset(&sSrc, 0, sizeof(sSrc));
    sSrc.nSrc = 1;
    sSrc.a[0].zName = p->zName;
    sSrc.a[0].pTab = p;
    sSrc.a[0].iCursor = -1;
    sNC.pParse = pParse;
    sNC.pSrcList = &sSrc;
    sNC.ncFlags = NC_IsCheck;
    pList = p->pCheck;
    for(i=0; i<pList->nExpr; i++){
      if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
        return;
      }
    }
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */

  /* If the db->init.busy is 1 it means we are reading the SQL off the
  ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  ** So do not write to the disk again.  Extract the root page number
  ** for the table from the db->init.newTnum field.  (The page number







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







85012
85013
85014
85015
85016
85017
85018




85019















85020
85021
85022
85023
85024
85025
85026

  iDb = sqlite3SchemaToIndex(db, p->pSchema);

#ifndef SQLITE_OMIT_CHECK
  /* Resolve names in all CHECK constraint expressions.
  */
  if( p->pCheck ){




    sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);















  }
#endif /* !defined(SQLITE_OMIT_CHECK) */

  /* If the db->init.busy is 1 it means we are reading the SQL off the
  ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  ** So do not write to the disk again.  Extract the root page number
  ** for the table from the db->init.newTnum field.  (The page number
84250
84251
84252
84253
84254
84255
84256
84257
84258
84259
84260
84261
84262
84263
84264
  Parse *pParse,         /* The parsing context */
  int iDb,               /* The database number */
  const char *zType,     /* "idx" or "tbl" */
  const char *zName      /* Name of index or table */
){
  int i;
  const char *zDbName = pParse->db->aDb[iDb].zName;
  for(i=1; i<=3; i++){
    char zTab[24];
    sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
    if( sqlite3FindTable(pParse->db, zTab, zDbName) ){
      sqlite3NestedParse(pParse,
        "DELETE FROM %Q.%s WHERE %s=%Q",
        zDbName, zTab, zType, zName
      );







|







85514
85515
85516
85517
85518
85519
85520
85521
85522
85523
85524
85525
85526
85527
85528
  Parse *pParse,         /* The parsing context */
  int iDb,               /* The database number */
  const char *zType,     /* "idx" or "tbl" */
  const char *zName      /* Name of index or table */
){
  int i;
  const char *zDbName = pParse->db->aDb[iDb].zName;
  for(i=1; i<=4; i++){
    char zTab[24];
    sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
    if( sqlite3FindTable(pParse->db, zTab, zDbName) ){
      sqlite3NestedParse(pParse,
        "DELETE FROM %Q.%s WHERE %s=%Q",
        zDbName, zTab, zType, zName
      );
84600
84601
84602
84603
84604
84605
84606

84607
84608
84609
84610
84611
84612
84613
  Table *pTab = pIndex->pTable;  /* The table that is indexed */
  int iTab = pParse->nTab++;     /* Btree cursor used for pTab */
  int iIdx = pParse->nTab++;     /* Btree cursor used for pIndex */
  int iSorter;                   /* Cursor opened by OpenSorter (if in use) */
  int addr1;                     /* Address of top of loop */
  int addr2;                     /* Address to jump to for next iteration */
  int tnum;                      /* Root page of index */

  Vdbe *v;                       /* Generate code into this virtual machine */
  KeyInfo *pKey;                 /* KeyInfo for index */
  int regRecord;                 /* Register holding assemblied index record */
  sqlite3 *db = pParse->db;      /* The database connection */
  int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);

#ifndef SQLITE_OMIT_AUTHORIZATION







>







85864
85865
85866
85867
85868
85869
85870
85871
85872
85873
85874
85875
85876
85877
85878
  Table *pTab = pIndex->pTable;  /* The table that is indexed */
  int iTab = pParse->nTab++;     /* Btree cursor used for pTab */
  int iIdx = pParse->nTab++;     /* Btree cursor used for pIndex */
  int iSorter;                   /* Cursor opened by OpenSorter (if in use) */
  int addr1;                     /* Address of top of loop */
  int addr2;                     /* Address to jump to for next iteration */
  int tnum;                      /* Root page of index */
  int iPartIdxLabel;             /* Jump to this label to skip a row */
  Vdbe *v;                       /* Generate code into this virtual machine */
  KeyInfo *pKey;                 /* KeyInfo for index */
  int regRecord;                 /* Register holding assemblied index record */
  sqlite3 *db = pParse->db;      /* The database connection */
  int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);

#ifndef SQLITE_OMIT_AUTHORIZATION
84639
84640
84641
84642
84643
84644
84645
84646
84647

84648
84649
84650
84651
84652
84653
84654

  /* Open the table. Loop through all rows of the table, inserting index
  ** records into the sorter. */
  sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
  regRecord = sqlite3GetTempReg(pParse);

  sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
  sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);

  sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
  sqlite3VdbeJumpHere(v, addr1);
  addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
  if( pIndex->onError!=OE_None ){
    int j2 = sqlite3VdbeCurrentAddr(v) + 3;
    sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
    addr2 = sqlite3VdbeCurrentAddr(v);







|

>







85904
85905
85906
85907
85908
85909
85910
85911
85912
85913
85914
85915
85916
85917
85918
85919
85920

  /* Open the table. Loop through all rows of the table, inserting index
  ** records into the sorter. */
  sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
  regRecord = sqlite3GetTempReg(pParse);

  sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, &iPartIdxLabel);
  sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
  sqlite3VdbeResolveLabel(v, iPartIdxLabel);
  sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
  sqlite3VdbeJumpHere(v, addr1);
  addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
  if( pIndex->onError!=OE_None ){
    int j2 = sqlite3VdbeCurrentAddr(v) + 3;
    sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
    addr2 = sqlite3VdbeCurrentAddr(v);
84691
84692
84693
84694
84695
84696
84697
84698
84699
84700
84701
84702
84703
84704
84705
  Parse *pParse,     /* All information about this parse */
  Token *pName1,     /* First part of index name. May be NULL */
  Token *pName2,     /* Second part of index name. May be NULL */
  SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
  ExprList *pList,   /* A list of columns to be indexed */
  int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  Token *pStart,     /* The CREATE token that begins this statement */
  Token *pEnd,       /* The ")" that closes the CREATE INDEX statement */
  int sortOrder,     /* Sort order of primary key when pList==NULL */
  int ifNotExist     /* Omit error if index already exists */
){
  Index *pRet = 0;     /* Pointer to return */
  Table *pTab = 0;     /* Table to be indexed */
  Index *pIndex = 0;   /* The index to be created */
  char *zName = 0;     /* Name of the index */







|







85957
85958
85959
85960
85961
85962
85963
85964
85965
85966
85967
85968
85969
85970
85971
  Parse *pParse,     /* All information about this parse */
  Token *pName1,     /* First part of index name. May be NULL */
  Token *pName2,     /* Second part of index name. May be NULL */
  SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
  ExprList *pList,   /* A list of columns to be indexed */
  int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  Token *pStart,     /* The CREATE token that begins this statement */
  Expr *pPIWhere,    /* WHERE clause for partial indices */
  int sortOrder,     /* Sort order of primary key when pList==NULL */
  int ifNotExist     /* Omit error if index already exists */
){
  Index *pRet = 0;     /* Pointer to return */
  Table *pTab = 0;     /* Table to be indexed */
  Index *pIndex = 0;   /* The index to be created */
  char *zName = 0;     /* Name of the index */
84713
84714
84715
84716
84717
84718
84719
84720
84721
84722
84723
84724
84725
84726
84727
  int iDb;             /* Index of the database that is being written */
  Token *pName = 0;    /* Unqualified name of the index to create */
  struct ExprList_item *pListItem; /* For looping over pList */
  int nCol;
  int nExtra = 0;
  char *zExtra;

  assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
  assert( pParse->nErr==0 );      /* Never called with prior errors */
  if( db->mallocFailed || IN_DECLARE_VTAB ){
    goto exit_create_index;
  }
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto exit_create_index;
  }







<







85979
85980
85981
85982
85983
85984
85985

85986
85987
85988
85989
85990
85991
85992
  int iDb;             /* Index of the database that is being written */
  Token *pName = 0;    /* Unqualified name of the index to create */
  struct ExprList_item *pListItem; /* For looping over pList */
  int nCol;
  int nExtra = 0;
  char *zExtra;


  assert( pParse->nErr==0 );      /* Never called with prior errors */
  if( db->mallocFailed || IN_DECLARE_VTAB ){
    goto exit_create_index;
  }
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto exit_create_index;
  }
84759
84760
84761
84762
84763
84764
84765
84766





84767
84768
84769
84770
84771
84772
84773
      /* Because the parser constructs pTblName from a single identifier,
      ** sqlite3FixSrcList can never fail. */
      assert(0);
    }
    pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
    assert( db->mallocFailed==0 || pTab==0 );
    if( pTab==0 ) goto exit_create_index;
    assert( db->aDb[iDb].pSchema==pTab->pSchema );





  }else{
    assert( pName==0 );
    assert( pStart==0 );
    pTab = pParse->pNewTable;
    if( !pTab ) goto exit_create_index;
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  }







|
>
>
>
>
>







86024
86025
86026
86027
86028
86029
86030
86031
86032
86033
86034
86035
86036
86037
86038
86039
86040
86041
86042
86043
      /* Because the parser constructs pTblName from a single identifier,
      ** sqlite3FixSrcList can never fail. */
      assert(0);
    }
    pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
    assert( db->mallocFailed==0 || pTab==0 );
    if( pTab==0 ) goto exit_create_index;
    if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){
      sqlite3ErrorMsg(pParse, 
           "cannot create a TEMP index on non-TEMP table \"%s\"",
           pTab->zName);
      goto exit_create_index;
    }
  }else{
    assert( pName==0 );
    assert( pStart==0 );
    pTab = pParse->pNewTable;
    if( !pTab ) goto exit_create_index;
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  }
84908
84909
84910
84911
84912
84913
84914





84915
84916
84917
84918
84919
84920
84921
  memcpy(pIndex->zName, zName, nName+1);
  pIndex->pTable = pTab;
  pIndex->nColumn = pList->nExpr;
  pIndex->onError = (u8)onError;
  pIndex->uniqNotNull = onError==OE_Abort;
  pIndex->autoIndex = (u8)(pName==0);
  pIndex->pSchema = db->aDb[iDb].pSchema;





  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );

  /* Check to see if we should honor DESC requests on index columns
  */
  if( pDb->pSchema->file_format>=4 ){
    sortOrderMask = -1;   /* Honor DESC */
  }else{







>
>
>
>
>







86178
86179
86180
86181
86182
86183
86184
86185
86186
86187
86188
86189
86190
86191
86192
86193
86194
86195
86196
  memcpy(pIndex->zName, zName, nName+1);
  pIndex->pTable = pTab;
  pIndex->nColumn = pList->nExpr;
  pIndex->onError = (u8)onError;
  pIndex->uniqNotNull = onError==OE_Abort;
  pIndex->autoIndex = (u8)(pName==0);
  pIndex->pSchema = db->aDb[iDb].pSchema;
  if( pPIWhere ){
    sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0);
    pIndex->pPartIdxWhere = pPIWhere;
    pPIWhere = 0;
  }
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );

  /* Check to see if we should honor DESC requests on index columns
  */
  if( pDb->pSchema->file_format>=4 ){
    sortOrderMask = -1;   /* Honor DESC */
  }else{
85063
85064
85065
85066
85067
85068
85069
85070
85071
85072
85073
85074
85075
85076
85077
85078
85079
85080
85081
85082
85083
85084
85085
85086
85087

85088
85089
85090
85091
85092
85093
85094
85095
85096
85097
85098
85099
85100
  ** we don't want to recreate it.
  **
  ** If pTblName==0 it means this index is generated as a primary key
  ** or UNIQUE constraint of a CREATE TABLE statement.  Since the table
  ** has just been created, it contains no data and the index initialization
  ** step can be skipped.
  */
  else{ /* if( db->init.busy==0 ) */
    Vdbe *v;
    char *zStmt;
    int iMem = ++pParse->nMem;

    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto exit_create_index;


    /* Create the rootpage for the index
    */
    sqlite3BeginWriteOperation(pParse, 1, iDb);
    sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);

    /* Gather the complete text of the CREATE INDEX statement into
    ** the zStmt variable
    */
    if( pStart ){

      assert( pEnd!=0 );
      /* A named index with an explicit CREATE INDEX statement */
      zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
        onError==OE_None ? "" : " UNIQUE",
        (int)(pEnd->z - pName->z) + 1,
        pName->z);
    }else{
      /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
      /* zStmt = sqlite3MPrintf(""); */
      zStmt = 0;
    }

    /* Add an entry in sqlite_master for this index







|

















>
|


|
<
<







86338
86339
86340
86341
86342
86343
86344
86345
86346
86347
86348
86349
86350
86351
86352
86353
86354
86355
86356
86357
86358
86359
86360
86361
86362
86363
86364
86365
86366
86367


86368
86369
86370
86371
86372
86373
86374
  ** we don't want to recreate it.
  **
  ** If pTblName==0 it means this index is generated as a primary key
  ** or UNIQUE constraint of a CREATE TABLE statement.  Since the table
  ** has just been created, it contains no data and the index initialization
  ** step can be skipped.
  */
  else if( pParse->nErr==0 ){
    Vdbe *v;
    char *zStmt;
    int iMem = ++pParse->nMem;

    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto exit_create_index;


    /* Create the rootpage for the index
    */
    sqlite3BeginWriteOperation(pParse, 1, iDb);
    sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);

    /* Gather the complete text of the CREATE INDEX statement into
    ** the zStmt variable
    */
    if( pStart ){
      int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
      if( pName->z[n-1]==';' ) n--;
      /* A named index with an explicit CREATE INDEX statement */
      zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
        onError==OE_None ? "" : " UNIQUE", n, pName->z);


    }else{
      /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
      /* zStmt = sqlite3MPrintf(""); */
      zStmt = 0;
    }

    /* Add an entry in sqlite_master for this index
85142
85143
85144
85145
85146
85147
85148
85149
85150
85151
85152
85153
85154
85155
85156
85157
85158
85159
    }
    pRet = pIndex;
    pIndex = 0;
  }

  /* Clean up before exiting */
exit_create_index:
  if( pIndex ){
    sqlite3DbFree(db, pIndex->zColAff);
    sqlite3DbFree(db, pIndex);
  }
  sqlite3ExprListDelete(db, pList);
  sqlite3SrcListDelete(db, pTblName);
  sqlite3DbFree(db, zName);
  return pRet;
}

/*







|
<
|
<







86416
86417
86418
86419
86420
86421
86422
86423

86424

86425
86426
86427
86428
86429
86430
86431
    }
    pRet = pIndex;
    pIndex = 0;
  }

  /* Clean up before exiting */
exit_create_index:
  if( pIndex ) freeIndex(db, pIndex);

  sqlite3ExprDelete(db, pPIWhere);

  sqlite3ExprListDelete(db, pList);
  sqlite3SrcListDelete(db, pTblName);
  sqlite3DbFree(db, zName);
  return pRet;
}

/*
86023
86024
86025
86026
86027
86028
86029
86030
86031
86032
86033

86034
86035
86036
86037
86038
86039
86040
86041
86042
86043
86044
86045
86046
86047
86048
86049
86050
86051
86052
86053
86054
86055
** pointer. If an error occurs (out of memory or missing collation 
** sequence), NULL is returned and the state of pParse updated to reflect
** the error.
*/
SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
  int i;
  int nCol = pIdx->nColumn;
  int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
  sqlite3 *db = pParse->db;
  KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);


  if( pKey ){
    pKey->db = pParse->db;
    pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
    assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
    for(i=0; i<nCol; i++){
      char *zColl = pIdx->azColl[i];
      assert( zColl );
      pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
      pKey->aSortOrder[i] = pIdx->aSortOrder[i];
    }
    pKey->nField = (u16)nCol;
  }

  if( pParse->nErr ){
    sqlite3DbFree(db, pKey);
    pKey = 0;
  }
  return pKey;
}

/************** End of build.c ***********************************************/
/************** Begin file callback.c ****************************************/







<
<
|

>

<
<
<






<



|







87295
87296
87297
87298
87299
87300
87301


87302
87303
87304
87305



87306
87307
87308
87309
87310
87311

87312
87313
87314
87315
87316
87317
87318
87319
87320
87321
87322
** pointer. If an error occurs (out of memory or missing collation 
** sequence), NULL is returned and the state of pParse updated to reflect
** the error.
*/
SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
  int i;
  int nCol = pIdx->nColumn;


  KeyInfo *pKey;

  pKey = sqlite3KeyInfoAlloc(pParse->db, nCol);
  if( pKey ){



    for(i=0; i<nCol; i++){
      char *zColl = pIdx->azColl[i];
      assert( zColl );
      pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
      pKey->aSortOrder[i] = pIdx->aSortOrder[i];
    }

  }

  if( pParse->nErr ){
    sqlite3DbFree(pParse->db, pKey);
    pKey = 0;
  }
  return pKey;
}

/************** End of build.c ***********************************************/
/************** Begin file callback.c ****************************************/
87121
87122
87123
87124
87125
87126
87127


87128
87129
87130
87131
87132

87133
87134
87135
87136
87137
87138
87139
87140
87141
87142
87143
87144
87145







87146
87147
87148
87149
87150
87151
87152

87153
87154
87155
87156
87157
87158
87159










87160
87161
87162
87163
87164
87165
87166
  Table *pTab,       /* Table containing the row to be deleted */
  int iCur,          /* Cursor number for the table */
  int *aRegIdx       /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
){
  int i;
  Index *pIdx;
  int r1;



  for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
    if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
    r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
    sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);

  }
}

/*
** Generate code that will assemble an index key and put it in register
** regOut.  The key with be for index pIdx which is an index on pTab.
** iCur is the index of a cursor open on the pTab table and pointing to
** the entry that needs indexing.
**
** Return a register number which is the first in a block of
** registers that holds the elements of the index key.  The
** block of registers has already been deallocated by the time
** this routine returns.







*/
SQLITE_PRIVATE int sqlite3GenerateIndexKey(
  Parse *pParse,     /* Parsing context */
  Index *pIdx,       /* The index for which to generate a key */
  int iCur,          /* Cursor number for the pIdx->pTable table */
  int regOut,        /* Write the new index key to this register */
  int doMakeRec      /* Run the OP_MakeRecord instruction if true */

){
  Vdbe *v = pParse->pVdbe;
  int j;
  Table *pTab = pIdx->pTable;
  int regBase;
  int nCol;











  nCol = pIdx->nColumn;
  regBase = sqlite3GetTempRange(pParse, nCol+1);
  sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
  for(j=0; j<nCol; j++){
    int idx = pIdx->aiColumn[j];
    if( idx==pTab->iPKey ){
      sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);







>
>



|
|
>













>
>
>
>
>
>
>


|
|
|
|
|
>







>
>
>
>
>
>
>
>
>
>







88388
88389
88390
88391
88392
88393
88394
88395
88396
88397
88398
88399
88400
88401
88402
88403
88404
88405
88406
88407
88408
88409
88410
88411
88412
88413
88414
88415
88416
88417
88418
88419
88420
88421
88422
88423
88424
88425
88426
88427
88428
88429
88430
88431
88432
88433
88434
88435
88436
88437
88438
88439
88440
88441
88442
88443
88444
88445
88446
88447
88448
88449
88450
88451
88452
88453
88454
  Table *pTab,       /* Table containing the row to be deleted */
  int iCur,          /* Cursor number for the table */
  int *aRegIdx       /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
){
  int i;
  Index *pIdx;
  int r1;
  int iPartIdxLabel;
  Vdbe *v = pParse->pVdbe;

  for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
    if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
    r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0, &iPartIdxLabel);
    sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nColumn+1);
    sqlite3VdbeResolveLabel(v, iPartIdxLabel);
  }
}

/*
** Generate code that will assemble an index key and put it in register
** regOut.  The key with be for index pIdx which is an index on pTab.
** iCur is the index of a cursor open on the pTab table and pointing to
** the entry that needs indexing.
**
** Return a register number which is the first in a block of
** registers that holds the elements of the index key.  The
** block of registers has already been deallocated by the time
** this routine returns.
**
** If *piPartIdxLabel is not NULL, fill it in with a label and jump
** to that label if pIdx is a partial index that should be skipped.
** A partial index should be skipped if its WHERE clause evaluates
** to false or null.  If pIdx is not a partial index, *piPartIdxLabel
** will be set to zero which is an empty label that is ignored by
** sqlite3VdbeResolveLabel().
*/
SQLITE_PRIVATE int sqlite3GenerateIndexKey(
  Parse *pParse,       /* Parsing context */
  Index *pIdx,         /* The index for which to generate a key */
  int iCur,            /* Cursor number for the pIdx->pTable table */
  int regOut,          /* Write the new index key to this register */
  int doMakeRec,       /* Run the OP_MakeRecord instruction if true */
  int *piPartIdxLabel  /* OUT: Jump to this label to skip partial index */
){
  Vdbe *v = pParse->pVdbe;
  int j;
  Table *pTab = pIdx->pTable;
  int regBase;
  int nCol;

  if( piPartIdxLabel ){
    if( pIdx->pPartIdxWhere ){
      *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
      pParse->iPartIdxTab = iCur;
      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
                         SQLITE_JUMPIFNULL);
    }else{
      *piPartIdxLabel = 0;
    }
  }
  nCol = pIdx->nColumn;
  regBase = sqlite3GetTempRange(pParse, nCol+1);
  sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
  for(j=0; j<nCol; j++){
    int idx = pIdx->aiColumn[j];
    if( idx==pTab->iPKey ){
      sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
88705
88706
88707
88708
88709
88710
88711
88712
88713
88714
88715
88716
88717
88718
88719
88720
88721
    sqlite3StrAccumAppend(pAccum, zVal, nVal);
  }
}
static void groupConcatFinalize(sqlite3_context *context){
  StrAccum *pAccum;
  pAccum = sqlite3_aggregate_context(context, 0);
  if( pAccum ){
    if( pAccum->tooBig ){
      sqlite3_result_error_toobig(context);
    }else if( pAccum->mallocFailed ){
      sqlite3_result_error_nomem(context);
    }else{    
      sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
                          sqlite3_free);
    }
  }
}







|

|







89993
89994
89995
89996
89997
89998
89999
90000
90001
90002
90003
90004
90005
90006
90007
90008
90009
    sqlite3StrAccumAppend(pAccum, zVal, nVal);
  }
}
static void groupConcatFinalize(sqlite3_context *context){
  StrAccum *pAccum;
  pAccum = sqlite3_aggregate_context(context, 0);
  if( pAccum ){
    if( pAccum->accError==STRACCUM_TOOBIG ){
      sqlite3_result_error_toobig(context);
    }else if( pAccum->accError==STRACCUM_NOMEM ){
      sqlite3_result_error_nomem(context);
    }else{    
      sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
                          sqlite3_free);
    }
  }
}
88897
88898
88899
88900
88901
88902
88903



88904
88905
88906
88907
88908
88909
88910

  for(i=0; i<ArraySize(aBuiltinFunc); i++){
    sqlite3FuncDefInsert(pHash, &aFunc[i]);
  }
  sqlite3RegisterDateTimeFunctions();
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions();



#endif
}

/************** End of func.c ************************************************/
/************** Begin file fkey.c ********************************************/
/*
**







>
>
>







90185
90186
90187
90188
90189
90190
90191
90192
90193
90194
90195
90196
90197
90198
90199
90200
90201

  for(i=0; i<ArraySize(aBuiltinFunc); i++){
    sqlite3FuncDefInsert(pHash, &aFunc[i]);
  }
  sqlite3RegisterDateTimeFunctions();
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions();
#endif
#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
  sqlite3AnalyzeFunctions();
#endif
}

/************** End of func.c ************************************************/
/************** Begin file fkey.c ********************************************/
/*
**
91516
91517
91518
91519
91520
91521
91522

91523
91524









91525
91526
91527
91528
91529
91530
91531
91532
91533
91534
91535
91536
91537
91538
91539
91540
91541
91542
91543
91544

91545
91546
91547
91548
91549
91550
91551
  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */
  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
    int regIdx;
    int regR;


    if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */










    /* Create a key for accessing the index entry */
    regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
    for(i=0; i<pIdx->nColumn; i++){
      int idx = pIdx->aiColumn[i];
      if( idx==pTab->iPKey ){
        sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
      }else{
        sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
      }
    }
    sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
    sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);

    /* Find out what action to take in case there is an indexing conflict */
    onError = pIdx->onError;
    if( onError==OE_None ){ 
      sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);

      continue;  /* pIdx is not a UNIQUE index */
    }
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }







>


>
>
>
>
>
>
>
>
>




















>







92807
92808
92809
92810
92811
92812
92813
92814
92815
92816
92817
92818
92819
92820
92821
92822
92823
92824
92825
92826
92827
92828
92829
92830
92831
92832
92833
92834
92835
92836
92837
92838
92839
92840
92841
92842
92843
92844
92845
92846
92847
92848
92849
92850
92851
92852
92853
  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
  ** Add the new records to the indices as we go.
  */
  for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
    int regIdx;
    int regR;
    int addrSkipRow = 0;

    if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */

    if( pIdx->pPartIdxWhere ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
      addrSkipRow = sqlite3VdbeMakeLabel(v);
      pParse->ckBase = regData;
      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrSkipRow,
                         SQLITE_JUMPIFNULL);
      pParse->ckBase = 0;
    }

    /* Create a key for accessing the index entry */
    regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
    for(i=0; i<pIdx->nColumn; i++){
      int idx = pIdx->aiColumn[i];
      if( idx==pTab->iPKey ){
        sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
      }else{
        sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
      }
    }
    sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
    sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);

    /* Find out what action to take in case there is an indexing conflict */
    onError = pIdx->onError;
    if( onError==OE_None ){ 
      sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
      sqlite3VdbeResolveLabel(v, addrSkipRow);
      continue;  /* pIdx is not a UNIQUE index */
    }
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
91607
91608
91609
91610
91611
91612
91613

91614
91615
91616
91617
91618
91619
91620
            pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
        );
        seenReplace = 1;
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j3);

    sqlite3ReleaseTempReg(pParse, regR);
  }
  
  if( pbMayReplace ){
    *pbMayReplace = seenReplace;
  }
}







>







92909
92910
92911
92912
92913
92914
92915
92916
92917
92918
92919
92920
92921
92922
92923
            pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
        );
        seenReplace = 1;
        break;
      }
    }
    sqlite3VdbeJumpHere(v, j3);
    sqlite3VdbeResolveLabel(v, addrSkipRow);
    sqlite3ReleaseTempReg(pParse, regR);
  }
  
  if( pbMayReplace ){
    *pbMayReplace = seenReplace;
  }
}
91636
91637
91638
91639
91640
91641
91642
91643
91644
91645
91646
91647
91648
91649
91650
91651
91652
91653
91654



91655
91656
91657
91658
91659
91660
91661
  int *aRegIdx,       /* Register used by each index.  0 for unused indices */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int appendBias,     /* True if this is likely to be an append */
  int useSeekResult   /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
  int i;
  Vdbe *v;
  int nIdx;
  Index *pIdx;
  u8 pik_flags;
  int regData;
  int regRec;

  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  for(i=nIdx-1; i>=0; i--){
    if( aRegIdx[i]==0 ) continue;



    sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
    if( useSeekResult ){
      sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
    }
  }
  regData = regRowid + 1;
  regRec = sqlite3GetTempReg(pParse);







<








|
<

>
>
>







92939
92940
92941
92942
92943
92944
92945

92946
92947
92948
92949
92950
92951
92952
92953
92954

92955
92956
92957
92958
92959
92960
92961
92962
92963
92964
92965
  int *aRegIdx,       /* Register used by each index.  0 for unused indices */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int appendBias,     /* True if this is likely to be an append */
  int useSeekResult   /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
  int i;
  Vdbe *v;

  Index *pIdx;
  u8 pik_flags;
  int regData;
  int regRec;

  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){

    if( aRegIdx[i]==0 ) continue;
    if( pIdx->pPartIdxWhere ){
      sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
    }
    sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
    if( useSeekResult ){
      sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
    }
  }
  regData = regRowid + 1;
  regRec = sqlite3GetTempReg(pParse);
91749
91750
91751
91752
91753
91754
91755

91756
91757
91758
91759
91760
91761
91762
** for index pDest in an insert transfer optimization.  The rules
** for a compatible index:
**
**    *   The index is over the same set of columns
**    *   The same DESC and ASC markings occurs on all columns
**    *   The same onError processing (OE_Abort, OE_Ignore, etc)
**    *   The same collating sequence on each column

*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
  int i;
  assert( pDest && pSrc );
  assert( pDest->pTable!=pSrc->pTable );
  if( pDest->nColumn!=pSrc->nColumn ){
    return 0;   /* Different number of columns */







>







93053
93054
93055
93056
93057
93058
93059
93060
93061
93062
93063
93064
93065
93066
93067
** for index pDest in an insert transfer optimization.  The rules
** for a compatible index:
**
**    *   The index is over the same set of columns
**    *   The same DESC and ASC markings occurs on all columns
**    *   The same onError processing (OE_Abort, OE_Ignore, etc)
**    *   The same collating sequence on each column
**    *   The index has the exact same WHERE clause
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
  int i;
  assert( pDest && pSrc );
  assert( pDest->pTable!=pSrc->pTable );
  if( pDest->nColumn!=pSrc->nColumn ){
    return 0;   /* Different number of columns */
91770
91771
91772
91773
91774
91775
91776



91777
91778
91779
91780
91781
91782
91783
    }
    if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
      return 0;   /* Different sort orders */
    }
    if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
      return 0;   /* Different collating sequences */
    }



  }

  /* If no test above fails then the indices must be compatible */
  return 1;
}

/*







>
>
>







93075
93076
93077
93078
93079
93080
93081
93082
93083
93084
93085
93086
93087
93088
93089
93090
93091
    }
    if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
      return 0;   /* Different sort orders */
    }
    if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
      return 0;   /* Different collating sequences */
    }
  }
  if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
    return 0;     /* Different WHERE clauses */
  }

  /* If no test above fails then the indices must be compatible */
  return 1;
}

/*
91926
91927
91928
91929
91930
91931
91932
91933
91934
91935
91936
91937
91938
91939
91940
      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
    }
    if( pSrcIdx==0 ){
      return 0;    /* pDestIdx has no corresponding index in pSrc */
    }
  }
#ifndef SQLITE_OMIT_CHECK
  if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){
    return 0;   /* Tables have different CHECK constraints.  Ticket #2252 */
  }
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
  /* Disallow the transfer optimization if the destination table constains
  ** any foreign key constraints.  This is more restrictive than necessary.
  ** But the main beneficiary of the transfer optimization is the VACUUM 







|







93234
93235
93236
93237
93238
93239
93240
93241
93242
93243
93244
93245
93246
93247
93248
      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
    }
    if( pSrcIdx==0 ){
      return 0;    /* pDestIdx has no corresponding index in pSrc */
    }
  }
#ifndef SQLITE_OMIT_CHECK
  if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
    return 0;   /* Tables have different CHECK constraints.  Ticket #2252 */
  }
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
  /* Disallow the transfer optimization if the destination table constains
  ** any foreign key constraints.  This is more restrictive than necessary.
  ** But the main beneficiary of the transfer optimization is the VACUUM 
93596
93597
93598
93599
93600
93601
93602






























93603
93604
93605
93606
93607
93608
93609
93610
93611
93612
93613
93614
93615
93616
93617
93618
93619
93620
93621

93622
93623
93624
93625
93626
93627
93628
    memcpy(pI64, &value, sizeof(value));
  }
  sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
  sqlite3VdbeSetNumCols(v, 1);
  sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
  sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
}































#ifndef SQLITE_OMIT_FLAG_PRAGMAS
/*
** Check to see if zRight and zLeft refer to a pragma that queries
** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
** Also, implement the pragma.
*/
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
  static const struct sPragmaType {
    const char *zName;  /* Name of the pragma */
    int mask;           /* Mask for the db->flags value */
  } aPragma[] = {
    { "full_column_names",        SQLITE_FullColNames  },
    { "short_column_names",       SQLITE_ShortColNames },
    { "count_changes",            SQLITE_CountRows     },
    { "empty_result_callbacks",   SQLITE_NullCallback  },
    { "legacy_file_format",       SQLITE_LegacyFileFmt },
    { "fullfsync",                SQLITE_FullFSync     },
    { "checkpoint_fullfsync",     SQLITE_CkptFullFSync },

    { "reverse_unordered_selects", SQLITE_ReverseOrder  },
    { "query_only",               SQLITE_QueryOnly     },
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    { "automatic_index",          SQLITE_AutoIndex     },
#endif
#ifdef SQLITE_DEBUG
    { "sql_trace",                SQLITE_SqlTrace      },







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



















>







94904
94905
94906
94907
94908
94909
94910
94911
94912
94913
94914
94915
94916
94917
94918
94919
94920
94921
94922
94923
94924
94925
94926
94927
94928
94929
94930
94931
94932
94933
94934
94935
94936
94937
94938
94939
94940
94941
94942
94943
94944
94945
94946
94947
94948
94949
94950
94951
94952
94953
94954
94955
94956
94957
94958
94959
94960
94961
94962
94963
94964
94965
94966
94967
    memcpy(pI64, &value, sizeof(value));
  }
  sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
  sqlite3VdbeSetNumCols(v, 1);
  sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
  sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
}


/*
** Set the safety_level and pager flags for pager iDb.  Or if iDb<0
** set these values for all pagers.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
static void setAllPagerFlags(sqlite3 *db){
  if( db->autoCommit ){
    Db *pDb = db->aDb;
    int n = db->nDb;
    assert( SQLITE_FullFSync==PAGER_FULLFSYNC );
    assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC );
    assert( SQLITE_CacheSpill==PAGER_CACHESPILL );
    assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL)
             ==  PAGER_FLAGS_MASK );
    assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level );
    while( (n--) > 0 ){
      if( pDb->pBt ){
        sqlite3BtreeSetPagerFlags(pDb->pBt,
                 pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) );
      }
      pDb++;
    }
  }
}
#else
# define setAllPagerFlags(X)  /* no-op */
#endif


#ifndef SQLITE_OMIT_FLAG_PRAGMAS
/*
** Check to see if zRight and zLeft refer to a pragma that queries
** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
** Also, implement the pragma.
*/
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
  static const struct sPragmaType {
    const char *zName;  /* Name of the pragma */
    int mask;           /* Mask for the db->flags value */
  } aPragma[] = {
    { "full_column_names",        SQLITE_FullColNames  },
    { "short_column_names",       SQLITE_ShortColNames },
    { "count_changes",            SQLITE_CountRows     },
    { "empty_result_callbacks",   SQLITE_NullCallback  },
    { "legacy_file_format",       SQLITE_LegacyFileFmt },
    { "fullfsync",                SQLITE_FullFSync     },
    { "checkpoint_fullfsync",     SQLITE_CkptFullFSync },
    { "cache_spill",              SQLITE_CacheSpill    },
    { "reverse_unordered_selects", SQLITE_ReverseOrder  },
    { "query_only",               SQLITE_QueryOnly     },
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    { "automatic_index",          SQLITE_AutoIndex     },
#endif
#ifdef SQLITE_DEBUG
    { "sql_trace",                SQLITE_SqlTrace      },
94069
94070
94071
94072
94073
94074
94075
94076
94077
94078
94079
94080
94081
94082
94083
  **
  ** Get or set the size limit on rollback journal files.
  */
  if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){
    Pager *pPager = sqlite3BtreePager(pDb->pBt);
    i64 iLimit = -2;
    if( zRight ){
      sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8);
      if( iLimit<-1 ) iLimit = -1;
    }
    iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
    returnSingleInt(pParse, "journal_size_limit", iLimit);
  }else

#endif /* SQLITE_OMIT_PAGER_PRAGMAS */







|







95408
95409
95410
95411
95412
95413
95414
95415
95416
95417
95418
95419
95420
95421
95422
  **
  ** Get or set the size limit on rollback journal files.
  */
  if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){
    Pager *pPager = sqlite3BtreePager(pDb->pBt);
    i64 iLimit = -2;
    if( zRight ){
      sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8);
      if( iLimit<-1 ) iLimit = -1;
    }
    iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
    returnSingleInt(pParse, "journal_size_limit", iLimit);
  }else

#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
94203
94204
94205
94206
94207
94208
94209

94210
94211
94212
94213
94214
94215
94216
94217
94218
94219
94220
94221
94222
94223
94224
94225

94226
94227
94228
94229
94230
94231
94232
  **
  ** This value is advisory.  The underlying VFS is free to memory map
  ** as little or as much as it wants.  Except, if N is set to 0 then the
  ** upper layers will never invoke the xFetch interfaces to the VFS.
  */
  if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){
    sqlite3_int64 sz;

    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
    if( zRight ){
      int ii;
      sqlite3Atoi64(zRight, &sz, 1000, SQLITE_UTF8);
      if( sz<0 ) sz = sqlite3GlobalConfig.szMmap;
      if( pId2->n==0 ) db->szMmap = sz;
      for(ii=db->nDb-1; ii>=0; ii--){
        if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
          sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz);
        }
      }
    }
    sz = -1;
    rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz);
#if SQLITE_MAX_MMAP_SIZE==0
    sz = 0;

#endif
    if( rc==SQLITE_OK ){
      returnSingleInt(pParse, "mmap_size", sz);
    }else if( rc!=SQLITE_NOTFOUND ){
      pParse->nErr++;
      pParse->rc = rc;
    }







>



|










|

>







95542
95543
95544
95545
95546
95547
95548
95549
95550
95551
95552
95553
95554
95555
95556
95557
95558
95559
95560
95561
95562
95563
95564
95565
95566
95567
95568
95569
95570
95571
95572
95573
  **
  ** This value is advisory.  The underlying VFS is free to memory map
  ** as little or as much as it wants.  Except, if N is set to 0 then the
  ** upper layers will never invoke the xFetch interfaces to the VFS.
  */
  if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){
    sqlite3_int64 sz;
#if SQLITE_MAX_MMAP_SIZE>0
    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
    if( zRight ){
      int ii;
      sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8);
      if( sz<0 ) sz = sqlite3GlobalConfig.szMmap;
      if( pId2->n==0 ) db->szMmap = sz;
      for(ii=db->nDb-1; ii>=0; ii--){
        if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
          sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz);
        }
      }
    }
    sz = -1;
    rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz);
#else
    sz = 0;
    rc = SQLITE_OK;
#endif
    if( rc==SQLITE_OK ){
      returnSingleInt(pParse, "mmap_size", sz);
    }else if( rc!=SQLITE_NOTFOUND ){
      pParse->nErr++;
      pParse->rc = rc;
    }
94405
94406
94407
94408
94409
94410
94411

94412
94413
94414
94415
94416
94417
94418
94419
94420
94421
94422
94423
94424
94425
94426
94427
      returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
    }else{
      if( !db->autoCommit ){
        sqlite3ErrorMsg(pParse, 
            "Safety level may not be changed inside a transaction");
      }else{
        pDb->safety_level = getSafetyLevel(zRight,0,1)+1;

      }
    }
  }else
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */

#ifndef SQLITE_OMIT_FLAG_PRAGMAS
  if( flagPragma(pParse, zLeft, zRight) ){
    /* The flagPragma() subroutine also generates any necessary code
    ** there is nothing more to do here */
  }else
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */

#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
  /*
  **   PRAGMA table_info(<table>)
  **







>







|
<







95746
95747
95748
95749
95750
95751
95752
95753
95754
95755
95756
95757
95758
95759
95760
95761

95762
95763
95764
95765
95766
95767
95768
      returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
    }else{
      if( !db->autoCommit ){
        sqlite3ErrorMsg(pParse, 
            "Safety level may not be changed inside a transaction");
      }else{
        pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
        setAllPagerFlags(db);
      }
    }
  }else
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */

#ifndef SQLITE_OMIT_FLAG_PRAGMAS
  if( flagPragma(pParse, zLeft, zRight) ){
    setAllPagerFlags(db);

  }else
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */

#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
  /*
  **   PRAGMA table_info(<table>)
  **
94839
94840
94841
94842
94843
94844
94845
94846
94847
94848
94849
94850
94851
94852
94853
94854
94855
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
          cnt++;
        }
      }

      /* Make sure sufficient number of registers have been allocated */
      if( pParse->nMem < cnt+4 ){
        pParse->nMem = cnt+4;
      }

      /* Do the b-tree integrity checks */
      sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
      sqlite3VdbeChangeP5(v, (u8)i);
      addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
      sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
         sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),







<
|
<







96180
96181
96182
96183
96184
96185
96186

96187

96188
96189
96190
96191
96192
96193
96194
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
          cnt++;
        }
      }

      /* Make sure sufficient number of registers have been allocated */

      pParse->nMem = MAX( pParse->nMem, cnt+7 );


      /* Do the b-tree integrity checks */
      sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
      sqlite3VdbeChangeP5(v, (u8)i);
      addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
      sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
         sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
94866
94867
94868
94869
94870
94871
94872

94873

94874


94875
94876
94877
94878
94879
94880
94881
94882
94883
94884
94885
94886
94887
94888
94889
94890
94891
94892
94893

94894
94895
94896
94897
94898
94899
94900

94901
94902
94903



94904
94905
94906
94907
94908
94909
94910
94911
94912
94913
94914
94915
94916
94917
94918
94919
94920
94921
94922
94923
94924
94925
94926
94927
94928
94929

94930
94931
94932
94933
94934
94935
94936
        Index *pIdx;
        int loopTop;

        if( pTab->pIndex==0 ) continue;
        addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);  /* Stop if out of errors */
        sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
        sqlite3VdbeJumpHere(v, addr);

        sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);

        sqlite3VdbeAddOp2(v, OP_Integer, 0, 2);  /* reg(2) will count entries */


        loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
        sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1);   /* increment entry count */
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          int jmp2;
          int r1;
          static const VdbeOpList idxErr[] = {
            { OP_AddImm,      1, -1,  0},
            { OP_String8,     0,  3,  0},    /* 1 */
            { OP_Rowid,       1,  4,  0},
            { OP_String8,     0,  5,  0},    /* 3 */
            { OP_String8,     0,  6,  0},    /* 4 */
            { OP_Concat,      4,  3,  3},
            { OP_Concat,      5,  3,  3},
            { OP_Concat,      6,  3,  3},
            { OP_ResultRow,   3,  1,  0},
            { OP_IfPos,       1,  0,  0},    /* 9 */
            { OP_Halt,        0,  0,  0},
          };
          r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0);

          jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
          sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
          sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
          sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
          sqlite3VdbeJumpHere(v, addr+9);
          sqlite3VdbeJumpHere(v, jmp2);

        }
        sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
        sqlite3VdbeJumpHere(v, loopTop);



        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          static const VdbeOpList cntIdx[] = {
             { OP_Integer,      0,  3,  0},
             { OP_Rewind,       0,  0,  0},  /* 1 */
             { OP_AddImm,       3,  1,  0},
             { OP_Next,         0,  0,  0},  /* 3 */
             { OP_Eq,           2,  0,  3},  /* 4 */
             { OP_AddImm,       1, -1,  0},
             { OP_String8,      0,  2,  0},  /* 6 */
             { OP_String8,      0,  3,  0},  /* 7 */
             { OP_Concat,       3,  2,  2},
             { OP_ResultRow,    2,  1,  0},
          };
          addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
          sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
          sqlite3VdbeJumpHere(v, addr);
          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
          sqlite3VdbeChangeP1(v, addr+1, j+2);
          sqlite3VdbeChangeP2(v, addr+1, addr+4);
          sqlite3VdbeChangeP1(v, addr+3, j+2);
          sqlite3VdbeChangeP2(v, addr+3, addr+2);
          sqlite3VdbeJumpHere(v, addr+4);
          sqlite3VdbeChangeP4(v, addr+6, 
                     "wrong # of entries in index ", P4_STATIC);
          sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT);
        }

      } 
    }
    addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
    sqlite3VdbeChangeP2(v, addr, -mxErr);
    sqlite3VdbeJumpHere(v, addr+1);
    sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
  }else







>

>
|
>
>
|
<

|














|
>







>

|
|
>
>
>

<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
<
|
|
|
|
<
<

>







96205
96206
96207
96208
96209
96210
96211
96212
96213
96214
96215
96216
96217
96218

96219
96220
96221
96222
96223
96224
96225
96226
96227
96228
96229
96230
96231
96232
96233
96234
96235
96236
96237
96238
96239
96240
96241
96242
96243
96244
96245
96246
96247
96248
96249
96250
96251












96252
96253
96254
96255
96256

96257
96258
96259
96260


96261
96262
96263
96264
96265
96266
96267
96268
96269
        Index *pIdx;
        int loopTop;

        if( pTab->pIndex==0 ) continue;
        addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);  /* Stop if out of errors */
        sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
        sqlite3VdbeJumpHere(v, addr);
        sqlite3ExprCacheClear(pParse);
        sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          sqlite3VdbeAddOp2(v, OP_Integer, 0, 7+j); /* index entries counter */
        }
        pParse->nMem = MAX(pParse->nMem, 7+j);
        loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0) + 1;

        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          int jmp2, jmp3;
          int r1;
          static const VdbeOpList idxErr[] = {
            { OP_AddImm,      1, -1,  0},
            { OP_String8,     0,  3,  0},    /* 1 */
            { OP_Rowid,       1,  4,  0},
            { OP_String8,     0,  5,  0},    /* 3 */
            { OP_String8,     0,  6,  0},    /* 4 */
            { OP_Concat,      4,  3,  3},
            { OP_Concat,      5,  3,  3},
            { OP_Concat,      6,  3,  3},
            { OP_ResultRow,   3,  1,  0},
            { OP_IfPos,       1,  0,  0},    /* 9 */
            { OP_Halt,        0,  0,  0},
          };
          r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3);
          sqlite3VdbeAddOp2(v, OP_AddImm, 7+j, 1);  /* increment entry count */
          jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
          sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
          sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
          sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
          sqlite3VdbeJumpHere(v, addr+9);
          sqlite3VdbeJumpHere(v, jmp2);
          sqlite3VdbeResolveLabel(v, jmp3);
        }
        sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop);
        sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
        sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, 
                     "wrong # of entries in index ", P4_STATIC);
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){












          addr = sqlite3VdbeCurrentAddr(v);
          sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
          sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
          sqlite3VdbeAddOp2(v, OP_Count, j+2, 3);
          sqlite3VdbeAddOp3(v, OP_Eq, 7+j, addr+8, 3);

          sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
          sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
          sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);


        }
#endif /* SQLITE_OMIT_BTREECOUNT */
      } 
    }
    addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
    sqlite3VdbeChangeP2(v, addr, -mxErr);
    sqlite3VdbeJumpHere(v, addr+1);
    sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
  }else
95252
95253
95254
95255
95256
95257
95258
95259
95260
95261
95262
95263
95264
95265
95266
95267
95268
95269
95270
95271
95272
95273
95274
95275
95276
#endif
  }else
#endif

 
  {/* Empty ELSE clause */}

  /*
  ** Reset the safety level, in case the fullfsync flag or synchronous
  ** setting changed.
  */
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
  if( db->autoCommit ){
    sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
               (db->flags&SQLITE_FullFSync)!=0,
               (db->flags&SQLITE_CkptFullFSync)!=0);
  }
#endif
pragma_out:
  sqlite3DbFree(db, zLeft);
  sqlite3DbFree(db, zRight);
}

#endif /* SQLITE_OMIT_PRAGMA */








<
<
<
<
<
<
<
<
<
<
<







96585
96586
96587
96588
96589
96590
96591











96592
96593
96594
96595
96596
96597
96598
#endif
  }else
#endif

 
  {/* Empty ELSE clause */}












pragma_out:
  sqlite3DbFree(db, zLeft);
  sqlite3DbFree(db, zRight);
}

#endif /* SQLITE_OMIT_PRAGMA */

96949
96950
96951
96952
96953
96954
96955



















96956
96957
96958
96959
96960
96961
96962
96963
96964
96965
96966
96967
96968
96969
96970
96971
96972
96973
96974
96975
96976

96977
96978
96979
96980
96981
96982
96983
96984
96985
96986
96987
96988
96989
96990
96991
96992
96993
96994
96995
96996
96997
96998
  ** there is a sorter, in which case the sorter has already limited
  ** the output for us.
  */
  if( pOrderBy==0 && p->iLimit ){
    sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
  }
}




















/*
** Given an expression list, generate a KeyInfo structure that records
** the collating sequence for each expression in that expression list.
**
** If the ExprList is an ORDER BY or GROUP BY clause then the resulting
** KeyInfo structure is appropriate for initializing a virtual index to
** implement that clause.  If the ExprList is the result set of a SELECT
** then the KeyInfo structure is appropriate for initializing a virtual
** index to implement a DISTINCT test.
**
** Space to hold the KeyInfo structure is obtain from malloc.  The calling
** function is responsible for seeing that this structure is eventually
** freed.  Add the KeyInfo structure to the P4 field of an opcode using
** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
*/
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
  sqlite3 *db = pParse->db;
  int nExpr;
  KeyInfo *pInfo;
  struct ExprList_item *pItem;

  int i;

  nExpr = pList->nExpr;
  pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
  if( pInfo ){
    pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
    pInfo->nField = (u16)nExpr;
    pInfo->enc = ENC(db);
    pInfo->db = db;
    for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
      CollSeq *pColl;
      pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
      if( !pColl ){
        pColl = db->pDfltColl;
      }
      pInfo->aColl[i] = pColl;
      pInfo->aSortOrder[i] = pItem->sortOrder;
    }
  }
  return pInfo;
}








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

















<



>



|

<
<
<
<



<
|
<







98271
98272
98273
98274
98275
98276
98277
98278
98279
98280
98281
98282
98283
98284
98285
98286
98287
98288
98289
98290
98291
98292
98293
98294
98295
98296
98297
98298
98299
98300
98301
98302
98303
98304
98305
98306
98307
98308
98309
98310
98311
98312
98313

98314
98315
98316
98317
98318
98319
98320
98321
98322




98323
98324
98325

98326

98327
98328
98329
98330
98331
98332
98333
  ** there is a sorter, in which case the sorter has already limited
  ** the output for us.
  */
  if( pOrderBy==0 && p->iLimit ){
    sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
  }
}

/*
** Allocate a KeyInfo object sufficient for an index of N columns.
**
** Actually, always allocate one extra column for the rowid at the end
** of the index.  So the KeyInfo returned will have space sufficient for
** N+1 columns.
*/
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N){
  KeyInfo *p = sqlite3DbMallocZero(db, 
                   sizeof(KeyInfo) + (N+1)*(sizeof(CollSeq*)+1));
  if( p ){
    p->aSortOrder = (u8*)&p->aColl[N+1];
    p->nField = (u16)N;
    p->enc = ENC(db);
    p->db = db;
  }
  return p;
}

/*
** Given an expression list, generate a KeyInfo structure that records
** the collating sequence for each expression in that expression list.
**
** If the ExprList is an ORDER BY or GROUP BY clause then the resulting
** KeyInfo structure is appropriate for initializing a virtual index to
** implement that clause.  If the ExprList is the result set of a SELECT
** then the KeyInfo structure is appropriate for initializing a virtual
** index to implement a DISTINCT test.
**
** Space to hold the KeyInfo structure is obtain from malloc.  The calling
** function is responsible for seeing that this structure is eventually
** freed.  Add the KeyInfo structure to the P4 field of an opcode using
** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
*/
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){

  int nExpr;
  KeyInfo *pInfo;
  struct ExprList_item *pItem;
  sqlite3 *db = pParse->db;
  int i;

  nExpr = pList->nExpr;
  pInfo = sqlite3KeyInfoAlloc(db, nExpr);
  if( pInfo ){




    for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
      CollSeq *pColl;
      pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);

      if( !pColl ) pColl = db->pDfltColl;

      pInfo->aColl[i] = pColl;
      pInfo->aSortOrder[i] = pItem->sortOrder;
    }
  }
  return pInfo;
}

98090
98091
98092
98093
98094
98095
98096
98097
98098
98099
98100
98101
98102
98103
98104
98105
98106
98107
98108
98109
98110
98111
98112
98113
98114
98115
98116
98117
98118
98119
98120
    KeyInfo *pKeyInfo;            /* Collating sequence for the result set */
    Select *pLoop;                /* For looping through SELECT statements */
    CollSeq **apColl;             /* For looping through pKeyInfo->aColl[] */
    int nCol;                     /* Number of columns in result set */

    assert( p->pRightmost==p );
    nCol = p->pEList->nExpr;
    pKeyInfo = sqlite3DbMallocZero(db,
                       sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
    if( !pKeyInfo ){
      rc = SQLITE_NOMEM;
      goto multi_select_end;
    }

    pKeyInfo->enc = ENC(db);
    pKeyInfo->nField = (u16)nCol;

    for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
      *apColl = multiSelectCollSeq(pParse, p, i);
      if( 0==*apColl ){
        *apColl = db->pDfltColl;
      }
    }
    pKeyInfo->aSortOrder = (u8*)apColl;

    for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
      for(i=0; i<2; i++){
        int addr = pLoop->addrOpenEphm[i];
        if( addr<0 ){
          /* If [0] is unused then [1] is also unused.  So we can
          ** always safely abort as soon as the first unused slot is found */







|
<




<
<
<
<






<







99425
99426
99427
99428
99429
99430
99431
99432

99433
99434
99435
99436




99437
99438
99439
99440
99441
99442

99443
99444
99445
99446
99447
99448
99449
    KeyInfo *pKeyInfo;            /* Collating sequence for the result set */
    Select *pLoop;                /* For looping through SELECT statements */
    CollSeq **apColl;             /* For looping through pKeyInfo->aColl[] */
    int nCol;                     /* Number of columns in result set */

    assert( p->pRightmost==p );
    nCol = p->pEList->nExpr;
    pKeyInfo = sqlite3KeyInfoAlloc(db, nCol);

    if( !pKeyInfo ){
      rc = SQLITE_NOMEM;
      goto multi_select_end;
    }




    for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
      *apColl = multiSelectCollSeq(pParse, p, i);
      if( 0==*apColl ){
        *apColl = db->pDfltColl;
      }
    }


    for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
      for(i=0; i<2; i++){
        int addr = pLoop->addrOpenEphm[i];
        if( addr<0 ){
          /* If [0] is unused then [1] is also unused.  So we can
          ** always safely abort as soon as the first unused slot is found */
98475
98476
98477
98478
98479
98480
98481
98482
98483
98484
98485
98486
98487
98488
98489
98490
98491
98492
98493
98494
  aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
  if( aPermute ){
    struct ExprList_item *pItem;
    for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
      assert( pItem->iOrderByCol>0  && pItem->iOrderByCol<=p->pEList->nExpr );
      aPermute[i] = pItem->iOrderByCol - 1;
    }
    pKeyMerge =
      sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
    if( pKeyMerge ){
      pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
      pKeyMerge->nField = (u16)nOrderBy;
      pKeyMerge->enc = ENC(db);
      for(i=0; i<nOrderBy; i++){
        CollSeq *pColl;
        Expr *pTerm = pOrderBy->a[i].pExpr;
        if( pTerm->flags & EP_Collate ){
          pColl = sqlite3ExprCollSeq(pParse, pTerm);
        }else{
          pColl = multiSelectCollSeq(pParse, p, aPermute[i]);







|
<

<
<
<







99804
99805
99806
99807
99808
99809
99810
99811

99812



99813
99814
99815
99816
99817
99818
99819
  aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
  if( aPermute ){
    struct ExprList_item *pItem;
    for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
      assert( pItem->iOrderByCol>0  && pItem->iOrderByCol<=p->pEList->nExpr );
      aPermute[i] = pItem->iOrderByCol - 1;
    }
    pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy);

    if( pKeyMerge ){



      for(i=0; i<nOrderBy; i++){
        CollSeq *pColl;
        Expr *pTerm = pOrderBy->a[i].pExpr;
        if( pTerm->flags & EP_Collate ){
          pColl = sqlite3ExprCollSeq(pParse, pTerm);
        }else{
          pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
98517
98518
98519
98520
98521
98522
98523
98524
98525
98526
98527
98528
98529
98530
98531
98532
98533
98534
98535
98536
    regPrev = 0;
  }else{
    int nExpr = p->pEList->nExpr;
    assert( nOrderBy>=nExpr || db->mallocFailed );
    regPrev = pParse->nMem+1;
    pParse->nMem += nExpr+1;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
    pKeyDup = sqlite3DbMallocZero(db,
                  sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
    if( pKeyDup ){
      pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
      pKeyDup->nField = (u16)nExpr;
      pKeyDup->enc = ENC(db);
      for(i=0; i<nExpr; i++){
        pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
        pKeyDup->aSortOrder[i] = 0;
      }
    }
  }
 







|
<

<
<
<







99842
99843
99844
99845
99846
99847
99848
99849

99850



99851
99852
99853
99854
99855
99856
99857
    regPrev = 0;
  }else{
    int nExpr = p->pEList->nExpr;
    assert( nOrderBy>=nExpr || db->mallocFailed );
    regPrev = pParse->nMem+1;
    pParse->nMem += nExpr+1;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
    pKeyDup = sqlite3KeyInfoAlloc(db, nExpr);

    if( pKeyDup ){



      for(i=0; i<nExpr; i++){
        pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
        pKeyDup->aSortOrder[i] = 0;
      }
    }
  }
 
99788
99789
99790
99791
99792
99793
99794
99795
99796
99797


99798

99799
99800
99801
99802
99803
99804
99805
** If anything goes wrong, an error message is written into pParse.
** The calling function can detect the problem by looking at pParse->nErr
** and/or pParse->db->mallocFailed.
*/
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
  Walker w;
  memset(&w, 0, sizeof(w));
  w.xSelectCallback = convertCompoundSelectToSubquery;
  w.xExprCallback = exprWalkNoop;
  w.pParse = pParse;


  sqlite3WalkSelect(&w, pSelect);

  w.xSelectCallback = selectExpander;
  sqlite3WalkSelect(&w, pSelect);
}


#ifndef SQLITE_OMIT_SUBQUERY
/*







<


>
>
|
>







101109
101110
101111
101112
101113
101114
101115

101116
101117
101118
101119
101120
101121
101122
101123
101124
101125
101126
101127
101128
** If anything goes wrong, an error message is written into pParse.
** The calling function can detect the problem by looking at pParse->nErr
** and/or pParse->db->mallocFailed.
*/
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
  Walker w;
  memset(&w, 0, sizeof(w));

  w.xExprCallback = exprWalkNoop;
  w.pParse = pParse;
  if( pParse->hasCompound ){
    w.xSelectCallback = convertCompoundSelectToSubquery;
    sqlite3WalkSelect(&w, pSelect);
  }
  w.xSelectCallback = selectExpander;
  sqlite3WalkSelect(&w, pSelect);
}


#ifndef SQLITE_OMIT_SUBQUERY
/*
100325
100326
100327
100328
100329
100330
100331
100332
100333
100334
100335
100336
100337
100338
100339
100340
100341
100342
100343
100344
100345
100346
100347
100348
100349
100350
100351
100352
100353
100354
100355
100356
100357
100358
100359
100360
  /* If there is both a GROUP BY and an ORDER BY clause and they are
  ** identical, then disable the ORDER BY clause since the GROUP BY
  ** will cause elements to come out in the correct order.  This is
  ** an optimization - the correct answer should result regardless.
  ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
  ** to disable this optimization for testing purposes.
  */
  if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
         && OptimizationEnabled(db, SQLITE_GroupByOrder) ){
    pOrderBy = 0;
  }

  /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and 
  ** if the select-list is the same as the ORDER BY list, then this query
  ** can be rewritten as a GROUP BY. In other words, this:
  **
  **     SELECT DISTINCT xyz FROM ... ORDER BY xyz
  **
  ** is transformed to:
  **
  **     SELECT xyz FROM ... GROUP BY xyz
  **
  ** The second form is preferred as a single index (or temp-table) may be 
  ** used for both the ORDER BY and DISTINCT processing. As originally 
  ** written the query must use a temp-table for at least one of the ORDER 
  ** BY and DISTINCT, and an index or separate temp-table for the other.
  */
  if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct 
   && sqlite3ExprListCompare(pOrderBy, p->pEList)==0
  ){
    p->selFlags &= ~SF_Distinct;
    p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
    pGroupBy = p->pGroupBy;
    pOrderBy = 0;
    /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
    ** the sDistinct.isTnct is still set.  Hence, isTnct represents the







|




















|







101648
101649
101650
101651
101652
101653
101654
101655
101656
101657
101658
101659
101660
101661
101662
101663
101664
101665
101666
101667
101668
101669
101670
101671
101672
101673
101674
101675
101676
101677
101678
101679
101680
101681
101682
101683
  /* If there is both a GROUP BY and an ORDER BY clause and they are
  ** identical, then disable the ORDER BY clause since the GROUP BY
  ** will cause elements to come out in the correct order.  This is
  ** an optimization - the correct answer should result regardless.
  ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
  ** to disable this optimization for testing purposes.
  */
  if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0
         && OptimizationEnabled(db, SQLITE_GroupByOrder) ){
    pOrderBy = 0;
  }

  /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and 
  ** if the select-list is the same as the ORDER BY list, then this query
  ** can be rewritten as a GROUP BY. In other words, this:
  **
  **     SELECT DISTINCT xyz FROM ... ORDER BY xyz
  **
  ** is transformed to:
  **
  **     SELECT xyz FROM ... GROUP BY xyz
  **
  ** The second form is preferred as a single index (or temp-table) may be 
  ** used for both the ORDER BY and DISTINCT processing. As originally 
  ** written the query must use a temp-table for at least one of the ORDER 
  ** BY and DISTINCT, and an index or separate temp-table for the other.
  */
  if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct 
   && sqlite3ExprListCompare(pOrderBy, p->pEList, -1)==0
  ){
    p->selFlags &= ~SF_Distinct;
    p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
    pGroupBy = p->pGroupBy;
    pOrderBy = 0;
    /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
    ** the sDistinct.isTnct is still set.  Hence, isTnct represents the
102388
102389
102390
102391
102392
102393
102394
102395
102396
102397
102398
102399
102400
102401
102402
** on register iReg. This is used when an equivalent integer value is 
** stored in place of an 8-byte floating point value in order to save 
** space.
*/
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
  assert( pTab!=0 );
  if( !pTab->pSelect ){
    sqlite3_value *pValue;
    u8 enc = ENC(sqlite3VdbeDb(v));
    Column *pCol = &pTab->aCol[i];
    VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
    assert( i<pTab->nCol );
    sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, 
                         pCol->affinity, &pValue);
    if( pValue ){







|







103711
103712
103713
103714
103715
103716
103717
103718
103719
103720
103721
103722
103723
103724
103725
** on register iReg. This is used when an equivalent integer value is 
** stored in place of an 8-byte floating point value in order to save 
** space.
*/
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
  assert( pTab!=0 );
  if( !pTab->pSelect ){
    sqlite3_value *pValue = 0;
    u8 enc = ENC(sqlite3VdbeDb(v));
    Column *pCol = &pTab->aCol[i];
    VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
    assert( i<pTab->nCol );
    sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, 
                         pCol->affinity, &pValue);
    if( pValue ){
102573
102574
102575
102576
102577
102578
102579
102580
102581
102582
102583
102584
102585
102586
102587
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  if( nIdx>0 ){
    aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
    if( aRegIdx==0 ) goto update_cleanup;
  }
  for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
    int reg;
    if( hasFK || chngRowid ){
      reg = ++pParse->nMem;
    }else{
      reg = 0;
      for(i=0; i<pIdx->nColumn; i++){
        if( aXRef[pIdx->aiColumn[i]]>=0 ){
          reg = ++pParse->nMem;
          break;







|







103896
103897
103898
103899
103900
103901
103902
103903
103904
103905
103906
103907
103908
103909
103910
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  if( nIdx>0 ){
    aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
    if( aRegIdx==0 ) goto update_cleanup;
  }
  for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
    int reg;
    if( hasFK || chngRowid || pIdx->pPartIdxWhere ){
      reg = ++pParse->nMem;
    }else{
      reg = 0;
      for(i=0; i<pIdx->nColumn; i++){
        if( aXRef[pIdx->aiColumn[i]]>=0 ){
          reg = ++pParse->nMem;
          break;
104164
104165
104166
104167
104168
104169
104170
104171
104172
104173
104174
104175
104176
104177
104178
104179
104180
104181
104182
104183
104184
104185
104186
104187
104188
104189
104190
104191
104192
104193
104194
}

/*
** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans
** array. Return the error code for the first error that occurs, or
** SQLITE_OK if all xSync operations are successful.
**
** Set *pzErrmsg to point to a buffer that should be released using 
** sqlite3DbFree() containing an error message, if one is available.
*/
SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
  int i;
  int rc = SQLITE_OK;
  VTable **aVTrans = db->aVTrans;

  db->aVTrans = 0;
  for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
    int (*x)(sqlite3_vtab *);
    sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
    if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
      rc = x(pVtab);
      sqlite3DbFree(db, *pzErrmsg);
      *pzErrmsg = pVtab->zErrMsg;
      pVtab->zErrMsg = 0;
    }
  }
  db->aVTrans = aVTrans;
  return rc;
}

/*







<
|

|










|
<
<







105487
105488
105489
105490
105491
105492
105493

105494
105495
105496
105497
105498
105499
105500
105501
105502
105503
105504
105505
105506
105507


105508
105509
105510
105511
105512
105513
105514
}

/*
** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans
** array. Return the error code for the first error that occurs, or
** SQLITE_OK if all xSync operations are successful.
**

** If an error message is available, leave it in p->zErrMsg.
*/
SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){
  int i;
  int rc = SQLITE_OK;
  VTable **aVTrans = db->aVTrans;

  db->aVTrans = 0;
  for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
    int (*x)(sqlite3_vtab *);
    sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
    if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
      rc = x(pVtab);
      sqlite3VtabImportErrmsg(p, pVtab);


    }
  }
  db->aVTrans = aVTrans;
  return rc;
}

/*
104488
104489
104490
104491
104492
104493
104494
104495
104496
104497
104498
104499
104500
104501
104502
    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
# define WHERETRACE(K,X)  if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X
# define WHERETRACE_ENABLED 1
#else
# define WHERETRACE(K,X)
#endif

/* Forward reference
*/
typedef struct WhereClause WhereClause;
typedef struct WhereMaskSet WhereMaskSet;
typedef struct WhereOrInfo WhereOrInfo;
typedef struct WhereAndInfo WhereAndInfo;
typedef struct WhereLevel WhereLevel;
typedef struct WhereLoop WhereLoop;







|







105808
105809
105810
105811
105812
105813
105814
105815
105816
105817
105818
105819
105820
105821
105822
    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
# define WHERETRACE(K,X)  if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X
# define WHERETRACE_ENABLED 1
#else
# define WHERETRACE(K,X)
#endif

/* Forward references
*/
typedef struct WhereClause WhereClause;
typedef struct WhereMaskSet WhereMaskSet;
typedef struct WhereOrInfo WhereOrInfo;
typedef struct WhereAndInfo WhereAndInfo;
typedef struct WhereLevel WhereLevel;
typedef struct WhereLoop WhereLoop;
104510
104511
104512
104513
104514
104515
104516
104517
104518
104519
104520
104521
104522
104523
104524

104525
104526
104527
104528
104529
104530
104531
/*
** Cost X is tracked as 10*log2(X) stored in a 16-bit integer.  The
** maximum cost for ordinary tables is 64*(2**63) which becomes 6900.
** (Virtual tables can return a larger cost, but let's assume they do not.)
** So all costs can be stored in a 16-bit unsigned integer without risk
** of overflow.
**
** Costs are estimates, so don't go to the computational trouble to compute
** 10*log2(X) exactly.  Instead, a close estimate is used.  Any value of
** X<=1 is stored as 0.  X=2 is 10.  X=3 is 16.  X=1000 is 99. etc.
**
** The tool/wherecosttest.c source file implements a command-line program
** that will convert between WhereCost to integers and do addition and
** multiplication on WhereCost values.  That command-line program is a
** useful utility to have around when working with this module.

*/
typedef unsigned short int WhereCost;

/*
** This object contains information needed to implement a single nested
** loop in WHERE clause.
**







|
|
|


|
|
|
>







105830
105831
105832
105833
105834
105835
105836
105837
105838
105839
105840
105841
105842
105843
105844
105845
105846
105847
105848
105849
105850
105851
105852
/*
** Cost X is tracked as 10*log2(X) stored in a 16-bit integer.  The
** maximum cost for ordinary tables is 64*(2**63) which becomes 6900.
** (Virtual tables can return a larger cost, but let's assume they do not.)
** So all costs can be stored in a 16-bit unsigned integer without risk
** of overflow.
**
** Costs are estimates, so no effort is made to compute 10*log2(X) exactly.
** Instead, a close estimate is used.  Any value of X<=1 is stored as 0.
** X=2 is 10.  X=3 is 16.  X=1000 is 99. etc.
**
** The tool/wherecosttest.c source file implements a command-line program
** that will convert WhereCosts to integers, convert integers to WhereCosts
** and do addition and multiplication on WhereCost values.  The wherecosttest
** command-line program is a useful utility to have around when working with
** this module.
*/
typedef unsigned short int WhereCost;

/*
** This object contains information needed to implement a single nested
** loop in WHERE clause.
**
104544
104545
104546
104547
104548
104549
104550

104551
104552
104553
104554
104555
104556
104557
  int iLeftJoin;        /* Memory cell used to implement LEFT OUTER JOIN */
  int iTabCur;          /* The VDBE cursor used to access the table */
  int iIdxCur;          /* The VDBE cursor used to access pIdx */
  int addrBrk;          /* Jump here to break out of the loop */
  int addrNxt;          /* Jump here to start the next IN combination */
  int addrCont;         /* Jump here to continue with the next loop cycle */
  int addrFirst;        /* First instruction of interior of the loop */

  u8 iFrom;             /* Which entry in the FROM clause */
  u8 op, p5;            /* Opcode and P5 of the opcode that ends the loop */
  int p1, p2;           /* Operands of the opcode used to ends the loop */
  union {               /* Information that depends on pWLoop->wsFlags */
    struct {
      int nIn;              /* Number of entries in aInLoop[] */
      struct InLoop {







>







105865
105866
105867
105868
105869
105870
105871
105872
105873
105874
105875
105876
105877
105878
105879
  int iLeftJoin;        /* Memory cell used to implement LEFT OUTER JOIN */
  int iTabCur;          /* The VDBE cursor used to access the table */
  int iIdxCur;          /* The VDBE cursor used to access pIdx */
  int addrBrk;          /* Jump here to break out of the loop */
  int addrNxt;          /* Jump here to start the next IN combination */
  int addrCont;         /* Jump here to continue with the next loop cycle */
  int addrFirst;        /* First instruction of interior of the loop */
  int addrBody;         /* Beginning of the body of this loop */
  u8 iFrom;             /* Which entry in the FROM clause */
  u8 op, p5;            /* Opcode and P5 of the opcode that ends the loop */
  int p1, p2;           /* Operands of the opcode used to ends the loop */
  union {               /* Information that depends on pWLoop->wsFlags */
    struct {
      int nIn;              /* Number of entries in aInLoop[] */
      struct InLoop {
104620
104621
104622
104623
104624
104625
104626
104627
104628
104629
104630
104631
104632
104633
104634
104635
104636
104637
104638
104639
104640
104641
104642
104643
104644
104645
104646
104647
104648
104649
104650
104651
104652
104653
104654
struct WhereOrCost {
  Bitmask prereq;     /* Prerequisites */
  WhereCost rRun;     /* Cost of running this subquery */
  WhereCost nOut;     /* Number of outputs for this subquery */
};

/* The WhereOrSet object holds a set of possible WhereOrCosts that
** correspond to the subquery(s) of OR-clause processing.  At most
** favorable N_OR_COST elements are retained.
*/
#define N_OR_COST 3
struct WhereOrSet {
  u16 n;                      /* Number of valid a[] entries */
  WhereOrCost a[N_OR_COST];   /* Set of best costs */
};


/* Forward declaration of methods */
static int whereLoopResize(sqlite3*, WhereLoop*, int);

/*
** Each instance of this object holds a sequence of WhereLoop objects
** that implement some or all of a query plan.
**
** Think of each WhereLoop object as a node in a graph with arcs
** showing dependences and costs for travelling between nodes.  (That is
** not a completely accurate description because WhereLoop costs are a
** vector, not a scalar, and because dependences are many-to-one, not
** one-to-one as are graph nodes.  But it is a useful visualization aid.)
** Then a WherePath object is a path through the graph that visits some
** or all of the WhereLoop objects once.
**
** The "solver" works by creating the N best WherePath objects of length
** 1.  Then using those as a basis to compute the N best WherePath objects
** of length 2.  And so forth until the length of WherePaths equals the







|
|
















|

|







105942
105943
105944
105945
105946
105947
105948
105949
105950
105951
105952
105953
105954
105955
105956
105957
105958
105959
105960
105961
105962
105963
105964
105965
105966
105967
105968
105969
105970
105971
105972
105973
105974
105975
105976
struct WhereOrCost {
  Bitmask prereq;     /* Prerequisites */
  WhereCost rRun;     /* Cost of running this subquery */
  WhereCost nOut;     /* Number of outputs for this subquery */
};

/* The WhereOrSet object holds a set of possible WhereOrCosts that
** correspond to the subquery(s) of OR-clause processing.  Only the
** best N_OR_COST elements are retained.
*/
#define N_OR_COST 3
struct WhereOrSet {
  u16 n;                      /* Number of valid a[] entries */
  WhereOrCost a[N_OR_COST];   /* Set of best costs */
};


/* Forward declaration of methods */
static int whereLoopResize(sqlite3*, WhereLoop*, int);

/*
** Each instance of this object holds a sequence of WhereLoop objects
** that implement some or all of a query plan.
**
** Think of each WhereLoop object as a node in a graph with arcs
** showing dependencies and costs for travelling between nodes.  (That is
** not a completely accurate description because WhereLoop costs are a
** vector, not a scalar, and because dependencies are many-to-one, not
** one-to-one as are graph nodes.  But it is a useful visualization aid.)
** Then a WherePath object is a path through the graph that visits some
** or all of the WhereLoop objects once.
**
** The "solver" works by creating the N best WherePath objects of length
** 1.  Then using those as a basis to compute the N best WherePath objects
** of length 2.  And so forth until the length of WherePaths equals the
104687
104688
104689
104690
104691
104692
104693
104694
104695
104696
104697
104698
104699
104700
104701
104702
104703
** use of a bitmask encoding for the operator allows us to search
** quickly for terms that match any of several different operators.
**
** A WhereTerm might also be two or more subterms connected by OR:
**
**         (t1.X <op> <expr>) OR (t1.Y <op> <expr>) OR ....
**
** In this second case, wtFlag as the TERM_ORINFO set and eOperator==WO_OR
** and the WhereTerm.u.pOrInfo field points to auxiliary information that
** is collected about the
**
** If a term in the WHERE clause does not match either of the two previous
** categories, then eOperator==0.  The WhereTerm.pExpr field is still set
** to the original subexpression content and wtFlags is set up appropriately
** but no other fields in the WhereTerm object are meaningful.
**
** When eOperator!=0, prereqRight and prereqAll record sets of cursor numbers,







|

|







106009
106010
106011
106012
106013
106014
106015
106016
106017
106018
106019
106020
106021
106022
106023
106024
106025
** use of a bitmask encoding for the operator allows us to search
** quickly for terms that match any of several different operators.
**
** A WhereTerm might also be two or more subterms connected by OR:
**
**         (t1.X <op> <expr>) OR (t1.Y <op> <expr>) OR ....
**
** In this second case, wtFlag has the TERM_ORINFO bit set and eOperator==WO_OR
** and the WhereTerm.u.pOrInfo field points to auxiliary information that
** is collected about the OR clause.
**
** If a term in the WHERE clause does not match either of the two previous
** categories, then eOperator==0.  The WhereTerm.pExpr field is still set
** to the original subexpression content and wtFlags is set up appropriately
** but no other fields in the WhereTerm object are meaningful.
**
** When eOperator!=0, prereqRight and prereqAll record sets of cursor numbers,
104739
104740
104741
104742
104743
104744
104745
104746
104747
104748
104749
104750
104751
104752
104753
#define TERM_DYNAMIC    0x01   /* Need to call sqlite3ExprDelete(db, pExpr) */
#define TERM_VIRTUAL    0x02   /* Added by the optimizer.  Do not code */
#define TERM_CODED      0x04   /* This term is already coded */
#define TERM_COPIED     0x08   /* Has a child */
#define TERM_ORINFO     0x10   /* Need to free the WhereTerm.u.pOrInfo object */
#define TERM_ANDINFO    0x20   /* Need to free the WhereTerm.u.pAndInfo obj */
#define TERM_OR_OK      0x40   /* Used during OR-clause processing */
#ifdef SQLITE_ENABLE_STAT3
#  define TERM_VNULL    0x80   /* Manufactured x>NULL or x<=NULL term */
#else
#  define TERM_VNULL    0x00   /* Disabled if not using stat3 */
#endif

/*
** An instance of the WhereScan object is used as an iterator for locating







|







106061
106062
106063
106064
106065
106066
106067
106068
106069
106070
106071
106072
106073
106074
106075
#define TERM_DYNAMIC    0x01   /* Need to call sqlite3ExprDelete(db, pExpr) */
#define TERM_VIRTUAL    0x02   /* Added by the optimizer.  Do not code */
#define TERM_CODED      0x04   /* This term is already coded */
#define TERM_COPIED     0x08   /* Has a child */
#define TERM_ORINFO     0x10   /* Need to free the WhereTerm.u.pOrInfo object */
#define TERM_ANDINFO    0x20   /* Need to free the WhereTerm.u.pAndInfo obj */
#define TERM_OR_OK      0x40   /* Used during OR-clause processing */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
#  define TERM_VNULL    0x80   /* Manufactured x>NULL or x<=NULL term */
#else
#  define TERM_VNULL    0x00   /* Disabled if not using stat3 */
#endif

/*
** An instance of the WhereScan object is used as an iterator for locating
104845
104846
104847
104848
104849
104850
104851




104852
104853
104854
104855
104856
104857
104858
*/
struct WhereLoopBuilder {
  WhereInfo *pWInfo;        /* Information about this WHERE */
  WhereClause *pWC;         /* WHERE clause terms */
  ExprList *pOrderBy;       /* ORDER BY clause */
  WhereLoop *pNew;          /* Template WhereLoop */
  WhereOrSet *pOrSet;       /* Record best loops here, if not NULL */




};

/*
** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
** this structure is returned by the first half and passed







>
>
>
>







106167
106168
106169
106170
106171
106172
106173
106174
106175
106176
106177
106178
106179
106180
106181
106182
106183
106184
*/
struct WhereLoopBuilder {
  WhereInfo *pWInfo;        /* Information about this WHERE */
  WhereClause *pWC;         /* WHERE clause terms */
  ExprList *pOrderBy;       /* ORDER BY clause */
  WhereLoop *pNew;          /* Template WhereLoop */
  WhereOrSet *pOrSet;       /* Record best loops here, if not NULL */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  UnpackedRecord *pRec;     /* Probe for stat4 (if required) */
  int nRecValid;            /* Number of valid fields currently in pRec */
#endif
};

/*
** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
** this structure is returned by the first half and passed
105113
105114
105115
105116
105117
105118
105119
105120
105121
105122
105123
105124
105125
105126
105127
** WhereTerms.  All pointers to WhereTerms should be invalidated after
** calling this routine.  Such pointers may be reinitialized by referencing
** the pWC->a[] array.
*/
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
  WhereTerm *pTerm;
  int idx;
  testcase( wtFlags & TERM_VIRTUAL );  /* EV: R-00211-15100 */
  if( pWC->nTerm>=pWC->nSlot ){
    WhereTerm *pOld = pWC->a;
    sqlite3 *db = pWC->pWInfo->pParse->db;
    pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
    if( pWC->a==0 ){
      if( wtFlags & TERM_DYNAMIC ){
        sqlite3ExprDelete(db, p);







|







106439
106440
106441
106442
106443
106444
106445
106446
106447
106448
106449
106450
106451
106452
106453
** WhereTerms.  All pointers to WhereTerms should be invalidated after
** calling this routine.  Such pointers may be reinitialized by referencing
** the pWC->a[] array.
*/
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
  WhereTerm *pTerm;
  int idx;
  testcase( wtFlags & TERM_VIRTUAL );
  if( pWC->nTerm>=pWC->nSlot ){
    WhereTerm *pOld = pWC->a;
    sqlite3 *db = pWC->pWInfo->pParse->db;
    pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
    if( pWC->a==0 ){
      if( wtFlags & TERM_DYNAMIC ){
        sqlite3ExprDelete(db, p);
105201
105202
105203
105204
105205
105206
105207
105208
105209
105210
105211
105212
105213
105214
105215
*/
static void createMask(WhereMaskSet *pMaskSet, int iCursor){
  assert( pMaskSet->n < ArraySize(pMaskSet->ix) );
  pMaskSet->ix[pMaskSet->n++] = iCursor;
}

/*
** These routine walk (recursively) an expression tree and generates
** a bitmask indicating which tables are used in that expression
** tree.
*/
static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){
  Bitmask mask = 0;







|







106527
106528
106529
106530
106531
106532
106533
106534
106535
106536
106537
106538
106539
106540
106541
*/
static void createMask(WhereMaskSet *pMaskSet, int iCursor){
  assert( pMaskSet->n < ArraySize(pMaskSet->ix) );
  pMaskSet->ix[pMaskSet->n++] = iCursor;
}

/*
** These routines walk (recursively) an expression tree and generate
** a bitmask indicating which tables are used in that expression
** tree.
*/
static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){
  Bitmask mask = 0;
105258
105259
105260
105261
105262
105263
105264
105265
105266
105267
105268
105269
105270
105271
105272
105273
105274
105275
105276
105277
105278
  return mask;
}

/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term.  The allowed operators are
** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
**
** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
** of one of the following forms: column = expression column > expression
** column >= expression column < expression column <= expression
** expression = column expression > column expression >= column
** expression < column expression <= column column IN
** (expression-list) column IN (subquery) column IS NULL
*/
static int allowedOp(int op){
  assert( TK_GT>TK_EQ && TK_GT<TK_GE );
  assert( TK_LT>TK_EQ && TK_LT<TK_GE );
  assert( TK_LE>TK_EQ && TK_LE<TK_GE );
  assert( TK_GE==TK_EQ+4 );
  return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;







<
<
<
<
<
<
<







106584
106585
106586
106587
106588
106589
106590







106591
106592
106593
106594
106595
106596
106597
  return mask;
}

/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term.  The allowed operators are
** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"







*/
static int allowedOp(int op){
  assert( TK_GT>TK_EQ && TK_GT<TK_GE );
  assert( TK_LT>TK_EQ && TK_LT<TK_GE );
  assert( TK_LE>TK_EQ && TK_LE<TK_GE );
  assert( TK_GE==TK_EQ+4 );
  return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
105583
105584
105585
105586
105587
105588
105589
105590
105591
105592
105593
105594
105595
105596
105597
  op = pRight->op;
  if( op==TK_REGISTER ){
    op = pRight->op2;
  }
  if( op==TK_VARIABLE ){
    Vdbe *pReprepare = pParse->pReprepare;
    int iCol = pRight->iColumn;
    pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
    if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
      z = (char *)sqlite3_value_text(pVal);
    }
    sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
    assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
  }else if( op==TK_STRING ){
    z = pRight->u.zToken;







|







106902
106903
106904
106905
106906
106907
106908
106909
106910
106911
106912
106913
106914
106915
106916
  op = pRight->op;
  if( op==TK_REGISTER ){
    op = pRight->op2;
  }
  if( op==TK_VARIABLE ){
    Vdbe *pReprepare = pParse->pReprepare;
    int iCol = pRight->iColumn;
    pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_NONE);
    if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
      z = (char *)sqlite3_value_text(pVal);
    }
    sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
    assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
  }else if( op==TK_STRING ){
    z = pRight->u.zToken;
105665
105666
105667
105668
105669
105670
105671

105672
105673

105674
105675
105676
105677
105678
105679
105680
#endif /* SQLITE_OMIT_VIRTUALTABLE */

/*
** If the pBase expression originated in the ON or USING clause of
** a join, then transfer the appropriate markings over to derived.
*/
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){

  pDerived->flags |= pBase->flags & EP_FromJoin;
  pDerived->iRightJoinTable = pBase->iRightJoinTable;

}

#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
/*
** Analyze a term that consists of two or more OR-connected
** subterms.  So in:
**







>
|
|
>







106984
106985
106986
106987
106988
106989
106990
106991
106992
106993
106994
106995
106996
106997
106998
106999
107000
107001
#endif /* SQLITE_OMIT_VIRTUALTABLE */

/*
** If the pBase expression originated in the ON or USING clause of
** a join, then transfer the appropriate markings over to derived.
*/
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
  if( pDerived ){
    pDerived->flags |= pBase->flags & EP_FromJoin;
    pDerived->iRightJoinTable = pBase->iRightJoinTable;
  }
}

#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
/*
** Analyze a term that consists of two or more OR-connected
** subterms.  So in:
**
105725
105726
105727
105728
105729
105730
105731
105732
105733
105734
105735
105736
105737
105738
105739
105740
105741
105742
** subsubterms at least one of which is indexable.  Indexable AND 
** subterms have their eOperator set to WO_AND and they have
** u.pAndInfo set to a dynamically allocated WhereAndTerm object.
**
** From another point of view, "indexable" means that the subterm could
** potentially be used with an index if an appropriate index exists.
** This analysis does not consider whether or not the index exists; that
** is something the bestIndex() routine will determine.  This analysis
** only looks at whether subterms appropriate for indexing exist.
**
** All examples A through E above all satisfy case 2.  But if a term
** also statisfies case 1 (such as B) we know that the optimizer will
** always prefer case 1, so in that case we pretend that case 2 is not
** satisfied.
**
** It might be the case that multiple tables are indexable.  For example,
** (E) above is indexable on tables P, Q, and R.
**







|
|

|







107046
107047
107048
107049
107050
107051
107052
107053
107054
107055
107056
107057
107058
107059
107060
107061
107062
107063
** subsubterms at least one of which is indexable.  Indexable AND 
** subterms have their eOperator set to WO_AND and they have
** u.pAndInfo set to a dynamically allocated WhereAndTerm object.
**
** From another point of view, "indexable" means that the subterm could
** potentially be used with an index if an appropriate index exists.
** This analysis does not consider whether or not the index exists; that
** is decided elsewhere.  This analysis only looks at whether subterms
** appropriate for indexing exist.
**
** All examples A through E above satisfy case 2.  But if a term
** also statisfies case 1 (such as B) we know that the optimizer will
** always prefer case 1, so in that case we pretend that case 2 is not
** satisfied.
**
** It might be the case that multiple tables are indexable.  For example,
** (E) above is indexable on tables P, Q, and R.
**
105938
105939
105940
105941
105942
105943
105944
105945
105946
105947
105948
105949
105950
105951
105952
105953
        }
      }
    }

    /* At this point, okToChngToIN is true if original pTerm satisfies
    ** case 1.  In that case, construct a new virtual term that is 
    ** pTerm converted into an IN operator.
    **
    ** EV: R-00211-15100
    */
    if( okToChngToIN ){
      Expr *pDup;            /* A transient duplicate expression */
      ExprList *pList = 0;   /* The RHS of the IN operator */
      Expr *pLeft = 0;       /* The LHS of the IN operator */
      Expr *pNew;            /* The complete IN operator */








<
<







107259
107260
107261
107262
107263
107264
107265


107266
107267
107268
107269
107270
107271
107272
        }
      }
    }

    /* At this point, okToChngToIN is true if original pTerm satisfies
    ** case 1.  In that case, construct a new virtual term that is 
    ** pTerm converted into an IN operator.


    */
    if( okToChngToIN ){
      Expr *pDup;            /* A transient duplicate expression */
      ExprList *pList = 0;   /* The RHS of the IN operator */
      Expr *pLeft = 0;       /* The LHS of the IN operator */
      Expr *pNew;            /* The complete IN operator */

106125
106126
106127
106128
106129
106130
106131

106132
106133
106134
106135
106136
106137
106138
    assert( pList->nExpr==2 );
    for(i=0; i<2; i++){
      Expr *pNewExpr;
      int idxNew;
      pNewExpr = sqlite3PExpr(pParse, ops[i], 
                             sqlite3ExprDup(db, pExpr->pLeft, 0),
                             sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);

      idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
      testcase( idxNew==0 );
      exprAnalyze(pSrc, pWC, idxNew);
      pTerm = &pWC->a[idxTerm];
      pWC->a[idxNew].iParent = idxTerm;
    }
    pTerm->nChild = 2;







>







107444
107445
107446
107447
107448
107449
107450
107451
107452
107453
107454
107455
107456
107457
107458
    assert( pList->nExpr==2 );
    for(i=0; i<2; i++){
      Expr *pNewExpr;
      int idxNew;
      pNewExpr = sqlite3PExpr(pParse, ops[i], 
                             sqlite3ExprDup(db, pExpr->pLeft, 0),
                             sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
      transferJoinMarkings(pNewExpr, pExpr);
      idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
      testcase( idxNew==0 );
      exprAnalyze(pSrc, pWC, idxNew);
      pTerm = &pWC->a[idxTerm];
      pWC->a[idxNew].iParent = idxTerm;
    }
    pTerm->nChild = 2;
106181
106182
106183
106184
106185
106186
106187
106188
106189
106190
106191
106192
106193
106194
106195
106196
106197
106198
106199
106200

106201
106202
106203
106204
106205
106206
106207

106208
106209
106210
106211
106212
106213
106214
      if( noCase ){
        /* The point is to increment the last character before the first
        ** wildcard.  But if we increment '@', that will push it into the
        ** alphabetic range where case conversions will mess up the 
        ** inequality.  To avoid this, make sure to also run the full
        ** LIKE on all candidate expressions by clearing the isComplete flag
        */
        if( c=='A'-1 ) isComplete = 0;   /* EV: R-64339-08207 */


        c = sqlite3UpperToLower[c];
      }
      *pC = c + 1;
    }
    sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
    sCollSeqName.n = 6;
    pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
    pNewExpr1 = sqlite3PExpr(pParse, TK_GE, 
           sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
           pStr1, 0);

    idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew1==0 );
    exprAnalyze(pSrc, pWC, idxNew1);
    pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
    pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
           sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
           pStr2, 0);

    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew2==0 );
    exprAnalyze(pSrc, pWC, idxNew2);
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){
      pWC->a[idxNew1].iParent = idxTerm;
      pWC->a[idxNew2].iParent = idxTerm;







|
<
<










>







>







107501
107502
107503
107504
107505
107506
107507
107508


107509
107510
107511
107512
107513
107514
107515
107516
107517
107518
107519
107520
107521
107522
107523
107524
107525
107526
107527
107528
107529
107530
107531
107532
107533
107534
      if( noCase ){
        /* The point is to increment the last character before the first
        ** wildcard.  But if we increment '@', that will push it into the
        ** alphabetic range where case conversions will mess up the 
        ** inequality.  To avoid this, make sure to also run the full
        ** LIKE on all candidate expressions by clearing the isComplete flag
        */
        if( c=='A'-1 ) isComplete = 0;


        c = sqlite3UpperToLower[c];
      }
      *pC = c + 1;
    }
    sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
    sCollSeqName.n = 6;
    pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
    pNewExpr1 = sqlite3PExpr(pParse, TK_GE, 
           sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
           pStr1, 0);
    transferJoinMarkings(pNewExpr1, pExpr);
    idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew1==0 );
    exprAnalyze(pSrc, pWC, idxNew1);
    pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
    pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
           sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
           pStr2, 0);
    transferJoinMarkings(pNewExpr2, pExpr);
    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew2==0 );
    exprAnalyze(pSrc, pWC, idxNew2);
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){
      pWC->a[idxNew1].iParent = idxTerm;
      pWC->a[idxNew2].iParent = idxTerm;
106250
106251
106252
106253
106254
106255
106256
106257
106258
106259
106260
106261
106262
106263
106264
      pTerm->nChild = 1;
      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifdef SQLITE_ENABLE_STAT3
  /* When sqlite_stat3 histogram data is available an operator of the
  ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
  ** as "x>NULL" if x is not an INTEGER PRIMARY KEY.  So construct a
  ** virtual term of that form.
  **
  ** Note that the virtual term must be tagged with TERM_VNULL.  This
  ** TERM_VNULL tag will suppress the not-null check at the beginning







|







107570
107571
107572
107573
107574
107575
107576
107577
107578
107579
107580
107581
107582
107583
107584
      pTerm->nChild = 1;
      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  /* When sqlite_stat3 histogram data is available an operator of the
  ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
  ** as "x>NULL" if x is not an INTEGER PRIMARY KEY.  So construct a
  ** virtual term of that form.
  **
  ** Note that the virtual term must be tagged with TERM_VNULL.  This
  ** TERM_VNULL tag will suppress the not-null check at the beginning
106290
106291
106292
106293
106294
106295
106296
106297
106298
106299
106300
106301
106302
106303
106304
      pNewTerm->iParent = idxTerm;
      pTerm = &pWC->a[idxTerm];
      pTerm->nChild = 1;
      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_ENABLE_STAT */

  /* Prevent ON clause terms of a LEFT JOIN from being used to drive
  ** an index for tables to the left of the join.
  */
  pTerm->prereqRight |= extraRight;
}








|







107610
107611
107612
107613
107614
107615
107616
107617
107618
107619
107620
107621
107622
107623
107624
      pNewTerm->iParent = idxTerm;
      pTerm = &pWC->a[idxTerm];
      pTerm->nChild = 1;
      pTerm->wtFlags |= TERM_COPIED;
      pNewTerm->prereqAll = pTerm->prereqAll;
    }
  }
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

  /* Prevent ON clause terms of a LEFT JOIN from being used to drive
  ** an index for tables to the left of the join.
  */
  pTerm->prereqRight |= extraRight;
}

106399
106400
106401
106402
106403
106404
106405
106406
106407
106408
106409
106410
106411
106412
106413
    }
  }

  return 0;
}

/* 
** The (an approximate) sum of two WhereCosts.  This computation is
** not a simple "+" operator because WhereCost is stored as a logarithmic
** value.
** 
*/
static WhereCost whereCostAdd(WhereCost a, WhereCost b){
  static const unsigned char x[] = {
     10, 10,                         /* 0,1 */







|







107719
107720
107721
107722
107723
107724
107725
107726
107727
107728
107729
107730
107731
107732
107733
    }
  }

  return 0;
}

/* 
** Find (an approximate) sum of two WhereCosts.  This computation is
** not a simple "+" operator because WhereCost is stored as a logarithmic
** value.
** 
*/
static WhereCost whereCostAdd(WhereCost a, WhereCost b){
  static const unsigned char x[] = {
     10, 10,                         /* 0,1 */
106690
106691
106692
106693
106694
106695
106696
106697
106698
106699
106700
106701
106702
106703
106704
  sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0,
                    (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
  VdbeComment((v, "for %s", pTable->zName));

  /* Fill the automatic index with content */
  addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
  regRecord = sqlite3GetTempReg(pParse);
  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1);
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
  sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);
  







|







108010
108011
108012
108013
108014
108015
108016
108017
108018
108019
108020
108021
108022
108023
108024
  sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0,
                    (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
  VdbeComment((v, "for %s", pTable->zName));

  /* Fill the automatic index with content */
  addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
  regRecord = sqlite3GetTempReg(pParse);
  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1, 0);
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
  sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);
  
106858
106859
106860
106861
106862
106863
106864
106865
106866
106867
106868
106869
106870
106871
106872
106873
106874
106875
106876
106877
106878
106879
106880
106881
106882
106883
106884
106885

106886
106887
106888
106889


106890
106891
106892
106893
106894
106895
106896
106897
106898
106899
106900
106901
106902
106903
106904
106905
106906
106907
106908
106909
106910
106911
106912

106913
106914
106915
106916
106917
106918
106919
106920
106921


106922
106923
106924
106925
106926
106927
106928
106929
106930
106931
106932
106933
106934
106935
106936
106937
106938
106939
106940

106941
106942
106943
106944
106945
106946
106947
106948
106949
106950
106951
106952
106953
106954
106955
106956
106957
106958
106959
106960
106961
106962
106963
106964
106965
106966
106967
106968
106969
106970
106971
106972
106973

106974
106975
106976
106977
106978
106979
106980
106981
106982
106983
106984
106985
106986
106987
106988
106989
106990
106991
106992
106993
106994
106995
106996
106997
106998
106999
107000
107001
107002
107003
107004
107005
107006
107007
107008
107009
107010
107011
107012
107013
107014
107015
107016
107017
107018
107019
107020
107021
107022
107023
107024
107025
107026
107027
107028
107029
107030
107031
107032
107033
107034
107035
107036
107037
107038
107039
107040
107041
107042
107043
107044
107045
107046
107047
107048
107049
107050
107051
107052
107053
107054
107055
107056
107057
107058
107059
107060
107061
107062
107063
107064
107065
107066
107067
107068
107069
107070
107071
107072
107073
107074
107075
107076
107077
107078
107079
107080
107081
107082
107083
107084
107085
107086
107087
107088
107089
107090
107091
107092
107093

107094
107095
107096
107097
107098
107099
107100
107101
107102
107103
107104
107105
107106
107107
107108

107109
107110


107111



107112




107113

















107114
107115
107116



107117
107118













107119

107120
107121
107122

107123

107124
107125
107126
107127

107128
107129
107130


107131

107132
107133
107134

107135

107136
107137
107138
107139

107140
107141
107142


107143
107144
107145
107146


107147

107148


107149
107150
107151
107152
107153
107154
107155
107156
107157
107158
107159
107160
107161
107162
107163
107164
107165
107166
107167
107168


107169
107170
107171
107172
107173
107174
107175
107176
107177
107178
107179
107180
107181
107182
107183
107184
107185
107186
107187
107188
107189
107190
107191
107192
107193
107194
107195
107196


107197
107198
107199

107200


107201
107202

107203


107204


107205


107206
107207
107208

107209





107210


107211
107212
107213
107214
107215
107216
107217
107218
107219
107220
107221
107222
107223
107224
107225
107226
107227
107228
107229
107230
107231
107232
107233
107234
107235
107236
107237
107238
107239
107240
107241
107242
107243
107244


107245
107246
107247
107248
107249
107250
107251
107252
107253
107254

107255

107256
107257
107258
107259
107260

107261
107262
107263
107264
107265
107266
107267
107268
107269
107270
107271
107272
107273
107274
107275
107276
107277
107278
107279
107280
107281
107282
107283
107284
107285
107286
107287
107288
107289
  }

  return pParse->nErr;
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */


#ifdef SQLITE_ENABLE_STAT3
/*
** Estimate the location of a particular key among all keys in an
** index.  Store the results in aStat as follows:
**
**    aStat[0]      Est. number of rows less than pVal
**    aStat[1]      Est. number of rows equal to pVal
**
** Return SQLITE_OK on success.
*/
static int whereKeyStats(
  Parse *pParse,              /* Database connection */
  Index *pIdx,                /* Index to consider domain of */
  sqlite3_value *pVal,        /* Value to consider */
  int roundUp,                /* Round up if true.  Round down if false */
  tRowcnt *aStat              /* OUT: stats written here */
){
  tRowcnt n;
  IndexSample *aSample;
  int i, eType;
  int isEq = 0;

  i64 v;
  double r, rS;

  assert( roundUp==0 || roundUp==1 );


  assert( pIdx->nSample>0 );
  if( pVal==0 ) return SQLITE_ERROR;
  n = pIdx->aiRowEst[0];
  aSample = pIdx->aSample;
  eType = sqlite3_value_type(pVal);

  if( eType==SQLITE_INTEGER ){
    v = sqlite3_value_int64(pVal);
    r = (i64)v;
    for(i=0; i<pIdx->nSample; i++){
      if( aSample[i].eType==SQLITE_NULL ) continue;
      if( aSample[i].eType>=SQLITE_TEXT ) break;
      if( aSample[i].eType==SQLITE_INTEGER ){
        if( aSample[i].u.i>=v ){
          isEq = aSample[i].u.i==v;
          break;
        }
      }else{
        assert( aSample[i].eType==SQLITE_FLOAT );
        if( aSample[i].u.r>=r ){
          isEq = aSample[i].u.r==r;
          break;
        }

      }
    }
  }else if( eType==SQLITE_FLOAT ){
    r = sqlite3_value_double(pVal);
    for(i=0; i<pIdx->nSample; i++){
      if( aSample[i].eType==SQLITE_NULL ) continue;
      if( aSample[i].eType>=SQLITE_TEXT ) break;
      if( aSample[i].eType==SQLITE_FLOAT ){
        rS = aSample[i].u.r;


      }else{
        rS = aSample[i].u.i;
      }
      if( rS>=r ){
        isEq = rS==r;
        break;
      }
    }
  }else if( eType==SQLITE_NULL ){
    i = 0;
    if( aSample[0].eType==SQLITE_NULL ) isEq = 1;
  }else{
    assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
    for(i=0; i<pIdx->nSample; i++){
      if( aSample[i].eType==SQLITE_TEXT || aSample[i].eType==SQLITE_BLOB ){
        break;
      }
    }
    if( i<pIdx->nSample ){      

      sqlite3 *db = pParse->db;
      CollSeq *pColl;
      const u8 *z;
      if( eType==SQLITE_BLOB ){
        z = (const u8 *)sqlite3_value_blob(pVal);
        pColl = db->pDfltColl;
        assert( pColl->enc==SQLITE_UTF8 );
      }else{
        pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl);
        /* If the collating sequence was unavailable, we should have failed
        ** long ago and never reached this point.  But we'll check just to
        ** be doubly sure. */
        if( NEVER(pColl==0) ) return SQLITE_ERROR;
        z = (const u8 *)sqlite3ValueText(pVal, pColl->enc);
        if( !z ){
          return SQLITE_NOMEM;
        }
        assert( z && pColl && pColl->xCmp );
      }
      n = sqlite3ValueBytes(pVal, pColl->enc);
  
      for(; i<pIdx->nSample; i++){
        int c;
        int eSampletype = aSample[i].eType;
        if( eSampletype<eType ) continue;
        if( eSampletype!=eType ) break;
#ifndef SQLITE_OMIT_UTF16
        if( pColl->enc!=SQLITE_UTF8 ){
          int nSample;
          char *zSample = sqlite3Utf8to16(
              db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample
          );
          if( !zSample ){

            assert( db->mallocFailed );
            return SQLITE_NOMEM;
          }
          c = pColl->xCmp(pColl->pUser, nSample, zSample, n, z);
          sqlite3DbFree(db, zSample);
        }else
#endif
        {
          c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z);
        }
        if( c>=0 ){
          if( c==0 ) isEq = 1;
          break;
        }
      }
    }
  }

  /* At this point, aSample[i] is the first sample that is greater than
  ** or equal to pVal.  Or if i==pIdx->nSample, then all samples are less
  ** than pVal.  If aSample[i]==pVal, then isEq==1.
  */
  if( isEq ){
    assert( i<pIdx->nSample );
    aStat[0] = aSample[i].nLt;
    aStat[1] = aSample[i].nEq;
  }else{
    tRowcnt iLower, iUpper, iGap;
    if( i==0 ){
      iLower = 0;
      iUpper = aSample[0].nLt;
    }else{
      iUpper = i>=pIdx->nSample ? n : aSample[i].nLt;
      iLower = aSample[i-1].nEq + aSample[i-1].nLt;
    }
    aStat[1] = pIdx->avgEq;
    if( iLower>=iUpper ){
      iGap = 0;
    }else{
      iGap = iUpper - iLower;
    }
    if( roundUp ){
      iGap = (iGap*2)/3;
    }else{
      iGap = iGap/3;
    }
    aStat[0] = iLower + iGap;
  }
  return SQLITE_OK;
}
#endif /* SQLITE_ENABLE_STAT3 */

/*
** If expression pExpr represents a literal value, set *pp to point to
** an sqlite3_value structure containing the same value, with affinity
** aff applied to it, before returning. It is the responsibility of the 
** caller to eventually release this structure by passing it to 
** sqlite3ValueFree().
**
** If the current parse is a recompile (sqlite3Reprepare()) and pExpr
** is an SQL variable that currently has a non-NULL value bound to it,
** create an sqlite3_value structure containing this value, again with
** affinity aff applied to it, instead.
**
** If neither of the above apply, set *pp to NULL.
**
** If an error occurs, return an error code. Otherwise, SQLITE_OK.
*/
#ifdef SQLITE_ENABLE_STAT3
static int valueFromExpr(
  Parse *pParse, 
  Expr *pExpr, 
  u8 aff, 
  sqlite3_value **pp
){
  if( pExpr->op==TK_VARIABLE
   || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
  ){
    int iVar = pExpr->iColumn;
    sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
    *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
    return SQLITE_OK;
  }
  return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
}
#endif

/*
** This function is used to estimate the number of rows that will be visited
** by scanning an index for a range of values. The range may have an upper
** bound, a lower bound, or both. The WHERE clause terms that set the upper
** and lower bounds are represented by pLower and pUpper respectively. For
** example, assuming that index p is on t1(a):
**
**   ... FROM t1 WHERE a > ? AND a < ? ...
**                    |_____|   |_____|
**                       |         |
**                     pLower    pUpper
**
** If either of the upper or lower bound is not present, then NULL is passed in
** place of the corresponding WhereTerm.
**
** The nEq parameter is passed the index of the index column subject to the
** range constraint. Or, equivalently, the number of equality constraints
** optimized by the proposed index scan. For example, assuming index p is
** on t1(a, b), and the SQL query is:
**
**   ... FROM t1 WHERE a = ? AND b > ? AND b < ? ...
**
** then nEq should be passed the value 1 (as the range restricted column,
** b, is the second left-most column of the index). Or, if the query is:
**
**   ... FROM t1 WHERE a > ? AND a < ? ...
**
** then nEq should be passed 0.
**
** The returned value is an integer divisor to reduce the estimated
** search space.  A return value of 1 means that range constraints are
** no help at all.  A return value of 2 means range constraints are
** expected to reduce the search space by half.  And so forth...

**
** In the absence of sqlite_stat3 ANALYZE data, each range inequality
** reduces the search space by a factor of 4.  Hence a single constraint (x>?)
** results in a return of 4 and a range constraint (x>? AND x<?) results
** in a return of 16.
*/
static int whereRangeScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index containing the range-compared column; "x" */
  int nEq,             /* index into p->aCol[] of the range-compared column */
  WhereTerm *pLower,   /* Lower bound on the range. ex: "x>123" Might be NULL */
  WhereTerm *pUpper,   /* Upper bound on the range. ex: "x<455" Might be NULL */
  WhereCost *pRangeDiv /* OUT: Reduce search space by this divisor */
){
  int rc = SQLITE_OK;


#ifdef SQLITE_ENABLE_STAT3






  if( nEq==0 && p->nSample && OptimizationEnabled(pParse->db, SQLITE_Stat3) ){




    sqlite3_value *pRangeVal;

















    tRowcnt iLower = 0;
    tRowcnt iUpper = p->aiRowEst[0];
    tRowcnt a[2];



    u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity;














    if( pLower ){

      Expr *pExpr = pLower->pExpr->pRight;
      rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
      assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );

      if( rc==SQLITE_OK

       && whereKeyStats(pParse, p, pRangeVal, 0, a)==SQLITE_OK
      ){
        iLower = a[0];
        if( (pLower->eOperator & WO_GT)!=0 ) iLower += a[1];

      }
      sqlite3ValueFree(pRangeVal);
    }


    if( rc==SQLITE_OK && pUpper ){

      Expr *pExpr = pUpper->pExpr->pRight;
      rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
      assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );

      if( rc==SQLITE_OK

       && whereKeyStats(pParse, p, pRangeVal, 1, a)==SQLITE_OK
      ){
        iUpper = a[0];
        if( (pUpper->eOperator & WO_LE)!=0 ) iUpper += a[1];

      }
      sqlite3ValueFree(pRangeVal);
    }


    if( rc==SQLITE_OK ){
      WhereCost iBase = whereCost(p->aiRowEst[0]);
      if( iUpper>iLower ){
        iBase -= whereCost(iUpper - iLower);


      }

      *pRangeDiv = iBase;


      WHERETRACE(0x100, ("range scan regions: %u..%u  div=%d\n",
                         (u32)iLower, (u32)iUpper, *pRangeDiv));
      return SQLITE_OK;
    }
  }
#else
  UNUSED_PARAMETER(pParse);
  UNUSED_PARAMETER(p);
  UNUSED_PARAMETER(nEq);
#endif
  assert( pLower || pUpper );
  *pRangeDiv = 0;
  /* TUNING:  Each inequality constraint reduces the search space 4-fold.
  ** A BETWEEN operator, therefore, reduces the search space 16-fold */
  if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){
    *pRangeDiv += 20;  assert( 20==whereCost(4) );
  }
  if( pUpper ){
    *pRangeDiv += 20;  assert( 20==whereCost(4) );
  }


  return rc;
}

#ifdef SQLITE_ENABLE_STAT3
/*
** Estimate the number of rows that will be returned based on
** an equality constraint x=VALUE and where that VALUE occurs in
** the histogram data.  This only works when x is the left-most
** column of an index and sqlite_stat3 histogram data is available
** for that index.  When pExpr==NULL that means the constraint is
** "x IS NULL" instead of "x=VALUE".
**
** Write the estimated row count into *pnRow and return SQLITE_OK. 
** If unable to make an estimate, leave *pnRow unchanged and return
** non-zero.
**
** This routine can fail if it is unable to load a collating sequence
** required for string comparison, or if unable to allocate memory
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
static int whereEqualScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index whose left-most column is pTerm */
  Expr *pExpr,         /* Expression for VALUE in the x=VALUE constraint */
  tRowcnt *pnRow       /* Write the revised row estimate here */
){
  sqlite3_value *pRhs = 0;  /* VALUE on right-hand side of pTerm */


  u8 aff;                   /* Column affinity */
  int rc;                   /* Subfunction return code */
  tRowcnt a[2];             /* Statistics */




  assert( p->aSample!=0 );
  assert( p->nSample>0 );

  aff = p->pTable->aCol[p->aiColumn[0]].affinity;


  if( pExpr ){


    rc = valueFromExpr(pParse, pExpr, aff, &pRhs);


    if( rc ) goto whereEqualScanEst_cancel;
  }else{
    pRhs = sqlite3ValueNew(pParse->db);

  }





  if( pRhs==0 ) return SQLITE_NOTFOUND;


  rc = whereKeyStats(pParse, p, pRhs, 0, a);
  if( rc==SQLITE_OK ){
    WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1]));
    *pnRow = a[1];
  }
whereEqualScanEst_cancel:
  sqlite3ValueFree(pRhs);
  return rc;
}
#endif /* defined(SQLITE_ENABLE_STAT3) */

#ifdef SQLITE_ENABLE_STAT3
/*
** Estimate the number of rows that will be returned based on
** an IN constraint where the right-hand side of the IN operator
** is a list of values.  Example:
**
**        WHERE x IN (1,2,3,4)
**
** Write the estimated row count into *pnRow and return SQLITE_OK. 
** If unable to make an estimate, leave *pnRow unchanged and return
** non-zero.
**
** This routine can fail if it is unable to load a collating sequence
** required for string comparison, or if unable to allocate memory
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
static int whereInScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  Index *p,            /* The index whose left-most column is pTerm */
  ExprList *pList,     /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
  tRowcnt *pnRow       /* Write the revised row estimate here */
){


  int rc = SQLITE_OK;     /* Subfunction return code */
  tRowcnt nEst;           /* Number of rows for a single term */
  tRowcnt nRowEst = 0;    /* New estimate of the number of rows */
  int i;                  /* Loop counter */

  assert( p->aSample!=0 );
  for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){
    nEst = p->aiRowEst[0];
    rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst);
    nRowEst += nEst;

  }

  if( rc==SQLITE_OK ){
    if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
    *pnRow = nRowEst;
    WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst));
  }

  return rc;
}
#endif /* defined(SQLITE_ENABLE_STAT3) */

/*
** Disable a term in the WHERE clause.  Except, do not disable the term
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
** or USING clause of that join.
**
** Consider the term t2.z='ok' in the following queries:
**
**   (1)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
**   (2)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
**   (3)  SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
**
** The t2.z='ok' is disabled in the in (2) because it originates
** in the ON clause.  The term is disabled in (3) because it is not part
** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
**
** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are
** completely satisfied by indices.
**
** Disabling a term causes that term to not be tested in the inner loop
** of the join.  Disabling is an optimization.  When terms are satisfied
** by indices, we disable them to prevent redundant tests in the inner
** loop.  We would get the correct results if nothing were ever disabled,
** but joins might run a little slower.  The trick is to disable as much
** as we can without disabling too much.  If we disabled in (1), we'd get
** the wrong answer.  See ticket #813.







|









|


|



<
|
|
|
>
|
|

|
>
>

<
<
|
<
|
<
<
|
<
|
<
<
|
|
<
<
|
<
<
|
<
|
>
|
<
|
<
<
<
<
<
<
>
>
|
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
>
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
|
<
|
|
|
>
|
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<



|

|
<
|
|




|

|
|

|












<

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















|
|
|
|



|
|



|

|
|
|
|
>
|
|
|
|
|



<
|


|


>

|
>
>

>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>

>

<

>
|
>
|
<
<
|
>

<

>
>
|
>

<

>
|
>
|
<
<
|
>

<

>
>

|

|
>
>

>
|
>
>
|
|





<
|


<



|


|

>
>



|



















|



|
>
>



>

>
>


>
|
>
>
|
>
>
|
>
>
|
<
|
>

>
>
>
>
>
|
>
>
|
<
|
|
|
<
<


|

|


















|



>
>








|

>

>





>


|
















<
<
<







108178
108179
108180
108181
108182
108183
108184
108185
108186
108187
108188
108189
108190
108191
108192
108193
108194
108195
108196
108197
108198
108199
108200
108201

108202
108203
108204
108205
108206
108207
108208
108209
108210
108211
108212


108213

108214


108215

108216


108217
108218


108219


108220

108221
108222
108223

108224






108225
108226
108227


108228









108229




108230
108231
108232






108233












108234
108235






108236

108237
108238
108239
108240
108241

108242



108243










108244
108245
108246
108247
108248
108249

108250
108251
108252
108253
108254
108255
108256
108257
108258
108259
108260
108261
108262
108263
108264
108265
108266
108267
108268
108269
108270
108271
108272
108273

108274
108275



































108276
108277
108278
108279
108280
108281
108282
108283
108284
108285
108286
108287
108288
108289
108290
108291
108292
108293
108294
108295
108296
108297
108298
108299
108300
108301
108302
108303
108304
108305
108306
108307
108308
108309
108310
108311
108312
108313
108314
108315
108316
108317
108318

108319
108320
108321
108322
108323
108324
108325
108326
108327
108328
108329
108330
108331
108332
108333
108334
108335
108336
108337
108338
108339
108340
108341
108342
108343
108344
108345
108346
108347
108348
108349
108350
108351
108352
108353
108354
108355
108356
108357
108358
108359
108360
108361
108362
108363
108364
108365
108366
108367
108368
108369
108370
108371
108372
108373
108374
108375
108376
108377
108378
108379
108380

108381
108382
108383
108384
108385


108386
108387
108388

108389
108390
108391
108392
108393
108394

108395
108396
108397
108398
108399


108400
108401
108402

108403
108404
108405
108406
108407
108408
108409
108410
108411
108412
108413
108414
108415
108416
108417
108418
108419
108420
108421
108422
108423

108424
108425
108426

108427
108428
108429
108430
108431
108432
108433
108434
108435
108436
108437
108438
108439
108440
108441
108442
108443
108444
108445
108446
108447
108448
108449
108450
108451
108452
108453
108454
108455
108456
108457
108458
108459
108460
108461
108462
108463
108464
108465
108466
108467
108468
108469
108470
108471
108472
108473
108474
108475
108476
108477
108478
108479
108480
108481
108482
108483
108484
108485
108486

108487
108488
108489
108490
108491
108492
108493
108494
108495
108496
108497
108498

108499
108500
108501


108502
108503
108504
108505
108506
108507
108508
108509
108510
108511
108512
108513
108514
108515
108516
108517
108518
108519
108520
108521
108522
108523
108524
108525
108526
108527
108528
108529
108530
108531
108532
108533
108534
108535
108536
108537
108538
108539
108540
108541
108542
108543
108544
108545
108546
108547
108548
108549
108550
108551
108552
108553
108554
108555
108556
108557
108558
108559
108560
108561
108562
108563
108564
108565
108566
108567
108568



108569
108570
108571
108572
108573
108574
108575
  }

  return pParse->nErr;
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */


#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the location of a particular key among all keys in an
** index.  Store the results in aStat as follows:
**
**    aStat[0]      Est. number of rows less than pVal
**    aStat[1]      Est. number of rows equal to pVal
**
** Return SQLITE_OK on success.
*/
static void whereKeyStats(
  Parse *pParse,              /* Database connection */
  Index *pIdx,                /* Index to consider domain of */
  UnpackedRecord *pRec,       /* Vector of values to consider */
  int roundUp,                /* Round up if true.  Round down if false */
  tRowcnt *aStat              /* OUT: stats written here */
){

  IndexSample *aSample = pIdx->aSample;
  int iCol;                   /* Index of required stats in anEq[] etc. */
  int iMin = 0;               /* Smallest sample not yet tested */
  int i = pIdx->nSample;      /* Smallest sample larger than or equal to pRec */
  int iTest;                  /* Next sample to test */
  int res;                    /* Result of comparison operation */

  assert( pRec!=0 || pParse->db->mallocFailed );
  if( pRec==0 ) return;
  iCol = pRec->nField - 1;
  assert( pIdx->nSample>0 );


  assert( pRec->nField>0 && iCol<pIdx->nSampleCol );

  do{


    iTest = (iMin+i)/2;

    res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec);


    if( res<0 ){
      iMin = iTest+1;


    }else{


      i = iTest;

    }
  }while( res && iMin<i );


#ifdef SQLITE_DEBUG






  /* The following assert statements check that the binary search code
  ** above found the right answer. This block serves no purpose other
  ** than to invoke the asserts.  */


  if( res==0 ){









    /* If (res==0) is true, then sample $i must be equal to pRec */




    assert( i<pIdx->nSample );
    assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)
         || pParse->db->mallocFailed );






  }else{












    /* Otherwise, pRec must be smaller than sample $i and larger than
    ** sample ($i-1).  */






    assert( i==pIdx->nSample 

         || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0
         || pParse->db->mallocFailed );
    assert( i==0
         || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0
         || pParse->db->mallocFailed );

  }



#endif /* ifdef SQLITE_DEBUG */











  /* At this point, aSample[i] is the first sample that is greater than
  ** or equal to pVal.  Or if i==pIdx->nSample, then all samples are less
  ** than pVal.  If aSample[i]==pVal, then res==0.
  */
  if( res==0 ){

    aStat[0] = aSample[i].anLt[iCol];
    aStat[1] = aSample[i].anEq[iCol];
  }else{
    tRowcnt iLower, iUpper, iGap;
    if( i==0 ){
      iLower = 0;
      iUpper = aSample[0].anLt[iCol];
    }else{
      iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol];
      iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
    }
    aStat[1] = (pIdx->nColumn>iCol ? pIdx->aAvgEq[iCol] : 1);
    if( iLower>=iUpper ){
      iGap = 0;
    }else{
      iGap = iUpper - iLower;
    }
    if( roundUp ){
      iGap = (iGap*2)/3;
    }else{
      iGap = iGap/3;
    }
    aStat[0] = iLower + iGap;
  }

}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */




































/*
** This function is used to estimate the number of rows that will be visited
** by scanning an index for a range of values. The range may have an upper
** bound, a lower bound, or both. The WHERE clause terms that set the upper
** and lower bounds are represented by pLower and pUpper respectively. For
** example, assuming that index p is on t1(a):
**
**   ... FROM t1 WHERE a > ? AND a < ? ...
**                    |_____|   |_____|
**                       |         |
**                     pLower    pUpper
**
** If either of the upper or lower bound is not present, then NULL is passed in
** place of the corresponding WhereTerm.
**
** The value in (pBuilder->pNew->u.btree.nEq) is the index of the index
** column subject to the range constraint. Or, equivalently, the number of
** equality constraints optimized by the proposed index scan. For example,
** assuming index p is on t1(a, b), and the SQL query is:
**
**   ... FROM t1 WHERE a = ? AND b > ? AND b < ? ...
**
** then nEq is set to 1 (as the range restricted column, b, is the second 
** left-most column of the index). Or, if the query is:
**
**   ... FROM t1 WHERE a > ? AND a < ? ...
**
** then nEq is set to 0.
**
** When this function is called, *pnOut is set to the whereCost() of the
** number of rows that the index scan is expected to visit without 
** considering the range constraints. If nEq is 0, this is the number of 
** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
** to account for the range contraints pLower and pUpper.
** 
** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be
** used, each range inequality reduces the search space by a factor of 4. 
** Hence a pair of constraints (x>? AND x<?) reduces the expected number of
** rows visited by a factor of 16.
*/
static int whereRangeScanEst(
  Parse *pParse,       /* Parsing & code generating context */

  WhereLoopBuilder *pBuilder,
  WhereTerm *pLower,   /* Lower bound on the range. ex: "x>123" Might be NULL */
  WhereTerm *pUpper,   /* Upper bound on the range. ex: "x<455" Might be NULL */
  WhereCost *pnOut     /* IN/OUT: Number of rows visited */
){
  int rc = SQLITE_OK;
  int nOut = (int)*pnOut;

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  Index *p = pBuilder->pNew->u.btree.pIndex;
  int nEq = pBuilder->pNew->u.btree.nEq;

  if( nEq==pBuilder->nRecValid
   && nEq<p->nSampleCol
   && p->nSample 
   && OptimizationEnabled(pParse->db, SQLITE_Stat3) 
  ){
    UnpackedRecord *pRec = pBuilder->pRec;
    tRowcnt a[2];
    u8 aff;

    /* Variable iLower will be set to the estimate of the number of rows in 
    ** the index that are less than the lower bound of the range query. The
    ** lower bound being the concatenation of $P and $L, where $P is the
    ** key-prefix formed by the nEq values matched against the nEq left-most
    ** columns of the index, and $L is the value in pLower.
    **
    ** Or, if pLower is NULL or $L cannot be extracted from it (because it
    ** is not a simple variable or literal value), the lower bound of the
    ** range is $P. Due to a quirk in the way whereKeyStats() works, even
    ** if $L is available, whereKeyStats() is called for both ($P) and 
    ** ($P:$L) and the larger of the two returned values used.
    **
    ** Similarly, iUpper is to be set to the estimate of the number of rows
    ** less than the upper bound of the range query. Where the upper bound
    ** is either ($P) or ($P:$U). Again, even if $U is available, both values
    ** of iUpper are requested of whereKeyStats() and the smaller used.
    */
    tRowcnt iLower;
    tRowcnt iUpper;

    if( nEq==p->nColumn ){
      aff = SQLITE_AFF_INTEGER;
    }else{
      aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
    }
    /* Determine iLower and iUpper using ($P) only. */
    if( nEq==0 ){
      iLower = 0;
      iUpper = p->aiRowEst[0];
    }else{
      /* Note: this call could be optimized away - since the same values must 
      ** have been requested when testing key $P in whereEqualScanEst().  */
      whereKeyStats(pParse, p, pRec, 0, a);
      iLower = a[0];
      iUpper = a[0] + a[1];
    }

    /* If possible, improve on the iLower estimate using ($P:$L). */
    if( pLower ){
      int bOk;                    /* True if value is extracted from pExpr */
      Expr *pExpr = pLower->pExpr->pRight;

      assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
      rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
      if( rc==SQLITE_OK && bOk ){
        tRowcnt iNew;
        whereKeyStats(pParse, p, pRec, 0, a);


        iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
        if( iNew>iLower ) iLower = iNew;
      }

    }

    /* If possible, improve on the iUpper estimate using ($P:$U). */
    if( pUpper ){
      int bOk;                    /* True if value is extracted from pExpr */
      Expr *pExpr = pUpper->pExpr->pRight;

      assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
      rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
      if( rc==SQLITE_OK && bOk ){
        tRowcnt iNew;
        whereKeyStats(pParse, p, pRec, 1, a);


        iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
        if( iNew<iUpper ) iUpper = iNew;
      }

    }

    pBuilder->pRec = pRec;
    if( rc==SQLITE_OK ){
      WhereCost nNew;
      if( iUpper>iLower ){
        nNew = whereCost(iUpper - iLower);
      }else{
        nNew = 10;        assert( 10==whereCost(2) );
      }
      if( nNew<nOut ){
        nOut = nNew;
      }
      *pnOut = (WhereCost)nOut;
      WHERETRACE(0x100, ("range scan regions: %u..%u  est=%d\n",
                         (u32)iLower, (u32)iUpper, nOut));
      return SQLITE_OK;
    }
  }
#else
  UNUSED_PARAMETER(pParse);

  UNUSED_PARAMETER(pBuilder);
#endif
  assert( pLower || pUpper );

  /* TUNING:  Each inequality constraint reduces the search space 4-fold.
  ** A BETWEEN operator, therefore, reduces the search space 16-fold */
  if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){
    nOut -= 20;        assert( 20==whereCost(4) );
  }
  if( pUpper ){
    nOut -= 20;        assert( 20==whereCost(4) );
  }
  if( nOut<10 ) nOut = 10;
  *pnOut = (WhereCost)nOut;
  return rc;
}

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
** an equality constraint x=VALUE and where that VALUE occurs in
** the histogram data.  This only works when x is the left-most
** column of an index and sqlite_stat3 histogram data is available
** for that index.  When pExpr==NULL that means the constraint is
** "x IS NULL" instead of "x=VALUE".
**
** Write the estimated row count into *pnRow and return SQLITE_OK. 
** If unable to make an estimate, leave *pnRow unchanged and return
** non-zero.
**
** This routine can fail if it is unable to load a collating sequence
** required for string comparison, or if unable to allocate memory
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
static int whereEqualScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  WhereLoopBuilder *pBuilder,
  Expr *pExpr,         /* Expression for VALUE in the x=VALUE constraint */
  tRowcnt *pnRow       /* Write the revised row estimate here */
){
  Index *p = pBuilder->pNew->u.btree.pIndex;
  int nEq = pBuilder->pNew->u.btree.nEq;
  UnpackedRecord *pRec = pBuilder->pRec;
  u8 aff;                   /* Column affinity */
  int rc;                   /* Subfunction return code */
  tRowcnt a[2];             /* Statistics */
  int bOk;

  assert( nEq>=1 );
  assert( nEq<=(p->nColumn+1) );
  assert( p->aSample!=0 );
  assert( p->nSample>0 );
  assert( pBuilder->nRecValid<nEq );

  /* If values are not available for all fields of the index to the left
  ** of this one, no estimate can be made. Return SQLITE_NOTFOUND. */
  if( pBuilder->nRecValid<(nEq-1) ){
    return SQLITE_NOTFOUND;
  }

  /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue()
  ** below would return the same value.  */
  if( nEq>p->nColumn ){

    *pnRow = 1;
    return SQLITE_OK;
  }

  aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity;
  rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk);
  pBuilder->pRec = pRec;
  if( rc!=SQLITE_OK ) return rc;
  if( bOk==0 ) return SQLITE_NOTFOUND;
  pBuilder->nRecValid = nEq;

  whereKeyStats(pParse, p, pRec, 0, a);

  WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1]));
  *pnRow = a[1];
  


  return rc;
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
** an IN constraint where the right-hand side of the IN operator
** is a list of values.  Example:
**
**        WHERE x IN (1,2,3,4)
**
** Write the estimated row count into *pnRow and return SQLITE_OK. 
** If unable to make an estimate, leave *pnRow unchanged and return
** non-zero.
**
** This routine can fail if it is unable to load a collating sequence
** required for string comparison, or if unable to allocate memory
** for a UTF conversion required for comparison.  The error is stored
** in the pParse structure.
*/
static int whereInScanEst(
  Parse *pParse,       /* Parsing & code generating context */
  WhereLoopBuilder *pBuilder,
  ExprList *pList,     /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
  tRowcnt *pnRow       /* Write the revised row estimate here */
){
  Index *p = pBuilder->pNew->u.btree.pIndex;
  int nRecValid = pBuilder->nRecValid;
  int rc = SQLITE_OK;     /* Subfunction return code */
  tRowcnt nEst;           /* Number of rows for a single term */
  tRowcnt nRowEst = 0;    /* New estimate of the number of rows */
  int i;                  /* Loop counter */

  assert( p->aSample!=0 );
  for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){
    nEst = p->aiRowEst[0];
    rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst);
    nRowEst += nEst;
    pBuilder->nRecValid = nRecValid;
  }

  if( rc==SQLITE_OK ){
    if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
    *pnRow = nRowEst;
    WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst));
  }
  assert( pBuilder->nRecValid==nRecValid );
  return rc;
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */

/*
** Disable a term in the WHERE clause.  Except, do not disable the term
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
** or USING clause of that join.
**
** Consider the term t2.z='ok' in the following queries:
**
**   (1)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
**   (2)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
**   (3)  SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
**
** The t2.z='ok' is disabled in the in (2) because it originates
** in the ON clause.  The term is disabled in (3) because it is not part
** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
**



** Disabling a term causes that term to not be tested in the inner loop
** of the join.  Disabling is an optimization.  When terms are satisfied
** by indices, we disable them to prevent redundant tests in the inner
** loop.  We would get the correct results if nothing were ever disabled,
** but joins might run a little slower.  The trick is to disable as much
** as we can without disabling too much.  If we disabled in (1), we'd get
** the wrong answer.  See ticket #813.
107497
107498
107499
107500
107501
107502
107503
107504
107505
107506
107507
107508
107509
107510
107511
107512
107513
107514
107515
107516
107517
107518
107519
  zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx));
  if( !zAff ){
    pParse->db->mallocFailed = 1;
  }

  /* Evaluate the equality constraints
  */
  assert( pIdx->nColumn>=nEq );
  for(j=0; j<nEq; j++){
    int r1;
    pTerm = pLoop->aLTerm[j];
    assert( pTerm!=0 );
    /* The following true for indices with redundant columns. 
    ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
    testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
    r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
    if( r1!=regBase+j ){
      if( nReg==1 ){
        sqlite3ReleaseTempReg(pParse, regBase);
        regBase = r1;
      }else{
        sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);







|







|







108783
108784
108785
108786
108787
108788
108789
108790
108791
108792
108793
108794
108795
108796
108797
108798
108799
108800
108801
108802
108803
108804
108805
  zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx));
  if( !zAff ){
    pParse->db->mallocFailed = 1;
  }

  /* Evaluate the equality constraints
  */
  assert( zAff==0 || (int)strlen(zAff)>=nEq );
  for(j=0; j<nEq; j++){
    int r1;
    pTerm = pLoop->aLTerm[j];
    assert( pTerm!=0 );
    /* The following true for indices with redundant columns. 
    ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
    testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
    testcase( pTerm->wtFlags & TERM_VIRTUAL );
    r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
    if( r1!=regBase+j ){
      if( nReg==1 ){
        sqlite3ReleaseTempReg(pParse, regBase);
        regBase = r1;
      }else{
        sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
107589
107590
107591
107592
107593
107594
107595

107596
107597
107598
107599
107600
107601
107602
107603
  if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
    return 0;
  }
  sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
  txt.db = db;
  sqlite3StrAccumAppend(&txt, " (", 2);
  for(i=0; i<nEq; i++){

    explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "=");
  }

  j = i;
  if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
    char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
    explainAppendTerm(&txt, i++, z, ">");
  }







>
|







108875
108876
108877
108878
108879
108880
108881
108882
108883
108884
108885
108886
108887
108888
108889
108890
  if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
    return 0;
  }
  sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
  txt.db = db;
  sqlite3StrAccumAppend(&txt, " (", 2);
  for(i=0; i<nEq; i++){
    char *z = (i==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[i]].zName;
    explainAppendTerm(&txt, i, z, "=");
  }

  j = i;
  if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
    char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
    explainAppendTerm(&txt, i++, z, ">");
  }
107705
107706
107707
107708
107709
107710
107711

107712
107713
107714
107715
107716
107717
107718
107719
107720
107721
107722

107723
107724
107725
107726
107727
107728
107729
  int omitTable;       /* True if we use the index only */
  int bRev;            /* True if we need to scan in reverse order */
  WhereLevel *pLevel;  /* The where level to be coded */
  WhereLoop *pLoop;    /* The WhereLoop object being coded */
  WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
  WhereTerm *pTerm;               /* A WHERE clause term */
  Parse *pParse;                  /* Parsing context */

  Vdbe *v;                        /* The prepared stmt under constructions */
  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
  int addrBrk;                    /* Jump here to break out of the loop */
  int addrCont;                   /* Jump here to continue with next cycle */
  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
  int iReleaseReg = 0;      /* Temp register to free before returning */
  Bitmask newNotReady;      /* Return value */

  pParse = pWInfo->pParse;
  v = pParse->pVdbe;
  pWC = &pWInfo->sWC;

  pLevel = &pWInfo->a[iLevel];
  pLoop = pLevel->pWLoop;
  pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
  iCur = pTabItem->iCursor;
  bRev = (pWInfo->revMask>>iLevel)&1;
  omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
           && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;







>











>







108992
108993
108994
108995
108996
108997
108998
108999
109000
109001
109002
109003
109004
109005
109006
109007
109008
109009
109010
109011
109012
109013
109014
109015
109016
109017
109018
  int omitTable;       /* True if we use the index only */
  int bRev;            /* True if we need to scan in reverse order */
  WhereLevel *pLevel;  /* The where level to be coded */
  WhereLoop *pLoop;    /* The WhereLoop object being coded */
  WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
  WhereTerm *pTerm;               /* A WHERE clause term */
  Parse *pParse;                  /* Parsing context */
  sqlite3 *db;                    /* Database connection */
  Vdbe *v;                        /* The prepared stmt under constructions */
  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
  int addrBrk;                    /* Jump here to break out of the loop */
  int addrCont;                   /* Jump here to continue with next cycle */
  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
  int iReleaseReg = 0;      /* Temp register to free before returning */
  Bitmask newNotReady;      /* Return value */

  pParse = pWInfo->pParse;
  v = pParse->pVdbe;
  pWC = &pWInfo->sWC;
  db = pParse->db;
  pLevel = &pWInfo->a[iLevel];
  pLoop = pLevel->pWLoop;
  pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
  iCur = pTabItem->iCursor;
  bRev = (pWInfo->revMask>>iLevel)&1;
  omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
           && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;
107814
107815
107816
107817
107818
107819
107820
107821
107822
107823
107824
107825
107826
107827
107828
    */
    assert( pLoop->u.btree.nEq==1 );
    iReleaseReg = sqlite3GetTempReg(pParse);
    pTerm = pLoop->aLTerm[0];
    assert( pTerm!=0 );
    assert( pTerm->pExpr!=0 );
    assert( omitTable==0 );
    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
    addrNxt = pLevel->addrNxt;
    sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
    sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
    sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
    VdbeComment((v, "pk"));







|







109103
109104
109105
109106
109107
109108
109109
109110
109111
109112
109113
109114
109115
109116
109117
    */
    assert( pLoop->u.btree.nEq==1 );
    iReleaseReg = sqlite3GetTempReg(pParse);
    pTerm = pLoop->aLTerm[0];
    assert( pTerm!=0 );
    assert( pTerm->pExpr!=0 );
    assert( omitTable==0 );
    testcase( pTerm->wtFlags & TERM_VIRTUAL );
    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
    addrNxt = pLevel->addrNxt;
    sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
    sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
    sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
    VdbeComment((v, "pk"));
107862
107863
107864
107865
107866
107867
107868
107869
107870
107871
107872
107873
107874
107875
107876
107877
107878
107879
107880
107881
107882
107883
107884
107885
107886
107887
107888
107889
107890
107891
107892
107893
107894
107895
           /* TK_GE */  OP_SeekGe
      };
      assert( TK_LE==TK_GT+1 );      /* Make sure the ordering.. */
      assert( TK_LT==TK_GT+2 );      /*  ... of the TK_xx values... */
      assert( TK_GE==TK_GT+3 );      /*  ... is correcct. */

      assert( (pStart->wtFlags & TERM_VNULL)==0 );
      testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
      pX = pStart->pExpr;
      assert( pX!=0 );
      testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
      r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
      sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
      VdbeComment((v, "pk"));
      sqlite3ExprCacheAffinityChange(pParse, r1, 1);
      sqlite3ReleaseTempReg(pParse, rTemp);
      disableTerm(pLevel, pStart);
    }else{
      sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
    }
    if( pEnd ){
      Expr *pX;
      pX = pEnd->pExpr;
      assert( pX!=0 );
      assert( (pEnd->wtFlags & TERM_VNULL)==0 );
      testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
      testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
      memEndValue = ++pParse->nMem;
      sqlite3ExprCode(pParse, pX->pRight, memEndValue);
      if( pX->op==TK_LT || pX->op==TK_GT ){
        testOp = bRev ? OP_Le : OP_Ge;
      }else{
        testOp = bRev ? OP_Lt : OP_Gt;
      }







|


















|







109151
109152
109153
109154
109155
109156
109157
109158
109159
109160
109161
109162
109163
109164
109165
109166
109167
109168
109169
109170
109171
109172
109173
109174
109175
109176
109177
109178
109179
109180
109181
109182
109183
109184
           /* TK_GE */  OP_SeekGe
      };
      assert( TK_LE==TK_GT+1 );      /* Make sure the ordering.. */
      assert( TK_LT==TK_GT+2 );      /*  ... of the TK_xx values... */
      assert( TK_GE==TK_GT+3 );      /*  ... is correcct. */

      assert( (pStart->wtFlags & TERM_VNULL)==0 );
      testcase( pStart->wtFlags & TERM_VIRTUAL );
      pX = pStart->pExpr;
      assert( pX!=0 );
      testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
      r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
      sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
      VdbeComment((v, "pk"));
      sqlite3ExprCacheAffinityChange(pParse, r1, 1);
      sqlite3ReleaseTempReg(pParse, rTemp);
      disableTerm(pLevel, pStart);
    }else{
      sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
    }
    if( pEnd ){
      Expr *pX;
      pX = pEnd->pExpr;
      assert( pX!=0 );
      assert( (pEnd->wtFlags & TERM_VNULL)==0 );
      testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
      testcase( pEnd->wtFlags & TERM_VIRTUAL );
      memEndValue = ++pParse->nMem;
      sqlite3ExprCode(pParse, pX->pRight, memEndValue);
      if( pX->op==TK_LT || pX->op==TK_GT ){
        testOp = bRev ? OP_Le : OP_Ge;
      }else{
        testOp = bRev ? OP_Lt : OP_Gt;
      }
108006
108007
108008
108009
108010
108011
108012
108013
108014
108015
108016
108017
108018
108019
108020
    }

    /* Generate code to evaluate all constraint terms using == or IN
    ** and store the values of those terms in an array of registers
    ** starting at regBase.
    */
    regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
    zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
    addrNxt = pLevel->addrNxt;

    /* If we are doing a reverse order scan on an ascending index, or
    ** a forward order scan on a descending index, interchange the 
    ** start and end terms (pRangeStart and pRangeEnd).
    */
    if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))







|







109295
109296
109297
109298
109299
109300
109301
109302
109303
109304
109305
109306
109307
109308
109309
    }

    /* Generate code to evaluate all constraint terms using == or IN
    ** and store the values of those terms in an array of registers
    ** starting at regBase.
    */
    regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
    zEndAff = sqlite3DbStrDup(db, zStartAff);
    addrNxt = pLevel->addrNxt;

    /* If we are doing a reverse order scan on an ascending index, or
    ** a forward order scan on a descending index, interchange the 
    ** start and end terms (pRangeStart and pRangeEnd).
    */
    if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
108047
108048
108049
108050
108051
108052
108053
108054
108055
108056
108057
108058
108059
108060
108061
          zStartAff[nEq] = SQLITE_AFF_NONE;
        }
        if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
          zStartAff[nEq] = SQLITE_AFF_NONE;
        }
      }  
      nConstraint++;
      testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
    }else if( isMinQuery ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
      nConstraint++;
      startEq = 0;
      start_constraints = 1;
    }
    codeApplyAffinity(pParse, regBase, nConstraint, zStartAff);







|







109336
109337
109338
109339
109340
109341
109342
109343
109344
109345
109346
109347
109348
109349
109350
          zStartAff[nEq] = SQLITE_AFF_NONE;
        }
        if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
          zStartAff[nEq] = SQLITE_AFF_NONE;
        }
      }  
      nConstraint++;
      testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
    }else if( isMinQuery ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
      nConstraint++;
      startEq = 0;
      start_constraints = 1;
    }
    codeApplyAffinity(pParse, regBase, nConstraint, zStartAff);
108089
108090
108091
108092
108093
108094
108095
108096
108097
108098
108099
108100
108101
108102
108103
108104
108105
108106
        }
        if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
          zEndAff[nEq] = SQLITE_AFF_NONE;
        }
      }  
      codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
      nConstraint++;
      testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
    }
    sqlite3DbFree(pParse->db, zStartAff);
    sqlite3DbFree(pParse->db, zEndAff);

    /* Top of the loop body */
    pLevel->p2 = sqlite3VdbeCurrentAddr(v);

    /* Check if the index cursor is past the end of the range. */
    op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
    testcase( op==OP_Noop );







|

|
|







109378
109379
109380
109381
109382
109383
109384
109385
109386
109387
109388
109389
109390
109391
109392
109393
109394
109395
        }
        if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
          zEndAff[nEq] = SQLITE_AFF_NONE;
        }
      }  
      codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
      nConstraint++;
      testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
    }
    sqlite3DbFree(db, zStartAff);
    sqlite3DbFree(db, zEndAff);

    /* Top of the loop body */
    pLevel->p2 = sqlite3VdbeCurrentAddr(v);

    /* Check if the index cursor is past the end of the range. */
    op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
    testcase( op==OP_Noop );
108219
108220
108221
108222
108223
108224
108225
108226
108227
108228
108229
108230
108231
108232
108233
    ** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
    ** This becomes the SrcList in the recursive call to sqlite3WhereBegin().
    */
    if( pWInfo->nLevel>1 ){
      int nNotReady;                 /* The number of notReady tables */
      struct SrcList_item *origSrc;     /* Original list of tables */
      nNotReady = pWInfo->nLevel - iLevel - 1;
      pOrTab = sqlite3StackAllocRaw(pParse->db,
                            sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
      if( pOrTab==0 ) return notReady;
      pOrTab->nAlloc = (u8)(nNotReady + 1);
      pOrTab->nSrc = pOrTab->nAlloc;
      memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
      origSrc = pWInfo->pTabList->a;
      for(k=1; k<=nNotReady; k++){







|







109508
109509
109510
109511
109512
109513
109514
109515
109516
109517
109518
109519
109520
109521
109522
    ** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
    ** This becomes the SrcList in the recursive call to sqlite3WhereBegin().
    */
    if( pWInfo->nLevel>1 ){
      int nNotReady;                 /* The number of notReady tables */
      struct SrcList_item *origSrc;     /* Original list of tables */
      nNotReady = pWInfo->nLevel - iLevel - 1;
      pOrTab = sqlite3StackAllocRaw(db,
                            sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
      if( pOrTab==0 ) return notReady;
      pOrTab->nAlloc = (u8)(nNotReady + 1);
      pOrTab->nSrc = pOrTab->nAlloc;
      memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
      origSrc = pWInfo->pTabList->a;
      for(k=1; k<=nNotReady; k++){
108273
108274
108275
108276
108277
108278
108279
108280
108281
108282
108283
108284
108285
108286
108287
108288
108289
108290
108291
108292
108293
108294
108295
108296
108297
108298
108299
108300
108301
108302
108303
108304
108305
108306
108307
108308
      int iTerm;
      for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
        Expr *pExpr = pWC->a[iTerm].pExpr;
        if( &pWC->a[iTerm] == pTerm ) continue;
        if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
        if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue;
        if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
        pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
        pAndExpr = sqlite3ExprAnd(pParse->db, pAndExpr, pExpr);
      }
      if( pAndExpr ){
        pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
      }
    }

    for(ii=0; ii<pOrWc->nTerm; ii++){
      WhereTerm *pOrTerm = &pOrWc->a[ii];
      if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
        WhereInfo *pSubWInfo;          /* Info for single OR-term scan */
        Expr *pOrExpr = pOrTerm->pExpr;
        if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
          pAndExpr->pLeft = pOrExpr;
          pOrExpr = pAndExpr;
        }
        /* Loop through table entries that match term pOrTerm. */
        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                        WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
                        WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
        assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed );
        if( pSubWInfo ){
          WhereLoop *pSubLoop;
          explainOneScan(
              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
          );
          if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
            int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);







|
|



















|







109562
109563
109564
109565
109566
109567
109568
109569
109570
109571
109572
109573
109574
109575
109576
109577
109578
109579
109580
109581
109582
109583
109584
109585
109586
109587
109588
109589
109590
109591
109592
109593
109594
109595
109596
109597
      int iTerm;
      for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
        Expr *pExpr = pWC->a[iTerm].pExpr;
        if( &pWC->a[iTerm] == pTerm ) continue;
        if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
        if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue;
        if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
        pExpr = sqlite3ExprDup(db, pExpr, 0);
        pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
      }
      if( pAndExpr ){
        pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
      }
    }

    for(ii=0; ii<pOrWc->nTerm; ii++){
      WhereTerm *pOrTerm = &pOrWc->a[ii];
      if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
        WhereInfo *pSubWInfo;          /* Info for single OR-term scan */
        Expr *pOrExpr = pOrTerm->pExpr;
        if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
          pAndExpr->pLeft = pOrExpr;
          pOrExpr = pAndExpr;
        }
        /* Loop through table entries that match term pOrTerm. */
        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                        WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
                        WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
        assert( pSubWInfo || pParse->nErr || db->mallocFailed );
        if( pSubWInfo ){
          WhereLoop *pSubLoop;
          explainOneScan(
              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
          );
          if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
            int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
108349
108350
108351
108352
108353
108354
108355
108356
108357
108358
108359
108360
108361
108362
108363
108364
108365
108366
108367
108368
108369
108370
108371
108372
108373
108374
108375
108376
108377
108378
108379
108380
108381
108382
108383
108384
108385
108386
108387
108388
108389
108390
108391
108392
108393
108394
108395
108396
108397
        }
      }
    }
    pLevel->u.pCovidx = pCov;
    if( pCov ) pLevel->iIdxCur = iCovCur;
    if( pAndExpr ){
      pAndExpr->pLeft = 0;
      sqlite3ExprDelete(pParse->db, pAndExpr);
    }
    sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
    sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
    sqlite3VdbeResolveLabel(v, iLoopBody);

    if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab);
    if( !untestedTerms ) disableTerm(pLevel, pTerm);
  }else
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */

  {
    /* Case 6:  There is no usable index.  We must do a complete
    **          scan of the entire table.
    */
    static const u8 aStep[] = { OP_Next, OP_Prev };
    static const u8 aStart[] = { OP_Rewind, OP_Last };
    assert( bRev==0 || bRev==1 );
    pLevel->op = aStep[bRev];
    pLevel->p1 = iCur;
    pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
    pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
  }
  newNotReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);

  /* Insert code to test every subexpression that can be completely
  ** computed using the current set of tables.
  **
  ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
  ** the use of indices become tests that are evaluated against each row of
  ** the relevant input tables.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE;
    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
    testcase( pTerm->wtFlags & TERM_CODED );
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( (pTerm->prereqAll & newNotReady)!=0 ){
      testcase( pWInfo->untestedTerms==0
               && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
      pWInfo->untestedTerms = 1;
      continue;







|





|




















<
<
<
<



|







109638
109639
109640
109641
109642
109643
109644
109645
109646
109647
109648
109649
109650
109651
109652
109653
109654
109655
109656
109657
109658
109659
109660
109661
109662
109663
109664
109665
109666
109667
109668
109669
109670
109671




109672
109673
109674
109675
109676
109677
109678
109679
109680
109681
109682
        }
      }
    }
    pLevel->u.pCovidx = pCov;
    if( pCov ) pLevel->iIdxCur = iCovCur;
    if( pAndExpr ){
      pAndExpr->pLeft = 0;
      sqlite3ExprDelete(db, pAndExpr);
    }
    sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
    sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
    sqlite3VdbeResolveLabel(v, iLoopBody);

    if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
    if( !untestedTerms ) disableTerm(pLevel, pTerm);
  }else
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */

  {
    /* Case 6:  There is no usable index.  We must do a complete
    **          scan of the entire table.
    */
    static const u8 aStep[] = { OP_Next, OP_Prev };
    static const u8 aStart[] = { OP_Rewind, OP_Last };
    assert( bRev==0 || bRev==1 );
    pLevel->op = aStep[bRev];
    pLevel->p1 = iCur;
    pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
    pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
  }
  newNotReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);

  /* Insert code to test every subexpression that can be completely
  ** computed using the current set of tables.




  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE;
    testcase( pTerm->wtFlags & TERM_VIRTUAL );
    testcase( pTerm->wtFlags & TERM_CODED );
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( (pTerm->prereqAll & newNotReady)!=0 ){
      testcase( pWInfo->untestedTerms==0
               && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
      pWInfo->untestedTerms = 1;
      continue;
108410
108411
108412
108413
108414
108415
108416
108417
108418
108419
108420
108421
108422
108423
108424
108425
108426
108427
108428
108429
108430
108431
108432


108433
108434
108435


108436
108437
108438
108439
108440
108441
108442
108443
108444
108445
108446
108447
108448
108449
108450
108451
108452
108453
108454
  **
  ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
  ** and we are coding the t1 loop and the t2 loop has not yet coded,
  ** then we cannot use the "t1.a=t2.b" constraint, but we can code
  ** the implied "t1.a=123" constraint.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE;
    WhereTerm *pAlt;
    Expr sEq;
    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
    if( pTerm->leftCursor!=iCur ) continue;
    if( pLevel->iLeftJoin ) continue;
    pE = pTerm->pExpr;
    assert( !ExprHasProperty(pE, EP_FromJoin) );
    assert( (pTerm->prereqRight & newNotReady)!=0 );
    pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
    if( pAlt==0 ) continue;
    if( pAlt->wtFlags & (TERM_CODED) ) continue;
    testcase( pAlt->eOperator & WO_EQ );
    testcase( pAlt->eOperator & WO_IN );
    VdbeNoopComment((v, "begin transitive constraint"));


    sEq = *pAlt->pExpr;
    sEq.pLeft = pE->pLeft;
    sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);


  }

  /* For a LEFT OUTER JOIN, generate code that will record the fact that
  ** at least one row of the right table has matched the left table.  
  */
  if( pLevel->iLeftJoin ){
    pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
    VdbeComment((v, "record LEFT JOIN hit"));
    sqlite3ExprCacheClear(pParse);
    for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
      testcase( pTerm->wtFlags & TERM_VIRTUAL );  /* IMP: R-30575-11662 */
      testcase( pTerm->wtFlags & TERM_CODED );
      if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
      if( (pTerm->prereqAll & newNotReady)!=0 ){
        assert( pWInfo->untestedTerms );
        continue;
      }
      assert( pTerm->pExpr );







|

<













>
>
|
|
|
>
>











|







109695
109696
109697
109698
109699
109700
109701
109702
109703

109704
109705
109706
109707
109708
109709
109710
109711
109712
109713
109714
109715
109716
109717
109718
109719
109720
109721
109722
109723
109724
109725
109726
109727
109728
109729
109730
109731
109732
109733
109734
109735
109736
109737
109738
109739
109740
109741
109742
  **
  ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
  ** and we are coding the t1 loop and the t2 loop has not yet coded,
  ** then we cannot use the "t1.a=t2.b" constraint, but we can code
  ** the implied "t1.a=123" constraint.
  */
  for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
    Expr *pE, *pEAlt;
    WhereTerm *pAlt;

    if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
    if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
    if( pTerm->leftCursor!=iCur ) continue;
    if( pLevel->iLeftJoin ) continue;
    pE = pTerm->pExpr;
    assert( !ExprHasProperty(pE, EP_FromJoin) );
    assert( (pTerm->prereqRight & newNotReady)!=0 );
    pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
    if( pAlt==0 ) continue;
    if( pAlt->wtFlags & (TERM_CODED) ) continue;
    testcase( pAlt->eOperator & WO_EQ );
    testcase( pAlt->eOperator & WO_IN );
    VdbeNoopComment((v, "begin transitive constraint"));
    pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
    if( pEAlt ){
      *pEAlt = *pAlt->pExpr;
      pEAlt->pLeft = pE->pLeft;
      sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
      sqlite3StackFree(db, pEAlt);
    }
  }

  /* For a LEFT OUTER JOIN, generate code that will record the fact that
  ** at least one row of the right table has matched the left table.  
  */
  if( pLevel->iLeftJoin ){
    pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
    VdbeComment((v, "record LEFT JOIN hit"));
    sqlite3ExprCacheClear(pParse);
    for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
      testcase( pTerm->wtFlags & TERM_VIRTUAL );
      testcase( pTerm->wtFlags & TERM_CODED );
      if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
      if( (pTerm->prereqAll & newNotReady)!=0 ){
        assert( pWInfo->untestedTerms );
        continue;
      }
      assert( pTerm->pExpr );
108664
108665
108666
108667
108668
108669
108670

108671
108672
108673

108674

108675
108676
108677
108678
108679
108680
108681
108682
108683
108684
108685
108686
108687
108688
108689
108690
108691
108692

108693
108694
108695
108696
108697

108698
108699
108700
108701
108702
108703
108704
    ** case first.  Hence compatible candidate WhereLoops never have a larger
    ** rSetup. Call this SETUP-INVARIANT */
    assert( p->rSetup>=pTemplate->rSetup );

    if( (p->prereq & pTemplate->prereq)==p->prereq
     && p->rSetup<=pTemplate->rSetup
     && p->rRun<=pTemplate->rRun

    ){
      /* This branch taken when p is equal or better than pTemplate in 
      ** all of (1) dependences (2) setup-cost, and (3) run-cost. */

      assert( p->rSetup==pTemplate->rSetup );

      if( p->nLTerm<pTemplate->nLTerm
       && (p->wsFlags & WHERE_INDEXED)!=0
       && (pTemplate->wsFlags & WHERE_INDEXED)!=0
       && p->u.btree.pIndex==pTemplate->u.btree.pIndex
       && p->prereq==pTemplate->prereq
      ){
        /* Overwrite an existing WhereLoop with an similar one that uses
        ** more terms of the index */
        pNext = p->pNextLoop;
        break;
      }else{
        /* pTemplate is not helpful.
        ** Return without changing or adding anything */
        goto whereLoopInsert_noop;
      }
    }
    if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
     && p->rRun>=pTemplate->rRun

     && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */
    ){
      /* Overwrite an existing WhereLoop with a better one: one that is
      ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost
      ** and is no worse in any of those categories. */

      pNext = p->pNextLoop;
      break;
    }
  }

  /* If we reach this point it means that either p[] should be overwritten
  ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new







>


|
>

>
|



<













>



|
|
>







109952
109953
109954
109955
109956
109957
109958
109959
109960
109961
109962
109963
109964
109965
109966
109967
109968
109969

109970
109971
109972
109973
109974
109975
109976
109977
109978
109979
109980
109981
109982
109983
109984
109985
109986
109987
109988
109989
109990
109991
109992
109993
109994
109995
109996
    ** case first.  Hence compatible candidate WhereLoops never have a larger
    ** rSetup. Call this SETUP-INVARIANT */
    assert( p->rSetup>=pTemplate->rSetup );

    if( (p->prereq & pTemplate->prereq)==p->prereq
     && p->rSetup<=pTemplate->rSetup
     && p->rRun<=pTemplate->rRun
     && p->nOut<=pTemplate->nOut
    ){
      /* This branch taken when p is equal or better than pTemplate in 
      ** all of (1) dependencies (2) setup-cost, (3) run-cost, and
      ** (4) number of output rows. */
      assert( p->rSetup==pTemplate->rSetup );
      if( p->prereq==pTemplate->prereq
       && p->nLTerm<pTemplate->nLTerm
       && (p->wsFlags & WHERE_INDEXED)!=0
       && (pTemplate->wsFlags & WHERE_INDEXED)!=0
       && p->u.btree.pIndex==pTemplate->u.btree.pIndex

      ){
        /* Overwrite an existing WhereLoop with an similar one that uses
        ** more terms of the index */
        pNext = p->pNextLoop;
        break;
      }else{
        /* pTemplate is not helpful.
        ** Return without changing or adding anything */
        goto whereLoopInsert_noop;
      }
    }
    if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
     && p->rRun>=pTemplate->rRun
     && p->nOut>=pTemplate->nOut
     && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */
    ){
      /* Overwrite an existing WhereLoop with a better one: one that is
      ** better at one of (1) dependencies, (2) setup-cost, (3) run-cost
      ** or (4) number of output rows, and is no worse in any of those
      ** categories. */
      pNext = p->pNextLoop;
      break;
    }
  }

  /* If we reach this point it means that either p[] should be overwritten
  ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
108802
108803
108804
108805
108806
108807
108808
108809
108810



108811

108812
108813

108814


108815
108816
108817
108818
108819
108820
108821
  saved_wsFlags = pNew->wsFlags;
  saved_prereq = pNew->prereq;
  saved_nOut = pNew->nOut;
  pNew->rSetup = 0;
  rLogSize = estLog(whereCost(pProbe->aiRowEst[0]));
  for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
    int nIn = 0;
    if( pTerm->prereqRight & pNew->maskSelf ) continue;
#ifdef SQLITE_ENABLE_STAT3



    if( (pTerm->wtFlags & TERM_VNULL)!=0 && pSrc->pTab->aCol[iCol].notNull ){

      continue; /* skip IS NOT NULL constraints on a NOT NULL column */
    }

#endif


    pNew->wsFlags = saved_wsFlags;
    pNew->u.btree.nEq = saved_nEq;
    pNew->nLTerm = saved_nLTerm;
    if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
    pNew->aLTerm[pNew->nLTerm++] = pTerm;
    pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf;
    pNew->rRun = rLogSize; /* Baseline cost is log2(N).  Adjustments below */







<
|
>
>
>
|
>
|

>
|
>
>







110094
110095
110096
110097
110098
110099
110100

110101
110102
110103
110104
110105
110106
110107
110108
110109
110110
110111
110112
110113
110114
110115
110116
110117
110118
110119
  saved_wsFlags = pNew->wsFlags;
  saved_prereq = pNew->prereq;
  saved_nOut = pNew->nOut;
  pNew->rSetup = 0;
  rLogSize = estLog(whereCost(pProbe->aiRowEst[0]));
  for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
    int nIn = 0;

#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    int nRecValid = pBuilder->nRecValid;
#endif
    if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
     && (iCol<0 || pSrc->pTab->aCol[iCol].notNull)
    ){
      continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
    }
    if( pTerm->prereqRight & pNew->maskSelf ) continue;

    assert( pNew->nOut==saved_nOut );

    pNew->wsFlags = saved_wsFlags;
    pNew->u.btree.nEq = saved_nEq;
    pNew->nLTerm = saved_nLTerm;
    if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
    pNew->aLTerm[pNew->nLTerm++] = pTerm;
    pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf;
    pNew->rRun = rLogSize; /* Baseline cost is log2(N).  Adjustments below */
108864
108865
108866
108867
108868
108869
108870
108871
108872
108873
108874
108875
108876

108877

108878


108879
108880
108881
108882
108883
108884
108885
108886
108887


108888


108889
108890
108891
108892
108893
108894
108895
108896
108897
108898
108899
108900
108901
108902
108903
108904




108905
108906
108907
108908
108909
108910
108911
      pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
      pTop = pTerm;
      pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
                     pNew->aLTerm[pNew->nLTerm-2] : 0;
    }
    if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
      /* Adjust nOut and rRun for STAT3 range values */
      WhereCost rDiv;
      whereRangeScanEst(pParse, pProbe, pNew->u.btree.nEq,
                        pBtm, pTop, &rDiv);
      pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10;
    }
#ifdef SQLITE_ENABLE_STAT3

    if( pNew->u.btree.nEq==1 && pProbe->nSample

     &&  OptimizationEnabled(db, SQLITE_Stat3) ){


      tRowcnt nOut = 0;
      if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
        testcase( pTerm->eOperator & WO_EQ );
        testcase( pTerm->eOperator & WO_ISNULL );
        rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
      }else if( (pTerm->eOperator & WO_IN)
             &&  !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)  ){
        rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
      }


      if( rc==SQLITE_OK ) pNew->nOut = whereCost(nOut);


    }
#endif
    if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
      /* Each row involves a step of the index, then a binary search of
      ** the main table */
      pNew->rRun =  whereCostAdd(pNew->rRun, rLogSize>27 ? rLogSize-17 : 10);
    }
    /* Step cost for each output row */
    pNew->rRun = whereCostAdd(pNew->rRun, pNew->nOut);
    /* TBD: Adjust nOut for additional constraints */
    rc = whereLoopInsert(pBuilder, pNew);
    if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
     && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0))
    ){
      whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
    }




  }
  pNew->prereq = saved_prereq;
  pNew->u.btree.nEq = saved_nEq;
  pNew->wsFlags = saved_wsFlags;
  pNew->nOut = saved_nOut;
  pNew->nLTerm = saved_nLTerm;
  return rc;







|
|
<
<

|
>
|
>
|
>
>




|

|
|

>
>
|
>
>
















>
>
>
>







110162
110163
110164
110165
110166
110167
110168
110169
110170


110171
110172
110173
110174
110175
110176
110177
110178
110179
110180
110181
110182
110183
110184
110185
110186
110187
110188
110189
110190
110191
110192
110193
110194
110195
110196
110197
110198
110199
110200
110201
110202
110203
110204
110205
110206
110207
110208
110209
110210
110211
110212
110213
110214
110215
110216
110217
110218
110219
      pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
      pTop = pTerm;
      pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
                     pNew->aLTerm[pNew->nLTerm-2] : 0;
    }
    if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
      /* Adjust nOut and rRun for STAT3 range values */
      assert( pNew->nOut==saved_nOut );
      whereRangeScanEst(pParse, pBuilder, pBtm, pTop, &pNew->nOut);


    }
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    if( nInMul==0 
     && pProbe->nSample 
     && pNew->u.btree.nEq<=pProbe->nSampleCol
     && OptimizationEnabled(db, SQLITE_Stat3) 
    ){
      Expr *pExpr = pTerm->pExpr;
      tRowcnt nOut = 0;
      if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
        testcase( pTerm->eOperator & WO_EQ );
        testcase( pTerm->eOperator & WO_ISNULL );
        rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
      }else if( (pTerm->eOperator & WO_IN)
             &&  !ExprHasProperty(pExpr, EP_xIsSelect)  ){
        rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut);
      }
      assert( nOut==0 || rc==SQLITE_OK );
      if( nOut ){
        nOut = whereCost(nOut);
        pNew->nOut = MIN(nOut, saved_nOut);
      }
    }
#endif
    if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
      /* Each row involves a step of the index, then a binary search of
      ** the main table */
      pNew->rRun =  whereCostAdd(pNew->rRun, rLogSize>27 ? rLogSize-17 : 10);
    }
    /* Step cost for each output row */
    pNew->rRun = whereCostAdd(pNew->rRun, pNew->nOut);
    /* TBD: Adjust nOut for additional constraints */
    rc = whereLoopInsert(pBuilder, pNew);
    if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
     && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0))
    ){
      whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
    }
    pNew->nOut = saved_nOut;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    pBuilder->nRecValid = nRecValid;
#endif
  }
  pNew->prereq = saved_prereq;
  pNew->u.btree.nEq = saved_nEq;
  pNew->wsFlags = saved_wsFlags;
  pNew->nOut = saved_nOut;
  pNew->nLTerm = saved_nLTerm;
  return rc;
108946
108947
108948
108949
108950
108951
108952

108953
108954
108955
108956
108957
108958
108959











108960
108961
108962
108963
108964
108965
108966
** the table is used by an index.  Only the first 63 columns are considered.
*/
static Bitmask columnsInIndex(Index *pIdx){
  Bitmask m = 0;
  int j;
  for(j=pIdx->nColumn-1; j>=0; j--){
    int x = pIdx->aiColumn[j];

    testcase( x==BMS-1 );
    testcase( x==BMS-2 );
    if( x<BMS-1 ) m |= MASKBIT(x);
  }
  return m;
}













/*
** Add all WhereLoop objects for a single table of the join where the table
** is idenfied by pBuilder->pNew->iTab.  That table is guaranteed to be
** a b-tree table, not a virtual table.
*/
static int whereLoopAddBtree(







>







>
>
>
>
>
>
>
>
>
>
>







110254
110255
110256
110257
110258
110259
110260
110261
110262
110263
110264
110265
110266
110267
110268
110269
110270
110271
110272
110273
110274
110275
110276
110277
110278
110279
110280
110281
110282
110283
110284
110285
110286
** the table is used by an index.  Only the first 63 columns are considered.
*/
static Bitmask columnsInIndex(Index *pIdx){
  Bitmask m = 0;
  int j;
  for(j=pIdx->nColumn-1; j>=0; j--){
    int x = pIdx->aiColumn[j];
    assert( x>=0 );
    testcase( x==BMS-1 );
    testcase( x==BMS-2 );
    if( x<BMS-1 ) m |= MASKBIT(x);
  }
  return m;
}

/* Check to see if a partial index with pPartIndexWhere can be used
** in the current query.  Return true if it can be and false if not.
*/
static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
  int i;
  WhereTerm *pTerm;
  for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
    if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1;
  }
  return 0;
}

/*
** Add all WhereLoop objects for a single table of the join where the table
** is idenfied by pBuilder->pNew->iTab.  That table is guaranteed to be
** a b-tree table, not a virtual table.
*/
static int whereLoopAddBtree(
108976
108977
108978
108979
108980
108981
108982

108983
108984
108985
108986
108987

108988
108989
108990
108991
108992
108993
108994
  struct SrcList_item *pSrc;  /* The FROM clause btree term to add */
  WhereLoop *pNew;            /* Template WhereLoop object */
  int rc = SQLITE_OK;         /* Return code */
  int iSortIdx = 1;           /* Index number */
  int b;                      /* A boolean value */
  WhereCost rSize;            /* number of rows in the table */
  WhereCost rLogSize;         /* Logarithm of the number of rows in the table */

  
  pNew = pBuilder->pNew;
  pWInfo = pBuilder->pWInfo;
  pTabList = pWInfo->pTabList;
  pSrc = pTabList->a + pNew->iTab;

  assert( !IsVirtual(pSrc->pTab) );

  if( pSrc->pIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->pIndex;
  }else{
    /* There is no INDEXED BY clause.  Create a fake Index object in local







>





>







110296
110297
110298
110299
110300
110301
110302
110303
110304
110305
110306
110307
110308
110309
110310
110311
110312
110313
110314
110315
110316
  struct SrcList_item *pSrc;  /* The FROM clause btree term to add */
  WhereLoop *pNew;            /* Template WhereLoop object */
  int rc = SQLITE_OK;         /* Return code */
  int iSortIdx = 1;           /* Index number */
  int b;                      /* A boolean value */
  WhereCost rSize;            /* number of rows in the table */
  WhereCost rLogSize;         /* Logarithm of the number of rows in the table */
  WhereClause *pWC;           /* The parsed WHERE clause */
  
  pNew = pBuilder->pNew;
  pWInfo = pBuilder->pWInfo;
  pTabList = pWInfo->pTabList;
  pSrc = pTabList->a + pNew->iTab;
  pWC = pBuilder->pWC;
  assert( !IsVirtual(pSrc->pTab) );

  if( pSrc->pIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->pIndex;
  }else{
    /* There is no INDEXED BY clause.  Create a fake Index object in local
109011
109012
109013
109014
109015
109016
109017

109018
109019
109020
109021
109022
109023
109024
109025
109026
109027
109028
109029
109030
109031
109032
109033
109034
      sPk.pNext = pFirst;
    }
    pProbe = &sPk;
  }
  rSize = whereCost(pSrc->pTab->nRowEst);
  rLogSize = estLog(rSize);


  /* Automatic indexes */
  if( !pBuilder->pOrSet
   && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
   && pSrc->pIndex==0
   && !pSrc->viaCoroutine
   && !pSrc->notIndexed
   && !pSrc->isCorrelated
  ){
    /* Generate auto-index WhereLoops */
    WhereClause *pWC = pBuilder->pWC;
    WhereTerm *pTerm;
    WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
    for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
      if( pTerm->prereqRight & pNew->maskSelf ) continue;
      if( termCanDriveIndex(pTerm, pSrc, 0) ){
        pNew->u.btree.nEq = 1;
        pNew->u.btree.pIndex = 0;







>









<







110333
110334
110335
110336
110337
110338
110339
110340
110341
110342
110343
110344
110345
110346
110347
110348
110349

110350
110351
110352
110353
110354
110355
110356
      sPk.pNext = pFirst;
    }
    pProbe = &sPk;
  }
  rSize = whereCost(pSrc->pTab->nRowEst);
  rLogSize = estLog(rSize);

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet
   && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
   && pSrc->pIndex==0
   && !pSrc->viaCoroutine
   && !pSrc->notIndexed
   && !pSrc->isCorrelated
  ){
    /* Generate auto-index WhereLoops */

    WhereTerm *pTerm;
    WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
    for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
      if( pTerm->prereqRight & pNew->maskSelf ) continue;
      if( termCanDriveIndex(pTerm, pSrc, 0) ){
        pNew->u.btree.nEq = 1;
        pNew->u.btree.pIndex = 0;
109046
109047
109048
109049
109050
109051
109052

109053
109054
109055
109056




109057
109058
109059
109060
109061
109062
109063
        pNew->rRun = whereCostAdd(rLogSize,pNew->nOut);
        pNew->wsFlags = WHERE_AUTO_INDEX;
        pNew->prereq = mExtra | pTerm->prereqRight;
        rc = whereLoopInsert(pBuilder, pNew);
      }
    }
  }


  /* Loop over all indices
  */
  for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){




    pNew->u.btree.nEq = 0;
    pNew->nLTerm = 0;
    pNew->iSortIdx = 0;
    pNew->rSetup = 0;
    pNew->prereq = mExtra;
    pNew->nOut = rSize;
    pNew->u.btree.pIndex = pProbe;







>




>
>
>
>







110368
110369
110370
110371
110372
110373
110374
110375
110376
110377
110378
110379
110380
110381
110382
110383
110384
110385
110386
110387
110388
110389
110390
        pNew->rRun = whereCostAdd(rLogSize,pNew->nOut);
        pNew->wsFlags = WHERE_AUTO_INDEX;
        pNew->prereq = mExtra | pTerm->prereqRight;
        rc = whereLoopInsert(pBuilder, pNew);
      }
    }
  }
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */

  /* Loop over all indices
  */
  for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
    if( pProbe->pPartIdxWhere!=0
     && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){
      continue;  /* Partial index inappropriate for this query */
    }
    pNew->u.btree.nEq = 0;
    pNew->nLTerm = 0;
    pNew->iSortIdx = 0;
    pNew->rSetup = 0;
    pNew->prereq = mExtra;
    pNew->nOut = rSize;
    pNew->u.btree.pIndex = pProbe;
109108
109109
109110
109111
109112
109113
109114

109115





109116
109117
109118
109119
109120
109121
109122
          ** which we will simplify to just N*log2(N) */
          pNew->rRun = rSize + rLogSize;
        }
        rc = whereLoopInsert(pBuilder, pNew);
        if( rc ) break;
      }
    }

    rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);






    /* If there was an INDEXED BY clause, then only that one index is
    ** considered. */
    if( pSrc->pIndex ) break;
  }
  return rc;
}







>

>
>
>
>
>







110435
110436
110437
110438
110439
110440
110441
110442
110443
110444
110445
110446
110447
110448
110449
110450
110451
110452
110453
110454
110455
          ** which we will simplify to just N*log2(N) */
          pNew->rRun = rSize + rLogSize;
        }
        rc = whereLoopInsert(pBuilder, pNew);
        if( rc ) break;
      }
    }

    rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    sqlite3Stat4ProbeFree(pBuilder->pRec);
    pBuilder->nRecValid = 0;
    pBuilder->pRec = 0;
#endif

    /* If there was an INDEXED BY clause, then only that one index is
    ** considered. */
    if( pSrc->pIndex ) break;
  }
  return rc;
}
109305
109306
109307
109308
109309
109310
109311

109312
109313
109314
109315
109316
109317
109318
  WhereOrSet sSum, sCur, sPrev;
  struct SrcList_item *pItem;
  
  pWC = pBuilder->pWC;
  if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
  pWCEnd = pWC->a + pWC->nTerm;
  pNew = pBuilder->pNew;


  for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
    if( (pTerm->eOperator & WO_OR)!=0
     && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 
    ){
      WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
      WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];







>







110638
110639
110640
110641
110642
110643
110644
110645
110646
110647
110648
110649
110650
110651
110652
  WhereOrSet sSum, sCur, sPrev;
  struct SrcList_item *pItem;
  
  pWC = pBuilder->pWC;
  if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
  pWCEnd = pWC->a + pWC->nTerm;
  pNew = pBuilder->pNew;
  memset(&sSum, 0, sizeof(sSum));

  for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
    if( (pTerm->eOperator & WO_OR)!=0
     && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 
    ){
      WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
      WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
109990
109991
109992
109993
109994
109995
109996


109997



109998
109999
110000
110001
110002
110003
110004
110005
110006
110007
110008
    pLoop->aLTerm[0] = pTerm;
    pLoop->nLTerm = 1;
    pLoop->u.btree.nEq = 1;
    /* TUNING: Cost of a rowid lookup is 10 */
    pLoop->rRun = 33;  /* 33==whereCost(10) */
  }else{
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){


      if( pIdx->onError==OE_None ) continue;



      for(j=0; j<pIdx->nColumn; j++){
        pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
        if( pTerm==0 ) break;
        whereLoopResize(pWInfo->pParse->db, pLoop, j);
        pLoop->aLTerm[j] = pTerm;
      }
      if( j!=pIdx->nColumn ) continue;
      pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
      if( (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
        pLoop->wsFlags |= WHERE_IDX_ONLY;
      }







>
>
|
>
>
>



<







111324
111325
111326
111327
111328
111329
111330
111331
111332
111333
111334
111335
111336
111337
111338
111339

111340
111341
111342
111343
111344
111345
111346
    pLoop->aLTerm[0] = pTerm;
    pLoop->nLTerm = 1;
    pLoop->u.btree.nEq = 1;
    /* TUNING: Cost of a rowid lookup is 10 */
    pLoop->rRun = 33;  /* 33==whereCost(10) */
  }else{
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      assert( pLoop->aLTermSpace==pLoop->aLTerm );
      assert( ArraySize(pLoop->aLTermSpace)==4 );
      if( pIdx->onError==OE_None 
       || pIdx->pPartIdxWhere!=0 
       || pIdx->nColumn>ArraySize(pLoop->aLTermSpace) 
      ) continue;
      for(j=0; j<pIdx->nColumn; j++){
        pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
        if( pTerm==0 ) break;

        pLoop->aLTerm[j] = pTerm;
      }
      if( j!=pIdx->nColumn ) continue;
      pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
      if( (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
        pLoop->wsFlags |= WHERE_IDX_ONLY;
      }
110196
110197
110198
110199
110200
110201
110202
110203
110204
110205
110206
110207
110208
110209
110210

  /* Split the WHERE clause into separate subexpressions where each
  ** subexpression is separated by an AND operator.
  */
  initMaskSet(pMaskSet);
  whereClauseInit(&pWInfo->sWC, pWInfo);
  sqlite3ExprCodeConstants(pParse, pWhere);
  whereSplit(&pWInfo->sWC, pWhere, TK_AND);   /* IMP: R-15842-53296 */
  sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
    
  /* Special case: a WHERE clause that is constant.  Evaluate the
  ** expression and either jump over all of the code or fall thru.
  */
  if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){
    sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL);







|







111534
111535
111536
111537
111538
111539
111540
111541
111542
111543
111544
111545
111546
111547
111548

  /* Split the WHERE clause into separate subexpressions where each
  ** subexpression is separated by an AND operator.
  */
  initMaskSet(pMaskSet);
  whereClauseInit(&pWInfo->sWC, pWInfo);
  sqlite3ExprCodeConstants(pParse, pWhere);
  whereSplit(&pWInfo->sWC, pWhere, TK_AND);
  sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
    
  /* Special case: a WHERE clause that is constant.  Evaluate the
  ** expression and either jump over all of the code or fall thru.
  */
  if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){
    sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL);
110349
110350
110351
110352
110353
110354
110355
110356
110357
110358
110359
110360
110361
110362
110363
#endif
  /* Attempt to omit tables from the join that do not effect the result */
  if( pWInfo->nLevel>=2
   && pResultSet!=0
   && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
  ){
    Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet);
    if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy);
    while( pWInfo->nLevel>=2 ){
      WhereTerm *pTerm, *pEnd;
      pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
      if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break;
      if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
       && (pLoop->wsFlags & WHERE_ONEROW)==0
      ){







|







111687
111688
111689
111690
111691
111692
111693
111694
111695
111696
111697
111698
111699
111700
111701
#endif
  /* Attempt to omit tables from the join that do not effect the result */
  if( pWInfo->nLevel>=2
   && pResultSet!=0
   && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
  ){
    Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet);
    if( sWLB.pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, sWLB.pOrderBy);
    while( pWInfo->nLevel>=2 ){
      WhereTerm *pTerm, *pEnd;
      pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
      if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break;
      if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
       && (pLoop->wsFlags & WHERE_ONEROW)==0
      ){
110431
110432
110433
110434
110435
110436
110437
110438
110439
110440
110441
110442
110443
110444
110445
110446
110447
110448
110449
        sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1, 
                            SQLITE_INT_TO_PTR(n), P4_INT32);
        assert( n<=pTab->nCol );
      }
    }else{
      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
    }
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    if( (pLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
      constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel);
    }else
#endif
    if( pLoop->wsFlags & WHERE_INDEXED ){
      Index *pIx = pLoop->u.btree.pIndex;
      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
      /* FIXME:  As an optimization use pTabItem->iCursor if WHERE_IDX_ONLY */
      int iIndexCur = pLevel->iIdxCur = iIdxCur ? iIdxCur : pParse->nTab++;
      assert( pIx->pSchema==pTab->pSchema );
      assert( iIndexCur>=0 );







<
<
<
<
<







111769
111770
111771
111772
111773
111774
111775





111776
111777
111778
111779
111780
111781
111782
        sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1, 
                            SQLITE_INT_TO_PTR(n), P4_INT32);
        assert( n<=pTab->nCol );
      }
    }else{
      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
    }





    if( pLoop->wsFlags & WHERE_INDEXED ){
      Index *pIx = pLoop->u.btree.pIndex;
      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
      /* FIXME:  As an optimization use pTabItem->iCursor if WHERE_IDX_ONLY */
      int iIndexCur = pLevel->iIdxCur = iIdxCur ? iIdxCur : pParse->nTab++;
      assert( pIx->pSchema==pTab->pSchema );
      assert( iIndexCur>=0 );
110460
110461
110462
110463
110464
110465
110466







110467

110468
110469
110470
110471
110472
110473
110474
  /* Generate the code to do the search.  Each iteration of the for
  ** loop below generates code for a single nested loop of the VM
  ** program.
  */
  notReady = ~(Bitmask)0;
  for(ii=0; ii<nTabList; ii++){
    pLevel = &pWInfo->a[ii];







    explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);

    notReady = codeOneLoopStart(pWInfo, ii, notReady);
    pWInfo->iContinue = pLevel->addrCont;
  }

  /* Done. */
  return pWInfo;








>
>
>
>
>
>
>

>







111793
111794
111795
111796
111797
111798
111799
111800
111801
111802
111803
111804
111805
111806
111807
111808
111809
111810
111811
111812
111813
111814
111815
  /* Generate the code to do the search.  Each iteration of the for
  ** loop below generates code for a single nested loop of the VM
  ** program.
  */
  notReady = ~(Bitmask)0;
  for(ii=0; ii<nTabList; ii++){
    pLevel = &pWInfo->a[ii];
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
      constructAutomaticIndex(pParse, &pWInfo->sWC,
                &pTabList->a[pLevel->iFrom], notReady, pLevel);
      if( db->mallocFailed ) goto whereBeginError;
    }
#endif
    explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
    pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
    notReady = codeOneLoopStart(pWInfo, ii, notReady);
    pWInfo->iContinue = pLevel->addrCont;
  }

  /* Done. */
  return pWInfo;

110580
110581
110582
110583
110584
110585
110586
110587
110588


110589
110590
110591
110592
110593
110594
110595
110596
    }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
      pIdx = pLevel->u.pCovidx;
    }
    if( pIdx && !db->mallocFailed ){
      int k, j, last;
      VdbeOp *pOp;

      pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
      last = sqlite3VdbeCurrentAddr(v);


      for(k=pWInfo->iTop; k<last; k++, pOp++){
        if( pOp->p1!=pLevel->iTabCur ) continue;
        if( pOp->opcode==OP_Column ){
          for(j=0; j<pIdx->nColumn; j++){
            if( pOp->p2==pIdx->aiColumn[j] ){
              pOp->p2 = j;
              pOp->p1 = pLevel->iIdxCur;
              break;







<

>
>
|







111921
111922
111923
111924
111925
111926
111927

111928
111929
111930
111931
111932
111933
111934
111935
111936
111937
111938
    }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
      pIdx = pLevel->u.pCovidx;
    }
    if( pIdx && !db->mallocFailed ){
      int k, j, last;
      VdbeOp *pOp;


      last = sqlite3VdbeCurrentAddr(v);
      k = pLevel->addrBody;
      pOp = sqlite3VdbeGetOp(v, k);
      for(; k<last; k++, pOp++){
        if( pOp->p1!=pLevel->iTabCur ) continue;
        if( pOp->opcode==OP_Column ){
          for(j=0; j<pIdx->nColumn; j++){
            if( pOp->p2==pIdx->aiColumn[j] ){
              pOp->p2 = j;
              pOp->p1 = pLevel->iIdxCur;
              break;
110830
110831
110832
110833
110834
110835
110836
110837
110838
110839
110840
110841
110842
110843
110844
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
#endif
#define sqlite3ParserARG_SDECL Parse *pParse;
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
#define YYNSTATE 627
#define YYNRULE 327
#define YYFALLBACK 1
#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)

/* The yyzerominor constant is used to initialize instances of







|







112172
112173
112174
112175
112176
112177
112178
112179
112180
112181
112182
112183
112184
112185
112186
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
#endif
#define sqlite3ParserARG_SDECL Parse *pParse;
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
#define YYNSTATE 628
#define YYNRULE 327
#define YYFALLBACK 1
#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)

/* The yyzerominor constant is used to initialize instances of
110903
110904
110905
110906
110907
110908
110909
110910
110911
110912
110913
110914
110915
110916
110917
110918
110919
110920
110921
110922
110923
110924
110925
110926
110927
110928
110929
110930
110931
110932
110933
110934
110935
110936
110937
110938
110939
110940
110941
110942
110943
110944
110945
110946
110947
110948
110949
110950
110951
110952
110953
110954
110955
110956
110957
110958
110959
110960
110961
110962
110963
110964
110965
110966
110967
110968
110969
110970
110971
110972
110973
110974
110975
110976
110977
110978
110979
110980
110981
110982
110983
110984
110985
110986
110987
110988
110989
110990
110991
110992
110993
110994
110995
110996
110997
110998
110999
111000
111001
111002
111003
111004
111005
111006
111007
111008
111009
111010
111011
111012
111013
111014
111015
111016
111017
111018
111019
111020
111021
111022
111023
111024
111025
111026
111027
111028
111029
111030
111031
111032
111033
111034
111035
111036
111037
111038
111039
111040
111041
111042
111043
111044
111045
111046
111047
111048
111049
111050
111051
111052
111053
111054
111055
111056
111057
111058
111059
111060
111061
111062
111063
111064
111065
111066
111067
111068
111069
111070
111071
111072
111073
**                     shifting terminals.
**  yy_reduce_ofst[]   For each state, the offset into yy_action for
**                     shifting non-terminals after a reduce.
**  yy_default[]       Default action for each state.
*/
#define YY_ACTTAB_COUNT (1564)
static const YYACTIONTYPE yy_action[] = {
 /*     0 */   309,  955,  184,  417,    2,  171,  624,  594,   56,   56,
 /*    10 */    56,   56,   49,   54,   54,   54,   54,   53,   53,   52,
 /*    20 */    52,   52,   51,  233,  620,  619,  298,  620,  619,  234,
 /*    30 */   587,  581,   56,   56,   56,   56,   19,   54,   54,   54,
 /*    40 */    54,   53,   53,   52,   52,   52,   51,  233,  605,   57,
 /*    50 */    58,   48,  579,  578,  580,  580,   55,   55,   56,   56,
 /*    60 */    56,   56,  541,   54,   54,   54,   54,   53,   53,   52,
 /*    70 */    52,   52,   51,  233,  309,  594,  325,  196,  195,  194,
 /*    80 */    33,   54,   54,   54,   54,   53,   53,   52,   52,   52,
 /*    90 */    51,  233,  617,  616,  165,  617,  616,  380,  377,  376,
 /*   100 */   407,  532,  576,  576,  587,  581,  303,  422,  375,   59,
 /*   110 */    53,   53,   52,   52,   52,   51,  233,   50,   47,  146,
 /*   120 */   574,  545,   65,   57,   58,   48,  579,  578,  580,  580,
 /*   130 */    55,   55,   56,   56,   56,   56,  213,   54,   54,   54,
 /*   140 */    54,   53,   53,   52,   52,   52,   51,  233,  309,  223,
 /*   150 */   539,  420,  170,  176,  138,  280,  383,  275,  382,  168,
 /*   160 */   489,  551,  409,  668,  620,  619,  271,  438,  409,  438,
 /*   170 */   550,  604,   67,  482,  507,  618,  599,  412,  587,  581,
 /*   180 */   600,  483,  618,  412,  618,  598,   91,  439,  440,  439,
 /*   190 */   335,  598,   73,  669,  222,  266,  480,   57,   58,   48,
 /*   200 */   579,  578,  580,  580,   55,   55,   56,   56,   56,   56,
 /*   210 */   670,   54,   54,   54,   54,   53,   53,   52,   52,   52,
 /*   220 */    51,  233,  309,  279,  232,  231,    1,  132,  200,  385,
 /*   230 */   620,  619,  617,  616,  278,  435,  289,  563,  175,  262,
 /*   240 */   409,  264,  437,  497,  436,  166,  441,  568,  336,  568,
 /*   250 */   201,  537,  587,  581,  599,  412,  165,  594,  600,  380,
 /*   260 */   377,  376,  597,  598,   92,  523,  618,  569,  569,  592,
 /*   270 */   375,   57,   58,   48,  579,  578,  580,  580,   55,   55,
 /*   280 */    56,   56,   56,   56,  597,   54,   54,   54,   54,   53,
 /*   290 */    53,   52,   52,   52,   51,  233,  309,  463,  617,  616,
 /*   300 */   590,  590,  590,  174,  272,  396,  409,  272,  409,  548,
 /*   310 */   397,  620,  619,   68,  326,  620,  619,  620,  619,  618,
 /*   320 */   546,  412,  618,  412,  471,  594,  587,  581,  472,  598,
 /*   330 */    92,  598,   92,   52,   52,   52,   51,  233,  513,  512,
 /*   340 */   206,  322,  363,  464,  221,   57,   58,   48,  579,  578,
 /*   350 */   580,  580,   55,   55,   56,   56,   56,   56,  529,   54,
 /*   360 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  233,
 /*   370 */   309,  396,  409,  396,  597,  372,  386,  530,  347,  617,
 /*   380 */   616,  575,  202,  617,  616,  617,  616,  412,  620,  619,
 /*   390 */   145,  255,  346,  254,  577,  598,   74,  351,   45,  489,
 /*   400 */   587,  581,  235,  189,  464,  544,  167,  296,  187,  469,
 /*   410 */   479,   67,   62,   39,  618,  546,  597,  345,  573,   57,
 /*   420 */    58,   48,  579,  578,  580,  580,   55,   55,   56,   56,
 /*   430 */    56,   56,    6,   54,   54,   54,   54,   53,   53,   52,
 /*   440 */    52,   52,   51,  233,  309,  562,  558,  407,  528,  576,
 /*   450 */   576,  344,  255,  346,  254,  182,  617,  616,  503,  504,
 /*   460 */   314,  409,  557,  235,  166,  271,  409,  352,  564,  181,
 /*   470 */   407,  546,  576,  576,  587,  581,  412,  537,  556,  561,
 /*   480 */   517,  412,  618,  249,  598,   16,    7,   36,  467,  598,
 /*   490 */    92,  516,  618,   57,   58,   48,  579,  578,  580,  580,
 /*   500 */    55,   55,   56,   56,   56,   56,  541,   54,   54,   54,
 /*   510 */    54,   53,   53,   52,   52,   52,   51,  233,  309,  327,
 /*   520 */   572,  571,  525,  558,  560,  394,  871,  246,  409,  248,
 /*   530 */   171,  392,  594,  219,  407,  409,  576,  576,  502,  557,
 /*   540 */   364,  145,  510,  412,  407,  229,  576,  576,  587,  581,
 /*   550 */   412,  598,   92,  381,  269,  556,  166,  400,  598,   69,
 /*   560 */   501,  419,  945,  199,  945,  198,  546,   57,   58,   48,
 /*   570 */   579,  578,  580,  580,   55,   55,   56,   56,   56,   56,
 /*   580 */   568,   54,   54,   54,   54,   53,   53,   52,   52,   52,
 /*   590 */    51,  233,  309,  317,  419,  944,  508,  944,  308,  597,
 /*   600 */   594,  565,  490,  212,  173,  247,  423,  615,  614,  613,
 /*   610 */   323,  197,  143,  405,  572,  571,  489,   66,   50,   47,
 /*   620 */   146,  594,  587,  581,  232,  231,  559,  427,   67,  555,
 /*   630 */    15,  618,  186,  543,  303,  421,   35,  206,  432,  423,
 /*   640 */   552,   57,   58,   48,  579,  578,  580,  580,   55,   55,
 /*   650 */    56,   56,   56,   56,  205,   54,   54,   54,   54,   53,
 /*   660 */    53,   52,   52,   52,   51,  233,  309,  569,  569,  260,
 /*   670 */   268,  597,   12,  373,  568,  166,  409,  313,  409,  420,
 /*   680 */   409,  473,  473,  365,  618,   50,   47,  146,  597,  594,
 /*   690 */   468,  412,  166,  412,  351,  412,  587,  581,   32,  598,
 /*   700 */    94,  598,   97,  598,   95,  627,  625,  329,  142,   50,
 /*   710 */    47,  146,  333,  349,  358,   57,   58,   48,  579,  578,
 /*   720 */   580,  580,   55,   55,   56,   56,   56,   56,  409,   54,
 /*   730 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  233,
 /*   740 */   309,  409,  388,  412,  409,   22,  565,  404,  212,  362,
 /*   750 */   389,  598,  104,  359,  409,  156,  412,  409,  603,  412,
 /*   760 */   537,  331,  569,  569,  598,  103,  493,  598,  105,  412,
 /*   770 */   587,  581,  412,  260,  549,  618,   11,  598,  106,  521,
 /*   780 */   598,  133,  169,  457,  456,  170,   35,  601,  618,   57,
 /*   790 */    58,   48,  579,  578,  580,  580,   55,   55,   56,   56,
 /*   800 */    56,   56,  409,   54,   54,   54,   54,   53,   53,   52,
 /*   810 */    52,   52,   51,  233,  309,  409,  259,  412,  409,   50,
 /*   820 */    47,  146,  357,  318,  355,  598,  134,  527,  352,  337,
 /*   830 */   412,  409,  356,  412,  357,  409,  357,  618,  598,   98,
 /*   840 */   129,  598,  102,  618,  587,  581,  412,   21,  235,  618,
 /*   850 */   412,  618,  211,  143,  598,  101,   30,  167,  598,   93,
 /*   860 */   350,  535,  203,   57,   58,   48,  579,  578,  580,  580,
 /*   870 */    55,   55,   56,   56,   56,   56,  409,   54,   54,   54,
 /*   880 */    54,   53,   53,   52,   52,   52,   51,  233,  309,  409,
 /*   890 */   526,  412,  409,  425,  215,  305,  597,  551,  141,  598,
 /*   900 */   100,   40,  409,   38,  412,  409,  550,  412,  409,  228,
 /*   910 */   220,  314,  598,   77,  500,  598,   96,  412,  587,  581,
 /*   920 */   412,  338,  253,  412,  218,  598,  137,  379,  598,  136,
 /*   930 */    28,  598,  135,  270,  715,  210,  481,   57,   58,   48,
 /*   940 */   579,  578,  580,  580,   55,   55,   56,   56,   56,   56,
 /*   950 */   409,   54,   54,   54,   54,   53,   53,   52,   52,   52,
 /*   960 */    51,  233,  309,  409,  272,  412,  409,  315,  147,  597,
 /*   970 */   272,  626,    2,  598,   76,  209,  409,  127,  412,  618,
 /*   980 */   126,  412,  409,  621,  235,  618,  598,   90,  374,  598,
 /*   990 */    89,  412,  587,  581,   27,  260,  350,  412,  618,  598,
 /*  1000 */    75,  321,  541,  541,  125,  598,   88,  320,  278,  597,
 /*  1010 */   618,   57,   46,   48,  579,  578,  580,  580,   55,   55,
 /*  1020 */    56,   56,   56,   56,  409,   54,   54,   54,   54,   53,
 /*  1030 */    53,   52,   52,   52,   51,  233,  309,  409,  450,  412,
 /*  1040 */   164,  284,  282,  272,  609,  424,  304,  598,   87,  370,
 /*  1050 */   409,  477,  412,  409,  608,  409,  607,  602,  618,  618,
 /*  1060 */   598,   99,  586,  585,  122,  412,  587,  581,  412,  618,
 /*  1070 */   412,  618,  618,  598,   86,  366,  598,   17,  598,   85,
 /*  1080 */   319,  185,  519,  518,  583,  582,   58,   48,  579,  578,
 /*  1090 */   580,  580,   55,   55,   56,   56,   56,   56,  409,   54,
 /*  1100 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  233,
 /*  1110 */   309,  584,  409,  412,  409,  260,  260,  260,  408,  591,
 /*  1120 */   474,  598,   84,  170,  409,  466,  518,  412,  121,  412,
 /*  1130 */   618,  618,  618,  618,  618,  598,   83,  598,   72,  412,
 /*  1140 */   587,  581,   51,  233,  625,  329,  470,  598,   71,  257,
 /*  1150 */   159,  120,   14,  462,  157,  158,  117,  260,  448,  447,
 /*  1160 */   446,   48,  579,  578,  580,  580,   55,   55,   56,   56,
 /*  1170 */    56,   56,  618,   54,   54,   54,   54,   53,   53,   52,
 /*  1180 */    52,   52,   51,  233,   44,  403,  260,    3,  409,  459,
 /*  1190 */   260,  413,  619,  118,  398,   10,   25,   24,  554,  348,
 /*  1200 */   217,  618,  406,  412,  409,  618,    4,   44,  403,  618,
 /*  1210 */     3,  598,   82,  618,  413,  619,  455,  542,  115,  412,
 /*  1220 */   538,  401,  536,  274,  506,  406,  251,  598,   81,  216,
 /*  1230 */   273,  563,  618,  243,  453,  618,  154,  618,  618,  618,
 /*  1240 */   449,  416,  623,  110,  401,  618,  409,  236,   64,  123,
 /*  1250 */   487,   41,   42,  531,  563,  204,  409,  267,   43,  411,
 /*  1260 */   410,  412,  265,  592,  108,  618,  107,  434,  332,  598,
 /*  1270 */    80,  412,  618,  263,   41,   42,  443,  618,  409,  598,
 /*  1280 */    70,   43,  411,  410,  433,  261,  592,  149,  618,  597,
 /*  1290 */   256,  237,  188,  412,  590,  590,  590,  589,  588,   13,
 /*  1300 */   618,  598,   18,  328,  235,  618,   44,  403,  360,    3,
 /*  1310 */   418,  461,  339,  413,  619,  227,  124,  590,  590,  590,
 /*  1320 */   589,  588,   13,  618,  406,  409,  618,  409,  139,   34,
 /*  1330 */   403,  387,    3,  148,  622,  312,  413,  619,  311,  330,
 /*  1340 */   412,  460,  412,  401,  180,  353,  412,  406,  598,   79,
 /*  1350 */   598,   78,  250,  563,  598,    9,  618,  612,  611,  610,
 /*  1360 */   618,    8,  452,  442,  242,  415,  401,  618,  239,  235,
 /*  1370 */   179,  238,  428,   41,   42,  288,  563,  618,  618,  618,
 /*  1380 */    43,  411,  410,  618,  144,  592,  618,  618,  177,   61,
 /*  1390 */   618,  596,  391,  620,  619,  287,   41,   42,  414,  618,
 /*  1400 */   293,   30,  393,   43,  411,  410,  292,  618,  592,   31,
 /*  1410 */   618,  395,  291,   60,  230,   37,  590,  590,  590,  589,
 /*  1420 */   588,   13,  214,  553,  183,  290,  172,  301,  300,  299,
 /*  1430 */   178,  297,  595,  563,  451,   29,  285,  390,  540,  590,
 /*  1440 */   590,  590,  589,  588,   13,  283,  520,  534,  150,  533,
 /*  1450 */   241,  281,  384,  192,  191,  324,  515,  514,  276,  240,
 /*  1460 */   510,  523,  307,  511,  128,  592,  509,  225,  226,  486,
 /*  1470 */   485,  224,  152,  491,  464,  306,  484,  163,  153,  371,
 /*  1480 */   478,  151,  162,  258,  369,  161,  367,  208,  475,  476,
 /*  1490 */    26,  160,  465,  140,  361,  131,  590,  590,  590,  116,
 /*  1500 */   119,  454,  343,  155,  114,  342,  113,  112,  445,  111,
 /*  1510 */   130,  109,  431,  316,  426,  430,   23,  429,   20,  606,
 /*  1520 */   190,  507,  255,  341,  244,   63,  294,  593,  310,  570,
 /*  1530 */   277,  402,  354,  235,  567,  496,  495,  492,  494,  302,
 /*  1540 */   458,  378,  286,  245,  566,    5,  252,  547,  193,  444,
 /*  1550 */   233,  340,  207,  524,  368,  505,  334,  522,  499,  399,
 /*  1560 */   295,  498,  956,  488,
};
static const YYCODETYPE yy_lookahead[] = {
 /*     0 */    19,  142,  143,  144,  145,   24,    1,   26,   77,   78,
 /*    10 */    79,   80,   81,   82,   83,   84,   85,   86,   87,   88,
 /*    20 */    89,   90,   91,   92,   26,   27,   15,   26,   27,  197,
 /*    30 */    49,   50,   77,   78,   79,   80,  204,   82,   83,   84,
 /*    40 */    85,   86,   87,   88,   89,   90,   91,   92,   23,   68,







|

|
|
|
|
|
|

|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







112245
112246
112247
112248
112249
112250
112251
112252
112253
112254
112255
112256
112257
112258
112259
112260
112261
112262
112263
112264
112265
112266
112267
112268
112269
112270
112271
112272
112273
112274
112275
112276
112277
112278
112279
112280
112281
112282
112283
112284
112285
112286
112287
112288
112289
112290
112291
112292
112293
112294
112295
112296
112297
112298
112299
112300
112301
112302
112303
112304
112305
112306
112307
112308
112309
112310
112311
112312
112313
112314
112315
112316
112317
112318
112319
112320
112321
112322
112323
112324
112325
112326
112327
112328
112329
112330
112331
112332
112333
112334
112335
112336
112337
112338
112339
112340
112341
112342
112343
112344
112345
112346
112347
112348
112349
112350
112351
112352
112353
112354
112355
112356
112357
112358
112359
112360
112361
112362
112363
112364
112365
112366
112367
112368
112369
112370
112371
112372
112373
112374
112375
112376
112377
112378
112379
112380
112381
112382
112383
112384
112385
112386
112387
112388
112389
112390
112391
112392
112393
112394
112395
112396
112397
112398
112399
112400
112401
112402
112403
112404
112405
112406
112407
112408
112409
112410
112411
112412
112413
112414
112415
**                     shifting terminals.
**  yy_reduce_ofst[]   For each state, the offset into yy_action for
**                     shifting non-terminals after a reduce.
**  yy_default[]       Default action for each state.
*/
#define YY_ACTTAB_COUNT (1564)
static const YYACTIONTYPE yy_action[] = {
 /*     0 */   310,  956,  184,  418,    2,  171,  625,  595,   56,   56,
 /*    10 */    56,   56,   49,   54,   54,   54,   54,   53,   53,   52,
 /*    20 */    52,   52,   51,  233,  621,  620,  299,  621,  620,  234,
 /*    30 */   588,  582,   56,   56,   56,   56,   19,   54,   54,   54,
 /*    40 */    54,   53,   53,   52,   52,   52,   51,  233,  606,   57,
 /*    50 */    58,   48,  580,  579,  581,  581,   55,   55,   56,   56,
 /*    60 */    56,   56,  542,   54,   54,   54,   54,   53,   53,   52,
 /*    70 */    52,   52,   51,  233,  310,  595,  326,  196,  195,  194,
 /*    80 */    33,   54,   54,   54,   54,   53,   53,   52,   52,   52,
 /*    90 */    51,  233,  618,  617,  165,  618,  617,  381,  378,  377,
 /*   100 */   408,  533,  577,  577,  588,  582,  304,  423,  376,   59,
 /*   110 */    53,   53,   52,   52,   52,   51,  233,   50,   47,  146,
 /*   120 */   575,  546,   65,   57,   58,   48,  580,  579,  581,  581,
 /*   130 */    55,   55,   56,   56,   56,   56,  213,   54,   54,   54,
 /*   140 */    54,   53,   53,   52,   52,   52,   51,  233,  310,  223,
 /*   150 */   540,  421,  170,  176,  138,  281,  384,  276,  383,  168,
 /*   160 */   490,  552,  410,  669,  621,  620,  272,  439,  410,  439,
 /*   170 */   551,  605,   67,  483,  508,  619,  600,  413,  588,  582,
 /*   180 */   601,  484,  619,  413,  619,  599,   91,  440,  441,  440,
 /*   190 */   336,  599,   73,  670,  222,  267,  481,   57,   58,   48,
 /*   200 */   580,  579,  581,  581,   55,   55,   56,   56,   56,   56,
 /*   210 */   671,   54,   54,   54,   54,   53,   53,   52,   52,   52,
 /*   220 */    51,  233,  310,  280,  232,  231,    1,  132,  200,  386,
 /*   230 */   621,  620,  618,  617,  279,  436,  290,  564,  175,  263,
 /*   240 */   410,  265,  438,  498,  437,  166,  442,  569,  337,  569,
 /*   250 */   201,  538,  588,  582,  600,  413,  165,  595,  601,  381,
 /*   260 */   378,  377,  598,  599,   92,  524,  619,  570,  570,  593,
 /*   270 */   376,   57,   58,   48,  580,  579,  581,  581,   55,   55,
 /*   280 */    56,   56,   56,   56,  598,   54,   54,   54,   54,   53,
 /*   290 */    53,   52,   52,   52,   51,  233,  310,  464,  618,  617,
 /*   300 */   591,  591,  591,  174,  273,  397,  410,  273,  410,  549,
 /*   310 */   398,  621,  620,   68,  327,  621,  620,  621,  620,  619,
 /*   320 */   547,  413,  619,  413,  472,  595,  588,  582,  473,  599,
 /*   330 */    92,  599,   92,   52,   52,   52,   51,  233,  514,  513,
 /*   340 */   206,  323,  364,  465,  221,   57,   58,   48,  580,  579,
 /*   350 */   581,  581,   55,   55,   56,   56,   56,   56,  530,   54,
 /*   360 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  233,
 /*   370 */   310,  397,  410,  397,  598,  373,  387,  531,  348,  618,
 /*   380 */   617,  576,  202,  618,  617,  618,  617,  413,  621,  620,
 /*   390 */   145,  255,  347,  254,  578,  599,   74,  352,   45,  490,
 /*   400 */   588,  582,  235,  189,  465,  545,  167,  297,  187,  470,
 /*   410 */   480,   67,   62,   39,  619,  547,  598,  346,  574,   57,
 /*   420 */    58,   48,  580,  579,  581,  581,   55,   55,   56,   56,
 /*   430 */    56,   56,    6,   54,   54,   54,   54,   53,   53,   52,
 /*   440 */    52,   52,   51,  233,  310,  563,  559,  408,  529,  577,
 /*   450 */   577,  345,  255,  347,  254,  182,  618,  617,  504,  505,
 /*   460 */   315,  410,  558,  235,  166,  272,  410,  353,  565,  181,
 /*   470 */   408,  547,  577,  577,  588,  582,  413,  538,  557,  562,
 /*   480 */   518,  413,  619,  249,  599,   16,    7,   36,  468,  599,
 /*   490 */    92,  517,  619,   57,   58,   48,  580,  579,  581,  581,
 /*   500 */    55,   55,   56,   56,   56,   56,  542,   54,   54,   54,
 /*   510 */    54,   53,   53,   52,   52,   52,   51,  233,  310,  328,
 /*   520 */   573,  572,  526,  559,  561,  395,  872,  246,  410,  248,
 /*   530 */   171,  393,  595,  219,  408,  410,  577,  577,  503,  558,
 /*   540 */   365,  145,  511,  413,  408,  229,  577,  577,  588,  582,
 /*   550 */   413,  599,   92,  382,  270,  557,  166,  401,  599,   69,
 /*   560 */   502,  420,  946,  199,  946,  198,  547,   57,   58,   48,
 /*   570 */   580,  579,  581,  581,   55,   55,   56,   56,   56,   56,
 /*   580 */   569,   54,   54,   54,   54,   53,   53,   52,   52,   52,
 /*   590 */    51,  233,  310,  318,  420,  945,  509,  945,  309,  598,
 /*   600 */   595,  566,  491,  212,  173,  247,  424,  616,  615,  614,
 /*   610 */   324,  197,  143,  406,  573,  572,  490,   66,   50,   47,
 /*   620 */   146,  595,  588,  582,  232,  231,  560,  428,   67,  556,
 /*   630 */    15,  619,  186,  544,  304,  422,   35,  206,  433,  424,
 /*   640 */   553,   57,   58,   48,  580,  579,  581,  581,   55,   55,
 /*   650 */    56,   56,   56,   56,  205,   54,   54,   54,   54,   53,
 /*   660 */    53,   52,   52,   52,   51,  233,  310,  570,  570,  261,
 /*   670 */   269,  598,   12,  374,  569,  166,  410,  314,  410,  421,
 /*   680 */   410,  474,  474,  366,  619,   50,   47,  146,  598,  595,
 /*   690 */   256,  413,  166,  413,  352,  413,  588,  582,   32,  599,
 /*   700 */    94,  599,   97,  599,   95,  628,  626,  330,  142,   50,
 /*   710 */    47,  146,  334,  350,  359,   57,   58,   48,  580,  579,
 /*   720 */   581,  581,   55,   55,   56,   56,   56,   56,  410,   54,
 /*   730 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  233,
 /*   740 */   310,  410,  389,  413,  410,   22,  566,  405,  212,  363,
 /*   750 */   390,  599,  104,  360,  410,  156,  413,  410,  604,  413,
 /*   760 */   538,  332,  570,  570,  599,  103,  494,  599,  105,  413,
 /*   770 */   588,  582,  413,  261,  550,  619,   11,  599,  106,  522,
 /*   780 */   599,  133,  169,  458,  457,  170,   35,  602,  619,   57,
 /*   790 */    58,   48,  580,  579,  581,  581,   55,   55,   56,   56,
 /*   800 */    56,   56,  410,   54,   54,   54,   54,   53,   53,   52,
 /*   810 */    52,   52,   51,  233,  310,  410,  260,  413,  410,   50,
 /*   820 */    47,  146,  358,  319,  356,  599,  134,  528,  353,  338,
 /*   830 */   413,  410,  357,  413,  358,  410,  358,  619,  599,   98,
 /*   840 */   129,  599,  102,  619,  588,  582,  413,   21,  235,  619,
 /*   850 */   413,  619,  211,  143,  599,  101,   30,  167,  599,   93,
 /*   860 */   351,  536,  203,   57,   58,   48,  580,  579,  581,  581,
 /*   870 */    55,   55,   56,   56,   56,   56,  410,   54,   54,   54,
 /*   880 */    54,   53,   53,   52,   52,   52,   51,  233,  310,  410,
 /*   890 */   527,  413,  410,  426,  215,  306,  598,  552,  141,  599,
 /*   900 */   100,   40,  410,   38,  413,  410,  551,  413,  410,  228,
 /*   910 */   220,  315,  599,   77,  501,  599,   96,  413,  588,  582,
 /*   920 */   413,  339,  253,  413,  218,  599,  137,  380,  599,  136,
 /*   930 */    28,  599,  135,  271,  716,  210,  482,   57,   58,   48,
 /*   940 */   580,  579,  581,  581,   55,   55,   56,   56,   56,   56,
 /*   950 */   410,   54,   54,   54,   54,   53,   53,   52,   52,   52,
 /*   960 */    51,  233,  310,  410,  273,  413,  410,  316,  147,  598,
 /*   970 */   273,  627,    2,  599,   76,  209,  410,  127,  413,  619,
 /*   980 */   126,  413,  410,  622,  235,  619,  599,   90,  375,  599,
 /*   990 */    89,  413,  588,  582,   27,  261,  351,  413,  619,  599,
 /*  1000 */    75,  322,  542,  542,  125,  599,   88,  321,  279,  598,
 /*  1010 */   619,   57,   46,   48,  580,  579,  581,  581,   55,   55,
 /*  1020 */    56,   56,   56,   56,  410,   54,   54,   54,   54,   53,
 /*  1030 */    53,   52,   52,   52,   51,  233,  310,  410,  451,  413,
 /*  1040 */   164,  285,  283,  273,  610,  425,  305,  599,   87,  371,
 /*  1050 */   410,  478,  413,  410,  609,  410,  608,  603,  619,  619,
 /*  1060 */   599,   99,  587,  586,  122,  413,  588,  582,  413,  619,
 /*  1070 */   413,  619,  619,  599,   86,  367,  599,   17,  599,   85,
 /*  1080 */   320,  185,  520,  519,  584,  583,   58,   48,  580,  579,
 /*  1090 */   581,  581,   55,   55,   56,   56,   56,   56,  410,   54,
 /*  1100 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  233,
 /*  1110 */   310,  585,  410,  413,  410,  261,  261,  261,  409,  592,
 /*  1120 */   475,  599,   84,  170,  410,  467,  519,  413,  121,  413,
 /*  1130 */   619,  619,  619,  619,  619,  599,   83,  599,   72,  413,
 /*  1140 */   588,  582,   51,  233,  626,  330,  471,  599,   71,  258,
 /*  1150 */   159,  120,   14,  463,  157,  158,  117,  261,  449,  448,
 /*  1160 */   447,   48,  580,  579,  581,  581,   55,   55,   56,   56,
 /*  1170 */    56,   56,  619,   54,   54,   54,   54,   53,   53,   52,
 /*  1180 */    52,   52,   51,  233,   44,  404,  261,    3,  410,  460,
 /*  1190 */   261,  414,  620,  118,  399,   10,   25,   24,  555,  349,
 /*  1200 */   217,  619,  407,  413,  410,  619,    4,   44,  404,  619,
 /*  1210 */     3,  599,   82,  619,  414,  620,  456,  543,  115,  413,
 /*  1220 */   539,  402,  537,  275,  507,  407,  251,  599,   81,  216,
 /*  1230 */   274,  564,  619,  243,  454,  619,  154,  619,  619,  619,
 /*  1240 */   450,  417,  624,  110,  402,  619,  410,  236,   64,  123,
 /*  1250 */   488,   41,   42,  532,  564,  204,  410,  268,   43,  412,
 /*  1260 */   411,  413,  266,  593,  108,  619,  107,  435,  333,  599,
 /*  1270 */    80,  413,  619,  264,   41,   42,  444,  619,  410,  599,
 /*  1280 */    70,   43,  412,  411,  434,  262,  593,  149,  619,  598,
 /*  1290 */   257,  237,  188,  413,  591,  591,  591,  590,  589,   13,
 /*  1300 */   619,  599,   18,  329,  235,  619,   44,  404,  361,    3,
 /*  1310 */   419,  462,  340,  414,  620,  227,  124,  591,  591,  591,
 /*  1320 */   590,  589,   13,  619,  407,  410,  619,  410,  139,   34,
 /*  1330 */   404,  388,    3,  148,  623,  313,  414,  620,  312,  331,
 /*  1340 */   413,  461,  413,  402,  180,  354,  413,  407,  599,   79,
 /*  1350 */   599,   78,  250,  564,  599,    9,  619,  613,  612,  611,
 /*  1360 */   619,    8,  453,  443,  242,  416,  402,  619,  239,  235,
 /*  1370 */   179,  238,  429,   41,   42,  289,  564,  619,  619,  619,
 /*  1380 */    43,  412,  411,  619,  144,  593,  619,  619,  177,   61,
 /*  1390 */   619,  597,  392,  621,  620,  288,   41,   42,  415,  619,
 /*  1400 */   294,   30,  394,   43,  412,  411,  293,  619,  593,   31,
 /*  1410 */   619,  396,  292,   60,  230,   37,  591,  591,  591,  590,
 /*  1420 */   589,   13,  214,  554,  183,  291,  172,  302,  301,  300,
 /*  1430 */   178,  298,  596,  564,  452,   29,  286,  391,  541,  591,
 /*  1440 */   591,  591,  590,  589,   13,  284,  521,  535,  150,  534,
 /*  1450 */   241,  282,  385,  192,  191,  325,  516,  515,  277,  240,
 /*  1460 */   511,  524,  308,  512,  128,  593,  510,  225,  226,  487,
 /*  1470 */   486,  224,  152,  492,  465,  307,  485,  163,  153,  372,
 /*  1480 */   479,  151,  162,  259,  370,  161,  368,  208,  476,  477,
 /*  1490 */    26,  160,  469,  466,  362,  140,  591,  591,  591,  116,
 /*  1500 */   119,  455,  344,  155,  114,  343,  113,  112,  446,  111,
 /*  1510 */   131,  109,  432,  317,  130,  431,   23,   20,  430,  427,
 /*  1520 */   190,   63,  255,  342,  244,  607,  295,  287,  311,  594,
 /*  1530 */   278,  508,  496,  235,  493,  571,  497,  568,  495,  403,
 /*  1540 */   459,  379,  355,  245,  193,  303,  567,  296,  341,    5,
 /*  1550 */   445,  548,  506,  207,  525,  500,  335,  489,  252,  369,
 /*  1560 */   400,  499,  523,  233,
};
static const YYCODETYPE yy_lookahead[] = {
 /*     0 */    19,  142,  143,  144,  145,   24,    1,   26,   77,   78,
 /*    10 */    79,   80,   81,   82,   83,   84,   85,   86,   87,   88,
 /*    20 */    89,   90,   91,   92,   26,   27,   15,   26,   27,  197,
 /*    30 */    49,   50,   77,   78,   79,   80,  204,   82,   83,   84,
 /*    40 */    85,   86,   87,   88,   89,   90,   91,   92,   23,   68,
111211
111212
111213
111214
111215
111216
111217
111218
111219
111220
111221
111222
111223
111224
111225
111226
111227
111228
111229
111230
111231
111232
111233
111234
111235
111236
111237
111238
111239
111240
111241
111242
111243
111244
111245
111246
111247
111248
111249
111250
111251
111252
111253
111254
111255
111256
111257
111258
111259
111260
111261
111262
111263
111264
111265
111266
111267
111268
111269
111270
111271
111272
111273
111274
111275
111276
111277
111278
111279
111280
111281
111282
111283
111284
111285
111286
111287
111288
111289
111290
111291
111292
111293
111294
111295
111296
111297
111298
111299
111300
111301
111302
111303
111304
111305
111306
111307
111308
111309
111310
111311
111312
111313
111314
111315
111316
111317
111318
111319
111320
111321
111322
111323
111324
111325
111326
111327
111328
111329
111330
111331
111332
111333
111334
111335
111336
111337
111338
111339
111340
111341
111342
111343
111344
111345
111346
111347
111348
111349
111350
111351
111352
111353
111354
111355
111356
111357
111358
111359
111360
111361
111362
111363
111364
111365
111366
111367
111368
111369
111370
111371
111372
111373
111374
111375
111376
111377
111378
111379
111380
111381
111382
 /*  1420 */   133,  134,    5,  157,  157,  202,  118,   10,   11,   12,
 /*  1430 */    13,   14,  203,   66,   17,  104,  210,  121,  211,  129,
 /*  1440 */   130,  131,  132,  133,  134,  210,  175,  211,   31,  211,
 /*  1450 */    33,  210,  104,   86,   87,   47,  175,  183,  175,   42,
 /*  1460 */   103,   94,  178,  177,   22,   98,  175,   92,  228,  175,
 /*  1470 */   175,  228,   55,  183,   57,  178,  175,  156,   61,   18,
 /*  1480 */   157,   64,  156,  235,  157,  156,   45,  157,  236,  157,
 /*  1490 */   135,  156,  189,   68,  157,  218,  129,  130,  131,   22,
 /*  1500 */   189,  199,  157,  156,  192,   18,  192,  192,  199,  192,
 /*  1510 */   218,  189,   40,  157,   38,  157,  240,  157,  240,  153,
 /*  1520 */   196,  181,  105,  106,  107,  243,  198,  166,  111,  230,
 /*  1530 */   176,  226,  239,  116,  230,  176,  166,  166,  176,  148,
 /*  1540 */   199,  177,  209,  209,  166,  196,  239,  208,  185,  199,
 /*  1550 */    92,  209,  233,  173,  234,  182,  139,  173,  182,  191,
 /*  1560 */   195,  182,  250,  186,
};
#define YY_SHIFT_USE_DFLT (-70)
#define YY_SHIFT_COUNT (416)
#define YY_SHIFT_MIN   (-69)
#define YY_SHIFT_MAX   (1487)
static const short yy_shift_ofst[] = {
 /*     0 */  1143, 1188, 1417, 1188, 1287, 1287,  138,  138,   -2,  -19,
 /*    10 */  1287, 1287, 1287, 1287,  347,  362,  129,  129,  795, 1165,
 /*    20 */  1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
 /*    30 */  1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
 /*    40 */  1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1310, 1287,
 /*    50 */  1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
 /*    60 */  1287, 1287,  286,  362,  362,  538,  538,  231, 1253,   55,
 /*    70 */   721,  647,  573,  499,  425,  351,  277,  203,  869,  869,
 /*    80 */   869,  869,  869,  869,  869,  869,  869,  869,  869,  869,
 /*    90 */   869,  869,  869,  943,  869, 1017, 1091, 1091,  -69,  -45,
 /*   100 */   -45,  -45,  -45,  -45,   -1,   24,  245,  362,  362,  362,
 /*   110 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
 /*   120 */   362,  362,  362,  388,  356,  362,  362,  362,  362,  362,
 /*   130 */   732,  868,  231, 1051, 1458,  -70,  -70,  -70, 1367,   57,
 /*   140 */   434,  434,  289,  291,  285,    1,  204,  572,  539,  362,
 /*   150 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
 /*   160 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
 /*   170 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
 /*   180 */   362,  506,  506,  506,  705, 1253, 1253, 1253,  -70,  -70,
 /*   190 */   -70,  171,  171,  160,  502,  502,  502,  446,  432,  511,
 /*   200 */   422,  358,  335,  -12,  -12,  -12,  -12,  576,  294,  -12,
 /*   210 */   -12,  295,  595,  141,  600,  730,  723,  723,  805,  730,
 /*   220 */   805,  439,  911,  231,  865,  231,  865,  807,  865,  723,
 /*   230 */   766,  633,  633,  231,  284,   63,  608, 1476, 1308, 1308,
 /*   240 */  1472, 1472, 1308, 1477, 1425, 1275, 1487, 1487, 1487, 1487,
 /*   250 */  1308, 1461, 1275, 1477, 1425, 1425, 1308, 1461, 1355, 1441,
 /*   260 */  1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348, 1348,
 /*   270 */  1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408, 1348,
 /*   280 */  1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308, 1280,
 /*   290 */  1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346, 1338,
 /*   300 */  1338, 1338, 1338,  -70,  -70,  -70,  -70,  -70,  -70, 1013,
 /*   310 */   467,  612,   84,  179,  -28,  870,  410,  761,  760,  667,
 /*   320 */   650,  531,  220,  361,  331,  125,  127,   97, 1306, 1300,
 /*   330 */  1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174, 1139,
 /*   340 */  1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184, 1174,
 /*   350 */  1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152, 1147,
 /*   360 */  1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032,  960, 1057,
 /*   370 */  1031, 1030,  899,  938,  982,  936,  972,  958,  910,  955,
 /*   380 */   875,  885,  908,  857,  859,  867,  804,  590,  834,  747,
 /*   390 */   818,  513,  611,  741,  673,  637,  611,  606,  603,  579,
 /*   400 */   501,  541,  468,  386,  445,  395,  376,  281,  185,  120,
 /*   410 */    92,   75,   45,  114,   25,   11,    5,
};
#define YY_REDUCE_USE_DFLT (-169)
#define YY_REDUCE_COUNT (308)
#define YY_REDUCE_MIN   (-168)
#define YY_REDUCE_MAX   (1391)
static const short yy_reduce_ofst[] = {
 /*     0 */  -141,   90, 1095,  222,  158,  156,   19,   17,   10, -104,
 /*    10 */   378,  316,  311,   12,  180,  249,  598,  464,  397, 1181,
 /*    20 */  1177, 1175, 1128, 1106, 1096, 1054, 1038,  974,  964,  962,
 /*    30 */   948,  905,  903,  900,  887,  874,  832,  826,  816,  813,
 /*    40 */   800,  758,  755,  752,  742,  739,  726,  685,  681,  668,
 /*    50 */   665,  652,  607,  604,  594,  591,  578,  530,  528,  526,
 /*    60 */   385,   18,  477,  466,  519,  444,  350,  435,  405,  488,
 /*    70 */   488,  488,  488,  488,  488,  488,  488,  488,  488,  488,
 /*    80 */   488,  488,  488,  488,  488,  488,  488,  488,  488,  488,
 /*    90 */   488,  488,  488,  488,  488,  488,  488,  488,  488,  488,
 /*   100 */   488,  488,  488,  488,  488,  488,  488, 1040,  678, 1036,
 /*   110 */  1007,  967,  966,  965,  845,  686,  610,  684,  317,  672,
 /*   120 */   893,  327,  623,  522,   -7,  820,  814,  157,  154,  101,
 /*   130 */   702,  494,  580,  488,  488,  488,  488,  488,  614,  586,
 /*   140 */   935,  892,  968, 1245, 1242, 1234, 1225,  798,  798, 1222,
 /*   150 */  1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
 /*   160 */  1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
 /*   170 */  1070, 1067, 1048, 1044,  969,  968,  907,  906,  904,  894,
 /*   180 */   833,  837,  836,  340,  827,  815,  775,   68,  722,  646,
 /*   190 */  -168, 1384, 1380, 1377, 1379, 1376, 1373, 1339, 1365, 1368,
 /*   200 */  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1320, 1319, 1365,
 /*   210 */  1365, 1339, 1378, 1349, 1391, 1350, 1342, 1334, 1307, 1341,
 /*   220 */  1293, 1364, 1363, 1371, 1362, 1370, 1359, 1340, 1354, 1333,
 /*   230 */  1305, 1304, 1299, 1361, 1328, 1324, 1366, 1282, 1360, 1358,
 /*   240 */  1278, 1276, 1356, 1292, 1322, 1309, 1317, 1315, 1314, 1312,
 /*   250 */  1345, 1347, 1302, 1277, 1311, 1303, 1337, 1335, 1252, 1248,
 /*   260 */  1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301, 1295,
 /*   270 */  1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274, 1281,
 /*   280 */  1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266, 1189,
 /*   290 */  1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219, 1216,
 /*   300 */  1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
};
static const YYACTIONTYPE yy_default[] = {
 /*     0 */   632,  866,  954,  954,  866,  866,  954,  954,  954,  756,
 /*    10 */   954,  954,  954,  864,  954,  954,  784,  784,  928,  954,
 /*    20 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*    30 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*    40 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*    50 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*    60 */   954,  954,  954,  954,  954,  954,  954,  671,  760,  790,
 /*    70 */   954,  954,  954,  954,  954,  954,  954,  954,  927,  929,
 /*    80 */   798,  797,  907,  771,  795,  788,  792,  867,  860,  861,
 /*    90 */   859,  863,  868,  954,  791,  827,  844,  826,  838,  843,
 /*   100 */   850,  842,  839,  829,  828,  830,  831,  954,  954,  954,
 /*   110 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*   120 */   954,  954,  954,  658,  725,  954,  954,  954,  954,  954,
 /*   130 */   954,  954,  954,  832,  833,  847,  846,  845,  954,  663,
 /*   140 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*   150 */   934,  932,  954,  879,  954,  954,  954,  954,  954,  954,
 /*   160 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*   170 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*   180 */   638,  756,  756,  756,  632,  954,  954,  954,  946,  760,
 /*   190 */   750,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*   200 */   954,  954,  954,  800,  739,  917,  919,  954,  900,  737,
 /*   210 */   660,  758,  673,  748,  640,  794,  773,  773,  912,  794,
 /*   220 */   912,  696,  719,  954,  784,  954,  784,  693,  784,  773,
 /*   230 */   862,  954,  954,  954,  757,  748,  954,  939,  764,  764,
 /*   240 */   931,  931,  764,  806,  729,  794,  736,  736,  736,  736,
 /*   250 */   764,  655,  794,  806,  729,  729,  764,  655,  906,  904,
 /*   260 */   764,  764,  655,  764,  655,  764,  655,  872,  727,  727,
 /*   270 */   727,  711,  876,  876,  872,  727,  696,  727,  711,  727,
 /*   280 */   727,  777,  772,  777,  772,  777,  772,  764,  764,  954,
 /*   290 */   789,  778,  787,  785,  794,  954,  714,  648,  648,  637,
 /*   300 */   637,  637,  637,  951,  951,  946,  698,  698,  681,  954,
 /*   310 */   954,  954,  954,  954,  954,  954,  881,  954,  954,  954,
 /*   320 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  633,
 /*   330 */   941,  954,  954,  938,  954,  954,  954,  954,  799,  954,
 /*   340 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  916,
 /*   350 */   954,  954,  954,  954,  954,  954,  954,  910,  954,  954,
 /*   360 */   954,  954,  954,  954,  903,  902,  954,  954,  954,  954,
 /*   370 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*   380 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
 /*   390 */   954,  954,  786,  954,  779,  954,  865,  954,  954,  954,
 /*   400 */   954,  954,  954,  954,  954,  954,  954,  742,  815,  954,
 /*   410 */   814,  818,  813,  665,  954,  646,  954,  629,  634,  950,
 /*   420 */   953,  952,  949,  948,  947,  942,  940,  937,  936,  935,
 /*   430 */   933,  930,  926,  885,  883,  890,  889,  888,  887,  886,
 /*   440 */   884,  882,  880,  801,  796,  793,  925,  878,  738,  735,
 /*   450 */   734,  654,  943,  909,  918,  805,  804,  807,  915,  914,
 /*   460 */   913,  911,  908,  895,  803,  802,  730,  870,  869,  657,
 /*   470 */   899,  898,  897,  901,  905,  896,  766,  656,  653,  662,
 /*   480 */   717,  718,  726,  724,  723,  722,  721,  720,  716,  664,
 /*   490 */   672,  710,  695,  694,  875,  877,  874,  873,  703,  702,
 /*   500 */   708,  707,  706,  705,  704,  701,  700,  699,  692,  691,
 /*   510 */   697,  690,  713,  712,  709,  689,  733,  732,  731,  728,
 /*   520 */   688,  687,  686,  818,  685,  684,  824,  823,  811,  854,
 /*   530 */   753,  752,  751,  763,  762,  775,  774,  809,  808,  776,
 /*   540 */   761,  755,  754,  770,  769,  768,  767,  759,  749,  781,
 /*   550 */   783,  782,  780,  856,  765,  853,  924,  923,  922,  921,
 /*   560 */   920,  858,  857,  825,  822,  676,  677,  893,  892,  894,
 /*   570 */   891,  679,  678,  675,  674,  855,  744,  743,  851,  848,
 /*   580 */   840,  836,  852,  849,  841,  837,  835,  834,  820,  819,
 /*   590 */   817,  816,  812,  821,  667,  745,  741,  740,  810,  747,
 /*   600 */   746,  683,  682,  680,  661,  659,  652,  650,  649,  651,
 /*   610 */   647,  645,  644,  643,  642,  641,  670,  669,  668,  666,
 /*   620 */   665,  639,  636,  635,  631,  630,  628,
};

/* The next table maps tokens into fallback tokens.  If a construct
** like the following:
** 
**      %fallback ID X Y Z.
**







|

|
|
|
|
|
|


|
















|









|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


|

|




















|
|
|
|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







112553
112554
112555
112556
112557
112558
112559
112560
112561
112562
112563
112564
112565
112566
112567
112568
112569
112570
112571
112572
112573
112574
112575
112576
112577
112578
112579
112580
112581
112582
112583
112584
112585
112586
112587
112588
112589
112590
112591
112592
112593
112594
112595
112596
112597
112598
112599
112600
112601
112602
112603
112604
112605
112606
112607
112608
112609
112610
112611
112612
112613
112614
112615
112616
112617
112618
112619
112620
112621
112622
112623
112624
112625
112626
112627
112628
112629
112630
112631
112632
112633
112634
112635
112636
112637
112638
112639
112640
112641
112642
112643
112644
112645
112646
112647
112648
112649
112650
112651
112652
112653
112654
112655
112656
112657
112658
112659
112660
112661
112662
112663
112664
112665
112666
112667
112668
112669
112670
112671
112672
112673
112674
112675
112676
112677
112678
112679
112680
112681
112682
112683
112684
112685
112686
112687
112688
112689
112690
112691
112692
112693
112694
112695
112696
112697
112698
112699
112700
112701
112702
112703
112704
112705
112706
112707
112708
112709
112710
112711
112712
112713
112714
112715
112716
112717
112718
112719
112720
112721
112722
112723
112724
 /*  1420 */   133,  134,    5,  157,  157,  202,  118,   10,   11,   12,
 /*  1430 */    13,   14,  203,   66,   17,  104,  210,  121,  211,  129,
 /*  1440 */   130,  131,  132,  133,  134,  210,  175,  211,   31,  211,
 /*  1450 */    33,  210,  104,   86,   87,   47,  175,  183,  175,   42,
 /*  1460 */   103,   94,  178,  177,   22,   98,  175,   92,  228,  175,
 /*  1470 */   175,  228,   55,  183,   57,  178,  175,  156,   61,   18,
 /*  1480 */   157,   64,  156,  235,  157,  156,   45,  157,  236,  157,
 /*  1490 */   135,  156,  199,  189,  157,   68,  129,  130,  131,   22,
 /*  1500 */   189,  199,  157,  156,  192,   18,  192,  192,  199,  192,
 /*  1510 */   218,  189,   40,  157,  218,  157,  240,  240,  157,   38,
 /*  1520 */   196,  243,  105,  106,  107,  153,  198,  209,  111,  166,
 /*  1530 */   176,  181,  166,  116,  166,  230,  176,  230,  176,  226,
 /*  1540 */   199,  177,  239,  209,  185,  148,  166,  195,  209,  196,
 /*  1550 */   199,  208,  182,  233,  173,  182,  139,  186,  239,  234,
 /*  1560 */   191,  182,  173,   92,
};
#define YY_SHIFT_USE_DFLT (-70)
#define YY_SHIFT_COUNT (417)
#define YY_SHIFT_MIN   (-69)
#define YY_SHIFT_MAX   (1487)
static const short yy_shift_ofst[] = {
 /*     0 */  1143, 1188, 1417, 1188, 1287, 1287,  138,  138,   -2,  -19,
 /*    10 */  1287, 1287, 1287, 1287,  347,  362,  129,  129,  795, 1165,
 /*    20 */  1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
 /*    30 */  1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
 /*    40 */  1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1310, 1287,
 /*    50 */  1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
 /*    60 */  1287, 1287,  286,  362,  362,  538,  538,  231, 1253,   55,
 /*    70 */   721,  647,  573,  499,  425,  351,  277,  203,  869,  869,
 /*    80 */   869,  869,  869,  869,  869,  869,  869,  869,  869,  869,
 /*    90 */   869,  869,  869,  943,  869, 1017, 1091, 1091,  -69,  -45,
 /*   100 */   -45,  -45,  -45,  -45,   -1,   24,  245,  362,  362,  362,
 /*   110 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
 /*   120 */   362,  362,  362,  388,  356,  362,  362,  362,  362,  362,
 /*   130 */   732,  868,  231, 1051, 1471,  -70,  -70,  -70, 1367,   57,
 /*   140 */   434,  434,  289,  291,  285,    1,  204,  572,  539,  362,
 /*   150 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
 /*   160 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
 /*   170 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
 /*   180 */   362,  506,  506,  506,  705, 1253, 1253, 1253,  -70,  -70,
 /*   190 */   -70,  171,  171,  160,  502,  502,  502,  446,  432,  511,
 /*   200 */   422,  358,  335,  -12,  -12,  -12,  -12,  576,  294,  -12,
 /*   210 */   -12,  295,  595,  141,  600,  730,  723,  723,  805,  730,
 /*   220 */   805,  439,  911,  231,  865,  231,  865,  807,  865,  723,
 /*   230 */   766,  633,  633,  231,  284,   63,  608, 1481, 1308, 1308,
 /*   240 */  1472, 1472, 1308, 1477, 1427, 1275, 1487, 1487, 1487, 1487,
 /*   250 */  1308, 1461, 1275, 1477, 1427, 1427, 1275, 1308, 1461, 1355,
 /*   260 */  1441, 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348,
 /*   270 */  1348, 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408,
 /*   280 */  1348, 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308,
 /*   290 */  1280, 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346,
 /*   300 */  1338, 1338, 1338, 1338,  -70,  -70,  -70,  -70,  -70,  -70,
 /*   310 */  1013,  467,  612,   84,  179,  -28,  870,  410,  761,  760,
 /*   320 */   667,  650,  531,  220,  361,  331,  125,  127,   97, 1306,
 /*   330 */  1300, 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174,
 /*   340 */  1139, 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184,
 /*   350 */  1174, 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152,
 /*   360 */  1147, 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032,  960,
 /*   370 */  1057, 1031, 1030,  899,  938,  982,  936,  972,  958,  910,
 /*   380 */   955,  875,  885,  908,  857,  859,  867,  804,  590,  834,
 /*   390 */   747,  818,  513,  611,  741,  673,  637,  611,  606,  603,
 /*   400 */   579,  501,  541,  468,  386,  445,  395,  376,  281,  185,
 /*   410 */   120,   92,   75,   45,  114,   25,   11,    5,
};
#define YY_REDUCE_USE_DFLT (-169)
#define YY_REDUCE_COUNT (309)
#define YY_REDUCE_MIN   (-168)
#define YY_REDUCE_MAX   (1397)
static const short yy_reduce_ofst[] = {
 /*     0 */  -141,   90, 1095,  222,  158,  156,   19,   17,   10, -104,
 /*    10 */   378,  316,  311,   12,  180,  249,  598,  464,  397, 1181,
 /*    20 */  1177, 1175, 1128, 1106, 1096, 1054, 1038,  974,  964,  962,
 /*    30 */   948,  905,  903,  900,  887,  874,  832,  826,  816,  813,
 /*    40 */   800,  758,  755,  752,  742,  739,  726,  685,  681,  668,
 /*    50 */   665,  652,  607,  604,  594,  591,  578,  530,  528,  526,
 /*    60 */   385,   18,  477,  466,  519,  444,  350,  435,  405,  488,
 /*    70 */   488,  488,  488,  488,  488,  488,  488,  488,  488,  488,
 /*    80 */   488,  488,  488,  488,  488,  488,  488,  488,  488,  488,
 /*    90 */   488,  488,  488,  488,  488,  488,  488,  488,  488,  488,
 /*   100 */   488,  488,  488,  488,  488,  488,  488, 1040,  678, 1036,
 /*   110 */  1007,  967,  966,  965,  845,  686,  610,  684,  317,  672,
 /*   120 */   893,  327,  623,  522,   -7,  820,  814,  157,  154,  101,
 /*   130 */   702,  494,  580,  488,  488,  488,  488,  488,  614,  586,
 /*   140 */   935,  892,  968, 1245, 1242, 1234, 1225,  798,  798, 1222,
 /*   150 */  1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
 /*   160 */  1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
 /*   170 */  1070, 1067, 1048, 1044,  969,  968,  907,  906,  904,  894,
 /*   180 */   833,  837,  836,  340,  827,  815,  775,   68,  722,  646,
 /*   190 */  -168, 1389, 1381, 1371, 1379, 1373, 1370, 1343, 1352, 1369,
 /*   200 */  1352, 1352, 1352, 1352, 1352, 1352, 1352, 1325, 1320, 1352,
 /*   210 */  1352, 1343, 1380, 1353, 1397, 1351, 1339, 1334, 1319, 1341,
 /*   220 */  1303, 1364, 1359, 1368, 1362, 1366, 1360, 1350, 1354, 1318,
 /*   230 */  1313, 1307, 1305, 1363, 1328, 1324, 1372, 1278, 1361, 1358,
 /*   240 */  1277, 1276, 1356, 1296, 1322, 1309, 1317, 1315, 1314, 1312,
 /*   250 */  1345, 1347, 1302, 1292, 1311, 1304, 1293, 1337, 1335, 1252,
 /*   260 */  1248, 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301,
 /*   270 */  1295, 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274,
 /*   280 */  1281, 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266,
 /*   290 */  1189, 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219,
 /*   300 */  1216, 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
};
static const YYACTIONTYPE yy_default[] = {
 /*     0 */   633,  867,  955,  955,  867,  867,  955,  955,  955,  757,
 /*    10 */   955,  955,  955,  865,  955,  955,  785,  785,  929,  955,
 /*    20 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*    30 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*    40 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*    50 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*    60 */   955,  955,  955,  955,  955,  955,  955,  672,  761,  791,
 /*    70 */   955,  955,  955,  955,  955,  955,  955,  955,  928,  930,
 /*    80 */   799,  798,  908,  772,  796,  789,  793,  868,  861,  862,
 /*    90 */   860,  864,  869,  955,  792,  828,  845,  827,  839,  844,
 /*   100 */   851,  843,  840,  830,  829,  831,  832,  955,  955,  955,
 /*   110 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*   120 */   955,  955,  955,  659,  726,  955,  955,  955,  955,  955,
 /*   130 */   955,  955,  955,  833,  834,  848,  847,  846,  955,  664,
 /*   140 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*   150 */   935,  933,  955,  880,  955,  955,  955,  955,  955,  955,
 /*   160 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*   170 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*   180 */   639,  757,  757,  757,  633,  955,  955,  955,  947,  761,
 /*   190 */   751,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*   200 */   955,  955,  955,  801,  740,  918,  920,  955,  901,  738,
 /*   210 */   661,  759,  674,  749,  641,  795,  774,  774,  913,  795,
 /*   220 */   913,  697,  720,  955,  785,  955,  785,  694,  785,  774,
 /*   230 */   863,  955,  955,  955,  758,  749,  955,  940,  765,  765,
 /*   240 */   932,  932,  765,  807,  730,  795,  737,  737,  737,  737,
 /*   250 */   765,  656,  795,  807,  730,  730,  795,  765,  656,  907,
 /*   260 */   905,  765,  765,  656,  765,  656,  765,  656,  873,  728,
 /*   270 */   728,  728,  712,  877,  877,  873,  728,  697,  728,  712,
 /*   280 */   728,  728,  778,  773,  778,  773,  778,  773,  765,  765,
 /*   290 */   955,  790,  779,  788,  786,  795,  955,  715,  649,  649,
 /*   300 */   638,  638,  638,  638,  952,  952,  947,  699,  699,  682,
 /*   310 */   955,  955,  955,  955,  955,  955,  955,  882,  955,  955,
 /*   320 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*   330 */   634,  942,  955,  955,  939,  955,  955,  955,  955,  800,
 /*   340 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*   350 */   917,  955,  955,  955,  955,  955,  955,  955,  911,  955,
 /*   360 */   955,  955,  955,  955,  955,  904,  903,  955,  955,  955,
 /*   370 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*   380 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
 /*   390 */   955,  955,  955,  787,  955,  780,  955,  866,  955,  955,
 /*   400 */   955,  955,  955,  955,  955,  955,  955,  955,  743,  816,
 /*   410 */   955,  815,  819,  814,  666,  955,  647,  955,  630,  635,
 /*   420 */   951,  954,  953,  950,  949,  948,  943,  941,  938,  937,
 /*   430 */   936,  934,  931,  927,  886,  884,  891,  890,  889,  888,
 /*   440 */   887,  885,  883,  881,  802,  797,  794,  926,  879,  739,
 /*   450 */   736,  735,  655,  944,  910,  919,  806,  805,  808,  916,
 /*   460 */   915,  914,  912,  909,  896,  804,  803,  731,  871,  870,
 /*   470 */   658,  900,  899,  898,  902,  906,  897,  767,  657,  654,
 /*   480 */   663,  718,  719,  727,  725,  724,  723,  722,  721,  717,
 /*   490 */   665,  673,  711,  696,  695,  876,  878,  875,  874,  704,
 /*   500 */   703,  709,  708,  707,  706,  705,  702,  701,  700,  693,
 /*   510 */   692,  698,  691,  714,  713,  710,  690,  734,  733,  732,
 /*   520 */   729,  689,  688,  687,  819,  686,  685,  825,  824,  812,
 /*   530 */   855,  754,  753,  752,  764,  763,  776,  775,  810,  809,
 /*   540 */   777,  762,  756,  755,  771,  770,  769,  768,  760,  750,
 /*   550 */   782,  784,  783,  781,  857,  766,  854,  925,  924,  923,
 /*   560 */   922,  921,  859,  858,  826,  823,  677,  678,  894,  893,
 /*   570 */   895,  892,  680,  679,  676,  675,  856,  745,  744,  852,
 /*   580 */   849,  841,  837,  853,  850,  842,  838,  836,  835,  821,
 /*   590 */   820,  818,  817,  813,  822,  668,  746,  742,  741,  811,
 /*   600 */   748,  747,  684,  683,  681,  662,  660,  653,  651,  650,
 /*   610 */   652,  648,  646,  645,  644,  643,  642,  671,  670,  669,
 /*   620 */   667,  666,  640,  637,  636,  632,  631,  629,
};

/* The next table maps tokens into fallback tokens.  If a construct
** like the following:
** 
**      %fallback ID X Y Z.
**
111840
111841
111842
111843
111844
111845
111846
111847
111848
111849
111850
111851
111852
111853
111854
 /* 235 */ "case_else ::=",
 /* 236 */ "case_operand ::= expr",
 /* 237 */ "case_operand ::=",
 /* 238 */ "exprlist ::= nexprlist",
 /* 239 */ "exprlist ::=",
 /* 240 */ "nexprlist ::= nexprlist COMMA expr",
 /* 241 */ "nexprlist ::= expr",
 /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
 /* 243 */ "uniqueflag ::= UNIQUE",
 /* 244 */ "uniqueflag ::=",
 /* 245 */ "idxlist_opt ::=",
 /* 246 */ "idxlist_opt ::= LP idxlist RP",
 /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder",
 /* 248 */ "idxlist ::= nm collate sortorder",
 /* 249 */ "collate ::=",







|







113182
113183
113184
113185
113186
113187
113188
113189
113190
113191
113192
113193
113194
113195
113196
 /* 235 */ "case_else ::=",
 /* 236 */ "case_operand ::= expr",
 /* 237 */ "case_operand ::=",
 /* 238 */ "exprlist ::= nexprlist",
 /* 239 */ "exprlist ::=",
 /* 240 */ "nexprlist ::= nexprlist COMMA expr",
 /* 241 */ "nexprlist ::= expr",
 /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
 /* 243 */ "uniqueflag ::= UNIQUE",
 /* 244 */ "uniqueflag ::=",
 /* 245 */ "idxlist_opt ::=",
 /* 246 */ "idxlist_opt ::= LP idxlist RP",
 /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder",
 /* 248 */ "idxlist ::= nm collate sortorder",
 /* 249 */ "collate ::=",
112559
112560
112561
112562
112563
112564
112565
112566
112567
112568
112569
112570
112571
112572
112573
  { 226, 0 },
  { 224, 1 },
  { 224, 0 },
  { 220, 1 },
  { 220, 0 },
  { 215, 3 },
  { 215, 1 },
  { 147, 11 },
  { 227, 1 },
  { 227, 0 },
  { 178, 0 },
  { 178, 3 },
  { 187, 5 },
  { 187, 3 },
  { 228, 0 },







|







113901
113902
113903
113904
113905
113906
113907
113908
113909
113910
113911
113912
113913
113914
113915
  { 226, 0 },
  { 224, 1 },
  { 224, 0 },
  { 220, 1 },
  { 220, 0 },
  { 215, 3 },
  { 215, 1 },
  { 147, 12 },
  { 227, 1 },
  { 227, 0 },
  { 178, 0 },
  { 178, 3 },
  { 187, 5 },
  { 187, 3 },
  { 228, 0 },
113001
113002
113003
113004
113005
113006
113007

113008
113009
113010
113011
113012
113013
113014
{yygotominor.yy159 = yymsp[0].minor.yy159;}
        break;
      case 114: /* select ::= select multiselect_op oneselect */
{
  if( yymsp[0].minor.yy159 ){
    yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
    yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;

  }else{
    sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
  }
  yygotominor.yy159 = yymsp[0].minor.yy159;
}
        break;
      case 116: /* multiselect_op ::= UNION ALL */







>







114343
114344
114345
114346
114347
114348
114349
114350
114351
114352
114353
114354
114355
114356
114357
{yygotominor.yy159 = yymsp[0].minor.yy159;}
        break;
      case 114: /* select ::= select multiselect_op oneselect */
{
  if( yymsp[0].minor.yy159 ){
    yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
    yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
    if( yymsp[-1].minor.yy392!=TK_ALL ) pParse->hasCompound = 1;
  }else{
    sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
  }
  yygotominor.yy159 = yymsp[0].minor.yy159;
}
        break;
      case 116: /* multiselect_op ::= UNION ALL */
113563
113564
113565
113566
113567
113568
113569
113570
113571
113572
113573
113574
113575
113576
113577
113578
113579
113580
113581
        break;
      case 240: /* nexprlist ::= nexprlist COMMA expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
        break;
      case 241: /* nexprlist ::= expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
        break;
      case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
{
  sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, 
                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, yymsp[-9].minor.yy392,
                      &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392);
}
        break;
      case 243: /* uniqueflag ::= UNIQUE */
      case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
{yygotominor.yy392 = OE_Abort;}
        break;
      case 244: /* uniqueflag ::= */







|

|
|
|







114906
114907
114908
114909
114910
114911
114912
114913
114914
114915
114916
114917
114918
114919
114920
114921
114922
114923
114924
        break;
      case 240: /* nexprlist ::= nexprlist COMMA expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
        break;
      case 241: /* nexprlist ::= expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
        break;
      case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
{
  sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, 
                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy442, yymsp[-10].minor.yy392,
                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy122, SQLITE_SO_ASC, yymsp[-8].minor.yy392);
}
        break;
      case 243: /* uniqueflag ::= UNIQUE */
      case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
{yygotominor.yy392 = OE_Abort;}
        break;
      case 244: /* uniqueflag ::= */
114493
114494
114495
114496
114497
114498
114499
114500
114501
114502
114503
114504
114505
114506
114507
      testcase( z[0]=='\r' );
      for(i=1; sqlite3Isspace(z[i]); i++){}
      *tokenType = TK_SPACE;
      return i;
    }
    case '-': {
      if( z[1]=='-' ){
        /* IMP: R-50417-27976 -- syntax diagram for comments */
        for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
        *tokenType = TK_SPACE;   /* IMP: R-22934-25134 */
        return i;
      }
      *tokenType = TK_MINUS;
      return 1;
    }







<







115836
115837
115838
115839
115840
115841
115842

115843
115844
115845
115846
115847
115848
115849
      testcase( z[0]=='\r' );
      for(i=1; sqlite3Isspace(z[i]); i++){}
      *tokenType = TK_SPACE;
      return i;
    }
    case '-': {
      if( z[1]=='-' ){

        for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
        *tokenType = TK_SPACE;   /* IMP: R-22934-25134 */
        return i;
      }
      *tokenType = TK_MINUS;
      return 1;
    }
114526
114527
114528
114529
114530
114531
114532
114533
114534
114535
114536
114537
114538
114539
114540
      return 1;
    }
    case '/': {
      if( z[1]!='*' || z[2]==0 ){
        *tokenType = TK_SLASH;
        return 1;
      }
      /* IMP: R-50417-27976 -- syntax diagram for comments */
      for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
      if( c ) i++;
      *tokenType = TK_SPACE;   /* IMP: R-22934-25134 */
      return i;
    }
    case '%': {
      *tokenType = TK_REM;







<







115868
115869
115870
115871
115872
115873
115874

115875
115876
115877
115878
115879
115880
115881
      return 1;
    }
    case '/': {
      if( z[1]!='*' || z[2]==0 ){
        *tokenType = TK_SLASH;
        return 1;
      }

      for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
      if( c ) i++;
      *tokenType = TK_SPACE;   /* IMP: R-22934-25134 */
      return i;
    }
    case '%': {
      *tokenType = TK_REM;
115388
115389
115390
115391
115392
115393
115394



115395
115396
115397
115398
115399
115400
115401
**
**    *  Recursive calls to this routine from thread X return immediately
**       without blocking.
*/
SQLITE_API int sqlite3_initialize(void){
  MUTEX_LOGIC( sqlite3_mutex *pMaster; )       /* The main static mutex */
  int rc;                                      /* Result code */




#ifdef SQLITE_OMIT_WSD
  rc = sqlite3_wsd_init(4096, 24);
  if( rc!=SQLITE_OK ){
    return rc;
  }
#endif







>
>
>







116729
116730
116731
116732
116733
116734
116735
116736
116737
116738
116739
116740
116741
116742
116743
116744
116745
**
**    *  Recursive calls to this routine from thread X return immediately
**       without blocking.
*/
SQLITE_API int sqlite3_initialize(void){
  MUTEX_LOGIC( sqlite3_mutex *pMaster; )       /* The main static mutex */
  int rc;                                      /* Result code */
#ifdef SQLITE_EXTRA_INIT
  int bRunExtraInit = 0;                       /* Extra initialization needed */
#endif

#ifdef SQLITE_OMIT_WSD
  rc = sqlite3_wsd_init(4096, 24);
  if( rc!=SQLITE_OK ){
    return rc;
  }
#endif
115485
115486
115487
115488
115489
115490
115491



115492
115493
115494
115495
115496
115497
115498
      sqlite3GlobalConfig.isPCacheInit = 1;
      rc = sqlite3OsInit();
    }
    if( rc==SQLITE_OK ){
      sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, 
          sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
      sqlite3GlobalConfig.isInit = 1;



    }
    sqlite3GlobalConfig.inProgress = 0;
  }
  sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex);

  /* Go back under the static mutex and clean up the recursive
  ** mutex to prevent a resource leak.







>
>
>







116829
116830
116831
116832
116833
116834
116835
116836
116837
116838
116839
116840
116841
116842
116843
116844
116845
      sqlite3GlobalConfig.isPCacheInit = 1;
      rc = sqlite3OsInit();
    }
    if( rc==SQLITE_OK ){
      sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, 
          sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
      sqlite3GlobalConfig.isInit = 1;
#ifdef SQLITE_EXTRA_INIT
      bRunExtraInit = 1;
#endif
    }
    sqlite3GlobalConfig.inProgress = 0;
  }
  sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex);

  /* Go back under the static mutex and clean up the recursive
  ** mutex to prevent a resource leak.
115525
115526
115527
115528
115529
115530
115531
115532
115533
115534
115535
115536
115537
115538
115539
#endif
#endif

  /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT
  ** compile-time option.
  */
#ifdef SQLITE_EXTRA_INIT
  if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){
    int SQLITE_EXTRA_INIT(const char*);
    rc = SQLITE_EXTRA_INIT(0);
  }
#endif

  return rc;
}







|







116872
116873
116874
116875
116876
116877
116878
116879
116880
116881
116882
116883
116884
116885
116886
#endif
#endif

  /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT
  ** compile-time option.
  */
#ifdef SQLITE_EXTRA_INIT
  if( bRunExtraInit ){
    int SQLITE_EXTRA_INIT(const char*);
    rc = SQLITE_EXTRA_INIT(0);
  }
#endif

  return rc;
}
115713
115714
115715
115716
115717
115718
115719
115720
115721
115722
115723
115724
115725
115726
115727
115728
115729
115730
115731
115732
115733
115734
115735
115736
115737
115738
115739
115740
115741
115742
115743
115744
115745
115746
115747
        ** back to NULL pointers too.  This will cause the malloc to go
        ** back to its default implementation when sqlite3_initialize() is
        ** run.
        */
        memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
      }else{
        /* The heap pointer is not NULL, then install one of the
        ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor
        ** ENABLE_MEMSYS5 is defined, return an error.
        */
#ifdef SQLITE_ENABLE_MEMSYS3
        sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
#endif
#ifdef SQLITE_ENABLE_MEMSYS5
        sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5();
#endif
      }
      break;
    }
#endif

    case SQLITE_CONFIG_LOOKASIDE: {
      sqlite3GlobalConfig.szLookaside = va_arg(ap, int);
      sqlite3GlobalConfig.nLookaside = va_arg(ap, int);
      break;
    }
    
    /* Record a pointer to the logger funcction and its first argument.
    ** The default is NULL.  Logging is disabled if the function pointer is
    ** NULL.
    */
    case SQLITE_CONFIG_LOG: {
      /* MSVC is picky about pulling func ptrs from va lists.
      ** http://support.microsoft.com/kb/47961
      ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*));







|
|


















|







117060
117061
117062
117063
117064
117065
117066
117067
117068
117069
117070
117071
117072
117073
117074
117075
117076
117077
117078
117079
117080
117081
117082
117083
117084
117085
117086
117087
117088
117089
117090
117091
117092
117093
117094
        ** back to NULL pointers too.  This will cause the malloc to go
        ** back to its default implementation when sqlite3_initialize() is
        ** run.
        */
        memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
      }else{
        /* The heap pointer is not NULL, then install one of the
        ** mem5.c/mem3.c methods.  The enclosing #if guarantees at
        ** least one of these methods is currently enabled.
        */
#ifdef SQLITE_ENABLE_MEMSYS3
        sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
#endif
#ifdef SQLITE_ENABLE_MEMSYS5
        sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5();
#endif
      }
      break;
    }
#endif

    case SQLITE_CONFIG_LOOKASIDE: {
      sqlite3GlobalConfig.szLookaside = va_arg(ap, int);
      sqlite3GlobalConfig.nLookaside = va_arg(ap, int);
      break;
    }
    
    /* Record a pointer to the logger function and its first argument.
    ** The default is NULL.  Logging is disabled if the function pointer is
    ** NULL.
    */
    case SQLITE_CONFIG_LOG: {
      /* MSVC is picky about pulling func ptrs from va lists.
      ** http://support.microsoft.com/kb/47961
      ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*));
116371
116372
116373
116374
116375
116376
116377


116378
116379
116380
116381
116382
116383
116384
116385

116386
116387
116388
116389
116390
116391
116392
      case SQLITE_IOERR_SHMOPEN:      zName = "SQLITE_IOERR_SHMOPEN";     break;
      case SQLITE_IOERR_SHMSIZE:      zName = "SQLITE_IOERR_SHMSIZE";     break;
      case SQLITE_IOERR_SHMLOCK:      zName = "SQLITE_IOERR_SHMLOCK";     break;
      case SQLITE_IOERR_SHMMAP:       zName = "SQLITE_IOERR_SHMMAP";      break;
      case SQLITE_IOERR_SEEK:         zName = "SQLITE_IOERR_SEEK";        break;
      case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
      case SQLITE_IOERR_MMAP:         zName = "SQLITE_IOERR_MMAP";        break;


      case SQLITE_CORRUPT:            zName = "SQLITE_CORRUPT";           break;
      case SQLITE_CORRUPT_VTAB:       zName = "SQLITE_CORRUPT_VTAB";      break;
      case SQLITE_NOTFOUND:           zName = "SQLITE_NOTFOUND";          break;
      case SQLITE_FULL:               zName = "SQLITE_FULL";              break;
      case SQLITE_CANTOPEN:           zName = "SQLITE_CANTOPEN";          break;
      case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
      case SQLITE_CANTOPEN_ISDIR:     zName = "SQLITE_CANTOPEN_ISDIR";    break;
      case SQLITE_CANTOPEN_FULLPATH:  zName = "SQLITE_CANTOPEN_FULLPATH"; break;

      case SQLITE_PROTOCOL:           zName = "SQLITE_PROTOCOL";          break;
      case SQLITE_EMPTY:              zName = "SQLITE_EMPTY";             break;
      case SQLITE_SCHEMA:             zName = "SQLITE_SCHEMA";            break;
      case SQLITE_TOOBIG:             zName = "SQLITE_TOOBIG";            break;
      case SQLITE_CONSTRAINT:         zName = "SQLITE_CONSTRAINT";        break;
      case SQLITE_CONSTRAINT_UNIQUE:  zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
      case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break;







>
>








>







117718
117719
117720
117721
117722
117723
117724
117725
117726
117727
117728
117729
117730
117731
117732
117733
117734
117735
117736
117737
117738
117739
117740
117741
117742
      case SQLITE_IOERR_SHMOPEN:      zName = "SQLITE_IOERR_SHMOPEN";     break;
      case SQLITE_IOERR_SHMSIZE:      zName = "SQLITE_IOERR_SHMSIZE";     break;
      case SQLITE_IOERR_SHMLOCK:      zName = "SQLITE_IOERR_SHMLOCK";     break;
      case SQLITE_IOERR_SHMMAP:       zName = "SQLITE_IOERR_SHMMAP";      break;
      case SQLITE_IOERR_SEEK:         zName = "SQLITE_IOERR_SEEK";        break;
      case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
      case SQLITE_IOERR_MMAP:         zName = "SQLITE_IOERR_MMAP";        break;
      case SQLITE_IOERR_GETTEMPPATH:  zName = "SQLITE_IOERR_GETTEMPPATH"; break;
      case SQLITE_IOERR_CONVPATH:     zName = "SQLITE_IOERR_CONVPATH";    break;
      case SQLITE_CORRUPT:            zName = "SQLITE_CORRUPT";           break;
      case SQLITE_CORRUPT_VTAB:       zName = "SQLITE_CORRUPT_VTAB";      break;
      case SQLITE_NOTFOUND:           zName = "SQLITE_NOTFOUND";          break;
      case SQLITE_FULL:               zName = "SQLITE_FULL";              break;
      case SQLITE_CANTOPEN:           zName = "SQLITE_CANTOPEN";          break;
      case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
      case SQLITE_CANTOPEN_ISDIR:     zName = "SQLITE_CANTOPEN_ISDIR";    break;
      case SQLITE_CANTOPEN_FULLPATH:  zName = "SQLITE_CANTOPEN_FULLPATH"; break;
      case SQLITE_CANTOPEN_CONVPATH:  zName = "SQLITE_CANTOPEN_CONVPATH"; break;
      case SQLITE_PROTOCOL:           zName = "SQLITE_PROTOCOL";          break;
      case SQLITE_EMPTY:              zName = "SQLITE_EMPTY";             break;
      case SQLITE_SCHEMA:             zName = "SQLITE_SCHEMA";            break;
      case SQLITE_TOOBIG:             zName = "SQLITE_TOOBIG";            break;
      case SQLITE_CONSTRAINT:         zName = "SQLITE_CONSTRAINT";        break;
      case SQLITE_CONSTRAINT_UNIQUE:  zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
      case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break;
117448
117449
117450
117451
117452
117453
117454


117455
117456
117457
117458
117459
117460
117461
117462
117463
117464
117465
117466
117467
117468

117469
117470
117471
117472
117473
117474
117475
    ** method that there may be extra parameters following the file-name.  */
    flags |= SQLITE_OPEN_URI;

    for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
    zFile = sqlite3_malloc(nByte);
    if( !zFile ) return SQLITE_NOMEM;



    /* Discard the scheme and authority segments of the URI. */
    if( zUri[5]=='/' && zUri[6]=='/' ){
      iIn = 7;
      while( zUri[iIn] && zUri[iIn]!='/' ) iIn++;

      if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){
        *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", 
            iIn-7, &zUri[7]);
        rc = SQLITE_ERROR;
        goto parse_uri_out;
      }
    }else{
      iIn = 5;
    }


    /* Copy the filename and any query parameters into the zFile buffer. 
    ** Decode %HH escape codes along the way. 
    **
    ** Within this loop, variable eState may be set to 0, 1 or 2, depending
    ** on the parsing context. As follows:
    **







>
>




<






<
<

>







118798
118799
118800
118801
118802
118803
118804
118805
118806
118807
118808
118809
118810

118811
118812
118813
118814
118815
118816


118817
118818
118819
118820
118821
118822
118823
118824
118825
    ** method that there may be extra parameters following the file-name.  */
    flags |= SQLITE_OPEN_URI;

    for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
    zFile = sqlite3_malloc(nByte);
    if( !zFile ) return SQLITE_NOMEM;

    iIn = 5;
#ifndef SQLITE_ALLOW_URI_AUTHORITY
    /* Discard the scheme and authority segments of the URI. */
    if( zUri[5]=='/' && zUri[6]=='/' ){
      iIn = 7;
      while( zUri[iIn] && zUri[iIn]!='/' ) iIn++;

      if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){
        *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", 
            iIn-7, &zUri[7]);
        rc = SQLITE_ERROR;
        goto parse_uri_out;
      }


    }
#endif

    /* Copy the filename and any query parameters into the zFile buffer. 
    ** Decode %HH escape codes along the way. 
    **
    ** Within this loop, variable eState may be set to 0, 1 or 2, depending
    ** on the parsing context. As follows:
    **
117725
117726
117727
117728
117729
117730
117731
117732
117733
117734
117735
117736
117737
117738
117739
117740

  assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
  memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
  db->autoCommit = 1;
  db->nextAutovac = -1;
  db->szMmap = sqlite3GlobalConfig.szMmap;
  db->nextPagesize = 0;
  db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger
#if !defined(SQLITE_DEAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
                 | SQLITE_AutoIndex
#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4
                 | SQLITE_LegacyFileFmt
#endif
#ifdef SQLITE_ENABLE_LOAD_EXTENSION
                 | SQLITE_LoadExtension







|
|







119075
119076
119077
119078
119079
119080
119081
119082
119083
119084
119085
119086
119087
119088
119089
119090

  assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
  memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
  db->autoCommit = 1;
  db->nextAutovac = -1;
  db->szMmap = sqlite3GlobalConfig.szMmap;
  db->nextPagesize = 0;
  db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
                 | SQLITE_AutoIndex
#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4
                 | SQLITE_LegacyFileFmt
#endif
#ifdef SQLITE_ENABLE_LOAD_EXTENSION
                 | SQLITE_LoadExtension
128199
128200
128201
128202
128203
128204
128205
128206
128207
128208
128209
128210
128211
128212
128213
  sqlite3_free(zCopy);
  return rc;
}


#ifdef SQLITE_TEST

/* #include <tcl.h> */
/* #include <string.h> */

/*
** Implementation of a special SQL scalar function for testing tokenizers 
** designed to be used in concert with the Tcl testing framework. This
** function must be called with two or more arguments:
**







|







129549
129550
129551
129552
129553
129554
129555
129556
129557
129558
129559
129560
129561
129562
129563
  sqlite3_free(zCopy);
  return rc;
}


#ifdef SQLITE_TEST

#include <tcl.h>
/* #include <string.h> */

/*
** Implementation of a special SQL scalar function for testing tokenizers 
** designed to be used in concert with the Tcl testing framework. This
** function must be called with two or more arguments:
**
130638
130639
130640
130641
130642
130643
130644
130645
130646
130647
130648
130649
130650
130651
130652
    ** following block advances it to point one byte past the end of
    ** the same offset list. */
    while( 1 ){
  
      /* The following line of code (and the "p++" below the while() loop) is
      ** normally all that is required to move pointer p to the desired 
      ** position. The exception is if this node is being loaded from disk
      ** incrementally and pointer "p" now points to the first byte passed
      ** the populated part of pReader->aNode[].
      */
      while( *p | c ) c = *p++ & 0x80;
      assert( *p==0 );
  
      if( pReader->pBlob==0 || p<&pReader->aNode[pReader->nPopulate] ) break;
      rc = fts3SegReaderIncrRead(pReader);







|







131988
131989
131990
131991
131992
131993
131994
131995
131996
131997
131998
131999
132000
132001
132002
    ** following block advances it to point one byte past the end of
    ** the same offset list. */
    while( 1 ){
  
      /* The following line of code (and the "p++" below the while() loop) is
      ** normally all that is required to move pointer p to the desired 
      ** position. The exception is if this node is being loaded from disk
      ** incrementally and pointer "p" now points to the first byte past
      ** the populated part of pReader->aNode[].
      */
      while( *p | c ) c = *p++ & 0x80;
      assert( *p==0 );
  
      if( pReader->pBlob==0 || p<&pReader->aNode[pReader->nPopulate] ) break;
      rc = fts3SegReaderIncrRead(pReader);
132025
132026
132027
132028
132029
132030
132031
132032
132033
132034
132035
132036
132037
132038
132039
132040
      */
      for(i=0; i<nMerge; i++){
        fts3SegReaderFirstDocid(p, apSegment[i]);
      }
      fts3SegReaderSort(apSegment, nMerge, nMerge, xCmp);
      while( apSegment[0]->pOffsetList ){
        int j;                    /* Number of segments that share a docid */
        char *pList;
        int nList;
        int nByte;
        sqlite3_int64 iDocid = apSegment[0]->iDocid;
        fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList);
        j = 1;
        while( j<nMerge
            && apSegment[j]->pOffsetList
            && apSegment[j]->iDocid==iDocid







|
|







133375
133376
133377
133378
133379
133380
133381
133382
133383
133384
133385
133386
133387
133388
133389
133390
      */
      for(i=0; i<nMerge; i++){
        fts3SegReaderFirstDocid(p, apSegment[i]);
      }
      fts3SegReaderSort(apSegment, nMerge, nMerge, xCmp);
      while( apSegment[0]->pOffsetList ){
        int j;                    /* Number of segments that share a docid */
        char *pList = 0;
        int nList = 0;
        int nByte;
        sqlite3_int64 iDocid = apSegment[0]->iDocid;
        fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList);
        j = 1;
        while( j<nMerge
            && apSegment[j]->pOffsetList
            && apSegment[j]->iDocid==iDocid
134312
134313
134314
134315
134316
134317
134318
134319

134320
134321
134322
134323
134324
134325
134326
134327
134328
134329
134330
              fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
            }
          }
        }
        if( pTC ) pModule->xClose(pTC);
        if( rc==SQLITE_DONE ) rc = SQLITE_OK;
      }


      for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
        if( pDef->pList ){
          rc = fts3PendingListAppendVarint(&pDef->pList, 0);
        }
      }
    }
  }

  return rc;
}








|
>
|
|
|
<







135662
135663
135664
135665
135666
135667
135668
135669
135670
135671
135672
135673

135674
135675
135676
135677
135678
135679
135680
              fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
            }
          }
        }
        if( pTC ) pModule->xClose(pTC);
        if( rc==SQLITE_DONE ) rc = SQLITE_OK;
      }
    }

    for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
      if( pDef->pList ){
        rc = fts3PendingListAppendVarint(&pDef->pList, 0);

      }
    }
  }

  return rc;
}

135099
135100
135101
135102
135103
135104
135105

135106
135107
135108
135109
135110
135111
135112
    char *zNew = sqlite3_realloc(pStr->z, nAlloc);
    if( !zNew ){
      return SQLITE_NOMEM;
    }
    pStr->z = zNew;
    pStr->nAlloc = nAlloc;
  }


  /* Append the data to the string buffer. */
  memcpy(&pStr->z[pStr->n], zAppend, nAppend);
  pStr->n += nAppend;
  pStr->z[pStr->n] = '\0';

  return SQLITE_OK;







>







136449
136450
136451
136452
136453
136454
136455
136456
136457
136458
136459
136460
136461
136462
136463
    char *zNew = sqlite3_realloc(pStr->z, nAlloc);
    if( !zNew ){
      return SQLITE_NOMEM;
    }
    pStr->z = zNew;
    pStr->nAlloc = nAlloc;
  }
  assert( pStr->z!=0 && (pStr->nAlloc >= pStr->n+nAppend+1) );

  /* Append the data to the string buffer. */
  memcpy(&pStr->z[pStr->n], zAppend, nAppend);
  pStr->n += nAppend;
  pStr->z[pStr->n] = '\0';

  return SQLITE_OK;
Changes to src/sqlite3.h.
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.0"
#define SQLITE_VERSION_NUMBER 3008000
#define SQLITE_SOURCE_ID      "2013-07-18 14:50:56 5dcffa671f592ae9355628afa439ae9a2d26f0cd"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|
|
|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.1"
#define SQLITE_VERSION_NUMBER 3008001
#define SQLITE_SOURCE_ID      "2013-09-04 04:04:08 8df95bb0b3f72222cf262174247a467c234f9939"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
474
475
476
477
478
479
480


481
482
483
484
485
486

487
488
489
490
491
492
493
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))


#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))

#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
#define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))







>
>






>







474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
#define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
#define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
#define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))
2557
2558
2559
2560
2561
2562
2563
2564

2565
2566
2567
2568
2569
2570
2571
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
** database connection D.  An example use for this
** interface is to keep a GUI updated during a large query.
**
** ^The parameter P is passed through as the only parameter to the 
** callback function X.  ^The parameter N is the approximate number of 
** [virtual machine instructions] that are evaluated between successive
** invocations of the callback X.

**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
** old one.  ^Setting parameter X to NULL disables the progress handler.
** ^The progress handler is also disabled by setting N to a value less
** than 1.
**







|
>







2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
** database connection D.  An example use for this
** interface is to keep a GUI updated during a large query.
**
** ^The parameter P is passed through as the only parameter to the 
** callback function X.  ^The parameter N is the approximate number of 
** [virtual machine instructions] that are evaluated between successive
** invocations of the callback X.  ^If N is less than one then the progress
** handler is disabled.
**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
** old one.  ^Setting parameter X to NULL disables the progress handler.
** ^The progress handler is also disabled by setting N to a value less
** than 1.
**
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190

4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206

4207
4208

4209
4210
4211
4212

4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
** registered the application defined function.
*/
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);

/*
** CAPI3REF: Function Auxiliary Data
**
** The following two functions may be used by scalar SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved. This might
** be used, for example, in a regular-expression matching
** function. The compiled version of the regular expression is stored as
** metadata associated with the SQL value passed as the regular expression

** pattern.  The compiled regular expression can be reused on multiple
** invocations of the same function so that the original pattern string
** does not need to be recompiled on each invocation.
**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
** value to the application-defined function. ^If no metadata has been ever
** been set for the Nth argument of the function, or if the corresponding
** function parameter has changed since the meta-data was set,
** then sqlite3_get_auxdata() returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** argument of the application-defined function.  ^Subsequent
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
** sqlite3_set_auxdata(C,N,P,X) call if the data has not been dropped, or
** NULL if the data has been dropped.

** ^(If it is not NULL, SQLite will invoke the destructor
** function X passed to sqlite3_set_auxdata(C,N,P,X) when <ul>

** <li> the corresponding function parameter changes,
** <li> [sqlite3_reset()] or [sqlite3_finalize()] is called for the
**      SQL statement,
** <li> sqlite3_set_auxdata() is invoked again on the same parameter, or

** <li> a memory allocation error occurs. </ul>)^
**
** SQLite is free to call the destructor and drop metadata on any
** parameter of any function at any time.  ^The only guarantee is that
** the destructor will be called when the [prepared statement] is destroyed.
** Note in particular that the destructor X in the call to
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before
** the sqlite3_set_auxdata() call even returns.  Hence sqlite3_set_auxdata()
** should be called near the end of the function implementation and the
** implementation should not make any use of P after sqlite3_set_auxdata()
** has been called.
**
** ^(In practice, metadata is preserved between function calls for
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
** These routines must be called from the same thread in which
** the SQL function is running.







|


|
|
|
|
>
|
|
<



|
<
|
|




|
|
>
|
|
>
|
|
|
|
>
|

<
<
<
|
|
|

|
|







4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197

4198
4199
4200
4201

4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220



4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
** registered the application defined function.
*/
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);

/*
** CAPI3REF: Function Auxiliary Data
**
** These functions may be used by (non-aggregate) SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
** some circumstances the associated metadata may be preserved.  An example
** of where this might be useful is in a regular-expression matching
** function. The compiled version of the regular expression can be stored as
** metadata associated with the pattern string.  
** Then as long as the pattern string remains the same,
** the compiled regular expression can be reused on multiple
** invocations of the same function.

**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
** value to the application-defined function. ^If there is no metadata

** associated with the function argument, this sqlite3_get_auxdata() interface
** returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
** argument of the application-defined function.  ^Subsequent
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
** NULL if the metadata has been discarded.
** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
** SQLite will invoke the destructor function X with parameter P exactly
** once, when the metadata is discarded.
** SQLite is free to discard the metadata at any time, including: <ul>
** <li> when the corresponding function parameter changes, or
** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
**      SQL statement, or
** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
** <li> during the original sqlite3_set_auxdata() call when a memory 
**      allocation error occurs. </ul>)^
**



** Note the last bullet in particular.  The destructor X in 
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
** sqlite3_set_auxdata() interface even returns.  Hence sqlite3_set_auxdata()
** should be called near the end of the function implementation and the
** function implementation should not make any use of P after
** sqlite3_set_auxdata() has been called.
**
** ^(In practice, metadata is preserved between function calls for
** function parameters that are compile-time constants, including literal
** values and [parameters] and expressions composed from the same.)^
**
** These routines must be called from the same thread in which
** the SQL function is running.
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
** transaction rollback or database recovery operations are not included.
** If an IO or other error occurs while writing a page to disk, the effect
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns the zero for the current value if and only if
** there all foreign key constraints (deferred or immediate) have been
** resolved.  The highwater mark is always 0.
** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED       0
#define SQLITE_DBSTATUS_CACHE_USED           1
#define SQLITE_DBSTATUS_SCHEMA_USED          2
#define SQLITE_DBSTATUS_STMT_USED            3







|
|
|







6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
** transaction rollback or database recovery operations are not included.
** If an IO or other error occurs while writing a page to disk, the effect
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns zero for the current value if and only if
** all foreign key constraints (deferred or immediate) have been
** resolved.)^  ^The highwater mark is always 0.
** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED       0
#define SQLITE_DBSTATUS_CACHE_USED           1
#define SQLITE_DBSTATUS_SCHEMA_USED          2
#define SQLITE_DBSTATUS_STMT_USED            3
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif

/*
** 2010 August 30
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**







|







7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif /* _SQLITE3_H_ */

/*
** 2010 August 30
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
Changes to src/style.c.
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
** The form of the anchor tag is determined by the g.javascriptHyperlink
** variable.  The href="URL" form is used if g.javascriptHyperlink is false.
** If g.javascriptHyperlink is true then the
** id="ID" form is used and javascript is generated in the footer to cause
** href values to be inserted after the page has loaded.  If
** g.perm.History is false, then the <a id="ID"> form is still
** generated but the javascript is not generated so the links never
** activate. 
**
** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
** g.javascriptHyperlink is set to 1.  The g.javascriptHyperlink defaults
** to 0 and only changes to one if the user lacks the Hyperlink (h) property
** and the "auto-hyperlink" setting is enabled.
**







|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
** The form of the anchor tag is determined by the g.javascriptHyperlink
** variable.  The href="URL" form is used if g.javascriptHyperlink is false.
** If g.javascriptHyperlink is true then the
** id="ID" form is used and javascript is generated in the footer to cause
** href values to be inserted after the page has loaded.  If
** g.perm.History is false, then the <a id="ID"> form is still
** generated but the javascript is not generated so the links never
** activate.
**
** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
** g.javascriptHyperlink is set to 1.  The g.javascriptHyperlink defaults
** to 0 and only changes to one if the user lacks the Hyperlink (h) property
** and the "auto-hyperlink" setting is enabled.
**
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
    return zHUrl;
  }
  if( nHref>=nHrefAlloc ){
    nHrefAlloc = nHrefAlloc*2 + 10;
    aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
  }
  aHref[nHref++] = zUrl;
  return mprintf("<a %s id='a%d'>", zExtra, nHref);
}
char *href(const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.perm.Hyperlink && !g.javascriptHyperlink ){
    char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
    fossil_free(zUrl);
    return zHUrl;
  }
  if( nHref>=nHrefAlloc ){
    nHrefAlloc = nHrefAlloc*2 + 10;
    aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
  }
  aHref[nHref++] = zUrl;
  return mprintf("<a id='a%d'>", nHref);
}

/*
** Generate <form method="post" action=ARG>.  The ARG value is inserted
** by javascript.
*/
void form_begin(const char *zOtherArgs, const char *zAction, ...){







|

















|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
    return zHUrl;
  }
  if( nHref>=nHrefAlloc ){
    nHrefAlloc = nHrefAlloc*2 + 10;
    aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
  }
  aHref[nHref++] = zUrl;
  return mprintf("<a %s id='a%d' href='%R/honeypot'>", zExtra, nHref);
}
char *href(const char *zFormat, ...){
  char *zUrl;
  va_list ap;
  va_start(ap, zFormat);
  zUrl = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.perm.Hyperlink && !g.javascriptHyperlink ){
    char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
    fossil_free(zUrl);
    return zHUrl;
  }
  if( nHref>=nHrefAlloc ){
    nHrefAlloc = nHrefAlloc*2 + 10;
    aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
  }
  aHref[nHref++] = zUrl;
  return mprintf("<a id='a%d' href='%R/honeypot'>", nHref);
}

/*
** Generate <form method="post" action=ARG>.  The ARG value is inserted
** by javascript.
*/
void form_begin(const char *zOtherArgs, const char *zAction, ...){
655
656
657
658
659
660
661





662
663
664
665
666
667
668
    @   border: 0;
  },
  { "td.timelineTableCell",
    "the format for the timeline data cells",
    @   vertical-align: top;
    @   text-align: left;
  },





  { "span.timelineLeaf",
    "the format for the timeline leaf marks",
    @   font-weight: bold;
  },
  { "a.timelineHistLink",
    "the format for the timeline version links",
    @







>
>
>
>
>







655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
    @   border: 0;
  },
  { "td.timelineTableCell",
    "the format for the timeline data cells",
    @   vertical-align: top;
    @   text-align: left;
  },
  { "tr.timelineCurrent td.timelineTableCell",
    "the format for the timeline data cell of the current checkout",
    @   padding: .1em .2em;
    @   border: 1px dashed #446979;
  },
  { "span.timelineLeaf",
    "the format for the timeline leaf marks",
    @   font-weight: bold;
  },
  { "a.timelineHistLink",
    "the format for the timeline version links",
    @
965
966
967
968
969
970
971

972
973
974
975
976
977
978
  { "ul.filelist",
    "List of files in a timeline",
    @   margin-top: 3px;
    @   line-height: 100%;
  },
  { "table.sbsdiffcols",
    "side-by-side diff display (column-based)",

    @   border-spacing: 0;
    @   font-size: xx-small;
  },
  { "table.sbsdiffcols td",
    "sbs diff table cell",
    @   padding: 0;
    @   vertical-align: top;







>







970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
  { "ul.filelist",
    "List of files in a timeline",
    @   margin-top: 3px;
    @   line-height: 100%;
  },
  { "table.sbsdiffcols",
    "side-by-side diff display (column-based)",
    @   width: 90%;
    @   border-spacing: 0;
    @   font-size: xx-small;
  },
  { "table.sbsdiffcols td",
    "sbs diff table cell",
    @   padding: 0;
    @   vertical-align: top;
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
    @   text-align: right;
    @   padding: 0.2ex 2ex;
  },
  { ".statistics-report-graph-line",
    "for the /stats_report views",
    @   background-color: #446979;
  },
  { ".statistics-report-table-events th"
    "",
    @   padding: 0 1em 0 1em;
  },
  { ".statistics-report-table-events td",
    "",
    @   padding: 0.1em 1em 0.1em 1em;
  },







|







1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
    @   text-align: right;
    @   padding: 0.2ex 2ex;
  },
  { ".statistics-report-graph-line",
    "for the /stats_report views",
    @   background-color: #446979;
  },
  { ".statistics-report-table-events th",
    "",
    @   padding: 0 1em 0 1em;
  },
  { ".statistics-report-table-events td",
    "",
    @   padding: 0.1em 1em 0.1em 1em;
  },
1077
1078
1079
1080
1081
1082
1083




1084
1085
1086
1087
1088
1089
1090
  { "tr.row0",
    "even table row color",
    @ /* use default */
  },
  { "tr.row1",
    "odd table row color",
    @ /* Use default */




  },
  { 0,
    0,
    0
  }
};








>
>
>
>







1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
  { "tr.row0",
    "even table row color",
    @ /* use default */
  },
  { "tr.row1",
    "odd table row color",
    @ /* Use default */
  },
  { "#canvas", "timeline graph node colors",
    @ color: black;
    @ background-color: white;
  },
  { 0,
    0,
    0
  }
};

1144
1145
1146
1147
1148
1149
1150









1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178
1179






1180
1181
1182
1183
1184

1185










** WEBPAGE: test_env
*/
void page_test_env(void){
  char c;
  int i;
  int showAll;
  char zCap[30];









  login_check_credentials();
  if( !g.perm.Admin && !g.perm.Setup && !db_get_boolean("test_env_enable",0) ){
    login_needed();
    return;
  }

  style_header("Environment Test");
  showAll = atoi(PD("showall","0"));
  if( !showAll ){
    style_submenu_element("Show Cookies", "Show Cookies",
                          "%s/test_env?showall=1", g.zTop);
  }else{
    style_submenu_element("Hide Cookies", "Hide Cookies",
                          "%s/test_env", g.zTop);
  }
#if !defined(_WIN32)
  @ uid=%d(getuid()), gid=%d(getgid())<br />
#endif
  @ g.zBaseURL = %h(g.zBaseURL)<br />
  @ g.zTop = %h(g.zTop)<br />
  for(i=0, c='a'; c<='z'; c++){
    if( login_has_capability(&c, 1) ) zCap[i++] = c;
  }
  zCap[i] = 0;
  @ g.userUid = %d(g.userUid)<br />
  @ g.zLogin = %h(g.zLogin)<br />

  @ capabilities = %s(zCap)<br />
  @ <hr>
  P("HTTP_USER_AGENT");
  cgi_print_all(atoi(PD("showall","0")));






  if( g.perm.Setup ){
    const char *zRedir = P("redirect");
    if( zRedir ) cgi_redirect(zRedir);
  }
  style_footer();

}

















>
>
>
>
>
>
>
>
>





>




















>



|
>
>
>
>
>
>





>

>
>
>
>
>
>
>
>
>
>
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
** WEBPAGE: test_env
*/
void page_test_env(void){
  char c;
  int i;
  int showAll;
  char zCap[30];
  static const char *azCgiVars[] = {
    "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE",
    "HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET", "HTTP_ACCEPT_ENCODING",
    "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION", "HTTP_HOST",
    "HTTP_USER_AGENT", "HTTP_REFERER", "PATH_INFO", "PATH_TRANSLATED",
    "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT", "REQUEST_METHOD",
    "REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_PROTOCOL",
  };

  login_check_credentials();
  if( !g.perm.Admin && !g.perm.Setup && !db_get_boolean("test_env_enable",0) ){
    login_needed();
    return;
  }
  for(i=0; i<count(azCgiVars); i++) (void)P(azCgiVars[i]);
  style_header("Environment Test");
  showAll = atoi(PD("showall","0"));
  if( !showAll ){
    style_submenu_element("Show Cookies", "Show Cookies",
                          "%s/test_env?showall=1", g.zTop);
  }else{
    style_submenu_element("Hide Cookies", "Hide Cookies",
                          "%s/test_env", g.zTop);
  }
#if !defined(_WIN32)
  @ uid=%d(getuid()), gid=%d(getgid())<br />
#endif
  @ g.zBaseURL = %h(g.zBaseURL)<br />
  @ g.zTop = %h(g.zTop)<br />
  for(i=0, c='a'; c<='z'; c++){
    if( login_has_capability(&c, 1) ) zCap[i++] = c;
  }
  zCap[i] = 0;
  @ g.userUid = %d(g.userUid)<br />
  @ g.zLogin = %h(g.zLogin)<br />
  @ g.isHuman = %d(g.isHuman)<br />
  @ capabilities = %s(zCap)<br />
  @ <hr>
  P("HTTP_USER_AGENT");
  cgi_print_all(showAll);
  if( showAll && blob_size(&g.httpHeader)>0 ){
    @ <hr>
    @ <pre>
    @ %h(blob_str(&g.httpHeader))
    @ </pre>
  }
  if( g.perm.Setup ){
    const char *zRedir = P("redirect");
    if( zRedir ) cgi_redirect(zRedir);
  }
  style_footer();
  if( g.perm.Admin && P("err") ) fossil_fatal("%s", P("err"));
}

/*
** This page is a honeypot for spiders and bots.
**
** WEBPAGE: honeypot
*/
void honeypot_page(void){
  cgi_set_status(403, "Forbidden");
  @ <p>Access by spiders and robots is forbidden</p>
}
Changes to src/sync.c.
92
93
94
95
96
97
98






99
100
101
102
103
104
105
  if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
  if( find_option("private",0,0)!=0 ){
    *pSyncFlags |= SYNC_PRIVATE;
  }
  if( find_option("verbose","v",0)!=0 ){
    *pSyncFlags |= SYNC_VERBOSE;
  }






  url_proxy_options();
  db_find_and_open_repository(0, 0);
  db_open_config(0);
  if( g.argc==2 ){
    if( db_get_boolean("auto-shun",1) ) configSync = CONFIGSET_SHUN;
  }else if( g.argc==3 ){
    zUrl = g.argv[2];







>
>
>
>
>
>







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
  if( find_option("private",0,0)!=0 ){
    *pSyncFlags |= SYNC_PRIVATE;
  }
  if( find_option("verbose","v",0)!=0 ){
    *pSyncFlags |= SYNC_VERBOSE;
  }
  /* The --verily option to sync, push, and pull forces extra igot cards
  ** to be exchanged.  This can overcome malfunctions in the sync protocol.
  */
  if( find_option("verily",0,0)!=0 ){
    *pSyncFlags |= SYNC_RESYNC;
  }
  url_proxy_options();
  db_find_and_open_repository(0, 0);
  db_open_config(0);
  if( g.argc==2 ){
    if( db_get_boolean("auto-shun",1) ) configSync = CONFIGSET_SHUN;
  }else if( g.argc==3 ){
    zUrl = g.argv[2];
127
128
129
130
131
132
133


134
135
136
137
138
139
140
** COMMAND: pull
**
** Usage: %fossil pull ?URL? ?options?
**
** Pull changes from a remote repository into the local repository.
** Use the "-R REPO" or "--repository REPO" command-line options
** to specify an alternative repository file.


**
** If the URL is not specified, then the URL from the most recent
** clone, push, pull, remote-url, or sync command is used.
**
** The URL specified normally becomes the new "remote-url" used for
** subsequent push, pull, and sync operations.  However, the "--once"
** command-line option makes the URL a one-time-use URL that is not







>
>







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
** COMMAND: pull
**
** Usage: %fossil pull ?URL? ?options?
**
** Pull changes from a remote repository into the local repository.
** Use the "-R REPO" or "--repository REPO" command-line options
** to specify an alternative repository file.
**
** See clone usage for possible URL formats.
**
** If the URL is not specified, then the URL from the most recent
** clone, push, pull, remote-url, or sync command is used.
**
** The URL specified normally becomes the new "remote-url" used for
** subsequent push, pull, and sync operations.  However, the "--once"
** command-line option makes the URL a one-time-use URL that is not
156
157
158
159
160
161
162


163
164
165
166
167
168
169
** COMMAND: push
**
** Usage: %fossil push ?URL? ?options?
**
** Push changes in the local repository over into a remote repository.
** Use the "-R REPO" or "--repository REPO" command-line options
** to specify an alternative repository file.


**
** If the URL is not specified, then the URL from the most recent
** clone, push, pull, remote-url, or sync command is used.
**
** The URL specified normally becomes the new "remote-url" used for
** subsequent push, pull, and sync operations.  However, the "--once"
** command-line option makes the URL a one-time-use URL that is not







>
>







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
** COMMAND: push
**
** Usage: %fossil push ?URL? ?options?
**
** Push changes in the local repository over into a remote repository.
** Use the "-R REPO" or "--repository REPO" command-line options
** to specify an alternative repository file.
**
** See clone usage for possible URL formats.
**
** If the URL is not specified, then the URL from the most recent
** clone, push, pull, remote-url, or sync command is used.
**
** The URL specified normally becomes the new "remote-url" used for
** subsequent push, pull, and sync operations.  However, the "--once"
** command-line option makes the URL a one-time-use URL that is not
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
** Usage: %fossil sync ?URL? ?options?
**
** Synchronize the local repository with a remote repository.  This is
** the equivalent of running both "push" and "pull" at the same time.
** Use the "-R REPO" or "--repository REPO" command-line options
** to specify an alternative repository file.
**
** If a user-id and password are required, specify them as follows:
**
**     http://userid:password@www.domain.com:1234/path
**
** If the URL is not specified, then the URL from the most recent successful
** clone, push, pull, remote-url, or sync command is used.
**
** The URL specified normally becomes the new "remote-url" used for
** subsequent push, pull, and sync operations.  However, the "--once"
** command-line option makes the URL a one-time-use URL that is not
** saved.
**
** Use the --private option to sync private branches with the







|

<
<
|
|







201
202
203
204
205
206
207
208
209


210
211
212
213
214
215
216
217
218
** Usage: %fossil sync ?URL? ?options?
**
** Synchronize the local repository with a remote repository.  This is
** the equivalent of running both "push" and "pull" at the same time.
** Use the "-R REPO" or "--repository REPO" command-line options
** to specify an alternative repository file.
**
** See clone usage for possible URL formats.
**


** If the URL is not specified, then the URL from the most recent
** successful clone, push, pull, remote-url, or sync command is used.
**
** The URL specified normally becomes the new "remote-url" used for
** subsequent push, pull, and sync operations.  However, the "--once"
** command-line option makes the URL a one-time-use URL that is not
** saved.
**
** Use the --private option to sync private branches with the
231
232
233
234
235
236
237


238
239
240
241
242
243
244
** Query and/or change the default server URL used by the "pull", "push",
** and "sync" commands.
**
** The remote-url is set automatically by a "clone" command or by any
** "sync", "push", or "pull" command that specifies an explicit URL.
** The default remote-url is used by auto-syncing and by "sync", "push",
** "pull" that omit the server URL.


**
** See also: clone, push, pull, sync
*/
void remote_url_cmd(void){
  char *zUrl;
  db_find_and_open_repository(0, 0);
  if( g.argc!=2 && g.argc!=3 ){







>
>







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
** Query and/or change the default server URL used by the "pull", "push",
** and "sync" commands.
**
** The remote-url is set automatically by a "clone" command or by any
** "sync", "push", or "pull" command that specifies an explicit URL.
** The default remote-url is used by auto-syncing and by "sync", "push",
** "pull" that omit the server URL.
**
** See clone usage for possible URL formats.
**
** See also: clone, push, pull, sync
*/
void remote_url_cmd(void){
  char *zUrl;
  db_find_and_open_repository(0, 0);
  if( g.argc!=2 && g.argc!=3 ){
Changes to src/tag.c.
346
347
348
349
350
351
352
353
354
355
356

357
358
359
360
361
362
363
**         the tag value propagates to all descendants of CHECK-IN
**
**     %fossil tag cancel ?--raw? TAGNAME CHECK-IN
**
**         Remove the tag TAGNAME from CHECK-IN, and also remove
**         the propagation of the tag to any descendants.
**
**     %fossil tag find ?--raw? ?-t|--type TYPE? TAGNAME
**
**         List all objects that use TAGNAME.  TYPE can be "ci" for
**         checkins or "e" for events.

**
**     %fossil tag list ?--raw? ?CHECK-IN?
**
**         List all tags, or if CHECK-IN is supplied, list
**         all tags and their values for CHECK-IN.
**
** The option --raw allows the manipulation of all types of tags







|


|
>







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
**         the tag value propagates to all descendants of CHECK-IN
**
**     %fossil tag cancel ?--raw? TAGNAME CHECK-IN
**
**         Remove the tag TAGNAME from CHECK-IN, and also remove
**         the propagation of the tag to any descendants.
**
**     %fossil tag find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME
**
**         List all objects that use TAGNAME.  TYPE can be "ci" for
**         checkins or "e" for events. The limit option limits the number
**         of results to the given value.
**
**     %fossil tag list ?--raw? ?CHECK-IN?
**
**         List all tags, or if CHECK-IN is supplied, list
**         all tags and their values for CHECK-IN.
**
** The option --raw allows the manipulation of all types of tags
385
386
387
388
389
390
391


392
393
394
395
396
397
398
** in order to import history from other scm systems
*/
void tag_cmd(void){
  int n;
  int fRaw = find_option("raw","",0)!=0;
  int fPropagate = find_option("propagate","",0)!=0;
  const char *zPrefix = fRaw ? "" : "sym-";



  db_find_and_open_repository(0, 0);
  if( g.argc<3 ){
    goto tag_cmd_usage;
  }
  n = strlen(g.argv[2]);
  if( n==0 ){







>
>







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
** in order to import history from other scm systems
*/
void tag_cmd(void){
  int n;
  int fRaw = find_option("raw","",0)!=0;
  int fPropagate = find_option("propagate","",0)!=0;
  const char *zPrefix = fRaw ? "" : "sym-";
  char const * zFindLimit = find_option("limit","n",1);
  int const nFindLimit = zFindLimit ? atoi(zFindLimit) : 0;

  db_find_and_open_repository(0, 0);
  if( g.argc<3 ){
    goto tag_cmd_usage;
  }
  n = strlen(g.argv[2]);
  if( n==0 ){
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441
442
443
444





445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462





463
464
465
466
467
468
469
    tag_add_artifact(zPrefix, g.argv[3], g.argv[4], 0, 0, 0, 0);
    db_end_transaction(0);
  }else

  if( strncmp(g.argv[2],"find",n)==0 ){
    Stmt q;
    const char *zType = find_option("type","t",1);

    if( zType==0 || zType[0]==0 ) zType = "*";
    if( g.argc!=4 ){
      usage("find ?--raw? ?-t|--type TYPE? TAGNAME");
    }
    if( fRaw ){
      db_prepare(&q,
        "SELECT blob.uuid FROM tagxref, blob"
        " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
        "   AND tagxref.tagtype>0"
        "   AND blob.rid=tagxref.rid",
        g.argv[3]
      );





      while( db_step(&q)==SQLITE_ROW ){
        fossil_print("%s\n", db_column_text(&q, 0));
      }
      db_finalize(&q);
    }else{
      int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
                         g.argv[3]);
      if( tagid>0 ){
        db_prepare(&q,
          "%s"
          "  AND event.type GLOB '%q'"
          "  AND blob.rid IN ("
                    " SELECT rid FROM tagxref"
                    "  WHERE tagtype>0 AND tagid=%d"
                    ")"
          " ORDER BY event.mtime DESC",
          timeline_query_for_tty(), zType, tagid
        );





        print_timeline(&q, 2000, 0);
        db_finalize(&q);
      }
    }
  }else

  if( strncmp(g.argv[2],"list",n)==0 ){







>


|


|






>
>
>
>
>








|









>
>
>
>
>







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
    tag_add_artifact(zPrefix, g.argv[3], g.argv[4], 0, 0, 0, 0);
    db_end_transaction(0);
  }else

  if( strncmp(g.argv[2],"find",n)==0 ){
    Stmt q;
    const char *zType = find_option("type","t",1);
    Blob sql = empty_blob;
    if( zType==0 || zType[0]==0 ) zType = "*";
    if( g.argc!=4 ){
      usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
    }
    if( fRaw ){
      blob_appendf(&sql,
        "SELECT blob.uuid FROM tagxref, blob"
        " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
        "   AND tagxref.tagtype>0"
        "   AND blob.rid=tagxref.rid",
        g.argv[3]
      );
      if(nFindLimit>0){
        blob_appendf(&sql, " LIMIT %d", nFindLimit);
      }
      db_prepare(&q, "%s", blob_str(&sql));
      blob_reset(&sql);
      while( db_step(&q)==SQLITE_ROW ){
        fossil_print("%s\n", db_column_text(&q, 0));
      }
      db_finalize(&q);
    }else{
      int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
                         g.argv[3]);
      if( tagid>0 ){
        blob_appendf(&sql,
          "%s"
          "  AND event.type GLOB '%q'"
          "  AND blob.rid IN ("
                    " SELECT rid FROM tagxref"
                    "  WHERE tagtype>0 AND tagid=%d"
                    ")"
          " ORDER BY event.mtime DESC",
          timeline_query_for_tty(), zType, tagid
        );
        if(nFindLimit>0){
          blob_appendf(&sql, " LIMIT %d", nFindLimit);
        }
        db_prepare(&q, "%s", blob_str(&sql));
        blob_reset(&sql);
        print_timeline(&q, 2000, 0);
        db_finalize(&q);
      }
    }
  }else

  if( strncmp(g.argv[2],"list",n)==0 ){
Changes to src/th.c.
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
  {"-",  OP_SUBTRACT,       3, ARG_NUMBER},
  {"<",  OP_LT,             5, ARG_NUMBER},
  {">",  OP_GT,             5, ARG_NUMBER},
  {"&",  OP_BITWISE_AND,    8, ARG_INTEGER},
  {"^",  OP_BITWISE_XOR,    9, ARG_INTEGER},
  {"|",  OP_BITWISE_OR,    10, ARG_INTEGER},

  {0,0,0}
};

/*
** The first part of the string (zInput,nInput) contains a number.
** Set *pnVarname to the number of bytes in the numeric string. 
*/
static int thNextNumber(







|







1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
  {"-",  OP_SUBTRACT,       3, ARG_NUMBER},
  {"<",  OP_LT,             5, ARG_NUMBER},
  {">",  OP_GT,             5, ARG_NUMBER},
  {"&",  OP_BITWISE_AND,    8, ARG_INTEGER},
  {"^",  OP_BITWISE_XOR,    9, ARG_INTEGER},
  {"|",  OP_BITWISE_OR,    10, ARG_INTEGER},

  {0,0,0,0}
};

/*
** The first part of the string (zInput,nInput) contains a number.
** Set *pnVarname to the number of bytes in the numeric string. 
*/
static int thNextNumber(
Changes to src/th_main.c.
428
429
430
431
432
433
434
435
436


437
438
439
440
441
442
443
    char **azElem;
    int i;

    if( Th_ToInt(interp, argv[3], argl[3], &height) ) return TH_ERROR;
    Th_SplitList(interp, argv[2], argl[2], &azElem, &aszElem, &nElem);
    blob_init(&name, (char*)argv[1], argl[1]);
    zValue = Th_Fetch(blob_str(&name), &nValue);
    z = mprintf("<select name=\"%z\" size=\"%d\">", 
                 htmlize(blob_buffer(&name), blob_size(&name)), height);


    sendText(z, -1, 0);
    free(z);
    blob_reset(&name);
    for(i=0; i<nElem; i++){
      zH = htmlize((char*)azElem[i], aszElem[i]);
      if( zValue && aszElem[i]==nValue 
             && memcmp(zValue, azElem[i], nValue)==0 ){







<
|
>
>







428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
    char **azElem;
    int i;

    if( Th_ToInt(interp, argv[3], argl[3], &height) ) return TH_ERROR;
    Th_SplitList(interp, argv[2], argl[2], &azElem, &aszElem, &nElem);
    blob_init(&name, (char*)argv[1], argl[1]);
    zValue = Th_Fetch(blob_str(&name), &nValue);

    zH = htmlize(blob_buffer(&name), blob_size(&name));
    z = mprintf("<select id=\"%s\" name=\"%s\" size=\"%d\">", zH, zH, height);
    free(zH);
    sendText(z, -1, 0);
    free(z);
    blob_reset(&name);
    for(i=0; i<nElem; i++){
      zH = htmlize((char*)azElem[i], aszElem[i]);
      if( zValue && aszElem[i]==nValue 
             && memcmp(zValue, azElem[i], nValue)==0 ){
Changes to src/timeline.c.
243
244
245
246
247
248
249

250



251
252
253
254
255
256
257
  char zPrevDate[20];
  GraphContext *pGraph = 0;
  int prevWasDivider = 0;     /* True if previous output row was <hr> */
  int fchngQueryInit = 0;     /* True if fchngQuery is initialized */
  Stmt fchngQuery;            /* Query for file changes on check-ins */
  static Stmt qbranch;
  int pendingEndTr = 0;       /* True if a </td></tr> is needed */





  zPrevDate[0] = 0;
  mxWikiLen = db_get_int("timeline-max-comment", 0);
  if( tmFlags & TIMELINE_GRAPH ){
    pGraph = graph_init();
    /* style is not moved to css, because this is
    ** a technical div for the timeline graph
    */







>
|
>
>
>







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
  char zPrevDate[20];
  GraphContext *pGraph = 0;
  int prevWasDivider = 0;     /* True if previous output row was <hr> */
  int fchngQueryInit = 0;     /* True if fchngQuery is initialized */
  Stmt fchngQuery;            /* Query for file changes on check-ins */
  static Stmt qbranch;
  int pendingEndTr = 0;       /* True if a </td></tr> is needed */
  int vid = 0;                /* Current checkout version */
  
  if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
    vid = db_lget_int("checkout", 0);
  }
  zPrevDate[0] = 0;
  mxWikiLen = db_get_int("timeline-max-comment", 0);
  if( tmFlags & TIMELINE_GRAPH ){
    pGraph = graph_init();
    /* style is not moved to css, because this is
    ** a technical div for the timeline graph
    */
316
317
318
319
320
321
322



323

324
325
326
327
328
329
330
      sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
      @ <tr><td>
      @   <div class="divider">%s(zPrevDate)</div>
      @ </td><td></td><td></td></tr>
    }
    memcpy(zTime, &zDate[11], 5);
    zTime[5] = 0;



    @ <tr>

    @ <td class="timelineTime">%s(zTime)</td>
    @ <td class="timelineGraph">
    if( tmFlags & TIMELINE_UCOLOR )  zBgClr = zUser ? hash_color(zUser) : 0;
    if( zType[0]=='c'
    && (pGraph || zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0)
    ){
      db_reset(&qbranch);







>
>
>
|
>







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
      sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
      @ <tr><td>
      @   <div class="divider">%s(zPrevDate)</div>
      @ </td><td></td><td></td></tr>
    }
    memcpy(zTime, &zDate[11], 5);
    zTime[5] = 0;
    if( rid == vid ){
      @ <tr class="timelineCurrent">
    }else {
      @ <tr>
    }
    @ <td class="timelineTime">%s(zTime)</td>
    @ <td class="timelineGraph">
    if( tmFlags & TIMELINE_UCOLOR )  zBgClr = zUser ? hash_color(zUser) : 0;
    if( zType[0]=='c'
    && (pGraph || zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0)
    ){
      db_reset(&qbranch);
639
640
641
642
643
644
645





646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
      }
      if( cSep=='[' ) cgi_printf("[");
      cgi_printf("],h:\"%s\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "];\n");
    }
    cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
    graph_free(pGraph);
    @ var canvasDiv = gebi("canvas");





    @ function drawBox(color,x0,y0,x1,y1){
    @   var n = document.createElement("div");
    @   if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
    @   if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
    @   var w = x1-x0+1;
    @   var h = y1-y0+1;
    @   n.style.position = "absolute";
    @   n.style.overflow = "hidden";
    @   n.style.left = x0+"px";
    @   n.style.top = y0+"px";
    @   n.style.width = w+"px";
    @   n.style.height = h+"px";
    @   n.style.backgroundColor = color;
    @   n.style.cursor = "pointer";
    @   canvasDiv.appendChild(n);
    @   return n;
    @ }
    @ function absoluteY(id){
    @   var obj = gebi(id);
    @   if( !obj ) return;
    @   var top = 0;







>
>
>
>
>













<







647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671

672
673
674
675
676
677
678
      }
      if( cSep=='[' ) cgi_printf("[");
      cgi_printf("],h:\"%s\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "];\n");
    }
    cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
    graph_free(pGraph);
    @ var canvasDiv = gebi("canvas");
    @ var canvasStyle = window.getComputedStyle && window.getComputedStyle(canvasDiv,null);
    @ var lineColor = (canvasStyle && canvasStyle.getPropertyValue('color')) || 'black';
    @ var bgColor = (canvasStyle && canvasStyle.getPropertyValue('background-color')) || 'white';
    @ if( bgColor=='transparent' ) bgColor = 'white';
    @ var boxColor = lineColor;
    @ function drawBox(color,x0,y0,x1,y1){
    @   var n = document.createElement("div");
    @   if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
    @   if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
    @   var w = x1-x0+1;
    @   var h = y1-y0+1;
    @   n.style.position = "absolute";
    @   n.style.overflow = "hidden";
    @   n.style.left = x0+"px";
    @   n.style.top = y0+"px";
    @   n.style.width = w+"px";
    @   n.style.height = h+"px";
    @   n.style.backgroundColor = color;

    @   canvasDiv.appendChild(n);
    @   return n;
    @ }
    @ function absoluteY(id){
    @   var obj = gebi(id);
    @   if( !obj ) return;
    @   var top = 0;
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708



709
710
711
712
713
714
715
716
717
718
719
720
    @     do{
    @       left += obj.offsetLeft;
    @     }while( obj = obj.offsetParent );
    @   }
    @   return left;
    @ }
    @ function drawUpArrow(x,y0,y1){
    @   drawBox("black",x,y0,x+1,y1);
    @   if( y0+10>=y1 ){
    @     drawBox("black",x-1,y0+1,x+2,y0+2);
    @     drawBox("black",x-2,y0+3,x+3,y0+4);
    @   }else{
    @     drawBox("black",x-1,y0+2,x+2,y0+4);
    @     drawBox("black",x-2,y0+5,x+3,y0+7);
    @   }
    @ }
    @ function drawThinArrow(y,xFrom,xTo){
    @   if( xFrom<xTo ){
    @     drawBox("black",xFrom,y,xTo,y);
    @     drawBox("black",xTo-3,y-1,xTo-2,y+1);
    @     drawBox("black",xTo-4,y-2,xTo-4,y+2);
    @   }else{
    @     drawBox("black",xTo,y,xFrom,y);
    @     drawBox("black",xTo+2,y-1,xTo+3,y+1);
    @     drawBox("black",xTo+4,y-2,xTo+4,y+2);
    @   }
    @ }
    @ function drawThinLine(x0,y0,x1,y1){
    @   drawBox("black",x0,y0,x1,y1);
    @ }



    @ function drawNode(p, left, btm){
    @   drawBox("black",p.x-5,p.y-5,p.x+6,p.y+6);
    @   drawBox(p.bg,p.x-4,p.y-4,p.x+5,p.y+5);
    @   if( p.u>0 ) drawUpArrow(p.x, rowinfo[p.u-1].y+6, p.y-5);
    @   if( p.f&1 ) drawBox("black",p.x-1,p.y-1,p.x+2,p.y+2);
    if( !omitDescenders ){
      @   if( p.u==0 ) drawUpArrow(p.x, 0, p.y-5);
      @   if( p.d ) drawUpArrow(p.x, p.y+6, btm);
    }
    @   if( p.mo>0 ){
    @     var x1 = p.mo + left - 1;
    @     var y1 = p.y-3;







|

|
|

|
|




|
|
|

|
|
|



|

>
>
>

|
|

|







691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
    @     do{
    @       left += obj.offsetLeft;
    @     }while( obj = obj.offsetParent );
    @   }
    @   return left;
    @ }
    @ function drawUpArrow(x,y0,y1){
    @   drawBox(lineColor,x,y0,x+1,y1);
    @   if( y0+10>=y1 ){
    @     drawBox(lineColor,x-1,y0+1,x+2,y0+2);
    @     drawBox(lineColor,x-2,y0+3,x+3,y0+4);
    @   }else{
    @     drawBox(lineColor,x-1,y0+2,x+2,y0+4);
    @     drawBox(lineColor,x-2,y0+5,x+3,y0+7);
    @   }
    @ }
    @ function drawThinArrow(y,xFrom,xTo){
    @   if( xFrom<xTo ){
    @     drawBox(lineColor,xFrom,y,xTo,y);
    @     drawBox(lineColor,xTo-3,y-1,xTo-2,y+1);
    @     drawBox(lineColor,xTo-4,y-2,xTo-4,y+2);
    @   }else{
    @     drawBox(lineColor,xTo,y,xFrom,y);
    @     drawBox(lineColor,xTo+2,y-1,xTo+3,y+1);
    @     drawBox(lineColor,xTo+4,y-2,xTo+4,y+2);
    @   }
    @ }
    @ function drawThinLine(x0,y0,x1,y1){
    @   drawBox(lineColor,x0,y0,x1,y1);
    @ }
    @ function drawNodeBox(color,x0,y0,x1,y1){
    @   drawBox(color,x0,y0,x1,y1).style.cursor = "pointer";
    @ }
    @ function drawNode(p, left, btm){
    @   drawNodeBox(boxColor,p.x-5,p.y-5,p.x+6,p.y+6);
    @   drawNodeBox(p.bg||bgColor,p.x-4,p.y-4,p.x+5,p.y+5);
    @   if( p.u>0 ) drawUpArrow(p.x, rowinfo[p.u-1].y+6, p.y-5);
    @   if( p.f&1 ) drawNodeBox(boxColor,p.x-1,p.y-1,p.x+2,p.y+2);
    if( !omitDescenders ){
      @   if( p.u==0 ) drawUpArrow(p.x, 0, p.y-5);
      @   if( p.d ) drawUpArrow(p.x, p.y+6, btm);
    }
    @   if( p.mo>0 ){
    @     var x1 = p.mo + left - 1;
    @     var y1 = p.y-3;
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
    @   }
    @   var n = p.au.length;
    @   for(var i=0; i<n; i+=2){
    @     var x1 = p.au[i]*railPitch + left;
    @     var x0 = x1>p.x ? p.x+7 : p.x-6;
    @     var u = rowinfo[p.au[i+1]-1];
    @     if(u.id<p.id){
    @       drawBox("black",x0,p.y,x1,p.y+1);
    @       drawUpArrow(x1, u.y+6, p.y);
    @     }else{
    @       drawBox("#600000",x0,p.y,x1,p.y+1);
    @       drawBox("#600000",x1-1,p.y,x1,u.y+1);
    @       drawBox("#600000",x1,u.y,u.x-6,u.y+1);
    @       drawBox("#600000",u.x-9,u.y-1,u.x-8,u.y+2);
    @       drawBox("#600000",u.x-11,u.y-2,u.x-10,u.y+3);







|







745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
    @   }
    @   var n = p.au.length;
    @   for(var i=0; i<n; i+=2){
    @     var x1 = p.au[i]*railPitch + left;
    @     var x0 = x1>p.x ? p.x+7 : p.x-6;
    @     var u = rowinfo[p.au[i+1]-1];
    @     if(u.id<p.id){
    @       drawBox(lineColor,x0,p.y,x1,p.y+1);
    @       drawUpArrow(x1, u.y+6, p.y);
    @     }else{
    @       drawBox("#600000",x0,p.y,x1,p.y+1);
    @       drawBox("#600000",x1-1,p.y,x1,u.y+1);
    @       drawBox("#600000",x1,u.y,u.x-6,u.y+1);
    @       drawBox("#600000",u.x-9,u.y-1,u.x-8,u.y+2);
    @       drawBox("#600000",u.x-11,u.y-2,u.x-10,u.y+3);
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896


1897
1898
1899
1900
1901
1902
1903
}

/*
** Helper for stats_report_by_month_year(), which generates a list of
** week numbers. zTimeframe should be either a timeframe in the form YYYY
** or YYYY-MM.
*/
static void stats_report_output_week_links(char const * zTimeframe){
  Stmt stWeek = empty_Stmt;
  char yearPart[5] = {0,0,0,0,0};
  memcpy(yearPart, zTimeframe, 4);
  db_prepare(&stWeek,
             "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
             "count(*) AS n, "
             "substr(date(mtime),1,%d) AS ym "
             "FROM event "
             "WHERE ym=%Q AND mtime < current_timestamp "
             "GROUP BY wk ORDER BY wk",
             strlen(zTimeframe),
             zTimeframe);
  while( SQLITE_ROW == db_step(&stWeek) ){
    char const * zWeek = db_column_text(&stWeek,0);
    int const nCount = db_column_int(&stWeek,1);
    cgi_printf("<a href='%s/timeline?"
               "yw=%t-%t&n=%d'>%s</a>",
               g.zTop, yearPart, zWeek,
               nCount, zWeek);
  }
  db_finalize(&stWeek);
}

/*
** Implements the "byyear" and "bymonth" reports for /stats_report.
** If includeMonth is true then it generates the "bymonth" report,
** else the "byyear" report. If zUserName is not NULL and not empty
** then the report is restricted to events created by the named user
** account.
*/
static void stats_report_by_month_year(char includeMonth,
                                       char includeWeeks,
                                       char const * zUserName){
  Stmt query = empty_Stmt;
  int const nPixelsPerEvent = 1;     /* for sizing the "graph" part */
  int nRowNumber = 0;                /* current TR number */
  int nEventTotal = 0;               /* Total event count */
  int rowClass = 0;                  /* counter for alternating
                                        row colors */
  Blob sql = empty_blob;             /* SQL */
  char const * zTimeLabel = includeMonth ? "Year/Month" : "Year";
  char zPrevYear[5] = {0};           /* For keeping track of when
                                        we change years while looping */
  int nEventsPerYear = 0;            /* Total event count for the
                                        current year */
  char showYearTotal = 0;            /* Flag telling us when to show
                                        the per-year event totals */
  Blob header = empty_blob;          /* Page header text */
  int nMaxEvents  = 1;            /* for calculating length of graph bars. */



  blob_appendf(&header, "Timeline Events by year%s",
               (includeMonth ? "/month" : ""));
  blob_appendf(&sql,
               "SELECT substr(date(mtime),1,%d) AS timeframe, "
               "count(*) AS eventCount "
               "FROM event ",
               includeMonth ? 7 : 4);







|













|
|









|







|

<





|







|
|
>
>







1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895

1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
}

/*
** Helper for stats_report_by_month_year(), which generates a list of
** week numbers. zTimeframe should be either a timeframe in the form YYYY
** or YYYY-MM.
*/
static void stats_report_output_week_links(const char * zTimeframe){
  Stmt stWeek = empty_Stmt;
  char yearPart[5] = {0,0,0,0,0};
  memcpy(yearPart, zTimeframe, 4);
  db_prepare(&stWeek,
             "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
             "count(*) AS n, "
             "substr(date(mtime),1,%d) AS ym "
             "FROM event "
             "WHERE ym=%Q AND mtime < current_timestamp "
             "GROUP BY wk ORDER BY wk",
             strlen(zTimeframe),
             zTimeframe);
  while( SQLITE_ROW == db_step(&stWeek) ){
    const char * zWeek = db_column_text(&stWeek,0);
    const int nCount = db_column_int(&stWeek,1);
    cgi_printf("<a href='%s/timeline?"
               "yw=%t-%t&n=%d'>%s</a>",
               g.zTop, yearPart, zWeek,
               nCount, zWeek);
  }
  db_finalize(&stWeek);
}

/*
** Implements the "byyear" and "bymonth" reports for /reports.
** If includeMonth is true then it generates the "bymonth" report,
** else the "byyear" report. If zUserName is not NULL and not empty
** then the report is restricted to events created by the named user
** account.
*/
static void stats_report_by_month_year(char includeMonth,
                                       char includeWeeks,
                                       const char * zUserName){
  Stmt query = empty_Stmt;

  int nRowNumber = 0;                /* current TR number */
  int nEventTotal = 0;               /* Total event count */
  int rowClass = 0;                  /* counter for alternating
                                        row colors */
  Blob sql = empty_blob;             /* SQL */
  const char * zTimeLabel = includeMonth ? "Year/Month" : "Year";
  char zPrevYear[5] = {0};           /* For keeping track of when
                                        we change years while looping */
  int nEventsPerYear = 0;            /* Total event count for the
                                        current year */
  char showYearTotal = 0;            /* Flag telling us when to show
                                        the per-year event totals */
  Blob header = empty_blob;          /* Page header text */
  int nMaxEvents  = 1;               /* for calculating length of graph
                                        bars. */
  int iterations = 0;                /* number of weeks/months we iterate
                                        over */
  blob_appendf(&header, "Timeline Events by year%s",
               (includeMonth ? "/month" : ""));
  blob_appendf(&sql,
               "SELECT substr(date(mtime),1,%d) AS timeframe, "
               "count(*) AS eventCount "
               "FROM event ",
               includeMonth ? 7 : 4);
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932

1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
  blob_reset(&header);
  /*
     Run the query twice. The first time we calculate the maximum
     number of events for a given row. Maybe someone with better SQL
     Fu can re-implement this with a single query.
  */
  while( SQLITE_ROW == db_step(&query) ){
    int const nCount = db_column_int(&query, 1);
    if(nCount>nMaxEvents){
      nMaxEvents = nCount;
    }

  }
  db_reset(&query);
  while( SQLITE_ROW == db_step(&query) ){
    char const * zTimeframe = db_column_text(&query, 0);
    int const nCount = db_column_int(&query, 1);
    int const nSize = nCount
      ? (int)(100 * nCount / nMaxEvents)
      : 1;
    showYearTotal = 0;
    if(includeMonth){
      /* For Month/year view, add a separator for each distinct year. */
      if(!*zPrevYear ||
         (0!=fossil_strncmp(zPrevYear,zTimeframe,4))){







|



>



|
|
|







1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
  blob_reset(&header);
  /*
     Run the query twice. The first time we calculate the maximum
     number of events for a given row. Maybe someone with better SQL
     Fu can re-implement this with a single query.
  */
  while( SQLITE_ROW == db_step(&query) ){
    const int nCount = db_column_int(&query, 1);
    if(nCount>nMaxEvents){
      nMaxEvents = nCount;
    }
    ++iterations;
  }
  db_reset(&query);
  while( SQLITE_ROW == db_step(&query) ){
    const char * zTimeframe = db_column_text(&query, 0);
    const int nCount = db_column_int(&query, 1);
    const int nSize = nCount
      ? (int)(100 * nCount / nMaxEvents)
      : 1;
    showYearTotal = 0;
    if(includeMonth){
      /* For Month/year view, add a separator for each distinct year. */
      if(!*zPrevYear ||
         (0!=fossil_strncmp(zPrevYear,zTimeframe,4))){
2011
2012
2013
2014
2015
2016
2017


2018


2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
    @ <tr class='row%d(rowClass)'>
    @ <td></td>
    @ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td>
    @</tr>    
  }
  @ </tbody></table>
  if(nEventTotal){


    @ <br><div>Total events: %d(nEventTotal)</div>


  }
  if( !includeMonth ){
    output_table_sorting_javascript("statsTable","tnx");
  }
}

/*
** Implements the "byuser" view for /stats_report.
*/
static void stats_report_by_user(){
  Stmt query = empty_Stmt;
  int const nPixelsPerEvent = 1;     /* for sizing the "graph" part */
  int nRowNumber = 0;                /* current TR number */
  int nEventTotal = 0;               /* Total event count */
  int rowClass = 0;                  /* counter for alternating
                                        row colors */
  Blob sql = empty_blob;             /* SQL */
  int nMaxEvents = 1;                /* max number of events for
                                        all rows. */







>
>
|
>
>







|



<







2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050

2051
2052
2053
2054
2055
2056
2057
    @ <tr class='row%d(rowClass)'>
    @ <td></td>
    @ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td>
    @</tr>    
  }
  @ </tbody></table>
  if(nEventTotal){
    char const * zAvgLabel = includeMonth ? "month" : "year";
    int nAvg = iterations ? (nEventTotal/iterations) : 0;
    @ <br><div>Total events: %d(nEventTotal)
    @ <br>Average per active %s(zAvgLabel): %d(nAvg)
    @ </div>
  }
  if( !includeMonth ){
    output_table_sorting_javascript("statsTable","tnx");
  }
}

/*
** Implements the "byuser" view for /reports.
*/
static void stats_report_by_user(){
  Stmt query = empty_Stmt;

  int nRowNumber = 0;                /* current TR number */
  int nEventTotal = 0;               /* Total event count */
  int rowClass = 0;                  /* counter for alternating
                                        row colors */
  Blob sql = empty_blob;             /* SQL */
  int nMaxEvents = 1;                /* max number of events for
                                        all rows. */
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
  @ cellpadding='2' cellspacing='0' id='statsTable'>
  @ <thead><tr>
  @ <th>User</th>
  @ <th>Events</th>
  @ <th width='90%%'><!-- relative commits graph --></th>
  @ </tr></thead><tbody>
  while( SQLITE_ROW == db_step(&query) ){
    int const nCount = db_column_int(&query, 1);
    if(nCount>nMaxEvents){
      nMaxEvents = nCount;
    }
  }
  db_reset(&query);
  while( SQLITE_ROW == db_step(&query) ){
    char const * zUser = db_column_text(&query, 0);
    int const nCount = db_column_int(&query, 1);
    int const nSize = nCount
      ? (int)(100 * nCount / nMaxEvents)
      : 0;
    if(!nCount) continue /* arguable! Possible? */;
    rowClass = ++nRowNumber % 2;
    nEventTotal += nCount;
    @<tr class='row%d(rowClass)'>
    @ <td>
    @ <a href="?view=bymonth&user=%h(zUser)" target="_new">%h(zUser)</a>
    @ </td><td>%d(nCount)</td>
    @ <td>
    @ <div class='statistics-report-graph-line'
    @  style='height:16px;width:%d(nSize)%%;'>
    @ </div></td>
    @</tr>
    /*







|






|
|
|







|







2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
  @ cellpadding='2' cellspacing='0' id='statsTable'>
  @ <thead><tr>
  @ <th>User</th>
  @ <th>Events</th>
  @ <th width='90%%'><!-- relative commits graph --></th>
  @ </tr></thead><tbody>
  while( SQLITE_ROW == db_step(&query) ){
    const int nCount = db_column_int(&query, 1);
    if(nCount>nMaxEvents){
      nMaxEvents = nCount;
    }
  }
  db_reset(&query);
  while( SQLITE_ROW == db_step(&query) ){
    const char * zUser = db_column_text(&query, 0);
    const int nCount = db_column_int(&query, 1);
    const int nSize = nCount
      ? (int)(100 * nCount / nMaxEvents)
      : 0;
    if(!nCount) continue /* arguable! Possible? */;
    rowClass = ++nRowNumber % 2;
    nEventTotal += nCount;
    @<tr class='row%d(rowClass)'>
    @ <td>
    @ <a href="?view=bymonth&user=%h(zUser)">%h(zUser)</a>
    @ </td><td>%d(nCount)</td>
    @ <td>
    @ <div class='statistics-report-graph-line'
    @  style='height:16px;width:%d(nSize)%%;'>
    @ </div></td>
    @</tr>
    /*
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103

2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141


/*
** Helper for stats_report_by_month_year(), which generates a list of
** week numbers. zTimeframe should be either a timeframe in the form YYYY
** or YYYY-MM.
*/
static void stats_report_year_weeks(char const * zUserName){
  char const * zYear = P("y");
  int nYear = zYear ? strlen(zYear) : 0;
  int i = 0;
  Stmt qYears = empty_Stmt;
  char * zDefaultYear = NULL;
  Blob sql = empty_blob;
  int nMaxEvents = 1;                /* max number of events for
                                        all rows. */


  cgi_printf("Select year: ");
  blob_append(&sql,
              "SELECT DISTINCT substr(date(mtime),1,4) AS y "
              "FROM event WHERE 1 ", -1);
  if(zUserName&&*zUserName){
    blob_appendf(&sql,"AND user=%Q ", zUserName);
  }
  blob_append(&sql,"GROUP BY y ORDER BY y", -1);
  db_prepare(&qYears, blob_str(&sql));
  blob_reset(&sql);
  while( SQLITE_ROW == db_step(&qYears) ){
    char const * zT = db_column_text(&qYears, 0);
    if( i++ ){
      cgi_printf(" ");
    }
    cgi_printf("<a href='?view=byweek&y=%s", zT);
    if(zUserName && *zUserName){
      cgi_printf("&user=%t",zUserName);
    }
    cgi_printf("'>%s</a>",zT);
  }
  db_finalize(&qYears);
  cgi_printf("<br/>");
  if(!zYear || !*zYear){
    zDefaultYear = db_text("????", "SELECT strftime('%%Y')");
    zYear = zDefaultYear;
    nYear = 4;
  }
  if(4 == nYear){
    int const nPixelsPerEvent = 3;     /* for sizing the "graph" part */
    Stmt stWeek = empty_Stmt;
    int rowCount = 0;
    int total = 0;
    Blob header = empty_blob;
    blob_appendf(&header, "Timeline events for the calendar weeks "
                 "of %h", zYear);
    blob_appendf(&sql,







|
|







>












|

















<







2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154

2155
2156
2157
2158
2159
2160
2161


/*
** Helper for stats_report_by_month_year(), which generates a list of
** week numbers. zTimeframe should be either a timeframe in the form YYYY
** or YYYY-MM.
*/
static void stats_report_year_weeks(const char * zUserName){
  const char * zYear = P("y");
  int nYear = zYear ? strlen(zYear) : 0;
  int i = 0;
  Stmt qYears = empty_Stmt;
  char * zDefaultYear = NULL;
  Blob sql = empty_blob;
  int nMaxEvents = 1;                /* max number of events for
                                        all rows. */
  int iterations = 0;                /* # of active time periods. */

  cgi_printf("Select year: ");
  blob_append(&sql,
              "SELECT DISTINCT substr(date(mtime),1,4) AS y "
              "FROM event WHERE 1 ", -1);
  if(zUserName&&*zUserName){
    blob_appendf(&sql,"AND user=%Q ", zUserName);
  }
  blob_append(&sql,"GROUP BY y ORDER BY y", -1);
  db_prepare(&qYears, blob_str(&sql));
  blob_reset(&sql);
  while( SQLITE_ROW == db_step(&qYears) ){
    const char * zT = db_column_text(&qYears, 0);
    if( i++ ){
      cgi_printf(" ");
    }
    cgi_printf("<a href='?view=byweek&y=%s", zT);
    if(zUserName && *zUserName){
      cgi_printf("&user=%t",zUserName);
    }
    cgi_printf("'>%s</a>",zT);
  }
  db_finalize(&qYears);
  cgi_printf("<br/>");
  if(!zYear || !*zYear){
    zDefaultYear = db_text("????", "SELECT strftime('%%Y')");
    zYear = zDefaultYear;
    nYear = 4;
  }
  if(4 == nYear){

    Stmt stWeek = empty_Stmt;
    int rowCount = 0;
    int total = 0;
    Blob header = empty_blob;
    blob_appendf(&header, "Timeline events for the calendar weeks "
                 "of %h", zYear);
    blob_appendf(&sql,
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170

2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
               "<th>Events</th>"
               "<th width='90%%'><!-- relative commits graph --></th>"
               "</tr></thead>"
               "<tbody>");
    db_prepare(&stWeek, blob_str(&sql));
    blob_reset(&sql);
    while( SQLITE_ROW == db_step(&stWeek) ){
      int const nCount = db_column_int(&stWeek, 1);
      if(nCount>nMaxEvents){
        nMaxEvents = nCount;
      }

    }
    db_reset(&stWeek);
    while( SQLITE_ROW == db_step(&stWeek) ){
      char const * zWeek = db_column_text(&stWeek,0);
      int const nCount = db_column_int(&stWeek,1);
      int const nSize = nCount
        ? (int)(100 * nCount / nMaxEvents)
        : 0;
      total += nCount;
      cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
      cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d",
                 g.zTop, zYear, zWeek, nCount);
      if(zUserName && *zUserName){







|



>



|
|
|







2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
               "<th>Events</th>"
               "<th width='90%%'><!-- relative commits graph --></th>"
               "</tr></thead>"
               "<tbody>");
    db_prepare(&stWeek, blob_str(&sql));
    blob_reset(&sql);
    while( SQLITE_ROW == db_step(&stWeek) ){
      const int nCount = db_column_int(&stWeek, 1);
      if(nCount>nMaxEvents){
        nMaxEvents = nCount;
      }
      ++iterations;
    }
    db_reset(&stWeek);
    while( SQLITE_ROW == db_step(&stWeek) ){
      const char * zWeek = db_column_text(&stWeek,0);
      const int nCount = db_column_int(&stWeek,1);
      const int nSize = nCount
        ? (int)(100 * nCount / nMaxEvents)
        : 0;
      total += nCount;
      cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
      cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d",
                 g.zTop, zYear, zWeek, nCount);
      if(zUserName && *zUserName){
2194
2195
2196
2197
2198
2199
2200

2201

2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
      }
      cgi_printf("</td></tr>");
    }
    db_finalize(&stWeek);
    free(zDefaultYear);
    cgi_printf("</tbody></table>");
    if(total){

      cgi_printf("<br><div>Total events: %d</div>",

                 total);
    }
    output_table_sorting_javascript("statsTable","tnx");
  }
}

/*
** WEBPAGE: stats_report
**
** Shows activity reports for the repository.
**
** Query Parameters:
**
**   view=REPORT_NAME  Valid values: bymonth, byyear, byuser
**   user=NAME         Restricts statistics to the given user
*/
void stats_report_page(){
  HQuery url;                        /* URL for various branch links */
  char const * zView = P("view");    /* Which view/report to show. */
  char const *zUserName = P("user");
  if(!zUserName) zUserName = P("u");
  url_initialize(&url, "stats_report");

  if(zUserName && *zUserName){
    url_add_parameter(&url,"user", zUserName);
    timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user");
  }
  timeline_submenu(&url, "By Year", "view", "byyear", 0);
  timeline_submenu(&url, "By Month", "view", "bymonth", 0);







>
|
>
|






|










|
|

|







2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
      }
      cgi_printf("</td></tr>");
    }
    db_finalize(&stWeek);
    free(zDefaultYear);
    cgi_printf("</tbody></table>");
    if(total){
      int nAvg = iterations ? (total/iterations) : 0;
      cgi_printf("<br><div>Total events: %d<br>"
                 "Average per active week: %d</div>",
                 total, nAvg);
    }
    output_table_sorting_javascript("statsTable","tnx");
  }
}

/*
** WEBPAGE: reports
**
** Shows activity reports for the repository.
**
** Query Parameters:
**
**   view=REPORT_NAME  Valid values: bymonth, byyear, byuser
**   user=NAME         Restricts statistics to the given user
*/
void stats_report_page(){
  HQuery url;                        /* URL for various branch links */
  const char * zView = P("view");    /* Which view/report to show. */
  const char *zUserName = P("user");
  if(!zUserName) zUserName = P("u");
  url_initialize(&url, "reports");

  if(zUserName && *zUserName){
    url_add_parameter(&url,"user", zUserName);
    timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user");
  }
  timeline_submenu(&url, "By Year", "view", "byyear", 0);
  timeline_submenu(&url, "By Month", "view", "bymonth", 0);
Changes to src/tkt.c.
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
static void ticket_put(
  Blob *pTicket,           /* The text of the ticket change record */
  const char *zTktId,      /* The ticket to which this change is applied */
  int needMod              /* True if moderation is needed */
){
  int rid = content_put_ex(pTicket, 0, 0, 0, needMod);
  if( rid==0 ){
    fossil_panic("trouble committing ticket: %s", g.zErrMsg);
  }
  if( needMod ){
    moderation_table_create();
    db_multi_exec(
      "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
      rid, zTktId
    );







|







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
static void ticket_put(
  Blob *pTicket,           /* The text of the ticket change record */
  const char *zTktId,      /* The ticket to which this change is applied */
  int needMod              /* True if moderation is needed */
){
  int rid = content_put_ex(pTicket, 0, 0, 0, needMod);
  if( rid==0 ){
    fossil_fatal("trouble committing ticket: %s", g.zErrMsg);
  }
  if( needMod ){
    moderation_table_create();
    db_multi_exec(
      "INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
      rid, zTktId
    );
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
  Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
                   (void*)&zNewUuid, 0);
  if( g.thTrace ) Th_Trace("BEGIN_TKTNEW_SCRIPT<br />\n", -1);
  if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zNewUuid ){
    cgi_redirect(mprintf("%s/tktview/%s", g.zTop, zNewUuid));
    return;
  }
  captcha_generate();
  @ </form>
  if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
  style_footer();
}

/*
** WEBPAGE: tktedit







|







674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
  Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
                   (void*)&zNewUuid, 0);
  if( g.thTrace ) Th_Trace("BEGIN_TKTNEW_SCRIPT<br />\n", -1);
  if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zNewUuid ){
    cgi_redirect(mprintf("%s/tktview/%s", g.zTop, zNewUuid));
    return;
  }
  captcha_generate(0);
  @ </form>
  if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
  style_footer();
}

/*
** WEBPAGE: tktedit
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
  Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
  Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT_SCRIPT<br />\n", -1);
  if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zName ){
    cgi_redirect(mprintf("%s/tktview/%s", g.zTop, zName));
    return;
  }
  captcha_generate();
  @ </form>
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
  style_footer();
}

/*
** Check the ticket table schema in zSchema to see if it appears to







|







742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
  Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
  Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT_SCRIPT<br />\n", -1);
  if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zName ){
    cgi_redirect(mprintf("%s/tktview/%s", g.zTop, zName));
    return;
  }
  captcha_generate(0);
  @ </form>
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
  style_footer();
}

/*
** Check the ticket table schema in zSchema to see if it appears to
Changes to src/unicode.c.
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  ** The most significant 22 bits in each 32-bit value contain the first 
  ** codepoint in the range. The least significant 10 bits are used to store
  ** the size of the range (always at least 1). In other words, the value 
  ** ((C<<22) + N) represents a range of N codepoints starting with codepoint 
  ** C. It is not possible to represent a range larger than 1023 codepoints 
  ** using this format.
  */
  const static unsigned int aEntry[] = {
    0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
    0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
    0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
    0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
    0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
    0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
    0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  ** The most significant 22 bits in each 32-bit value contain the first 
  ** codepoint in the range. The least significant 10 bits are used to store
  ** the size of the range (always at least 1). In other words, the value 
  ** ((C<<22) + N) represents a range of N codepoints starting with codepoint 
  ** C. It is not possible to represent a range larger than 1023 codepoints 
  ** using this format.
  */
  static const unsigned int aEntry[] = {
    0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
    0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
    0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
    0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
    0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
    0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
    0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,
Changes to src/update.c.
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
    tid = db_int(0, "SELECT rid FROM leaves, event"
                    " WHERE event.objid=leaves.rid"
                    " ORDER BY event.mtime DESC"); 
    if( tid==0 ) tid = vid;
  }

  if( tid==0 ){
    fossil_panic("Internal Error: unable to find a version to update to.");
  }

  db_begin_transaction();
  vfile_check_signature(vid, CKSIG_ENOTFILE);
  if( !dryRunFlag && !internalUpdate ) undo_begin();
  load_vfile_from_rid(tid);








|







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
    tid = db_int(0, "SELECT rid FROM leaves, event"
                    " WHERE event.objid=leaves.rid"
                    " ORDER BY event.mtime DESC"); 
    if( tid==0 ) tid = vid;
  }

  if( tid==0 ){
    fossil_panic("unable to find a version to update to.");
  }

  db_begin_transaction();
  vfile_check_signature(vid, CKSIG_ENOTFILE);
  if( !dryRunFlag && !internalUpdate ) undo_begin();
  load_vfile_from_rid(tid);

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
    "  idt INTEGER,"              /* VFILE entry for target version */
    "  chnged BOOLEAN,"           /* True if current version has been edited */
    "  islinkv BOOLEAN,"          /* True if current file is a link */
    "  islinkt BOOLEAN,"          /* True if target file is a link */
    "  ridv INTEGER,"             /* Record ID for current version */
    "  ridt INTEGER,"             /* Record ID for target */
    "  isexe BOOLEAN,"            /* Does target have execute permission? */
    "  deleted BOOLEAN DEFAULT 0,"/* File marke by "rm" to become unmanaged */
    "  fnt TEXT %s"               /* Filename of same file on target version */
    ");",
    filename_collation(), filename_collation()
  );

  /* Add files found in the current version
  */







|







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
    "  idt INTEGER,"              /* VFILE entry for target version */
    "  chnged BOOLEAN,"           /* True if current version has been edited */
    "  islinkv BOOLEAN,"          /* True if current file is a link */
    "  islinkt BOOLEAN,"          /* True if target file is a link */
    "  ridv INTEGER,"             /* Record ID for current version */
    "  ridt INTEGER,"             /* Record ID for target */
    "  isexe BOOLEAN,"            /* Does target have execute permission? */
    "  deleted BOOLEAN DEFAULT 0,"/* File marked by "rm" to become unmanaged */
    "  fnt TEXT %s"               /* Filename of same file on target version */
    ");",
    filename_collation(), filename_collation()
  );

  /* Add files found in the current version
  */
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
      }
      undo_save(zName);
      if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
    }else if( idt>0 && idv>0 && ridt!=ridv && (chnged==0 || deleted) ){
      /* The file is unedited.  Change it to the target version */
      undo_save(zName);
      if( deleted ){
        fossil_print("UPDATE %s - change to unmanged file\n", zName);
      }else{
        fossil_print("UPDATE %s\n", zName);
      }
      if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
    }else if( idt>0 && idv>0 && file_wd_size(zFullPath)<0 ){
      /* The file missing from the local check-out. Restore it to the
      ** version that appears in the target. */
      fossil_print("UPDATE %s%s\n", zName,
                    deleted?" - change to unmanaged file":"");
      undo_save(zName);
      if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
    }else if( idt==0 && idv>0 ){
      if( ridv==0 ){
        /* Added in current checkout.  Continue to hold the file as
        ** as an addition */
        db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv);







|




|


|
<







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
      }
      undo_save(zName);
      if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
    }else if( idt>0 && idv>0 && ridt!=ridv && (chnged==0 || deleted) ){
      /* The file is unedited.  Change it to the target version */
      undo_save(zName);
      if( deleted ){
        fossil_print("UPDATE %s - change to unmanaged file\n", zName);
      }else{
        fossil_print("UPDATE %s\n", zName);
      }
      if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
    }else if( idt>0 && idv>0 && !deleted && file_wd_size(zFullPath)<0 ){
      /* The file missing from the local check-out. Restore it to the
      ** version that appears in the target. */
      fossil_print("UPDATE %s\n", zName);

      undo_save(zName);
      if( !dryRunFlag ) vfile_to_disk(0, idt, 0, 0);
    }else if( idt==0 && idv>0 ){
      if( ridv==0 ){
        /* Added in current checkout.  Continue to hold the file as
        ** as an addition */
        db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv);
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
    if( errCode<=0 ){
      fossil_fatal("file %s does not exist in checkin: %s", file, revision);
    }
  }else if( errCode<=0 ){
    if( revision==0 ){
      revision = db_text("current", "SELECT uuid FROM blob WHERE rid=%d", rid);
    }
    fossil_panic("could not parse manifest for checkin: %s", revision);
  }
  return errCode;
}


/*
** COMMAND: revert







|







656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
    if( errCode<=0 ){
      fossil_fatal("file %s does not exist in checkin: %s", file, revision);
    }
  }else if( errCode<=0 ){
    if( revision==0 ){
      revision = db_text("current", "SELECT uuid FROM blob WHERE rid=%d", rid);
    }
    fossil_fatal("could not parse manifest for checkin: %s", revision);
  }
  return errCode;
}


/*
** COMMAND: revert
Changes to src/user.c.
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
      db_multi_exec(
        "UPDATE user SET cap=%Q, mtime=now() WHERE uid=%d",
        g.argv[4], uid
      );
    }
    fossil_print("%s\n", db_text(0, "SELECT cap FROM user WHERE uid=%d", uid));
  }else{
    fossil_panic("user subcommand should be one of: "
                 "capabilities default list new password");
  }
}

/*
** Attempt to set the user to zLogin
*/







|







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
      db_multi_exec(
        "UPDATE user SET cap=%Q, mtime=now() WHERE uid=%d",
        g.argv[4], uid
      );
    }
    fossil_print("%s\n", db_text(0, "SELECT cap FROM user WHERE uid=%d", uid));
  }else{
    fossil_fatal("user subcommand should be one of: "
                 "capabilities default list new password");
  }
}

/*
** Attempt to set the user to zLogin
*/
Changes to src/util.c.
24
25
26
27
28
29
30



31
32
33
34
35
36
37
** For the fossil_timer_xxx() family of functions...
*/
#ifdef _WIN32
# include <windows.h>
#else
# include <sys/time.h>
# include <sys/resource.h>



#endif


/*
** Exit.  Take care to close the database first.
*/
NORETURN void fossil_exit(int rc){







>
>
>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
** For the fossil_timer_xxx() family of functions...
*/
#ifdef _WIN32
# include <windows.h>
#else
# include <sys/time.h>
# include <sys/resource.h>
# include <unistd.h>
# include <fcntl.h>
# include <errno.h>
#endif


/*
** Exit.  Take care to close the database first.
*/
NORETURN void fossil_exit(int rc){
297
298
299
300
301
302
303












    return 0;
  }else{
    int const rc = fossilTimerList[timerId-1].id;
    assert(!rc || (rc == timerId));
    return fossilTimerList[timerId-1].id;
  }
}



















>
>
>
>
>
>
>
>
>
>
>
>
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
    return 0;
  }else{
    int const rc = fossilTimerList[timerId-1].id;
    assert(!rc || (rc == timerId));
    return fossilTimerList[timerId-1].id;
  }
}

/*
** Return TRUE if fd is a valid open file descriptor.  This only
** works on unix.  The function always returns true on Windows.
*/
int is_valid_fd(int fd){
#ifdef _WIN32
  return 1;
#else
  return fcntl(fd, F_GETFL)!=(-1) || errno!=EBADF;
#endif
}
Changes to src/verify.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  Blob uuid, hash, content;
  if( content_size(rid, 0)<0 ){
    return;  /* No way to verify phantoms */
  }
  blob_zero(&uuid);
  db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d", rid);
  if( blob_size(&uuid)!=UUID_SIZE ){
    fossil_panic("not a valid rid: %d", rid);
  }
  if( content_get(rid, &content) ){
    sha1sum_blob(&content, &hash);
    blob_reset(&content);
    if( blob_compare(&uuid, &hash) ){
      fossil_fatal("hash of rid %d (%b) does not match its uuid (%b)",
                    rid, &hash, &uuid);







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  Blob uuid, hash, content;
  if( content_size(rid, 0)<0 ){
    return;  /* No way to verify phantoms */
  }
  blob_zero(&uuid);
  db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d", rid);
  if( blob_size(&uuid)!=UUID_SIZE ){
    fossil_fatal("not a valid rid: %d", rid);
  }
  if( content_get(rid, &content) ){
    sha1sum_blob(&content, &hash);
    blob_reset(&content);
    if( blob_compare(&uuid, &hash) ){
      fossil_fatal("hash of rid %d (%b) does not match its uuid (%b)",
                    rid, &hash, &uuid);
Changes to src/vfile.c.
80
81
82
83
84
85
86
87
88


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

  if( db_exists("SELECT 1 FROM vfile WHERE vid=%d", vid) ){
    return;
  }

  db_begin_transaction();
  p = manifest_get(vid, CFTYPE_MANIFEST);
  if( p==0 ) return;
  db_multi_exec("DELETE FROM vfile WHERE vid=%d", vid);


  db_prepare(&ins,
    "INSERT INTO vfile(vid,isexe,islink,rid,mrid,pathname) "
    " VALUES(:vid,:isexe,:islink,:id,:id,:name)");
  db_prepare(&ridq, "SELECT rid,size FROM blob WHERE uuid=:uuid");
  db_bind_int(&ins, ":vid", vid);
  manifest_file_rewind(p);
  while( (pFile = manifest_file_next(p,0))!=0 ){
    if( pFile->zUuid==0 || uuid_is_shunned(pFile->zUuid) ) continue;
    db_bind_text(&ridq, ":uuid", pFile->zUuid);
    if( db_step(&ridq)==SQLITE_ROW ){
      rid = db_column_int(&ridq, 0);
      size = db_column_int(&ridq, 0);
    }else{
      rid = 0;
      size = 0;
    }
    db_reset(&ridq);
    if( rid==0 || size<0 ){
      fossil_warning("content missing for %s", pFile->zName);







|
|
>
>











|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

  if( db_exists("SELECT 1 FROM vfile WHERE vid=%d", vid) ){
    return;
  }

  db_begin_transaction();
  p = manifest_get(vid, CFTYPE_MANIFEST);
  if( p==0 ) {
    db_end_transaction(1);
    return;
  }
  db_prepare(&ins,
    "INSERT INTO vfile(vid,isexe,islink,rid,mrid,pathname) "
    " VALUES(:vid,:isexe,:islink,:id,:id,:name)");
  db_prepare(&ridq, "SELECT rid,size FROM blob WHERE uuid=:uuid");
  db_bind_int(&ins, ":vid", vid);
  manifest_file_rewind(p);
  while( (pFile = manifest_file_next(p,0))!=0 ){
    if( pFile->zUuid==0 || uuid_is_shunned(pFile->zUuid) ) continue;
    db_bind_text(&ridq, ":uuid", pFile->zUuid);
    if( db_step(&ridq)==SQLITE_ROW ){
      rid = db_column_int(&ridq, 0);
      size = db_column_int(&ridq, 1);
    }else{
      rid = 0;
      size = 0;
    }
    db_reset(&ridq);
    if( rid==0 || size<0 ){
      fossil_warning("content missing for %s", pFile->zName);
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
      db_ephemeral_blob(&q, 5, &origCksum);
      if( sha1sum_file(zName, &fileCksum) ){
        blob_zero(&fileCksum);
      }
      if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
      blob_reset(&origCksum);
      blob_reset(&fileCksum);
    }else if( (chnged==0 || chnged==2)
           && (useMtime==0 || currentMtime!=oldMtime) ){
      /* For files that were formerly believed to be unchanged or that were
      ** changed by merging, if their mtime changes, or unconditionally
      ** if --sha1sum is used, check to see if they have been edited by
      ** looking at their SHA1 sum */
      assert( origSize==currentSize );
      db_ephemeral_blob(&q, 5, &origCksum);
      if( sha1sum_file(zName, &fileCksum) ){
        blob_zero(&fileCksum);
      }
      if( blob_compare(&fileCksum, &origCksum) ){
        chnged = 1;
      }
      blob_reset(&origCksum);
      blob_reset(&fileCksum);
    }
    if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2) ){
      i64 desiredMtime;
      if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){
        if( currentMtime!=desiredMtime ){
          file_set_mtime(zName, desiredMtime);
          currentMtime = file_wd_mtime(zName);
        }
      }







|
















|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
      db_ephemeral_blob(&q, 5, &origCksum);
      if( sha1sum_file(zName, &fileCksum) ){
        blob_zero(&fileCksum);
      }
      if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
      blob_reset(&origCksum);
      blob_reset(&fileCksum);
    }else if( (chnged==0 || chnged==2 || chnged==4)
           && (useMtime==0 || currentMtime!=oldMtime) ){
      /* For files that were formerly believed to be unchanged or that were
      ** changed by merging, if their mtime changes, or unconditionally
      ** if --sha1sum is used, check to see if they have been edited by
      ** looking at their SHA1 sum */
      assert( origSize==currentSize );
      db_ephemeral_blob(&q, 5, &origCksum);
      if( sha1sum_file(zName, &fileCksum) ){
        blob_zero(&fileCksum);
      }
      if( blob_compare(&fileCksum, &origCksum) ){
        chnged = 1;
      }
      blob_reset(&origCksum);
      blob_reset(&fileCksum);
    }
    if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2 || chnged==4) ){
      i64 desiredMtime;
      if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){
        if( currentMtime!=desiredMtime ){
          file_set_mtime(zName, desiredMtime);
          currentMtime = file_wd_mtime(zName);
        }
      }
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
  blob_zero(pOut);
  if( pManOut ){
    blob_zero(pManOut);
  }
  db_must_be_within_tree();
  pManifest = manifest_get(vid, CFTYPE_MANIFEST);
  if( pManifest==0 ){
    fossil_panic("manifest file (%d) is malformed", vid);
  }
  manifest_file_rewind(pManifest);
  while( (pFile = manifest_file_next(pManifest,0))!=0 ){
    if( pFile->zUuid==0 ) continue;
    fid = uuid_to_rid(pFile->zUuid, 0);
    md5sum_step_text(pFile->zName, -1);
    content_get(fid, &file);







|







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
  blob_zero(pOut);
  if( pManOut ){
    blob_zero(pManOut);
  }
  db_must_be_within_tree();
  pManifest = manifest_get(vid, CFTYPE_MANIFEST);
  if( pManifest==0 ){
    fossil_fatal("manifest file (%d) is malformed", vid);
  }
  manifest_file_rewind(pManifest);
  while( (pFile = manifest_file_next(pManifest,0))!=0 ){
    if( pFile->zUuid==0 ) continue;
    fid = uuid_to_rid(pFile->zUuid, 0);
    md5sum_step_text(pFile->zName, -1);
    content_get(fid, &file);
Changes to src/wiki.c.
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  }
  if( !g.perm.RdWiki ){
    cgi_redirectf("%s/login?g=%s/home", g.zTop, g.zTop);
  }
  if( zPageName ){
    login_check_credentials();
    g.zExtra = zPageName;
    cgi_set_parameter_nocopy("name", g.zExtra);
    g.isHome = 1;
    wiki_page();
    return;
  }
  style_header("Home");
  @ <p>This is a stub home-page for the project.
  @ To fill in this page, first go to







|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  }
  if( !g.perm.RdWiki ){
    cgi_redirectf("%s/login?g=%s/home", g.zTop, g.zTop);
  }
  if( zPageName ){
    login_check_credentials();
    g.zExtra = zPageName;
    cgi_set_parameter_nocopy("name", g.zExtra, 1);
    g.isHome = 1;
    wiki_page();
    return;
  }
  style_header("Home");
  @ <p>This is a stub home-page for the project.
  @ To fill in this page, first go to
176
177
178
179
180
181
182






183
184
185
186
187
188
189
190
191
192
193

  login_check_credentials();
  if( !g.perm.RdWiki ){ login_needed(); return; }
  zPageName = P("name");
  if( zPageName==0 ){
    style_header("Wiki");
    @ <ul>






    { char *zHomePageName = db_get("project-name",0);
      if( zHomePageName ){
        @ <li> %z(href("%R/wiki?name=%t",zHomePageName))
        @      %h(zHomePageName)</a> wiki home page.</li>
      }
    }
    @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li>
    @ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li>
    @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a>
    @      to experiment.</li>
    if( g.perm.NewWiki ){







>
>
>
>
>
>



|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

  login_check_credentials();
  if( !g.perm.RdWiki ){ login_needed(); return; }
  zPageName = P("name");
  if( zPageName==0 ){
    style_header("Wiki");
    @ <ul>
    { char *zWikiHomePageName = db_get("index-page",0);
      if( zWikiHomePageName ){
        @ <li> %z(href("%R%s",zWikiHomePageName))
        @      %h(zWikiHomePageName)</a> wiki home page.</li>
      }
    }
    { char *zHomePageName = db_get("project-name",0);
      if( zHomePageName ){
        @ <li> %z(href("%R/wiki?name=%t",zHomePageName))
        @      %h(zHomePageName)</a> project home page.</li>
      }
    }
    @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li>
    @ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li>
    @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a>
    @      to experiment.</li>
    if( g.perm.NewWiki ){
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
  }
  login_insert_csrf_secret();
  @ <input type="submit" name="submit" value="Apply These Changes" />
  @ <input type="hidden" name="name" value="%h(zPageName)" />
  @ <input type="submit" name="cancel" value="Cancel"
  @  onclick='confirm("Abandon your changes?")' />
  @ </div>
  captcha_generate();
  @ </form>
  manifest_destroy(pWiki);
  blob_reset(&wiki);
  style_footer();
}

/*







|







491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
  }
  login_insert_csrf_secret();
  @ <input type="submit" name="submit" value="Apply These Changes" />
  @ <input type="hidden" name="name" value="%h(zPageName)" />
  @ <input type="submit" name="cancel" value="Cancel"
  @  onclick='confirm("Abandon your changes?")' />
  @ </div>
  captcha_generate(0);
  @ </form>
  manifest_destroy(pWiki);
  blob_reset(&wiki);
  style_footer();
}

/*
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
  @ Comment to append (formatted as %s(zFormat)):<br />
  @ <textarea name="r" class="wikiedit" cols="80" 
  @  rows="10" wrap="virtual">%h(PD("r",""))</textarea>
  @ <br />
  @ <input type="submit" name="preview" value="Preview Your Comment" />
  @ <input type="submit" name="submit" value="Append Your Changes" />
  @ <input type="submit" name="cancel" value="Cancel" />
  captcha_generate();
  @ </form>
  style_footer();
}

/*
** Name of the wiki history page being generated
*/







|







694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
  @ Comment to append (formatted as %s(zFormat)):<br />
  @ <textarea name="r" class="wikiedit" cols="80" 
  @  rows="10" wrap="virtual">%h(PD("r",""))</textarea>
  @ <br />
  @ <input type="submit" name="preview" value="Preview Your Comment" />
  @ <input type="submit" name="submit" value="Append Your Changes" />
  @ <input type="submit" name="cancel" value="Cancel" />
  captcha_generate(0);
  @ </form>
  style_footer();
}

/*
** Name of the wiki history page being generated
*/
Changes to src/winhttp.c.
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  }
  return 0;
}

/*
** Process a single incoming HTTP request.
*/
static void win32_process_one_http_request(void *pAppData){
  HttpRequest *p = (HttpRequest*)pAppData;
  FILE *in = 0, *out = 0;
  int amt, got;
  int wanted = 0;
  char *z;
  char zRequestFName[MAX_PATH];
  char zReplyFName[MAX_PATH];







|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  }
  return 0;
}

/*
** Process a single incoming HTTP request.
*/
static void win32_http_request(void *pAppData){
  HttpRequest *p = (HttpRequest*)pAppData;
  FILE *in = 0, *out = 0;
  int amt, got;
  int wanted = 0;
  char *z;
  char zRequestFName[MAX_PATH];
  char zReplyFName[MAX_PATH];
126
127
128
129
130
131
132






























































133
134
135
136
137
138
139
  if( out ) fclose(out);
  if( in ) fclose(in);
  closesocket(p->s);
  file_delete(zRequestFName);
  file_delete(zReplyFName);
  free(p);
}































































/*
** Start a listening socket and process incoming HTTP requests on
** that socket.
*/
void win32_http_server(
  int mnPort, int mxPort,   /* Range of allowed TCP port numbers */







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







126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  if( out ) fclose(out);
  if( in ) fclose(in);
  closesocket(p->s);
  file_delete(zRequestFName);
  file_delete(zReplyFName);
  free(p);
}

/*
** Process a single incoming SCGI request.
*/
static void win32_scgi_request(void *pAppData){
  HttpRequest *p = (HttpRequest*)pAppData;
  FILE *in = 0, *out = 0;
  int amt, got, nHdr, i;
  int wanted = 0;
  char zRequestFName[MAX_PATH];
  char zReplyFName[MAX_PATH];
  char zCmd[2000];          /* Command-line to process the request */
  char zHdr[2000];          /* The SCGI request header */

  sqlite3_snprintf(MAX_PATH, zRequestFName,
                   "%s_in%d.txt", zTempPrefix, p->id);
  sqlite3_snprintf(MAX_PATH, zReplyFName,
                   "%s_out%d.txt", zTempPrefix, p->id);
  out = fossil_fopen(zRequestFName, "wb");
  if( out==0 ) goto end_request;
  amt = 0;
  got = recv(p->s, zHdr, sizeof(zHdr), 0);
  if( got==SOCKET_ERROR ) goto end_request;
  amt = fwrite(zHdr, 1, got, out);
  nHdr = 0;
  for(i=0; zHdr[i]>='0' && zHdr[i]<='9'; i++){
    nHdr = 10*nHdr + zHdr[i] - '0';
  }
  wanted = nHdr + i + 1;
  if( strcmp(zHdr+i+1, "CONTENT_LENGTH")==0 ){
    wanted += atoi(zHdr+i+15);
  }
  while( wanted>amt ){
    got = recv(p->s, zHdr, wanted<sizeof(zHdr) ? wanted : sizeof(zHdr), 0);
    if( got<=0 ) break;
    fwrite(zHdr, 1, got, out);
    wanted += got;
  }
  fclose(out);
  out = 0;
  sqlite3_snprintf(sizeof(zCmd), zCmd,
    "\"%s\" http \"%s\" %s %s %s --scgi --nossl%s",
    g.nameOfExe, g.zRepositoryName, zRequestFName, zReplyFName,
    inet_ntoa(p->addr.sin_addr), p->zOptions
  );
  fossil_system(zCmd);
  in = fossil_fopen(zReplyFName, "rb");
  if( in ){
    while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
      send(p->s, zHdr, got, 0);
    }
  }

end_request:
  if( out ) fclose(out);
  if( in ) fclose(in);
  closesocket(p->s);
  file_delete(zRequestFName);
  file_delete(zReplyFName);
  free(p);
}


/*
** Start a listening socket and process incoming HTTP requests on
** that socket.
*/
void win32_http_server(
  int mnPort, int mxPort,   /* Range of allowed TCP port numbers */
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
    }
  }
  if( !GetTempPathW(MAX_PATH, zTmpPath) ){
    fossil_fatal("unable to get path to the temporary directory.");
  }
  zTempPrefix = mprintf("%sfossil_server_P%d_",
                        fossil_unicode_to_utf8(zTmpPath), iPort);
  fossil_print("Listening for HTTP requests on TCP port %d\n", iPort);

  if( zBrowser ){
    zBrowser = mprintf(zBrowser, iPort);
    fossil_print("Launch webbrowser: %s\n", zBrowser);
    fossil_system(zBrowser);
  }
  fossil_print("Type Ctrl-C to stop the HTTP server\n");
  /* Set the service status to running and pass the listener socket to the







|
>







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
    }
  }
  if( !GetTempPathW(MAX_PATH, zTmpPath) ){
    fossil_fatal("unable to get path to the temporary directory.");
  }
  zTempPrefix = mprintf("%sfossil_server_P%d_",
                        fossil_unicode_to_utf8(zTmpPath), iPort);
  fossil_print("Listening for %s requests on TCP port %d\n",
               (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
  if( zBrowser ){
    zBrowser = mprintf(zBrowser, iPort);
    fossil_print("Launch webbrowser: %s\n", zBrowser);
    fossil_system(zBrowser);
  }
  fossil_print("Type Ctrl-C to stop the HTTP server\n");
  /* Set the service status to running and pass the listener socket to the
242
243
244
245
246
247
248



249

250
251
252
253
254
255
256
      break;
    }
    p = fossil_malloc( sizeof(*p) );
    p->id = ++idCnt;
    p->s = client;
    p->addr = client_addr;
    p->zOptions = blob_str(&options);



    _beginthread(win32_process_one_http_request, 0, (void*)p);

  }
  closesocket(s);
  WSACleanup();
}

/*
** The HttpService structure is used to pass information to the service main







>
>
>
|
>







305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
      break;
    }
    p = fossil_malloc( sizeof(*p) );
    p->id = ++idCnt;
    p->s = client;
    p->addr = client_addr;
    p->zOptions = blob_str(&options);
    if( flags & HTTP_SERVER_SCGI ){
      _beginthread(win32_scgi_request, 0, (void*)p);
    }else{
      _beginthread(win32_http_request, 0, (void*)p);
    }
  }
  closesocket(s);
  WSACleanup();
}

/*
** The HttpService structure is used to pass information to the service main
537
538
539
540
541
542
543




544
545
546
547
548
549
550
**
**         --localauth
**
**              Enables automatic login if the --localauth option is present
**              and the "localauth" setting is off and the connection is from
**              localhost.
**




**
**    fossil winsrv delete ?SERVICE-NAME?
**
**         Deletes a service. If the service is currently running, it will be
**         stopped first and then deleted.
**
**







>
>
>
>







604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
**
**         --localauth
**
**              Enables automatic login if the --localauth option is present
**              and the "localauth" setting is off and the connection is from
**              localhost.
**
**         --scgi
**
**              Create an SCGI server instead of an HTTP server
**
**
**    fossil winsrv delete ?SERVICE-NAME?
**
**         Deletes a service. If the service is currently running, it will be
**         stopped first and then deleted.
**
**
590
591
592
593
594
595
596

597
598
599
600
601
602
603
    const char *zUsername   = find_option("username", "U", 1);
    const char *zPassword   = find_option("password", "W", 1);
    const char *zPort       = find_option("port", "P", 1);
    const char *zNotFound   = find_option("notfound", 0, 1);
    const char *zFileGlob   = find_option("files", 0, 1);
    const char *zLocalAuth  = find_option("localauth", 0, 0);
    const char *zRepository = find_option("repository", "R", 1);

    Blob binPath;

    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("to much arguments for create method.");







>







661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
    const char *zUsername   = find_option("username", "U", 1);
    const char *zPassword   = find_option("password", "W", 1);
    const char *zPort       = find_option("port", "P", 1);
    const char *zNotFound   = find_option("notfound", 0, 1);
    const char *zFileGlob   = find_option("files", 0, 1);
    const char *zLocalAuth  = find_option("localauth", 0, 0);
    const char *zRepository = find_option("repository", "R", 1);
    int useSCGI             = find_option("scgi", 0, 0)!=0;
    Blob binPath;

    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("to much arguments for create method.");
630
631
632
633
634
635
636

637
638
639
640
641
642
643
      db_open_repository(zRepository);
    }
    db_close(0);
    /* Build the fully-qualified path to the service binary file. */
    blob_zero(&binPath);
    blob_appendf(&binPath, "\"%s\" server", g.nameOfExe);
    if( zPort ) blob_appendf(&binPath, " --port %s", zPort);

    if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound);
    if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob);
    if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
    blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
    /* Create the service. */
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());







>







702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
      db_open_repository(zRepository);
    }
    db_close(0);
    /* Build the fully-qualified path to the service binary file. */
    blob_zero(&binPath);
    blob_appendf(&binPath, "\"%s\" server", g.nameOfExe);
    if( zPort ) blob_appendf(&binPath, " --port %s", zPort);
    if( useSCGI ) blob_appendf(&binPath, " --scgi");
    if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound);
    if( zFileGlob ) blob_appendf(&binPath, " --files-urlenc %T", zFileGlob);
    if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
    blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
    /* Create the service. */
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
Changes to src/xfer.c.
44
45
46
47
48
49
50

51
52
53
54
55
56
57
  int nGimmeSent;     /* Number of gimme cards sent */
  int nFileSent;      /* Number of files sent */
  int nDeltaSent;     /* Number of deltas sent */
  int nFileRcvd;      /* Number of files received */
  int nDeltaRcvd;     /* Number of deltas received */
  int nDanglingFile;  /* Number of dangling deltas received */
  int mxSend;         /* Stop sending "file" with pOut reaches this size */

  u8 syncPrivate;     /* True to enable syncing private content */
  u8 nextIsPrivate;   /* If true, next "file" received is a private */
  time_t maxTime;     /* Time when this transfer should be finished */
};


/*







>







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  int nGimmeSent;     /* Number of gimme cards sent */
  int nFileSent;      /* Number of files sent */
  int nDeltaSent;     /* Number of deltas sent */
  int nFileRcvd;      /* Number of files received */
  int nDeltaRcvd;     /* Number of deltas received */
  int nDanglingFile;  /* Number of dangling deltas received */
  int mxSend;         /* Stop sending "file" with pOut reaches this size */
  int resync;         /* Send igot cards for all holdings */
  u8 syncPrivate;     /* True to enable syncing private content */
  u8 nextIsPrivate;   /* If true, next "file" received is a private */
  time_t maxTime;     /* Time when this transfer should be finished */
};


/*
734
735
736
737
738
739
740

741










742
743
744
745
746

747
748
749


750

751

752
753
754
755
756
757
758
/*
** Send an igot message for every entry in unclustered table.
** Return the number of cards sent.
*/
static int send_unclustered(Xfer *pXfer){
  Stmt q;
  int cnt = 0;

  db_prepare(&q, 










    "SELECT uuid FROM unclustered JOIN blob USING(rid)"
    " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
    "   AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
    "   AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
  );

  while( db_step(&q)==SQLITE_ROW ){
    blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0));
    cnt++;


  }

  db_finalize(&q);

  return cnt;
}

/*
** Send an igot message for every artifact.
*/
static void send_all(Xfer *pXfer){







>
|
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
>



>
>
|
>

>







735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
/*
** Send an igot message for every entry in unclustered table.
** Return the number of cards sent.
*/
static int send_unclustered(Xfer *pXfer){
  Stmt q;
  int cnt = 0;
  if( pXfer->resync ){
    db_prepare(&q, 
      "SELECT uuid, rid FROM blob"
      " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
      "   AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
      "   AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
      "   AND blob.rid<=%d"
      " ORDER BY blob.rid DESC",
      pXfer->resync
    );
  }else{
    db_prepare(&q, 
      "SELECT uuid FROM unclustered JOIN blob USING(rid)"
      " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
      "   AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
      "   AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
    );
  }
  while( db_step(&q)==SQLITE_ROW ){
    blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0));
    cnt++;
    if( pXfer->resync && pXfer->mxSend<blob_size(pXfer->pOut) ){
      pXfer->resync = db_column_int(&q, 1)-1;
    }
  }
  db_finalize(&q);
  if( cnt==0 ) pXfer->resync = 0;
  return cnt;
}

/*
** Send an igot message for every artifact.
*/
static void send_all(Xfer *pXfer){
1193
1194
1195
1196
1197
1198
1199







1200
1201
1202
1203
1204
1205
1206
        login_check_credentials();
        if( !g.perm.Private ){
          server_private_xfer_not_authorized();
        }else{
          xfer.syncPrivate = 1;
        }
      }







    }else

    /* Unknown message
    */
    {
      cgi_reset_content();
      @ error bad\scommand:\s%F(blob_str(&xfer.line))







>
>
>
>
>
>
>







1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
        login_check_credentials();
        if( !g.perm.Private ){
          server_private_xfer_not_authorized();
        }else{
          xfer.syncPrivate = 1;
        }
      }
      /*   pragma send-catalog
      **
      ** Send igot cards for all known artifacts.
      */
      if( blob_eq(&xfer.aToken[1], "send-catalog") ){
        xfer.resync = 0x7fffffff;
      }
    }else

    /* Unknown message
    */
    {
      cgi_reset_content();
      @ error bad\scommand:\s%F(blob_str(&xfer.line))
1290
1291
1292
1293
1294
1295
1296

1297
1298
1299
1300
1301
1302
1303
** Flag options for controlling client_sync()
*/
#define SYNC_PUSH      0x0001
#define SYNC_PULL      0x0002
#define SYNC_CLONE     0x0004
#define SYNC_PRIVATE   0x0008
#define SYNC_VERBOSE   0x0010

#endif

/*
** Sync to the host identified in g.urlName and g.urlPath.  This
** routine is called by the client.
**
** Records are pushed to the server if pushFlag is true.  Records







>







1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
** Flag options for controlling client_sync()
*/
#define SYNC_PUSH      0x0001
#define SYNC_PULL      0x0002
#define SYNC_CLONE     0x0004
#define SYNC_PRIVATE   0x0008
#define SYNC_VERBOSE   0x0010
#define SYNC_RESYNC    0x0020
#endif

/*
** Sync to the host identified in g.urlName and g.urlPath.  This
** routine is called by the client.
**
** Records are pushed to the server if pushFlag is true.  Records
1378
1379
1380
1381
1382
1383
1384




1385
1386
1387
1388
1389

1390
1391
1392
1393
1394
1395
1396
    /* TBD: Request all transferable configuration values */
    content_enable_dephantomize(0);
    zOpType = "Clone";
  }else if( syncFlags & SYNC_PULL ){
    blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
    nCardSent++;
    zOpType = (syncFlags & SYNC_PUSH)?"Sync":"Pull";




  }
  if( syncFlags & SYNC_PUSH ){
    blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
    nCardSent++;
    if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";

  }
  manifest_crosslink_begin();
  transport_global_startup();
  if( syncFlags & SYNC_VERBOSE ){
    fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
  }








>
>
>
>





>







1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
    /* TBD: Request all transferable configuration values */
    content_enable_dephantomize(0);
    zOpType = "Clone";
  }else if( syncFlags & SYNC_PULL ){
    blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
    nCardSent++;
    zOpType = (syncFlags & SYNC_PUSH)?"Sync":"Pull";
    if( (syncFlags & SYNC_RESYNC)!=0 && nCycle<2 ){
      blob_appendf(&send, "pragma send-catalog\n");
      nCardSent++;
    }
  }
  if( syncFlags & SYNC_PUSH ){
    blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
    nCardSent++;
    if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
    if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
  }
  manifest_crosslink_begin();
  transport_global_startup();
  if( syncFlags & SYNC_VERBOSE ){
    fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
  }

Changes to test/merge1.test.
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
write_file_indented t23 {
  111 - This is line ONE of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test OF THE merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
  555 - we think it well and other stuff too - 5555
}
fossil test-3 t1 t3 t2 a32
test merge1-1.1 {[same_file t23 a32]}
fossil test-3 t1 t2 t3 a23
test merge1-1.2 {[same_file t23 a23]}

write_file_indented t1 {
  111 - This is line one of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444







|

|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
write_file_indented t23 {
  111 - This is line ONE of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test OF THE merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
  555 - we think it well and other stuff too - 5555
}
fossil 3-way-merge t1 t3 t2 a32
test merge1-1.1 {[same_file t23 a32]}
fossil 3-way-merge t1 t2 t3 a23
test merge1-1.2 {[same_file t23 a23]}

write_file_indented t1 {
  111 - This is line one of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  111 - This is line ONE of the demo program - 1111
  >>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
  555 - we think it well and other stuff too - 5555
}
fossil test-3 t1 t3 t2 a32
test merge1-2.1 {[same_file t32 a32]}
fossil test-3 t1 t2 t3 a23
test merge1-2.2 {[same_file t23 a23]}

write_file_indented t1 {
  111 - This is line one of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444







|

|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  111 - This is line ONE of the demo program - 1111
  >>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
  555 - we think it well and other stuff too - 5555
}
fossil 3-way-merge t1 t3 t2 a32
test merge1-2.1 {[same_file t32 a32]}
fossil 3-way-merge t1 t2 t3 a23
test merge1-2.2 {[same_file t23 a23]}

write_file_indented t1 {
  111 - This is line one of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
write_file_indented t23 {
  111 - This is line ONE of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
  555 - we think it well and other stuff too - 5555
}
fossil test-3 t1 t3 t2 a32
test merge1-3.1 {[same_file t23 a32]}
fossil test-3 t1 t2 t3 a23
test merge1-3.2 {[same_file t23 a23]}

write_file_indented t1 {
  111 - This is line one of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444







|

|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
write_file_indented t23 {
  111 - This is line ONE of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
  555 - we think it well and other stuff too - 5555
}
fossil 3-way-merge t1 t3 t2 a32
test merge1-3.1 {[same_file t23 a32]}
fossil 3-way-merge t1 t2 t3 a23
test merge1-3.2 {[same_file t23 a23]}

write_file_indented t1 {
  111 - This is line one of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  ======= MERGED IN content follows ==================================
  >>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
  555 - we think it well and other stuff too - 5555
}
fossil test-3 t1 t3 t2 a32
test merge1-4.1 {[same_file t32 a32]}
fossil test-3 t1 t2 t3 a23
test merge1-4.2 {[same_file t23 a23]}

write_file_indented t1 {
  111 - This is line one of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444







|

|







179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  ======= MERGED IN content follows ==================================
  >>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
  555 - we think it well and other stuff too - 5555
}
fossil 3-way-merge t1 t3 t2 a32
test merge1-4.1 {[same_file t32 a32]}
fossil 3-way-merge t1 t2 t3 a23
test merge1-4.2 {[same_file t23 a23]}

write_file_indented t1 {
  111 - This is line one of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
write_file_indented t32 {
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
  555 - we think it well and other stuff too - 5555
  666 - Extra line at the end of the file wi - 6666
}
fossil test-3 t1 t3 t2 a32
test merge1-5.1 {[same_file t32 a32]}
fossil test-3 t1 t2 t3 a23
test merge1-5.2 {[same_file t32 a23]}

write_file_indented t1 {
  111 - This is line one of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444







|

|







212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
write_file_indented t32 {
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
  555 - we think it well and other stuff too - 5555
  666 - Extra line at the end of the file wi - 6666
}
fossil 3-way-merge t1 t3 t2 a32
test merge1-5.1 {[same_file t32 a32]}
fossil 3-way-merge t1 t2 t3 a23
test merge1-5.2 {[same_file t32 a23]}

write_file_indented t1 {
  111 - This is line one of the demo program - 1111
  222 - The second line program line in code - 2222
  333 - This is a test of the merging algohm - 3333
  444 - If all goes well, we will be pleased - 4444
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  555 - we think it well and other stuff too - 5555
}
write_file_indented t32 {
  111 - This is line one of the demo program - 1111
  333 - This is a test of the merging algohm - 3333
  555 - we think it well and other stuff too - 5555
}
fossil test-3 t1 t3 t2 a32
test merge1-6.1 {[same_file t32 a32]}
fossil test-3 t1 t2 t3 a23
test merge1-6.2 {[same_file t32 a23]}

write_file_indented t1 {
  abcd
  efgh
  ijkl
  mnop







|

|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  555 - we think it well and other stuff too - 5555
}
write_file_indented t32 {
  111 - This is line one of the demo program - 1111
  333 - This is a test of the merging algohm - 3333
  555 - we think it well and other stuff too - 5555
}
fossil 3-way-merge t1 t3 t2 a32
test merge1-6.1 {[same_file t32 a32]}
fossil 3-way-merge t1 t2 t3 a23
test merge1-6.2 {[same_file t32 a23]}

write_file_indented t1 {
  abcd
  efgh
  ijkl
  mnop
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  GHIJ
  >>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  KLMN
  OPQR
  STUV
  XYZ.
}
fossil test-3 t1 t2 t3 a23
test merge1-7.1 {[same_file t23 a23]}

write_file_indented t2 {
  abcd
  efgh 2
  ijkl 2
  mnop 







|







326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  GHIJ
  >>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  KLMN
  OPQR
  STUV
  XYZ.
}
fossil 3-way-merge t1 t2 t3 a23
test merge1-7.1 {[same_file t23 a23]}

write_file_indented t2 {
  abcd
  efgh 2
  ijkl 2
  mnop 
394
395
396
397
398
399
400
401
402
  GHIJ
  >>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  KLMN
  OPQR
  STUV
  XYZ.
}
fossil test-3 t1 t2 t3 a23
test merge1-7.2 {[same_file t23 a23]}







|

394
395
396
397
398
399
400
401
402
  GHIJ
  >>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  KLMN
  OPQR
  STUV
  XYZ.
}
fossil 3-way-merge t1 t2 t3 a23
test merge1-7.2 {[same_file t23 a23]}
Changes to test/merge2.test.
29
30
31
32
33
34
35
36
37
38
39
40
41
    write_file t2 [set f2 [random_changes $f1 2 4 0 0.1]]
    expr {srand($i*2+1)}
    write_file t3 [set f3 [random_changes $f1 2 4 2 0.1]]
    expr {srand($i*2+1)}
    write_file t23 [random_changes $f2 2 4 2 0.1]
    expr {srand($i*2)}
    write_file t32 [random_changes $f3 2 4 0 0.1]
    fossil test-3-way-merge t1 t2 t3 a23
    test merge-$base-$i-23 {[same_file a23 t23]}
    fossil test-3-way-merge t1 t3 t2 a32
    test merge-$base-$i-32 {[same_file a32 t32]}
  }
}







|

|



29
30
31
32
33
34
35
36
37
38
39
40
41
    write_file t2 [set f2 [random_changes $f1 2 4 0 0.1]]
    expr {srand($i*2+1)}
    write_file t3 [set f3 [random_changes $f1 2 4 2 0.1]]
    expr {srand($i*2+1)}
    write_file t23 [random_changes $f2 2 4 2 0.1]
    expr {srand($i*2)}
    write_file t32 [random_changes $f3 2 4 0 0.1]
    fossil 3-way-merge t1 t2 t3 a23
    test merge-$base-$i-23 {[same_file a23 t23]}
    fossil 3-way-merge t1 t3 t2 a32
    test merge-$base-$i-32 {[same_file a32 t32]}
  }
}
Changes to test/merge3.test.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Tests of the 3-way merge
#

proc merge-test {testid basis v1 v2 result} {
  write_file t1 [join [string trim $basis] \n]\n
  write_file t2 [join [string trim $v1] \n]\n
  write_file t3 [join [string trim $v2] \n]\n
  fossil test-3-way-merge t1 t2 t3 t4
  set x [read_file t4]
  regsub -all {<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <+} $x \
              {MINE:} x
  regsub -all {======= COMMON ANCESTOR content follows =+} $x {COM:} x
  regsub -all {======= MERGED IN content follows =+} $x {YOURS:} x
  regsub -all {>>>>>>> END MERGE CONFLICT >+} $x {END} x
  set x [split [string trim $x] \n]







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Tests of the 3-way merge
#

proc merge-test {testid basis v1 v2 result} {
  write_file t1 [join [string trim $basis] \n]\n
  write_file t2 [join [string trim $v1] \n]\n
  write_file t3 [join [string trim $v2] \n]\n
  fossil 3-way-merge t1 t2 t3 t4
  set x [read_file t4]
  regsub -all {<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <+} $x \
              {MINE:} x
  regsub -all {======= COMMON ANCESTOR content follows =+} $x {COM:} x
  regsub -all {======= MERGED IN content follows =+} $x {YOURS:} x
  regsub -all {>>>>>>> END MERGE CONFLICT >+} $x {END} x
  set x [split [string trim $x] \n]
Changes to test/merge4.test.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Tests of the 3-way merge
#

proc merge-test {testid basis v1 v2 result1 result2} {
  write_file t1 [join [string trim $basis] \n]\n
  write_file t2 [join [string trim $v1] \n]\n
  write_file t3 [join [string trim $v2] \n]\n
  fossil test-3-way-merge t1 t2 t3 t4
  fossil test-3-way-merge t1 t3 t2 t5
  set x [read_file t4]
  regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<<} $x {>} x
  regsub -all {=======.*=======} $x {=} x
  regsub -all {>>>>>>> END MERGE CONFLICT.*>>>>} $x {<} x
  set x [split [string trim $x] \n]
  set y [read_file t5]
  regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<<} $y {>} y







|
|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Tests of the 3-way merge
#

proc merge-test {testid basis v1 v2 result1 result2} {
  write_file t1 [join [string trim $basis] \n]\n
  write_file t2 [join [string trim $v1] \n]\n
  write_file t3 [join [string trim $v2] \n]\n
  fossil 3-way-merge t1 t2 t3 t4
  fossil 3-way-merge t1 t3 t2 t5
  set x [read_file t4]
  regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<<} $x {>} x
  regsub -all {=======.*=======} $x {=} x
  regsub -all {>>>>>>> END MERGE CONFLICT.*>>>>} $x {<} x
  set x [split [string trim $x] \n]
  set y [read_file t5]
  regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<<} $y {>} y
Changes to www/adding_code.wiki.
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<blockquote><verbatim>
** COMMAND: xyzzy*
</verbatim></blockquote>

Then the command will only show up if you add the "--all" option to
[/help/help|fossil help].  Or, if the command name starts with
"test" then the command will be considered experimental and will only
show up when the --help option is used with [/help/help|fossil help].

The example above is a fully functioning Fossil command.  You can add
the text shown to an existing Fossil source file, recompiling then test
it out by typing:

    <b>./fossil xyzzy<br>
    ./fossil help xyzzy<br>
    ./fossil xyzzy --help</b>

The name of the C function that implements the command can be anything
you like (as long as it does not collide with some other symbol in the
Fossil code) but it is traditional to name the function
"<i>commandname</i><b>_cmd</b>", as is done in the example.

You could also use "printf()" instead of "fossil_print()" to generate
the output text, if desired.  But "fossil_print()" is recommended as
it has extra logic to insert \r characters at the right times on
windows systems.

Once you have the command running, you can then start adding code to
make it do useful things.  There are logs of utility functions in
Fossil for parsing command-line options and for
opening and accessing and manipulating the repository and
the working check-out.  Study at the implementations of existing commands
to get an idea of how things are done.  You can easily find the implementations
of existing commands by searching for "COMMAND: <i>name</i>" in the
files of the "src/" directory.

<h2>5.0 Creating A New Web Page</h2>

As with commands, new webpages can be added simply by inserting a function







|




















|


|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<blockquote><verbatim>
** COMMAND: xyzzy*
</verbatim></blockquote>

Then the command will only show up if you add the "--all" option to
[/help/help|fossil help].  Or, if the command name starts with
"test" then the command will be considered experimental and will only
show up when the --test option is used with [/help/help|fossil help].

The example above is a fully functioning Fossil command.  You can add
the text shown to an existing Fossil source file, recompiling then test
it out by typing:

    <b>./fossil xyzzy<br>
    ./fossil help xyzzy<br>
    ./fossil xyzzy --help</b>

The name of the C function that implements the command can be anything
you like (as long as it does not collide with some other symbol in the
Fossil code) but it is traditional to name the function
"<i>commandname</i><b>_cmd</b>", as is done in the example.

You could also use "printf()" instead of "fossil_print()" to generate
the output text, if desired.  But "fossil_print()" is recommended as
it has extra logic to insert \r characters at the right times on
windows systems.

Once you have the command running, you can then start adding code to
make it do useful things.  There are lots of utility functions in
Fossil for parsing command-line options and for
opening and accessing and manipulating the repository and
the working check-out.  Study implementations of existing commands
to get an idea of how things are done.  You can easily find the implementations
of existing commands by searching for "COMMAND: <i>name</i>" in the
files of the "src/" directory.

<h2>5.0 Creating A New Web Page</h2>

As with commands, new webpages can be added simply by inserting a function
Changes to www/changes.wiki.
1
2
3
4
5
6
7












8
9
10
11
12
13
14
<title>Change Log</title>

<h2>Changes For Version 1.27 (as yet unreleased)</h2>
  *  Enhance the [/help?cmd=changes | fossil changes],
     [/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
     [/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
     to restrict operation to files and directories named on the command-line.













<h2>Changes For Version 1.26 (2013-06-18)</h2>
  *  The argument to the --port option for the [/help?cmd=ui | fossil ui] and
     [/help?cmd=server | fossil server] commands can take an IP address in addition
     to the port number, causing Fossil to bind to just that one IP address.
  *  After prompting for a password, also ask if that password should be
     remembered.







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







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<title>Change Log</title>

<h2>Changes For Version 1.27 (as yet unreleased)</h2>
  *  Enhance the [/help?cmd=changes | fossil changes],
     [/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
     [/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
     to restrict operation to files and directories named on the command-line.
  *  New --integrate option to [/help?cmd=merge | fossil merge], which
     automatically closes the merged branch when committing.
  *  Renamed <tt>/stats_report</tt> page to [/reports]. Graph width is now
     relative, not absolute.
  *  Added <tt>yw=YYYY-WW</tt> (year-week) filter to timeline to limit the results
     to a specific year and calendar week number, e.g. [/timeline?yw=2013-01].
  *  Fixed an obscure condition under which an assertion failure could overwrite
     part of a repository database file, corrupting it. This problem has only
     been seen once in the wild.
  *  Added support for unlimited line lengths in side-by-side diffs.
  *  New --close option to [/help?cmd=commit | fossil commit], which
     immediately closes the branch being committed.

<h2>Changes For Version 1.26 (2013-06-18)</h2>
  *  The argument to the --port option for the [/help?cmd=ui | fossil ui] and
     [/help?cmd=server | fossil server] commands can take an IP address in addition
     to the port number, causing Fossil to bind to just that one IP address.
  *  After prompting for a password, also ask if that password should be
     remembered.
Changes to www/embeddeddoc.wiki.
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
CGI mode.  The "index.html" CGI script looks like this:

<blockquote><pre>
#!/usr/bin/fossil
repository: /fossil/fossil.fossil
</pre></blockquote>

This is one of three ways to set up a 
<a href="quickstart.wiki#serversetup">fossil web server</a>.

The "<b>/trunk/</b>" part of the URL tells fossil to use
the documentation files from the most recent trunk check-in.
If you wanted to see an historical version of this document,
you could substitute the name of a check-in for "<b>/trunk/</b>".
For example, to see the version of this document associated with
check-in [9be1b00392], simply replace the "<b>/trunk/</b>" with







|
|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
CGI mode.  The "index.html" CGI script looks like this:

<blockquote><pre>
#!/usr/bin/fossil
repository: /fossil/fossil.fossil
</pre></blockquote>

This is one of four ways to set up a 
<a href="./server.wiki">fossil web server</a>.

The "<b>/trunk/</b>" part of the URL tells fossil to use
the documentation files from the most recent trunk check-in.
If you wanted to see an historical version of this document,
you could substitute the name of a check-in for "<b>/trunk/</b>".
For example, to see the version of this document associated with
check-in [9be1b00392], simply replace the "<b>/trunk/</b>" with
Changes to www/fileformat.wiki.
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<li> [#ctrl | Control Artifacts] </li>
<li> [#wikichng | Wiki Pages] </li>
<li> [#tktchng | Ticket Changes] </li>
<li> [#attachment | Attachments] </li>
<li> [#event | Events] </li>
</ul>

These seven artifact types are described in the sequel.

In the current implementation (as of 2009-01-25) the artifacts that
make up a fossil repository are stored in in as delta- and zlib-compressed
blobs in an <a href="http://www.sqlite.org/">SQLite</a> database.  This
is an implementation detail and might change in a future release.  For
the purpose of this article "file format" means the format of the artifacts,
not how the artifacts are stored on disk.  It is the artifact format that







|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<li> [#ctrl | Control Artifacts] </li>
<li> [#wikichng | Wiki Pages] </li>
<li> [#tktchng | Ticket Changes] </li>
<li> [#attachment | Attachments] </li>
<li> [#event | Events] </li>
</ul>

These seven artifact types are described in the following sections.

In the current implementation (as of 2009-01-25) the artifacts that
make up a fossil repository are stored in in as delta- and zlib-compressed
blobs in an <a href="http://www.sqlite.org/">SQLite</a> database.  This
is an implementation detail and might change in a future release.  For
the purpose of this article "file format" means the format of the artifacts,
not how the artifacts are stored on disk.  It is the artifact format that
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

Allowed cards in the manifest are as follows:

<blockquote>
<b>B</b> <i>baseline-manifest</i><br>
<b>C</b> <i>checkin-comment</i><br>
<b>D</b> <i>time-and-date-stamp</i><br>
<b>F</b> <i>filename</i> <i>SHA1-hash</i> <i>permissions</i> <i>old-name</i><br>
<b>N</b> <i>mimetype</i><br>
<b>P</b> <i>SHA1-hash</i>+<br>
<b>Q</b> (<b>+</b>|<b>-</b>)<i>SHA1-hash ?SHA1-hash?</i><br>
<b>R</b> <i>repository-checksum</i><br>
<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name  <b>*</b> ?value?</i><br>
<b>U</b> <i>user-login</i><br>
<b>Z</b> <i>manifest-checksum</i>
</blockquote>

A manifest may optionally have a single B-card.  The B-card specifies
another manifest that serves as the "baseline" for this manifest.  A
manifest that has a B-card is called a delta-manifest and a manifest







|


|

|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

Allowed cards in the manifest are as follows:

<blockquote>
<b>B</b> <i>baseline-manifest</i><br>
<b>C</b> <i>checkin-comment</i><br>
<b>D</b> <i>time-and-date-stamp</i><br>
<b>F</b> <i>filename</i> ?<i>SHA1-hash</i>? ?<i>permissions</i>? ?<i>old-name</i>?<br>
<b>N</b> <i>mimetype</i><br>
<b>P</b> <i>SHA1-hash</i>+<br>
<b>Q</b> (<b>+</b>|<b>-</b>)<i>SHA1-hash</i> ?<i>SHA1-hash</i>?<br>
<b>R</b> <i>repository-checksum</i><br>
<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <b>*</b> ?<i>value</i>?<br>
<b>U</b> <i>user-login</i><br>
<b>Z</b> <i>manifest-checksum</i>
</blockquote>

A manifest may optionally have a single B-card.  The B-card specifies
another manifest that serves as the "baseline" for this manifest.  A
manifest that has a B-card is called a delta-manifest and a manifest
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
character (ASCII 0x0A), and the complete text of the file.
Compute the MD5 checksum of the result.

A manifest might contain one or more T-cards used to set
[./branching.wiki#tags | tags or properties]
on the check-in.  The format of the T-card is the same as
described in <i>Control Artifacts</i> section below, except that the
second argument is the single characcter "<b>*</b>" instead of an
artifact ID.  The <b>*</b> in place of the artifact ID indicates that
the tag or property applies to the current artifact.  It is not
possible to encode the current artifact ID as part of an artifact,
since the act of inserting the artifact ID would change the artifact ID,
hence a <b>*</b> is used to represent "self".  T-cards are typically
added to manifests in order to set the <b>branch</b> property and a
symbolic name when the check-in is intended to start a new branch.







|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
character (ASCII 0x0A), and the complete text of the file.
Compute the MD5 checksum of the result.

A manifest might contain one or more T-cards used to set
[./branching.wiki#tags | tags or properties]
on the check-in.  The format of the T-card is the same as
described in <i>Control Artifacts</i> section below, except that the
second argument is the single character "<b>*</b>" instead of an
artifact ID.  The <b>*</b> in place of the artifact ID indicates that
the tag or property applies to the current artifact.  It is not
possible to encode the current artifact ID as part of an artifact,
since the act of inserting the artifact ID would change the artifact ID,
hence a <b>*</b> is used to represent "self".  T-cards are typically
added to manifests in order to set the <b>branch</b> property and a
symbolic name when the check-in is intended to start a new branch.
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
the card type and the arguments.  No surplus whitespace is allowed.
All cards must occur in strict lexicographical order.

Allowed cards in a control artifact are as follows:

<blockquote>
<b>D</b> <i>time-and-date-stamp</i><br />
<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name  artifact-id  ?value?</i><br />
<b>U</b> <i>user-name</i><br />
<b>Z</b> <i>checksum</i><br />
</blockquote>

A control artifact must have one D card and one Z card and
one or more T cards.  No other cards or other text is
allowed in a control artifact.  Control artifacts might be PGP
clearsigned.

The D card and the Z card of a control artifact are the same
as in a manifest.








|




|







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
the card type and the arguments.  No surplus whitespace is allowed.
All cards must occur in strict lexicographical order.

Allowed cards in a control artifact are as follows:

<blockquote>
<b>D</b> <i>time-and-date-stamp</i><br />
<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <i>artifact-id</i> ?<i>value</i>?<br />
<b>U</b> <i>user-name</i><br />
<b>Z</b> <i>checksum</i><br />
</blockquote>

A control artifact must have one D card, one U card, one Z card and
one or more T cards.  No other cards or other text is
allowed in a control artifact.  Control artifacts might be PGP
clearsigned.

The D card and the Z card of a control artifact are the same
as in a manifest.

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520

<blockquote>
<b>C</b> <i>comment</i><br>
<b>D</b> <i>time-and-date-stamp</i><br />
<b>E</b> <i>event-time</i> <i>event-id</i><br />
<b>N</b> <i>mimetype</i><br />
<b>P</b> <i>parent-artifact-id</i>+<br />
<b>T</b> <b>+</b><i>tag-name</i> <b>*</b> <i>value</i><br />
<b>U</b> <i>user-name</i><br />
<b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
<b>Z</b> <i>checksum</i>
</blockquote>

The C card contains text that is displayed on the timeline for the
event.  Exactly one C card is required on an event artifact.

A single D card is required to give the date and time when the 
event artifact was created.  This is different from the time at which
the event occurs.

A single E card gives the time of the event (the point on the timeline
where the event is displayed) and a unique identifier for the event.
When there are multiple artifacts with the same event-id, the one with
the most recent D card is the only one used.  The event-id must be a
40-character lower-case hexadecimal string.

The optional N card specifies the mimetype of the text of the event
that is contained in the W card.  If the N card is omitted, then the
W card text mimetype is assumed to be text/x-fossil, which is the
Fossil wiki format.

The option P card specifies a prior event with the same event-id from
which the current event is an edit.  The P card is a hint to the system
that it might be space efficient to store one event as a delta of the
other.

An event might contain one or more T-cards used to set
[./branching.wiki#tags | tags or properties]
on the event.  The format of the T-card is the same as
described in [#ctrl | Control Artifacts] section above, except that the
second argument is the single characcter "<b>*</b>" instead of an
artifact ID and the name is always prefaced by "<b>+</b>".
The <b>*</b> in place of the artifact ID indicates that
the tag or property applies to the current artifact.  It is not
possible to encode the current artifact ID as part of an artifact,
since the act of inserting the artifact ID would change the artifact ID,
hence a <b>*</b> is used to represent "self".  The "<b>+</b>" on the
name means that tags can only be add and they can only be non-propagating







|






|
















|








|







473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520

<blockquote>
<b>C</b> <i>comment</i><br>
<b>D</b> <i>time-and-date-stamp</i><br />
<b>E</b> <i>event-time</i> <i>event-id</i><br />
<b>N</b> <i>mimetype</i><br />
<b>P</b> <i>parent-artifact-id</i>+<br />
<b>T</b> <b>+</b><i>tag-name</i> <b>*</b> ?<i>value</i>?<br />
<b>U</b> <i>user-name</i><br />
<b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
<b>Z</b> <i>checksum</i>
</blockquote>

The C card contains text that is displayed on the timeline for the
event.  The C card is optional, but there can only be one.

A single D card is required to give the date and time when the 
event artifact was created.  This is different from the time at which
the event occurs.

A single E card gives the time of the event (the point on the timeline
where the event is displayed) and a unique identifier for the event.
When there are multiple artifacts with the same event-id, the one with
the most recent D card is the only one used.  The event-id must be a
40-character lower-case hexadecimal string.

The optional N card specifies the mimetype of the text of the event
that is contained in the W card.  If the N card is omitted, then the
W card text mimetype is assumed to be text/x-fossil, which is the
Fossil wiki format.

The optional P card specifies a prior event with the same event-id from
which the current event is an edit.  The P card is a hint to the system
that it might be space efficient to store one event as a delta of the
other.

An event might contain one or more T-cards used to set
[./branching.wiki#tags | tags or properties]
on the event.  The format of the T-card is the same as
described in [#ctrl | Control Artifacts] section above, except that the
second argument is the single character "<b>*</b>" instead of an
artifact ID and the name is always prefaced by "<b>+</b>".
The <b>*</b> in place of the artifact ID indicates that
the tag or property applies to the current artifact.  It is not
possible to encode the current artifact ID as part of an artifact,
since the act of inserting the artifact ID would change the artifact ID,
hence a <b>*</b> is used to represent "self".  The "<b>+</b>" on the
name means that tags can only be add and they can only be non-propagating
529
530
531
532
533
534
535
536
537




538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570


571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732















































The Z card is the required checksum over the rest of the artifact.


<a name="summary"></a>
<h2>8.0 Card Summary</h2>

The following table summaries the various kinds of cards that
appear on Fossil artifacts:





<table border=1 width="100%">
<tr>
<th rowspan=2 valign=bottom>Card Format</th>
<th colspan=7>Used By</th>
</tr>
<tr>
<th>Manifest</th>
<th>Cluster</th>
<th>Control</th>
<th>Wiki</th>
<th>Ticket</th>
<th>Attachment</th>
<th>Event</th>
</tr>
<tr>
<td><b>A</b> <i>filename target source</i></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td align=center><b>X</b></td>
<td>&nbsp;</td>
</tr>
<tr>
<td><b>B</b> <i>baseline</i></td>
<td align=center><b>X</b></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>


<td>&nbsp;</td>
</tr>
<tr>
<td><b>C</b> <i>comment-text</i></td>
<td align=center><b>X</b></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
</tr>
<tr>
<td><b>D</b> <i>date-time-stamp</i></td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
</tr>
<tr>
<td><b>E</b> <i>event-time event-id</i></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
</tr>
<tr>
<td><b>F</b> <i>filename uuid permissions oldname</i></td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>J</b> <i>name value</i></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>K</b> <i>ticket-uuid</i></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>L</b> <i>wiki-title</i></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>M</b> <i>uuid</i></td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>N</b> <i>mimetype</i></td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
</tr>
<tr>
<td><b>P</b> <i>uuid ...</i></td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>Q</b> (<b>+</b>|<b>-</b>)<i>uuid uuid</i></td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>R</b> <i>md5sum</i></td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<tr>
<td><b>T</b> (<b>+</b>|<b>*</b>|<b>-</b>)<i>tagname uuid value</i></td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
</tr>
<tr>
<td><b>U</b> <i>username</i></td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
</tr>
<tr>
<td><b>W</b> <i>size</i></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>X</b></td>
</tr>
<tr>
<td><b>Z</b> <i>md5sum</i></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
<td align=center><b>X</b></td>
</tr>
</table>





















































|
|
>
>
>
>
















|





|




|





>
>
|
<


|




|
|



|

|
|
|
|
|









|


|
|








|




|









|








|







|








|


|

|
|



|


|


|


|
|









|







|
|

|



|



|

|
|
|
|
|






|


|



|
|
|
|
|
|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783

The Z card is the required checksum over the rest of the artifact.


<a name="summary"></a>
<h2>8.0 Card Summary</h2>

The following table summarizes the various kinds of cards that appear
on Fossil artifacts. A blank entry means that combination of card and
artifact is not legal. A number or range of numbers indicates the number
of times a card may (or must) appear in the corresponding artifact type.
e.g. a value of 1 indicates a required unique card and 1+ indicates that one
or more such cards are required.

<table border=1 width="100%">
<tr>
<th rowspan=2 valign=bottom>Card Format</th>
<th colspan=7>Used By</th>
</tr>
<tr>
<th>Manifest</th>
<th>Cluster</th>
<th>Control</th>
<th>Wiki</th>
<th>Ticket</th>
<th>Attachment</th>
<th>Event</th>
</tr>
<tr>
<td><b>A</b> <i>filename</i> <i>target</i> ?<i>source</i>?</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td align=center><b>1</b></td>
<td>&nbsp;</td>
</tr>
<tr>
<td><b>B</b> <i>baseline</i></td>
<td align=center><b>0-1*</b></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr><td>&nbsp;</td><td colspan='7'>* = Required for delta manifests</td></tr>

<tr>
<td><b>C</b> <i>comment-text</i></td>
<td align=center><b>1</b></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td align=center><b>0-1</b></td>
<td align=center><b>0-1</b></td>
</tr>
<tr>
<td><b>D</b> <i>date-time-stamp</i></td>
<td align=center><b>1</b></td>
<td align=center>&nbsp;</td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
</tr>
<tr>
<td><b>E</b> <i>event-time event-id</i></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>1</b></td>
</tr>
<tr>
<td><b>F</b> <i>filename</i> ?<i>uuid</i>? ?<i>permissions</i>? ?<i>oldname</i>?</td>
<td align=center><b>0+</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>J</b> <i>name</i> ?<i>value</i>?</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>1+</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>K</b> <i>ticket-uuid</i></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>1</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>L</b> <i>wiki-title</i></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>1</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>M</b> <i>uuid</i></td>
<td align=center>&nbsp;</td>
<td align=center><b>1+</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>N</b> <i>mimetype</i></td>
<td align=center><b>0-1</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>0-1</b></td>
<td align=center>&nbsp;</td>
<td align=center><b>0-1</b></td>
<td align=center><b>0-1</b></td>
</tr>
<tr>
<td><b>P</b> <i>uuid ...</i></td>
<td align=center><b>0-1</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>0-1</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>0-1</b></td>
</tr>
<tr>
<td><b>Q</b> (<b>+</b>|<b>-</b>)<i>uuid</i> ?<i>uuid</i>?</td>
<td align=center><b>0+</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
</tr>
<tr>
<td><b>R</b> <i>md5sum</i></td>
<td align=center><b>0-1</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<tr>
<td><b>T</b> (<b>+</b>|<b>*</b>|<b>-</b>)<i>tagname</i> <i>uuid</i> ?<i>value</i>?</td>
<td align=center><b>0+</b></td>
<td align=center>&nbsp;</td>
<td align=center><b>1+</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>0+</b></td>
</tr>
<tr>
<td><b>U</b> <i>username</i></td>
<td align=center><b>1</b></td>
<td align=center>&nbsp;</td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
<td align=center><b>0-1</b></td>
<td align=center><b>0-1</b></td>
</tr>
<tr>
<td><b>W</b> <i>size</i></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>1</b></td>
<td align=center>&nbsp;</td>
<td align=center>&nbsp;</td>
<td align=center><b>1</b></td>
</tr>
<tr>
<td><b>Z</b> <i>md5sum</i></td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
<td align=center><b>1</b></td>
</tr>
</table>


<a name="addenda"></a>
<h2>9.0 Addenda</h2>

This section contains additional information which may be useful when
implementing algorithms described above.

<h3>R Card Hash Calculation</h3>

Given a manifest file named <tt>MF</tt>, the following Bash shell code
demonstrates how to compute the value of the R card in that manifest.
This example uses manifest [28987096ac]. Lines starting with <tt>#</tt> are
shell input and other lines are output. This demonstration assumes that the
file versions represented by the input manifest are checked out
under the current directory.

<nowiki><pre>
# head MF
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

C Make\sthe\s"clearsign"\sPGP\ssigning\sdefault\sto\soff.
D 2010-02-23T15:33:14
F BUILD.txt 4f7988767e4e48b29f7eddd0e2cdea4555b9161c
F COPYRIGHT-GPL2.txt 06877624ea5c77efe3b7e39b0f909eda6e25a4ec
...

# grep '^R ' MF
R c0788982781981c96a0d81465fec7192

# for i in $(awk '/^F /{print $2}' MF); do \
  echo $i $(stat -c '%s' $i); \
  cat $i; \
done | md5sum
c0788982781981c96a0d81465fec7192  -
</pre></nowiki>

Minor caveats: the above demonstration will work only when none of the
filenames in the manifest are "fossilized" (encoded) because they contain
spaces. In that case the shell-generated hash would differ because the
<tt>stat</tt> calls will fail to find such files (which are output in encoded
form here). That approach also won't work for delta manifests. Calculating
the R-card for delta manifests requires traversing both the delta and its baseline in
lexical order of the files, prefering the delta's copy if both contain
a given file.
Added www/hacker-howto.wiki.


























>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
<title>Fossil Hackers How-To</title>

The following links are of interest to programmers who want to modify
or enhance Fossil.  Ordinary users can safely ignore this information.

  *  [./build.wiki | How To Compile And Install Fossil]
  *  [./makefile.wiki | The Fossil Build Process]
  *  [./tech_overview.wiki | A Technical Overview of Fossil]
  *  [./adding_code.wiki | Adding Features To Fossil]
  *  [./contribute.wiki|Contributing Code Or Enhancements To The Fossil Project]
  *  [./style.wiki | Coding Style Guidelines]
  *  [./checkin.wiki | Pre-checkin Checklist]
  *  [../test/release-checklist.wiki | Release Checklist]
Changes to www/index.wiki.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<ul>
<li> [http://www.fossil-scm.org/download.html | Download]
<li> [./quickstart.wiki | Quick Start]
<li> [./build.wiki | Install]
<li> [../COPYRIGHT-BSD2.txt | License]
<li> [/timeline | Recent changes]
<li> [./faq.wiki | FAQ]
<li> [./contribute.wiki | Contributing]
<li> [./changes.wiki | Change Log]
<li> [./hints.wiki | Tip &amp; Hints]
<li> [./permutedindex.wiki#pindex | Documentation Index]
<li> [http://www.fossil-scm.org/schimpf-book/home | Jim Schimpf's book]
<li> Mailing list
     <ul>
     <li> [http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | sign-up]







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<ul>
<li> [http://www.fossil-scm.org/download.html | Download]
<li> [./quickstart.wiki | Quick Start]
<li> [./build.wiki | Install]
<li> [../COPYRIGHT-BSD2.txt | License]
<li> [/timeline | Recent changes]
<li> [./faq.wiki | FAQ]
<li> [./hacker-howto.wiki | Hacker How-To]
<li> [./changes.wiki | Change Log]
<li> [./hints.wiki | Tip &amp; Hints]
<li> [./permutedindex.wiki#pindex | Documentation Index]
<li> [http://www.fossil-scm.org/schimpf-book/home | Jim Schimpf's book]
<li> Mailing list
     <ul>
     <li> [http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | sign-up]
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
      Fossil is a single stand-alone executable that contains everything
      needed to do configuration management.
      Installation is trivial: simply download a 
      <a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
      for Linux, Mac, or Windows and put it on your $PATH.
      [./build.wiki | Easy-to-compile source code] is available for
      users on other platforms.  Fossil sources are also mostly self-contained,
      requiring only the "zlib" library and the standard C library to build.

  5.  <b>Simple Networking</b> -
      Fossil uses plain old HTTP (with
      [./quickstart.wiki#proxy | proxy support])
      for all network communications, meaning that it works fine from behind
      restrictive firewalls.  The protocol is
      [./stats.wiki | bandwidth efficient] to the point that Fossil can be
      used comfortably over a dial-up internet connection.

  6.  <b>CGI Enabled</b> -
      No server is required to use fossil.  But a
      server does make collaboration easier.  Fossil supports three different
      yet simple [./quickstart.wiki#serversetup | server configurations].
      The most popular is a 2-line CGI script.  This is the approach
      used by the [./selfhost.wiki | self-hosting fossil repositories].

  7.  <b>Robust &amp; Reliable</b> -
      Fossil stores content using an [./fileformat.wiki | enduring file format]
      in an SQLite database so that transactions are
      atomic even if interrupted by a power loss or system crash.  Furthermore,
      automatic [./selfcheck.wiki | self-checks] verify that all aspects of
      the repository are consistent prior to each commit.  In over three years
      of operation, no work has ever been lost after having been committed to
      a Fossil repository.

<hr>
<h3>Links For Fossil Users:</h3>

  *  [./reviews.wiki | Testimonials] from satisfied fossil users and







|









|

|
|








|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
      Fossil is a single stand-alone executable that contains everything
      needed to do configuration management.
      Installation is trivial: simply download a 
      <a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
      for Linux, Mac, or Windows and put it on your $PATH.
      [./build.wiki | Easy-to-compile source code] is available for
      users on other platforms.  Fossil sources are also mostly self-contained,
      requiring only the standard C library to build.

  5.  <b>Simple Networking</b> -
      Fossil uses plain old HTTP (with
      [./quickstart.wiki#proxy | proxy support])
      for all network communications, meaning that it works fine from behind
      restrictive firewalls.  The protocol is
      [./stats.wiki | bandwidth efficient] to the point that Fossil can be
      used comfortably over a dial-up internet connection.

  6.  <b>CGI/SCGI Enabled</b> -
      No server is required to use fossil.  But a
      server does make collaboration easier.  Fossil supports four different
      yet simple [./server.wiki | server configurations].
      The most popular is a 2-line CGI script.  This is the approach
      used by the [./selfhost.wiki | self-hosting fossil repositories].

  7.  <b>Robust &amp; Reliable</b> -
      Fossil stores content using an [./fileformat.wiki | enduring file format]
      in an SQLite database so that transactions are
      atomic even if interrupted by a power loss or system crash.  Furthermore,
      automatic [./selfcheck.wiki | self-checks] verify that all aspects of
      the repository are consistent prior to each commit.  In over six years
      of operation, no work has ever been lost after having been committed to
      a Fossil repository.

<hr>
<h3>Links For Fossil Users:</h3>

  *  [./reviews.wiki | Testimonials] from satisfied fossil users and
Changes to www/makefile.wiki.
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
When compiling sqlite.c, the following macros are recommended:

  *  -Dlocaltime=fossil_localtime
  *  -DSQLITE_OMIT_LOAD_EXTENSION=1
  *  -DSQLITE_ENABLE_LOCKING_STYLE=0
  *  -DSQLITE_THREADSAFE=0
  *  -DSQLITE_DEFAULT_FILE_FORMAT=4
  *  -DSQLITE_ENABLE_STAT2

The first and second symbol definitions above are required; the others
are merely recommended.  The "localtime()" library function in SQLite must
be redefined to invoke fossil_localtime() instead.  The fossil_localtime()
routine will invoke either gmtime() or localtime() depending on the 
"Use UTC" setting for the fossil repository.  Extension loading is omitted
as a security measure.  Fossil is single-threaded so mutexing is disabled







|







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
When compiling sqlite.c, the following macros are recommended:

  *  -Dlocaltime=fossil_localtime
  *  -DSQLITE_OMIT_LOAD_EXTENSION=1
  *  -DSQLITE_ENABLE_LOCKING_STYLE=0
  *  -DSQLITE_THREADSAFE=0
  *  -DSQLITE_DEFAULT_FILE_FORMAT=4
  *  -DSQLITE_ENABLE_STAT3

The first and second symbol definitions above are required; the others
are merely recommended.  The "localtime()" library function in SQLite must
be redefined to invoke fossil_localtime() instead.  The fossil_localtime()
routine will invoke either gmtime() or localtime() depending on the 
"Use UTC" setting for the fossil repository.  Extension loading is omitted
as a security measure.  Fossil is single-threaded so mutexing is disabled
Changes to www/mkindex.tcl.
26
27
28
29
30
31
32

33
34
35
36
37
38
39
  event.wiki {Events}
  faq.wiki {Frequently Asked Questions}
  fileformat.wiki {Fossil File Format}
  fiveminutes.wiki {Update and Running in 5 Minutes as a Single User}
  foss-cklist.wiki {Checklist For Successful Open-Source Projects}
  fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
  fossil-v-git.wiki {Fossil Versus Git}

  hints.wiki {Fossil Tips And Usage Hints}
  index.wiki {Home Page}
  inout.wiki {Import And Export To And From Git}
  makefile.wiki {The Fossil Build Process}
  newrepo.wiki {How To Create A New Fossil Repository}
  password.wiki {Password Management And Authentication}
  pop.wiki {Principles Of Operations}







>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  event.wiki {Events}
  faq.wiki {Frequently Asked Questions}
  fileformat.wiki {Fossil File Format}
  fiveminutes.wiki {Update and Running in 5 Minutes as a Single User}
  foss-cklist.wiki {Checklist For Successful Open-Source Projects}
  fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
  fossil-v-git.wiki {Fossil Versus Git}
  hacker-howto.wiki {Hacker How-To}
  hints.wiki {Fossil Tips And Usage Hints}
  index.wiki {Home Page}
  inout.wiki {Import And Export To And From Git}
  makefile.wiki {The Fossil Build Process}
  newrepo.wiki {How To Create A New Fossil Repository}
  password.wiki {Password Management And Authentication}
  pop.wiki {Principles Of Operations}
Changes to www/permutedindex.wiki.
86
87
88
89
90
91
92

93
94
95
96
97
98

99
100
101
102
103
104
105
<li><a href="inout.wiki">From Git &mdash; Import And Export To And</a></li>
<li><a href="quotes.wiki">General &mdash; Quotes: What People Are Saying About Fossil, Git, and DVCSes in</a></li>
<li><a href="fossil-v-git.wiki">Git &mdash; Fossil Versus</a></li>
<li><a href="inout.wiki">Git &mdash; Import And Export To And From</a></li>
<li><a href="quotes.wiki">Git, and DVCSes in General &mdash; Quotes: What People Are Saying About Fossil,</a></li>
<li><a href="quickstart.wiki">Guide &mdash; Fossil Quick Start</a></li>
<li><a href="style.wiki">Guidelines &mdash; Source Code Style</a></li>

<li><a href="adding_code.wiki">Hacking Fossil</a></li>
<li><a href="hints.wiki">Hints &mdash; Fossil Tips And Usage</a></li>
<li><a href="index.wiki">Home Page</a></li>
<li><a href="selfhost.wiki">Hosting Repositories &mdash; Fossil Self</a></li>
<li><a href="server.wiki">How To Configure A Fossil Server</a></li>
<li><a href="newrepo.wiki">How To Create A New Fossil Repository</a></li>

<li><a href="fossil-from-msvc.wiki">IDE &mdash; Integrating Fossil in the Microsoft Express 2010</a></li>
<li><a href="tech_overview.wiki">Implementation Of Fossil &mdash; A Technical Overview Of The Design And</a></li>
<li><a href="inout.wiki">Import And Export To And From Git</a></li>
<li><a href="build.wiki">Installing Fossil &mdash; Compiling and</a></li>
<li><a href="fossil-from-msvc.wiki">Integrating Fossil in the Microsoft Express 2010 IDE</a></li>
<li><a href="selfcheck.wiki">Integrity Self Checks &mdash; Fossil Repository</a></li>
<li><a href="webui.wiki">Interface &mdash; The Fossil Web</a></li>







>






>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<li><a href="inout.wiki">From Git &mdash; Import And Export To And</a></li>
<li><a href="quotes.wiki">General &mdash; Quotes: What People Are Saying About Fossil, Git, and DVCSes in</a></li>
<li><a href="fossil-v-git.wiki">Git &mdash; Fossil Versus</a></li>
<li><a href="inout.wiki">Git &mdash; Import And Export To And From</a></li>
<li><a href="quotes.wiki">Git, and DVCSes in General &mdash; Quotes: What People Are Saying About Fossil,</a></li>
<li><a href="quickstart.wiki">Guide &mdash; Fossil Quick Start</a></li>
<li><a href="style.wiki">Guidelines &mdash; Source Code Style</a></li>
<li><a href="hacker-howto.wiki">Hacker How-To</a></li>
<li><a href="adding_code.wiki">Hacking Fossil</a></li>
<li><a href="hints.wiki">Hints &mdash; Fossil Tips And Usage</a></li>
<li><a href="index.wiki">Home Page</a></li>
<li><a href="selfhost.wiki">Hosting Repositories &mdash; Fossil Self</a></li>
<li><a href="server.wiki">How To Configure A Fossil Server</a></li>
<li><a href="newrepo.wiki">How To Create A New Fossil Repository</a></li>
<li><a href="hacker-howto.wiki">How-To &mdash; Hacker</a></li>
<li><a href="fossil-from-msvc.wiki">IDE &mdash; Integrating Fossil in the Microsoft Express 2010</a></li>
<li><a href="tech_overview.wiki">Implementation Of Fossil &mdash; A Technical Overview Of The Design And</a></li>
<li><a href="inout.wiki">Import And Export To And From Git</a></li>
<li><a href="build.wiki">Installing Fossil &mdash; Compiling and</a></li>
<li><a href="fossil-from-msvc.wiki">Integrating Fossil in the Microsoft Express 2010 IDE</a></li>
<li><a href="selfcheck.wiki">Integrity Self Checks &mdash; Fossil Repository</a></li>
<li><a href="webui.wiki">Interface &mdash; The Fossil Web</a></li>
Changes to www/quickstart.wiki.
283
284
285
286
287
288
289
290
291
292

293
294
295
296

297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
    <p>This will back out the changes that the merge or update made to the
    working checkout.  There is also a [/help/redo|redo] command if you undo by
    mistake.  Undo and redo only work for changes that have
    not yet been checked in using commit and there is only a single
    level of undo/redo.</p>


<a name="serversetup"></a>
<h2>Setting Up A Server</h2>


    <p>The easiest way to set up a server is:</p>

    <blockquote>
    <b>[/help/server | fossil server]</b> <i>repository-filename</i>

    </blockquote>

    <p>Or</b>

    <blockquote>
    <b>[/help/ui | fossil ui]</b> <i>repository-filename</i>

    </blockquote>

    <p>The <b>ui</b> command is intended for accessing the web interface
    from a local desktop.  The <b>ui</b> command binds to the loopback IP
    address only (and thus makes the web interface visible only on the
    local machine) and it automatically start your web browser pointing at the
    server.  For cross-machine collaboration, use the <b>server</b> command,
    which binds on all IP addresses and does not try to start a web browser.
    You can omit the <i>repository-filename</i> if you are within
    a checked-out local tree.  The <b>server</b> uses port 8080 by default
    but you can specify a different port using the <b>-port</b> option.</p>

    <p>Command-line servers like this are useful when two people want
    to share a repository on temporary or ad-hoc basis.  For a more
    permanent installation, you should use either the CGI server or the
    inetd server.
    <a name="cgiserver"></a>
    To use the CGI server, create a CGI script that
    looks something like this:</p>

    <blockquote><b>
    #!/usr/local/bin/fossil<br>
    repository: /home/proj1/repos1.fossil
    </b></blockquote>

    <p>Adjust the paths in this CGI script to match your installation
    and make sure both repository file and the directory that contains it
    are readable and writable by the user that CGI scripts run as.
    Then point clients at the CGI script.  That's all there is to it!</p>

    <a name="inetdserver"></a>
    <p>You can also run fossil from inetd or xinetd.  For an inetd
    installation, make an entry in /etc/inetd.conf that looks something
    like this:</p>

    <blockquote><b>
    80 stream tcp nowait.1000 root /usr/bin/fossil \<br>
        /usr/bin/fossil http /home/proj1/repos1.fossil
    </b></blockquote>

    <p>Adjust the paths to suit your installation, of course.  Notice that
    fossil runs as root.  This is not required - you can run it as an
    unprivileged user.  But it is more secure to run fossil as root.
    When you do run fossil as root, it automatically puts itself in a
    chroot jail in the same directory as the repository, then drops
    root privileges prior to reading any information from the socket.</p>

<a name="proxy"></a>
<h2>HTTP Proxies</h2>

    <p>If you are behind a restrictive firewall that requires you to use
    an HTTP proxy to reach the internet, then you can configure the proxy
    in three different ways.  You can tell fossil about your proxy using







<


>
|


|
>


<
<
<
|
>
|






|
<
<
<

<
<
<
|
<
<
<
|
<
<
<
<
|
<
<
<
<
|
|
<
<
|

<
<
|
<
|
<
<
<
<
<
<







283
284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299



300
301
302
303
304
305
306
307
308
309



310



311



312




313




314
315


316
317


318

319






320
321
322
323
324
325
326
    <p>This will back out the changes that the merge or update made to the
    working checkout.  There is also a [/help/redo|redo] command if you undo by
    mistake.  Undo and redo only work for changes that have
    not yet been checked in using commit and there is only a single
    level of undo/redo.</p>



<h2>Setting Up A Server</h2>

    <p>Fossil can act as a stand-alone web server using one of these
    commands:</p>

    <blockquote>
    <b>[/help/server | fossil server]</b> <i>repository-filename</i><br>
    <b>[/help/ui | fossil ui]</b> <i>repository-filename</i>
    </blockquote>




    <p>The <i>repository-filename</i> can be omitted when these commands
    are run from within an open check-out, which a particularly useful
    shortcut for the <b>fossil ui</b> command.

    <p>The <b>ui</b> command is intended for accessing the web interface
    from a local desktop.  The <b>ui</b> command binds to the loopback IP
    address only (and thus makes the web interface visible only on the
    local machine) and it automatically start your web browser pointing at the
    server.  For cross-machine collaboration, use the <b>server</b> command,
    which binds on all IP addresses and does not try to start a web browser.</p>







    <p>Servers are also easily configured as:



    <ul>




    <li>[./server.wiki#inetd|inetd/xinetd]




    <li>[./server.wiki#cgi|CGI]
    <li>[./server.wiki#scgi|SCGI]


    </ul>



    <p>The the [./selfhost.wiki | self-hosting fossil repositories] use

    CGI.  







<a name="proxy"></a>
<h2>HTTP Proxies</h2>

    <p>If you are behind a restrictive firewall that requires you to use
    an HTTP proxy to reach the internet, then you can configure the proxy
    in three different ways.  You can tell fossil about your proxy using
Added www/scgi.wiki.




















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<title>Fossil SCGI</title>

To run Fossil using SCGI, start the [/help/server|fossil server] command
with the --scgi command-line option.  You will probably also want to
specific an alternative TCP/IP port using --port.  For example:

<blockquote><pre>
fossil server $REPOSITORY --port 9000 --scgi
</pre></blockquote>

Then configure your SCGI-aware web-server to send SCGI requests to port
9000 on the machine where Fossil is running.  A typical configuration for
this in Nginx is:

<blockquote><pre>
location ~ ^/demo_project/ {
    include scgi_params;
    scgi_pass localhost:9000;
    scgi_param SCRIPT_NAME "/demo_project";
}
</pre></blockquote>

Note that Nginx does not normally send either the PATH_INFO or SCRIPT_NAME
variables via SCGI, but Fossil needs one or the other.  So the configuration
above needs to add SCRIPT_NAME.  If you do not do this, Fossil return an
error.
Changes to www/selfhost.wiki.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
on any of the three servers and those changes automatically propagate to the
other two servers.

Server (1) runs as a CGI script on a
<a href="http://www.linode.com/">Linode 1024</a> located in Dallas, TX
- on the same virtual machine that 
hosts <a href="http://www.sqlite.org/">SQLite</a> and over a
dozen other smaller projects.  This demonstrates that Fossil does not
require much server power.
Multiple fossil-based projects can easily be hosted on the same machine,
even if that machine is itself one of several dozen virtual machines on
single physical box.  The CGI script that runs the canonical Fossil
self-hosting repository is as follows:

<blockquote><pre>
#!/usr/bin/fossil
repository: /fossil/fossil.fossil
</pre></blockquote>

Server (3) runs as a CGI script on a shared hosting account at
<a href="http://www.he.net/">Hurricane Electric</a> in Fremont, CA.  
This server demonstrates the ability of
Fossil to run on an economical shared-host web account with no
privileges beyond port 80 HTTP access and CGI.  It is not necessary

to have a dedicated server to run Fossil.  As far as we are aware, 
Fossil is the only full-featured configuration management system 
that can run in
such a restricted environment.  The CGI script that runs on the
Hurricane Electric server is the same as the CGI script shown above,
except that the pathnames are modified to suit the environment:

<blockquote><pre>







|
|















>
|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
on any of the three servers and those changes automatically propagate to the
other two servers.

Server (1) runs as a CGI script on a
<a href="http://www.linode.com/">Linode 1024</a> located in Dallas, TX
- on the same virtual machine that 
hosts <a href="http://www.sqlite.org/">SQLite</a> and over a
dozen other smaller projects.  This demonstrates that Fossil can run on
a low-power host processor.
Multiple fossil-based projects can easily be hosted on the same machine,
even if that machine is itself one of several dozen virtual machines on
single physical box.  The CGI script that runs the canonical Fossil
self-hosting repository is as follows:

<blockquote><pre>
#!/usr/bin/fossil
repository: /fossil/fossil.fossil
</pre></blockquote>

Server (3) runs as a CGI script on a shared hosting account at
<a href="http://www.he.net/">Hurricane Electric</a> in Fremont, CA.  
This server demonstrates the ability of
Fossil to run on an economical shared-host web account with no
privileges beyond port 80 HTTP access and CGI.  It is not necessary
to have a dedicated computer with administrator to run Fossil.
As far as we are aware, 
Fossil is the only full-featured configuration management system 
that can run in
such a restricted environment.  The CGI script that runs on the
Hurricane Electric server is the same as the CGI script shown above,
except that the pathnames are modified to suit the environment:

<blockquote><pre>
Changes to www/server.wiki.
1
2








3
4









5
6
7
8
9
10
11
12
13
14
15


16

17



18
19
20
21
22
23
24
25




26
27






28
29
30

31
32
33



34








35




36









37
38
39
40
41
42

43
44
45
46
47
48
49




50
51
52
53




54
55







56


57
58


59


60

61
62
63
64
65
66
67

68


69
70
71




72















73
74


75
76
77
78






79
80
81

82
83
84



85






86
87
88



89
90
91
92
93

94




95
96
97


98
99
100

101
102
103
104
105
106
107
108
109

110
111

112
113
114
115
116





117
118
119








120
121
122
123
124
<title>How To Configure A Fossil Server</title>
<nowiki>








<p>This guide is intended to help guide you in setting up a Fossil server.</p>










<h2>Standalone server</h2><blockquote>
The easiest way to set up a Fossil server is to use the <tt>server</tt> or
<tt>ui</tt> command.  Assuming the repository you are interested in serving is
in the file "<tt>repo.fossil</tt>", you can use either of these commands to
start Fossil as a server:
<ul>
<li><tt>fossil server repo.fossil</tt>
<li><tt>fossil ui repo.fossil</tt>
</ul>

<p>


Both of these commands start a Fossil server on port 8080 on the local machine,

which can be accessed with the URL: <tt>http://localhost:8080/</tt> using any



handy web browser.  The difference between the two commands is that "ui", in
addition to starting the Fossil server, also starts a web browser and points it
to the URL mentioned above.  On the other hand, the "ui" command binds to
the loopback IP address only (127.0.0.1) so that the "ui" command cannot be
used to serve content to a different machine.
</p>
<p>
NOTES:




<ol>
<li>The option "--port NNN" will start the server on port "NNN" instead of 8080.  






<li>If port 8080 is already being used (perhaps by another Fossil server), then
Fossil will use the next available port number.
<li>Starting either command from within an "open" Fossil checkout will start a

server using the repository corresponding to the checkout.
<li>This is an excellent option for quickly sharing with coworkers on a small network.
<li>A huge advantage to this deployment scenario is that no special "root" or "administrator" access is required in order to share the repository.



</ol>








</p>




</blockquote>










<h2>Fossil as an ''inetd'' service</h2><blockquote>
<p>
Modify your <tt>/etc/inetd.conf</tt> (on Linux, modify as appropriate for your platform) so it contains a line like this:
<blockquote>
<tt>

12345 stream tcp nowait.1000 root /path-to/fossil /path-to/fossil http /other-path-to/repository
</tt>
</blockquote>
In this example, you are telling "inetd" that when an incoming connection on port "12345" happens, it should launch the binary "/path-to/fossil".  Obviously you will need to modify the "path-to" parts as appropriate for your particular setup.
</p>
<p>
This is a more complex setup than the "standalone" server, but it has the advantage of only using system resources when an actual connection is attempted.  If no-one ever connects to that port, a Fossil server will not (automatically) run.  It has the disadvantage of requiring "root" access and therefore may not normally be available to lower-priced "shared" servers on the internet.




</p>
</blockquote>

<h2>Fossil as a ''CGI script''</h2><blockquote>




<p>
This is the most flexible and most likely to be widely usable of these deployment scenarios.  In order for it to work, you must have the ability to install "CGI scripts" on the server you are interested in using. 







</p>


</blockquote>



<h3>One script per repository</h3><blockquote>


<p>

Create a script (let's call it 'repo') in your CGI directory which has content like this:
<blockquote><tt>
#!/path-to/fossil<br>
repository: /path-to-repo/repository
</tt></blockquote>
</p>
<p>

It may be necessary to set permissions properly, or to modify an ".htaccess" file or other server-specific things like that.  Consult with your server provider if you need that sort of assistance.


</p>
<p>
Once the script is set up correctly, and assuming your server is also set correctly, you should be able to access your repository with a URL like: <tt>http://mydomain.org/cgi-bin/repo</tt> (assuming the "repo" script is accessible under "cgi-bin", which would be a typical deployment on Apache for instance).




</p>















</blockquote>



<h3>Serving multiple repositories with one script</h3><blockquote>
<p>
This scenario is almost identical to the previous one.  However, here we will assume you have multiple repositories, in one directory.
(Call the directory 'fossils').  All repositories served, in this case, must






use the ".fossil" filename suffix.
As before, create a script (again, 'repo'):
<blockquote><tt>

#!/path-to/fossil<br>
directory: /path-to-repo/fossils<br>
notfound: http://url-to-go-to-if-repo-not-found/



</tt></blockquote>






</p>
<p>
Once deployed, a URL like: <tt>http://mydomain.org/cgi-bin/repo/XYZ</tt> will serve up the repository "fossils/XYX.fossil" (if it exists).  This makes serving multiple projects on one server pretty painless.



</p>
</blockquote>

<h2>Securing a repository with SSL</h2><blockquote>
<p>

Using either of the CGI script approaches, it is trivial to use SSL to secure the server.  Simply set up the Fossil CGI scripts etc. as above, but modify the Apache (or IIS, etc.) server to require SSL (that is, a URL with "https://") in order to access the CGI script directory.  This may also be accomplished (on Apache, at least) using appropriate ".htaccess" rules.




</p>
<p>
If you are using "inetd" to serve your repository, then you simply need to add "/usr/bin/stunnel" (perhaps on a different path, depending on your setup) before the command line to launch Fossil.


</p>
<p>
At this stage, the standalone server (e.g. "fossil server") does not support SSL.

</p>
<p>
For more information, see <a href="./ssl.wiki">Using SSL with Fossil</a>.
</p>
</blockquote>

<h2>Various security concerns with hosted repositories</h2><blockquote>
<p>
There are two main concerns relating to usage of Fossil for sharing sensitive information (source or any other data):

<ul>
<li>Interception of the Fossil synchronization stream, thereby capturing data, and

<li>Direct access to the Fossil repository on the server
</ul>
</p>
<p>
Regarding the first, it is adequate to secure the server using SSL, and disallowing any non-SSL access.  The data stream will be encrypted by the HTTPS protocol, rendering the data reasonably secure.  The truly paranoid may wish to deploy <i>ssh</i> encrypted tunnels, but that is quite a bit more difficult and cumbersome to set up (particularly for a larger number of users).





</p>
<p>
As far as direct access to the repository, the same steps must be taken as for any other internet-facing data-store.  Access passwords to any disk-accessing accounts should be strong (and preferably changed from time to time).  However, the data in the repository itself are <i>not</i> encrypted (unless you save encrypted data yourself), and so the system administrators of your server will be able to access your data (as with any hosting service setup).  The only workaround in this case is to host the server yourself, in which case you will need to allocate resources to deal with administration issues.








</p>

</blockquote>

</nowiki>

|
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>

|
<
<
|

|
|

<

>
>
|
>
|
>
>
>
|
|
|
|



<
>
>
>
>
|
|
>
>
>
>
>
>
|
|
<
>
|
<
<
>
>
>
|
>
>
>
>
>
>
>
>

>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
<
|
<
|
|
>
|
<
<
<


<
>
>
>
>

|
|
|
>
>
>
>

<
>
>
>
>
>
>
>

>
>
|
|
>
>
|
>
>

>
|
|
|
|
|


>
|
>
>


|
>
>
>
>

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


>
>
|

<
<
>
>
>
>
>
>
|
<
|
>
|
<
<
>
>
>
|
>
>
>
>
>
>


<
>
>
>





>
|
>
>
>
>


|
>
>


|
>








|
>

|
>




|
>
>
>
>
>


|
>
>
>
>
>
>
>
>



<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89

90
91
92
93



94
95

96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167


168
169
170
171
172
173
174

175
176
177


178
179
180
181
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249


<title>How To Configure A Fossil Server</title>
<h2>Introduction</h2><blockquote>
<p>A server is not necessary to use Fossil, but a server does help in collaborating with
peers.  A Fossil server also works well as a complete website for a project.
For example, the complete <b>http://www.fossil-scm.org/</b> website, including the
page you are now reading (but excepting the download page),
is just a Fossil server displaying the content of the 
self-hosting repository for Fossil.</p>
<p>This article is a guide for setting up your own Fossil server.</p></blockquote>
<h2>Overview</h2><blockquote>
There are basically four ways to set up a Fossil server:
<ol>
<li>A stand-alone server
<li>Using inetd or xinetd or stunnel
<li>CGI
<li>SCGI (a.k.a. SimpleCGI)
</ol>
Each of these can serve either a single repository, or a directory hierarchy 
containing many repositories with names ending in ".fossil".
</blockquote>
<a name="standalone"></a>
<h2>Standalone server</h2><blockquote>
The easiest way to set up a Fossil server is to use either the


[/help/server|server] or the [/help/ui|ui] commands:
<ul>
<li><b>fossil server</b> <i>REPOSITORY</i>
<li><b>fossil ui</b> <i>REPOSITORY</i>
</ul>

<p>
The <i>REPOSITORY</i> argument is either the name of the repository file, or
a directory containing many repositories.
Both of these commands start a Fossil server, usually on TCP port 8080, though
a higher numbered port might also be used if 8080 is already occupied.  You can
access these using URLs of the form <b>http://localhost:8080/</b>, or if 
<i>REPOSITORY</i> is a directory, URLs of the form
<b>http://localhost:8080/</b><i>repo</i><b>/</b> where <i>repo</i> is the base
name of the repository file without the ".fossil" suffix.
The difference between "ui" and "server" is that "ui" will
also start a web browser and points it
to the URL mentioned above, and "ui" command binds to
the loopback IP address (127.0.0.1) only so that the "ui" command cannot be
used to serve content to a different machine.
</p>
<p>

If one of the commands above is run from within an option checkout,
then the <i>REPOSITORY</i> argument can be omitted and the checkout is used as
the repository.
</p>
<p>
Both commands have additional command-line options that can be used to refine
their behavior.  See the [/help/server|online documentation] for an overview.
</p>
</blockquote>
<a name="inetd"></a>
<h2>Fossil as an inetd/xinetd or stunnel service</h2><blockquote>
<p>
A Fossil server can be launched on-demand by inetd or xinetd using
the [/help/http|fossil http] command.  To launch Fossil from inetd, modify

your inetd configuration file (typically "/etc/inetd.conf") to contain a
line something like this:


<blockquote>
<pre>
12345 stream tcp nowait.1000 root /usr/bin/fossil /usr/bin/fossil http /home/fossil/repo.fossil
</pre>
</blockquote>
In this example, you are telling "inetd" that when an incoming connection
appears on port "12345", that it should launch the binary "/usr/bin/fossil"
program with the arguments shown.
Obviously you will
need to modify the pathnames parts as appropriate for your particular setup.
The final argument is either the name of the fossil repository to be served,
or a directory containing multiple repositories.
</p>
<p>
If you system is running xinetd, then the configuration is likely to be
in the file "/etc/xinetd.conf" or in a subfile of "/etc/xinetd.d".
An xinetd configuration file will appear like this:</p>
<blockquote>
<pre>
service http-alt
{
  port = 591
  socket_type = stream
  wait = no
  user = root
  server = /usr/bin/fossil
  server_args = http /home/fossil/repos/
}

</pre>

</blockquote>
<p>
The xinetd example above has Fossil configured to serve multiple
repositories, contained under the "/home/fossil/repos/" directory.



</p>
<p>

In both cases notice that Fossil was launched as root.  This is not required,
but if it is done, then Fossil will automatically put itself into a chroot
jail for the user who owns the fossil repository before reading any information
off of the wire.
</p>
<p>
[http://www.stunnel.org/ | Stunnel version 4] is an inetd-like process that
accepts and decodes SSL-encrypted connections.  Fossil can be run directly from
stunnel in a mannar similar to inetd and xinetd.  This can be used to provide
a secure link to a Fossil project.  The configuration needed to get stunnel4
to invoke Fossil is very similar to the inetd and xinetd examples shown above.
See the stunnel4 documentation for details.
<p>

Using inetd or xinetd or stunnel is a more complex setup 
than the "standalone" server, but it has the
advantage of only using system resources when an actual connection is
attempted.  If no-one ever connects to that port, a Fossil server will
not (automatically) run. It has the disadvantage of requiring "root" access
and therefore may not normally be available to lower-priced "shared" servers
on the internet.
</p>
</blockquote>
<a name="cgi"></a>
<h2>Fossil as CGI</h2><blockquote>
<p>
A Fossil server can also be run from an ordinary web server as a CGI program.
This feature allows Fossil to be seamlessly integrated into a larger website.
CGI is how the [./selfhost.wiki | self-hosting fossil repositories] are 
implemented.
</p>
<p>
To run Fossil as CGI, create a CGI script (here called "repo") in the CGI directory
of your web server and having content like this:
<blockquote><pre>
#!/usr/bin/fossil
repository: /home/fossil/repo.fossil
</pre></blockquote>
</p>
<p>
As always, adjust your paths appropriately.
It may be necessary to set permissions properly, or to modify an ".htaccess"
file or other server-specific things like that.  Consult the documentation
for your particular server.
</p>
<p>
Once the script is set up correctly, and assuming your server is also set
correctly, you should be able to access your repository with a URL like:
<b>http://mydomain.org/cgi-bin/repo</b> (assuming the "repo" script is
accessible under "cgi-bin", which would be a typical deployment on Apache
for instance).
</p>
<p>
To server multiple repositories from a directory using CGI, use the "directory:"
tag in the CGI script rather than "repository:".   You might also want to add
a "notfound:" tag to tell where to redirect if the particular repository requested
by the URL is not found:
<blockquote><pre>
#!/usr/bin/fossil
directory: /home/fossil/repos
notfound: http://url-to-go-to-if-repo-not-found/
</pre></blockquote>
</p>
<p>
Once deployed, a URL like: <b>http://mydomain.org/cgi-bin/repo/XYZ</b>
will serve up the repository "/home/fossil/repos/XYX.fossil" (if it exists).
</p>
</blockquote>

<a name="scgi"></a>
<h2>Fossil as SCGI</h2><blockquote>

<p>


The [/help/server|fossil server] command, described above as a way of 
starting a stand-alone web server, can also be used for SCGI.  Simply add
the --scgi command-line option and the stand-alone server will interpret
and respond to the SimpleCGI or SCGI protocol rather than raw HTTP.  This can
be used in combination with a webserver (such as [http://nginx.org|Nginx])
that does not support CGI.  A typical Nginx configuration to support SCGI
with Fossil would look something like this:

<blockquote><pre>
location ~ ^/demo_project/ {
    include scgi_params;


    scgi_pass localhost:9000;
    scgi_param SCRIPT_NAME "/demo_project";
}
</pre></blockquote>
<p>
Note that Fossil requires the SCRIPT_NAME variable
in order to function properly, but Nginx does not provide this
variable by default.
So it is necessary to provide the SCRIPT_NAME parameter in the configuration.
Failure to do this will cause Fossil to return an error.
</p>
<p>

All of the features of the stand-alone server mode described above,
such as the ability to server a directory full of Fossil repositories
rather than just a single repository, work the same way in SCGI mode.
</p>
</blockquote>

<h2>Securing a repository with SSL</h2><blockquote>
<p>
Using either CGI or SCGI, it is trivial to use SSL to
secure the server.  Simply set up the Fossil CGI scripts etc. as above,
but modify the Apache (or IIS, etc.) server to require SSL (that is, a
URL with "https://") in order to access the CGI script directory.  This
may also be accomplished (on Apache, at least) using appropriate
".htaccess" rules.
</p>
<p>
If you are using "inetd" to serve your repository, then you simply need
to add "/usr/bin/stunnel" (perhaps on a different path, depending on your
setup) before the command line to launch Fossil.
</p>
<p>
At this stage, the standalone server (e.g. "fossil server") does not
support SSL.
</p>
<p>
For more information, see <a href="./ssl.wiki">Using SSL with Fossil</a>.
</p>
</blockquote>

<h2>Various security concerns with hosted repositories</h2><blockquote>
<p>
There are two main concerns relating to usage of Fossil for sharing
sensitive information (source or any other data):
<ul>
<li>Interception of the Fossil synchronization stream, thereby capturing
data, and 
<li>Direct access to the Fossil repository on the server
</ul>
</p>
<p>
Regarding the first, it is adequate to secure the server using SSL, and
disallowing any non-SSL access.  The data stream will be encrypted by
the HTTPS protocol, rendering the data reasonably secure.  The truly
paranoid may wish to deploy <i>ssh</i> encrypted tunnels, but that is
quite a bit more difficult and cumbersome to set up (particularly for
a larger number of users).
</p>
<p>
As far as direct access to the repository, the same steps must be taken
as for any other internet-facing data-store.  Access passwords to any
disk-accessing accounts should be strong (and preferably changed from
time to time).  However, the data in the repository itself are <i>not</i>
encrypted (unless you save encrypted data yourself), and so the system
administrators of your server will be able to access your data (as with
any hosting service setup).  The only workaround in this case is to
host the server yourself, in which case you will need to allocate
resources to deal with administration issues.
</p>

</blockquote>


Changes to www/webui.wiki.
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
Notice that Fossil automatically finds an unused TCP port to run the
server own and automatically points your web browser to the correct
URL.  So there is never any fumbling around trying to find an open
port or to type arcane strings into your browser URL entry box.
The interface just pops right up, ready to run.

The Fossil web interface is also very easy to setup and run on a
network server, as either a CGI program or from inetd.  Details on how

to do that are described further below.

<h2>Things To Do Using The Web Interface</h2>

You can view <b>timelines</b> of changes to the project.  The default
"Timeline" link on the menu bar takes you to a page that shows the 20
most recent check-ins, wiki page edits, ticket/bug-report changes,







|
>







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
Notice that Fossil automatically finds an unused TCP port to run the
server own and automatically points your web browser to the correct
URL.  So there is never any fumbling around trying to find an open
port or to type arcane strings into your browser URL entry box.
The interface just pops right up, ready to run.

The Fossil web interface is also very easy to setup and run on a
network server, as either a CGI program or from inetd, or as an
SCGI server.  Details on how
to do that are described further below.

<h2>Things To Do Using The Web Interface</h2>

You can view <b>timelines</b> of changes to the project.  The default
"Timeline" link on the menu bar takes you to a page that shows the 20
most recent check-ins, wiki page edits, ticket/bug-report changes,
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155



156

157
158
159
160
161
162
163
164
165
166
167
168
"Home" page to be a wiki page or an embedded document.

<h2>Installing On A Network Server</h2>

When you create a new Fossil project and after you have configured it
like you want it using the web interface, you can make the project
available to a distributed team by simply copying the single
repository file up to a web server that supports CGI.  Just put the

<b>sample-project.fossil</b> file in a directory where CGI scripts
have both read and write permission on the file and the directory that
contains the file, then add a CGI script that looks something like this:

  <verbatim>
  #!/usr/local/bin/fossil
  repository: /home/www/sample-project.fossil
  </verbatim>

Adjust the script above so that the paths are correct for your system,
of course, and also make sure the Fossil binary is installed on the server.
But that is <u>all</u> you have to do.  You now have everything you need to host
a distributed software development project in less than five minutes using a 
two-line CGI script.




You don't have a CGI-capable web server running on your server machine?

Not a problem.  The Fossil interface can also be launched via inetd or
xinetd.  An inetd configuration line sufficient to launch the Fossil
web interface looks like this:

  <verbatim>
  80 stream tcp nowait.1000 root /usr/local/bin/fossil \
  /usr/local/bin/fossil http /home/www/sample-project.fossil 
  </verbatim>

As always, you'll want to adjust the pathnames to whatever is appropriate
for your system.  The xinetd setup uses a different syntax but follows
the same idea.







|
>















>
>
>
|
>












134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
"Home" page to be a wiki page or an embedded document.

<h2>Installing On A Network Server</h2>

When you create a new Fossil project and after you have configured it
like you want it using the web interface, you can make the project
available to a distributed team by simply copying the single
repository file up to a web server that supports CGI or SCGI.  To
run Fossil as CGI, just put the
<b>sample-project.fossil</b> file in a directory where CGI scripts
have both read and write permission on the file and the directory that
contains the file, then add a CGI script that looks something like this:

  <verbatim>
  #!/usr/local/bin/fossil
  repository: /home/www/sample-project.fossil
  </verbatim>

Adjust the script above so that the paths are correct for your system,
of course, and also make sure the Fossil binary is installed on the server.
But that is <u>all</u> you have to do.  You now have everything you need to host
a distributed software development project in less than five minutes using a 
two-line CGI script.

Instructions for setting up an SCGI server are
[./scgi.wiki | available separately].

You don't have a CGI- or SCGI-capable web server running on your
server machine?
Not a problem.  The Fossil interface can also be launched via inetd or
xinetd.  An inetd configuration line sufficient to launch the Fossil
web interface looks like this:

  <verbatim>
  80 stream tcp nowait.1000 root /usr/local/bin/fossil \
  /usr/local/bin/fossil http /home/www/sample-project.fossil 
  </verbatim>

As always, you'll want to adjust the pathnames to whatever is appropriate
for your system.  The xinetd setup uses a different syntax but follows
the same idea.