Fossil SCM

Merge updates from trunk.

mistachkin 2013-01-07 17:33 tclRdOnly merge
Commit a6647539f6f7f589a03b65251204ab73e6ca3d63
+1 -1
--- src/add.c
+++ src/add.c
@@ -140,11 +140,11 @@
140140
const char *zPath, /* Tree-name of file to add. */
141141
int vid, /* Add to this VFILE */
142142
int caseSensitive /* True if filenames are case sensitive */
143143
){
144144
const char *zCollate = caseSensitive ? "binary" : "nocase";
145
- if( !file_is_simple_pathname(zPath) ){
145
+ if( !file_is_simple_pathname(zPath, 1) ){
146146
fossil_warning("filename contains illegal characters: %s", zPath);
147147
return 0;
148148
}
149149
if( db_exists("SELECT 1 FROM vfile"
150150
" WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){
151151
--- src/add.c
+++ src/add.c
@@ -140,11 +140,11 @@
140 const char *zPath, /* Tree-name of file to add. */
141 int vid, /* Add to this VFILE */
142 int caseSensitive /* True if filenames are case sensitive */
143 ){
144 const char *zCollate = caseSensitive ? "binary" : "nocase";
145 if( !file_is_simple_pathname(zPath) ){
146 fossil_warning("filename contains illegal characters: %s", zPath);
147 return 0;
148 }
149 if( db_exists("SELECT 1 FROM vfile"
150 " WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){
151
--- src/add.c
+++ src/add.c
@@ -140,11 +140,11 @@
140 const char *zPath, /* Tree-name of file to add. */
141 int vid, /* Add to this VFILE */
142 int caseSensitive /* True if filenames are case sensitive */
143 ){
144 const char *zCollate = caseSensitive ? "binary" : "nocase";
145 if( !file_is_simple_pathname(zPath, 1) ){
146 fossil_warning("filename contains illegal characters: %s", zPath);
147 return 0;
148 }
149 if( db_exists("SELECT 1 FROM vfile"
150 " WHERE pathname=%Q COLLATE %s", zPath, zCollate) ){
151
+1 -1
--- src/bisect.c
+++ src/bisect.c
@@ -123,11 +123,11 @@
123123
for(p=path_last(), n=0; p; p=p->pFrom, n++){
124124
if( p->isHidden && (nHidden || (p->pFrom && p->pFrom->isHidden)) ){
125125
nHidden++;
126126
continue;
127127
}else if( nHidden ){
128
- fossil_print(" ... eliding %d check-ins\n", nHidden);
128
+ fossil_print(" ... %d other check-ins omitted\n", nHidden);
129129
nHidden = 0;
130130
}
131131
db_bind_int(&s, ":rid", p->rid);
132132
if( db_step(&s)==SQLITE_ROW ){
133133
const char *zUuid = db_column_text(&s, 0);
134134
--- src/bisect.c
+++ src/bisect.c
@@ -123,11 +123,11 @@
123 for(p=path_last(), n=0; p; p=p->pFrom, n++){
124 if( p->isHidden && (nHidden || (p->pFrom && p->pFrom->isHidden)) ){
125 nHidden++;
126 continue;
127 }else if( nHidden ){
128 fossil_print(" ... eliding %d check-ins\n", nHidden);
129 nHidden = 0;
130 }
131 db_bind_int(&s, ":rid", p->rid);
132 if( db_step(&s)==SQLITE_ROW ){
133 const char *zUuid = db_column_text(&s, 0);
134
--- src/bisect.c
+++ src/bisect.c
@@ -123,11 +123,11 @@
123 for(p=path_last(), n=0; p; p=p->pFrom, n++){
124 if( p->isHidden && (nHidden || (p->pFrom && p->pFrom->isHidden)) ){
125 nHidden++;
126 continue;
127 }else if( nHidden ){
128 fossil_print(" ... %d other check-ins omitted\n", nHidden);
129 nHidden = 0;
130 }
131 db_bind_int(&s, ":rid", p->rid);
132 if( db_step(&s)==SQLITE_ROW ){
133 const char *zUuid = db_column_text(&s, 0);
134
+1
--- src/cgi.c
+++ src/cgi.c
@@ -21,10 +21,11 @@
2121
** formatting function and its cousins, and routines to encode and
2222
** decode strings in HTML or HTTP.
2323
*/
2424
#include "config.h"
2525
#ifdef _WIN32
26
+# include <winsock2.h>
2627
# include <ws2tcpip.h>
2728
#else
2829
# include <sys/socket.h>
2930
# include <netinet/in.h>
3031
# include <arpa/inet.h>
3132
--- src/cgi.c
+++ src/cgi.c
@@ -21,10 +21,11 @@
21 ** formatting function and its cousins, and routines to encode and
22 ** decode strings in HTML or HTTP.
23 */
24 #include "config.h"
25 #ifdef _WIN32
 
26 # include <ws2tcpip.h>
27 #else
28 # include <sys/socket.h>
29 # include <netinet/in.h>
30 # include <arpa/inet.h>
31
--- src/cgi.c
+++ src/cgi.c
@@ -21,10 +21,11 @@
21 ** formatting function and its cousins, and routines to encode and
22 ** decode strings in HTML or HTTP.
23 */
24 #include "config.h"
25 #ifdef _WIN32
26 # include <winsock2.h>
27 # include <ws2tcpip.h>
28 #else
29 # include <sys/socket.h>
30 # include <netinet/in.h>
31 # include <arpa/inet.h>
32
+2 -2
--- src/checkin.c
+++ src/checkin.c
@@ -316,11 +316,11 @@
316316
** unless overridden by the --abs-paths or --rel-paths options.
317317
**
318318
** Options:
319319
** --abs-paths Display absolute pathnames.
320320
** --dotfiles include files beginning with a dot (".")
321
-** --ignore <CSG> ignore files matching patterns from the
321
+** --ignore <CSG> ignore files matching patterns from the argument
322322
** --rel-paths Display pathnames relative to the current working
323323
** directory.
324324
**
325325
** See also: changes, clean, status
326326
*/
@@ -1144,11 +1144,11 @@
11441144
}
11451145
11461146
/* So that older versions of Fossil (that do not understand delta-
11471147
** manifest) can continue to use this repository, do not create a new
11481148
** delta-manifest unless this repository already contains one or more
1149
- ** delta-manifets, or unless the delta-manifest is explicitly requested
1149
+ ** delta-manifests, or unless the delta-manifest is explicitly requested
11501150
** by the --delta option.
11511151
*/
11521152
if( !forceDelta && !db_get_boolean("seen-delta-manifest",0) ){
11531153
forceBaseline = 1;
11541154
}
11551155
--- src/checkin.c
+++ src/checkin.c
@@ -316,11 +316,11 @@
316 ** unless overridden by the --abs-paths or --rel-paths options.
317 **
318 ** Options:
319 ** --abs-paths Display absolute pathnames.
320 ** --dotfiles include files beginning with a dot (".")
321 ** --ignore <CSG> ignore files matching patterns from the
322 ** --rel-paths Display pathnames relative to the current working
323 ** directory.
324 **
325 ** See also: changes, clean, status
326 */
@@ -1144,11 +1144,11 @@
1144 }
1145
1146 /* So that older versions of Fossil (that do not understand delta-
1147 ** manifest) can continue to use this repository, do not create a new
1148 ** delta-manifest unless this repository already contains one or more
1149 ** delta-manifets, or unless the delta-manifest is explicitly requested
1150 ** by the --delta option.
1151 */
1152 if( !forceDelta && !db_get_boolean("seen-delta-manifest",0) ){
1153 forceBaseline = 1;
1154 }
1155
--- src/checkin.c
+++ src/checkin.c
@@ -316,11 +316,11 @@
316 ** unless overridden by the --abs-paths or --rel-paths options.
317 **
318 ** Options:
319 ** --abs-paths Display absolute pathnames.
320 ** --dotfiles include files beginning with a dot (".")
321 ** --ignore <CSG> ignore files matching patterns from the argument
322 ** --rel-paths Display pathnames relative to the current working
323 ** directory.
324 **
325 ** See also: changes, clean, status
326 */
@@ -1144,11 +1144,11 @@
1144 }
1145
1146 /* So that older versions of Fossil (that do not understand delta-
1147 ** manifest) can continue to use this repository, do not create a new
1148 ** delta-manifest unless this repository already contains one or more
1149 ** delta-manifests, or unless the delta-manifest is explicitly requested
1150 ** by the --delta option.
1151 */
1152 if( !forceDelta && !db_get_boolean("seen-delta-manifest",0) ){
1153 forceBaseline = 1;
1154 }
1155
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -1422,11 +1422,10 @@
14221422
extern "C" {
14231423
#endif
14241424
14251425
14261426
1427
-
14281427
/**
14291428
This type holds the "vtbl" for type-specific operations when
14301429
working with cson_value objects.
14311430
14321431
All cson_values of a given logical type share a pointer to a single
@@ -1524,13 +1523,11 @@
15241523
*/
15251524
#define cson_value_empty_m { &cson_value_api_empty/*api*/, NULL/*value*/, 0/*refcount*/ }
15261525
/**
15271526
Empty-initialized cson_value object.
15281527
*/
1529
-extern const cson_value cson_value_empty;
1530
-
1531
-const cson_value cson_value_empty = cson_value_empty_m;
1528
+static const cson_value cson_value_empty = cson_value_empty_m;
15321529
const cson_parse_opt cson_parse_opt_empty = cson_parse_opt_empty_m;
15331530
const cson_output_opt cson_output_opt_empty = cson_output_opt_empty_m;
15341531
const cson_object_iterator cson_object_iterator_empty = cson_object_iterator_empty_m;
15351532
const cson_buffer cson_buffer_empty = cson_buffer_empty_m;
15361533
const cson_parse_info cson_parse_info_empty = cson_parse_info_empty_m;
@@ -1661,11 +1658,11 @@
16611658
{
16621659
if((m >= (void const *)&CSON_EMPTY_HOLDER)
16631660
&& ( m < (void const *)(&CSON_EMPTY_HOLDER+1)))
16641661
return 1;
16651662
else return
1666
- ((m > (void const *)&CSON_SPECIAL_VALUES[0])
1663
+ ((m >= (void const *)&CSON_SPECIAL_VALUES[0])
16671664
&& ( m < (void const *)&CSON_SPECIAL_VALUES[CSON_INTERNAL_VALUES_LENGTH]) )
16681665
? 1
16691666
: 0;
16701667
}
16711668
@@ -1711,13 +1708,13 @@
17111708
malloc/free funcs because fossil's lack of header files
17121709
means we would have to #include "main.c" here to
17131710
get the declarations.
17141711
*/
17151712
#if defined(CSON_FOSSIL_MODE)
1716
-void *fossil_malloc(size_t n);
1717
-void fossil_free(void *p);
1718
-void *fossil_realloc(void *p, size_t n);
1713
+extern void *fossil_malloc(size_t n);
1714
+extern void fossil_free(void *p);
1715
+extern void *fossil_realloc(void *p, size_t n);
17191716
# define CSON_MALLOC_IMPL fossil_malloc
17201717
# define CSON_FREE_IMPL fossil_free
17211718
# define CSON_REALLOC_IMPL fossil_realloc
17221719
#endif
17231720
@@ -4380,11 +4377,11 @@
43804377
arg MUST be a (cson_buffer*). This function appends n bytes at
43814378
position arg->used, expanding the buffer as necessary.
43824379
*/
43834380
static int cson_data_dest_cson_buffer( void * arg, void const * data_, unsigned int n )
43844381
{
4385
- if( ! arg || (n<0) ) return cson_rc.ArgError;
4382
+ if( !arg ) return cson_rc.ArgError;
43864383
else if( ! n ) return 0;
43874384
else
43884385
{
43894386
cson_buffer * sb = (cson_buffer*)arg;
43904387
char const * data = (char const *)data_;
@@ -4500,11 +4497,10 @@
45004497
cson_value * cv = NULL;
45014498
cson_object const * curObj = obj;
45024499
enum { BufSize = 128 };
45034500
char buf[BufSize];
45044501
memset( buf, 0, BufSize );
4505
- rc = cson_rc.RangeError;
45064502
45074503
while( cson_next_token( &beg, sep, &end ) )
45084504
{
45094505
if( beg == end ) break;
45104506
else
45114507
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -1422,11 +1422,10 @@
1422 extern "C" {
1423 #endif
1424
1425
1426
1427
1428 /**
1429 This type holds the "vtbl" for type-specific operations when
1430 working with cson_value objects.
1431
1432 All cson_values of a given logical type share a pointer to a single
@@ -1524,13 +1523,11 @@
1524 */
1525 #define cson_value_empty_m { &cson_value_api_empty/*api*/, NULL/*value*/, 0/*refcount*/ }
1526 /**
1527 Empty-initialized cson_value object.
1528 */
1529 extern const cson_value cson_value_empty;
1530
1531 const cson_value cson_value_empty = cson_value_empty_m;
1532 const cson_parse_opt cson_parse_opt_empty = cson_parse_opt_empty_m;
1533 const cson_output_opt cson_output_opt_empty = cson_output_opt_empty_m;
1534 const cson_object_iterator cson_object_iterator_empty = cson_object_iterator_empty_m;
1535 const cson_buffer cson_buffer_empty = cson_buffer_empty_m;
1536 const cson_parse_info cson_parse_info_empty = cson_parse_info_empty_m;
@@ -1661,11 +1658,11 @@
1661 {
1662 if((m >= (void const *)&CSON_EMPTY_HOLDER)
1663 && ( m < (void const *)(&CSON_EMPTY_HOLDER+1)))
1664 return 1;
1665 else return
1666 ((m > (void const *)&CSON_SPECIAL_VALUES[0])
1667 && ( m < (void const *)&CSON_SPECIAL_VALUES[CSON_INTERNAL_VALUES_LENGTH]) )
1668 ? 1
1669 : 0;
1670 }
1671
@@ -1711,13 +1708,13 @@
1711 malloc/free funcs because fossil's lack of header files
1712 means we would have to #include "main.c" here to
1713 get the declarations.
1714 */
1715 #if defined(CSON_FOSSIL_MODE)
1716 void *fossil_malloc(size_t n);
1717 void fossil_free(void *p);
1718 void *fossil_realloc(void *p, size_t n);
1719 # define CSON_MALLOC_IMPL fossil_malloc
1720 # define CSON_FREE_IMPL fossil_free
1721 # define CSON_REALLOC_IMPL fossil_realloc
1722 #endif
1723
@@ -4380,11 +4377,11 @@
4380 arg MUST be a (cson_buffer*). This function appends n bytes at
4381 position arg->used, expanding the buffer as necessary.
4382 */
4383 static int cson_data_dest_cson_buffer( void * arg, void const * data_, unsigned int n )
4384 {
4385 if( ! arg || (n<0) ) return cson_rc.ArgError;
4386 else if( ! n ) return 0;
4387 else
4388 {
4389 cson_buffer * sb = (cson_buffer*)arg;
4390 char const * data = (char const *)data_;
@@ -4500,11 +4497,10 @@
4500 cson_value * cv = NULL;
4501 cson_object const * curObj = obj;
4502 enum { BufSize = 128 };
4503 char buf[BufSize];
4504 memset( buf, 0, BufSize );
4505 rc = cson_rc.RangeError;
4506
4507 while( cson_next_token( &beg, sep, &end ) )
4508 {
4509 if( beg == end ) break;
4510 else
4511
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -1422,11 +1422,10 @@
1422 extern "C" {
1423 #endif
1424
1425
1426
 
1427 /**
1428 This type holds the "vtbl" for type-specific operations when
1429 working with cson_value objects.
1430
1431 All cson_values of a given logical type share a pointer to a single
@@ -1524,13 +1523,11 @@
1523 */
1524 #define cson_value_empty_m { &cson_value_api_empty/*api*/, NULL/*value*/, 0/*refcount*/ }
1525 /**
1526 Empty-initialized cson_value object.
1527 */
1528 static const cson_value cson_value_empty = cson_value_empty_m;
 
 
1529 const cson_parse_opt cson_parse_opt_empty = cson_parse_opt_empty_m;
1530 const cson_output_opt cson_output_opt_empty = cson_output_opt_empty_m;
1531 const cson_object_iterator cson_object_iterator_empty = cson_object_iterator_empty_m;
1532 const cson_buffer cson_buffer_empty = cson_buffer_empty_m;
1533 const cson_parse_info cson_parse_info_empty = cson_parse_info_empty_m;
@@ -1661,11 +1658,11 @@
1658 {
1659 if((m >= (void const *)&CSON_EMPTY_HOLDER)
1660 && ( m < (void const *)(&CSON_EMPTY_HOLDER+1)))
1661 return 1;
1662 else return
1663 ((m >= (void const *)&CSON_SPECIAL_VALUES[0])
1664 && ( m < (void const *)&CSON_SPECIAL_VALUES[CSON_INTERNAL_VALUES_LENGTH]) )
1665 ? 1
1666 : 0;
1667 }
1668
@@ -1711,13 +1708,13 @@
1708 malloc/free funcs because fossil's lack of header files
1709 means we would have to #include "main.c" here to
1710 get the declarations.
1711 */
1712 #if defined(CSON_FOSSIL_MODE)
1713 extern void *fossil_malloc(size_t n);
1714 extern void fossil_free(void *p);
1715 extern void *fossil_realloc(void *p, size_t n);
1716 # define CSON_MALLOC_IMPL fossil_malloc
1717 # define CSON_FREE_IMPL fossil_free
1718 # define CSON_REALLOC_IMPL fossil_realloc
1719 #endif
1720
@@ -4380,11 +4377,11 @@
4377 arg MUST be a (cson_buffer*). This function appends n bytes at
4378 position arg->used, expanding the buffer as necessary.
4379 */
4380 static int cson_data_dest_cson_buffer( void * arg, void const * data_, unsigned int n )
4381 {
4382 if( !arg ) return cson_rc.ArgError;
4383 else if( ! n ) return 0;
4384 else
4385 {
4386 cson_buffer * sb = (cson_buffer*)arg;
4387 char const * data = (char const *)data_;
@@ -4500,11 +4497,10 @@
4497 cson_value * cv = NULL;
4498 cson_object const * curObj = obj;
4499 enum { BufSize = 128 };
4500 char buf[BufSize];
4501 memset( buf, 0, BufSize );
 
4502
4503 while( cson_next_token( &beg, sep, &end ) )
4504 {
4505 if( beg == end ) break;
4506 else
4507
--- src/cson_amalgamation.h
+++ src/cson_amalgamation.h
@@ -1236,11 +1236,14 @@
12361236
eventually either free the value using cson_value_free() or
12371237
inserting it into a container (array or object), which transfers
12381238
ownership to the container. See the cson_value class documentation
12391239
for more details.
12401240
1241
- Returns NULL on allocation error.
1241
+ Semantically speaking this function Returns NULL on allocation
1242
+ error, but the implementation never actually allocates for this
1243
+ case. Nonetheless, it must be treated as if it were an allocated
1244
+ value.
12421245
*/
12431246
cson_value * cson_value_new_bool( char v );
12441247
12451248
12461249
/**
@@ -1927,11 +1930,12 @@
19271930
modified.
19281931
19291932
buf->mem is owned by buf and must eventually be freed by passing an
19301933
n value of 0 to this function.
19311934
1932
- buf->used is never modified by this function.
1935
+ buf->used is never modified by this function unless n is 0, in which case
1936
+ it is reset.
19331937
*/
19341938
int cson_buffer_reserve( cson_buffer * buf, cson_size_t n );
19351939
19361940
/**
19371941
Fills all bytes of the given buffer with the given character.
19381942
--- src/cson_amalgamation.h
+++ src/cson_amalgamation.h
@@ -1236,11 +1236,14 @@
1236 eventually either free the value using cson_value_free() or
1237 inserting it into a container (array or object), which transfers
1238 ownership to the container. See the cson_value class documentation
1239 for more details.
1240
1241 Returns NULL on allocation error.
 
 
 
1242 */
1243 cson_value * cson_value_new_bool( char v );
1244
1245
1246 /**
@@ -1927,11 +1930,12 @@
1927 modified.
1928
1929 buf->mem is owned by buf and must eventually be freed by passing an
1930 n value of 0 to this function.
1931
1932 buf->used is never modified by this function.
 
1933 */
1934 int cson_buffer_reserve( cson_buffer * buf, cson_size_t n );
1935
1936 /**
1937 Fills all bytes of the given buffer with the given character.
1938
--- src/cson_amalgamation.h
+++ src/cson_amalgamation.h
@@ -1236,11 +1236,14 @@
1236 eventually either free the value using cson_value_free() or
1237 inserting it into a container (array or object), which transfers
1238 ownership to the container. See the cson_value class documentation
1239 for more details.
1240
1241 Semantically speaking this function Returns NULL on allocation
1242 error, but the implementation never actually allocates for this
1243 case. Nonetheless, it must be treated as if it were an allocated
1244 value.
1245 */
1246 cson_value * cson_value_new_bool( char v );
1247
1248
1249 /**
@@ -1927,11 +1930,12 @@
1930 modified.
1931
1932 buf->mem is owned by buf and must eventually be freed by passing an
1933 n value of 0 to this function.
1934
1935 buf->used is never modified by this function unless n is 0, in which case
1936 it is reset.
1937 */
1938 int cson_buffer_reserve( cson_buffer * buf, cson_size_t n );
1939
1940 /**
1941 Fills all bytes of the given buffer with the given character.
1942
+5 -1
--- src/db.c
+++ src/db.c
@@ -1604,11 +1604,11 @@
16041604
16051605
/*
16061606
** This function registers auxiliary functions when the SQLite
16071607
** database connection is first established.
16081608
*/
1609
-LOCAL void db_connection_init(void){
1609
+void db_connection_init(void){
16101610
sqlite3_exec(g.db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
16111611
sqlite3_create_function(g.db, "user", 0, SQLITE_ANY, 0, db_sql_user, 0, 0);
16121612
sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
16131613
sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
16141614
sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
@@ -1619,10 +1619,11 @@
16191619
g.db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
16201620
);
16211621
if( g.fSqlTrace ){
16221622
sqlite3_trace(g.db, db_sql_trace, 0);
16231623
}
1624
+ re_add_sql_func(g.db);
16241625
}
16251626
16261627
/*
16271628
** Return true if the string zVal represents "true" (or "false").
16281629
*/
@@ -2116,10 +2117,13 @@
21162117
** file named .fossil-settings/PROPERTY in the checked out files, if that
21172118
** file exists.
21182119
**
21192120
** The "unset" command clears a property setting.
21202121
**
2122
+**
2123
+** access-log If enabled, record successful and failed login attempts
2124
+** in the "accesslog" table. Default: off
21212125
**
21222126
** allow-symlinks If enabled, don't follow symlinks, and instead treat
21232127
** (versionable) them as symlinks on Unix. Has no effect on Windows
21242128
** (existing links in repository created on Unix become
21252129
** plain-text files with link destination path inside).
21262130
--- src/db.c
+++ src/db.c
@@ -1604,11 +1604,11 @@
1604
1605 /*
1606 ** This function registers auxiliary functions when the SQLite
1607 ** database connection is first established.
1608 */
1609 LOCAL void db_connection_init(void){
1610 sqlite3_exec(g.db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
1611 sqlite3_create_function(g.db, "user", 0, SQLITE_ANY, 0, db_sql_user, 0, 0);
1612 sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
1613 sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
1614 sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
@@ -1619,10 +1619,11 @@
1619 g.db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
1620 );
1621 if( g.fSqlTrace ){
1622 sqlite3_trace(g.db, db_sql_trace, 0);
1623 }
 
1624 }
1625
1626 /*
1627 ** Return true if the string zVal represents "true" (or "false").
1628 */
@@ -2116,10 +2117,13 @@
2116 ** file named .fossil-settings/PROPERTY in the checked out files, if that
2117 ** file exists.
2118 **
2119 ** The "unset" command clears a property setting.
2120 **
 
 
 
2121 **
2122 ** allow-symlinks If enabled, don't follow symlinks, and instead treat
2123 ** (versionable) them as symlinks on Unix. Has no effect on Windows
2124 ** (existing links in repository created on Unix become
2125 ** plain-text files with link destination path inside).
2126
--- src/db.c
+++ src/db.c
@@ -1604,11 +1604,11 @@
1604
1605 /*
1606 ** This function registers auxiliary functions when the SQLite
1607 ** database connection is first established.
1608 */
1609 void db_connection_init(void){
1610 sqlite3_exec(g.db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
1611 sqlite3_create_function(g.db, "user", 0, SQLITE_ANY, 0, db_sql_user, 0, 0);
1612 sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
1613 sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
1614 sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
@@ -1619,10 +1619,11 @@
1619 g.db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
1620 );
1621 if( g.fSqlTrace ){
1622 sqlite3_trace(g.db, db_sql_trace, 0);
1623 }
1624 re_add_sql_func(g.db);
1625 }
1626
1627 /*
1628 ** Return true if the string zVal represents "true" (or "false").
1629 */
@@ -2116,10 +2117,13 @@
2117 ** file named .fossil-settings/PROPERTY in the checked out files, if that
2118 ** file exists.
2119 **
2120 ** The "unset" command clears a property setting.
2121 **
2122 **
2123 ** access-log If enabled, record successful and failed login attempts
2124 ** in the "accesslog" table. Default: off
2125 **
2126 ** allow-symlinks If enabled, don't follow symlinks, and instead treat
2127 ** (versionable) them as symlinks on Unix. Has no effect on Windows
2128 ** (existing links in repository created on Unix become
2129 ** plain-text files with link destination path inside).
2130
+5 -1
--- src/db.c
+++ src/db.c
@@ -1604,11 +1604,11 @@
16041604
16051605
/*
16061606
** This function registers auxiliary functions when the SQLite
16071607
** database connection is first established.
16081608
*/
1609
-LOCAL void db_connection_init(void){
1609
+void db_connection_init(void){
16101610
sqlite3_exec(g.db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
16111611
sqlite3_create_function(g.db, "user", 0, SQLITE_ANY, 0, db_sql_user, 0, 0);
16121612
sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
16131613
sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
16141614
sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
@@ -1619,10 +1619,11 @@
16191619
g.db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
16201620
);
16211621
if( g.fSqlTrace ){
16221622
sqlite3_trace(g.db, db_sql_trace, 0);
16231623
}
1624
+ re_add_sql_func(g.db);
16241625
}
16251626
16261627
/*
16271628
** Return true if the string zVal represents "true" (or "false").
16281629
*/
@@ -2116,10 +2117,13 @@
21162117
** file named .fossil-settings/PROPERTY in the checked out files, if that
21172118
** file exists.
21182119
**
21192120
** The "unset" command clears a property setting.
21202121
**
2122
+**
2123
+** access-log If enabled, record successful and failed login attempts
2124
+** in the "accesslog" table. Default: off
21212125
**
21222126
** allow-symlinks If enabled, don't follow symlinks, and instead treat
21232127
** (versionable) them as symlinks on Unix. Has no effect on Windows
21242128
** (existing links in repository created on Unix become
21252129
** plain-text files with link destination path inside).
21262130
--- src/db.c
+++ src/db.c
@@ -1604,11 +1604,11 @@
1604
1605 /*
1606 ** This function registers auxiliary functions when the SQLite
1607 ** database connection is first established.
1608 */
1609 LOCAL void db_connection_init(void){
1610 sqlite3_exec(g.db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
1611 sqlite3_create_function(g.db, "user", 0, SQLITE_ANY, 0, db_sql_user, 0, 0);
1612 sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
1613 sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
1614 sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
@@ -1619,10 +1619,11 @@
1619 g.db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
1620 );
1621 if( g.fSqlTrace ){
1622 sqlite3_trace(g.db, db_sql_trace, 0);
1623 }
 
1624 }
1625
1626 /*
1627 ** Return true if the string zVal represents "true" (or "false").
1628 */
@@ -2116,10 +2117,13 @@
2116 ** file named .fossil-settings/PROPERTY in the checked out files, if that
2117 ** file exists.
2118 **
2119 ** The "unset" command clears a property setting.
2120 **
 
 
 
2121 **
2122 ** allow-symlinks If enabled, don't follow symlinks, and instead treat
2123 ** (versionable) them as symlinks on Unix. Has no effect on Windows
2124 ** (existing links in repository created on Unix become
2125 ** plain-text files with link destination path inside).
2126
--- src/db.c
+++ src/db.c
@@ -1604,11 +1604,11 @@
1604
1605 /*
1606 ** This function registers auxiliary functions when the SQLite
1607 ** database connection is first established.
1608 */
1609 void db_connection_init(void){
1610 sqlite3_exec(g.db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
1611 sqlite3_create_function(g.db, "user", 0, SQLITE_ANY, 0, db_sql_user, 0, 0);
1612 sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
1613 sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
1614 sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
@@ -1619,10 +1619,11 @@
1619 g.db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
1620 );
1621 if( g.fSqlTrace ){
1622 sqlite3_trace(g.db, db_sql_trace, 0);
1623 }
1624 re_add_sql_func(g.db);
1625 }
1626
1627 /*
1628 ** Return true if the string zVal represents "true" (or "false").
1629 */
@@ -2116,10 +2117,13 @@
2117 ** file named .fossil-settings/PROPERTY in the checked out files, if that
2118 ** file exists.
2119 **
2120 ** The "unset" command clears a property setting.
2121 **
2122 **
2123 ** access-log If enabled, record successful and failed login attempts
2124 ** in the "accesslog" table. Default: off
2125 **
2126 ** allow-symlinks If enabled, don't follow symlinks, and instead treat
2127 ** (versionable) them as symlinks on Unix. Has no effect on Windows
2128 ** (existing links in repository created on Unix become
2129 ** plain-text files with link destination path inside).
2130
+267 -87
--- src/diff.c
+++ src/diff.c
@@ -23,11 +23,12 @@
2323
#include <assert.h>
2424
2525
2626
#if INTERFACE
2727
/*
28
-** Allowed flag parameters to the text_diff() and html_sbsdiff() functions:
28
+** Flag parameters to the text_diff() routine used to control the formatting
29
+** of the diff output.
2930
*/
3031
#define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
3132
#define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
3233
#define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */
3334
#define DIFF_SIDEBYSIDE ((u64)0x02000000) /* Generate a side-by-side diff */
@@ -37,10 +38,11 @@
3738
#define DIFF_HTML ((u64)0x10000000) /* Render for HTML */
3839
#define DIFF_LINENO ((u64)0x20000000) /* Show line numbers */
3940
#define DIFF_WS_WARNING ((u64)0x40000000) /* Warn about whitespace */
4041
#define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
4142
#define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
43
+#define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
4244
4345
/*
4446
** These error messages are shared in multiple locations. They are defined
4547
** here for consistency.
4648
*/
@@ -52,11 +54,11 @@
5254
5355
#define looks_like_binary(blob) (looks_like_utf8((blob)) == 0)
5456
#endif /* INTERFACE */
5557
5658
/*
57
-** Maximum length of a line in a text file, in bytes. (8192)
59
+** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
5860
*/
5961
#define LENGTH_MASK_SZ 13
6062
#define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
6163
6264
/*
@@ -116,10 +118,13 @@
116118
** more. If trailing whitespace is ignored, the "patch" command gets
117119
** confused by the diff output. Ticket [a9f7b23c2e376af5b0e5b]
118120
**
119121
** Return 0 if the file is binary or contains a line that is
120122
** too long.
123
+**
124
+** Profiling show that in most cases this routine consumes the bulk of
125
+** the CPU time on a diff.
121126
*/
122127
static DLine *break_into_lines(const char *z, int n, int *pnLine, int ignoreWS){
123128
int nLine, i, j, k, x;
124129
unsigned int h, h2;
125130
DLine *a;
@@ -407,34 +412,50 @@
407412
** Return true if two DLine elements are identical.
408413
*/
409414
static int same_dline(DLine *pA, DLine *pB){
410415
return pA->h==pB->h && memcmp(pA->z,pB->z,pA->h & LENGTH_MASK)==0;
411416
}
417
+
418
+/*
419
+** Return true if the regular expression *pRe matches any of the
420
+** N dlines
421
+*/
422
+static int re_dline_match(
423
+ ReCompiled *pRe, /* The regular expression to be matched */
424
+ DLine *aDLine, /* First of N DLines to compare against */
425
+ int N /* Number of DLines to check */
426
+){
427
+ while( N-- ){
428
+ if( re_match(pRe, (const unsigned char *)aDLine->z, LENGTH(aDLine)) ){
429
+ return 1;
430
+ }
431
+ aDLine++;
432
+ }
433
+ return 0;
434
+}
412435
413436
/*
414437
** Append a single line of context-diff output to pOut.
415438
*/
416439
static void appendDiffLine(
417440
Blob *pOut, /* Where to write the line of output */
418441
char cPrefix, /* One of " ", "+", or "-" */
419442
DLine *pLine, /* The line to be output */
420
- int html /* True if generating HTML. False for plain text */
443
+ int html, /* True if generating HTML. False for plain text */
444
+ ReCompiled *pRe /* Colorize only if line matches this Regex */
421445
){
422
- int i;
423446
blob_append(pOut, &cPrefix, 1);
424447
if( html ){
425448
char *zHtml;
426
- if( cPrefix=='+' ){
449
+ if( pRe && re_dline_match(pRe, pLine, 1)==0 ){
450
+ cPrefix = ' ';
451
+ }else if( cPrefix=='+' ){
427452
blob_append(pOut, "<span class=\"diffadd\">", -1);
428453
}else if( cPrefix=='-' ){
429454
blob_append(pOut, "<span class=\"diffrm\">", -1);
430455
}
431456
zHtml = htmlize(pLine->z, (pLine->h & LENGTH_MASK));
432
- for(i=0; i<strlen(zHtml); i++){
433
- char c = zHtml[i];
434
- if( c=='\t' || c=='\r' || c=='\f' ) zHtml[i] = ' ';
435
- }
436457
blob_append(pOut, zHtml, -1);
437458
fossil_free(zHtml);
438459
if( cPrefix!=' ' ){
439460
blob_append(pOut, "</span>", -1);
440461
}
@@ -444,11 +465,11 @@
444465
blob_append(pOut, "\n", 1);
445466
}
446467
447468
/*
448469
** Add two line numbers to the beginning of an output line for a context
449
-** diff. One or of the other of the two numbers might be zero, which means
470
+** diff. One or the other of the two numbers might be zero, which means
450471
** to leave that number field blank. The "html" parameter means to format
451472
** the output for HTML.
452473
*/
453474
static void appendDiffLineno(Blob *pOut, int lnA, int lnB, int html){
454475
if( html ) blob_append(pOut, "<span class=\"diffln\">", -1);
@@ -463,21 +484,19 @@
463484
blob_append(pOut, " ", 8);
464485
}
465486
if( html ) blob_append(pOut, "</span>", -1);
466487
}
467488
468
-
469489
/*
470490
** Given a raw diff p[] in which the p->aEdit[] array has been filled
471491
** in, compute a context diff into pOut.
472492
*/
473493
static void contextDiff(
474494
DContext *p, /* The difference */
475495
Blob *pOut, /* Output a context diff to here */
476
- int nContext, /* Number of lines of context */
477
- int showLn, /* Show line numbers */
478
- int html /* Render as HTML */
496
+ ReCompiled *pRe, /* Only show changes that match this regex */
497
+ u64 diffFlags /* Flags controlling the diff format */
479498
){
480499
DLine *A; /* Left side of the diff */
481500
DLine *B; /* Right side of the diff */
482501
int a = 0; /* Index of next line in A[] */
483502
int b = 0; /* Index of next line in B[] */
@@ -488,11 +507,18 @@
488507
int na, nb; /* Number of lines shown from A and B */
489508
int i, j; /* Loop counters */
490509
int m; /* Number of lines to output */
491510
int skip; /* Number of lines to skip */
492511
int nChunk = 0; /* Number of diff chunks seen so far */
512
+ int nContext; /* Number of lines of context */
513
+ int showLn; /* Show line numbers */
514
+ int html; /* Render as HTML */
515
+ int showDivider = 0; /* True to show the divider between diff blocks */
493516
517
+ nContext = diff_context_lines(diffFlags);
518
+ showLn = (diffFlags & DIFF_LINENO)!=0;
519
+ html = (diffFlags & DIFF_HTML)!=0;
494520
A = p->aFrom;
495521
B = p->aTo;
496522
R = p->aEdit;
497523
mxr = p->nEdit;
498524
while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
@@ -499,10 +525,35 @@
499525
for(r=0; r<mxr; r += 3*nr){
500526
/* Figure out how many triples to show in a single block */
501527
for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
502528
/* printf("r=%d nr=%d\n", r, nr); */
503529
530
+ /* If there is a regex, skip this block (generate no diff output)
531
+ ** if the regex matches or does not match both insert and delete.
532
+ ** Only display the block if one side matches but the other side does
533
+ ** not.
534
+ */
535
+ if( pRe ){
536
+ int hideBlock = 1;
537
+ int xa = a, xb = b;
538
+ for(i=0; hideBlock && i<nr; i++){
539
+ int c1, c2;
540
+ xa += R[r+i*3];
541
+ xb += R[r+i*3];
542
+ c1 = re_dline_match(pRe, &A[xa], R[r+i*3+1]);
543
+ c2 = re_dline_match(pRe, &B[xb], R[r+i*3+2]);
544
+ hideBlock = c1==c2;
545
+ xa += R[r+i*3+1];
546
+ xb += R[r+i*3+2];
547
+ }
548
+ if( hideBlock ){
549
+ a = xa;
550
+ b = xb;
551
+ continue;
552
+ }
553
+ }
554
+
504555
/* For the current block comprising nr triples, figure out
505556
** how many lines of A and B are to be displayed
506557
*/
507558
if( R[r]>nContext ){
508559
na = nb = nContext;
@@ -526,17 +577,18 @@
526577
na += R[r+i*3];
527578
nb += R[r+i*3];
528579
}
529580
530581
/* Show the header for this block, or if we are doing a modified
531
- ** context diff that contains line numbers, show the separate from
582
+ ** context diff that contains line numbers, show the separator from
532583
** the previous block.
533584
*/
534585
nChunk++;
535586
if( showLn ){
536
- if( r==0 ){
587
+ if( !showDivider ){
537588
/* Do not show a top divider */
589
+ showDivider = 1;
538590
}else if( html ){
539591
blob_appendf(pOut, "<span class=\"diffhr\">%.80c</span>\n", '.');
540592
blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
541593
}else{
542594
blob_appendf(pOut, "%.80c\n", '.');
@@ -559,34 +611,36 @@
559611
a += skip;
560612
b += skip;
561613
m = R[r] - skip;
562614
for(j=0; j<m; j++){
563615
if( showLn ) appendDiffLineno(pOut, a+j+1, b+j+1, html);
564
- appendDiffLine(pOut, ' ', &A[a+j], html);
616
+ appendDiffLine(pOut, ' ', &A[a+j], html, 0);
565617
}
566618
a += m;
567619
b += m;
568620
569621
/* Show the differences */
570622
for(i=0; i<nr; i++){
571623
m = R[r+i*3+1];
572624
for(j=0; j<m; j++){
625
+ char cMark = '-';
573626
if( showLn ) appendDiffLineno(pOut, a+j+1, 0, html);
574
- appendDiffLine(pOut, '-', &A[a+j], html);
627
+ if( pRe && re_dline_match(pRe, &A[a+j], 1)==0 ) cMark = ' ';
628
+ appendDiffLine(pOut, '-', &A[a+j], html, pRe);
575629
}
576630
a += m;
577631
m = R[r+i*3+2];
578632
for(j=0; j<m; j++){
579633
if( showLn ) appendDiffLineno(pOut, 0, b+j+1, html);
580
- appendDiffLine(pOut, '+', &B[b+j], html);
634
+ appendDiffLine(pOut, '+', &B[b+j], html, pRe);
581635
}
582636
b += m;
583637
if( i<nr-1 ){
584638
m = R[r+i*3+3];
585639
for(j=0; j<m; j++){
586640
if( showLn ) appendDiffLineno(pOut, a+j+1, b+j+1, html);
587
- appendDiffLine(pOut, ' ', &B[b+j], html);
641
+ appendDiffLine(pOut, ' ', &B[b+j], html, 0);
588642
}
589643
b += m;
590644
a += m;
591645
}
592646
}
@@ -595,11 +649,11 @@
595649
assert( nr==i );
596650
m = R[r+nr*3];
597651
if( m>nContext ) m = nContext;
598652
for(j=0; j<m; j++){
599653
if( showLn ) appendDiffLineno(pOut, a+j+1, b+j+1, html);
600
- appendDiffLine(pOut, ' ', &B[b+j], html);
654
+ appendDiffLine(pOut, ' ', &B[b+j], html, 0);
601655
}
602656
}
603657
}
604658
605659
/*
@@ -615,10 +669,11 @@
615669
const char *zStart; /* A <span> tag */
616670
int iEnd; /* Write </span> prior to character iEnd */
617671
int iStart2; /* Write zStart2 prior to character iStart2 */
618672
const char *zStart2; /* A <span> tag */
619673
int iEnd2; /* Write </span> prior to character iEnd2 */
674
+ ReCompiled *pRe; /* Only colorize matching lines, if not NULL */
620675
};
621676
622677
/*
623678
** Flags for sbsWriteText()
624679
*/
@@ -640,13 +695,17 @@
640695
int k; /* Cursor position */
641696
int needEndSpan = 0;
642697
const char *zIn = pLine->z;
643698
char *z = &p->zLine[p->n];
644699
int w = p->width;
700
+ int colorize = p->escHtml;
701
+ if( colorize && p->pRe && re_dline_match(p->pRe, pLine, 1)==0 ){
702
+ colorize = 0;
703
+ }
645704
for(i=j=k=0; k<w && i<n; i++, k++){
646705
char c = zIn[i];
647
- if( p->escHtml ){
706
+ if( colorize ){
648707
if( i==p->iStart ){
649708
int x = strlen(p->zStart);
650709
memcpy(z+j, p->zStart, x);
651710
j += x;
652711
needEndSpan = 1;
@@ -797,10 +856,41 @@
797856
}
798857
}
799858
}
800859
return rc;
801860
}
861
+
862
+/*
863
+** Try to shift iStart as far as possible to the left.
864
+*/
865
+static void sbsShiftLeft(SbsLine *p, const char *z){
866
+ int i, j;
867
+ while( (i=p->iStart)>0 && z[i-1]==z[i] ){
868
+ for(j=i+1; j<p->iEnd && z[j-1]==z[j]; j++){}
869
+ if( j<p->iEnd ) break;
870
+ p->iStart--;
871
+ p->iEnd--;
872
+ }
873
+}
874
+
875
+/*
876
+** Simplify iStart and iStart2:
877
+**
878
+** * If iStart is a null-change then move iStart2 into iStart
879
+** * Make sure any null-changes are in canonoical form.
880
+*/
881
+static void sbsSimplifyLine(SbsLine *p){
882
+ if( p->iStart2==p->iEnd2 ) p->iStart2 = p->iEnd2 = 0;
883
+ if( p->iStart==p->iEnd ){
884
+ p->iStart = p->iStart2;
885
+ p->iEnd = p->iEnd2;
886
+ p->zStart = p->zStart2;
887
+ p->iStart2 = 0;
888
+ p->iEnd2 = 0;
889
+ }
890
+ if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
891
+}
802892
803893
/*
804894
** Write out lines that have been edited. Adjust the highlight to cover
805895
** only those parts of the line that actually changed.
806896
*/
@@ -891,41 +981,35 @@
891981
&& textLCS(&zLeft[nPrefix], nLeftDiff, &zRight[nPrefix], nRightDiff, aLCS)
892982
){
893983
sbsWriteLineno(p, lnLeft);
894984
p->iStart = nPrefix;
895985
p->iEnd = nPrefix + aLCS[0];
896
- p->zStart = aLCS[2]==0 ? zClassRm : zClassChng;
986
+ if( aLCS[2]==0 ){
987
+ sbsShiftLeft(p, pLeft->z);
988
+ p->zStart = zClassRm;
989
+ }else{
990
+ p->zStart = zClassChng;
991
+ }
897992
p->iStart2 = nPrefix + aLCS[1];
898993
p->iEnd2 = nLeft - nSuffix;
899994
p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
900
- if( p->iStart2==p->iEnd2 ) p->iStart2 = p->iEnd2 = 0;
901
- if( p->iStart==p->iEnd ){
902
- p->iStart = p->iStart2;
903
- p->iEnd = p->iEnd2;
904
- p->zStart = p->zStart2;
905
- p->iStart2 = 0;
906
- p->iEnd2 = 0;
907
- }
908
- if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
995
+ sbsSimplifyLine(p);
909996
sbsWriteText(p, pLeft, SBS_PAD);
910997
sbsWrite(p, " | ", 3);
911998
sbsWriteLineno(p, lnRight);
912999
p->iStart = nPrefix;
9131000
p->iEnd = nPrefix + aLCS[2];
914
- p->zStart = aLCS[0]==0 ? zClassAdd : zClassChng;
1001
+ if( aLCS[0]==0 ){
1002
+ sbsShiftLeft(p, pRight->z);
1003
+ p->zStart = zClassAdd;
1004
+ }else{
1005
+ p->zStart = zClassChng;
1006
+ }
9151007
p->iStart2 = nPrefix + aLCS[3];
9161008
p->iEnd2 = nRight - nSuffix;
9171009
p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
918
- if( p->iStart2==p->iEnd2 ) p->iStart2 = p->iEnd2 = 0;
919
- if( p->iStart==p->iEnd ){
920
- p->iStart = p->iStart2;
921
- p->iEnd = p->iEnd2;
922
- p->zStart = p->zStart2;
923
- p->iStart2 = 0;
924
- p->iEnd2 = 0;
925
- }
926
- if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
1010
+ sbsSimplifyLine(p);
9271011
sbsWriteText(p, pRight, SBS_NEWLINE);
9281012
return;
9291013
}
9301014
9311015
/* If all else fails, show a single big change between left and right */
@@ -1018,13 +1102,16 @@
10181102
**
10191103
** The return value is a buffer of unsigned characters, obtained from
10201104
** fossil_malloc(). (The caller needs to free the return value using
10211105
** fossil_free().) Entries in the returned array have values as follows:
10221106
**
1023
-** 1. Delete the next line of pLeft.
1024
-** 2. The next line of pLeft changes into the next line of pRight.
1025
-** 3. Insert the next line of pRight.
1107
+** 1. Delete the next line of pLeft.
1108
+** 2. Insert the next line of pRight.
1109
+** 3. The next line of pLeft changes into the next line of pRight.
1110
+** 4. Delete one line from pLeft and add one line to pRight.
1111
+**
1112
+** Values larger than three indicate better matches.
10261113
**
10271114
** The length of the returned array will be just large enough to cause
10281115
** all elements of pLeft and pRight to be consumed.
10291116
**
10301117
** Algorithm: Wagner's minimum edit-distance algorithm, modified by
@@ -1039,27 +1126,32 @@
10391126
){
10401127
int i, j, k; /* Loop counters */
10411128
int *a; /* One row of the Wagner matrix */
10421129
int *pToFree; /* Space that needs to be freed */
10431130
unsigned char *aM; /* Wagner result matrix */
1131
+ int nMatch, iMatch; /* Number of matching lines and match score */
1132
+ int mnLen; /* MIN(nLeft, nRight) */
1133
+ int mxLen; /* MAX(nLeft, nRight) */
10441134
int aBuf[100]; /* Stack space for a[] if nRight not to big */
10451135
10461136
aM = fossil_malloc( (nLeft+1)*(nRight+1) );
10471137
if( nLeft==0 ){
1048
- memset(aM, 3, nRight);
1138
+ memset(aM, 2, nRight);
10491139
return aM;
10501140
}
10511141
if( nRight==0 ){
10521142
memset(aM, 1, nLeft);
10531143
return aM;
10541144
}
10551145
10561146
/* This algorithm is O(N**2). So if N is too big, bail out with a
10571147
** simple (but stupid and ugly) result that doesn't take too long. */
1148
+ mnLen = nLeft<nRight ? nLeft : nRight;
10581149
if( nLeft*nRight>100000 ){
1059
- memset(aM, 3, nRight);
1060
- memset(aM+nRight, 1, nLeft);
1150
+ memset(aM, 4, mnLen);
1151
+ if( nLeft>mnLen ) memset(aM+mnLen, 1, nLeft-mnLen);
1152
+ if( nRight>mnLen ) memset(aM+mnLen, 2, nRight-mnLen);
10611153
return aM;
10621154
}
10631155
10641156
if( nRight < (sizeof(aBuf)/sizeof(aBuf[0]))-1 ){
10651157
pToFree = 0;
@@ -1068,30 +1160,30 @@
10681160
a = pToFree = fossil_malloc( sizeof(a[0])*(nRight+1) );
10691161
}
10701162
10711163
/* Compute the best alignment */
10721164
for(i=0; i<=nRight; i++){
1073
- aM[i] = 3;
1165
+ aM[i] = 2;
10741166
a[i] = i*50;
10751167
}
10761168
aM[0] = 0;
10771169
for(j=1; j<=nLeft; j++){
10781170
int p = a[0];
10791171
a[0] = p+50;
10801172
aM[j*(nRight+1)] = 1;
10811173
for(i=1; i<=nRight; i++){
10821174
int m = a[i-1]+50;
1083
- int d = 3;
1175
+ int d = 2;
10841176
if( m>a[i]+50 ){
10851177
m = a[i]+50;
10861178
d = 1;
10871179
}
10881180
if( m>p ){
10891181
int score = match_dline(&aLeft[j-1], &aRight[i-1]);
1090
- if( (score<66 || (i<j+1 && i>j-1)) && m>p+score ){
1182
+ if( (score<=63 || (i<j+1 && i>j-1)) && m>p+score ){
10911183
m = p+score;
1092
- d = 2;
1184
+ d = 3 | score*4;
10931185
}
10941186
}
10951187
p = a[i];
10961188
a[i] = m;
10971189
aM[j*(nRight+1)+i] = d;
@@ -1100,28 +1192,50 @@
11001192
11011193
/* Compute the lowest-cost path back through the matrix */
11021194
i = nRight;
11031195
j = nLeft;
11041196
k = (nRight+1)*(nLeft+1)-1;
1197
+ nMatch = iMatch = 0;
11051198
while( i+j>0 ){
1106
- unsigned char c = aM[k--];
1107
- if( c==2 ){
1199
+ unsigned char c = aM[k];
1200
+ if( c>=3 ){
11081201
assert( i>0 && j>0 );
11091202
i--;
11101203
j--;
1111
- }else if( c==3 ){
1204
+ nMatch++;
1205
+ iMatch += (c>>2);
1206
+ aM[k] = 3;
1207
+ }else if( c==2 ){
11121208
assert( i>0 );
11131209
i--;
11141210
}else{
11151211
assert( j>0 );
11161212
j--;
11171213
}
1214
+ k--;
11181215
aM[k] = aM[j*(nRight+1)+i];
11191216
}
11201217
k++;
11211218
i = (nRight+1)*(nLeft+1) - k;
11221219
memmove(aM, &aM[k], i);
1220
+
1221
+ /* If:
1222
+ ** (1) the alignment is more than 25% longer than the longest side, and
1223
+ ** (2) the average match cost exceeds 15
1224
+ ** Then this is probably an alignment that will be difficult for humans
1225
+ ** to read. So instead, just show all of the right side inserted followed
1226
+ ** by all of the left side deleted.
1227
+ **
1228
+ ** The coefficients for conditions (1) and (2) above are determined by
1229
+ ** experimentation.
1230
+ */
1231
+ mxLen = nLeft>nRight ? nLeft : nRight;
1232
+ if( i*4>mxLen*5 && (nMatch==0 || iMatch/nMatch>15) ){
1233
+ memset(aM, 4, mnLen);
1234
+ if( nLeft>mnLen ) memset(aM+mnLen, 1, nLeft-mnLen);
1235
+ if( nRight>mnLen ) memset(aM+mnLen, 2, nRight-mnLen);
1236
+ }
11231237
11241238
/* Return the result */
11251239
fossil_free(pToFree);
11261240
return aM;
11271241
}
@@ -1141,13 +1255,12 @@
11411255
** in, compute a side-by-side diff into pOut.
11421256
*/
11431257
static void sbsDiff(
11441258
DContext *p, /* The computed diff */
11451259
Blob *pOut, /* Write the results here */
1146
- int nContext, /* Number of lines of context around each change */
1147
- int width, /* Width of each column of output */
1148
- int escHtml /* True to generate HTML output */
1260
+ ReCompiled *pRe, /* Only show changes that match this regex */
1261
+ u64 diffFlags /* Flags controlling the diff */
11491262
){
11501263
DLine *A; /* Left side of the diff */
11511264
DLine *B; /* Right side of the diff */
11521265
int a = 0; /* Index of next line in A[] */
11531266
int b = 0; /* Index of next line in B[] */
@@ -1159,16 +1272,20 @@
11591272
int i, j; /* Loop counters */
11601273
int m, ma, mb;/* Number of lines to output */
11611274
int skip; /* Number of lines to skip */
11621275
int nChunk = 0; /* Number of chunks of diff output seen so far */
11631276
SbsLine s; /* Output line buffer */
1277
+ int nContext; /* Lines of context above and below each change */
1278
+ int showDivider = 0; /* True to show the divider */
11641279
11651280
memset(&s, 0, sizeof(s));
1166
- s.zLine = fossil_malloc( 15*width + 200 );
1281
+ s.width = diff_width(diffFlags);
1282
+ s.zLine = fossil_malloc( 15*s.width + 200 );
11671283
if( s.zLine==0 ) return;
1168
- s.width = width;
1169
- s.escHtml = escHtml;
1284
+ nContext = diff_context_lines(diffFlags);
1285
+ s.escHtml = (diffFlags & DIFF_HTML)!=0;
1286
+ s.pRe = pRe;
11701287
s.iStart = -1;
11711288
s.iStart2 = 0;
11721289
s.iEnd = -1;
11731290
A = p->aFrom;
11741291
B = p->aTo;
@@ -1177,10 +1294,35 @@
11771294
while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
11781295
for(r=0; r<mxr; r += 3*nr){
11791296
/* Figure out how many triples to show in a single block */
11801297
for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
11811298
/* printf("r=%d nr=%d\n", r, nr); */
1299
+
1300
+ /* If there is a regex, skip this block (generate no diff output)
1301
+ ** if the regex matches or does not match both insert and delete.
1302
+ ** Only display the block if one side matches but the other side does
1303
+ ** not.
1304
+ */
1305
+ if( pRe ){
1306
+ int hideBlock = 1;
1307
+ int xa = a, xb = b;
1308
+ for(i=0; hideBlock && i<nr; i++){
1309
+ int c1, c2;
1310
+ xa += R[r+i*3];
1311
+ xb += R[r+i*3];
1312
+ c1 = re_dline_match(pRe, &A[xa], R[r+i*3+1]);
1313
+ c2 = re_dline_match(pRe, &B[xb], R[r+i*3+2]);
1314
+ hideBlock = c1==c2;
1315
+ xa += R[r+i*3+1];
1316
+ xb += R[r+i*3+2];
1317
+ }
1318
+ if( hideBlock ){
1319
+ a = xa;
1320
+ b = xb;
1321
+ continue;
1322
+ }
1323
+ }
11821324
11831325
/* For the current block comprising nr triples, figure out
11841326
** how many lines of A and B are to be displayed
11851327
*/
11861328
if( R[r]>nContext ){
@@ -1205,20 +1347,21 @@
12051347
na += R[r+i*3];
12061348
nb += R[r+i*3];
12071349
}
12081350
12091351
/* Draw the separator between blocks */
1210
- if( r>0 ){
1211
- if( escHtml ){
1352
+ if( showDivider ){
1353
+ if( s.escHtml ){
12121354
blob_appendf(pOut, "<span class=\"diffhr\">%.*c</span>\n",
1213
- width*2+16, '.');
1355
+ s.width*2+16, '.');
12141356
}else{
1215
- blob_appendf(pOut, "%.*c\n", width*2+16, '.');
1357
+ blob_appendf(pOut, "%.*c\n", s.width*2+16, '.');
12161358
}
12171359
}
1360
+ showDivider = 1;
12181361
nChunk++;
1219
- if( escHtml ){
1362
+ if( s.escHtml ){
12201363
blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
12211364
}
12221365
12231366
/* Show the initial common area */
12241367
a += skip;
@@ -1254,38 +1397,41 @@
12541397
}
12551398
12561399
alignment = sbsAlignment(&A[a], ma, &B[b], mb);
12571400
for(j=0; ma+mb>0; j++){
12581401
if( alignment[j]==1 ){
1402
+ /* Delete one line from the left */
12591403
s.n = 0;
12601404
sbsWriteLineno(&s, a);
12611405
s.iStart = 0;
12621406
s.zStart = "<span class=\"diffrm\">";
12631407
s.iEnd = s.width;
12641408
sbsWriteText(&s, &A[a], SBS_PAD);
1265
- if( escHtml ){
1409
+ if( s.escHtml ){
12661410
sbsWrite(&s, " &lt;\n", 6);
12671411
}else{
12681412
sbsWrite(&s, " <\n", 3);
12691413
}
12701414
blob_append(pOut, s.zLine, s.n);
12711415
assert( ma>0 );
12721416
ma--;
12731417
a++;
1274
- }else if( alignment[j]==2 ){
1418
+ }else if( alignment[j]==3 ){
1419
+ /* The left line is changed into the right line */
12751420
s.n = 0;
12761421
sbsWriteLineChange(&s, &A[a], a, &B[b], b);
12771422
blob_append(pOut, s.zLine, s.n);
12781423
assert( ma>0 && mb>0 );
12791424
ma--;
12801425
mb--;
12811426
a++;
12821427
b++;
1283
- }else{
1428
+ }else if( alignment[j]==2 ){
1429
+ /* Insert one line on the right */
12841430
s.n = 0;
1285
- sbsWriteSpace(&s, width + 7);
1286
- if( escHtml ){
1431
+ sbsWriteSpace(&s, s.width + 7);
1432
+ if( s.escHtml ){
12871433
sbsWrite(&s, " &gt; ", 6);
12881434
}else{
12891435
sbsWrite(&s, " > ", 3);
12901436
}
12911437
sbsWriteLineno(&s, b);
@@ -1295,11 +1441,31 @@
12951441
sbsWriteText(&s, &B[b], SBS_NEWLINE);
12961442
blob_append(pOut, s.zLine, s.n);
12971443
assert( mb>0 );
12981444
mb--;
12991445
b++;
1446
+ }else{
1447
+ /* Delete from the left and insert on the right */
1448
+ s.n = 0;
1449
+ sbsWriteLineno(&s, a);
1450
+ s.iStart = 0;
1451
+ s.zStart = "<span class=\"diffrm\">";
1452
+ s.iEnd = s.width;
1453
+ sbsWriteText(&s, &A[a], SBS_PAD);
1454
+ sbsWrite(&s, " | ", 3);
1455
+ sbsWriteLineno(&s, b);
1456
+ s.iStart = 0;
1457
+ s.zStart = "<span class=\"diffadd\">";
1458
+ s.iEnd = s.width;
1459
+ sbsWriteText(&s, &B[b], SBS_NEWLINE);
1460
+ blob_append(pOut, s.zLine, s.n);
1461
+ ma--;
1462
+ mb--;
1463
+ a++;
1464
+ b++;
13001465
}
1466
+
13011467
}
13021468
fossil_free(alignment);
13031469
if( i<nr-1 ){
13041470
m = R[r+i*3+3];
13051471
for(j=0; j<m; j++){
@@ -1723,11 +1889,11 @@
17231889
** Extract the number of lines of context from diffFlags. Supply an
17241890
** appropriate default if no context width is specified.
17251891
*/
17261892
int diff_context_lines(u64 diffFlags){
17271893
int n = diffFlags & DIFF_CONTEXT_MASK;
1728
- if( n==0 ) n = 5;
1894
+ if( n==0 && (diffFlags & DIFF_CONTEXT_EX)==0 ) n = 5;
17291895
return n;
17301896
}
17311897
17321898
/*
17331899
** Extract the width of columns for side-by-side diff. Supply an
@@ -1755,22 +1921,21 @@
17551921
*/
17561922
int *text_diff(
17571923
Blob *pA_Blob, /* FROM file */
17581924
Blob *pB_Blob, /* TO file */
17591925
Blob *pOut, /* Write diff here if not NULL */
1926
+ ReCompiled *pRe, /* Only output changes where this Regexp matches */
17601927
u64 diffFlags /* DIFF_* flags defined above */
17611928
){
17621929
int ignoreEolWs; /* Ignore whitespace at the end of lines */
1763
- int nContext; /* Amount of context to display */
17641930
DContext c;
17651931
17661932
if( diffFlags & DIFF_INVERT ){
17671933
Blob *pTemp = pA_Blob;
17681934
pA_Blob = pB_Blob;
17691935
pB_Blob = pTemp;
17701936
}
1771
- nContext = diff_context_lines(diffFlags);
17721937
ignoreEolWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0;
17731938
17741939
/* Prepare the input files */
17751940
memset(&c, 0, sizeof(c));
17761941
c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
@@ -1790,17 +1955,14 @@
17901955
diff_all(&c);
17911956
if( (diffFlags & DIFF_NOOPT)==0 ) diff_optimize(&c);
17921957
17931958
if( pOut ){
17941959
/* Compute a context or side-by-side diff into pOut */
1795
- int escHtml = (diffFlags & DIFF_HTML)!=0;
17961960
if( diffFlags & DIFF_SIDEBYSIDE ){
1797
- int width = diff_width(diffFlags);
1798
- sbsDiff(&c, pOut, nContext, width, escHtml);
1961
+ sbsDiff(&c, pOut, pRe, diffFlags);
17991962
}else{
1800
- int showLn = (diffFlags & DIFF_LINENO)!=0;
1801
- contextDiff(&c, pOut, nContext, showLn, escHtml);
1963
+ contextDiff(&c, pOut, pRe, diffFlags);
18021964
}
18031965
fossil_free(c.aFrom);
18041966
fossil_free(c.aTo);
18051967
fossil_free(c.aEdit);
18061968
return 0;
@@ -1826,19 +1988,19 @@
18261988
** --noopt Disable optimization DIFF_NOOPT
18271989
** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
18281990
** --unified Unified diff. ~DIFF_SIDEBYSIDE
18291991
** --width|-W N N character lines. DIFF_WIDTH_MASK
18301992
*/
1831
-int diff_options(void){
1993
+u64 diff_options(void){
18321994
u64 diffFlags = 0;
18331995
const char *z;
18341996
int f;
18351997
if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
18361998
if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE;
1837
- if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>0 ){
1999
+ if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){
18382000
if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
1839
- diffFlags |= f;
2001
+ diffFlags |= f + DIFF_CONTEXT_EX;
18402002
}
18412003
if( (z = find_option("width","W",1))!=0 && (f = atoi(z))>0 ){
18422004
f *= DIFF_CONTEXT_MASK+1;
18432005
if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
18442006
diffFlags |= f;
@@ -1863,34 +2025,52 @@
18632025
if( g.argc<4 ) usage("FILE1 FILE2 ...");
18642026
blob_read_from_file(&a, g.argv[2]);
18652027
for(i=3; i<g.argc; i++){
18662028
if( i>3 ) fossil_print("-------------------------------\n");
18672029
blob_read_from_file(&b, g.argv[i]);
1868
- R = text_diff(&a, &b, 0, diffFlags);
2030
+ R = text_diff(&a, &b, 0, 0, diffFlags);
18692031
for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
18702032
fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]);
18712033
}
18722034
/* free(R); */
18732035
blob_reset(&b);
18742036
}
18752037
}
18762038
18772039
/*
1878
-** COMMAND: test-udiff
2040
+** COMMAND: test-diff
2041
+**
2042
+** Usage: %fossil [options] FILE1 FILE2
18792043
**
18802044
** Print the difference between two files. The usual diff options apply.
18812045
*/
1882
-void test_udiff_cmd(void){
2046
+void test_diff_cmd(void){
18832047
Blob a, b, out;
1884
- u64 diffFlag = diff_options();
2048
+ u64 diffFlag;
2049
+ const char *zRe; /* Regex filter for diff output */
2050
+ ReCompiled *pRe = 0; /* Regex filter for diff output */
18852051
2052
+ if( find_option("tk",0,0)!=0 ){
2053
+ diff_tk("test-diff", 2);
2054
+ return;
2055
+ }
2056
+ find_option("i",0,0);
2057
+ zRe = find_option("regexp","e",1);
2058
+ if( zRe ){
2059
+ const char *zErr = re_compile(&pRe, zRe, 0);
2060
+ if( zErr ) fossil_fatal("regex error: %s", zErr);
2061
+ }
2062
+ diffFlag = diff_options();
2063
+ verify_all_options();
18862064
if( g.argc!=4 ) usage("FILE1 FILE2");
2065
+ diff_print_filenames(g.argv[2], g.argv[3], diffFlag);
18872066
blob_read_from_file(&a, g.argv[2]);
18882067
blob_read_from_file(&b, g.argv[3]);
18892068
blob_zero(&out);
1890
- text_diff(&a, &b, &out, diffFlag);
2069
+ text_diff(&a, &b, &out, pRe, diffFlag);
18912070
blob_write_to_file(&out, "-");
2071
+ re_free(pRe);
18922072
}
18932073
18942074
/**************************************************************************
18952075
** The basic difference engine is above. What follows is the annotation
18962076
** engine. Both are in the same file since they share many components.
18972077
--- src/diff.c
+++ src/diff.c
@@ -23,11 +23,12 @@
23 #include <assert.h>
24
25
26 #if INTERFACE
27 /*
28 ** Allowed flag parameters to the text_diff() and html_sbsdiff() functions:
 
29 */
30 #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
31 #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
32 #define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */
33 #define DIFF_SIDEBYSIDE ((u64)0x02000000) /* Generate a side-by-side diff */
@@ -37,10 +38,11 @@
37 #define DIFF_HTML ((u64)0x10000000) /* Render for HTML */
38 #define DIFF_LINENO ((u64)0x20000000) /* Show line numbers */
39 #define DIFF_WS_WARNING ((u64)0x40000000) /* Warn about whitespace */
40 #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
41 #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
 
42
43 /*
44 ** These error messages are shared in multiple locations. They are defined
45 ** here for consistency.
46 */
@@ -52,11 +54,11 @@
52
53 #define looks_like_binary(blob) (looks_like_utf8((blob)) == 0)
54 #endif /* INTERFACE */
55
56 /*
57 ** Maximum length of a line in a text file, in bytes. (8192)
58 */
59 #define LENGTH_MASK_SZ 13
60 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
61
62 /*
@@ -116,10 +118,13 @@
116 ** more. If trailing whitespace is ignored, the "patch" command gets
117 ** confused by the diff output. Ticket [a9f7b23c2e376af5b0e5b]
118 **
119 ** Return 0 if the file is binary or contains a line that is
120 ** too long.
 
 
 
121 */
122 static DLine *break_into_lines(const char *z, int n, int *pnLine, int ignoreWS){
123 int nLine, i, j, k, x;
124 unsigned int h, h2;
125 DLine *a;
@@ -407,34 +412,50 @@
407 ** Return true if two DLine elements are identical.
408 */
409 static int same_dline(DLine *pA, DLine *pB){
410 return pA->h==pB->h && memcmp(pA->z,pB->z,pA->h & LENGTH_MASK)==0;
411 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
412
413 /*
414 ** Append a single line of context-diff output to pOut.
415 */
416 static void appendDiffLine(
417 Blob *pOut, /* Where to write the line of output */
418 char cPrefix, /* One of " ", "+", or "-" */
419 DLine *pLine, /* The line to be output */
420 int html /* True if generating HTML. False for plain text */
 
421 ){
422 int i;
423 blob_append(pOut, &cPrefix, 1);
424 if( html ){
425 char *zHtml;
426 if( cPrefix=='+' ){
 
 
427 blob_append(pOut, "<span class=\"diffadd\">", -1);
428 }else if( cPrefix=='-' ){
429 blob_append(pOut, "<span class=\"diffrm\">", -1);
430 }
431 zHtml = htmlize(pLine->z, (pLine->h & LENGTH_MASK));
432 for(i=0; i<strlen(zHtml); i++){
433 char c = zHtml[i];
434 if( c=='\t' || c=='\r' || c=='\f' ) zHtml[i] = ' ';
435 }
436 blob_append(pOut, zHtml, -1);
437 fossil_free(zHtml);
438 if( cPrefix!=' ' ){
439 blob_append(pOut, "</span>", -1);
440 }
@@ -444,11 +465,11 @@
444 blob_append(pOut, "\n", 1);
445 }
446
447 /*
448 ** Add two line numbers to the beginning of an output line for a context
449 ** diff. One or of the other of the two numbers might be zero, which means
450 ** to leave that number field blank. The "html" parameter means to format
451 ** the output for HTML.
452 */
453 static void appendDiffLineno(Blob *pOut, int lnA, int lnB, int html){
454 if( html ) blob_append(pOut, "<span class=\"diffln\">", -1);
@@ -463,21 +484,19 @@
463 blob_append(pOut, " ", 8);
464 }
465 if( html ) blob_append(pOut, "</span>", -1);
466 }
467
468
469 /*
470 ** Given a raw diff p[] in which the p->aEdit[] array has been filled
471 ** in, compute a context diff into pOut.
472 */
473 static void contextDiff(
474 DContext *p, /* The difference */
475 Blob *pOut, /* Output a context diff to here */
476 int nContext, /* Number of lines of context */
477 int showLn, /* Show line numbers */
478 int html /* Render as HTML */
479 ){
480 DLine *A; /* Left side of the diff */
481 DLine *B; /* Right side of the diff */
482 int a = 0; /* Index of next line in A[] */
483 int b = 0; /* Index of next line in B[] */
@@ -488,11 +507,18 @@
488 int na, nb; /* Number of lines shown from A and B */
489 int i, j; /* Loop counters */
490 int m; /* Number of lines to output */
491 int skip; /* Number of lines to skip */
492 int nChunk = 0; /* Number of diff chunks seen so far */
 
 
 
 
493
 
 
 
494 A = p->aFrom;
495 B = p->aTo;
496 R = p->aEdit;
497 mxr = p->nEdit;
498 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
@@ -499,10 +525,35 @@
499 for(r=0; r<mxr; r += 3*nr){
500 /* Figure out how many triples to show in a single block */
501 for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
502 /* printf("r=%d nr=%d\n", r, nr); */
503
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504 /* For the current block comprising nr triples, figure out
505 ** how many lines of A and B are to be displayed
506 */
507 if( R[r]>nContext ){
508 na = nb = nContext;
@@ -526,17 +577,18 @@
526 na += R[r+i*3];
527 nb += R[r+i*3];
528 }
529
530 /* Show the header for this block, or if we are doing a modified
531 ** context diff that contains line numbers, show the separate from
532 ** the previous block.
533 */
534 nChunk++;
535 if( showLn ){
536 if( r==0 ){
537 /* Do not show a top divider */
 
538 }else if( html ){
539 blob_appendf(pOut, "<span class=\"diffhr\">%.80c</span>\n", '.');
540 blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
541 }else{
542 blob_appendf(pOut, "%.80c\n", '.');
@@ -559,34 +611,36 @@
559 a += skip;
560 b += skip;
561 m = R[r] - skip;
562 for(j=0; j<m; j++){
563 if( showLn ) appendDiffLineno(pOut, a+j+1, b+j+1, html);
564 appendDiffLine(pOut, ' ', &A[a+j], html);
565 }
566 a += m;
567 b += m;
568
569 /* Show the differences */
570 for(i=0; i<nr; i++){
571 m = R[r+i*3+1];
572 for(j=0; j<m; j++){
 
573 if( showLn ) appendDiffLineno(pOut, a+j+1, 0, html);
574 appendDiffLine(pOut, '-', &A[a+j], html);
 
575 }
576 a += m;
577 m = R[r+i*3+2];
578 for(j=0; j<m; j++){
579 if( showLn ) appendDiffLineno(pOut, 0, b+j+1, html);
580 appendDiffLine(pOut, '+', &B[b+j], html);
581 }
582 b += m;
583 if( i<nr-1 ){
584 m = R[r+i*3+3];
585 for(j=0; j<m; j++){
586 if( showLn ) appendDiffLineno(pOut, a+j+1, b+j+1, html);
587 appendDiffLine(pOut, ' ', &B[b+j], html);
588 }
589 b += m;
590 a += m;
591 }
592 }
@@ -595,11 +649,11 @@
595 assert( nr==i );
596 m = R[r+nr*3];
597 if( m>nContext ) m = nContext;
598 for(j=0; j<m; j++){
599 if( showLn ) appendDiffLineno(pOut, a+j+1, b+j+1, html);
600 appendDiffLine(pOut, ' ', &B[b+j], html);
601 }
602 }
603 }
604
605 /*
@@ -615,10 +669,11 @@
615 const char *zStart; /* A <span> tag */
616 int iEnd; /* Write </span> prior to character iEnd */
617 int iStart2; /* Write zStart2 prior to character iStart2 */
618 const char *zStart2; /* A <span> tag */
619 int iEnd2; /* Write </span> prior to character iEnd2 */
 
620 };
621
622 /*
623 ** Flags for sbsWriteText()
624 */
@@ -640,13 +695,17 @@
640 int k; /* Cursor position */
641 int needEndSpan = 0;
642 const char *zIn = pLine->z;
643 char *z = &p->zLine[p->n];
644 int w = p->width;
 
 
 
 
645 for(i=j=k=0; k<w && i<n; i++, k++){
646 char c = zIn[i];
647 if( p->escHtml ){
648 if( i==p->iStart ){
649 int x = strlen(p->zStart);
650 memcpy(z+j, p->zStart, x);
651 j += x;
652 needEndSpan = 1;
@@ -797,10 +856,41 @@
797 }
798 }
799 }
800 return rc;
801 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
802
803 /*
804 ** Write out lines that have been edited. Adjust the highlight to cover
805 ** only those parts of the line that actually changed.
806 */
@@ -891,41 +981,35 @@
891 && textLCS(&zLeft[nPrefix], nLeftDiff, &zRight[nPrefix], nRightDiff, aLCS)
892 ){
893 sbsWriteLineno(p, lnLeft);
894 p->iStart = nPrefix;
895 p->iEnd = nPrefix + aLCS[0];
896 p->zStart = aLCS[2]==0 ? zClassRm : zClassChng;
 
 
 
 
 
897 p->iStart2 = nPrefix + aLCS[1];
898 p->iEnd2 = nLeft - nSuffix;
899 p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
900 if( p->iStart2==p->iEnd2 ) p->iStart2 = p->iEnd2 = 0;
901 if( p->iStart==p->iEnd ){
902 p->iStart = p->iStart2;
903 p->iEnd = p->iEnd2;
904 p->zStart = p->zStart2;
905 p->iStart2 = 0;
906 p->iEnd2 = 0;
907 }
908 if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
909 sbsWriteText(p, pLeft, SBS_PAD);
910 sbsWrite(p, " | ", 3);
911 sbsWriteLineno(p, lnRight);
912 p->iStart = nPrefix;
913 p->iEnd = nPrefix + aLCS[2];
914 p->zStart = aLCS[0]==0 ? zClassAdd : zClassChng;
 
 
 
 
 
915 p->iStart2 = nPrefix + aLCS[3];
916 p->iEnd2 = nRight - nSuffix;
917 p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
918 if( p->iStart2==p->iEnd2 ) p->iStart2 = p->iEnd2 = 0;
919 if( p->iStart==p->iEnd ){
920 p->iStart = p->iStart2;
921 p->iEnd = p->iEnd2;
922 p->zStart = p->zStart2;
923 p->iStart2 = 0;
924 p->iEnd2 = 0;
925 }
926 if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
927 sbsWriteText(p, pRight, SBS_NEWLINE);
928 return;
929 }
930
931 /* If all else fails, show a single big change between left and right */
@@ -1018,13 +1102,16 @@
1018 **
1019 ** The return value is a buffer of unsigned characters, obtained from
1020 ** fossil_malloc(). (The caller needs to free the return value using
1021 ** fossil_free().) Entries in the returned array have values as follows:
1022 **
1023 ** 1. Delete the next line of pLeft.
1024 ** 2. The next line of pLeft changes into the next line of pRight.
1025 ** 3. Insert the next line of pRight.
 
 
 
1026 **
1027 ** The length of the returned array will be just large enough to cause
1028 ** all elements of pLeft and pRight to be consumed.
1029 **
1030 ** Algorithm: Wagner's minimum edit-distance algorithm, modified by
@@ -1039,27 +1126,32 @@
1039 ){
1040 int i, j, k; /* Loop counters */
1041 int *a; /* One row of the Wagner matrix */
1042 int *pToFree; /* Space that needs to be freed */
1043 unsigned char *aM; /* Wagner result matrix */
 
 
 
1044 int aBuf[100]; /* Stack space for a[] if nRight not to big */
1045
1046 aM = fossil_malloc( (nLeft+1)*(nRight+1) );
1047 if( nLeft==0 ){
1048 memset(aM, 3, nRight);
1049 return aM;
1050 }
1051 if( nRight==0 ){
1052 memset(aM, 1, nLeft);
1053 return aM;
1054 }
1055
1056 /* This algorithm is O(N**2). So if N is too big, bail out with a
1057 ** simple (but stupid and ugly) result that doesn't take too long. */
 
1058 if( nLeft*nRight>100000 ){
1059 memset(aM, 3, nRight);
1060 memset(aM+nRight, 1, nLeft);
 
1061 return aM;
1062 }
1063
1064 if( nRight < (sizeof(aBuf)/sizeof(aBuf[0]))-1 ){
1065 pToFree = 0;
@@ -1068,30 +1160,30 @@
1068 a = pToFree = fossil_malloc( sizeof(a[0])*(nRight+1) );
1069 }
1070
1071 /* Compute the best alignment */
1072 for(i=0; i<=nRight; i++){
1073 aM[i] = 3;
1074 a[i] = i*50;
1075 }
1076 aM[0] = 0;
1077 for(j=1; j<=nLeft; j++){
1078 int p = a[0];
1079 a[0] = p+50;
1080 aM[j*(nRight+1)] = 1;
1081 for(i=1; i<=nRight; i++){
1082 int m = a[i-1]+50;
1083 int d = 3;
1084 if( m>a[i]+50 ){
1085 m = a[i]+50;
1086 d = 1;
1087 }
1088 if( m>p ){
1089 int score = match_dline(&aLeft[j-1], &aRight[i-1]);
1090 if( (score<66 || (i<j+1 && i>j-1)) && m>p+score ){
1091 m = p+score;
1092 d = 2;
1093 }
1094 }
1095 p = a[i];
1096 a[i] = m;
1097 aM[j*(nRight+1)+i] = d;
@@ -1100,28 +1192,50 @@
1100
1101 /* Compute the lowest-cost path back through the matrix */
1102 i = nRight;
1103 j = nLeft;
1104 k = (nRight+1)*(nLeft+1)-1;
 
1105 while( i+j>0 ){
1106 unsigned char c = aM[k--];
1107 if( c==2 ){
1108 assert( i>0 && j>0 );
1109 i--;
1110 j--;
1111 }else if( c==3 ){
 
 
 
1112 assert( i>0 );
1113 i--;
1114 }else{
1115 assert( j>0 );
1116 j--;
1117 }
 
1118 aM[k] = aM[j*(nRight+1)+i];
1119 }
1120 k++;
1121 i = (nRight+1)*(nLeft+1) - k;
1122 memmove(aM, &aM[k], i);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1123
1124 /* Return the result */
1125 fossil_free(pToFree);
1126 return aM;
1127 }
@@ -1141,13 +1255,12 @@
1141 ** in, compute a side-by-side diff into pOut.
1142 */
1143 static void sbsDiff(
1144 DContext *p, /* The computed diff */
1145 Blob *pOut, /* Write the results here */
1146 int nContext, /* Number of lines of context around each change */
1147 int width, /* Width of each column of output */
1148 int escHtml /* True to generate HTML output */
1149 ){
1150 DLine *A; /* Left side of the diff */
1151 DLine *B; /* Right side of the diff */
1152 int a = 0; /* Index of next line in A[] */
1153 int b = 0; /* Index of next line in B[] */
@@ -1159,16 +1272,20 @@
1159 int i, j; /* Loop counters */
1160 int m, ma, mb;/* Number of lines to output */
1161 int skip; /* Number of lines to skip */
1162 int nChunk = 0; /* Number of chunks of diff output seen so far */
1163 SbsLine s; /* Output line buffer */
 
 
1164
1165 memset(&s, 0, sizeof(s));
1166 s.zLine = fossil_malloc( 15*width + 200 );
 
1167 if( s.zLine==0 ) return;
1168 s.width = width;
1169 s.escHtml = escHtml;
 
1170 s.iStart = -1;
1171 s.iStart2 = 0;
1172 s.iEnd = -1;
1173 A = p->aFrom;
1174 B = p->aTo;
@@ -1177,10 +1294,35 @@
1177 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
1178 for(r=0; r<mxr; r += 3*nr){
1179 /* Figure out how many triples to show in a single block */
1180 for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
1181 /* printf("r=%d nr=%d\n", r, nr); */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1182
1183 /* For the current block comprising nr triples, figure out
1184 ** how many lines of A and B are to be displayed
1185 */
1186 if( R[r]>nContext ){
@@ -1205,20 +1347,21 @@
1205 na += R[r+i*3];
1206 nb += R[r+i*3];
1207 }
1208
1209 /* Draw the separator between blocks */
1210 if( r>0 ){
1211 if( escHtml ){
1212 blob_appendf(pOut, "<span class=\"diffhr\">%.*c</span>\n",
1213 width*2+16, '.');
1214 }else{
1215 blob_appendf(pOut, "%.*c\n", width*2+16, '.');
1216 }
1217 }
 
1218 nChunk++;
1219 if( escHtml ){
1220 blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
1221 }
1222
1223 /* Show the initial common area */
1224 a += skip;
@@ -1254,38 +1397,41 @@
1254 }
1255
1256 alignment = sbsAlignment(&A[a], ma, &B[b], mb);
1257 for(j=0; ma+mb>0; j++){
1258 if( alignment[j]==1 ){
 
1259 s.n = 0;
1260 sbsWriteLineno(&s, a);
1261 s.iStart = 0;
1262 s.zStart = "<span class=\"diffrm\">";
1263 s.iEnd = s.width;
1264 sbsWriteText(&s, &A[a], SBS_PAD);
1265 if( escHtml ){
1266 sbsWrite(&s, " &lt;\n", 6);
1267 }else{
1268 sbsWrite(&s, " <\n", 3);
1269 }
1270 blob_append(pOut, s.zLine, s.n);
1271 assert( ma>0 );
1272 ma--;
1273 a++;
1274 }else if( alignment[j]==2 ){
 
1275 s.n = 0;
1276 sbsWriteLineChange(&s, &A[a], a, &B[b], b);
1277 blob_append(pOut, s.zLine, s.n);
1278 assert( ma>0 && mb>0 );
1279 ma--;
1280 mb--;
1281 a++;
1282 b++;
1283 }else{
 
1284 s.n = 0;
1285 sbsWriteSpace(&s, width + 7);
1286 if( escHtml ){
1287 sbsWrite(&s, " &gt; ", 6);
1288 }else{
1289 sbsWrite(&s, " > ", 3);
1290 }
1291 sbsWriteLineno(&s, b);
@@ -1295,11 +1441,31 @@
1295 sbsWriteText(&s, &B[b], SBS_NEWLINE);
1296 blob_append(pOut, s.zLine, s.n);
1297 assert( mb>0 );
1298 mb--;
1299 b++;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1300 }
 
1301 }
1302 fossil_free(alignment);
1303 if( i<nr-1 ){
1304 m = R[r+i*3+3];
1305 for(j=0; j<m; j++){
@@ -1723,11 +1889,11 @@
1723 ** Extract the number of lines of context from diffFlags. Supply an
1724 ** appropriate default if no context width is specified.
1725 */
1726 int diff_context_lines(u64 diffFlags){
1727 int n = diffFlags & DIFF_CONTEXT_MASK;
1728 if( n==0 ) n = 5;
1729 return n;
1730 }
1731
1732 /*
1733 ** Extract the width of columns for side-by-side diff. Supply an
@@ -1755,22 +1921,21 @@
1755 */
1756 int *text_diff(
1757 Blob *pA_Blob, /* FROM file */
1758 Blob *pB_Blob, /* TO file */
1759 Blob *pOut, /* Write diff here if not NULL */
 
1760 u64 diffFlags /* DIFF_* flags defined above */
1761 ){
1762 int ignoreEolWs; /* Ignore whitespace at the end of lines */
1763 int nContext; /* Amount of context to display */
1764 DContext c;
1765
1766 if( diffFlags & DIFF_INVERT ){
1767 Blob *pTemp = pA_Blob;
1768 pA_Blob = pB_Blob;
1769 pB_Blob = pTemp;
1770 }
1771 nContext = diff_context_lines(diffFlags);
1772 ignoreEolWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0;
1773
1774 /* Prepare the input files */
1775 memset(&c, 0, sizeof(c));
1776 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
@@ -1790,17 +1955,14 @@
1790 diff_all(&c);
1791 if( (diffFlags & DIFF_NOOPT)==0 ) diff_optimize(&c);
1792
1793 if( pOut ){
1794 /* Compute a context or side-by-side diff into pOut */
1795 int escHtml = (diffFlags & DIFF_HTML)!=0;
1796 if( diffFlags & DIFF_SIDEBYSIDE ){
1797 int width = diff_width(diffFlags);
1798 sbsDiff(&c, pOut, nContext, width, escHtml);
1799 }else{
1800 int showLn = (diffFlags & DIFF_LINENO)!=0;
1801 contextDiff(&c, pOut, nContext, showLn, escHtml);
1802 }
1803 fossil_free(c.aFrom);
1804 fossil_free(c.aTo);
1805 fossil_free(c.aEdit);
1806 return 0;
@@ -1826,19 +1988,19 @@
1826 ** --noopt Disable optimization DIFF_NOOPT
1827 ** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
1828 ** --unified Unified diff. ~DIFF_SIDEBYSIDE
1829 ** --width|-W N N character lines. DIFF_WIDTH_MASK
1830 */
1831 int diff_options(void){
1832 u64 diffFlags = 0;
1833 const char *z;
1834 int f;
1835 if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
1836 if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE;
1837 if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>0 ){
1838 if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
1839 diffFlags |= f;
1840 }
1841 if( (z = find_option("width","W",1))!=0 && (f = atoi(z))>0 ){
1842 f *= DIFF_CONTEXT_MASK+1;
1843 if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
1844 diffFlags |= f;
@@ -1863,34 +2025,52 @@
1863 if( g.argc<4 ) usage("FILE1 FILE2 ...");
1864 blob_read_from_file(&a, g.argv[2]);
1865 for(i=3; i<g.argc; i++){
1866 if( i>3 ) fossil_print("-------------------------------\n");
1867 blob_read_from_file(&b, g.argv[i]);
1868 R = text_diff(&a, &b, 0, diffFlags);
1869 for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
1870 fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]);
1871 }
1872 /* free(R); */
1873 blob_reset(&b);
1874 }
1875 }
1876
1877 /*
1878 ** COMMAND: test-udiff
 
 
1879 **
1880 ** Print the difference between two files. The usual diff options apply.
1881 */
1882 void test_udiff_cmd(void){
1883 Blob a, b, out;
1884 u64 diffFlag = diff_options();
 
 
1885
 
 
 
 
 
 
 
 
 
 
 
 
1886 if( g.argc!=4 ) usage("FILE1 FILE2");
 
1887 blob_read_from_file(&a, g.argv[2]);
1888 blob_read_from_file(&b, g.argv[3]);
1889 blob_zero(&out);
1890 text_diff(&a, &b, &out, diffFlag);
1891 blob_write_to_file(&out, "-");
 
1892 }
1893
1894 /**************************************************************************
1895 ** The basic difference engine is above. What follows is the annotation
1896 ** engine. Both are in the same file since they share many components.
1897
--- src/diff.c
+++ src/diff.c
@@ -23,11 +23,12 @@
23 #include <assert.h>
24
25
26 #if INTERFACE
27 /*
28 ** Flag parameters to the text_diff() routine used to control the formatting
29 ** of the diff output.
30 */
31 #define DIFF_CONTEXT_MASK ((u64)0x0000ffff) /* Lines of context. Default if 0 */
32 #define DIFF_WIDTH_MASK ((u64)0x00ff0000) /* side-by-side column width */
33 #define DIFF_IGNORE_EOLWS ((u64)0x01000000) /* Ignore end-of-line whitespace */
34 #define DIFF_SIDEBYSIDE ((u64)0x02000000) /* Generate a side-by-side diff */
@@ -37,10 +38,11 @@
38 #define DIFF_HTML ((u64)0x10000000) /* Render for HTML */
39 #define DIFF_LINENO ((u64)0x20000000) /* Show line numbers */
40 #define DIFF_WS_WARNING ((u64)0x40000000) /* Warn about whitespace */
41 #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
42 #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
43 #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
44
45 /*
46 ** These error messages are shared in multiple locations. They are defined
47 ** here for consistency.
48 */
@@ -52,11 +54,11 @@
54
55 #define looks_like_binary(blob) (looks_like_utf8((blob)) == 0)
56 #endif /* INTERFACE */
57
58 /*
59 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
60 */
61 #define LENGTH_MASK_SZ 13
62 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
63
64 /*
@@ -116,10 +118,13 @@
118 ** more. If trailing whitespace is ignored, the "patch" command gets
119 ** confused by the diff output. Ticket [a9f7b23c2e376af5b0e5b]
120 **
121 ** Return 0 if the file is binary or contains a line that is
122 ** too long.
123 **
124 ** Profiling show that in most cases this routine consumes the bulk of
125 ** the CPU time on a diff.
126 */
127 static DLine *break_into_lines(const char *z, int n, int *pnLine, int ignoreWS){
128 int nLine, i, j, k, x;
129 unsigned int h, h2;
130 DLine *a;
@@ -407,34 +412,50 @@
412 ** Return true if two DLine elements are identical.
413 */
414 static int same_dline(DLine *pA, DLine *pB){
415 return pA->h==pB->h && memcmp(pA->z,pB->z,pA->h & LENGTH_MASK)==0;
416 }
417
418 /*
419 ** Return true if the regular expression *pRe matches any of the
420 ** N dlines
421 */
422 static int re_dline_match(
423 ReCompiled *pRe, /* The regular expression to be matched */
424 DLine *aDLine, /* First of N DLines to compare against */
425 int N /* Number of DLines to check */
426 ){
427 while( N-- ){
428 if( re_match(pRe, (const unsigned char *)aDLine->z, LENGTH(aDLine)) ){
429 return 1;
430 }
431 aDLine++;
432 }
433 return 0;
434 }
435
436 /*
437 ** Append a single line of context-diff output to pOut.
438 */
439 static void appendDiffLine(
440 Blob *pOut, /* Where to write the line of output */
441 char cPrefix, /* One of " ", "+", or "-" */
442 DLine *pLine, /* The line to be output */
443 int html, /* True if generating HTML. False for plain text */
444 ReCompiled *pRe /* Colorize only if line matches this Regex */
445 ){
 
446 blob_append(pOut, &cPrefix, 1);
447 if( html ){
448 char *zHtml;
449 if( pRe && re_dline_match(pRe, pLine, 1)==0 ){
450 cPrefix = ' ';
451 }else if( cPrefix=='+' ){
452 blob_append(pOut, "<span class=\"diffadd\">", -1);
453 }else if( cPrefix=='-' ){
454 blob_append(pOut, "<span class=\"diffrm\">", -1);
455 }
456 zHtml = htmlize(pLine->z, (pLine->h & LENGTH_MASK));
 
 
 
 
457 blob_append(pOut, zHtml, -1);
458 fossil_free(zHtml);
459 if( cPrefix!=' ' ){
460 blob_append(pOut, "</span>", -1);
461 }
@@ -444,11 +465,11 @@
465 blob_append(pOut, "\n", 1);
466 }
467
468 /*
469 ** Add two line numbers to the beginning of an output line for a context
470 ** diff. One or the other of the two numbers might be zero, which means
471 ** to leave that number field blank. The "html" parameter means to format
472 ** the output for HTML.
473 */
474 static void appendDiffLineno(Blob *pOut, int lnA, int lnB, int html){
475 if( html ) blob_append(pOut, "<span class=\"diffln\">", -1);
@@ -463,21 +484,19 @@
484 blob_append(pOut, " ", 8);
485 }
486 if( html ) blob_append(pOut, "</span>", -1);
487 }
488
 
489 /*
490 ** Given a raw diff p[] in which the p->aEdit[] array has been filled
491 ** in, compute a context diff into pOut.
492 */
493 static void contextDiff(
494 DContext *p, /* The difference */
495 Blob *pOut, /* Output a context diff to here */
496 ReCompiled *pRe, /* Only show changes that match this regex */
497 u64 diffFlags /* Flags controlling the diff format */
 
498 ){
499 DLine *A; /* Left side of the diff */
500 DLine *B; /* Right side of the diff */
501 int a = 0; /* Index of next line in A[] */
502 int b = 0; /* Index of next line in B[] */
@@ -488,11 +507,18 @@
507 int na, nb; /* Number of lines shown from A and B */
508 int i, j; /* Loop counters */
509 int m; /* Number of lines to output */
510 int skip; /* Number of lines to skip */
511 int nChunk = 0; /* Number of diff chunks seen so far */
512 int nContext; /* Number of lines of context */
513 int showLn; /* Show line numbers */
514 int html; /* Render as HTML */
515 int showDivider = 0; /* True to show the divider between diff blocks */
516
517 nContext = diff_context_lines(diffFlags);
518 showLn = (diffFlags & DIFF_LINENO)!=0;
519 html = (diffFlags & DIFF_HTML)!=0;
520 A = p->aFrom;
521 B = p->aTo;
522 R = p->aEdit;
523 mxr = p->nEdit;
524 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
@@ -499,10 +525,35 @@
525 for(r=0; r<mxr; r += 3*nr){
526 /* Figure out how many triples to show in a single block */
527 for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
528 /* printf("r=%d nr=%d\n", r, nr); */
529
530 /* If there is a regex, skip this block (generate no diff output)
531 ** if the regex matches or does not match both insert and delete.
532 ** Only display the block if one side matches but the other side does
533 ** not.
534 */
535 if( pRe ){
536 int hideBlock = 1;
537 int xa = a, xb = b;
538 for(i=0; hideBlock && i<nr; i++){
539 int c1, c2;
540 xa += R[r+i*3];
541 xb += R[r+i*3];
542 c1 = re_dline_match(pRe, &A[xa], R[r+i*3+1]);
543 c2 = re_dline_match(pRe, &B[xb], R[r+i*3+2]);
544 hideBlock = c1==c2;
545 xa += R[r+i*3+1];
546 xb += R[r+i*3+2];
547 }
548 if( hideBlock ){
549 a = xa;
550 b = xb;
551 continue;
552 }
553 }
554
555 /* For the current block comprising nr triples, figure out
556 ** how many lines of A and B are to be displayed
557 */
558 if( R[r]>nContext ){
559 na = nb = nContext;
@@ -526,17 +577,18 @@
577 na += R[r+i*3];
578 nb += R[r+i*3];
579 }
580
581 /* Show the header for this block, or if we are doing a modified
582 ** context diff that contains line numbers, show the separator from
583 ** the previous block.
584 */
585 nChunk++;
586 if( showLn ){
587 if( !showDivider ){
588 /* Do not show a top divider */
589 showDivider = 1;
590 }else if( html ){
591 blob_appendf(pOut, "<span class=\"diffhr\">%.80c</span>\n", '.');
592 blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
593 }else{
594 blob_appendf(pOut, "%.80c\n", '.');
@@ -559,34 +611,36 @@
611 a += skip;
612 b += skip;
613 m = R[r] - skip;
614 for(j=0; j<m; j++){
615 if( showLn ) appendDiffLineno(pOut, a+j+1, b+j+1, html);
616 appendDiffLine(pOut, ' ', &A[a+j], html, 0);
617 }
618 a += m;
619 b += m;
620
621 /* Show the differences */
622 for(i=0; i<nr; i++){
623 m = R[r+i*3+1];
624 for(j=0; j<m; j++){
625 char cMark = '-';
626 if( showLn ) appendDiffLineno(pOut, a+j+1, 0, html);
627 if( pRe && re_dline_match(pRe, &A[a+j], 1)==0 ) cMark = ' ';
628 appendDiffLine(pOut, '-', &A[a+j], html, pRe);
629 }
630 a += m;
631 m = R[r+i*3+2];
632 for(j=0; j<m; j++){
633 if( showLn ) appendDiffLineno(pOut, 0, b+j+1, html);
634 appendDiffLine(pOut, '+', &B[b+j], html, pRe);
635 }
636 b += m;
637 if( i<nr-1 ){
638 m = R[r+i*3+3];
639 for(j=0; j<m; j++){
640 if( showLn ) appendDiffLineno(pOut, a+j+1, b+j+1, html);
641 appendDiffLine(pOut, ' ', &B[b+j], html, 0);
642 }
643 b += m;
644 a += m;
645 }
646 }
@@ -595,11 +649,11 @@
649 assert( nr==i );
650 m = R[r+nr*3];
651 if( m>nContext ) m = nContext;
652 for(j=0; j<m; j++){
653 if( showLn ) appendDiffLineno(pOut, a+j+1, b+j+1, html);
654 appendDiffLine(pOut, ' ', &B[b+j], html, 0);
655 }
656 }
657 }
658
659 /*
@@ -615,10 +669,11 @@
669 const char *zStart; /* A <span> tag */
670 int iEnd; /* Write </span> prior to character iEnd */
671 int iStart2; /* Write zStart2 prior to character iStart2 */
672 const char *zStart2; /* A <span> tag */
673 int iEnd2; /* Write </span> prior to character iEnd2 */
674 ReCompiled *pRe; /* Only colorize matching lines, if not NULL */
675 };
676
677 /*
678 ** Flags for sbsWriteText()
679 */
@@ -640,13 +695,17 @@
695 int k; /* Cursor position */
696 int needEndSpan = 0;
697 const char *zIn = pLine->z;
698 char *z = &p->zLine[p->n];
699 int w = p->width;
700 int colorize = p->escHtml;
701 if( colorize && p->pRe && re_dline_match(p->pRe, pLine, 1)==0 ){
702 colorize = 0;
703 }
704 for(i=j=k=0; k<w && i<n; i++, k++){
705 char c = zIn[i];
706 if( colorize ){
707 if( i==p->iStart ){
708 int x = strlen(p->zStart);
709 memcpy(z+j, p->zStart, x);
710 j += x;
711 needEndSpan = 1;
@@ -797,10 +856,41 @@
856 }
857 }
858 }
859 return rc;
860 }
861
862 /*
863 ** Try to shift iStart as far as possible to the left.
864 */
865 static void sbsShiftLeft(SbsLine *p, const char *z){
866 int i, j;
867 while( (i=p->iStart)>0 && z[i-1]==z[i] ){
868 for(j=i+1; j<p->iEnd && z[j-1]==z[j]; j++){}
869 if( j<p->iEnd ) break;
870 p->iStart--;
871 p->iEnd--;
872 }
873 }
874
875 /*
876 ** Simplify iStart and iStart2:
877 **
878 ** * If iStart is a null-change then move iStart2 into iStart
879 ** * Make sure any null-changes are in canonoical form.
880 */
881 static void sbsSimplifyLine(SbsLine *p){
882 if( p->iStart2==p->iEnd2 ) p->iStart2 = p->iEnd2 = 0;
883 if( p->iStart==p->iEnd ){
884 p->iStart = p->iStart2;
885 p->iEnd = p->iEnd2;
886 p->zStart = p->zStart2;
887 p->iStart2 = 0;
888 p->iEnd2 = 0;
889 }
890 if( p->iStart==p->iEnd ) p->iStart = p->iEnd = -1;
891 }
892
893 /*
894 ** Write out lines that have been edited. Adjust the highlight to cover
895 ** only those parts of the line that actually changed.
896 */
@@ -891,41 +981,35 @@
981 && textLCS(&zLeft[nPrefix], nLeftDiff, &zRight[nPrefix], nRightDiff, aLCS)
982 ){
983 sbsWriteLineno(p, lnLeft);
984 p->iStart = nPrefix;
985 p->iEnd = nPrefix + aLCS[0];
986 if( aLCS[2]==0 ){
987 sbsShiftLeft(p, pLeft->z);
988 p->zStart = zClassRm;
989 }else{
990 p->zStart = zClassChng;
991 }
992 p->iStart2 = nPrefix + aLCS[1];
993 p->iEnd2 = nLeft - nSuffix;
994 p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
995 sbsSimplifyLine(p);
 
 
 
 
 
 
 
 
996 sbsWriteText(p, pLeft, SBS_PAD);
997 sbsWrite(p, " | ", 3);
998 sbsWriteLineno(p, lnRight);
999 p->iStart = nPrefix;
1000 p->iEnd = nPrefix + aLCS[2];
1001 if( aLCS[0]==0 ){
1002 sbsShiftLeft(p, pRight->z);
1003 p->zStart = zClassAdd;
1004 }else{
1005 p->zStart = zClassChng;
1006 }
1007 p->iStart2 = nPrefix + aLCS[3];
1008 p->iEnd2 = nRight - nSuffix;
1009 p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
1010 sbsSimplifyLine(p);
 
 
 
 
 
 
 
 
1011 sbsWriteText(p, pRight, SBS_NEWLINE);
1012 return;
1013 }
1014
1015 /* If all else fails, show a single big change between left and right */
@@ -1018,13 +1102,16 @@
1102 **
1103 ** The return value is a buffer of unsigned characters, obtained from
1104 ** fossil_malloc(). (The caller needs to free the return value using
1105 ** fossil_free().) Entries in the returned array have values as follows:
1106 **
1107 ** 1. Delete the next line of pLeft.
1108 ** 2. Insert the next line of pRight.
1109 ** 3. The next line of pLeft changes into the next line of pRight.
1110 ** 4. Delete one line from pLeft and add one line to pRight.
1111 **
1112 ** Values larger than three indicate better matches.
1113 **
1114 ** The length of the returned array will be just large enough to cause
1115 ** all elements of pLeft and pRight to be consumed.
1116 **
1117 ** Algorithm: Wagner's minimum edit-distance algorithm, modified by
@@ -1039,27 +1126,32 @@
1126 ){
1127 int i, j, k; /* Loop counters */
1128 int *a; /* One row of the Wagner matrix */
1129 int *pToFree; /* Space that needs to be freed */
1130 unsigned char *aM; /* Wagner result matrix */
1131 int nMatch, iMatch; /* Number of matching lines and match score */
1132 int mnLen; /* MIN(nLeft, nRight) */
1133 int mxLen; /* MAX(nLeft, nRight) */
1134 int aBuf[100]; /* Stack space for a[] if nRight not to big */
1135
1136 aM = fossil_malloc( (nLeft+1)*(nRight+1) );
1137 if( nLeft==0 ){
1138 memset(aM, 2, nRight);
1139 return aM;
1140 }
1141 if( nRight==0 ){
1142 memset(aM, 1, nLeft);
1143 return aM;
1144 }
1145
1146 /* This algorithm is O(N**2). So if N is too big, bail out with a
1147 ** simple (but stupid and ugly) result that doesn't take too long. */
1148 mnLen = nLeft<nRight ? nLeft : nRight;
1149 if( nLeft*nRight>100000 ){
1150 memset(aM, 4, mnLen);
1151 if( nLeft>mnLen ) memset(aM+mnLen, 1, nLeft-mnLen);
1152 if( nRight>mnLen ) memset(aM+mnLen, 2, nRight-mnLen);
1153 return aM;
1154 }
1155
1156 if( nRight < (sizeof(aBuf)/sizeof(aBuf[0]))-1 ){
1157 pToFree = 0;
@@ -1068,30 +1160,30 @@
1160 a = pToFree = fossil_malloc( sizeof(a[0])*(nRight+1) );
1161 }
1162
1163 /* Compute the best alignment */
1164 for(i=0; i<=nRight; i++){
1165 aM[i] = 2;
1166 a[i] = i*50;
1167 }
1168 aM[0] = 0;
1169 for(j=1; j<=nLeft; j++){
1170 int p = a[0];
1171 a[0] = p+50;
1172 aM[j*(nRight+1)] = 1;
1173 for(i=1; i<=nRight; i++){
1174 int m = a[i-1]+50;
1175 int d = 2;
1176 if( m>a[i]+50 ){
1177 m = a[i]+50;
1178 d = 1;
1179 }
1180 if( m>p ){
1181 int score = match_dline(&aLeft[j-1], &aRight[i-1]);
1182 if( (score<=63 || (i<j+1 && i>j-1)) && m>p+score ){
1183 m = p+score;
1184 d = 3 | score*4;
1185 }
1186 }
1187 p = a[i];
1188 a[i] = m;
1189 aM[j*(nRight+1)+i] = d;
@@ -1100,28 +1192,50 @@
1192
1193 /* Compute the lowest-cost path back through the matrix */
1194 i = nRight;
1195 j = nLeft;
1196 k = (nRight+1)*(nLeft+1)-1;
1197 nMatch = iMatch = 0;
1198 while( i+j>0 ){
1199 unsigned char c = aM[k];
1200 if( c>=3 ){
1201 assert( i>0 && j>0 );
1202 i--;
1203 j--;
1204 nMatch++;
1205 iMatch += (c>>2);
1206 aM[k] = 3;
1207 }else if( c==2 ){
1208 assert( i>0 );
1209 i--;
1210 }else{
1211 assert( j>0 );
1212 j--;
1213 }
1214 k--;
1215 aM[k] = aM[j*(nRight+1)+i];
1216 }
1217 k++;
1218 i = (nRight+1)*(nLeft+1) - k;
1219 memmove(aM, &aM[k], i);
1220
1221 /* If:
1222 ** (1) the alignment is more than 25% longer than the longest side, and
1223 ** (2) the average match cost exceeds 15
1224 ** Then this is probably an alignment that will be difficult for humans
1225 ** to read. So instead, just show all of the right side inserted followed
1226 ** by all of the left side deleted.
1227 **
1228 ** The coefficients for conditions (1) and (2) above are determined by
1229 ** experimentation.
1230 */
1231 mxLen = nLeft>nRight ? nLeft : nRight;
1232 if( i*4>mxLen*5 && (nMatch==0 || iMatch/nMatch>15) ){
1233 memset(aM, 4, mnLen);
1234 if( nLeft>mnLen ) memset(aM+mnLen, 1, nLeft-mnLen);
1235 if( nRight>mnLen ) memset(aM+mnLen, 2, nRight-mnLen);
1236 }
1237
1238 /* Return the result */
1239 fossil_free(pToFree);
1240 return aM;
1241 }
@@ -1141,13 +1255,12 @@
1255 ** in, compute a side-by-side diff into pOut.
1256 */
1257 static void sbsDiff(
1258 DContext *p, /* The computed diff */
1259 Blob *pOut, /* Write the results here */
1260 ReCompiled *pRe, /* Only show changes that match this regex */
1261 u64 diffFlags /* Flags controlling the diff */
 
1262 ){
1263 DLine *A; /* Left side of the diff */
1264 DLine *B; /* Right side of the diff */
1265 int a = 0; /* Index of next line in A[] */
1266 int b = 0; /* Index of next line in B[] */
@@ -1159,16 +1272,20 @@
1272 int i, j; /* Loop counters */
1273 int m, ma, mb;/* Number of lines to output */
1274 int skip; /* Number of lines to skip */
1275 int nChunk = 0; /* Number of chunks of diff output seen so far */
1276 SbsLine s; /* Output line buffer */
1277 int nContext; /* Lines of context above and below each change */
1278 int showDivider = 0; /* True to show the divider */
1279
1280 memset(&s, 0, sizeof(s));
1281 s.width = diff_width(diffFlags);
1282 s.zLine = fossil_malloc( 15*s.width + 200 );
1283 if( s.zLine==0 ) return;
1284 nContext = diff_context_lines(diffFlags);
1285 s.escHtml = (diffFlags & DIFF_HTML)!=0;
1286 s.pRe = pRe;
1287 s.iStart = -1;
1288 s.iStart2 = 0;
1289 s.iEnd = -1;
1290 A = p->aFrom;
1291 B = p->aTo;
@@ -1177,10 +1294,35 @@
1294 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
1295 for(r=0; r<mxr; r += 3*nr){
1296 /* Figure out how many triples to show in a single block */
1297 for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
1298 /* printf("r=%d nr=%d\n", r, nr); */
1299
1300 /* If there is a regex, skip this block (generate no diff output)
1301 ** if the regex matches or does not match both insert and delete.
1302 ** Only display the block if one side matches but the other side does
1303 ** not.
1304 */
1305 if( pRe ){
1306 int hideBlock = 1;
1307 int xa = a, xb = b;
1308 for(i=0; hideBlock && i<nr; i++){
1309 int c1, c2;
1310 xa += R[r+i*3];
1311 xb += R[r+i*3];
1312 c1 = re_dline_match(pRe, &A[xa], R[r+i*3+1]);
1313 c2 = re_dline_match(pRe, &B[xb], R[r+i*3+2]);
1314 hideBlock = c1==c2;
1315 xa += R[r+i*3+1];
1316 xb += R[r+i*3+2];
1317 }
1318 if( hideBlock ){
1319 a = xa;
1320 b = xb;
1321 continue;
1322 }
1323 }
1324
1325 /* For the current block comprising nr triples, figure out
1326 ** how many lines of A and B are to be displayed
1327 */
1328 if( R[r]>nContext ){
@@ -1205,20 +1347,21 @@
1347 na += R[r+i*3];
1348 nb += R[r+i*3];
1349 }
1350
1351 /* Draw the separator between blocks */
1352 if( showDivider ){
1353 if( s.escHtml ){
1354 blob_appendf(pOut, "<span class=\"diffhr\">%.*c</span>\n",
1355 s.width*2+16, '.');
1356 }else{
1357 blob_appendf(pOut, "%.*c\n", s.width*2+16, '.');
1358 }
1359 }
1360 showDivider = 1;
1361 nChunk++;
1362 if( s.escHtml ){
1363 blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
1364 }
1365
1366 /* Show the initial common area */
1367 a += skip;
@@ -1254,38 +1397,41 @@
1397 }
1398
1399 alignment = sbsAlignment(&A[a], ma, &B[b], mb);
1400 for(j=0; ma+mb>0; j++){
1401 if( alignment[j]==1 ){
1402 /* Delete one line from the left */
1403 s.n = 0;
1404 sbsWriteLineno(&s, a);
1405 s.iStart = 0;
1406 s.zStart = "<span class=\"diffrm\">";
1407 s.iEnd = s.width;
1408 sbsWriteText(&s, &A[a], SBS_PAD);
1409 if( s.escHtml ){
1410 sbsWrite(&s, " &lt;\n", 6);
1411 }else{
1412 sbsWrite(&s, " <\n", 3);
1413 }
1414 blob_append(pOut, s.zLine, s.n);
1415 assert( ma>0 );
1416 ma--;
1417 a++;
1418 }else if( alignment[j]==3 ){
1419 /* The left line is changed into the right line */
1420 s.n = 0;
1421 sbsWriteLineChange(&s, &A[a], a, &B[b], b);
1422 blob_append(pOut, s.zLine, s.n);
1423 assert( ma>0 && mb>0 );
1424 ma--;
1425 mb--;
1426 a++;
1427 b++;
1428 }else if( alignment[j]==2 ){
1429 /* Insert one line on the right */
1430 s.n = 0;
1431 sbsWriteSpace(&s, s.width + 7);
1432 if( s.escHtml ){
1433 sbsWrite(&s, " &gt; ", 6);
1434 }else{
1435 sbsWrite(&s, " > ", 3);
1436 }
1437 sbsWriteLineno(&s, b);
@@ -1295,11 +1441,31 @@
1441 sbsWriteText(&s, &B[b], SBS_NEWLINE);
1442 blob_append(pOut, s.zLine, s.n);
1443 assert( mb>0 );
1444 mb--;
1445 b++;
1446 }else{
1447 /* Delete from the left and insert on the right */
1448 s.n = 0;
1449 sbsWriteLineno(&s, a);
1450 s.iStart = 0;
1451 s.zStart = "<span class=\"diffrm\">";
1452 s.iEnd = s.width;
1453 sbsWriteText(&s, &A[a], SBS_PAD);
1454 sbsWrite(&s, " | ", 3);
1455 sbsWriteLineno(&s, b);
1456 s.iStart = 0;
1457 s.zStart = "<span class=\"diffadd\">";
1458 s.iEnd = s.width;
1459 sbsWriteText(&s, &B[b], SBS_NEWLINE);
1460 blob_append(pOut, s.zLine, s.n);
1461 ma--;
1462 mb--;
1463 a++;
1464 b++;
1465 }
1466
1467 }
1468 fossil_free(alignment);
1469 if( i<nr-1 ){
1470 m = R[r+i*3+3];
1471 for(j=0; j<m; j++){
@@ -1723,11 +1889,11 @@
1889 ** Extract the number of lines of context from diffFlags. Supply an
1890 ** appropriate default if no context width is specified.
1891 */
1892 int diff_context_lines(u64 diffFlags){
1893 int n = diffFlags & DIFF_CONTEXT_MASK;
1894 if( n==0 && (diffFlags & DIFF_CONTEXT_EX)==0 ) n = 5;
1895 return n;
1896 }
1897
1898 /*
1899 ** Extract the width of columns for side-by-side diff. Supply an
@@ -1755,22 +1921,21 @@
1921 */
1922 int *text_diff(
1923 Blob *pA_Blob, /* FROM file */
1924 Blob *pB_Blob, /* TO file */
1925 Blob *pOut, /* Write diff here if not NULL */
1926 ReCompiled *pRe, /* Only output changes where this Regexp matches */
1927 u64 diffFlags /* DIFF_* flags defined above */
1928 ){
1929 int ignoreEolWs; /* Ignore whitespace at the end of lines */
 
1930 DContext c;
1931
1932 if( diffFlags & DIFF_INVERT ){
1933 Blob *pTemp = pA_Blob;
1934 pA_Blob = pB_Blob;
1935 pB_Blob = pTemp;
1936 }
 
1937 ignoreEolWs = (diffFlags & DIFF_IGNORE_EOLWS)!=0;
1938
1939 /* Prepare the input files */
1940 memset(&c, 0, sizeof(c));
1941 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
@@ -1790,17 +1955,14 @@
1955 diff_all(&c);
1956 if( (diffFlags & DIFF_NOOPT)==0 ) diff_optimize(&c);
1957
1958 if( pOut ){
1959 /* Compute a context or side-by-side diff into pOut */
 
1960 if( diffFlags & DIFF_SIDEBYSIDE ){
1961 sbsDiff(&c, pOut, pRe, diffFlags);
 
1962 }else{
1963 contextDiff(&c, pOut, pRe, diffFlags);
 
1964 }
1965 fossil_free(c.aFrom);
1966 fossil_free(c.aTo);
1967 fossil_free(c.aEdit);
1968 return 0;
@@ -1826,19 +1988,19 @@
1988 ** --noopt Disable optimization DIFF_NOOPT
1989 ** --side-by-side|-y Side-by-side diff. DIFF_SIDEBYSIDE
1990 ** --unified Unified diff. ~DIFF_SIDEBYSIDE
1991 ** --width|-W N N character lines. DIFF_WIDTH_MASK
1992 */
1993 u64 diff_options(void){
1994 u64 diffFlags = 0;
1995 const char *z;
1996 int f;
1997 if( find_option("side-by-side","y",0)!=0 ) diffFlags |= DIFF_SIDEBYSIDE;
1998 if( find_option("unified",0,0)!=0 ) diffFlags &= ~DIFF_SIDEBYSIDE;
1999 if( (z = find_option("context","c",1))!=0 && (f = atoi(z))>=0 ){
2000 if( f > DIFF_CONTEXT_MASK ) f = DIFF_CONTEXT_MASK;
2001 diffFlags |= f + DIFF_CONTEXT_EX;
2002 }
2003 if( (z = find_option("width","W",1))!=0 && (f = atoi(z))>0 ){
2004 f *= DIFF_CONTEXT_MASK+1;
2005 if( f > DIFF_WIDTH_MASK ) f = DIFF_CONTEXT_MASK;
2006 diffFlags |= f;
@@ -1863,34 +2025,52 @@
2025 if( g.argc<4 ) usage("FILE1 FILE2 ...");
2026 blob_read_from_file(&a, g.argv[2]);
2027 for(i=3; i<g.argc; i++){
2028 if( i>3 ) fossil_print("-------------------------------\n");
2029 blob_read_from_file(&b, g.argv[i]);
2030 R = text_diff(&a, &b, 0, 0, diffFlags);
2031 for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
2032 fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]);
2033 }
2034 /* free(R); */
2035 blob_reset(&b);
2036 }
2037 }
2038
2039 /*
2040 ** COMMAND: test-diff
2041 **
2042 ** Usage: %fossil [options] FILE1 FILE2
2043 **
2044 ** Print the difference between two files. The usual diff options apply.
2045 */
2046 void test_diff_cmd(void){
2047 Blob a, b, out;
2048 u64 diffFlag;
2049 const char *zRe; /* Regex filter for diff output */
2050 ReCompiled *pRe = 0; /* Regex filter for diff output */
2051
2052 if( find_option("tk",0,0)!=0 ){
2053 diff_tk("test-diff", 2);
2054 return;
2055 }
2056 find_option("i",0,0);
2057 zRe = find_option("regexp","e",1);
2058 if( zRe ){
2059 const char *zErr = re_compile(&pRe, zRe, 0);
2060 if( zErr ) fossil_fatal("regex error: %s", zErr);
2061 }
2062 diffFlag = diff_options();
2063 verify_all_options();
2064 if( g.argc!=4 ) usage("FILE1 FILE2");
2065 diff_print_filenames(g.argv[2], g.argv[3], diffFlag);
2066 blob_read_from_file(&a, g.argv[2]);
2067 blob_read_from_file(&b, g.argv[3]);
2068 blob_zero(&out);
2069 text_diff(&a, &b, &out, pRe, diffFlag);
2070 blob_write_to_file(&out, "-");
2071 re_free(pRe);
2072 }
2073
2074 /**************************************************************************
2075 ** The basic difference engine is above. What follows is the annotation
2076 ** engine. Both are in the same file since they share many components.
2077
+9 -3
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -109,11 +109,11 @@
109109
if( blob_compare(pFile1, &file2) ){
110110
fossil_print("CHANGED %s\n", zName);
111111
}
112112
}else{
113113
blob_zero(&out);
114
- text_diff(pFile1, &file2, &out, diffFlags);
114
+ text_diff(pFile1, &file2, &out, 0, diffFlags);
115115
if( blob_size(&out) ){
116116
diff_print_filenames(zName, zName2, diffFlags);
117117
fossil_print("%s\n", blob_str(&out));
118118
}
119119
blob_reset(&out);
@@ -210,11 +210,11 @@
210210
if( diffFlags & DIFF_BRIEF ) return;
211211
if( zDiffCmd==0 ){
212212
Blob out; /* Diff output text */
213213
214214
blob_zero(&out);
215
- text_diff(pFile1, pFile2, &out, diffFlags);
215
+ text_diff(pFile1, pFile2, &out, 0, diffFlags);
216216
diff_print_filenames(zName, zName, diffFlags);
217217
fossil_print("%s\n", blob_str(&out));
218218
219219
/* Release memory resources */
220220
blob_reset(&out);
@@ -659,12 +659,18 @@
659659
char *zCmd;
660660
blob_zero(&script);
661661
blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i",
662662
g.nameOfExe, zSubCmd);
663663
for(i=firstArg; i<g.argc; i++){
664
+ const char *z = g.argv[i];
665
+ if( z[0]=='-' ){
666
+ if( strglob("*-html",z) ) continue;
667
+ if( strglob("*-y",z) ) continue;
668
+ if( strglob("*-i",z) ) continue;
669
+ }
664670
blob_append(&script, " ", 1);
665
- shell_escape(&script, g.argv[i]);
671
+ shell_escape(&script, z);
666672
}
667673
blob_appendf(&script, "}\n%s", zDiffScript);
668674
zTempFile = write_blob_to_temp_file(&script);
669675
zCmd = mprintf("tclsh \"%s\"", zTempFile);
670676
fossil_system(zCmd);
671677
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -109,11 +109,11 @@
109 if( blob_compare(pFile1, &file2) ){
110 fossil_print("CHANGED %s\n", zName);
111 }
112 }else{
113 blob_zero(&out);
114 text_diff(pFile1, &file2, &out, diffFlags);
115 if( blob_size(&out) ){
116 diff_print_filenames(zName, zName2, diffFlags);
117 fossil_print("%s\n", blob_str(&out));
118 }
119 blob_reset(&out);
@@ -210,11 +210,11 @@
210 if( diffFlags & DIFF_BRIEF ) return;
211 if( zDiffCmd==0 ){
212 Blob out; /* Diff output text */
213
214 blob_zero(&out);
215 text_diff(pFile1, pFile2, &out, diffFlags);
216 diff_print_filenames(zName, zName, diffFlags);
217 fossil_print("%s\n", blob_str(&out));
218
219 /* Release memory resources */
220 blob_reset(&out);
@@ -659,12 +659,18 @@
659 char *zCmd;
660 blob_zero(&script);
661 blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i",
662 g.nameOfExe, zSubCmd);
663 for(i=firstArg; i<g.argc; i++){
 
 
 
 
 
 
664 blob_append(&script, " ", 1);
665 shell_escape(&script, g.argv[i]);
666 }
667 blob_appendf(&script, "}\n%s", zDiffScript);
668 zTempFile = write_blob_to_temp_file(&script);
669 zCmd = mprintf("tclsh \"%s\"", zTempFile);
670 fossil_system(zCmd);
671
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -109,11 +109,11 @@
109 if( blob_compare(pFile1, &file2) ){
110 fossil_print("CHANGED %s\n", zName);
111 }
112 }else{
113 blob_zero(&out);
114 text_diff(pFile1, &file2, &out, 0, diffFlags);
115 if( blob_size(&out) ){
116 diff_print_filenames(zName, zName2, diffFlags);
117 fossil_print("%s\n", blob_str(&out));
118 }
119 blob_reset(&out);
@@ -210,11 +210,11 @@
210 if( diffFlags & DIFF_BRIEF ) return;
211 if( zDiffCmd==0 ){
212 Blob out; /* Diff output text */
213
214 blob_zero(&out);
215 text_diff(pFile1, pFile2, &out, 0, diffFlags);
216 diff_print_filenames(zName, zName, diffFlags);
217 fossil_print("%s\n", blob_str(&out));
218
219 /* Release memory resources */
220 blob_reset(&out);
@@ -659,12 +659,18 @@
659 char *zCmd;
660 blob_zero(&script);
661 blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i",
662 g.nameOfExe, zSubCmd);
663 for(i=firstArg; i<g.argc; i++){
664 const char *z = g.argv[i];
665 if( z[0]=='-' ){
666 if( strglob("*-html",z) ) continue;
667 if( strglob("*-y",z) ) continue;
668 if( strglob("*-i",z) ) continue;
669 }
670 blob_append(&script, " ", 1);
671 shell_escape(&script, z);
672 }
673 blob_appendf(&script, "}\n%s", zDiffScript);
674 zTempFile = write_blob_to_temp_file(&script);
675 zCmd = mprintf("tclsh \"%s\"", zTempFile);
676 fossil_system(zCmd);
677
+2 -2
--- src/doc.c
+++ src/doc.c
@@ -380,15 +380,15 @@
380380
g.zPath = mprintf("%s/%s", g.zPath, zName);
381381
memcpy(zBaseline, zName, i);
382382
zBaseline[i] = 0;
383383
zName += i;
384384
while( zName[0]=='/' ){ zName++; }
385
- if( !file_is_simple_pathname(zName) ){
385
+ if( !file_is_simple_pathname(zName, 1) ){
386386
int n = strlen(zName);
387387
if( n>0 && zName[n-1]=='/' ){
388388
zName = mprintf("%sindex.html", zName);
389
- if( !file_is_simple_pathname(zName) ){
389
+ if( !file_is_simple_pathname(zName, 1) ){
390390
goto doc_not_found;
391391
}
392392
}else{
393393
goto doc_not_found;
394394
}
395395
--- src/doc.c
+++ src/doc.c
@@ -380,15 +380,15 @@
380 g.zPath = mprintf("%s/%s", g.zPath, zName);
381 memcpy(zBaseline, zName, i);
382 zBaseline[i] = 0;
383 zName += i;
384 while( zName[0]=='/' ){ zName++; }
385 if( !file_is_simple_pathname(zName) ){
386 int n = strlen(zName);
387 if( n>0 && zName[n-1]=='/' ){
388 zName = mprintf("%sindex.html", zName);
389 if( !file_is_simple_pathname(zName) ){
390 goto doc_not_found;
391 }
392 }else{
393 goto doc_not_found;
394 }
395
--- src/doc.c
+++ src/doc.c
@@ -380,15 +380,15 @@
380 g.zPath = mprintf("%s/%s", g.zPath, zName);
381 memcpy(zBaseline, zName, i);
382 zBaseline[i] = 0;
383 zName += i;
384 while( zName[0]=='/' ){ zName++; }
385 if( !file_is_simple_pathname(zName, 1) ){
386 int n = strlen(zName);
387 if( n>0 && zName[n-1]=='/' ){
388 zName = mprintf("%sindex.html", zName);
389 if( !file_is_simple_pathname(zName, 1) ){
390 goto doc_not_found;
391 }
392 }else{
393 goto doc_not_found;
394 }
395
+31 -24
--- src/file.c
+++ src/file.c
@@ -487,43 +487,50 @@
487487
** * Does not contain any path element named "." or ".."
488488
** * Does not contain any of these characters in the path: "\"
489489
** * Does not end with "/".
490490
** * Does not contain two or more "/" characters in a row.
491491
** * Contains at least one character
492
+**
493
+** Invalid UTF8 characters result in a false return if bStrictUtf8 is
494
+** true. If bStrictUtf8 is false, invalid UTF8 characters are silently
495
+** ignored.
492496
*/
493
-int file_is_simple_pathname(const char *z){
497
+int file_is_simple_pathname(const char *z, int bStrictUtf8){
494498
int i;
495499
char c = z[0];
500
+ char maskNonAscii = bStrictUtf8 ? 0x80 : 0x00;
496501
if( c=='/' || c==0 ) return 0;
497502
if( c=='.' ){
498503
if( z[1]=='/' || z[1]==0 ) return 0;
499504
if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
500505
}
501506
for(i=0; (c=z[i])!=0; i++){
502
- if( (c & 0xf0) == 0xf0 ) {
503
- /* Unicode characters > U+FFFF are not supported.
504
- * Windows XP and earlier cannot handle them.
505
- */
506
- return 0;
507
- }
508
- if( (c & 0xf0) == 0xe0 ) {
509
- /* This is a 3-byte UTF-8 character */
510
- if ( (c & 0xfe) == 0xee ){
511
- /* Range U+E000 - U+FFFF (Starting with 0xee or 0xef in UTF-8 ) */
512
- if ( (c & 1) && ((z[i+1] & 0xff) >= 0xa4) ){
513
- /* But exclude U+F900 - U+FFFF (0xef followed by byte >= 0xa4),
514
- * which contain valid characters. */
515
- continue;
516
- }
517
- /* Unicode character in the range U+E000 - U+F8FF are for
518
- * private use, they shouldn't occur in filenames. */
519
- return 0;
520
- }
521
- if( ((c & 0xff) == 0xed) && ((z[i+1] & 0xe0) == 0xa0) ){
522
- /* Unicode character in the range U+D800 - U+DFFF are for
523
- * surrogate pairs, they shouldn't occur in filenames. */
524
- return 0;
507
+ if( c & maskNonAscii ){
508
+ if( (c & 0xf0) == 0xf0 ) {
509
+ /* Unicode characters > U+FFFF are not supported.
510
+ * Windows XP and earlier cannot handle them.
511
+ */
512
+ return 0;
513
+ }
514
+ if( (c & 0xf0) == 0xe0 ) {
515
+ /* This is a 3-byte UTF-8 character */
516
+ if ( (c & 0xfe) == 0xee ){
517
+ /* Range U+E000 - U+FFFF (Starting with 0xee or 0xef in UTF-8 ) */
518
+ if ( (c & 1) && ((z[i+1] & 0xff) >= 0xa4) ){
519
+ /* But exclude U+F900 - U+FFFF (0xef followed by byte >= 0xa4),
520
+ * which contain valid characters. */
521
+ continue;
522
+ }
523
+ /* Unicode character in the range U+E000 - U+F8FF are for
524
+ * private use, they shouldn't occur in filenames. */
525
+ return 0;
526
+ }
527
+ if( ((c & 0xff) == 0xed) && ((z[i+1] & 0xe0) == 0xa0) ){
528
+ /* Unicode character in the range U+D800 - U+DFFF are for
529
+ * surrogate pairs, they shouldn't occur in filenames. */
530
+ return 0;
531
+ }
525532
}
526533
}
527534
if( c=='\\' ){
528535
return 0;
529536
}
530537
--- src/file.c
+++ src/file.c
@@ -487,43 +487,50 @@
487 ** * Does not contain any path element named "." or ".."
488 ** * Does not contain any of these characters in the path: "\"
489 ** * Does not end with "/".
490 ** * Does not contain two or more "/" characters in a row.
491 ** * Contains at least one character
 
 
 
 
492 */
493 int file_is_simple_pathname(const char *z){
494 int i;
495 char c = z[0];
 
496 if( c=='/' || c==0 ) return 0;
497 if( c=='.' ){
498 if( z[1]=='/' || z[1]==0 ) return 0;
499 if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
500 }
501 for(i=0; (c=z[i])!=0; i++){
502 if( (c & 0xf0) == 0xf0 ) {
503 /* Unicode characters > U+FFFF are not supported.
504 * Windows XP and earlier cannot handle them.
505 */
506 return 0;
507 }
508 if( (c & 0xf0) == 0xe0 ) {
509 /* This is a 3-byte UTF-8 character */
510 if ( (c & 0xfe) == 0xee ){
511 /* Range U+E000 - U+FFFF (Starting with 0xee or 0xef in UTF-8 ) */
512 if ( (c & 1) && ((z[i+1] & 0xff) >= 0xa4) ){
513 /* But exclude U+F900 - U+FFFF (0xef followed by byte >= 0xa4),
514 * which contain valid characters. */
515 continue;
516 }
517 /* Unicode character in the range U+E000 - U+F8FF are for
518 * private use, they shouldn't occur in filenames. */
519 return 0;
520 }
521 if( ((c & 0xff) == 0xed) && ((z[i+1] & 0xe0) == 0xa0) ){
522 /* Unicode character in the range U+D800 - U+DFFF are for
523 * surrogate pairs, they shouldn't occur in filenames. */
524 return 0;
 
 
525 }
526 }
527 if( c=='\\' ){
528 return 0;
529 }
530
--- src/file.c
+++ src/file.c
@@ -487,43 +487,50 @@
487 ** * Does not contain any path element named "." or ".."
488 ** * Does not contain any of these characters in the path: "\"
489 ** * Does not end with "/".
490 ** * Does not contain two or more "/" characters in a row.
491 ** * Contains at least one character
492 **
493 ** Invalid UTF8 characters result in a false return if bStrictUtf8 is
494 ** true. If bStrictUtf8 is false, invalid UTF8 characters are silently
495 ** ignored.
496 */
497 int file_is_simple_pathname(const char *z, int bStrictUtf8){
498 int i;
499 char c = z[0];
500 char maskNonAscii = bStrictUtf8 ? 0x80 : 0x00;
501 if( c=='/' || c==0 ) return 0;
502 if( c=='.' ){
503 if( z[1]=='/' || z[1]==0 ) return 0;
504 if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
505 }
506 for(i=0; (c=z[i])!=0; i++){
507 if( c & maskNonAscii ){
508 if( (c & 0xf0) == 0xf0 ) {
509 /* Unicode characters > U+FFFF are not supported.
510 * Windows XP and earlier cannot handle them.
511 */
512 return 0;
513 }
514 if( (c & 0xf0) == 0xe0 ) {
515 /* This is a 3-byte UTF-8 character */
516 if ( (c & 0xfe) == 0xee ){
517 /* Range U+E000 - U+FFFF (Starting with 0xee or 0xef in UTF-8 ) */
518 if ( (c & 1) && ((z[i+1] & 0xff) >= 0xa4) ){
519 /* But exclude U+F900 - U+FFFF (0xef followed by byte >= 0xa4),
520 * which contain valid characters. */
521 continue;
522 }
523 /* Unicode character in the range U+E000 - U+F8FF are for
524 * private use, they shouldn't occur in filenames. */
525 return 0;
526 }
527 if( ((c & 0xff) == 0xed) && ((z[i+1] & 0xe0) == 0xa0) ){
528 /* Unicode character in the range U+D800 - U+DFFF are for
529 * surrogate pairs, they shouldn't occur in filenames. */
530 return 0;
531 }
532 }
533 }
534 if( c=='\\' ){
535 return 0;
536 }
537
--- src/http_socket.c
+++ src/http_socket.c
@@ -27,14 +27,12 @@
2727
*/
2828
2929
#include "config.h"
3030
#include "http_socket.h"
3131
#if defined(_WIN32)
32
-# if defined(__MINGW32__)
33
-# include <ws2tcpip.h>
34
-# endif
35
-# include <windows.h>
32
+# include <winsock2.h>
33
+# include <ws2tcpip.h>
3634
#else
3735
# include <netinet/in.h>
3836
# include <arpa/inet.h>
3937
# include <sys/socket.h>
4038
# include <netdb.h>
4139
--- src/http_socket.c
+++ src/http_socket.c
@@ -27,14 +27,12 @@
27 */
28
29 #include "config.h"
30 #include "http_socket.h"
31 #if defined(_WIN32)
32 # if defined(__MINGW32__)
33 # include <ws2tcpip.h>
34 # endif
35 # include <windows.h>
36 #else
37 # include <netinet/in.h>
38 # include <arpa/inet.h>
39 # include <sys/socket.h>
40 # include <netdb.h>
41
--- src/http_socket.c
+++ src/http_socket.c
@@ -27,14 +27,12 @@
27 */
28
29 #include "config.h"
30 #include "http_socket.h"
31 #if defined(_WIN32)
32 # include <winsock2.h>
33 # include <ws2tcpip.h>
 
 
34 #else
35 # include <netinet/in.h>
36 # include <arpa/inet.h>
37 # include <sys/socket.h>
38 # include <netdb.h>
39
+53 -17
--- src/info.c
+++ src/info.c
@@ -287,13 +287,18 @@
287287
}
288288
}
289289
290290
291291
/*
292
-** Append the difference between two RIDs to the output
292
+** Append the difference between artifacts to the output
293293
*/
294
-static void append_diff(const char *zFrom, const char *zTo, u64 diffFlags){
294
+static void append_diff(
295
+ const char *zFrom, /* Diff from this artifact */
296
+ const char *zTo, /* ... to this artifact */
297
+ u64 diffFlags, /* Diff formatting flags */
298
+ ReCompiled *pRe /* Only show change matching this regex */
299
+){
295300
int fromid;
296301
int toid;
297302
Blob from, to, out;
298303
if( zFrom ){
299304
fromid = uuid_to_rid(zFrom, 0);
@@ -307,16 +312,16 @@
307312
}else{
308313
blob_zero(&to);
309314
}
310315
blob_zero(&out);
311316
if( diffFlags & DIFF_SIDEBYSIDE ){
312
- text_diff(&from, &to, &out, diffFlags | DIFF_HTML);
317
+ text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML);
313318
@ <div class="sbsdiff">
314319
@ %s(blob_str(&out))
315320
@ </div>
316321
}else{
317
- text_diff(&from, &to, &out, diffFlags | DIFF_LINENO | DIFF_HTML);
322
+ text_diff(&from, &to, &out, pRe, diffFlags | DIFF_LINENO | DIFF_HTML);
318323
@ <div class="udiff">
319324
@ %s(blob_str(&out))
320325
@ </div>
321326
}
322327
blob_reset(&from);
@@ -333,10 +338,11 @@
333338
const char *zName, /* Name of the file that has changed */
334339
const char *zOld, /* blob.uuid before change. NULL for added files */
335340
const char *zNew, /* blob.uuid after change. NULL for deletes */
336341
const char *zOldName, /* Prior name. NULL if no name change. */
337342
u64 diffFlags, /* Flags for text_diff(). Zero to omit diffs */
343
+ ReCompiled *pRe, /* Only show diffs that match this regex, if not NULL */
338344
int mperm /* executable or symlink permission for zNew */
339345
){
340346
if( !g.perm.Hyperlink ){
341347
if( zNew==0 ){
342348
@ <p>Deleted %h(zName)</p>
@@ -350,21 +356,21 @@
350356
}else{
351357
@ <p>Changes to %h(zName)</p>
352358
}
353359
if( diffFlags ){
354360
@ <pre style="white-space:pre;">
355
- append_diff(zOld, zNew, diffFlags);
361
+ append_diff(zOld, zNew, diffFlags, pRe);
356362
@ </pre>
357363
}
358364
}else{
359365
if( zOld && zNew ){
360366
if( fossil_strcmp(zOld, zNew)!=0 ){
361367
@ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
362368
@ from %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a>
363369
@ to %z(href("%R/artifact/%s",zNew))[%S(zNew)].</a>
364370
}else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
365
- @ <p>Name change from
371
+ @ <p>Name change
366372
@ from %z(href("%R/finfo?name=%T",zOldName))%h(zOldName)</a>
367373
@ to %z(href("%R/finfo?name=%T",zName))%h(zName)</a>.
368374
}else{
369375
@ <p>Execute permission %s(( mperm==PERM_EXE )?"set":"cleared") for
370376
@ %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@@ -376,11 +382,11 @@
376382
@ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
377383
@ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
378384
}
379385
if( diffFlags ){
380386
@ <pre style="white-space:pre;">
381
- append_diff(zOld, zNew, diffFlags);
387
+ append_diff(zOld, zNew, diffFlags, pRe);
382388
@ </pre>
383389
}else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
384390
@ &nbsp;&nbsp;
385391
@ %z(href("%R/fdiff?v1=%S&v2=%S",zOld,zNew))[diff]</a>
386392
}
@@ -444,10 +450,12 @@
444450
int sideBySide; /* True for side-by-side diffs */
445451
u64 diffFlags; /* Flag parameter for text_diff() */
446452
const char *zName; /* Name of the checkin to be displayed */
447453
const char *zUuid; /* UUID of zName */
448454
const char *zParent; /* UUID of the parent checkin (if any) */
455
+ const char *zRe; /* regex parameter */
456
+ ReCompiled *pRe = 0; /* regex */
449457
450458
login_check_credentials();
451459
if( !g.perm.Read ){ login_needed(); return; }
452460
zName = P("name");
453461
rid = name_to_rid_www("name");
@@ -455,10 +463,12 @@
455463
style_header("Check-in Information Error");
456464
@ No such object: %h(g.argv[2])
457465
style_footer();
458466
return;
459467
}
468
+ zRe = P("regex");
469
+ if( zRe ) re_compile(&pRe, zRe, 0);
460470
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
461471
zParent = db_text(0,
462472
"SELECT uuid FROM plink, blob"
463473
" WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim",
464474
rid
@@ -479,13 +489,13 @@
479489
char *zEUser, *zEComment;
480490
const char *zUser;
481491
const char *zComment;
482492
const char *zDate;
483493
const char *zOrigDate;
494
+#if 0
484495
char *zThisBranch;
485496
double thisMtime;
486
-#if 0
487497
int seenDiffTitle = 0;
488498
#endif
489499
490500
style_header(zTitle);
491501
login_anonymous_available();
@@ -498,11 +508,13 @@
498508
TAG_COMMENT, rid);
499509
zUser = db_column_text(&q, 2);
500510
zComment = db_column_text(&q, 3);
501511
zDate = db_column_text(&q,1);
502512
zOrigDate = db_column_text(&q, 4);
513
+#if 0
503514
thisMtime = db_column_double(&q, 5);
515
+#endif
504516
@ <div class="section">Overview</div>
505517
@ <table class="label-value">
506518
@ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
507519
if( g.perm.Setup ){
508520
@ (Record ID: %d(rid))
@@ -567,17 +579,17 @@
567579
const char *zTagName = db_column_text(&q, 0);
568580
@ | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a>
569581
}
570582
db_finalize(&q);
571583
584
+#if 0
572585
/* Select a few other branches to diff against */
573586
zThisBranch = db_text("trunk", "SELECT value FROM tagxref"
574587
" WHERE tagid=%d AND tagtype>0"
575588
" AND rid=%d",
576589
TAG_BRANCH, rid);
577590
578
-#if 0
579591
/* Find nearby leaves to offer to diff against */
580592
db_prepare(&q,
581593
"SELECT tagxref.value, blob.uuid, min(%.17g-event.mtime)"
582594
" FROM leaf, event, tagxref, blob"
583595
" WHERE event.mtime BETWEEN %.17g AND %.17g"
@@ -690,29 +702,35 @@
690702
@ show&nbsp;side-by-side&nbsp;diffs</a>
691703
}
692704
}
693705
@ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid))
694706
@ patch</a></div>
707
+ if( pRe ){
708
+ @ <p><b>Only differences that match regular expression "%h(zRe)"
709
+ @ are shown.</b></p>
710
+ }
695711
db_prepare(&q,
696712
"SELECT name,"
697713
" mperm,"
698714
" (SELECT uuid FROM blob WHERE rid=mlink.pid),"
699715
" (SELECT uuid FROM blob WHERE rid=mlink.fid),"
700716
" (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)"
701717
" FROM mlink JOIN filename ON filename.fnid=mlink.fnid"
702718
" WHERE mlink.mid=%d"
719
+ " AND (mlink.fid>0"
720
+ " OR mlink.fnid NOT IN (SELECT pfnid FROM mlink WHERE mid=%d))"
703721
" ORDER BY name /*sort*/",
704
- rid
722
+ rid, rid
705723
);
706724
diffFlags = construct_diff_flags(showDiff, sideBySide);
707725
while( db_step(&q)==SQLITE_ROW ){
708726
const char *zName = db_column_text(&q,0);
709727
int mperm = db_column_int(&q, 1);
710728
const char *zOld = db_column_text(&q,2);
711729
const char *zNew = db_column_text(&q,3);
712730
const char *zOldName = db_column_text(&q, 4);
713
- append_file_change_line(zName, zOld, zNew, zOldName, diffFlags, mperm);
731
+ append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
714732
}
715733
db_finalize(&q);
716734
}
717735
style_footer();
718736
}
@@ -931,15 +949,19 @@
931949
Manifest *pFrom, *pTo;
932950
ManifestFile *pFileFrom, *pFileTo;
933951
const char *zBranch;
934952
const char *zFrom;
935953
const char *zTo;
954
+ const char *zRe;
955
+ ReCompiled *pRe = 0;
936956
937957
login_check_credentials();
938958
if( !g.perm.Read ){ login_needed(); return; }
939959
login_anonymous_available();
940960
961
+ zRe = P("regex");
962
+ if( zRe ) re_compile(&pRe, zRe, 0);
941963
zBranch = P("branch");
942964
if( zBranch && zBranch[0] ){
943965
cgi_replace_parameter("from", mprintf("root:%s", zBranch));
944966
cgi_replace_parameter("to", zBranch);
945967
}
@@ -967,11 +989,16 @@
967989
style_header("Check-in Differences");
968990
@ <h2>Difference From:</h2><blockquote>
969991
checkin_description(ridFrom);
970992
@ </blockquote><h2>To:</h2><blockquote>
971993
checkin_description(ridTo);
972
- @ </blockquote><hr /><p>
994
+ @ </blockquote>
995
+ if( pRe ){
996
+ @ <p><b>Only differences that match regular expression "%h(zRe)"
997
+ @ are shown.</b></p>
998
+ }
999
+ @<hr /><p>
9731000
9741001
manifest_file_rewind(pFrom);
9751002
pFileFrom = manifest_file_next(pFrom, 0);
9761003
manifest_file_rewind(pTo);
9771004
pFileTo = manifest_file_next(pTo, 0);
@@ -985,25 +1012,25 @@
9851012
}else{
9861013
cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
9871014
}
9881015
if( cmp<0 ){
9891016
append_file_change_line(pFileFrom->zName,
990
- pFileFrom->zUuid, 0, 0, diffFlags, 0);
1017
+ pFileFrom->zUuid, 0, 0, diffFlags, pRe, 0);
9911018
pFileFrom = manifest_file_next(pFrom, 0);
9921019
}else if( cmp>0 ){
9931020
append_file_change_line(pFileTo->zName,
994
- 0, pFileTo->zUuid, 0, diffFlags,
1021
+ 0, pFileTo->zUuid, 0, diffFlags, pRe,
9951022
manifest_file_mperm(pFileTo));
9961023
pFileTo = manifest_file_next(pTo, 0);
9971024
}else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
9981025
/* No changes */
9991026
pFileFrom = manifest_file_next(pFrom, 0);
10001027
pFileTo = manifest_file_next(pTo, 0);
10011028
}else{
10021029
append_file_change_line(pFileFrom->zName,
10031030
pFileFrom->zUuid,
1004
- pFileTo->zUuid, 0, diffFlags,
1031
+ pFileTo->zUuid, 0, diffFlags, pRe,
10051032
manifest_file_mperm(pFileTo));
10061033
pFileFrom = manifest_file_next(pFrom, 0);
10071034
pFileTo = manifest_file_next(pTo, 0);
10081035
}
10091036
}
@@ -1252,11 +1279,11 @@
12521279
}
12531280
12541281
12551282
/*
12561283
** WEBPAGE: fdiff
1257
-** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN
1284
+** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN&regex=REGEX
12581285
**
12591286
** Two arguments, v1 and v2, identify the files to be diffed. Show the
12601287
** difference between the two artifacts. Show diff side by side unless sbs
12611288
** is 0. Generate plaintext if "patch" is present.
12621289
*/
@@ -1265,12 +1292,15 @@
12651292
int isPatch;
12661293
int sideBySide;
12671294
Blob c1, c2, diff, *pOut;
12681295
char *zV1;
12691296
char *zV2;
1297
+ const char *zRe;
1298
+ ReCompiled *pRe = 0;
12701299
u64 diffFlags;
12711300
const char *zStyle = "sbsdiff";
1301
+ const char *zReErr = 0;
12721302
12731303
login_check_credentials();
12741304
if( !g.perm.Read ){ login_needed(); return; }
12751305
v1 = name_to_rid_www("v1");
12761306
v2 = name_to_rid_www("v2");
@@ -1292,13 +1322,15 @@
12921322
}else{
12931323
diffFlags |= DIFF_LINENO;
12941324
zStyle = "udiff";
12951325
}
12961326
}
1327
+ zRe = P("regex");
1328
+ if( zRe ) zReErr = re_compile(&pRe, zRe, 0);
12971329
content_get(v1, &c1);
12981330
content_get(v2, &c2);
1299
- text_diff(&c1, &c2, pOut, diffFlags);
1331
+ text_diff(&c1, &c2, pOut, pRe, diffFlags);
13001332
blob_reset(&c1);
13011333
blob_reset(&c2);
13021334
if( !isPatch ){
13031335
style_header("Diff");
13041336
style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
@@ -1322,10 +1354,14 @@
13221354
@ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
13231355
object_description(v1, 0, 0);
13241356
@ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
13251357
object_description(v2, 0, 0);
13261358
}
1359
+ if( pRe ){
1360
+ @ <b>Only differences that match regular expression "%h(zRe)"
1361
+ @ are shown.</b>
1362
+ }
13271363
@ <hr />
13281364
@ <div class="%s(zStyle)">
13291365
@ %s(blob_str(&diff))
13301366
@ </div>
13311367
blob_reset(&diff);
13321368
--- src/info.c
+++ src/info.c
@@ -287,13 +287,18 @@
287 }
288 }
289
290
291 /*
292 ** Append the difference between two RIDs to the output
293 */
294 static void append_diff(const char *zFrom, const char *zTo, u64 diffFlags){
 
 
 
 
 
295 int fromid;
296 int toid;
297 Blob from, to, out;
298 if( zFrom ){
299 fromid = uuid_to_rid(zFrom, 0);
@@ -307,16 +312,16 @@
307 }else{
308 blob_zero(&to);
309 }
310 blob_zero(&out);
311 if( diffFlags & DIFF_SIDEBYSIDE ){
312 text_diff(&from, &to, &out, diffFlags | DIFF_HTML);
313 @ <div class="sbsdiff">
314 @ %s(blob_str(&out))
315 @ </div>
316 }else{
317 text_diff(&from, &to, &out, diffFlags | DIFF_LINENO | DIFF_HTML);
318 @ <div class="udiff">
319 @ %s(blob_str(&out))
320 @ </div>
321 }
322 blob_reset(&from);
@@ -333,10 +338,11 @@
333 const char *zName, /* Name of the file that has changed */
334 const char *zOld, /* blob.uuid before change. NULL for added files */
335 const char *zNew, /* blob.uuid after change. NULL for deletes */
336 const char *zOldName, /* Prior name. NULL if no name change. */
337 u64 diffFlags, /* Flags for text_diff(). Zero to omit diffs */
 
338 int mperm /* executable or symlink permission for zNew */
339 ){
340 if( !g.perm.Hyperlink ){
341 if( zNew==0 ){
342 @ <p>Deleted %h(zName)</p>
@@ -350,21 +356,21 @@
350 }else{
351 @ <p>Changes to %h(zName)</p>
352 }
353 if( diffFlags ){
354 @ <pre style="white-space:pre;">
355 append_diff(zOld, zNew, diffFlags);
356 @ </pre>
357 }
358 }else{
359 if( zOld && zNew ){
360 if( fossil_strcmp(zOld, zNew)!=0 ){
361 @ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
362 @ from %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a>
363 @ to %z(href("%R/artifact/%s",zNew))[%S(zNew)].</a>
364 }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
365 @ <p>Name change from
366 @ from %z(href("%R/finfo?name=%T",zOldName))%h(zOldName)</a>
367 @ to %z(href("%R/finfo?name=%T",zName))%h(zName)</a>.
368 }else{
369 @ <p>Execute permission %s(( mperm==PERM_EXE )?"set":"cleared") for
370 @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@@ -376,11 +382,11 @@
376 @ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
377 @ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
378 }
379 if( diffFlags ){
380 @ <pre style="white-space:pre;">
381 append_diff(zOld, zNew, diffFlags);
382 @ </pre>
383 }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
384 @ &nbsp;&nbsp;
385 @ %z(href("%R/fdiff?v1=%S&v2=%S",zOld,zNew))[diff]</a>
386 }
@@ -444,10 +450,12 @@
444 int sideBySide; /* True for side-by-side diffs */
445 u64 diffFlags; /* Flag parameter for text_diff() */
446 const char *zName; /* Name of the checkin to be displayed */
447 const char *zUuid; /* UUID of zName */
448 const char *zParent; /* UUID of the parent checkin (if any) */
 
 
449
450 login_check_credentials();
451 if( !g.perm.Read ){ login_needed(); return; }
452 zName = P("name");
453 rid = name_to_rid_www("name");
@@ -455,10 +463,12 @@
455 style_header("Check-in Information Error");
456 @ No such object: %h(g.argv[2])
457 style_footer();
458 return;
459 }
 
 
460 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
461 zParent = db_text(0,
462 "SELECT uuid FROM plink, blob"
463 " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim",
464 rid
@@ -479,13 +489,13 @@
479 char *zEUser, *zEComment;
480 const char *zUser;
481 const char *zComment;
482 const char *zDate;
483 const char *zOrigDate;
 
484 char *zThisBranch;
485 double thisMtime;
486 #if 0
487 int seenDiffTitle = 0;
488 #endif
489
490 style_header(zTitle);
491 login_anonymous_available();
@@ -498,11 +508,13 @@
498 TAG_COMMENT, rid);
499 zUser = db_column_text(&q, 2);
500 zComment = db_column_text(&q, 3);
501 zDate = db_column_text(&q,1);
502 zOrigDate = db_column_text(&q, 4);
 
503 thisMtime = db_column_double(&q, 5);
 
504 @ <div class="section">Overview</div>
505 @ <table class="label-value">
506 @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
507 if( g.perm.Setup ){
508 @ (Record ID: %d(rid))
@@ -567,17 +579,17 @@
567 const char *zTagName = db_column_text(&q, 0);
568 @ | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a>
569 }
570 db_finalize(&q);
571
 
572 /* Select a few other branches to diff against */
573 zThisBranch = db_text("trunk", "SELECT value FROM tagxref"
574 " WHERE tagid=%d AND tagtype>0"
575 " AND rid=%d",
576 TAG_BRANCH, rid);
577
578 #if 0
579 /* Find nearby leaves to offer to diff against */
580 db_prepare(&q,
581 "SELECT tagxref.value, blob.uuid, min(%.17g-event.mtime)"
582 " FROM leaf, event, tagxref, blob"
583 " WHERE event.mtime BETWEEN %.17g AND %.17g"
@@ -690,29 +702,35 @@
690 @ show&nbsp;side-by-side&nbsp;diffs</a>
691 }
692 }
693 @ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid))
694 @ patch</a></div>
 
 
 
 
695 db_prepare(&q,
696 "SELECT name,"
697 " mperm,"
698 " (SELECT uuid FROM blob WHERE rid=mlink.pid),"
699 " (SELECT uuid FROM blob WHERE rid=mlink.fid),"
700 " (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)"
701 " FROM mlink JOIN filename ON filename.fnid=mlink.fnid"
702 " WHERE mlink.mid=%d"
 
 
703 " ORDER BY name /*sort*/",
704 rid
705 );
706 diffFlags = construct_diff_flags(showDiff, sideBySide);
707 while( db_step(&q)==SQLITE_ROW ){
708 const char *zName = db_column_text(&q,0);
709 int mperm = db_column_int(&q, 1);
710 const char *zOld = db_column_text(&q,2);
711 const char *zNew = db_column_text(&q,3);
712 const char *zOldName = db_column_text(&q, 4);
713 append_file_change_line(zName, zOld, zNew, zOldName, diffFlags, mperm);
714 }
715 db_finalize(&q);
716 }
717 style_footer();
718 }
@@ -931,15 +949,19 @@
931 Manifest *pFrom, *pTo;
932 ManifestFile *pFileFrom, *pFileTo;
933 const char *zBranch;
934 const char *zFrom;
935 const char *zTo;
 
 
936
937 login_check_credentials();
938 if( !g.perm.Read ){ login_needed(); return; }
939 login_anonymous_available();
940
 
 
941 zBranch = P("branch");
942 if( zBranch && zBranch[0] ){
943 cgi_replace_parameter("from", mprintf("root:%s", zBranch));
944 cgi_replace_parameter("to", zBranch);
945 }
@@ -967,11 +989,16 @@
967 style_header("Check-in Differences");
968 @ <h2>Difference From:</h2><blockquote>
969 checkin_description(ridFrom);
970 @ </blockquote><h2>To:</h2><blockquote>
971 checkin_description(ridTo);
972 @ </blockquote><hr /><p>
 
 
 
 
 
973
974 manifest_file_rewind(pFrom);
975 pFileFrom = manifest_file_next(pFrom, 0);
976 manifest_file_rewind(pTo);
977 pFileTo = manifest_file_next(pTo, 0);
@@ -985,25 +1012,25 @@
985 }else{
986 cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
987 }
988 if( cmp<0 ){
989 append_file_change_line(pFileFrom->zName,
990 pFileFrom->zUuid, 0, 0, diffFlags, 0);
991 pFileFrom = manifest_file_next(pFrom, 0);
992 }else if( cmp>0 ){
993 append_file_change_line(pFileTo->zName,
994 0, pFileTo->zUuid, 0, diffFlags,
995 manifest_file_mperm(pFileTo));
996 pFileTo = manifest_file_next(pTo, 0);
997 }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
998 /* No changes */
999 pFileFrom = manifest_file_next(pFrom, 0);
1000 pFileTo = manifest_file_next(pTo, 0);
1001 }else{
1002 append_file_change_line(pFileFrom->zName,
1003 pFileFrom->zUuid,
1004 pFileTo->zUuid, 0, diffFlags,
1005 manifest_file_mperm(pFileTo));
1006 pFileFrom = manifest_file_next(pFrom, 0);
1007 pFileTo = manifest_file_next(pTo, 0);
1008 }
1009 }
@@ -1252,11 +1279,11 @@
1252 }
1253
1254
1255 /*
1256 ** WEBPAGE: fdiff
1257 ** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN
1258 **
1259 ** Two arguments, v1 and v2, identify the files to be diffed. Show the
1260 ** difference between the two artifacts. Show diff side by side unless sbs
1261 ** is 0. Generate plaintext if "patch" is present.
1262 */
@@ -1265,12 +1292,15 @@
1265 int isPatch;
1266 int sideBySide;
1267 Blob c1, c2, diff, *pOut;
1268 char *zV1;
1269 char *zV2;
 
 
1270 u64 diffFlags;
1271 const char *zStyle = "sbsdiff";
 
1272
1273 login_check_credentials();
1274 if( !g.perm.Read ){ login_needed(); return; }
1275 v1 = name_to_rid_www("v1");
1276 v2 = name_to_rid_www("v2");
@@ -1292,13 +1322,15 @@
1292 }else{
1293 diffFlags |= DIFF_LINENO;
1294 zStyle = "udiff";
1295 }
1296 }
 
 
1297 content_get(v1, &c1);
1298 content_get(v2, &c2);
1299 text_diff(&c1, &c2, pOut, diffFlags);
1300 blob_reset(&c1);
1301 blob_reset(&c2);
1302 if( !isPatch ){
1303 style_header("Diff");
1304 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
@@ -1322,10 +1354,14 @@
1322 @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
1323 object_description(v1, 0, 0);
1324 @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
1325 object_description(v2, 0, 0);
1326 }
 
 
 
 
1327 @ <hr />
1328 @ <div class="%s(zStyle)">
1329 @ %s(blob_str(&diff))
1330 @ </div>
1331 blob_reset(&diff);
1332
--- src/info.c
+++ src/info.c
@@ -287,13 +287,18 @@
287 }
288 }
289
290
291 /*
292 ** Append the difference between artifacts to the output
293 */
294 static void append_diff(
295 const char *zFrom, /* Diff from this artifact */
296 const char *zTo, /* ... to this artifact */
297 u64 diffFlags, /* Diff formatting flags */
298 ReCompiled *pRe /* Only show change matching this regex */
299 ){
300 int fromid;
301 int toid;
302 Blob from, to, out;
303 if( zFrom ){
304 fromid = uuid_to_rid(zFrom, 0);
@@ -307,16 +312,16 @@
312 }else{
313 blob_zero(&to);
314 }
315 blob_zero(&out);
316 if( diffFlags & DIFF_SIDEBYSIDE ){
317 text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML);
318 @ <div class="sbsdiff">
319 @ %s(blob_str(&out))
320 @ </div>
321 }else{
322 text_diff(&from, &to, &out, pRe, diffFlags | DIFF_LINENO | DIFF_HTML);
323 @ <div class="udiff">
324 @ %s(blob_str(&out))
325 @ </div>
326 }
327 blob_reset(&from);
@@ -333,10 +338,11 @@
338 const char *zName, /* Name of the file that has changed */
339 const char *zOld, /* blob.uuid before change. NULL for added files */
340 const char *zNew, /* blob.uuid after change. NULL for deletes */
341 const char *zOldName, /* Prior name. NULL if no name change. */
342 u64 diffFlags, /* Flags for text_diff(). Zero to omit diffs */
343 ReCompiled *pRe, /* Only show diffs that match this regex, if not NULL */
344 int mperm /* executable or symlink permission for zNew */
345 ){
346 if( !g.perm.Hyperlink ){
347 if( zNew==0 ){
348 @ <p>Deleted %h(zName)</p>
@@ -350,21 +356,21 @@
356 }else{
357 @ <p>Changes to %h(zName)</p>
358 }
359 if( diffFlags ){
360 @ <pre style="white-space:pre;">
361 append_diff(zOld, zNew, diffFlags, pRe);
362 @ </pre>
363 }
364 }else{
365 if( zOld && zNew ){
366 if( fossil_strcmp(zOld, zNew)!=0 ){
367 @ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
368 @ from %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a>
369 @ to %z(href("%R/artifact/%s",zNew))[%S(zNew)].</a>
370 }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
371 @ <p>Name change
372 @ from %z(href("%R/finfo?name=%T",zOldName))%h(zOldName)</a>
373 @ to %z(href("%R/finfo?name=%T",zName))%h(zName)</a>.
374 }else{
375 @ <p>Execute permission %s(( mperm==PERM_EXE )?"set":"cleared") for
376 @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@@ -376,11 +382,11 @@
382 @ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
383 @ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
384 }
385 if( diffFlags ){
386 @ <pre style="white-space:pre;">
387 append_diff(zOld, zNew, diffFlags, pRe);
388 @ </pre>
389 }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
390 @ &nbsp;&nbsp;
391 @ %z(href("%R/fdiff?v1=%S&v2=%S",zOld,zNew))[diff]</a>
392 }
@@ -444,10 +450,12 @@
450 int sideBySide; /* True for side-by-side diffs */
451 u64 diffFlags; /* Flag parameter for text_diff() */
452 const char *zName; /* Name of the checkin to be displayed */
453 const char *zUuid; /* UUID of zName */
454 const char *zParent; /* UUID of the parent checkin (if any) */
455 const char *zRe; /* regex parameter */
456 ReCompiled *pRe = 0; /* regex */
457
458 login_check_credentials();
459 if( !g.perm.Read ){ login_needed(); return; }
460 zName = P("name");
461 rid = name_to_rid_www("name");
@@ -455,10 +463,12 @@
463 style_header("Check-in Information Error");
464 @ No such object: %h(g.argv[2])
465 style_footer();
466 return;
467 }
468 zRe = P("regex");
469 if( zRe ) re_compile(&pRe, zRe, 0);
470 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
471 zParent = db_text(0,
472 "SELECT uuid FROM plink, blob"
473 " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim",
474 rid
@@ -479,13 +489,13 @@
489 char *zEUser, *zEComment;
490 const char *zUser;
491 const char *zComment;
492 const char *zDate;
493 const char *zOrigDate;
494 #if 0
495 char *zThisBranch;
496 double thisMtime;
 
497 int seenDiffTitle = 0;
498 #endif
499
500 style_header(zTitle);
501 login_anonymous_available();
@@ -498,11 +508,13 @@
508 TAG_COMMENT, rid);
509 zUser = db_column_text(&q, 2);
510 zComment = db_column_text(&q, 3);
511 zDate = db_column_text(&q,1);
512 zOrigDate = db_column_text(&q, 4);
513 #if 0
514 thisMtime = db_column_double(&q, 5);
515 #endif
516 @ <div class="section">Overview</div>
517 @ <table class="label-value">
518 @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
519 if( g.perm.Setup ){
520 @ (Record ID: %d(rid))
@@ -567,17 +579,17 @@
579 const char *zTagName = db_column_text(&q, 0);
580 @ | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a>
581 }
582 db_finalize(&q);
583
584 #if 0
585 /* Select a few other branches to diff against */
586 zThisBranch = db_text("trunk", "SELECT value FROM tagxref"
587 " WHERE tagid=%d AND tagtype>0"
588 " AND rid=%d",
589 TAG_BRANCH, rid);
590
 
591 /* Find nearby leaves to offer to diff against */
592 db_prepare(&q,
593 "SELECT tagxref.value, blob.uuid, min(%.17g-event.mtime)"
594 " FROM leaf, event, tagxref, blob"
595 " WHERE event.mtime BETWEEN %.17g AND %.17g"
@@ -690,29 +702,35 @@
702 @ show&nbsp;side-by-side&nbsp;diffs</a>
703 }
704 }
705 @ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid))
706 @ patch</a></div>
707 if( pRe ){
708 @ <p><b>Only differences that match regular expression "%h(zRe)"
709 @ are shown.</b></p>
710 }
711 db_prepare(&q,
712 "SELECT name,"
713 " mperm,"
714 " (SELECT uuid FROM blob WHERE rid=mlink.pid),"
715 " (SELECT uuid FROM blob WHERE rid=mlink.fid),"
716 " (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)"
717 " FROM mlink JOIN filename ON filename.fnid=mlink.fnid"
718 " WHERE mlink.mid=%d"
719 " AND (mlink.fid>0"
720 " OR mlink.fnid NOT IN (SELECT pfnid FROM mlink WHERE mid=%d))"
721 " ORDER BY name /*sort*/",
722 rid, rid
723 );
724 diffFlags = construct_diff_flags(showDiff, sideBySide);
725 while( db_step(&q)==SQLITE_ROW ){
726 const char *zName = db_column_text(&q,0);
727 int mperm = db_column_int(&q, 1);
728 const char *zOld = db_column_text(&q,2);
729 const char *zNew = db_column_text(&q,3);
730 const char *zOldName = db_column_text(&q, 4);
731 append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
732 }
733 db_finalize(&q);
734 }
735 style_footer();
736 }
@@ -931,15 +949,19 @@
949 Manifest *pFrom, *pTo;
950 ManifestFile *pFileFrom, *pFileTo;
951 const char *zBranch;
952 const char *zFrom;
953 const char *zTo;
954 const char *zRe;
955 ReCompiled *pRe = 0;
956
957 login_check_credentials();
958 if( !g.perm.Read ){ login_needed(); return; }
959 login_anonymous_available();
960
961 zRe = P("regex");
962 if( zRe ) re_compile(&pRe, zRe, 0);
963 zBranch = P("branch");
964 if( zBranch && zBranch[0] ){
965 cgi_replace_parameter("from", mprintf("root:%s", zBranch));
966 cgi_replace_parameter("to", zBranch);
967 }
@@ -967,11 +989,16 @@
989 style_header("Check-in Differences");
990 @ <h2>Difference From:</h2><blockquote>
991 checkin_description(ridFrom);
992 @ </blockquote><h2>To:</h2><blockquote>
993 checkin_description(ridTo);
994 @ </blockquote>
995 if( pRe ){
996 @ <p><b>Only differences that match regular expression "%h(zRe)"
997 @ are shown.</b></p>
998 }
999 @<hr /><p>
1000
1001 manifest_file_rewind(pFrom);
1002 pFileFrom = manifest_file_next(pFrom, 0);
1003 manifest_file_rewind(pTo);
1004 pFileTo = manifest_file_next(pTo, 0);
@@ -985,25 +1012,25 @@
1012 }else{
1013 cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
1014 }
1015 if( cmp<0 ){
1016 append_file_change_line(pFileFrom->zName,
1017 pFileFrom->zUuid, 0, 0, diffFlags, pRe, 0);
1018 pFileFrom = manifest_file_next(pFrom, 0);
1019 }else if( cmp>0 ){
1020 append_file_change_line(pFileTo->zName,
1021 0, pFileTo->zUuid, 0, diffFlags, pRe,
1022 manifest_file_mperm(pFileTo));
1023 pFileTo = manifest_file_next(pTo, 0);
1024 }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
1025 /* No changes */
1026 pFileFrom = manifest_file_next(pFrom, 0);
1027 pFileTo = manifest_file_next(pTo, 0);
1028 }else{
1029 append_file_change_line(pFileFrom->zName,
1030 pFileFrom->zUuid,
1031 pFileTo->zUuid, 0, diffFlags, pRe,
1032 manifest_file_mperm(pFileTo));
1033 pFileFrom = manifest_file_next(pFrom, 0);
1034 pFileTo = manifest_file_next(pTo, 0);
1035 }
1036 }
@@ -1252,11 +1279,11 @@
1279 }
1280
1281
1282 /*
1283 ** WEBPAGE: fdiff
1284 ** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN&regex=REGEX
1285 **
1286 ** Two arguments, v1 and v2, identify the files to be diffed. Show the
1287 ** difference between the two artifacts. Show diff side by side unless sbs
1288 ** is 0. Generate plaintext if "patch" is present.
1289 */
@@ -1265,12 +1292,15 @@
1292 int isPatch;
1293 int sideBySide;
1294 Blob c1, c2, diff, *pOut;
1295 char *zV1;
1296 char *zV2;
1297 const char *zRe;
1298 ReCompiled *pRe = 0;
1299 u64 diffFlags;
1300 const char *zStyle = "sbsdiff";
1301 const char *zReErr = 0;
1302
1303 login_check_credentials();
1304 if( !g.perm.Read ){ login_needed(); return; }
1305 v1 = name_to_rid_www("v1");
1306 v2 = name_to_rid_www("v2");
@@ -1292,13 +1322,15 @@
1322 }else{
1323 diffFlags |= DIFF_LINENO;
1324 zStyle = "udiff";
1325 }
1326 }
1327 zRe = P("regex");
1328 if( zRe ) zReErr = re_compile(&pRe, zRe, 0);
1329 content_get(v1, &c1);
1330 content_get(v2, &c2);
1331 text_diff(&c1, &c2, pOut, pRe, diffFlags);
1332 blob_reset(&c1);
1333 blob_reset(&c2);
1334 if( !isPatch ){
1335 style_header("Diff");
1336 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
@@ -1322,10 +1354,14 @@
1354 @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
1355 object_description(v1, 0, 0);
1356 @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
1357 object_description(v2, 0, 0);
1358 }
1359 if( pRe ){
1360 @ <b>Only differences that match regular expression "%h(zRe)"
1361 @ are shown.</b>
1362 }
1363 @ <hr />
1364 @ <div class="%s(zStyle)">
1365 @ %s(blob_str(&diff))
1366 @ </div>
1367 blob_reset(&diff);
1368
+1 -1
--- src/json_diff.c
+++ src/json_diff.c
@@ -58,11 +58,11 @@
5858
return NULL;
5959
}
6060
content_get(fromid, &from);
6161
content_get(toid, &to);
6262
blob_zero(&out);
63
- text_diff(&from, &to, &out, flags);
63
+ text_diff(&from, &to, &out, 0, flags);
6464
blob_reset(&from);
6565
blob_reset(&to);
6666
outLen = blob_size(&out);
6767
if(outLen>=0){
6868
rc = cson_value_new_string(blob_buffer(&out),
6969
--- src/json_diff.c
+++ src/json_diff.c
@@ -58,11 +58,11 @@
58 return NULL;
59 }
60 content_get(fromid, &from);
61 content_get(toid, &to);
62 blob_zero(&out);
63 text_diff(&from, &to, &out, flags);
64 blob_reset(&from);
65 blob_reset(&to);
66 outLen = blob_size(&out);
67 if(outLen>=0){
68 rc = cson_value_new_string(blob_buffer(&out),
69
--- src/json_diff.c
+++ src/json_diff.c
@@ -58,11 +58,11 @@
58 return NULL;
59 }
60 content_get(fromid, &from);
61 content_get(toid, &to);
62 blob_zero(&out);
63 text_diff(&from, &to, &out, 0, flags);
64 blob_reset(&from);
65 blob_reset(&to);
66 outLen = blob_size(&out);
67 if(outLen>=0){
68 rc = cson_value_new_string(blob_buffer(&out),
69
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -90,11 +90,11 @@
9090
9191
/*
9292
** Return a pointer to a constant string that forms the basis
9393
** for a timeline query for the JSON interface.
9494
*/
95
-const char const * json_timeline_query(void){
95
+char const * json_timeline_query(void){
9696
/* Field order MUST match that from json_timeline_temp_table()!!! */
9797
static const char zBaseSql[] =
9898
@ SELECT
9999
@ NULL,
100100
@ blob.rid,
101101
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -90,11 +90,11 @@
90
91 /*
92 ** Return a pointer to a constant string that forms the basis
93 ** for a timeline query for the JSON interface.
94 */
95 const char const * json_timeline_query(void){
96 /* Field order MUST match that from json_timeline_temp_table()!!! */
97 static const char zBaseSql[] =
98 @ SELECT
99 @ NULL,
100 @ blob.rid,
101
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -90,11 +90,11 @@
90
91 /*
92 ** Return a pointer to a constant string that forms the basis
93 ** for a timeline query for the JSON interface.
94 */
95 char const * json_timeline_query(void){
96 /* Field order MUST match that from json_timeline_temp_table()!!! */
97 static const char zBaseSql[] =
98 @ SELECT
99 @ NULL,
100 @ blob.rid,
101
+1 -1
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -543,11 +543,11 @@
543543
blob_init(&w1, pW1->zWiki, -1);
544544
blob_zero(&w2);
545545
blob_init(&w2, pW2->zWiki, -1);
546546
blob_zero(&d);
547547
diffFlags = DIFF_IGNORE_EOLWS | DIFF_INLINE;
548
- text_diff(&w2, &w1, &d, diffFlags);
548
+ text_diff(&w2, &w1, &d, 0, diffFlags);
549549
blob_reset(&w1);
550550
blob_reset(&w2);
551551
552552
pay = cson_new_object();
553553
554554
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -543,11 +543,11 @@
543 blob_init(&w1, pW1->zWiki, -1);
544 blob_zero(&w2);
545 blob_init(&w2, pW2->zWiki, -1);
546 blob_zero(&d);
547 diffFlags = DIFF_IGNORE_EOLWS | DIFF_INLINE;
548 text_diff(&w2, &w1, &d, diffFlags);
549 blob_reset(&w1);
550 blob_reset(&w2);
551
552 pay = cson_new_object();
553
554
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -543,11 +543,11 @@
543 blob_init(&w1, pW1->zWiki, -1);
544 blob_zero(&w2);
545 blob_init(&w2, pW2->zWiki, -1);
546 blob_zero(&d);
547 diffFlags = DIFF_IGNORE_EOLWS | DIFF_INLINE;
548 text_diff(&w2, &w1, &d, 0, diffFlags);
549 blob_reset(&w1);
550 blob_reset(&w2);
551
552 pay = cson_new_object();
553
554
+2 -2
--- src/login.c
+++ src/login.c
@@ -397,11 +397,11 @@
397397
}
398398
if( memcmp(zAgent, "Mozilla/", 8)==0 ){
399399
if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
400400
if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
401401
if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
402
- if( strglob("*(compatible;?MSIE?[1-9]*", zAgent) ) return 1;
402
+ if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
403403
if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
404404
return 0;
405405
}
406406
if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
407407
if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
@@ -625,11 +625,11 @@
625625
@ <a href="%s(g.zTop)/register?g=%T(P("G"))">create one</a>.
626626
}
627627
if( zAnonPw ){
628628
unsigned int uSeed = captcha_seed();
629629
char const *zDecoded = captcha_decode(uSeed);
630
- int bAutoCaptcha = db_get_boolean("auto-captcha", 1);
630
+ int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
631631
char *zCaptcha = captcha_render(zDecoded);
632632
633633
@ <p><input type="hidden" name="cs" value="%u(uSeed)" />
634634
@ Visitors may enter <b>anonymous</b> as the user-ID with
635635
@ the 8-character hexadecimal password shown below:</p>
636636
--- src/login.c
+++ src/login.c
@@ -397,11 +397,11 @@
397 }
398 if( memcmp(zAgent, "Mozilla/", 8)==0 ){
399 if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
400 if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
401 if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
402 if( strglob("*(compatible;?MSIE?[1-9]*", zAgent) ) return 1;
403 if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
404 return 0;
405 }
406 if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
407 if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
@@ -625,11 +625,11 @@
625 @ <a href="%s(g.zTop)/register?g=%T(P("G"))">create one</a>.
626 }
627 if( zAnonPw ){
628 unsigned int uSeed = captcha_seed();
629 char const *zDecoded = captcha_decode(uSeed);
630 int bAutoCaptcha = db_get_boolean("auto-captcha", 1);
631 char *zCaptcha = captcha_render(zDecoded);
632
633 @ <p><input type="hidden" name="cs" value="%u(uSeed)" />
634 @ Visitors may enter <b>anonymous</b> as the user-ID with
635 @ the 8-character hexadecimal password shown below:</p>
636
--- src/login.c
+++ src/login.c
@@ -397,11 +397,11 @@
397 }
398 if( memcmp(zAgent, "Mozilla/", 8)==0 ){
399 if( atoi(&zAgent[8])<4 ) return 0; /* Many bots advertise as Mozilla/3 */
400 if( strglob("*Firefox/[1-9]*", zAgent) ) return 1;
401 if( strglob("*Chrome/[1-9]*", zAgent) ) return 1;
402 if( strglob("*(compatible;?MSIE?[1789]*", zAgent) ) return 1;
403 if( strglob("*AppleWebKit/[1-9]*(KHTML*", zAgent) ) return 1;
404 return 0;
405 }
406 if( memcmp(zAgent, "Opera/", 6)==0 ) return 1;
407 if( memcmp(zAgent, "Safari/", 7)==0 ) return 1;
@@ -625,11 +625,11 @@
625 @ <a href="%s(g.zTop)/register?g=%T(P("G"))">create one</a>.
626 }
627 if( zAnonPw ){
628 unsigned int uSeed = captcha_seed();
629 char const *zDecoded = captcha_decode(uSeed);
630 int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
631 char *zCaptcha = captcha_render(zDecoded);
632
633 @ <p><input type="hidden" name="cs" value="%u(uSeed)" />
634 @ Visitors may enter <b>anonymous</b> as the user-ID with
635 @ the 8-character hexadecimal password shown below:</p>
636
+3 -1
--- src/main.c
+++ src/main.c
@@ -892,11 +892,13 @@
892892
*/
893893
void verify_all_options(void){
894894
int i;
895895
for(i=1; i<g.argc; i++){
896896
if( g.argv[i][0]=='-' ){
897
- fossil_fatal("unrecognized command-line option, or missing argument: %s", g.argv[i]);
897
+ fossil_fatal(
898
+ "unrecognized command-line option, or missing argument: %s",
899
+ g.argv[i]);
898900
}
899901
}
900902
}
901903
902904
/*
903905
--- src/main.c
+++ src/main.c
@@ -892,11 +892,13 @@
892 */
893 void verify_all_options(void){
894 int i;
895 for(i=1; i<g.argc; i++){
896 if( g.argv[i][0]=='-' ){
897 fossil_fatal("unrecognized command-line option, or missing argument: %s", g.argv[i]);
 
 
898 }
899 }
900 }
901
902 /*
903
--- src/main.c
+++ src/main.c
@@ -892,11 +892,13 @@
892 */
893 void verify_all_options(void){
894 int i;
895 for(i=1; i<g.argc; i++){
896 if( g.argv[i][0]=='-' ){
897 fossil_fatal(
898 "unrecognized command-line option, or missing argument: %s",
899 g.argv[i]);
900 }
901 }
902 }
903
904 /*
905
+21 -1
--- src/main.mk
+++ src/main.mk
@@ -81,10 +81,11 @@
8181
$(SRCDIR)/pivot.c \
8282
$(SRCDIR)/popen.c \
8383
$(SRCDIR)/pqueue.c \
8484
$(SRCDIR)/printf.c \
8585
$(SRCDIR)/rebuild.c \
86
+ $(SRCDIR)/regexp.c \
8687
$(SRCDIR)/report.c \
8788
$(SRCDIR)/rss.c \
8889
$(SRCDIR)/schema.c \
8990
$(SRCDIR)/search.c \
9091
$(SRCDIR)/setup.c \
@@ -101,10 +102,11 @@
101102
$(SRCDIR)/th_main.c \
102103
$(SRCDIR)/timeline.c \
103104
$(SRCDIR)/tkt.c \
104105
$(SRCDIR)/tktsetup.c \
105106
$(SRCDIR)/undo.c \
107
+ $(SRCDIR)/unicode.c \
106108
$(SRCDIR)/update.c \
107109
$(SRCDIR)/url.c \
108110
$(SRCDIR)/user.c \
109111
$(SRCDIR)/utf8.c \
110112
$(SRCDIR)/verify.c \
@@ -185,10 +187,11 @@
185187
$(OBJDIR)/pivot_.c \
186188
$(OBJDIR)/popen_.c \
187189
$(OBJDIR)/pqueue_.c \
188190
$(OBJDIR)/printf_.c \
189191
$(OBJDIR)/rebuild_.c \
192
+ $(OBJDIR)/regexp_.c \
190193
$(OBJDIR)/report_.c \
191194
$(OBJDIR)/rss_.c \
192195
$(OBJDIR)/schema_.c \
193196
$(OBJDIR)/search_.c \
194197
$(OBJDIR)/setup_.c \
@@ -205,10 +208,11 @@
205208
$(OBJDIR)/th_main_.c \
206209
$(OBJDIR)/timeline_.c \
207210
$(OBJDIR)/tkt_.c \
208211
$(OBJDIR)/tktsetup_.c \
209212
$(OBJDIR)/undo_.c \
213
+ $(OBJDIR)/unicode_.c \
210214
$(OBJDIR)/update_.c \
211215
$(OBJDIR)/url_.c \
212216
$(OBJDIR)/user_.c \
213217
$(OBJDIR)/utf8_.c \
214218
$(OBJDIR)/verify_.c \
@@ -289,10 +293,11 @@
289293
$(OBJDIR)/pivot.o \
290294
$(OBJDIR)/popen.o \
291295
$(OBJDIR)/pqueue.o \
292296
$(OBJDIR)/printf.o \
293297
$(OBJDIR)/rebuild.o \
298
+ $(OBJDIR)/regexp.o \
294299
$(OBJDIR)/report.o \
295300
$(OBJDIR)/rss.o \
296301
$(OBJDIR)/schema.o \
297302
$(OBJDIR)/search.o \
298303
$(OBJDIR)/setup.o \
@@ -309,10 +314,11 @@
309314
$(OBJDIR)/th_main.o \
310315
$(OBJDIR)/timeline.o \
311316
$(OBJDIR)/tkt.o \
312317
$(OBJDIR)/tktsetup.o \
313318
$(OBJDIR)/undo.o \
319
+ $(OBJDIR)/unicode.o \
314320
$(OBJDIR)/update.o \
315321
$(OBJDIR)/url.o \
316322
$(OBJDIR)/user.o \
317323
$(OBJDIR)/utf8.o \
318324
$(OBJDIR)/verify.o \
@@ -390,11 +396,11 @@
390396
391397
392398
$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
393399
$(OBJDIR)/mkindex $(TRANS_SRC) >$@
394400
$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
395
- $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
401
+ $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
396402
touch $(OBJDIR)/headers
397403
$(OBJDIR)/headers: Makefile
398404
$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
399405
Makefile:
400406
$(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
@@ -878,10 +884,17 @@
878884
879885
$(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
880886
$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
881887
882888
$(OBJDIR)/rebuild.h: $(OBJDIR)/headers
889
+$(OBJDIR)/regexp_.c: $(SRCDIR)/regexp.c $(OBJDIR)/translate
890
+ $(OBJDIR)/translate $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c
891
+
892
+$(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
893
+ $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
894
+
895
+$(OBJDIR)/regexp.h: $(OBJDIR)/headers
883896
$(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
884897
$(OBJDIR)/translate $(SRCDIR)/report.c >$(OBJDIR)/report_.c
885898
886899
$(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
887900
$(XTCC) -o $(OBJDIR)/report.o -c $(OBJDIR)/report_.c
@@ -1018,10 +1031,17 @@
10181031
10191032
$(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
10201033
$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
10211034
10221035
$(OBJDIR)/undo.h: $(OBJDIR)/headers
1036
+$(OBJDIR)/unicode_.c: $(SRCDIR)/unicode.c $(OBJDIR)/translate
1037
+ $(OBJDIR)/translate $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c
1038
+
1039
+$(OBJDIR)/unicode.o: $(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
1040
+ $(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c
1041
+
1042
+$(OBJDIR)/unicode.h: $(OBJDIR)/headers
10231043
$(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
10241044
$(OBJDIR)/translate $(SRCDIR)/update.c >$(OBJDIR)/update_.c
10251045
10261046
$(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
10271047
$(XTCC) -o $(OBJDIR)/update.o -c $(OBJDIR)/update_.c
10281048
--- src/main.mk
+++ src/main.mk
@@ -81,10 +81,11 @@
81 $(SRCDIR)/pivot.c \
82 $(SRCDIR)/popen.c \
83 $(SRCDIR)/pqueue.c \
84 $(SRCDIR)/printf.c \
85 $(SRCDIR)/rebuild.c \
 
86 $(SRCDIR)/report.c \
87 $(SRCDIR)/rss.c \
88 $(SRCDIR)/schema.c \
89 $(SRCDIR)/search.c \
90 $(SRCDIR)/setup.c \
@@ -101,10 +102,11 @@
101 $(SRCDIR)/th_main.c \
102 $(SRCDIR)/timeline.c \
103 $(SRCDIR)/tkt.c \
104 $(SRCDIR)/tktsetup.c \
105 $(SRCDIR)/undo.c \
 
106 $(SRCDIR)/update.c \
107 $(SRCDIR)/url.c \
108 $(SRCDIR)/user.c \
109 $(SRCDIR)/utf8.c \
110 $(SRCDIR)/verify.c \
@@ -185,10 +187,11 @@
185 $(OBJDIR)/pivot_.c \
186 $(OBJDIR)/popen_.c \
187 $(OBJDIR)/pqueue_.c \
188 $(OBJDIR)/printf_.c \
189 $(OBJDIR)/rebuild_.c \
 
190 $(OBJDIR)/report_.c \
191 $(OBJDIR)/rss_.c \
192 $(OBJDIR)/schema_.c \
193 $(OBJDIR)/search_.c \
194 $(OBJDIR)/setup_.c \
@@ -205,10 +208,11 @@
205 $(OBJDIR)/th_main_.c \
206 $(OBJDIR)/timeline_.c \
207 $(OBJDIR)/tkt_.c \
208 $(OBJDIR)/tktsetup_.c \
209 $(OBJDIR)/undo_.c \
 
210 $(OBJDIR)/update_.c \
211 $(OBJDIR)/url_.c \
212 $(OBJDIR)/user_.c \
213 $(OBJDIR)/utf8_.c \
214 $(OBJDIR)/verify_.c \
@@ -289,10 +293,11 @@
289 $(OBJDIR)/pivot.o \
290 $(OBJDIR)/popen.o \
291 $(OBJDIR)/pqueue.o \
292 $(OBJDIR)/printf.o \
293 $(OBJDIR)/rebuild.o \
 
294 $(OBJDIR)/report.o \
295 $(OBJDIR)/rss.o \
296 $(OBJDIR)/schema.o \
297 $(OBJDIR)/search.o \
298 $(OBJDIR)/setup.o \
@@ -309,10 +314,11 @@
309 $(OBJDIR)/th_main.o \
310 $(OBJDIR)/timeline.o \
311 $(OBJDIR)/tkt.o \
312 $(OBJDIR)/tktsetup.o \
313 $(OBJDIR)/undo.o \
 
314 $(OBJDIR)/update.o \
315 $(OBJDIR)/url.o \
316 $(OBJDIR)/user.o \
317 $(OBJDIR)/utf8.o \
318 $(OBJDIR)/verify.o \
@@ -390,11 +396,11 @@
390
391
392 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
393 $(OBJDIR)/mkindex $(TRANS_SRC) >$@
394 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
395 $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
396 touch $(OBJDIR)/headers
397 $(OBJDIR)/headers: Makefile
398 $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
399 Makefile:
400 $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
@@ -878,10 +884,17 @@
878
879 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
880 $(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
881
882 $(OBJDIR)/rebuild.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
883 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
884 $(OBJDIR)/translate $(SRCDIR)/report.c >$(OBJDIR)/report_.c
885
886 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
887 $(XTCC) -o $(OBJDIR)/report.o -c $(OBJDIR)/report_.c
@@ -1018,10 +1031,17 @@
1018
1019 $(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
1020 $(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
1021
1022 $(OBJDIR)/undo.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
1023 $(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
1024 $(OBJDIR)/translate $(SRCDIR)/update.c >$(OBJDIR)/update_.c
1025
1026 $(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
1027 $(XTCC) -o $(OBJDIR)/update.o -c $(OBJDIR)/update_.c
1028
--- src/main.mk
+++ src/main.mk
@@ -81,10 +81,11 @@
81 $(SRCDIR)/pivot.c \
82 $(SRCDIR)/popen.c \
83 $(SRCDIR)/pqueue.c \
84 $(SRCDIR)/printf.c \
85 $(SRCDIR)/rebuild.c \
86 $(SRCDIR)/regexp.c \
87 $(SRCDIR)/report.c \
88 $(SRCDIR)/rss.c \
89 $(SRCDIR)/schema.c \
90 $(SRCDIR)/search.c \
91 $(SRCDIR)/setup.c \
@@ -101,10 +102,11 @@
102 $(SRCDIR)/th_main.c \
103 $(SRCDIR)/timeline.c \
104 $(SRCDIR)/tkt.c \
105 $(SRCDIR)/tktsetup.c \
106 $(SRCDIR)/undo.c \
107 $(SRCDIR)/unicode.c \
108 $(SRCDIR)/update.c \
109 $(SRCDIR)/url.c \
110 $(SRCDIR)/user.c \
111 $(SRCDIR)/utf8.c \
112 $(SRCDIR)/verify.c \
@@ -185,10 +187,11 @@
187 $(OBJDIR)/pivot_.c \
188 $(OBJDIR)/popen_.c \
189 $(OBJDIR)/pqueue_.c \
190 $(OBJDIR)/printf_.c \
191 $(OBJDIR)/rebuild_.c \
192 $(OBJDIR)/regexp_.c \
193 $(OBJDIR)/report_.c \
194 $(OBJDIR)/rss_.c \
195 $(OBJDIR)/schema_.c \
196 $(OBJDIR)/search_.c \
197 $(OBJDIR)/setup_.c \
@@ -205,10 +208,11 @@
208 $(OBJDIR)/th_main_.c \
209 $(OBJDIR)/timeline_.c \
210 $(OBJDIR)/tkt_.c \
211 $(OBJDIR)/tktsetup_.c \
212 $(OBJDIR)/undo_.c \
213 $(OBJDIR)/unicode_.c \
214 $(OBJDIR)/update_.c \
215 $(OBJDIR)/url_.c \
216 $(OBJDIR)/user_.c \
217 $(OBJDIR)/utf8_.c \
218 $(OBJDIR)/verify_.c \
@@ -289,10 +293,11 @@
293 $(OBJDIR)/pivot.o \
294 $(OBJDIR)/popen.o \
295 $(OBJDIR)/pqueue.o \
296 $(OBJDIR)/printf.o \
297 $(OBJDIR)/rebuild.o \
298 $(OBJDIR)/regexp.o \
299 $(OBJDIR)/report.o \
300 $(OBJDIR)/rss.o \
301 $(OBJDIR)/schema.o \
302 $(OBJDIR)/search.o \
303 $(OBJDIR)/setup.o \
@@ -309,10 +314,11 @@
314 $(OBJDIR)/th_main.o \
315 $(OBJDIR)/timeline.o \
316 $(OBJDIR)/tkt.o \
317 $(OBJDIR)/tktsetup.o \
318 $(OBJDIR)/undo.o \
319 $(OBJDIR)/unicode.o \
320 $(OBJDIR)/update.o \
321 $(OBJDIR)/url.o \
322 $(OBJDIR)/user.o \
323 $(OBJDIR)/utf8.o \
324 $(OBJDIR)/verify.o \
@@ -390,11 +396,11 @@
396
397
398 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
399 $(OBJDIR)/mkindex $(TRANS_SRC) >$@
400 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
401 $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
402 touch $(OBJDIR)/headers
403 $(OBJDIR)/headers: Makefile
404 $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
405 Makefile:
406 $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
@@ -878,10 +884,17 @@
884
885 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
886 $(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
887
888 $(OBJDIR)/rebuild.h: $(OBJDIR)/headers
889 $(OBJDIR)/regexp_.c: $(SRCDIR)/regexp.c $(OBJDIR)/translate
890 $(OBJDIR)/translate $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c
891
892 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
893 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
894
895 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
896 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
897 $(OBJDIR)/translate $(SRCDIR)/report.c >$(OBJDIR)/report_.c
898
899 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
900 $(XTCC) -o $(OBJDIR)/report.o -c $(OBJDIR)/report_.c
@@ -1018,10 +1031,17 @@
1031
1032 $(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
1033 $(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
1034
1035 $(OBJDIR)/undo.h: $(OBJDIR)/headers
1036 $(OBJDIR)/unicode_.c: $(SRCDIR)/unicode.c $(OBJDIR)/translate
1037 $(OBJDIR)/translate $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c
1038
1039 $(OBJDIR)/unicode.o: $(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
1040 $(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c
1041
1042 $(OBJDIR)/unicode.h: $(OBJDIR)/headers
1043 $(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
1044 $(OBJDIR)/translate $(SRCDIR)/update.c >$(OBJDIR)/update_.c
1045
1046 $(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
1047 $(XTCC) -o $(OBJDIR)/update.o -c $(OBJDIR)/update_.c
1048
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -84,10 +84,11 @@
8484
pivot
8585
popen
8686
pqueue
8787
printf
8888
rebuild
89
+ regexp
8990
report
9091
rss
9192
schema
9293
search
9394
setup
@@ -104,10 +105,11 @@
104105
th_main
105106
timeline
106107
tkt
107108
tktsetup
108109
undo
110
+ unicode
109111
update
110112
url
111113
user
112114
utf8
113115
verify
@@ -405,11 +407,11 @@
405407
406408
#### Check if the workaround for the MinGW command line handling needs to
407409
# be enabled by default.
408410
#
409411
ifndef BROKEN_MINGW_CMDLINE
410
-ifeq ($(PREFIX),)
412
+ifeq (,$(findstring w64-mingw32,$(PREFIX)))
411413
BROKEN_MINGW_CMDLINE = 1
412414
endif
413415
endif
414416
415417
#### The directories where the zlib include and library files are located.
416418
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -84,10 +84,11 @@
84 pivot
85 popen
86 pqueue
87 printf
88 rebuild
 
89 report
90 rss
91 schema
92 search
93 setup
@@ -104,10 +105,11 @@
104 th_main
105 timeline
106 tkt
107 tktsetup
108 undo
 
109 update
110 url
111 user
112 utf8
113 verify
@@ -405,11 +407,11 @@
405
406 #### Check if the workaround for the MinGW command line handling needs to
407 # be enabled by default.
408 #
409 ifndef BROKEN_MINGW_CMDLINE
410 ifeq ($(PREFIX),)
411 BROKEN_MINGW_CMDLINE = 1
412 endif
413 endif
414
415 #### The directories where the zlib include and library files are located.
416
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -84,10 +84,11 @@
84 pivot
85 popen
86 pqueue
87 printf
88 rebuild
89 regexp
90 report
91 rss
92 schema
93 search
94 setup
@@ -104,10 +105,11 @@
105 th_main
106 timeline
107 tkt
108 tktsetup
109 undo
110 unicode
111 update
112 url
113 user
114 utf8
115 verify
@@ -405,11 +407,11 @@
407
408 #### Check if the workaround for the MinGW command line handling needs to
409 # be enabled by default.
410 #
411 ifndef BROKEN_MINGW_CMDLINE
412 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
413 BROKEN_MINGW_CMDLINE = 1
414 endif
415 endif
416
417 #### The directories where the zlib include and library files are located.
418
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -84,10 +84,11 @@
8484
pivot
8585
popen
8686
pqueue
8787
printf
8888
rebuild
89
+ regexp
8990
report
9091
rss
9192
schema
9293
search
9394
setup
@@ -104,10 +105,11 @@
104105
th_main
105106
timeline
106107
tkt
107108
tktsetup
108109
undo
110
+ unicode
109111
update
110112
url
111113
user
112114
utf8
113115
verify
@@ -405,11 +407,11 @@
405407
406408
#### Check if the workaround for the MinGW command line handling needs to
407409
# be enabled by default.
408410
#
409411
ifndef BROKEN_MINGW_CMDLINE
410
-ifeq ($(PREFIX),)
412
+ifeq (,$(findstring w64-mingw32,$(PREFIX)))
411413
BROKEN_MINGW_CMDLINE = 1
412414
endif
413415
endif
414416
415417
#### The directories where the zlib include and library files are located.
416418
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -84,10 +84,11 @@
84 pivot
85 popen
86 pqueue
87 printf
88 rebuild
 
89 report
90 rss
91 schema
92 search
93 setup
@@ -104,10 +105,11 @@
104 th_main
105 timeline
106 tkt
107 tktsetup
108 undo
 
109 update
110 url
111 user
112 utf8
113 verify
@@ -405,11 +407,11 @@
405
406 #### Check if the workaround for the MinGW command line handling needs to
407 # be enabled by default.
408 #
409 ifndef BROKEN_MINGW_CMDLINE
410 ifeq ($(PREFIX),)
411 BROKEN_MINGW_CMDLINE = 1
412 endif
413 endif
414
415 #### The directories where the zlib include and library files are located.
416
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -84,10 +84,11 @@
84 pivot
85 popen
86 pqueue
87 printf
88 rebuild
89 regexp
90 report
91 rss
92 schema
93 search
94 setup
@@ -104,10 +105,11 @@
105 th_main
106 timeline
107 tkt
108 tktsetup
109 undo
110 unicode
111 update
112 url
113 user
114 utf8
115 verify
@@ -405,11 +407,11 @@
407
408 #### Check if the workaround for the MinGW command line handling needs to
409 # be enabled by default.
410 #
411 ifndef BROKEN_MINGW_CMDLINE
412 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
413 BROKEN_MINGW_CMDLINE = 1
414 endif
415 endif
416
417 #### The directories where the zlib include and library files are located.
418
+21 -3
--- src/manifest.c
+++ src/manifest.c
@@ -430,11 +430,11 @@
430430
zTarget = next_token(&x, &nTarget);
431431
zSrc = next_token(&x, &nSrc);
432432
if( zName==0 || zTarget==0 ) goto manifest_syntax_error;
433433
if( p->zAttachName!=0 ) goto manifest_syntax_error;
434434
defossilize(zName);
435
- if( !file_is_simple_pathname(zName) ){
435
+ if( !file_is_simple_pathname(zName, 0) ){
436436
SYNTAX("invalid filename on A-card");
437437
}
438438
defossilize(zTarget);
439439
if( (nTarget!=UUID_SIZE || !validate16(zTarget, UUID_SIZE))
440440
&& !wiki_name_is_wellformed((const unsigned char *)zTarget) ){
@@ -524,11 +524,11 @@
524524
case 'F': {
525525
char *zName, *zPerm, *zPriorName;
526526
zName = next_token(&x,0);
527527
if( zName==0 ) SYNTAX("missing filename on F-card");
528528
defossilize(zName);
529
- if( !file_is_simple_pathname(zName) ){
529
+ if( !file_is_simple_pathname(zName, 0) ){
530530
SYNTAX("F-card filename is not a simple path");
531531
}
532532
zUuid = next_token(&x, &sz);
533533
if( p->zBaseline==0 || zUuid!=0 ){
534534
if( sz!=UUID_SIZE ) SYNTAX("F-card UUID is the wrong size");
@@ -536,11 +536,11 @@
536536
}
537537
zPerm = next_token(&x,0);
538538
zPriorName = next_token(&x,0);
539539
if( zPriorName ){
540540
defossilize(zPriorName);
541
- if( !file_is_simple_pathname(zPriorName) ){
541
+ if( !file_is_simple_pathname(zPriorName, 0) ){
542542
SYNTAX("F-card old filename is not a simple path");
543543
}
544544
}
545545
if( p->nFile>=p->nFileAlloc ){
546546
p->nFileAlloc = p->nFileAlloc*2 + 10;
@@ -1983,5 +1983,23 @@
19831983
manifest_destroy(p);
19841984
}
19851985
assert( blob_is_reset(pContent) );
19861986
return 1;
19871987
}
1988
+
1989
+/*
1990
+** COMMAND: test-crosslink
1991
+**
1992
+** Usage: %fossil test-crosslink RECORDID
1993
+**
1994
+** Run the manifest_crosslink() routine on the artifact with the given
1995
+** record ID. This is typically done in the debugger.
1996
+*/
1997
+void test_crosslink_cmd(void){
1998
+ int rid;
1999
+ Blob content;
2000
+ db_find_and_open_repository(0, 0);
2001
+ if( g.argc!=3 ) usage("RECORDID");
2002
+ rid = name_to_rid(g.argv[2]);
2003
+ content_get(rid, &content);
2004
+ manifest_crosslink(rid, &content);
2005
+}
19882006
--- src/manifest.c
+++ src/manifest.c
@@ -430,11 +430,11 @@
430 zTarget = next_token(&x, &nTarget);
431 zSrc = next_token(&x, &nSrc);
432 if( zName==0 || zTarget==0 ) goto manifest_syntax_error;
433 if( p->zAttachName!=0 ) goto manifest_syntax_error;
434 defossilize(zName);
435 if( !file_is_simple_pathname(zName) ){
436 SYNTAX("invalid filename on A-card");
437 }
438 defossilize(zTarget);
439 if( (nTarget!=UUID_SIZE || !validate16(zTarget, UUID_SIZE))
440 && !wiki_name_is_wellformed((const unsigned char *)zTarget) ){
@@ -524,11 +524,11 @@
524 case 'F': {
525 char *zName, *zPerm, *zPriorName;
526 zName = next_token(&x,0);
527 if( zName==0 ) SYNTAX("missing filename on F-card");
528 defossilize(zName);
529 if( !file_is_simple_pathname(zName) ){
530 SYNTAX("F-card filename is not a simple path");
531 }
532 zUuid = next_token(&x, &sz);
533 if( p->zBaseline==0 || zUuid!=0 ){
534 if( sz!=UUID_SIZE ) SYNTAX("F-card UUID is the wrong size");
@@ -536,11 +536,11 @@
536 }
537 zPerm = next_token(&x,0);
538 zPriorName = next_token(&x,0);
539 if( zPriorName ){
540 defossilize(zPriorName);
541 if( !file_is_simple_pathname(zPriorName) ){
542 SYNTAX("F-card old filename is not a simple path");
543 }
544 }
545 if( p->nFile>=p->nFileAlloc ){
546 p->nFileAlloc = p->nFileAlloc*2 + 10;
@@ -1983,5 +1983,23 @@
1983 manifest_destroy(p);
1984 }
1985 assert( blob_is_reset(pContent) );
1986 return 1;
1987 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1988
--- src/manifest.c
+++ src/manifest.c
@@ -430,11 +430,11 @@
430 zTarget = next_token(&x, &nTarget);
431 zSrc = next_token(&x, &nSrc);
432 if( zName==0 || zTarget==0 ) goto manifest_syntax_error;
433 if( p->zAttachName!=0 ) goto manifest_syntax_error;
434 defossilize(zName);
435 if( !file_is_simple_pathname(zName, 0) ){
436 SYNTAX("invalid filename on A-card");
437 }
438 defossilize(zTarget);
439 if( (nTarget!=UUID_SIZE || !validate16(zTarget, UUID_SIZE))
440 && !wiki_name_is_wellformed((const unsigned char *)zTarget) ){
@@ -524,11 +524,11 @@
524 case 'F': {
525 char *zName, *zPerm, *zPriorName;
526 zName = next_token(&x,0);
527 if( zName==0 ) SYNTAX("missing filename on F-card");
528 defossilize(zName);
529 if( !file_is_simple_pathname(zName, 0) ){
530 SYNTAX("F-card filename is not a simple path");
531 }
532 zUuid = next_token(&x, &sz);
533 if( p->zBaseline==0 || zUuid!=0 ){
534 if( sz!=UUID_SIZE ) SYNTAX("F-card UUID is the wrong size");
@@ -536,11 +536,11 @@
536 }
537 zPerm = next_token(&x,0);
538 zPriorName = next_token(&x,0);
539 if( zPriorName ){
540 defossilize(zPriorName);
541 if( !file_is_simple_pathname(zPriorName, 0) ){
542 SYNTAX("F-card old filename is not a simple path");
543 }
544 }
545 if( p->nFile>=p->nFileAlloc ){
546 p->nFileAlloc = p->nFileAlloc*2 + 10;
@@ -1983,5 +1983,23 @@
1983 manifest_destroy(p);
1984 }
1985 assert( blob_is_reset(pContent) );
1986 return 1;
1987 }
1988
1989 /*
1990 ** COMMAND: test-crosslink
1991 **
1992 ** Usage: %fossil test-crosslink RECORDID
1993 **
1994 ** Run the manifest_crosslink() routine on the artifact with the given
1995 ** record ID. This is typically done in the debugger.
1996 */
1997 void test_crosslink_cmd(void){
1998 int rid;
1999 Blob content;
2000 db_find_and_open_repository(0, 0);
2001 if( g.argc!=3 ) usage("RECORDID");
2002 rid = name_to_rid(g.argv[2]);
2003 content_get(rid, &content);
2004 manifest_crosslink(rid, &content);
2005 }
2006
+1 -1
--- src/merge.c
+++ src/merge.c
@@ -87,11 +87,11 @@
8787
** option overrides the "binary-glob" setting.
8888
**
8989
** --nochange | -n Dryrun: do not actually make any changes; just
9090
** show what would have happened.
9191
**
92
-** --case-sensitive BOOL Overwrite the case-sensitive setting. If false,
92
+** --case-sensitive BOOL Override the case-sensitive setting. If false,
9393
** files whose names differ only in case are taken
9494
** to be the same file.
9595
**
9696
** --force | -f Force the merge even if it would be a no-op.
9797
*/
9898
--- src/merge.c
+++ src/merge.c
@@ -87,11 +87,11 @@
87 ** option overrides the "binary-glob" setting.
88 **
89 ** --nochange | -n Dryrun: do not actually make any changes; just
90 ** show what would have happened.
91 **
92 ** --case-sensitive BOOL Overwrite the case-sensitive setting. If false,
93 ** files whose names differ only in case are taken
94 ** to be the same file.
95 **
96 ** --force | -f Force the merge even if it would be a no-op.
97 */
98
--- src/merge.c
+++ src/merge.c
@@ -87,11 +87,11 @@
87 ** option overrides the "binary-glob" setting.
88 **
89 ** --nochange | -n Dryrun: do not actually make any changes; just
90 ** show what would have happened.
91 **
92 ** --case-sensitive BOOL Override the case-sensitive setting. If false,
93 ** files whose names differ only in case are taken
94 ** to be the same file.
95 **
96 ** --force | -f Force the merge even if it would be a no-op.
97 */
98
+2 -2
--- src/merge3.c
+++ src/merge3.c
@@ -175,12 +175,12 @@
175175
** is the number of lines of text to copy directly from the pivot,
176176
** the second integer is the number of lines of text to omit from the
177177
** pivot, and the third integer is the number of lines of text that are
178178
** inserted. The edit array ends with a triple of 0,0,0.
179179
*/
180
- aC1 = text_diff(pPivot, pV1, 0, 0);
181
- aC2 = text_diff(pPivot, pV2, 0, 0);
180
+ aC1 = text_diff(pPivot, pV1, 0, 0, 0);
181
+ aC2 = text_diff(pPivot, pV2, 0, 0, 0);
182182
if( aC1==0 || aC2==0 ){
183183
free(aC1);
184184
free(aC2);
185185
return -1;
186186
}
187187
188188
ADDED src/regexp.c
--- src/merge3.c
+++ src/merge3.c
@@ -175,12 +175,12 @@
175 ** is the number of lines of text to copy directly from the pivot,
176 ** the second integer is the number of lines of text to omit from the
177 ** pivot, and the third integer is the number of lines of text that are
178 ** inserted. The edit array ends with a triple of 0,0,0.
179 */
180 aC1 = text_diff(pPivot, pV1, 0, 0);
181 aC2 = text_diff(pPivot, pV2, 0, 0);
182 if( aC1==0 || aC2==0 ){
183 free(aC1);
184 free(aC2);
185 return -1;
186 }
187
188 DDED src/regexp.c
--- src/merge3.c
+++ src/merge3.c
@@ -175,12 +175,12 @@
175 ** is the number of lines of text to copy directly from the pivot,
176 ** the second integer is the number of lines of text to omit from the
177 ** pivot, and the third integer is the number of lines of text that are
178 ** inserted. The edit array ends with a triple of 0,0,0.
179 */
180 aC1 = text_diff(pPivot, pV1, 0, 0, 0);
181 aC2 = text_diff(pPivot, pV2, 0, 0, 0);
182 if( aC1==0 || aC2==0 ){
183 free(aC1);
184 free(aC2);
185 return -1;
186 }
187
188 DDED src/regexp.c
+55
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -0,0 +1,55 @@
1
+/*
2
+** Co#ifndef SQL(sizeof(aSp*
3
+** Co#ifndef SQLITE_MAX_REGEXP_REPEAT
4
+# define SQLITE_MAX_REGEXP_REPEAT 999
5
+#endifcharacter3CC_INC>0 &&ute a reasonable limit on the length of the REGEXP NFA.
6
+*/
7
+int re_maxlen(void){
8
+ return 1000) : 1000;
9
+}re_maxlen(), noCase) Co0);
10
+ /, 0 <= p,q <= 999*
11
+** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
12
+** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999 return 1; return 1
13
+*/
14
+static void grepprintfREPEAT
15
+# define SQLITE_MAX_REGEXP_REPEAT 999
16
+#endifcharacter3CC_INC>0 &&ute a reasonable limit on the length of the REGEXP NFA.
17
+*/
18
+int re_maxlen(void){
19
+ return 1000) : 1000;
20
+}re_maxlen(), noCase) Co0);
21
+ /, 0 <= p,q <= 999*
22
+** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
23
+** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999 return 1; return 1
24
+*/
25
+static void grepprintf har const
26
+ int argc, resqlite3char zInit[12];
27
+** Co#ifnde** Co#ifndef SQLITE_MAX_REGEXP_REPEAT
28
+# define SQLITE_MAX_REGEXP_REPEAT 999
29
+#endifcharacter3CC_INC>0 &&ute a reasonable limit on the length of the REGEXP NFA.
30
+*/
31
+int re_maxlen(void){
32
+ return 1000) : 1000;
33
+}re_maxlen(), noCase) Co0);
34
+ /, 0 <= p,q <= 999*
35
+** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
36
+** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999 return 1; return 1
37
+*/
38
+static void grepprintfREPEAT
39
+# define SQLITE_MAX_REGEXP_REPEAT 999
40
+#endifcharacter3CC_INC>0 &&ute a reasonable limit on X Where XXX is any number ofn the length of the REGEXP NF
41
+ return 1000) : 1000;
42
+}re_maxlen(), noCase) Co0);
43
+ /, 0 <= p,q <= 999*
44
+** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
45
+** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999 return 1; return 1
46
+*/
47
+static void grepprintf har const
48
+ int argc, resqlite3 strncmp(zIn+in.i, mem if( re_hex(zIn[1],&v) ){
49
+ += 3v;
50
+ }5v = 0;
51
+v = 0;
52
+ for(i=1; p->sIn.i<p->sIn.mx && re_hex(p->sIn.z[p->sIn.i+i], &v); i++){}
53
+ if( i>1 ){
54
+{
55
+ return 1000) :/
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -0,0 +1,55 @@
1 /*
2 ** Co#ifndef SQL(sizeof(aSp*
3 ** Co#ifndef SQLITE_MAX_REGEXP_REPEAT
4 # define SQLITE_MAX_REGEXP_REPEAT 999
5 #endifcharacter3CC_INC>0 &&ute a reasonable limit on the length of the REGEXP NFA.
6 */
7 int re_maxlen(void){
8 return 1000) : 1000;
9 }re_maxlen(), noCase) Co0);
10 /, 0 <= p,q <= 999*
11 ** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
12 ** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999 return 1; return 1
13 */
14 static void grepprintfREPEAT
15 # define SQLITE_MAX_REGEXP_REPEAT 999
16 #endifcharacter3CC_INC>0 &&ute a reasonable limit on the length of the REGEXP NFA.
17 */
18 int re_maxlen(void){
19 return 1000) : 1000;
20 }re_maxlen(), noCase) Co0);
21 /, 0 <= p,q <= 999*
22 ** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
23 ** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999 return 1; return 1
24 */
25 static void grepprintf har const
26 int argc, resqlite3char zInit[12];
27 ** Co#ifnde** Co#ifndef SQLITE_MAX_REGEXP_REPEAT
28 # define SQLITE_MAX_REGEXP_REPEAT 999
29 #endifcharacter3CC_INC>0 &&ute a reasonable limit on the length of the REGEXP NFA.
30 */
31 int re_maxlen(void){
32 return 1000) : 1000;
33 }re_maxlen(), noCase) Co0);
34 /, 0 <= p,q <= 999*
35 ** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
36 ** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999 return 1; return 1
37 */
38 static void grepprintfREPEAT
39 # define SQLITE_MAX_REGEXP_REPEAT 999
40 #endifcharacter3CC_INC>0 &&ute a reasonable limit on X Where XXX is any number ofn the length of the REGEXP NF
41 return 1000) : 1000;
42 }re_maxlen(), noCase) Co0);
43 /, 0 <= p,q <= 999*
44 ** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
45 ** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999 return 1; return 1
46 */
47 static void grepprintf har const
48 int argc, resqlite3 strncmp(zIn+in.i, mem if( re_hex(zIn[1],&v) ){
49 += 3v;
50 }5v = 0;
51 v = 0;
52 for(i=1; p->sIn.i<p->sIn.mx && re_hex(p->sIn.z[p->sIn.i+i], &v); i++){}
53 if( i>1 ){
54 {
55 return 1000) :/
--- src/report.c
+++ src/report.c
@@ -172,10 +172,11 @@
172172
break;
173173
}
174174
case SQLITE_READ: {
175175
static const char *const azAllowed[] = {
176176
"ticket",
177
+ "ticketchng",
177178
"blob",
178179
"filename",
179180
"mlink",
180181
"plink",
181182
"event",
182183
--- src/report.c
+++ src/report.c
@@ -172,10 +172,11 @@
172 break;
173 }
174 case SQLITE_READ: {
175 static const char *const azAllowed[] = {
176 "ticket",
 
177 "blob",
178 "filename",
179 "mlink",
180 "plink",
181 "event",
182
--- src/report.c
+++ src/report.c
@@ -172,10 +172,11 @@
172 break;
173 }
174 case SQLITE_READ: {
175 static const char *const azAllowed[] = {
176 "ticket",
177 "ticketchng",
178 "blob",
179 "filename",
180 "mlink",
181 "plink",
182 "event",
183
+47 -1
--- src/setup.c
+++ src/setup.c
@@ -94,11 +94,11 @@
9494
"Edit HTML text inserted at the top of every page");
9595
setup_menu_entry("Footer", "setup_footer",
9696
"Edit HTML text inserted at the bottom of every page");
9797
setup_menu_entry("Moderation", "setup_modreq",
9898
"Enable/Disable requiring moderator approval of Wiki and/or Ticket"
99
- "edits and attachments.");
99
+ " changes and attachments.");
100100
setup_menu_entry("Ad-Unit", "setup_adunit",
101101
"Edit HTML text for an ad unit inserted after the menu bar");
102102
setup_menu_entry("Logo", "setup_logo",
103103
"Change the logo and background images for the server");
104104
setup_menu_entry("Shunned", "shun",
@@ -109,10 +109,12 @@
109109
"A record of login attempts");
110110
setup_menu_entry("Stats", "stat",
111111
"Display repository statistics");
112112
setup_menu_entry("SQL", "admin_sql",
113113
"Enter raw SQL commands");
114
+ setup_menu_entry("TH1", "admin_th1",
115
+ "Enter raw TH1 commands");
114116
@ </table>
115117
116118
style_footer();
117119
}
118120
@@ -1759,8 +1761,52 @@
17591761
@ </tr>
17601762
}
17611763
sqlite3_finalize(pStmt);
17621764
@ </table>
17631765
}
1766
+ }
1767
+ style_footer();
1768
+}
1769
+
1770
+
1771
+/*
1772
+** WEBPAGE: admin_th1
1773
+**
1774
+** Run raw TH1 commands using the web interface. If Tcl integration was
1775
+** enabled at compile-time and the "tcl" setting is enabled, Tcl commands
1776
+** may be run as well.
1777
+*/
1778
+void th1_page(void){
1779
+ const char *zQ = P("q");
1780
+ int go = P("go")!=0;
1781
+ login_check_credentials();
1782
+ if( !g.perm.Setup ){
1783
+ login_needed();
1784
+ }
1785
+ db_begin_transaction();
1786
+ style_header("Raw TH1 Commands");
1787
+ @ <p><b>Caution:</b> There are no restrictions on the TH1 that can be
1788
+ @ run by this page. If Tcl integration was enabled at compile-time and
1789
+ @ the "tcl" setting is enabled, Tcl commands may be run as well.</p>
1790
+ @
1791
+ @ <form method="post" action="%s(g.zTop)/admin_th1">
1792
+ login_insert_csrf_secret();
1793
+ @ TH1:<br />
1794
+ @ <textarea name="q" rows="5" cols="80">%h(zQ)</textarea><br />
1795
+ @ <input type="submit" name="go" value="Run TH1">
1796
+ @ </form>
1797
+ if( go ){
1798
+ const char *zR;
1799
+ int rc;
1800
+ int n;
1801
+ @ <hr />
1802
+ login_verify_csrf_secret();
1803
+ rc = Th_Eval(g.interp, 0, zQ, -1);
1804
+ zR = Th_GetResult(g.interp, &n);
1805
+ if( rc==TH_OK ){
1806
+ @ <pre class="th1result">%h(zR)</pre>
1807
+ }else{
1808
+ @ <pre class="th1error">%h(zR)</pre>
1809
+ }
17641810
}
17651811
style_footer();
17661812
}
17671813
--- src/setup.c
+++ src/setup.c
@@ -94,11 +94,11 @@
94 "Edit HTML text inserted at the top of every page");
95 setup_menu_entry("Footer", "setup_footer",
96 "Edit HTML text inserted at the bottom of every page");
97 setup_menu_entry("Moderation", "setup_modreq",
98 "Enable/Disable requiring moderator approval of Wiki and/or Ticket"
99 "edits and attachments.");
100 setup_menu_entry("Ad-Unit", "setup_adunit",
101 "Edit HTML text for an ad unit inserted after the menu bar");
102 setup_menu_entry("Logo", "setup_logo",
103 "Change the logo and background images for the server");
104 setup_menu_entry("Shunned", "shun",
@@ -109,10 +109,12 @@
109 "A record of login attempts");
110 setup_menu_entry("Stats", "stat",
111 "Display repository statistics");
112 setup_menu_entry("SQL", "admin_sql",
113 "Enter raw SQL commands");
 
 
114 @ </table>
115
116 style_footer();
117 }
118
@@ -1759,8 +1761,52 @@
1759 @ </tr>
1760 }
1761 sqlite3_finalize(pStmt);
1762 @ </table>
1763 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1764 }
1765 style_footer();
1766 }
1767
--- src/setup.c
+++ src/setup.c
@@ -94,11 +94,11 @@
94 "Edit HTML text inserted at the top of every page");
95 setup_menu_entry("Footer", "setup_footer",
96 "Edit HTML text inserted at the bottom of every page");
97 setup_menu_entry("Moderation", "setup_modreq",
98 "Enable/Disable requiring moderator approval of Wiki and/or Ticket"
99 " changes and attachments.");
100 setup_menu_entry("Ad-Unit", "setup_adunit",
101 "Edit HTML text for an ad unit inserted after the menu bar");
102 setup_menu_entry("Logo", "setup_logo",
103 "Change the logo and background images for the server");
104 setup_menu_entry("Shunned", "shun",
@@ -109,10 +109,12 @@
109 "A record of login attempts");
110 setup_menu_entry("Stats", "stat",
111 "Display repository statistics");
112 setup_menu_entry("SQL", "admin_sql",
113 "Enter raw SQL commands");
114 setup_menu_entry("TH1", "admin_th1",
115 "Enter raw TH1 commands");
116 @ </table>
117
118 style_footer();
119 }
120
@@ -1759,8 +1761,52 @@
1761 @ </tr>
1762 }
1763 sqlite3_finalize(pStmt);
1764 @ </table>
1765 }
1766 }
1767 style_footer();
1768 }
1769
1770
1771 /*
1772 ** WEBPAGE: admin_th1
1773 **
1774 ** Run raw TH1 commands using the web interface. If Tcl integration was
1775 ** enabled at compile-time and the "tcl" setting is enabled, Tcl commands
1776 ** may be run as well.
1777 */
1778 void th1_page(void){
1779 const char *zQ = P("q");
1780 int go = P("go")!=0;
1781 login_check_credentials();
1782 if( !g.perm.Setup ){
1783 login_needed();
1784 }
1785 db_begin_transaction();
1786 style_header("Raw TH1 Commands");
1787 @ <p><b>Caution:</b> There are no restrictions on the TH1 that can be
1788 @ run by this page. If Tcl integration was enabled at compile-time and
1789 @ the "tcl" setting is enabled, Tcl commands may be run as well.</p>
1790 @
1791 @ <form method="post" action="%s(g.zTop)/admin_th1">
1792 login_insert_csrf_secret();
1793 @ TH1:<br />
1794 @ <textarea name="q" rows="5" cols="80">%h(zQ)</textarea><br />
1795 @ <input type="submit" name="go" value="Run TH1">
1796 @ </form>
1797 if( go ){
1798 const char *zR;
1799 int rc;
1800 int n;
1801 @ <hr />
1802 login_verify_csrf_secret();
1803 rc = Th_Eval(g.interp, 0, zQ, -1);
1804 zR = Th_GetResult(g.interp, &n);
1805 if( rc==TH_OK ){
1806 @ <pre class="th1result">%h(zR)</pre>
1807 }else{
1808 @ <pre class="th1error">%h(zR)</pre>
1809 }
1810 }
1811 style_footer();
1812 }
1813
--- src/shell.c
+++ src/shell.c
@@ -1477,10 +1477,16 @@
14771477
p->zDbFilename, sqlite3_errmsg(db));
14781478
exit(1);
14791479
}
14801480
#ifndef SQLITE_OMIT_LOAD_EXTENSION
14811481
sqlite3_enable_load_extension(p->db, 1);
1482
+#endif
1483
+#ifdef SQLITE_ENABLE_REGEXP
1484
+ {
1485
+ extern int sqlite3_add_regexp_func(sqlite3*);
1486
+ sqlite3_add_regexp_func(db);
1487
+ }
14821488
#endif
14831489
}
14841490
}
14851491
14861492
/*
14871493
--- src/shell.c
+++ src/shell.c
@@ -1477,10 +1477,16 @@
1477 p->zDbFilename, sqlite3_errmsg(db));
1478 exit(1);
1479 }
1480 #ifndef SQLITE_OMIT_LOAD_EXTENSION
1481 sqlite3_enable_load_extension(p->db, 1);
 
 
 
 
 
 
1482 #endif
1483 }
1484 }
1485
1486 /*
1487
--- src/shell.c
+++ src/shell.c
@@ -1477,10 +1477,16 @@
1477 p->zDbFilename, sqlite3_errmsg(db));
1478 exit(1);
1479 }
1480 #ifndef SQLITE_OMIT_LOAD_EXTENSION
1481 sqlite3_enable_load_extension(p->db, 1);
1482 #endif
1483 #ifdef SQLITE_ENABLE_REGEXP
1484 {
1485 extern int sqlite3_add_regexp_func(sqlite3*);
1486 sqlite3_add_regexp_func(db);
1487 }
1488 #endif
1489 }
1490 }
1491
1492 /*
1493
+12 -7
--- src/skins.c
+++ src/skins.c
@@ -355,12 +355,13 @@
355355
@ div.footer a:visited { color: white; }
356356
@ div.footer a:hover { background-color: white; color: #558195; }
357357
@
358358
@ /* <verbatim> blocks */
359359
@ pre.verbatim {
360
-@ background-color: #f5f5f5;
361
-@ padding: 0.5em;
360
+@ background-color: #f5f5f5;
361
+@ padding: 0.5em;
362
+@ white-space: pre-wrap;
362363
@ }
363364
@
364365
@ /* The label/value pairs on (for example) the ci page */
365366
@ table.label-value th {
366367
@ vertical-align: top;
@@ -595,12 +596,13 @@
595596
@ color: #555;
596597
@ }
597598
@
598599
@ /* <verbatim> blocks */
599600
@ pre.verbatim {
600
-@ background-color: #f5f5f5;
601
-@ padding: 0.5em;
601
+@ background-color: #f5f5f5;
602
+@ padding: 0.5em;
603
+@ white-space: pre-wrap;
602604
@ }
603605
@
604606
@ /* The label/value pairs on (for example) the ci page */
605607
@ table.label-value th {
606608
@ vertical-align: top;
@@ -1083,13 +1085,14 @@
10831085
@ div.footer a:visited { color: white; }
10841086
@ div.footer a:hover { background-color: white; color: #558195; }
10851087
@
10861088
@ /* verbatim blocks */
10871089
@ pre.verbatim {
1088
-@ background-color: #f5f5f5;
1089
-@ padding: 0.5em;
1090
-@}
1090
+@ background-color: #f5f5f5;
1091
+@ padding: 0.5em;
1092
+@ white-space: pre-wrap;
1093
+@ }
10911094
@
10921095
@ /* The label/value pairs on (for example) the ci page */
10931096
@ table.label-value th {
10941097
@ vertical-align: top;
10951098
@ text-align: right;
@@ -1226,10 +1229,12 @@
12261229
@ }
12271230
@ set version [getVersion $manifest_version]
12281231
@ set tclVersion [getTclVersion]
12291232
@ set fossilUrl http://www.fossil-scm.org
12301233
@ </th1>
1234
+@ This page was generated in about
1235
+@ <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by
12311236
@ <a href="$fossilUrl/">Fossil</a>
12321237
@ version $release_version $tclVersion
12331238
@ <a href="$fossilUrl/index.html/info/$version">$manifest_version</a>
12341239
@ <a href="$fossilUrl/fossil/timeline?c=$manifest_date&amp;y=ci">$manifest_date</a>
12351240
@ </div>
12361241
--- src/skins.c
+++ src/skins.c
@@ -355,12 +355,13 @@
355 @ div.footer a:visited { color: white; }
356 @ div.footer a:hover { background-color: white; color: #558195; }
357 @
358 @ /* <verbatim> blocks */
359 @ pre.verbatim {
360 @ background-color: #f5f5f5;
361 @ padding: 0.5em;
 
362 @ }
363 @
364 @ /* The label/value pairs on (for example) the ci page */
365 @ table.label-value th {
366 @ vertical-align: top;
@@ -595,12 +596,13 @@
595 @ color: #555;
596 @ }
597 @
598 @ /* <verbatim> blocks */
599 @ pre.verbatim {
600 @ background-color: #f5f5f5;
601 @ padding: 0.5em;
 
602 @ }
603 @
604 @ /* The label/value pairs on (for example) the ci page */
605 @ table.label-value th {
606 @ vertical-align: top;
@@ -1083,13 +1085,14 @@
1083 @ div.footer a:visited { color: white; }
1084 @ div.footer a:hover { background-color: white; color: #558195; }
1085 @
1086 @ /* verbatim blocks */
1087 @ pre.verbatim {
1088 @ background-color: #f5f5f5;
1089 @ padding: 0.5em;
1090 @}
 
1091 @
1092 @ /* The label/value pairs on (for example) the ci page */
1093 @ table.label-value th {
1094 @ vertical-align: top;
1095 @ text-align: right;
@@ -1226,10 +1229,12 @@
1226 @ }
1227 @ set version [getVersion $manifest_version]
1228 @ set tclVersion [getTclVersion]
1229 @ set fossilUrl http://www.fossil-scm.org
1230 @ </th1>
 
 
1231 @ <a href="$fossilUrl/">Fossil</a>
1232 @ version $release_version $tclVersion
1233 @ <a href="$fossilUrl/index.html/info/$version">$manifest_version</a>
1234 @ <a href="$fossilUrl/fossil/timeline?c=$manifest_date&amp;y=ci">$manifest_date</a>
1235 @ </div>
1236
--- src/skins.c
+++ src/skins.c
@@ -355,12 +355,13 @@
355 @ div.footer a:visited { color: white; }
356 @ div.footer a:hover { background-color: white; color: #558195; }
357 @
358 @ /* <verbatim> blocks */
359 @ pre.verbatim {
360 @ background-color: #f5f5f5;
361 @ padding: 0.5em;
362 @ white-space: pre-wrap;
363 @ }
364 @
365 @ /* The label/value pairs on (for example) the ci page */
366 @ table.label-value th {
367 @ vertical-align: top;
@@ -595,12 +596,13 @@
596 @ color: #555;
597 @ }
598 @
599 @ /* <verbatim> blocks */
600 @ pre.verbatim {
601 @ background-color: #f5f5f5;
602 @ padding: 0.5em;
603 @ white-space: pre-wrap;
604 @ }
605 @
606 @ /* The label/value pairs on (for example) the ci page */
607 @ table.label-value th {
608 @ vertical-align: top;
@@ -1083,13 +1085,14 @@
1085 @ div.footer a:visited { color: white; }
1086 @ div.footer a:hover { background-color: white; color: #558195; }
1087 @
1088 @ /* verbatim blocks */
1089 @ pre.verbatim {
1090 @ background-color: #f5f5f5;
1091 @ padding: 0.5em;
1092 @ white-space: pre-wrap;
1093 @ }
1094 @
1095 @ /* The label/value pairs on (for example) the ci page */
1096 @ table.label-value th {
1097 @ vertical-align: top;
1098 @ text-align: right;
@@ -1226,10 +1229,12 @@
1229 @ }
1230 @ set version [getVersion $manifest_version]
1231 @ set tclVersion [getTclVersion]
1232 @ set fossilUrl http://www.fossil-scm.org
1233 @ </th1>
1234 @ This page was generated in about
1235 @ <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by
1236 @ <a href="$fossilUrl/">Fossil</a>
1237 @ version $release_version $tclVersion
1238 @ <a href="$fossilUrl/index.html/info/$version">$manifest_version</a>
1239 @ <a href="$fossilUrl/fossil/timeline?c=$manifest_date&amp;y=ci">$manifest_date</a>
1240 @ </div>
1241
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -118,10 +118,11 @@
118118
sqlcmd_content, 0, 0);
119119
sqlite3_create_function(db, "compress", 1, SQLITE_ANY, 0,
120120
sqlcmd_compress, 0, 0);
121121
sqlite3_create_function(db, "decompress", 1, SQLITE_ANY, 0,
122122
sqlcmd_decompress, 0, 0);
123
+ re_add_sql_func(db);
123124
g.repositoryOpen = 1;
124125
g.db = db;
125126
return SQLITE_OK;
126127
}
127128
128129
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -118,10 +118,11 @@
118 sqlcmd_content, 0, 0);
119 sqlite3_create_function(db, "compress", 1, SQLITE_ANY, 0,
120 sqlcmd_compress, 0, 0);
121 sqlite3_create_function(db, "decompress", 1, SQLITE_ANY, 0,
122 sqlcmd_decompress, 0, 0);
 
123 g.repositoryOpen = 1;
124 g.db = db;
125 return SQLITE_OK;
126 }
127
128
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -118,10 +118,11 @@
118 sqlcmd_content, 0, 0);
119 sqlite3_create_function(db, "compress", 1, SQLITE_ANY, 0,
120 sqlcmd_compress, 0, 0);
121 sqlite3_create_function(db, "decompress", 1, SQLITE_ANY, 0,
122 sqlcmd_decompress, 0, 0);
123 re_add_sql_func(db);
124 g.repositoryOpen = 1;
125 g.db = db;
126 return SQLITE_OK;
127 }
128
129
+844 -470
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
11
/******************************************************************************
22
** This file is an amalgamation of many separate C source files from SQLite
3
-** version 3.7.15. By combining all the individual C code files into this
3
+** version 3.7.16. By combining all the individual C code files into this
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -671,13 +671,13 @@
671671
**
672672
** See also: [sqlite3_libversion()],
673673
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674674
** [sqlite_version()] and [sqlite_source_id()].
675675
*/
676
-#define SQLITE_VERSION "3.7.15"
677
-#define SQLITE_VERSION_NUMBER 3007015
678
-#define SQLITE_SOURCE_ID "2012-10-16 23:08:28 f021559d8a23934e3bdccad5b55fc7a91d185f53"
676
+#define SQLITE_VERSION "3.7.16"
677
+#define SQLITE_VERSION_NUMBER 3007016
678
+#define SQLITE_SOURCE_ID "2012-12-08 06:46:05 e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0"
679679
680680
/*
681681
** CAPI3REF: Run-Time Library Version Numbers
682682
** KEYWORDS: sqlite3_version, sqlite3_sourceid
683683
**
@@ -2162,11 +2162,11 @@
21622162
** database connection is opened. By default, URI handling is globally
21632163
** disabled. The default value may be changed by compiling with the
21642164
** [SQLITE_USE_URI] symbol defined.
21652165
**
21662166
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
2167
-** <dd> This option taks a single integer argument which is interpreted as
2167
+** <dd> This option takes a single integer argument which is interpreted as
21682168
** a boolean in order to enable or disable the use of covering indices for
21692169
** full table scans in the query optimizer. The default setting is determined
21702170
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
21712171
** if that compile-time option is omitted.
21722172
** The ability to disable the use of covering indices for full table scans
@@ -10573,24 +10573,24 @@
1057310573
** and the value of Index.onError indicate the which conflict resolution
1057410574
** algorithm to employ whenever an attempt is made to insert a non-unique
1057510575
** element.
1057610576
*/
1057710577
struct Index {
10578
- char *zName; /* Name of this index */
10579
- int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10580
- tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
10581
- Table *pTable; /* The SQL table being indexed */
10582
- char *zColAff; /* String defining the affinity of each column */
10583
- Index *pNext; /* The next index associated with the same table */
10584
- Schema *pSchema; /* Schema containing this index */
10585
- u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
10586
- char **azColl; /* Array of collation sequence names for index */
10587
- int nColumn; /* Number of columns in the table used by this index */
10588
- int tnum; /* Page containing root of this index in database file */
10589
- u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10590
- u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
10591
- u8 bUnordered; /* Use this index for == or IN queries only */
10578
+ char *zName; /* Name of this index */
10579
+ int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10580
+ tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */
10581
+ Table *pTable; /* The SQL table being indexed */
10582
+ char *zColAff; /* String defining the affinity of each column */
10583
+ Index *pNext; /* The next index associated with the same table */
10584
+ Schema *pSchema; /* Schema containing this index */
10585
+ u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
10586
+ char **azColl; /* Array of collation sequence names for index */
10587
+ int tnum; /* DB Page containing root of this index */
10588
+ u16 nColumn; /* Number of columns in table used by this index */
10589
+ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10590
+ unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
10591
+ unsigned bUnordered:1; /* Use this index for == or IN queries only */
1059210592
#ifdef SQLITE_ENABLE_STAT3
1059310593
int nSample; /* Number of elements in aSample[] */
1059410594
tRowcnt avgEq; /* Average nEq value for key values not in aSample */
1059510595
IndexSample *aSample; /* Samples of the left-most key */
1059610596
#endif
@@ -10767,11 +10767,10 @@
1076710767
Expr *pRight; /* Right subnode */
1076810768
union {
1076910769
ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
1077010770
Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
1077110771
} x;
10772
- CollSeq *pColl; /* The collation type of the column or 0 */
1077310772
1077410773
/* If the EP_Reduced flag is set in the Expr.flags mask, then no
1077510774
** space is allocated for the fields below this point. An attempt to
1077610775
** access them will result in a segfault or malfunction.
1077710776
*********************************************************************/
@@ -10803,11 +10802,11 @@
1080310802
#define EP_Error 0x0008 /* Expression contains one or more errors */
1080410803
#define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
1080510804
#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
1080610805
#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
1080710806
#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
10808
-#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
10807
+#define EP_Collate 0x0100 /* Tree contains a TK_COLLATE opeartor */
1080910808
#define EP_FixedDest 0x0200 /* Result needed in a specific register */
1081010809
#define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
1081110810
#define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
1081210811
#define EP_Hint 0x1000 /* Not used */
1081310812
#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
@@ -10861,22 +10860,31 @@
1086110860
** name. An expr/name combination can be used in several ways, such
1086210861
** as the list of "expr AS ID" fields following a "SELECT" or in the
1086310862
** list of "ID = expr" items in an UPDATE. A list of expressions can
1086410863
** also be used as the argument to a function, in which case the a.zName
1086510864
** field is not used.
10865
+**
10866
+** By default the Expr.zSpan field holds a human-readable description of
10867
+** the expression that is used in the generation of error messages and
10868
+** column labels. In this case, Expr.zSpan is typically the text of a
10869
+** column expression as it exists in a SELECT statement. However, if
10870
+** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name
10871
+** of the result column in the form: DATABASE.TABLE.COLUMN. This later
10872
+** form is used for name resolution with nested FROM clauses.
1086610873
*/
1086710874
struct ExprList {
1086810875
int nExpr; /* Number of expressions on the list */
1086910876
int iECursor; /* VDBE Cursor associated with this ExprList */
1087010877
struct ExprList_item { /* For each expression in the list */
10871
- Expr *pExpr; /* The list of expressions */
10872
- char *zName; /* Token associated with this expression */
10873
- char *zSpan; /* Original text of the expression */
10874
- u8 sortOrder; /* 1 for DESC or 0 for ASC */
10875
- u8 done; /* A flag to indicate when processing is finished */
10876
- u16 iOrderByCol; /* For ORDER BY, column number in result set */
10877
- u16 iAlias; /* Index into Parse.aAlias[] for zName */
10878
+ Expr *pExpr; /* The list of expressions */
10879
+ char *zName; /* Token associated with this expression */
10880
+ char *zSpan; /* Original text of the expression */
10881
+ u8 sortOrder; /* 1 for DESC or 0 for ASC */
10882
+ unsigned done :1; /* A flag to indicate when processing is finished */
10883
+ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
10884
+ u16 iOrderByCol; /* For ORDER BY, column number in result set */
10885
+ u16 iAlias; /* Index into Parse.aAlias[] for zName */
1087810886
} *a; /* Alloc a power of two greater or equal to nExpr */
1087910887
};
1088010888
1088110889
/*
1088210890
** An instance of this structure is used by the parser to record both
@@ -11192,10 +11200,11 @@
1119211200
#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
1119311201
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
1119411202
#define SF_UseSorter 0x0040 /* Sort using a sorter */
1119511203
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
1119611204
#define SF_Materialize 0x0100 /* Force materialization of views */
11205
+#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
1119711206
1119811207
1119911208
/*
1120011209
** The results of a select can be distributed in several ways. The
1120111210
** "SRT" prefix means "SELECT Result Type".
@@ -11420,10 +11429,11 @@
1142011429
#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
1142111430
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
1142211431
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
1142311432
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
1142411433
#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
11434
+#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
1142511435
1142611436
/*
1142711437
* Each trigger present in the database schema is stored as an instance of
1142811438
* struct Trigger.
1142911439
*
@@ -11904,11 +11914,11 @@
1190411914
SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
1190511915
Token*, int, int);
1190611916
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
1190711917
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
1190811918
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
11909
- Expr*,ExprList*,int,Expr*,Expr*);
11919
+ Expr*,ExprList*,u16,Expr*,Expr*);
1191011920
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
1191111921
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
1191211922
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
1191311923
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
1191411924
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
@@ -12112,12 +12122,13 @@
1211212122
SQLITE_PRIVATE const char *sqlite3ErrStr(int);
1211312123
SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
1211412124
SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
1211512125
SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
1211612126
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
12117
-SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
12118
-SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
12127
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
12128
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
12129
+SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
1211912130
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
1212012131
SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
1212112132
SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
1212212133
SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
1212312134
SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
@@ -12160,10 +12171,11 @@
1216012171
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
1216112172
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
1216212173
SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
1216312174
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
1216412175
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
12176
+SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
1216512177
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
1216612178
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
1216712179
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
1216812180
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
1216912181
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -12298,12 +12310,14 @@
1229812310
#define sqlite3FkOldmask(a,b) 0
1229912311
#define sqlite3FkRequired(a,b,c,d) 0
1230012312
#endif
1230112313
#ifndef SQLITE_OMIT_FOREIGN_KEY
1230212314
SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*);
12315
+SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**);
1230312316
#else
1230412317
#define sqlite3FkDelete(a,b)
12318
+ #define sqlite3FkLocateIndex(a,b,c,d,e)
1230512319
#endif
1230612320
1230712321
1230812322
/*
1230912323
** Available fault injectors. Should be numbered beginning with 0.
@@ -23307,15 +23321,11 @@
2330723321
{ "pwrite64", (sqlite3_syscall_ptr)0, 0 },
2330823322
#endif
2330923323
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
2331023324
aSyscall[13].pCurrent)
2331123325
23312
-#if SQLITE_ENABLE_LOCKING_STYLE
2331323326
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
23314
-#else
23315
- { "fchmod", (sqlite3_syscall_ptr)0, 0 },
23316
-#endif
2331723327
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
2331823328
2331923329
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
2332023330
{ "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
2332123331
#else
@@ -23336,13 +23346,10 @@
2333623346
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
2333723347
2333823348
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
2333923349
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
2334023350
23341
- { "umask", (sqlite3_syscall_ptr)umask, 0 },
23342
-#define osUmask ((mode_t(*)(mode_t))aSyscall[21].pCurrent)
23343
-
2334423351
}; /* End of the overrideable system calls */
2334523352
2334623353
/*
2334723354
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
2334823355
** "unix" VFSes. Return SQLITE_OK opon successfully updating the
@@ -23443,31 +23450,29 @@
2344323450
** process that is able to write to the database will also be able to
2344423451
** recover the hot journals.
2344523452
*/
2344623453
static int robust_open(const char *z, int f, mode_t m){
2344723454
int fd;
23448
- mode_t m2;
23449
- mode_t origM = 0;
23450
- if( m==0 ){
23451
- m2 = SQLITE_DEFAULT_FILE_PERMISSIONS;
23452
- }else{
23453
- m2 = m;
23454
- origM = osUmask(0);
23455
- }
23455
+ mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
2345623456
do{
2345723457
#if defined(O_CLOEXEC)
2345823458
fd = osOpen(z,f|O_CLOEXEC,m2);
2345923459
#else
2346023460
fd = osOpen(z,f,m2);
2346123461
#endif
2346223462
}while( fd<0 && errno==EINTR );
23463
- if( m ){
23464
- osUmask(origM);
23465
- }
23463
+ if( fd>=0 ){
23464
+ if( m!=0 ){
23465
+ struct stat statbuf;
23466
+ if( osFstat(fd, &statbuf)==0 && (statbuf.st_mode&0777)!=m ){
23467
+ osFchmod(fd, m);
23468
+ }
23469
+ }
2346623470
#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
23467
- if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
23471
+ osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
2346823472
#endif
23473
+ }
2346923474
return fd;
2347023475
}
2347123476
2347223477
/*
2347323478
** Helper functions to obtain and relinquish the global mutex. The
@@ -29889,11 +29894,11 @@
2988929894
};
2989029895
unsigned int i; /* Loop counter */
2989129896
2989229897
/* Double-check that the aSyscall[] array has been constructed
2989329898
** correctly. See ticket [bb3a86e890c8e96ab] */
29894
- assert( ArraySize(aSyscall)==22 );
29899
+ assert( ArraySize(aSyscall)==21 );
2989529900
2989629901
/* Register all VFSes defined in the aVfs[] array */
2989729902
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
2989829903
sqlite3_vfs_register(&aVfs[i], i==0);
2989929904
}
@@ -56355,11 +56360,11 @@
5635556360
sqlite3BtreeLeave(p);
5635656361
return 0;
5635756362
}
5635856363
i = PENDING_BYTE_PAGE(pBt);
5635956364
if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
56360
- sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000);
56365
+ sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
5636156366
sCheck.errMsg.useMalloc = 2;
5636256367
5636356368
/* Check the integrity of the freelist
5636456369
*/
5636556370
checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
@@ -56890,11 +56895,16 @@
5689056895
/*
5689156896
** Parameter zSrcData points to a buffer containing the data for
5689256897
** page iSrcPg from the source database. Copy this data into the
5689356898
** destination database.
5689456899
*/
56895
-static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
56900
+static int backupOnePage(
56901
+ sqlite3_backup *p, /* Backup handle */
56902
+ Pgno iSrcPg, /* Source database page to backup */
56903
+ const u8 *zSrcData, /* Source database page data */
56904
+ int bUpdate /* True for an update, false otherwise */
56905
+){
5689656906
Pager * const pDestPager = sqlite3BtreePager(p->pDest);
5689756907
const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
5689856908
int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
5689956909
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
5690056910
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
@@ -56963,10 +56973,13 @@
5696356973
** cached parse of the page). MemPage.isInit is marked
5696456974
** "MUST BE FIRST" for this purpose.
5696556975
*/
5696656976
memcpy(zOut, zIn, nCopy);
5696756977
((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
56978
+ if( iOff==0 && bUpdate==0 ){
56979
+ sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc));
56980
+ }
5696856981
}
5696956982
sqlite3PagerUnref(pDestPg);
5697056983
}
5697156984
5697256985
return rc;
@@ -57069,11 +57082,11 @@
5706957082
const Pgno iSrcPg = p->iNext; /* Source page number */
5707057083
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
5707157084
DbPage *pSrcPg; /* Source page object */
5707257085
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
5707357086
if( rc==SQLITE_OK ){
57074
- rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg));
57087
+ rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
5707557088
sqlite3PagerUnref(pSrcPg);
5707657089
}
5707757090
}
5707857091
p->iNext++;
5707957092
}
@@ -57317,11 +57330,11 @@
5731757330
** the new data into the backup.
5731857331
*/
5731957332
int rc;
5732057333
assert( p->pDestDb );
5732157334
sqlite3_mutex_enter(p->pDestDb->mutex);
57322
- rc = backupOnePage(p, iPage, aData);
57335
+ rc = backupOnePage(p, iPage, aData, 1);
5732357336
sqlite3_mutex_leave(p->pDestDb->mutex);
5732457337
assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
5732557338
if( rc!=SQLITE_OK ){
5732657339
p->rc = rc;
5732757340
}
@@ -59434,26 +59447,22 @@
5943459447
assert( pKeyInfo->aSortOrder!=0 );
5943559448
sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
5943659449
i = sqlite3Strlen30(zTemp);
5943759450
for(j=0; j<pKeyInfo->nField; j++){
5943859451
CollSeq *pColl = pKeyInfo->aColl[j];
59439
- if( pColl ){
59440
- int n = sqlite3Strlen30(pColl->zName);
59441
- if( i+n>nTemp-6 ){
59442
- memcpy(&zTemp[i],",...",4);
59443
- break;
59444
- }
59445
- zTemp[i++] = ',';
59446
- if( pKeyInfo->aSortOrder[j] ){
59447
- zTemp[i++] = '-';
59448
- }
59449
- memcpy(&zTemp[i], pColl->zName,n+1);
59450
- i += n;
59451
- }else if( i+4<nTemp-6 ){
59452
- memcpy(&zTemp[i],",nil",4);
59453
- i += 4;
59454
- }
59452
+ const char *zColl = pColl ? pColl->zName : "nil";
59453
+ int n = sqlite3Strlen30(zColl);
59454
+ if( i+n>nTemp-6 ){
59455
+ memcpy(&zTemp[i],",...",4);
59456
+ break;
59457
+ }
59458
+ zTemp[i++] = ',';
59459
+ if( pKeyInfo->aSortOrder[j] ){
59460
+ zTemp[i++] = '-';
59461
+ }
59462
+ memcpy(&zTemp[i], zColl, n+1);
59463
+ i += n;
5945559464
}
5945659465
zTemp[i++] = ')';
5945759466
zTemp[i] = 0;
5945859467
assert( i<nTemp );
5945959468
break;
@@ -63839,11 +63848,13 @@
6383963848
#ifdef SQLITE_DEBUG
6384063849
/*
6384163850
** Print the value of a register for tracing purposes:
6384263851
*/
6384363852
static void memTracePrint(FILE *out, Mem *p){
63844
- if( p->flags & MEM_Null ){
63853
+ if( p->flags & MEM_Invalid ){
63854
+ fprintf(out, " undefined");
63855
+ }else if( p->flags & MEM_Null ){
6384563856
fprintf(out, " NULL");
6384663857
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
6384763858
fprintf(out, " si:%lld", p->u.i);
6384863859
}else if( p->flags & MEM_Int ){
6384963860
fprintf(out, " i:%lld", p->u.i);
@@ -64112,10 +64123,11 @@
6411264123
} af;
6411364124
struct OP_Concat_stack_vars {
6411464125
i64 nByte;
6411564126
} ag;
6411664127
struct OP_Remainder_stack_vars {
64128
+ char bIntint; /* Started out as two integer operands */
6411764129
int flags; /* Combined MEM_* flags from both inputs */
6411864130
i64 iA; /* Integer value of left operand */
6411964131
i64 iB; /* Integer value of right operand */
6412064132
double rA; /* Real value of left operand */
6412164133
double rB; /* Real value of right operand */
@@ -65021,10 +65033,13 @@
6502165033
pOut = &aMem[pOp->p2];
6502265034
assert( pOut!=pIn1 );
6502365035
while( 1 ){
6502465036
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
6502565037
Deephemeralize(pOut);
65038
+#ifdef SQLITE_DEBUG
65039
+ pOut->pScopyFrom = 0;
65040
+#endif
6502665041
REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
6502765042
if( (u.ae.n--)==0 ) break;
6502865043
pOut++;
6502965044
pIn1++;
6503065045
}
@@ -65214,10 +65229,11 @@
6521465229
case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
6521565230
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
6521665231
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
6521765232
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
6521865233
#if 0 /* local variables moved into u.ah */
65234
+ char bIntint; /* Started out as two integer operands */
6521965235
int flags; /* Combined MEM_* flags from both inputs */
6522065236
i64 iA; /* Integer value of left operand */
6522165237
i64 iB; /* Integer value of right operand */
6522265238
double rA; /* Real value of left operand */
6522365239
double rB; /* Real value of right operand */
@@ -65231,10 +65247,11 @@
6523165247
u.ah.flags = pIn1->flags | pIn2->flags;
6523265248
if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
6523365249
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
6523465250
u.ah.iA = pIn1->u.i;
6523565251
u.ah.iB = pIn2->u.i;
65252
+ u.ah.bIntint = 1;
6523665253
switch( pOp->opcode ){
6523765254
case OP_Add: if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
6523865255
case OP_Subtract: if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
6523965256
case OP_Multiply: if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
6524065257
case OP_Divide: {
@@ -65251,10 +65268,11 @@
6525165268
}
6525265269
}
6525365270
pOut->u.i = u.ah.iB;
6525465271
MemSetTypeFlag(pOut, MEM_Int);
6525565272
}else{
65273
+ u.ah.bIntint = 0;
6525665274
fp_math:
6525765275
u.ah.rA = sqlite3VdbeRealValue(pIn1);
6525865276
u.ah.rB = sqlite3VdbeRealValue(pIn2);
6525965277
switch( pOp->opcode ){
6526065278
case OP_Add: u.ah.rB += u.ah.rA; break;
@@ -65282,11 +65300,11 @@
6528265300
if( sqlite3IsNaN(u.ah.rB) ){
6528365301
goto arithmetic_result_is_null;
6528465302
}
6528565303
pOut->r = u.ah.rB;
6528665304
MemSetTypeFlag(pOut, MEM_Real);
65287
- if( (u.ah.flags & MEM_Real)==0 ){
65305
+ if( (u.ah.flags & MEM_Real)==0 && !u.ah.bIntint ){
6528865306
sqlite3VdbeIntegerAffinity(pOut);
6528965307
}
6529065308
#endif
6529165309
}
6529265310
break;
@@ -65843,26 +65861,31 @@
6584365861
/* Opcode: Permutation * * * P4 *
6584465862
**
6584565863
** Set the permutation used by the OP_Compare operator to be the array
6584665864
** of integers in P4.
6584765865
**
65848
-** The permutation is only valid until the next OP_Permutation, OP_Compare,
65849
-** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur
65850
-** immediately prior to the OP_Compare.
65866
+** The permutation is only valid until the next OP_Compare that has
65867
+** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
65868
+** occur immediately prior to the OP_Compare.
6585165869
*/
6585265870
case OP_Permutation: {
6585365871
assert( pOp->p4type==P4_INTARRAY );
6585465872
assert( pOp->p4.ai );
6585565873
aPermute = pOp->p4.ai;
6585665874
break;
6585765875
}
6585865876
65859
-/* Opcode: Compare P1 P2 P3 P4 *
65877
+/* Opcode: Compare P1 P2 P3 P4 P5
6586065878
**
6586165879
** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
6586265880
** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
6586365881
** the comparison for use by the next OP_Jump instruct.
65882
+**
65883
+** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is
65884
+** determined by the most recent OP_Permutation operator. If the
65885
+** OPFLAG_PERMUTE bit is clear, then register are compared in sequential
65886
+** order.
6586465887
**
6586565888
** P4 is a KeyInfo structure that defines collating sequences and sort
6586665889
** orders for the comparison. The permutation applies to registers
6586765890
** only. The KeyInfo elements are used sequentially.
6586865891
**
@@ -65880,10 +65903,11 @@
6588065903
int idx;
6588165904
CollSeq *pColl; /* Collating sequence to use on this term */
6588265905
int bRev; /* True for DESCENDING sort order */
6588365906
#endif /* local variables moved into u.al */
6588465907
65908
+ if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
6588565909
u.al.n = pOp->p3;
6588665910
u.al.pKeyInfo = pOp->p4.pKeyInfo;
6588765911
assert( u.al.n>0 );
6588865912
assert( u.al.pKeyInfo!=0 );
6588965913
u.al.p1 = pOp->p1;
@@ -66025,12 +66049,10 @@
6602566049
6602666050
/* Opcode: Once P1 P2 * * *
6602766051
**
6602866052
** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
6602966053
** set the flag and fall through to the next instruction.
66030
-**
66031
-** See also: JumpOnce
6603266054
*/
6603366055
case OP_Once: { /* jump */
6603466056
assert( pOp->p1<p->nOnceFlag );
6603566057
if( p->aOnceFlag[pOp->p1] ){
6603666058
pc = pOp->p2-1;
@@ -71902,10 +71924,18 @@
7190271924
p->pReal = pReal;
7190371925
if( p->iSize>0 ){
7190471926
assert(p->iSize<=p->nBuf);
7190571927
rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
7190671928
}
71929
+ if( rc!=SQLITE_OK ){
71930
+ /* If an error occurred while writing to the file, close it before
71931
+ ** returning. This way, SQLite uses the in-memory journal data to
71932
+ ** roll back changes made to the internal page-cache before this
71933
+ ** function was called. */
71934
+ sqlite3OsClose(pReal);
71935
+ p->pReal = 0;
71936
+ }
7190771937
}
7190871938
}
7190971939
return rc;
7191071940
}
7191171941
@@ -72565,10 +72595,19 @@
7256572595
** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
7256672596
**
7256772597
** The result of random()%5 in the GROUP BY clause is probably different
7256872598
** from the result in the result-set. We might fix this someday. Or
7256972599
** then again, we might not...
72600
+**
72601
+** If the reference is followed by a COLLATE operator, then make sure
72602
+** the COLLATE operator is preserved. For example:
72603
+**
72604
+** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
72605
+**
72606
+** Should be transformed into:
72607
+**
72608
+** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
7257072609
**
7257172610
** The nSubquery parameter specifies how many levels of subquery the
7257272611
** alias is removed from the original expression. The usually value is
7257372612
** zero but it might be more if the alias is contained within a subquery
7257472613
** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
@@ -72589,45 +72628,40 @@
7258972628
assert( iCol>=0 && iCol<pEList->nExpr );
7259072629
pOrig = pEList->a[iCol].pExpr;
7259172630
assert( pOrig!=0 );
7259272631
assert( pOrig->flags & EP_Resolved );
7259372632
db = pParse->db;
72633
+ pDup = sqlite3ExprDup(db, pOrig, 0);
72634
+ if( pDup==0 ) return;
7259472635
if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
72595
- pDup = sqlite3ExprDup(db, pOrig, 0);
7259672636
incrAggFunctionDepth(pDup, nSubquery);
7259772637
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
7259872638
if( pDup==0 ) return;
7259972639
if( pEList->a[iCol].iAlias==0 ){
7260072640
pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
7260172641
}
7260272642
pDup->iTable = pEList->a[iCol].iAlias;
72603
- }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
72604
- pDup = sqlite3ExprDup(db, pOrig, 0);
72605
- if( pDup==0 ) return;
72606
- }else{
72607
- char *zToken = pOrig->u.zToken;
72608
- assert( zToken!=0 );
72609
- pOrig->u.zToken = 0;
72610
- pDup = sqlite3ExprDup(db, pOrig, 0);
72611
- pOrig->u.zToken = zToken;
72612
- if( pDup==0 ) return;
72613
- assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
72614
- pDup->flags2 |= EP2_MallocedToken;
72615
- pDup->u.zToken = sqlite3DbStrDup(db, zToken);
72616
- }
72617
- if( pExpr->flags & EP_ExpCollate ){
72618
- pDup->pColl = pExpr->pColl;
72619
- pDup->flags |= EP_ExpCollate;
72643
+ }
72644
+ if( pExpr->op==TK_COLLATE ){
72645
+ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
7262072646
}
7262172647
7262272648
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
7262372649
** prevents ExprDelete() from deleting the Expr structure itself,
7262472650
** allowing it to be repopulated by the memcpy() on the following line.
72651
+ ** The pExpr->u.zToken might point into memory that will be freed by the
72652
+ ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
72653
+ ** make a copy of the token before doing the sqlite3DbFree().
7262572654
*/
7262672655
ExprSetProperty(pExpr, EP_Static);
7262772656
sqlite3ExprDelete(db, pExpr);
7262872657
memcpy(pExpr, pDup, sizeof(*pExpr));
72658
+ if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
72659
+ assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
72660
+ pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
72661
+ pExpr->flags2 |= EP2_MallocedToken;
72662
+ }
7262972663
sqlite3DbFree(db, pDup);
7263072664
}
7263172665
7263272666
7263372667
/*
@@ -72644,10 +72678,39 @@
7264472678
}
7264572679
}
7264672680
return 0;
7264772681
}
7264872682
72683
+/*
72684
+** Subqueries stores the original database, table and column names for their
72685
+** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN".
72686
+** Check to see if the zSpan given to this routine matches the zDb, zTab,
72687
+** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will
72688
+** match anything.
72689
+*/
72690
+SQLITE_PRIVATE int sqlite3MatchSpanName(
72691
+ const char *zSpan,
72692
+ const char *zCol,
72693
+ const char *zTab,
72694
+ const char *zDb
72695
+){
72696
+ int n;
72697
+ for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72698
+ if( zDb && sqlite3StrNICmp(zSpan, zDb, n)!=0 ){
72699
+ return 0;
72700
+ }
72701
+ zSpan += n+1;
72702
+ for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72703
+ if( zTab && sqlite3StrNICmp(zSpan, zTab, n)!=0 ){
72704
+ return 0;
72705
+ }
72706
+ zSpan += n+1;
72707
+ if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){
72708
+ return 0;
72709
+ }
72710
+ return 1;
72711
+}
7264972712
7265072713
/*
7265172714
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
7265272715
** that name in the set of source tables in pSrcList and make the pExpr
7265372716
** expression node refer back to that source column. The following changes
@@ -72699,44 +72762,63 @@
7269972762
7270072763
/* Initialize the node to no-match */
7270172764
pExpr->iTable = -1;
7270272765
pExpr->pTab = 0;
7270372766
ExprSetIrreducible(pExpr);
72767
+
72768
+ /* Translate the schema name in zDb into a pointer to the corresponding
72769
+ ** schema. If not found, pSchema will remain NULL and nothing will match
72770
+ ** resulting in an appropriate error message toward the end of this routine
72771
+ */
72772
+ if( zDb ){
72773
+ for(i=0; i<db->nDb; i++){
72774
+ assert( db->aDb[i].zName );
72775
+ if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
72776
+ pSchema = db->aDb[i].pSchema;
72777
+ break;
72778
+ }
72779
+ }
72780
+ }
7270472781
7270572782
/* Start at the inner-most context and move outward until a match is found */
7270672783
while( pNC && cnt==0 ){
7270772784
ExprList *pEList;
7270872785
SrcList *pSrcList = pNC->pSrcList;
7270972786
7271072787
if( pSrcList ){
7271172788
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
7271272789
Table *pTab;
72713
- int iDb;
7271472790
Column *pCol;
7271572791
7271672792
pTab = pItem->pTab;
7271772793
assert( pTab!=0 && pTab->zName!=0 );
72718
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
7271972794
assert( pTab->nCol>0 );
72795
+ if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
72796
+ ExprList *pEList = pItem->pSelect->pEList;
72797
+ int hit = 0;
72798
+ for(j=0; j<pEList->nExpr; j++){
72799
+ if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
72800
+ cnt++;
72801
+ cntTab = 2;
72802
+ pMatch = pItem;
72803
+ pExpr->iColumn = j;
72804
+ hit = 1;
72805
+ }
72806
+ }
72807
+ if( hit || zTab==0 ) continue;
72808
+ }
72809
+ if( zDb && pTab->pSchema!=pSchema ){
72810
+ continue;
72811
+ }
7272072812
if( zTab ){
72721
- if( pItem->zAlias ){
72722
- char *zTabName = pItem->zAlias;
72723
- if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
72724
- }else{
72725
- char *zTabName = pTab->zName;
72726
- if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){
72727
- continue;
72728
- }
72729
- if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
72730
- continue;
72731
- }
72813
+ const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
72814
+ assert( zTabName!=0 );
72815
+ if( sqlite3StrICmp(zTabName, zTab)!=0 ){
72816
+ continue;
7273272817
}
7273372818
}
7273472819
if( 0==(cntTab++) ){
72735
- pExpr->iTable = pItem->iCursor;
72736
- pExpr->pTab = pTab;
72737
- pSchema = pTab->pSchema;
7273872820
pMatch = pItem;
7273972821
}
7274072822
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
7274172823
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
7274272824
/* If there has been exactly one prior match and this match
@@ -72746,21 +72828,23 @@
7274672828
if( cnt==1 ){
7274772829
if( pItem->jointype & JT_NATURAL ) continue;
7274872830
if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
7274972831
}
7275072832
cnt++;
72751
- pExpr->iTable = pItem->iCursor;
72752
- pExpr->pTab = pTab;
7275372833
pMatch = pItem;
72754
- pSchema = pTab->pSchema;
7275572834
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
7275672835
pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
7275772836
break;
7275872837
}
7275972838
}
7276072839
}
72761
- }
72840
+ if( pMatch ){
72841
+ pExpr->iTable = pMatch->iCursor;
72842
+ pExpr->pTab = pMatch->pTab;
72843
+ pSchema = pExpr->pTab->pSchema;
72844
+ }
72845
+ } /* if( pSrcList ) */
7276272846
7276372847
#ifndef SQLITE_OMIT_TRIGGER
7276472848
/* If we have not already resolved the name, then maybe
7276572849
** it is a new.* or old.* trigger argument reference
7276672850
*/
@@ -73055,42 +73139,43 @@
7305573139
int wrong_num_args = 0; /* True if wrong number of arguments */
7305673140
int is_agg = 0; /* True if is an aggregate function */
7305773141
int auth; /* Authorization to use the function */
7305873142
int nId; /* Number of characters in function name */
7305973143
const char *zId; /* The function name. */
73060
- FuncDef *pDef; /* Information about the function */
7306173144
u8 enc = ENC(pParse->db); /* The database encoding */
7306273145
7306373146
testcase( pExpr->op==TK_CONST_FUNC );
7306473147
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
7306573148
zId = pExpr->u.zToken;
7306673149
nId = sqlite3Strlen30(zId);
73067
- pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
73068
- if( pDef==0 ){
73069
- pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
73070
- if( pDef==0 ){
73071
- no_such_func = 1;
73072
- }else{
73073
- wrong_num_args = 1;
73074
- }
73075
- }else{
73076
- is_agg = pDef->xFunc==0;
73077
- }
73078
-#ifndef SQLITE_OMIT_AUTHORIZATION
73079
- if( pDef ){
73080
- auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
73081
- if( auth!=SQLITE_OK ){
73082
- if( auth==SQLITE_DENY ){
73083
- sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
73084
- pDef->zName);
73085
- pNC->nErr++;
73086
- }
73087
- pExpr->op = TK_NULL;
73088
- return WRC_Prune;
73089
- }
73090
- }
73091
-#endif
73150
+ if( pParse->db->init.busy==0 ){
73151
+ FuncDef *pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
73152
+ if( pDef==0 ){
73153
+ pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
73154
+ if( pDef==0 ){
73155
+ no_such_func = 1;
73156
+ }else{
73157
+ wrong_num_args = 1;
73158
+ }
73159
+ }else{
73160
+ is_agg = pDef->xFunc==0;
73161
+ }
73162
+#ifndef SQLITE_OMIT_AUTHORIZATION
73163
+ if( pDef ){
73164
+ auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
73165
+ if( auth!=SQLITE_OK ){
73166
+ if( auth==SQLITE_DENY ){
73167
+ sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
73168
+ pDef->zName);
73169
+ pNC->nErr++;
73170
+ }
73171
+ pExpr->op = TK_NULL;
73172
+ return WRC_Prune;
73173
+ }
73174
+ }
73175
+#endif
73176
+ }
7309273177
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
7309373178
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
7309473179
pNC->nErr++;
7309573180
is_agg = 0;
7309673181
}else if( no_such_func ){
@@ -73310,11 +73395,11 @@
7331073395
assert( pEList!=0 );
7331173396
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
7331273397
int iCol = -1;
7331373398
Expr *pE, *pDup;
7331473399
if( pItem->done ) continue;
73315
- pE = pItem->pExpr;
73400
+ pE = sqlite3ExprSkipCollate(pItem->pExpr);
7331673401
if( sqlite3ExprIsInteger(pE, &iCol) ){
7331773402
if( iCol<=0 || iCol>pEList->nExpr ){
7331873403
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
7331973404
return 1;
7332073405
}
@@ -73328,18 +73413,24 @@
7332873413
}
7332973414
sqlite3ExprDelete(db, pDup);
7333073415
}
7333173416
}
7333273417
if( iCol>0 ){
73333
- CollSeq *pColl = pE->pColl;
73334
- int flags = pE->flags & EP_ExpCollate;
73418
+ /* Convert the ORDER BY term into an integer column number iCol,
73419
+ ** taking care to preserve the COLLATE clause if it exists */
73420
+ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
73421
+ if( pNew==0 ) return 1;
73422
+ pNew->flags |= EP_IntValue;
73423
+ pNew->u.iValue = iCol;
73424
+ if( pItem->pExpr==pE ){
73425
+ pItem->pExpr = pNew;
73426
+ }else{
73427
+ assert( pItem->pExpr->op==TK_COLLATE );
73428
+ assert( pItem->pExpr->pLeft==pE );
73429
+ pItem->pExpr->pLeft = pNew;
73430
+ }
7333573431
sqlite3ExprDelete(db, pE);
73336
- pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
73337
- if( pE==0 ) return 1;
73338
- pE->pColl = pColl;
73339
- pE->flags |= EP_IntValue | flags;
73340
- pE->u.iValue = iCol;
7334173432
pItem->iOrderByCol = (u16)iCol;
7334273433
pItem->done = 1;
7334373434
}else{
7334473435
moreToDo = 1;
7334573436
}
@@ -73440,15 +73531,15 @@
7344073531
** sqlite3ResolveOrderGroupBy() will convert the expression to a
7344173532
** copy of the iCol-th result-set expression. */
7344273533
pItem->iOrderByCol = (u16)iCol;
7344373534
continue;
7344473535
}
73445
- if( sqlite3ExprIsInteger(pE, &iCol) ){
73536
+ if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
7344673537
/* The ORDER BY term is an integer constant. Again, set the column
7344773538
** number so that sqlite3ResolveOrderGroupBy() will convert the
7344873539
** order-by term to a copy of the result-set expression */
73449
- if( iCol<1 ){
73540
+ if( iCol<1 || iCol>0xffff ){
7345073541
resolveOutOfRangeError(pParse, zType, i+1, nResult);
7345173542
return 1;
7345273543
}
7345373544
pItem->iOrderByCol = (u16)iCol;
7345473545
continue;
@@ -73521,27 +73612,10 @@
7352173612
if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
7352273613
sqlite3ResolveExprNames(&sNC, p->pOffset) ){
7352373614
return WRC_Abort;
7352473615
}
7352573616
73526
- /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
73527
- ** resolve the result-set expression list.
73528
- */
73529
- sNC.ncFlags = NC_AllowAgg;
73530
- sNC.pSrcList = p->pSrc;
73531
- sNC.pNext = pOuterNC;
73532
-
73533
- /* Resolve names in the result set. */
73534
- pEList = p->pEList;
73535
- assert( pEList!=0 );
73536
- for(i=0; i<pEList->nExpr; i++){
73537
- Expr *pX = pEList->a[i].pExpr;
73538
- if( sqlite3ResolveExprNames(&sNC, pX) ){
73539
- return WRC_Abort;
73540
- }
73541
- }
73542
-
7354373617
/* Recursively resolve names in all subqueries
7354473618
*/
7354573619
for(i=0; i<p->pSrc->nSrc; i++){
7354673620
struct SrcList_item *pItem = &p->pSrc->a[i];
7354773621
if( pItem->pSelect ){
@@ -73564,10 +73638,27 @@
7356473638
for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
7356573639
assert( pItem->isCorrelated==0 && nRef<=0 );
7356673640
pItem->isCorrelated = (nRef!=0);
7356773641
}
7356873642
}
73643
+
73644
+ /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
73645
+ ** resolve the result-set expression list.
73646
+ */
73647
+ sNC.ncFlags = NC_AllowAgg;
73648
+ sNC.pSrcList = p->pSrc;
73649
+ sNC.pNext = pOuterNC;
73650
+
73651
+ /* Resolve names in the result set. */
73652
+ pEList = p->pEList;
73653
+ assert( pEList!=0 );
73654
+ for(i=0; i<pEList->nExpr; i++){
73655
+ Expr *pX = pEList->a[i].pExpr;
73656
+ if( sqlite3ResolveExprNames(&sNC, pX) ){
73657
+ return WRC_Abort;
73658
+ }
73659
+ }
7356973660
7357073661
/* If there are no aggregate functions in the result-set, and no GROUP BY
7357173662
** expression, do not allow aggregates in any of the other expressions.
7357273663
*/
7357373664
assert( (p->selFlags & SF_Aggregate)==0 );
@@ -73798,11 +73889,13 @@
7379873889
** SELECT * FROM t1 WHERE a;
7379973890
** SELECT a AS b FROM t1 WHERE b;
7380073891
** SELECT * FROM t1 WHERE (select a from t1);
7380173892
*/
7380273893
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
73803
- int op = pExpr->op;
73894
+ int op;
73895
+ pExpr = sqlite3ExprSkipCollate(pExpr);
73896
+ op = pExpr->op;
7380473897
if( op==TK_SELECT ){
7380573898
assert( pExpr->flags&EP_xIsSelect );
7380673899
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
7380773900
}
7380873901
#ifndef SQLITE_OMIT_CAST
@@ -73823,70 +73916,98 @@
7382373916
}
7382473917
return pExpr->affinity;
7382573918
}
7382673919
7382773920
/*
73828
-** Set the explicit collating sequence for an expression to the
73829
-** collating sequence supplied in the second argument.
73830
-*/
73831
-SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){
73832
- if( pExpr && pColl ){
73833
- pExpr->pColl = pColl;
73834
- pExpr->flags |= EP_ExpCollate;
73835
- }
73836
- return pExpr;
73837
-}
73838
-
73839
-/*
73840
-** Set the collating sequence for expression pExpr to be the collating
73841
-** sequence named by pToken. Return a pointer to the revised expression.
73842
-** The collating sequence is marked as "explicit" using the EP_ExpCollate
73843
-** flag. An explicit collating sequence will override implicit
73844
-** collating sequences.
73845
-*/
73846
-SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){
73847
- char *zColl = 0; /* Dequoted name of collation sequence */
73848
- CollSeq *pColl;
73849
- sqlite3 *db = pParse->db;
73850
- zColl = sqlite3NameFromToken(db, pCollName);
73851
- pColl = sqlite3LocateCollSeq(pParse, zColl);
73852
- sqlite3ExprSetColl(pExpr, pColl);
73853
- sqlite3DbFree(db, zColl);
73854
- return pExpr;
73855
-}
73856
-
73857
-/*
73858
-** Return the default collation sequence for the expression pExpr. If
73859
-** there is no default collation type, return 0.
73860
-*/
73861
-SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
73862
- CollSeq *pColl = 0;
73863
- Expr *p = pExpr;
73864
- while( p ){
73865
- int op;
73866
- pColl = p->pColl;
73867
- if( pColl ) break;
73868
- op = p->op;
73869
- if( p->pTab!=0 && (
73870
- op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
73871
- )){
73872
- /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
73873
- ** a TK_COLUMN but was previously evaluated and cached in a register */
73874
- const char *zColl;
73875
- int j = p->iColumn;
73876
- if( j>=0 ){
73877
- sqlite3 *db = pParse->db;
73878
- zColl = p->pTab->aCol[j].zColl;
73879
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
73880
- pExpr->pColl = pColl;
73881
- }
73882
- break;
73883
- }
73884
- if( op!=TK_CAST && op!=TK_UPLUS ){
73885
- break;
73886
- }
73887
- p = p->pLeft;
73921
+** Set the collating sequence for expression pExpr to be the collating
73922
+** sequence named by pToken. Return a pointer to a new Expr node that
73923
+** implements the COLLATE operator.
73924
+**
73925
+** If a memory allocation error occurs, that fact is recorded in pParse->db
73926
+** and the pExpr parameter is returned unchanged.
73927
+*/
73928
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
73929
+ if( pCollName->n>0 ){
73930
+ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
73931
+ if( pNew ){
73932
+ pNew->pLeft = pExpr;
73933
+ pNew->flags |= EP_Collate;
73934
+ pExpr = pNew;
73935
+ }
73936
+ }
73937
+ return pExpr;
73938
+}
73939
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
73940
+ Token s;
73941
+ assert( zC!=0 );
73942
+ s.z = zC;
73943
+ s.n = sqlite3Strlen30(s.z);
73944
+ return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
73945
+}
73946
+
73947
+/*
73948
+** Skip over any TK_COLLATE and/or TK_AS operators at the root of
73949
+** an expression.
73950
+*/
73951
+SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
73952
+ while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
73953
+ pExpr = pExpr->pLeft;
73954
+ }
73955
+ return pExpr;
73956
+}
73957
+
73958
+/*
73959
+** Return the collation sequence for the expression pExpr. If
73960
+** there is no defined collating sequence, return NULL.
73961
+**
73962
+** The collating sequence might be determined by a COLLATE operator
73963
+** or by the presence of a column with a defined collating sequence.
73964
+** COLLATE operators take first precedence. Left operands take
73965
+** precedence over right operands.
73966
+*/
73967
+SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
73968
+ sqlite3 *db = pParse->db;
73969
+ CollSeq *pColl = 0;
73970
+ Expr *p = pExpr;
73971
+ while( p ){
73972
+ int op = p->op;
73973
+ if( op==TK_CAST || op==TK_UPLUS ){
73974
+ p = p->pLeft;
73975
+ continue;
73976
+ }
73977
+ assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
73978
+ if( op==TK_COLLATE ){
73979
+ if( db->init.busy ){
73980
+ /* Do not report errors when parsing while the schema */
73981
+ pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0);
73982
+ }else{
73983
+ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
73984
+ }
73985
+ break;
73986
+ }
73987
+ if( p->pTab!=0
73988
+ && (op==TK_AGG_COLUMN || op==TK_COLUMN
73989
+ || op==TK_REGISTER || op==TK_TRIGGER)
73990
+ ){
73991
+ /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
73992
+ ** a TK_COLUMN but was previously evaluated and cached in a register */
73993
+ int j = p->iColumn;
73994
+ if( j>=0 ){
73995
+ const char *zColl = p->pTab->aCol[j].zColl;
73996
+ pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
73997
+ }
73998
+ break;
73999
+ }
74000
+ if( p->flags & EP_Collate ){
74001
+ if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
74002
+ p = p->pLeft;
74003
+ }else{
74004
+ p = p->pRight;
74005
+ }
74006
+ }else{
74007
+ break;
74008
+ }
7388874009
}
7388974010
if( sqlite3CheckCollSeq(pParse, pColl) ){
7389074011
pColl = 0;
7389174012
}
7389274013
return pColl;
@@ -73986,16 +74107,14 @@
7398674107
Expr *pLeft,
7398774108
Expr *pRight
7398874109
){
7398974110
CollSeq *pColl;
7399074111
assert( pLeft );
73991
- if( pLeft->flags & EP_ExpCollate ){
73992
- assert( pLeft->pColl );
73993
- pColl = pLeft->pColl;
73994
- }else if( pRight && pRight->flags & EP_ExpCollate ){
73995
- assert( pRight->pColl );
73996
- pColl = pRight->pColl;
74112
+ if( pLeft->flags & EP_Collate ){
74113
+ pColl = sqlite3ExprCollSeq(pParse, pLeft);
74114
+ }else if( pRight && (pRight->flags & EP_Collate)!=0 ){
74115
+ pColl = sqlite3ExprCollSeq(pParse, pRight);
7399774116
}else{
7399874117
pColl = sqlite3ExprCollSeq(pParse, pLeft);
7399974118
if( !pColl ){
7400074119
pColl = sqlite3ExprCollSeq(pParse, pRight);
7400174120
}
@@ -74221,21 +74340,15 @@
7422174340
sqlite3ExprDelete(db, pLeft);
7422274341
sqlite3ExprDelete(db, pRight);
7422374342
}else{
7422474343
if( pRight ){
7422574344
pRoot->pRight = pRight;
74226
- if( pRight->flags & EP_ExpCollate ){
74227
- pRoot->flags |= EP_ExpCollate;
74228
- pRoot->pColl = pRight->pColl;
74229
- }
74345
+ pRoot->flags |= EP_Collate & pRight->flags;
7423074346
}
7423174347
if( pLeft ){
7423274348
pRoot->pLeft = pLeft;
74233
- if( pLeft->flags & EP_ExpCollate ){
74234
- pRoot->flags |= EP_ExpCollate;
74235
- pRoot->pColl = pLeft->pColl;
74236
- }
74349
+ pRoot->flags |= EP_Collate & pLeft->flags;
7423774350
}
7423874351
exprSetHeight(pRoot);
7423974352
}
7424074353
}
7424174354
@@ -74489,11 +74602,11 @@
7448974602
}else{
7449074603
assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
7449174604
assert( !ExprHasProperty(p, EP_FromJoin) );
7449274605
assert( (p->flags2 & EP2_MallocedToken)==0 );
7449374606
assert( (p->flags2 & EP2_Irreducible)==0 );
74494
- if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
74607
+ if( p->pLeft || p->pRight || p->x.pList ){
7449574608
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
7449674609
}else{
7449774610
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
7449874611
}
7449974612
}
@@ -76513,10 +76626,11 @@
7651376626
sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
7651476627
sqlite3ReleaseTempReg(pParse, r3);
7651576628
sqlite3ReleaseTempReg(pParse, r4);
7651676629
break;
7651776630
}
76631
+ case TK_COLLATE:
7651876632
case TK_UPLUS: {
7651976633
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
7652076634
break;
7652176635
}
7652276636
@@ -76881,10 +76995,16 @@
7688176995
case TK_UPLUS: zUniOp = "UPLUS"; break;
7688276996
case TK_BITNOT: zUniOp = "BITNOT"; break;
7688376997
case TK_NOT: zUniOp = "NOT"; break;
7688476998
case TK_ISNULL: zUniOp = "ISNULL"; break;
7688576999
case TK_NOTNULL: zUniOp = "NOTNULL"; break;
77000
+
77001
+ case TK_COLLATE: {
77002
+ sqlite3ExplainExpr(pOut, pExpr->pLeft);
77003
+ sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
77004
+ break;
77005
+ }
7688677006
7688777007
case TK_AGG_FUNCTION:
7688877008
case TK_CONST_FUNC:
7688977009
case TK_FUNCTION: {
7689077010
ExprList *pFarg; /* List of function arguments */
@@ -77019,10 +77139,16 @@
7701977139
for(i=0; i<pList->nExpr; i++){
7702077140
sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
7702177141
sqlite3ExplainPush(pOut);
7702277142
sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
7702377143
sqlite3ExplainPop(pOut);
77144
+ if( pList->a[i].zName ){
77145
+ sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
77146
+ }
77147
+ if( pList->a[i].bSpanIsTab ){
77148
+ sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
77149
+ }
7702477150
if( i<pList->nExpr-1 ){
7702577151
sqlite3ExplainNL(pOut);
7702677152
}
7702777153
}
7702877154
sqlite3ExplainPop(pOut);
@@ -77100,10 +77226,13 @@
7710077226
switch( pExpr->op ){
7710177227
case TK_IN:
7710277228
case TK_REGISTER: {
7710377229
return WRC_Prune;
7710477230
}
77231
+ case TK_COLLATE: {
77232
+ return WRC_Continue;
77233
+ }
7710577234
case TK_FUNCTION:
7710677235
case TK_AGG_FUNCTION:
7710777236
case TK_CONST_FUNC: {
7710877237
/* The arguments to a function have a fixed destination.
7710977238
** Mark them this way to avoid generated unneeded OP_SCopy
@@ -77121,13 +77250,15 @@
7712177250
break;
7712277251
}
7712377252
}
7712477253
if( isAppropriateForFactoring(pExpr) ){
7712577254
int r1 = ++pParse->nMem;
77126
- int r2;
77127
- r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
77128
- if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
77255
+ int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
77256
+ /* If r2!=r1, it means that register r1 is never used. That is harmless
77257
+ ** but suboptimal, so we want to know about the situation to fix it.
77258
+ ** Hence the following assert: */
77259
+ assert( r2==r1 );
7712977260
pExpr->op2 = pExpr->op;
7713077261
pExpr->op = TK_REGISTER;
7713177262
pExpr->iTable = r2;
7713277263
return WRC_Prune;
7713377264
}
@@ -77540,11 +77671,19 @@
7754077671
assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
7754177672
if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
7754277673
return 2;
7754377674
}
7754477675
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
77545
- if( pA->op!=pB->op ) return 2;
77676
+ if( pA->op!=pB->op ){
77677
+ if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
77678
+ return 1;
77679
+ }
77680
+ if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
77681
+ return 1;
77682
+ }
77683
+ return 2;
77684
+ }
7754677685
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
7754777686
if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
7754877687
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
7754977688
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
7755077689
if( ExprHasProperty(pA, EP_IntValue) ){
@@ -77552,15 +77691,13 @@
7755277691
return 2;
7755377692
}
7755477693
}else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
7755577694
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
7755677695
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
77557
- return 2;
77696
+ return pA->op==TK_COLLATE ? 1 : 2;
7755877697
}
7755977698
}
77560
- if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
77561
- if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
7756277699
return 0;
7756377700
}
7756477701
7756577702
/*
7756677703
** Compare two ExprList objects. Return 0 if they are identical and
@@ -83371,14 +83508,12 @@
8337183508
** specified collation sequence names.
8337283509
*/
8337383510
for(i=0; i<pList->nExpr; i++){
8337483511
Expr *pExpr = pList->a[i].pExpr;
8337583512
if( pExpr ){
83376
- CollSeq *pColl = pExpr->pColl;
83377
- /* Either pColl!=0 or there was an OOM failure. But if an OOM
83378
- ** failure we have quit before reaching this point. */
83379
- if( ALWAYS(pColl) ){
83513
+ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
83514
+ if( pColl ){
8338083515
nExtra += (1 + sqlite3Strlen30(pColl->zName));
8338183516
}
8338283517
}
8338383518
}
8338483519
@@ -83437,10 +83572,11 @@
8343783572
*/
8343883573
for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
8343983574
const char *zColName = pListItem->zName;
8344083575
Column *pTabCol;
8344183576
int requestedSortOrder;
83577
+ CollSeq *pColl; /* Collating sequence */
8344283578
char *zColl; /* Collation sequence name */
8344383579
8344483580
for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
8344583581
if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
8344683582
}
@@ -83449,18 +83585,15 @@
8344983585
pTab->zName, zColName);
8345083586
pParse->checkSchema = 1;
8345183587
goto exit_create_index;
8345283588
}
8345383589
pIndex->aiColumn[i] = j;
83454
- /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
83455
- ** the way the "idxlist" non-terminal is constructed by the parser,
83456
- ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
83457
- ** must exist or else there must have been an OOM error. But if there
83458
- ** was an OOM error, we would never reach this point. */
83459
- if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
83590
+ if( pListItem->pExpr
83591
+ && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
83592
+ ){
8346083593
int nColl;
83461
- zColl = pListItem->pExpr->pColl->zName;
83594
+ zColl = pColl->zName;
8346283595
nColl = sqlite3Strlen30(zColl) + 1;
8346383596
assert( nExtra>=nColl );
8346483597
memcpy(zExtra, zColl, nColl);
8346583598
zColl = zExtra;
8346683599
zExtra += nColl;
@@ -87489,11 +87622,11 @@
8748987622
8749087623
/*
8749187624
** A foreign key constraint requires that the key columns in the parent
8749287625
** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
8749387626
** Given that pParent is the parent table for foreign key constraint pFKey,
87494
-** search the schema a unique index on the parent key columns.
87627
+** search the schema for a unique index on the parent key columns.
8749587628
**
8749687629
** If successful, zero is returned. If the parent key is an INTEGER PRIMARY
8749787630
** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx
8749887631
** is set to point to the unique index.
8749987632
**
@@ -87525,11 +87658,11 @@
8752587658
**
8752687659
** then non-zero is returned, and a "foreign key mismatch" error loaded
8752787660
** into pParse. If an OOM error occurs, non-zero is returned and the
8752887661
** pParse->db->mallocFailed flag is set.
8752987662
*/
87530
-static int locateFkeyIndex(
87663
+SQLITE_PRIVATE int sqlite3FkLocateIndex(
8753187664
Parse *pParse, /* Parse context to store any error in */
8753287665
Table *pParent, /* Parent table of FK constraint pFKey */
8753387666
FKey *pFKey, /* Foreign key to find index for */
8753487667
Index **ppIdx, /* OUT: Unique index on parent table */
8753587668
int **paiCol /* OUT: Map of index columns in pFKey */
@@ -87622,11 +87755,13 @@
8762287755
}
8762387756
}
8762487757
8762587758
if( !pIdx ){
8762687759
if( !pParse->disableTriggers ){
87627
- sqlite3ErrorMsg(pParse, "foreign key mismatch");
87760
+ sqlite3ErrorMsg(pParse,
87761
+ "foreign key mismatch - \"%w\" referencing \"%w\"",
87762
+ pFKey->pFrom->zName, pFKey->zTo);
8762887763
}
8762987764
sqlite3DbFree(pParse->db, aiCol);
8763087765
return 1;
8763187766
}
8763287767
@@ -87858,16 +87993,19 @@
8785887993
if( pLeft ){
8785987994
/* Set the collation sequence and affinity of the LHS of each TK_EQ
8786087995
** expression to the parent key column defaults. */
8786187996
if( pIdx ){
8786287997
Column *pCol;
87998
+ const char *zColl;
8786387999
iCol = pIdx->aiColumn[i];
8786488000
pCol = &pTab->aCol[iCol];
8786588001
if( pTab->iPKey==iCol ) iCol = -1;
8786688002
pLeft->iTable = regData+iCol+1;
8786788003
pLeft->affinity = pCol->affinity;
87868
- pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl);
88004
+ zColl = pCol->zColl;
88005
+ if( zColl==0 ) zColl = db->pDfltColl->zName;
88006
+ pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
8786988007
}else{
8787088008
pLeft->iTable = regData;
8787188009
pLeft->affinity = SQLITE_AFF_INTEGER;
8787288010
}
8787388011
}
@@ -88080,11 +88218,11 @@
8808088218
if( pParse->disableTriggers ){
8808188219
pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
8808288220
}else{
8808388221
pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
8808488222
}
88085
- if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
88223
+ if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
8808688224
assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
8808788225
if( !isIgnoreErrors || db->mallocFailed ) return;
8808888226
if( pTo==0 ){
8808988227
/* If isIgnoreErrors is true, then a table is being dropped. In this
8809088228
** case SQLite runs a "DELETE FROM xxx" on the table being dropped
@@ -88160,11 +88298,11 @@
8816088298
/* Inserting a single row into a parent table cannot cause an immediate
8816188299
** foreign key violation. So do nothing in this case. */
8816288300
continue;
8816388301
}
8816488302
88165
- if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
88303
+ if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
8816688304
if( !isIgnoreErrors || db->mallocFailed ) return;
8816788305
continue;
8816888306
}
8816988307
assert( aiCol || pFKey->nCol==1 );
8817088308
@@ -88215,11 +88353,11 @@
8821588353
for(p=pTab->pFKey; p; p=p->pNextFrom){
8821688354
for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
8821788355
}
8821888356
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
8821988357
Index *pIdx = 0;
88220
- locateFkeyIndex(pParse, pTab, p, &pIdx, 0);
88358
+ sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
8822188359
if( pIdx ){
8822288360
for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
8822388361
}
8822488362
}
8822588363
}
@@ -88341,11 +88479,11 @@
8834188479
ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */
8834288480
Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */
8834388481
int i; /* Iterator variable */
8834488482
Expr *pWhen = 0; /* WHEN clause for the trigger */
8834588483
88346
- if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
88484
+ if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
8834788485
assert( aiCol || pFKey->nCol==1 );
8834888486
8834988487
for(i=0; i<pFKey->nCol; i++){
8835088488
Token tOld = { "old", 3 }; /* Literal "old" token */
8835188489
Token tNew = { "new", 3 }; /* Literal "new" token */
@@ -89843,29 +89981,24 @@
8984389981
ExprList *pCheck = pTab->pCheck;
8984489982
pParse->ckBase = regData;
8984589983
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
8984689984
for(i=0; i<pCheck->nExpr; i++){
8984789985
int allOk = sqlite3VdbeMakeLabel(v);
89848
- Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0);
89849
- if( !db->mallocFailed ){
89850
- assert( pDup!=0 );
89851
- sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL);
89852
- if( onError==OE_Ignore ){
89853
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
89854
- }else{
89855
- char *zConsName = pCheck->a[i].zName;
89856
- if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
89857
- if( zConsName ){
89858
- zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
89859
- }else{
89860
- zConsName = 0;
89861
- }
89862
- sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
89863
- }
89864
- sqlite3VdbeResolveLabel(v, allOk);
89865
- }
89866
- sqlite3ExprDelete(db, pDup);
89986
+ sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
89987
+ if( onError==OE_Ignore ){
89988
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
89989
+ }else{
89990
+ char *zConsName = pCheck->a[i].zName;
89991
+ if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
89992
+ if( zConsName ){
89993
+ zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
89994
+ }else{
89995
+ zConsName = 0;
89996
+ }
89997
+ sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
89998
+ }
89999
+ sqlite3VdbeResolveLabel(v, allOk);
8986790000
}
8986890001
}
8986990002
#endif /* !defined(SQLITE_OMIT_CHECK) */
8987090003
8987190004
/* If we have an INTEGER PRIMARY KEY, make sure the primary key
@@ -92686,13 +92819,15 @@
9268692819
if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
9268792820
Table *pTab;
9268892821
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
9268992822
pTab = sqlite3FindTable(db, zRight, zDb);
9269092823
if( pTab ){
92691
- int i;
92824
+ int i, k;
9269292825
int nHidden = 0;
9269392826
Column *pCol;
92827
+ Index *pPk;
92828
+ for(pPk=pTab->pIndex; pPk && pPk->autoIndex!=2; pPk=pPk->pNext){}
9269492829
sqlite3VdbeSetNumCols(v, 6);
9269592830
pParse->nMem = 6;
9269692831
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
9269792832
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
9269892833
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
@@ -92713,12 +92848,18 @@
9271392848
if( pCol->zDflt ){
9271492849
sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
9271592850
}else{
9271692851
sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
9271792852
}
92718
- sqlite3VdbeAddOp2(v, OP_Integer,
92719
- (pCol->colFlags&COLFLAG_PRIMKEY)!=0, 6);
92853
+ if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
92854
+ k = 0;
92855
+ }else if( pPk==0 ){
92856
+ k = 1;
92857
+ }else{
92858
+ for(k=1; ALWAYS(k<=pTab->nCol) && pPk->aiColumn[k-1]!=i; k++){}
92859
+ }
92860
+ sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
9272092861
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
9272192862
}
9272292863
}
9272392864
}else
9272492865
@@ -92849,10 +92990,124 @@
9284992990
++i;
9285092991
pFK = pFK->pNextFrom;
9285192992
}
9285292993
}
9285392994
}
92995
+ }else
92996
+#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
92997
+
92998
+#ifndef SQLITE_OMIT_FOREIGN_KEY
92999
+ if( sqlite3StrICmp(zLeft, "foreign_key_check")==0 ){
93000
+ FKey *pFK; /* A foreign key constraint */
93001
+ Table *pTab; /* Child table contain "REFERENCES" keyword */
93002
+ Table *pParent; /* Parent table that child points to */
93003
+ Index *pIdx; /* Index in the parent table */
93004
+ int i; /* Loop counter: Foreign key number for pTab */
93005
+ int j; /* Loop counter: Field of the foreign key */
93006
+ HashElem *k; /* Loop counter: Next table in schema */
93007
+ int x; /* result variable */
93008
+ int regResult; /* 3 registers to hold a result row */
93009
+ int regKey; /* Register to hold key for checking the FK */
93010
+ int regRow; /* Registers to hold a row from pTab */
93011
+ int addrTop; /* Top of a loop checking foreign keys */
93012
+ int addrOk; /* Jump here if the key is OK */
93013
+ int *aiCols; /* child to parent column mapping */
93014
+
93015
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
93016
+ regResult = pParse->nMem+1;
93017
+ pParse->nMem += 4;
93018
+ regKey = ++pParse->nMem;
93019
+ regRow = ++pParse->nMem;
93020
+ v = sqlite3GetVdbe(pParse);
93021
+ sqlite3VdbeSetNumCols(v, 4);
93022
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
93023
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC);
93024
+ sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "parent", SQLITE_STATIC);
93025
+ sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "fkid", SQLITE_STATIC);
93026
+ sqlite3CodeVerifySchema(pParse, iDb);
93027
+ k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
93028
+ while( k ){
93029
+ if( zRight ){
93030
+ pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
93031
+ k = 0;
93032
+ }else{
93033
+ pTab = (Table*)sqliteHashData(k);
93034
+ k = sqliteHashNext(k);
93035
+ }
93036
+ if( pTab==0 || pTab->pFKey==0 ) continue;
93037
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
93038
+ if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
93039
+ sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
93040
+ sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName,
93041
+ P4_TRANSIENT);
93042
+ for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
93043
+ pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
93044
+ if( pParent==0 ) break;
93045
+ pIdx = 0;
93046
+ sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
93047
+ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
93048
+ if( x==0 ){
93049
+ if( pIdx==0 ){
93050
+ sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
93051
+ }else{
93052
+ KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
93053
+ sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
93054
+ sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
93055
+ }
93056
+ }else{
93057
+ k = 0;
93058
+ break;
93059
+ }
93060
+ }
93061
+ if( pFK ) break;
93062
+ if( pParse->nTab<i ) pParse->nTab = i;
93063
+ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0);
93064
+ for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
93065
+ pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
93066
+ assert( pParent!=0 );
93067
+ pIdx = 0;
93068
+ aiCols = 0;
93069
+ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
93070
+ assert( x==0 );
93071
+ addrOk = sqlite3VdbeMakeLabel(v);
93072
+ if( pIdx==0 ){
93073
+ int iKey = pFK->aCol[0].iFrom;
93074
+ assert( iKey>=0 && iKey<pTab->nCol );
93075
+ if( iKey!=pTab->iPKey ){
93076
+ sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
93077
+ sqlite3ColumnDefault(v, pTab, iKey, regRow);
93078
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk);
93079
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
93080
+ sqlite3VdbeCurrentAddr(v)+3);
93081
+ }else{
93082
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
93083
+ }
93084
+ sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow);
93085
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
93086
+ sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
93087
+ }else{
93088
+ for(j=0; j<pFK->nCol; j++){
93089
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
93090
+ aiCols ? aiCols[j] : pFK->aCol[0].iFrom, regRow+j);
93091
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk);
93092
+ }
93093
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey);
93094
+ sqlite3VdbeChangeP4(v, -1,
93095
+ sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
93096
+ sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
93097
+ }
93098
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
93099
+ sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0,
93100
+ pFK->zTo, P4_TRANSIENT);
93101
+ sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+3);
93102
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
93103
+ sqlite3VdbeResolveLabel(v, addrOk);
93104
+ sqlite3DbFree(db, aiCols);
93105
+ }
93106
+ sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1);
93107
+ sqlite3VdbeJumpHere(v, addrTop);
93108
+ }
9285493109
}else
9285593110
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
9285693111
9285793112
#ifndef NDEBUG
9285893113
if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
@@ -94308,11 +94563,11 @@
9430894563
SrcList *pSrc, /* the FROM clause -- which tables to scan */
9430994564
Expr *pWhere, /* the WHERE clause */
9431094565
ExprList *pGroupBy, /* the GROUP BY clause */
9431194566
Expr *pHaving, /* the HAVING clause */
9431294567
ExprList *pOrderBy, /* the ORDER BY clause */
94313
- int isDistinct, /* true if the DISTINCT keyword is present */
94568
+ u16 selFlags, /* Flag parameters, such as SF_Distinct */
9431494569
Expr *pLimit, /* LIMIT value. NULL means not used */
9431594570
Expr *pOffset /* OFFSET value. NULL means no offset */
9431694571
){
9431794572
Select *pNew;
9431894573
Select standin;
@@ -94332,11 +94587,11 @@
9433294587
pNew->pSrc = pSrc;
9433394588
pNew->pWhere = pWhere;
9433494589
pNew->pGroupBy = pGroupBy;
9433594590
pNew->pHaving = pHaving;
9433694591
pNew->pOrderBy = pOrderBy;
94337
- pNew->selFlags = isDistinct ? SF_Distinct : 0;
94592
+ pNew->selFlags = selFlags;
9433894593
pNew->op = TK_SELECT;
9433994594
pNew->pLimit = pLimit;
9434094595
pNew->pOffset = pOffset;
9434194596
assert( pOffset==0 || pLimit!=0 );
9434294597
pNew->addrOpenEphm[0] = -1;
@@ -95588,13 +95843,11 @@
9558895843
*paCol = aCol;
9558995844
9559095845
for(i=0, pCol=aCol; i<nCol; i++, pCol++){
9559195846
/* Get an appropriate name for the column
9559295847
*/
95593
- p = pEList->a[i].pExpr;
95594
- assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
95595
- || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
95848
+ p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
9559695849
if( (zName = pEList->a[i].zName)!=0 ){
9559795850
/* If the column contains an "AS <name>" phrase, use <name> as the name */
9559895851
zName = sqlite3DbStrDup(db, zName);
9559995852
}else{
9560095853
Expr *pColExpr = p; /* The expression that is the result column name */
@@ -95628,10 +95881,13 @@
9562895881
*/
9562995882
nName = sqlite3Strlen30(zName);
9563095883
for(j=cnt=0; j<i; j++){
9563195884
if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
9563295885
char *zNewName;
95886
+ int k;
95887
+ for(k=nName-1; k>1 && sqlite3Isdigit(zName[k]); k--){}
95888
+ if( zName[k]==':' ) nName = k;
9563395889
zName[nName] = 0;
9563495890
zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
9563595891
sqlite3DbFree(db, zName);
9563695892
zName = zNewName;
9563795893
j = -1;
@@ -96586,16 +96842,17 @@
9658696842
pKeyMerge->nField = (u16)nOrderBy;
9658796843
pKeyMerge->enc = ENC(db);
9658896844
for(i=0; i<nOrderBy; i++){
9658996845
CollSeq *pColl;
9659096846
Expr *pTerm = pOrderBy->a[i].pExpr;
96591
- if( pTerm->flags & EP_ExpCollate ){
96592
- pColl = pTerm->pColl;
96847
+ if( pTerm->flags & EP_Collate ){
96848
+ pColl = sqlite3ExprCollSeq(pParse, pTerm);
9659396849
}else{
9659496850
pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
96595
- pTerm->flags |= EP_ExpCollate;
96596
- pTerm->pColl = pColl;
96851
+ if( pColl==0 ) pColl = db->pDfltColl;
96852
+ pOrderBy->a[i].pExpr =
96853
+ sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
9659796854
}
9659896855
pKeyMerge->aColl[i] = pColl;
9659996856
pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
9660096857
}
9660196858
}
@@ -96794,10 +97051,11 @@
9679497051
*/
9679597052
sqlite3VdbeResolveLabel(v, labelCmpr);
9679697053
sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
9679797054
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
9679897055
(char*)pKeyMerge, P4_KEYINFO_HANDOFF);
97056
+ sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
9679997057
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
9680097058
9680197059
/* Release temporary registers
9680297060
*/
9680397061
if( regPrev ){
@@ -96861,13 +97119,10 @@
9686197119
}else{
9686297120
Expr *pNew;
9686397121
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
9686497122
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
9686597123
pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
96866
- if( pNew && pExpr->pColl ){
96867
- pNew->pColl = pExpr->pColl;
96868
- }
9686997124
sqlite3ExprDelete(db, pExpr);
9687097125
pExpr = pNew;
9687197126
}
9687297127
}else{
9687397128
pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
@@ -97414,38 +97669,47 @@
9741497669
return 1;
9741597670
}
9741697671
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
9741797672
9741897673
/*
97419
-** Analyze the SELECT statement passed as an argument to see if it
97420
-** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if
97421
-** it is, or 0 otherwise. At present, a query is considered to be
97422
-** a min()/max() query if:
97423
-**
97424
-** 1. There is a single object in the FROM clause.
97425
-**
97426
-** 2. There is a single expression in the result set, and it is
97427
-** either min(x) or max(x), where x is a column reference.
97428
-*/
97429
-static u8 minMaxQuery(Select *p){
97430
- Expr *pExpr;
97431
- ExprList *pEList = p->pEList;
97432
-
97433
- if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
97434
- pExpr = pEList->a[0].pExpr;
97435
- if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
97436
- if( NEVER(ExprHasProperty(pExpr, EP_xIsSelect)) ) return 0;
97437
- pEList = pExpr->x.pList;
97438
- if( pEList==0 || pEList->nExpr!=1 ) return 0;
97439
- if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
97440
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
97441
- if( sqlite3StrICmp(pExpr->u.zToken,"min")==0 ){
97442
- return WHERE_ORDERBY_MIN;
97443
- }else if( sqlite3StrICmp(pExpr->u.zToken,"max")==0 ){
97444
- return WHERE_ORDERBY_MAX;
97445
- }
97446
- return WHERE_ORDERBY_NORMAL;
97674
+** Based on the contents of the AggInfo structure indicated by the first
97675
+** argument, this function checks if the following are true:
97676
+**
97677
+** * the query contains just a single aggregate function,
97678
+** * the aggregate function is either min() or max(), and
97679
+** * the argument to the aggregate function is a column value.
97680
+**
97681
+** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX
97682
+** is returned as appropriate. Also, *ppMinMax is set to point to the
97683
+** list of arguments passed to the aggregate before returning.
97684
+**
97685
+** Or, if the conditions above are not met, *ppMinMax is set to 0 and
97686
+** WHERE_ORDERBY_NORMAL is returned.
97687
+*/
97688
+static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){
97689
+ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
97690
+
97691
+ *ppMinMax = 0;
97692
+ if( pAggInfo->nFunc==1 ){
97693
+ Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */
97694
+ ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */
97695
+
97696
+ assert( pExpr->op==TK_AGG_FUNCTION );
97697
+ if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){
97698
+ const char *zFunc = pExpr->u.zToken;
97699
+ if( sqlite3StrICmp(zFunc, "min")==0 ){
97700
+ eRet = WHERE_ORDERBY_MIN;
97701
+ *ppMinMax = pEList;
97702
+ }else if( sqlite3StrICmp(zFunc, "max")==0 ){
97703
+ eRet = WHERE_ORDERBY_MAX;
97704
+ *ppMinMax = pEList;
97705
+ }
97706
+ }
97707
+ }
97708
+
97709
+ assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 );
97710
+ return eRet;
9744797711
}
9744897712
9744997713
/*
9745097714
** The select statement passed as the first argument is an aggregate query.
9745197715
** The second argment is the associated aggregate-info object. This
@@ -97536,10 +97800,11 @@
9753697800
int i, j, k;
9753797801
SrcList *pTabList;
9753897802
ExprList *pEList;
9753997803
struct SrcList_item *pFrom;
9754097804
sqlite3 *db = pParse->db;
97805
+ Expr *pE, *pRight, *pExpr;
9754197806
9754297807
if( db->mallocFailed ){
9754397808
return WRC_Abort;
9754497809
}
9754597810
if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
@@ -97621,11 +97886,11 @@
9762197886
**
9762297887
** The first loop just checks to see if there are any "*" operators
9762397888
** that need expanding.
9762497889
*/
9762597890
for(k=0; k<pEList->nExpr; k++){
97626
- Expr *pE = pEList->a[k].pExpr;
97891
+ pE = pEList->a[k].pExpr;
9762797892
if( pE->op==TK_ALL ) break;
9762897893
assert( pE->op!=TK_DOT || pE->pRight!=0 );
9762997894
assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
9763097895
if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
9763197896
}
@@ -97639,14 +97904,22 @@
9763997904
ExprList *pNew = 0;
9764097905
int flags = pParse->db->flags;
9764197906
int longNames = (flags & SQLITE_FullColNames)!=0
9764297907
&& (flags & SQLITE_ShortColNames)==0;
9764397908
97909
+ /* When processing FROM-clause subqueries, it is always the case
97910
+ ** that full_column_names=OFF and short_column_names=ON. The
97911
+ ** sqlite3ResultSetOfSelect() routine makes it so. */
97912
+ assert( (p->selFlags & SF_NestedFrom)==0
97913
+ || ((flags & SQLITE_FullColNames)==0 &&
97914
+ (flags & SQLITE_ShortColNames)!=0) );
97915
+
9764497916
for(k=0; k<pEList->nExpr; k++){
97645
- Expr *pE = a[k].pExpr;
97646
- assert( pE->op!=TK_DOT || pE->pRight!=0 );
97647
- if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight->op!=TK_ALL) ){
97917
+ pE = a[k].pExpr;
97918
+ pRight = pE->pRight;
97919
+ assert( pE->op!=TK_DOT || pRight!=0 );
97920
+ if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
9764897921
/* This particular expression does not need to be expanded.
9764997922
*/
9765097923
pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
9765197924
if( pNew ){
9765297925
pNew->a[pNew->nExpr-1].zName = a[k].zName;
@@ -97657,44 +97930,56 @@
9765797930
a[k].pExpr = 0;
9765897931
}else{
9765997932
/* This expression is a "*" or a "TABLE.*" and needs to be
9766097933
** expanded. */
9766197934
int tableSeen = 0; /* Set to 1 when TABLE matches */
97662
- char *zTName; /* text of name of TABLE */
97935
+ char *zTName = 0; /* text of name of TABLE */
9766397936
if( pE->op==TK_DOT ){
9766497937
assert( pE->pLeft!=0 );
9766597938
assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
9766697939
zTName = pE->pLeft->u.zToken;
97667
- }else{
97668
- zTName = 0;
9766997940
}
9767097941
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
9767197942
Table *pTab = pFrom->pTab;
97943
+ Select *pSub = pFrom->pSelect;
9767297944
char *zTabName = pFrom->zAlias;
97945
+ const char *zSchemaName = 0;
97946
+ int iDb;
9767397947
if( zTabName==0 ){
9767497948
zTabName = pTab->zName;
9767597949
}
9767697950
if( db->mallocFailed ) break;
97677
- if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
97678
- continue;
97951
+ if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
97952
+ pSub = 0;
97953
+ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
97954
+ continue;
97955
+ }
97956
+ iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
97957
+ zSchemaName = iDb>=0 ? db->aDb[iDb].zName : "*";
9767997958
}
97680
- tableSeen = 1;
9768197959
for(j=0; j<pTab->nCol; j++){
97682
- Expr *pExpr, *pRight;
9768397960
char *zName = pTab->aCol[j].zName;
9768497961
char *zColname; /* The computed column name */
9768597962
char *zToFree; /* Malloced string that needs to be freed */
9768697963
Token sColname; /* Computed column name as a token */
97964
+
97965
+ assert( zName );
97966
+ if( zTName && pSub
97967
+ && sqlite3MatchSpanName(pSub->pEList->a[j].zSpan, 0, zTName, 0)==0
97968
+ ){
97969
+ continue;
97970
+ }
9768797971
9768897972
/* If a column is marked as 'hidden' (currently only possible
9768997973
** for virtual tables), do not include it in the expanded
9769097974
** result-set list.
9769197975
*/
9769297976
if( IsHiddenColumn(&pTab->aCol[j]) ){
9769397977
assert(IsVirtual(pTab));
9769497978
continue;
9769597979
}
97980
+ tableSeen = 1;
9769697981
9769797982
if( i>0 && zTName==0 ){
9769897983
if( (pFrom->jointype & JT_NATURAL)!=0
9769997984
&& tableAndColumnIndex(pTabList, i, zName, 0, 0)
9770097985
){
@@ -97713,10 +97998,14 @@
9771397998
zToFree = 0;
9771497999
if( longNames || pTabList->nSrc>1 ){
9771598000
Expr *pLeft;
9771698001
pLeft = sqlite3Expr(db, TK_ID, zTabName);
9771798002
pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
98003
+ if( zSchemaName ){
98004
+ pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
98005
+ pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr, 0);
98006
+ }
9771898007
if( longNames ){
9771998008
zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
9772098009
zToFree = zColname;
9772198010
}
9772298011
}else{
@@ -97724,10 +98013,22 @@
9772498013
}
9772598014
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
9772698015
sColname.z = zColname;
9772798016
sColname.n = sqlite3Strlen30(zColname);
9772898017
sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
98018
+ if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
98019
+ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
98020
+ if( pSub ){
98021
+ pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan);
98022
+ testcase( pX->zSpan==0 );
98023
+ }else{
98024
+ pX->zSpan = sqlite3MPrintf(db, "%s.%s.%s",
98025
+ zSchemaName, zTabName, zColname);
98026
+ testcase( pX->zSpan==0 );
98027
+ }
98028
+ pX->bSpanIsTab = 1;
98029
+ }
9772998030
sqlite3DbFree(db, zToFree);
9773098031
}
9773198032
}
9773298033
if( !tableSeen ){
9773398034
if( zTName ){
@@ -98781,15 +99082,21 @@
9878199082
** index or indices to use) should place a different priority on
9878299083
** satisfying the 'ORDER BY' clause than it does in other cases.
9878399084
** Refer to code and comments in where.c for details.
9878499085
*/
9878599086
ExprList *pMinMax = 0;
98786
- u8 flag = minMaxQuery(p);
99087
+ u8 flag = WHERE_ORDERBY_NORMAL;
99088
+
99089
+ assert( p->pGroupBy==0 );
99090
+ assert( flag==0 );
99091
+ if( p->pHaving==0 ){
99092
+ flag = minMaxQuery(&sAggInfo, &pMinMax);
99093
+ }
99094
+ assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) );
99095
+
9878799096
if( flag ){
98788
- assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
98789
- assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 );
98790
- pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
99097
+ pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
9879199098
pDel = pMinMax;
9879299099
if( pMinMax && !db->mallocFailed ){
9879399100
pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
9879499101
pMinMax->a[0].pExpr->op = TK_COLUMN;
9879599102
}
@@ -102673,11 +102980,11 @@
102673102980
#define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */
102674102981
#define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */
102675102982
#define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */
102676102983
#define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
102677102984
#define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
102678
-#define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */
102985
+#define WHERE_IN_ABLE 0x080f1000 /* Able to support an IN operator */
102679102986
#define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
102680102987
#define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
102681102988
#define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
102682102989
#define WHERE_IDX_ONLY 0x00400000 /* Use index only - omit table */
102683102990
#define WHERE_ORDERED 0x00800000 /* Output will appear in correct order */
@@ -102823,11 +103130,11 @@
102823103130
sqlite3DbFree(db, pOld);
102824103131
}
102825103132
pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
102826103133
}
102827103134
pTerm = &pWC->a[idx = pWC->nTerm++];
102828
- pTerm->pExpr = p;
103135
+ pTerm->pExpr = sqlite3ExprSkipCollate(p);
102829103136
pTerm->wtFlags = wtFlags;
102830103137
pTerm->pWC = pWC;
102831103138
pTerm->iParent = -1;
102832103139
return idx;
102833103140
}
@@ -102983,27 +103290,36 @@
102983103290
102984103291
/*
102985103292
** Commute a comparison operator. Expressions of the form "X op Y"
102986103293
** are converted into "Y op X".
102987103294
**
102988
-** If a collation sequence is associated with either the left or right
103295
+** If left/right precendence rules come into play when determining the
103296
+** collating
102989103297
** side of the comparison, it remains associated with the same side after
102990103298
** the commutation. So "Y collate NOCASE op X" becomes
102991
-** "X collate NOCASE op Y". This is because any collation sequence on
103299
+** "X op Y". This is because any collation sequence on
102992103300
** the left hand side of a comparison overrides any collation sequence
102993
-** attached to the right. For the same reason the EP_ExpCollate flag
103301
+** attached to the right. For the same reason the EP_Collate flag
102994103302
** is not commuted.
102995103303
*/
102996103304
static void exprCommute(Parse *pParse, Expr *pExpr){
102997
- u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
102998
- u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
103305
+ u16 expRight = (pExpr->pRight->flags & EP_Collate);
103306
+ u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
102999103307
assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
103000
- pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
103001
- pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
103002
- SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
103003
- pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;
103004
- pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;
103308
+ if( expRight==expLeft ){
103309
+ /* Either X and Y both have COLLATE operator or neither do */
103310
+ if( expRight ){
103311
+ /* Both X and Y have COLLATE operators. Make sure X is always
103312
+ ** used by clearing the EP_Collate flag from Y. */
103313
+ pExpr->pRight->flags &= ~EP_Collate;
103314
+ }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
103315
+ /* Neither X nor Y have COLLATE operators, but X has a non-default
103316
+ ** collating sequence. So add the EP_Collate marker on X to cause
103317
+ ** it to be searched first. */
103318
+ pExpr->pLeft->flags |= EP_Collate;
103319
+ }
103320
+ }
103005103321
SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
103006103322
if( pExpr->op>=TK_GT ){
103007103323
assert( TK_LT==TK_GT+2 );
103008103324
assert( TK_GE==TK_LE+2 );
103009103325
assert( TK_GT>TK_EQ );
@@ -103076,16 +103392,16 @@
103076103392
** it to be useful for optimising expression pX. Store this
103077103393
** value in variable pColl.
103078103394
*/
103079103395
assert(pX->pLeft);
103080103396
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
103081
- assert(pColl || pParse->nErr);
103397
+ if( pColl==0 ) pColl = pParse->db->pDfltColl;
103082103398
103083103399
for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
103084103400
if( NEVER(j>=pIdx->nColumn) ) return 0;
103085103401
}
103086
- if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
103402
+ if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
103087103403
}
103088103404
return pTerm;
103089103405
}
103090103406
}
103091103407
}
@@ -103600,10 +103916,11 @@
103600103916
return;
103601103917
}
103602103918
pTerm = &pWC->a[idxTerm];
103603103919
pMaskSet = pWC->pMaskSet;
103604103920
pExpr = pTerm->pExpr;
103921
+ assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
103605103922
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
103606103923
op = pExpr->op;
103607103924
if( op==TK_IN ){
103608103925
assert( pExpr->pRight==0 );
103609103926
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
@@ -103626,12 +103943,12 @@
103626103943
pTerm->prereqAll = prereqAll;
103627103944
pTerm->leftCursor = -1;
103628103945
pTerm->iParent = -1;
103629103946
pTerm->eOperator = 0;
103630103947
if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
103631
- Expr *pLeft = pExpr->pLeft;
103632
- Expr *pRight = pExpr->pRight;
103948
+ Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
103949
+ Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
103633103950
if( pLeft->op==TK_COLUMN ){
103634103951
pTerm->leftCursor = pLeft->iTable;
103635103952
pTerm->u.leftColumn = pLeft->iColumn;
103636103953
pTerm->eOperator = operatorMask(op);
103637103954
}
@@ -103655,11 +103972,11 @@
103655103972
}else{
103656103973
pDup = pExpr;
103657103974
pNew = pTerm;
103658103975
}
103659103976
exprCommute(pParse, pDup);
103660
- pLeft = pDup->pLeft;
103977
+ pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
103661103978
pNew->leftCursor = pLeft->iTable;
103662103979
pNew->u.leftColumn = pLeft->iColumn;
103663103980
testcase( (prereqLeft | extraRight) != prereqLeft );
103664103981
pNew->prereqRight = prereqLeft | extraRight;
103665103982
pNew->prereqAll = prereqAll;
@@ -103734,11 +104051,11 @@
103734104051
Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */
103735104052
Expr *pNewExpr1;
103736104053
Expr *pNewExpr2;
103737104054
int idxNew1;
103738104055
int idxNew2;
103739
- CollSeq *pColl; /* Collating sequence to use */
104056
+ Token sCollSeqName; /* Name of collating sequence */
103740104057
103741104058
pLeft = pExpr->x.pList->a[1].pExpr;
103742104059
pStr2 = sqlite3ExprDup(db, pStr1, 0);
103743104060
if( !db->mallocFailed ){
103744104061
u8 c, *pC; /* Last character before the first wildcard */
@@ -103756,20 +104073,23 @@
103756104073
103757104074
c = sqlite3UpperToLower[c];
103758104075
}
103759104076
*pC = c + 1;
103760104077
}
103761
- pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0);
104078
+ sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
104079
+ sCollSeqName.n = 6;
104080
+ pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
103762104081
pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
103763
- sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
103764
- pStr1, 0);
104082
+ sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
104083
+ pStr1, 0);
103765104084
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
103766104085
testcase( idxNew1==0 );
103767104086
exprAnalyze(pSrc, pWC, idxNew1);
104087
+ pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
103768104088
pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
103769
- sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
103770
- pStr2, 0);
104089
+ sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
104090
+ pStr2, 0);
103771104091
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
103772104092
testcase( idxNew2==0 );
103773104093
exprAnalyze(pSrc, pWC, idxNew2);
103774104094
pTerm = &pWC->a[idxTerm];
103775104095
if( isComplete ){
@@ -103883,16 +104203,16 @@
103883104203
){
103884104204
int i;
103885104205
const char *zColl = pIdx->azColl[iCol];
103886104206
103887104207
for(i=0; i<pList->nExpr; i++){
103888
- Expr *p = pList->a[i].pExpr;
104208
+ Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
103889104209
if( p->op==TK_COLUMN
103890104210
&& p->iColumn==pIdx->aiColumn[iCol]
103891104211
&& p->iTable==iBase
103892104212
){
103893
- CollSeq *pColl = sqlite3ExprCollSeq(pParse, p);
104213
+ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
103894104214
if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
103895104215
return i;
103896104216
}
103897104217
}
103898104218
}
@@ -103935,11 +104255,11 @@
103935104255
** matching "col=X" expression and the column is on the same table as pIdx,
103936104256
** set the corresponding bit in variable mask.
103937104257
*/
103938104258
for(i=0; i<pDistinct->nExpr; i++){
103939104259
WhereTerm *pTerm;
103940
- Expr *p = pDistinct->a[i].pExpr;
104260
+ Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
103941104261
if( p->op!=TK_COLUMN ) return 0;
103942104262
pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
103943104263
if( pTerm ){
103944104264
Expr *pX = pTerm->pExpr;
103945104265
CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -103987,11 +104307,11 @@
103987104307
/* If any of the expressions is an IPK column on table iBase, then return
103988104308
** true. Note: The (p->iTable==iBase) part of this test may be false if the
103989104309
** current SELECT is a correlated sub-query.
103990104310
*/
103991104311
for(i=0; i<pDistinct->nExpr; i++){
103992
- Expr *p = pDistinct->a[i].pExpr;
104312
+ Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
103993104313
if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
103994104314
}
103995104315
103996104316
/* Loop through all indices on the table, checking each to see if it makes
103997104317
** the DISTINCT qualifier redundant. It does so if:
@@ -104464,11 +104784,11 @@
104464104784
for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
104465104785
if( pTerm->leftCursor != pSrc->iCursor ) continue;
104466104786
assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104467104787
testcase( pTerm->eOperator==WO_IN );
104468104788
testcase( pTerm->eOperator==WO_ISNULL );
104469
- if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
104789
+ if( pTerm->eOperator & (WO_ISNULL) ) continue;
104470104790
if( pTerm->wtFlags & TERM_VNULL ) continue;
104471104791
nTerm++;
104472104792
}
104473104793
104474104794
/* If the ORDER BY clause contains only columns in the current
@@ -104512,29 +104832,32 @@
104512104832
*(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
104513104833
*(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
104514104834
pUsage;
104515104835
104516104836
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
104837
+ u8 op;
104517104838
if( pTerm->leftCursor != pSrc->iCursor ) continue;
104518104839
assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104519104840
testcase( pTerm->eOperator==WO_IN );
104520104841
testcase( pTerm->eOperator==WO_ISNULL );
104521
- if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
104842
+ if( pTerm->eOperator & (WO_ISNULL) ) continue;
104522104843
if( pTerm->wtFlags & TERM_VNULL ) continue;
104523104844
pIdxCons[j].iColumn = pTerm->u.leftColumn;
104524104845
pIdxCons[j].iTermOffset = i;
104525
- pIdxCons[j].op = (u8)pTerm->eOperator;
104846
+ op = (u8)pTerm->eOperator;
104847
+ if( op==WO_IN ) op = WO_EQ;
104848
+ pIdxCons[j].op = op;
104526104849
/* The direct assignment in the previous line is possible only because
104527104850
** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
104528104851
** following asserts verify this fact. */
104529104852
assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
104530104853
assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
104531104854
assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
104532104855
assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
104533104856
assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
104534104857
assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
104535
- assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
104858
+ assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
104536104859
j++;
104537104860
}
104538104861
for(i=0; i<nOrderBy; i++){
104539104862
Expr *pExpr = pOrderBy->a[i].pExpr;
104540104863
pIdxOrderBy[i].iColumn = pExpr->iColumn;
@@ -104616,10 +104939,11 @@
104616104939
struct sqlite3_index_constraint *pIdxCons;
104617104940
struct sqlite3_index_constraint_usage *pUsage;
104618104941
WhereTerm *pTerm;
104619104942
int i, j;
104620104943
int nOrderBy;
104944
+ int bAllowIN; /* Allow IN optimizations */
104621104945
double rCost;
104622104946
104623104947
/* Make sure wsFlags is initialized to some sane value. Otherwise, if the
104624104948
** malloc in allocateIndexInfo() fails and this function returns leaving
104625104949
** wsFlags in an uninitialized state, the caller may behave unpredictably.
@@ -104650,63 +104974,91 @@
104650104974
** sqlite3ViewGetColumnNames() would have picked up the error.
104651104975
*/
104652104976
assert( pTab->azModuleArg && pTab->azModuleArg[0] );
104653104977
assert( sqlite3GetVTable(pParse->db, pTab) );
104654104978
104655
- /* Set the aConstraint[].usable fields and initialize all
104656
- ** output variables to zero.
104657
- **
104658
- ** aConstraint[].usable is true for constraints where the right-hand
104659
- ** side contains only references to tables to the left of the current
104660
- ** table. In other words, if the constraint is of the form:
104661
- **
104662
- ** column = expr
104663
- **
104664
- ** and we are evaluating a join, then the constraint on column is
104665
- ** only valid if all tables referenced in expr occur to the left
104666
- ** of the table containing column.
104667
- **
104668
- ** The aConstraints[] array contains entries for all constraints
104669
- ** on the current table. That way we only have to compute it once
104670
- ** even though we might try to pick the best index multiple times.
104671
- ** For each attempt at picking an index, the order of tables in the
104672
- ** join might be different so we have to recompute the usable flag
104673
- ** each time.
104674
- */
104675
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
104676
- pUsage = pIdxInfo->aConstraintUsage;
104677
- for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
104678
- j = pIdxCons->iTermOffset;
104679
- pTerm = &pWC->a[j];
104680
- pIdxCons->usable = (pTerm->prereqRight&p->notReady) ? 0 : 1;
104681
- }
104682
- memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
104683
- if( pIdxInfo->needToFreeIdxStr ){
104684
- sqlite3_free(pIdxInfo->idxStr);
104685
- }
104686
- pIdxInfo->idxStr = 0;
104687
- pIdxInfo->idxNum = 0;
104688
- pIdxInfo->needToFreeIdxStr = 0;
104689
- pIdxInfo->orderByConsumed = 0;
104690
- /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
104691
- pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
104692
- nOrderBy = pIdxInfo->nOrderBy;
104693
- if( !p->pOrderBy ){
104694
- pIdxInfo->nOrderBy = 0;
104695
- }
104696
-
104697
- if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
104698
- return;
104699
- }
104700
-
104701
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
104702
- for(i=0; i<pIdxInfo->nConstraint; i++){
104703
- if( pUsage[i].argvIndex>0 ){
104704
- p->cost.used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
104705
- }
104706
- }
104707
-
104979
+ /* Try once or twice. On the first attempt, allow IN optimizations.
104980
+ ** If an IN optimization is accepted by the virtual table xBestIndex
104981
+ ** method, but the pInfo->aConstrainUsage.omit flag is not set, then
104982
+ ** the query will not work because it might allow duplicate rows in
104983
+ ** output. In that case, run the xBestIndex method a second time
104984
+ ** without the IN constraints. Usually this loop only runs once.
104985
+ ** The loop will exit using a "break" statement.
104986
+ */
104987
+ for(bAllowIN=1; 1; bAllowIN--){
104988
+ assert( bAllowIN==0 || bAllowIN==1 );
104989
+
104990
+ /* Set the aConstraint[].usable fields and initialize all
104991
+ ** output variables to zero.
104992
+ **
104993
+ ** aConstraint[].usable is true for constraints where the right-hand
104994
+ ** side contains only references to tables to the left of the current
104995
+ ** table. In other words, if the constraint is of the form:
104996
+ **
104997
+ ** column = expr
104998
+ **
104999
+ ** and we are evaluating a join, then the constraint on column is
105000
+ ** only valid if all tables referenced in expr occur to the left
105001
+ ** of the table containing column.
105002
+ **
105003
+ ** The aConstraints[] array contains entries for all constraints
105004
+ ** on the current table. That way we only have to compute it once
105005
+ ** even though we might try to pick the best index multiple times.
105006
+ ** For each attempt at picking an index, the order of tables in the
105007
+ ** join might be different so we have to recompute the usable flag
105008
+ ** each time.
105009
+ */
105010
+ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105011
+ pUsage = pIdxInfo->aConstraintUsage;
105012
+ for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105013
+ j = pIdxCons->iTermOffset;
105014
+ pTerm = &pWC->a[j];
105015
+ if( (pTerm->prereqRight&p->notReady)==0
105016
+ && (bAllowIN || pTerm->eOperator!=WO_IN)
105017
+ ){
105018
+ pIdxCons->usable = 1;
105019
+ }else{
105020
+ pIdxCons->usable = 0;
105021
+ }
105022
+ }
105023
+ memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
105024
+ if( pIdxInfo->needToFreeIdxStr ){
105025
+ sqlite3_free(pIdxInfo->idxStr);
105026
+ }
105027
+ pIdxInfo->idxStr = 0;
105028
+ pIdxInfo->idxNum = 0;
105029
+ pIdxInfo->needToFreeIdxStr = 0;
105030
+ pIdxInfo->orderByConsumed = 0;
105031
+ /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
105032
+ pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
105033
+ nOrderBy = pIdxInfo->nOrderBy;
105034
+ if( !p->pOrderBy ){
105035
+ pIdxInfo->nOrderBy = 0;
105036
+ }
105037
+
105038
+ if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
105039
+ return;
105040
+ }
105041
+
105042
+ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105043
+ for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105044
+ if( pUsage[i].argvIndex>0 ){
105045
+ j = pIdxCons->iTermOffset;
105046
+ pTerm = &pWC->a[j];
105047
+ p->cost.used |= pTerm->prereqRight;
105048
+ if( pTerm->eOperator==WO_IN && pUsage[i].omit==0 ){
105049
+ /* Do not attempt to use an IN constraint if the virtual table
105050
+ ** says that the equivalent EQ constraint cannot be safely omitted.
105051
+ ** If we do attempt to use such a constraint, some rows might be
105052
+ ** repeated in the output. */
105053
+ break;
105054
+ }
105055
+ }
105056
+ }
105057
+ if( i>=pIdxInfo->nConstraint ) break;
105058
+ }
105059
+
104708105060
/* If there is an ORDER BY clause, and the selected virtual table index
104709105061
** does not satisfy it, increase the cost of the scan accordingly. This
104710105062
** matches the processing for non-virtual tables in bestBtreeIndex().
104711105063
*/
104712105064
rCost = pIdxInfo->estimatedCost;
@@ -105273,11 +105625,11 @@
105273105625
WhereTerm *pConstraint; /* A constraint in the WHERE clause */
105274105626
105275105627
/* If the next term of the ORDER BY clause refers to anything other than
105276105628
** a column in the "base" table, then this index will not be of any
105277105629
** further use in handling the ORDER BY. */
105278
- pOBExpr = pOBItem->pExpr;
105630
+ pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr);
105279105631
if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
105280105632
break;
105281105633
}
105282105634
105283105635
/* Find column number and collating sequence for the next entry
@@ -105299,11 +105651,11 @@
105299105651
/* Check to see if the column number and collating sequence of the
105300105652
** index match the column number and collating sequence of the ORDER BY
105301105653
** clause entry. Set isMatch to 1 if they both match. */
105302105654
if( pOBExpr->iColumn==iColumn ){
105303105655
if( zColl ){
105304
- pColl = sqlite3ExprCollSeq(pParse, pOBExpr);
105656
+ pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr);
105305105657
if( !pColl ) pColl = db->pDfltColl;
105306105658
isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
105307105659
}else{
105308105660
isMatch = 1;
105309105661
}
@@ -105440,10 +105792,15 @@
105440105792
int idxEqTermMask; /* Index mask of valid equality operators */
105441105793
Index sPk; /* A fake index object for the primary key */
105442105794
tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
105443105795
int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
105444105796
int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */
105797
+ int nPriorSat; /* ORDER BY terms satisfied by outer loops */
105798
+ int nOrderBy; /* Number of ORDER BY terms */
105799
+ char bSortInit; /* Initializer for bSort in inner loop */
105800
+ char bDistInit; /* Initializer for bDist in inner loop */
105801
+
105445105802
105446105803
/* Initialize the cost to a worst-case value */
105447105804
memset(&p->cost, 0, sizeof(p->cost));
105448105805
p->cost.rCost = SQLITE_BIG_DBL;
105449105806
@@ -105488,10 +105845,21 @@
105488105845
WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
105489105846
);
105490105847
eqTermMask = WO_EQ|WO_IN;
105491105848
pIdx = 0;
105492105849
}
105850
+
105851
+ nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
105852
+ if( p->i ){
105853
+ nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
105854
+ bSortInit = nPriorSat<nOrderBy;
105855
+ bDistInit = 0;
105856
+ }else{
105857
+ nPriorSat = 0;
105858
+ bSortInit = nOrderBy>0;
105859
+ bDistInit = p->pDistinct!=0;
105860
+ }
105493105861
105494105862
/* Loop over all indices looking for the best one to use
105495105863
*/
105496105864
for(; pProbe; pIdx=pProbe=pProbe->pNext){
105497105865
const tRowcnt * const aiRowEst = pProbe->aiRowEst;
@@ -105566,15 +105934,13 @@
105566105934
*/
105567105935
int bInEst = 0; /* True if "x IN (SELECT...)" seen */
105568105936
int nInMul = 1; /* Number of distinct equalities to lookup */
105569105937
double rangeDiv = (double)1; /* Estimated reduction in search space */
105570105938
int nBound = 0; /* Number of range constraints seen */
105571
- int bSort; /* True if external sort required */
105572
- int bDist; /* True if index cannot help with DISTINCT */
105573
- int bLookup = 0; /* True if not a covering index */
105574
- int nPriorSat; /* ORDER BY terms satisfied by outer loops */
105575
- int nOrderBy; /* Number of ORDER BY terms */
105939
+ char bSort = bSortInit; /* True if external sort required */
105940
+ char bDist = bDistInit; /* True if index cannot help with DISTINCT */
105941
+ char bLookup = 0; /* True if not a covering index */
105576105942
WhereTerm *pTerm; /* A single term of the WHERE clause */
105577105943
#ifdef SQLITE_ENABLE_STAT3
105578105944
WhereTerm *pFirstTerm = 0; /* First term matching the index */
105579105945
#endif
105580105946
@@ -105581,20 +105947,11 @@
105581105947
WHERETRACE((
105582105948
" %s(%s):\n",
105583105949
pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
105584105950
));
105585105951
memset(&pc, 0, sizeof(pc));
105586
- nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
105587
- if( p->i ){
105588
- nPriorSat = pc.plan.nOBSat = p->aLevel[p->i-1].plan.nOBSat;
105589
- bSort = nPriorSat<nOrderBy;
105590
- bDist = 0;
105591
- }else{
105592
- nPriorSat = pc.plan.nOBSat = 0;
105593
- bSort = nOrderBy>0;
105594
- bDist = p->pDistinct!=0;
105595
- }
105952
+ pc.plan.nOBSat = nPriorSat;
105596105953
105597105954
/* Determine the values of pc.plan.nEq and nInMul */
105598105955
for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
105599105956
int j = pProbe->aiColumn[pc.plan.nEq];
105600105957
pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
@@ -106466,32 +106823,40 @@
106466106823
if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
106467106824
/* Case 0: The table is a virtual-table. Use the VFilter and VNext
106468106825
** to access the data.
106469106826
*/
106470106827
int iReg; /* P3 Value for OP_VFilter */
106828
+ int addrNotFound;
106471106829
sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
106472106830
int nConstraint = pVtabIdx->nConstraint;
106473106831
struct sqlite3_index_constraint_usage *aUsage =
106474106832
pVtabIdx->aConstraintUsage;
106475106833
const struct sqlite3_index_constraint *aConstraint =
106476106834
pVtabIdx->aConstraint;
106477106835
106478106836
sqlite3ExprCachePush(pParse);
106479106837
iReg = sqlite3GetTempRange(pParse, nConstraint+2);
106838
+ addrNotFound = pLevel->addrBrk;
106480106839
for(j=1; j<=nConstraint; j++){
106481106840
for(k=0; k<nConstraint; k++){
106482106841
if( aUsage[k].argvIndex==j ){
106483
- int iTerm = aConstraint[k].iTermOffset;
106484
- sqlite3ExprCode(pParse, pWC->a[iTerm].pExpr->pRight, iReg+j+1);
106842
+ WhereTerm *pTerm = &pWC->a[aConstraint[k].iTermOffset];
106843
+ int iTarget = iReg+j+1;
106844
+ if( pTerm->eOperator & WO_IN ){
106845
+ codeEqualityTerm(pParse, pTerm, pLevel, iTarget);
106846
+ addrNotFound = pLevel->addrNxt;
106847
+ }else{
106848
+ sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
106849
+ }
106485106850
break;
106486106851
}
106487106852
}
106488106853
if( k==nConstraint ) break;
106489106854
}
106490106855
sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
106491106856
sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
106492
- sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrBrk, iReg, pVtabIdx->idxStr,
106857
+ sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, pVtabIdx->idxStr,
106493106858
pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
106494106859
pVtabIdx->needToFreeIdxStr = 0;
106495106860
for(j=0; j<nConstraint; j++){
106496106861
if( aUsage[j].omit ){
106497106862
int iTerm = aConstraint[j].iTermOffset;
@@ -108134,10 +108499,11 @@
108134108499
Expr* yy122;
108135108500
Select* yy159;
108136108501
IdList* yy180;
108137108502
struct {int value; int mask;} yy207;
108138108503
u8 yy258;
108504
+ u16 yy305;
108139108505
struct LikeOp yy318;
108140108506
TriggerStep* yy327;
108141108507
ExprSpan yy342;
108142108508
SrcList* yy347;
108143108509
int yy392;
@@ -110084,22 +110450,19 @@
110084110450
case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
110085110451
case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
110086110452
case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
110087110453
case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
110088110454
case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
110089
- case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120);
110090
- case 121: /* distinct ::= */ yytestcase(yyruleno==121);
110091110455
case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
110092110456
case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
110093110457
{yygotominor.yy392 = 0;}
110094110458
break;
110095110459
case 29: /* ifnotexists ::= IF NOT EXISTS */
110096110460
case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
110097110461
case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
110098110462
case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
110099110463
case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
110100
- case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119);
110101110464
case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
110102110465
case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
110103110466
{yygotominor.yy392 = 1;}
110104110467
break;
110105110468
case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
@@ -110335,12 +110698,19 @@
110335110698
case 116: /* multiselect_op ::= UNION ALL */
110336110699
{yygotominor.yy392 = TK_ALL;}
110337110700
break;
110338110701
case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
110339110702
{
110340
- yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
110703
+ yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy305,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
110341110704
}
110705
+ break;
110706
+ case 119: /* distinct ::= DISTINCT */
110707
+{yygotominor.yy305 = SF_Distinct;}
110708
+ break;
110709
+ case 120: /* distinct ::= ALL */
110710
+ case 121: /* distinct ::= */ yytestcase(yyruleno==121);
110711
+{yygotominor.yy305 = 0;}
110342110712
break;
110343110713
case 122: /* sclp ::= selcollist COMMA */
110344110714
case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
110345110715
{yygotominor.yy442 = yymsp[-1].minor.yy442;}
110346110716
break;
@@ -110406,14 +110776,24 @@
110406110776
break;
110407110777
case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
110408110778
{
110409110779
if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
110410110780
yygotominor.yy347 = yymsp[-4].minor.yy347;
110781
+ }else if( yymsp[-4].minor.yy347->nSrc==1 ){
110782
+ yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
110783
+ if( yygotominor.yy347 ){
110784
+ struct SrcList_item *pNew = &yygotominor.yy347->a[yygotominor.yy347->nSrc-1];
110785
+ struct SrcList_item *pOld = yymsp[-4].minor.yy347->a;
110786
+ pNew->zName = pOld->zName;
110787
+ pNew->zDatabase = pOld->zDatabase;
110788
+ pOld->zName = pOld->zDatabase = 0;
110789
+ }
110790
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy347);
110411110791
}else{
110412110792
Select *pSubquery;
110413110793
sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
110414
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,0,0,0);
110794
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,SF_NestedFrom,0,0);
110415110795
yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
110416110796
}
110417110797
}
110418110798
break;
110419110799
case 137: /* dbnm ::= */
@@ -110624,11 +111004,11 @@
110624111004
spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
110625111005
}
110626111006
break;
110627111007
case 194: /* expr ::= expr COLLATE ids */
110628111008
{
110629
- yygotominor.yy342.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
111009
+ yygotominor.yy342.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
110630111010
yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
110631111011
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
110632111012
}
110633111013
break;
110634111014
case 195: /* expr ::= CAST LP expr AS typetoken RP */
@@ -110642,11 +111022,11 @@
110642111022
if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
110643111023
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
110644111024
}
110645111025
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
110646111026
spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
110647
- if( yymsp[-2].minor.yy392 && yygotominor.yy342.pExpr ){
111027
+ if( yymsp[-2].minor.yy305 && yygotominor.yy342.pExpr ){
110648111028
yygotominor.yy342.pExpr->flags |= EP_Distinct;
110649111029
}
110650111030
}
110651111031
break;
110652111032
case 197: /* expr ::= ID LP STAR RP */
@@ -110883,28 +111263,20 @@
110883111263
case 244: /* uniqueflag ::= */
110884111264
{yygotominor.yy392 = OE_None;}
110885111265
break;
110886111266
case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
110887111267
{
110888
- Expr *p = 0;
110889
- if( yymsp[-1].minor.yy0.n>0 ){
110890
- p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
110891
- sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
110892
- }
111268
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
110893111269
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
110894111270
sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
110895111271
sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
110896111272
if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
110897111273
}
110898111274
break;
110899111275
case 248: /* idxlist ::= nm collate sortorder */
110900111276
{
110901
- Expr *p = 0;
110902
- if( yymsp[-1].minor.yy0.n>0 ){
110903
- p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
110904
- sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
110905
- }
111277
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
110906111278
yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
110907111279
sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
110908111280
sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
110909111281
if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
110910111282
}
@@ -141105,10 +141477,11 @@
141105141477
extern int Sqlitemultiplex_Init(Tcl_Interp*);
141106141478
extern int SqliteSuperlock_Init(Tcl_Interp*);
141107141479
extern int SqlitetestSyscall_Init(Tcl_Interp*);
141108141480
extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
141109141481
extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
141482
+ extern int Sqlitetestregexp_Init(Tcl_Interp*);
141110141483
141111141484
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141112141485
extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
141113141486
#endif
141114141487
@@ -141148,10 +141521,11 @@
141148141521
Sqlitemultiplex_Init(interp);
141149141522
SqliteSuperlock_Init(interp);
141150141523
SqlitetestSyscall_Init(interp);
141151141524
Sqlitetestfuzzer_Init(interp);
141152141525
Sqlitetestwholenumber_Init(interp);
141526
+ Sqlitetestregexp_Init(interp);
141153141527
141154141528
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141155141529
Sqlitetestfts3_Init(interp);
141156141530
#endif
141157141531
141158141532
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.7.15. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -671,13 +671,13 @@
671 **
672 ** See also: [sqlite3_libversion()],
673 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674 ** [sqlite_version()] and [sqlite_source_id()].
675 */
676 #define SQLITE_VERSION "3.7.15"
677 #define SQLITE_VERSION_NUMBER 3007015
678 #define SQLITE_SOURCE_ID "2012-10-16 23:08:28 f021559d8a23934e3bdccad5b55fc7a91d185f53"
679
680 /*
681 ** CAPI3REF: Run-Time Library Version Numbers
682 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
683 **
@@ -2162,11 +2162,11 @@
2162 ** database connection is opened. By default, URI handling is globally
2163 ** disabled. The default value may be changed by compiling with the
2164 ** [SQLITE_USE_URI] symbol defined.
2165 **
2166 ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
2167 ** <dd> This option taks a single integer argument which is interpreted as
2168 ** a boolean in order to enable or disable the use of covering indices for
2169 ** full table scans in the query optimizer. The default setting is determined
2170 ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
2171 ** if that compile-time option is omitted.
2172 ** The ability to disable the use of covering indices for full table scans
@@ -10573,24 +10573,24 @@
10573 ** and the value of Index.onError indicate the which conflict resolution
10574 ** algorithm to employ whenever an attempt is made to insert a non-unique
10575 ** element.
10576 */
10577 struct Index {
10578 char *zName; /* Name of this index */
10579 int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10580 tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
10581 Table *pTable; /* The SQL table being indexed */
10582 char *zColAff; /* String defining the affinity of each column */
10583 Index *pNext; /* The next index associated with the same table */
10584 Schema *pSchema; /* Schema containing this index */
10585 u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
10586 char **azColl; /* Array of collation sequence names for index */
10587 int nColumn; /* Number of columns in the table used by this index */
10588 int tnum; /* Page containing root of this index in database file */
10589 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10590 u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
10591 u8 bUnordered; /* Use this index for == or IN queries only */
10592 #ifdef SQLITE_ENABLE_STAT3
10593 int nSample; /* Number of elements in aSample[] */
10594 tRowcnt avgEq; /* Average nEq value for key values not in aSample */
10595 IndexSample *aSample; /* Samples of the left-most key */
10596 #endif
@@ -10767,11 +10767,10 @@
10767 Expr *pRight; /* Right subnode */
10768 union {
10769 ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
10770 Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
10771 } x;
10772 CollSeq *pColl; /* The collation type of the column or 0 */
10773
10774 /* If the EP_Reduced flag is set in the Expr.flags mask, then no
10775 ** space is allocated for the fields below this point. An attempt to
10776 ** access them will result in a segfault or malfunction.
10777 *********************************************************************/
@@ -10803,11 +10802,11 @@
10803 #define EP_Error 0x0008 /* Expression contains one or more errors */
10804 #define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
10805 #define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
10806 #define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
10807 #define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
10808 #define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
10809 #define EP_FixedDest 0x0200 /* Result needed in a specific register */
10810 #define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
10811 #define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
10812 #define EP_Hint 0x1000 /* Not used */
10813 #define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
@@ -10861,22 +10860,31 @@
10861 ** name. An expr/name combination can be used in several ways, such
10862 ** as the list of "expr AS ID" fields following a "SELECT" or in the
10863 ** list of "ID = expr" items in an UPDATE. A list of expressions can
10864 ** also be used as the argument to a function, in which case the a.zName
10865 ** field is not used.
 
 
 
 
 
 
 
 
10866 */
10867 struct ExprList {
10868 int nExpr; /* Number of expressions on the list */
10869 int iECursor; /* VDBE Cursor associated with this ExprList */
10870 struct ExprList_item { /* For each expression in the list */
10871 Expr *pExpr; /* The list of expressions */
10872 char *zName; /* Token associated with this expression */
10873 char *zSpan; /* Original text of the expression */
10874 u8 sortOrder; /* 1 for DESC or 0 for ASC */
10875 u8 done; /* A flag to indicate when processing is finished */
10876 u16 iOrderByCol; /* For ORDER BY, column number in result set */
10877 u16 iAlias; /* Index into Parse.aAlias[] for zName */
 
10878 } *a; /* Alloc a power of two greater or equal to nExpr */
10879 };
10880
10881 /*
10882 ** An instance of this structure is used by the parser to record both
@@ -11192,10 +11200,11 @@
11192 #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
11193 #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
11194 #define SF_UseSorter 0x0040 /* Sort using a sorter */
11195 #define SF_Values 0x0080 /* Synthesized from VALUES clause */
11196 #define SF_Materialize 0x0100 /* Force materialization of views */
 
11197
11198
11199 /*
11200 ** The results of a select can be distributed in several ways. The
11201 ** "SRT" prefix means "SELECT Result Type".
@@ -11420,10 +11429,11 @@
11420 #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
11421 #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
11422 #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
11423 #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
11424 #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
 
11425
11426 /*
11427 * Each trigger present in the database schema is stored as an instance of
11428 * struct Trigger.
11429 *
@@ -11904,11 +11914,11 @@
11904 SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
11905 Token*, int, int);
11906 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
11907 SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
11908 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
11909 Expr*,ExprList*,int,Expr*,Expr*);
11910 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
11911 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
11912 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
11913 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
11914 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
@@ -12112,12 +12122,13 @@
12112 SQLITE_PRIVATE const char *sqlite3ErrStr(int);
12113 SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
12114 SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
12115 SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
12116 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
12117 SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
12118 SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
 
12119 SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
12120 SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
12121 SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
12122 SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
12123 SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
@@ -12160,10 +12171,11 @@
12160 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
12161 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
12162 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
12163 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
12164 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
 
12165 SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
12166 SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
12167 SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
12168 SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
12169 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -12298,12 +12310,14 @@
12298 #define sqlite3FkOldmask(a,b) 0
12299 #define sqlite3FkRequired(a,b,c,d) 0
12300 #endif
12301 #ifndef SQLITE_OMIT_FOREIGN_KEY
12302 SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*);
 
12303 #else
12304 #define sqlite3FkDelete(a,b)
 
12305 #endif
12306
12307
12308 /*
12309 ** Available fault injectors. Should be numbered beginning with 0.
@@ -23307,15 +23321,11 @@
23307 { "pwrite64", (sqlite3_syscall_ptr)0, 0 },
23308 #endif
23309 #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
23310 aSyscall[13].pCurrent)
23311
23312 #if SQLITE_ENABLE_LOCKING_STYLE
23313 { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
23314 #else
23315 { "fchmod", (sqlite3_syscall_ptr)0, 0 },
23316 #endif
23317 #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
23318
23319 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
23320 { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
23321 #else
@@ -23336,13 +23346,10 @@
23336 #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
23337
23338 { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
23339 #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
23340
23341 { "umask", (sqlite3_syscall_ptr)umask, 0 },
23342 #define osUmask ((mode_t(*)(mode_t))aSyscall[21].pCurrent)
23343
23344 }; /* End of the overrideable system calls */
23345
23346 /*
23347 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
23348 ** "unix" VFSes. Return SQLITE_OK opon successfully updating the
@@ -23443,31 +23450,29 @@
23443 ** process that is able to write to the database will also be able to
23444 ** recover the hot journals.
23445 */
23446 static int robust_open(const char *z, int f, mode_t m){
23447 int fd;
23448 mode_t m2;
23449 mode_t origM = 0;
23450 if( m==0 ){
23451 m2 = SQLITE_DEFAULT_FILE_PERMISSIONS;
23452 }else{
23453 m2 = m;
23454 origM = osUmask(0);
23455 }
23456 do{
23457 #if defined(O_CLOEXEC)
23458 fd = osOpen(z,f|O_CLOEXEC,m2);
23459 #else
23460 fd = osOpen(z,f,m2);
23461 #endif
23462 }while( fd<0 && errno==EINTR );
23463 if( m ){
23464 osUmask(origM);
23465 }
 
 
 
 
23466 #if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
23467 if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
23468 #endif
 
23469 return fd;
23470 }
23471
23472 /*
23473 ** Helper functions to obtain and relinquish the global mutex. The
@@ -29889,11 +29894,11 @@
29889 };
29890 unsigned int i; /* Loop counter */
29891
29892 /* Double-check that the aSyscall[] array has been constructed
29893 ** correctly. See ticket [bb3a86e890c8e96ab] */
29894 assert( ArraySize(aSyscall)==22 );
29895
29896 /* Register all VFSes defined in the aVfs[] array */
29897 for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
29898 sqlite3_vfs_register(&aVfs[i], i==0);
29899 }
@@ -56355,11 +56360,11 @@
56355 sqlite3BtreeLeave(p);
56356 return 0;
56357 }
56358 i = PENDING_BYTE_PAGE(pBt);
56359 if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
56360 sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000);
56361 sCheck.errMsg.useMalloc = 2;
56362
56363 /* Check the integrity of the freelist
56364 */
56365 checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
@@ -56890,11 +56895,16 @@
56890 /*
56891 ** Parameter zSrcData points to a buffer containing the data for
56892 ** page iSrcPg from the source database. Copy this data into the
56893 ** destination database.
56894 */
56895 static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
 
 
 
 
 
56896 Pager * const pDestPager = sqlite3BtreePager(p->pDest);
56897 const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
56898 int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
56899 const int nCopy = MIN(nSrcPgsz, nDestPgsz);
56900 const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
@@ -56963,10 +56973,13 @@
56963 ** cached parse of the page). MemPage.isInit is marked
56964 ** "MUST BE FIRST" for this purpose.
56965 */
56966 memcpy(zOut, zIn, nCopy);
56967 ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
 
 
 
56968 }
56969 sqlite3PagerUnref(pDestPg);
56970 }
56971
56972 return rc;
@@ -57069,11 +57082,11 @@
57069 const Pgno iSrcPg = p->iNext; /* Source page number */
57070 if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
57071 DbPage *pSrcPg; /* Source page object */
57072 rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
57073 if( rc==SQLITE_OK ){
57074 rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg));
57075 sqlite3PagerUnref(pSrcPg);
57076 }
57077 }
57078 p->iNext++;
57079 }
@@ -57317,11 +57330,11 @@
57317 ** the new data into the backup.
57318 */
57319 int rc;
57320 assert( p->pDestDb );
57321 sqlite3_mutex_enter(p->pDestDb->mutex);
57322 rc = backupOnePage(p, iPage, aData);
57323 sqlite3_mutex_leave(p->pDestDb->mutex);
57324 assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
57325 if( rc!=SQLITE_OK ){
57326 p->rc = rc;
57327 }
@@ -59434,26 +59447,22 @@
59434 assert( pKeyInfo->aSortOrder!=0 );
59435 sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
59436 i = sqlite3Strlen30(zTemp);
59437 for(j=0; j<pKeyInfo->nField; j++){
59438 CollSeq *pColl = pKeyInfo->aColl[j];
59439 if( pColl ){
59440 int n = sqlite3Strlen30(pColl->zName);
59441 if( i+n>nTemp-6 ){
59442 memcpy(&zTemp[i],",...",4);
59443 break;
59444 }
59445 zTemp[i++] = ',';
59446 if( pKeyInfo->aSortOrder[j] ){
59447 zTemp[i++] = '-';
59448 }
59449 memcpy(&zTemp[i], pColl->zName,n+1);
59450 i += n;
59451 }else if( i+4<nTemp-6 ){
59452 memcpy(&zTemp[i],",nil",4);
59453 i += 4;
59454 }
59455 }
59456 zTemp[i++] = ')';
59457 zTemp[i] = 0;
59458 assert( i<nTemp );
59459 break;
@@ -63839,11 +63848,13 @@
63839 #ifdef SQLITE_DEBUG
63840 /*
63841 ** Print the value of a register for tracing purposes:
63842 */
63843 static void memTracePrint(FILE *out, Mem *p){
63844 if( p->flags & MEM_Null ){
 
 
63845 fprintf(out, " NULL");
63846 }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
63847 fprintf(out, " si:%lld", p->u.i);
63848 }else if( p->flags & MEM_Int ){
63849 fprintf(out, " i:%lld", p->u.i);
@@ -64112,10 +64123,11 @@
64112 } af;
64113 struct OP_Concat_stack_vars {
64114 i64 nByte;
64115 } ag;
64116 struct OP_Remainder_stack_vars {
 
64117 int flags; /* Combined MEM_* flags from both inputs */
64118 i64 iA; /* Integer value of left operand */
64119 i64 iB; /* Integer value of right operand */
64120 double rA; /* Real value of left operand */
64121 double rB; /* Real value of right operand */
@@ -65021,10 +65033,13 @@
65021 pOut = &aMem[pOp->p2];
65022 assert( pOut!=pIn1 );
65023 while( 1 ){
65024 sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
65025 Deephemeralize(pOut);
 
 
 
65026 REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
65027 if( (u.ae.n--)==0 ) break;
65028 pOut++;
65029 pIn1++;
65030 }
@@ -65214,10 +65229,11 @@
65214 case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
65215 case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
65216 case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
65217 case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
65218 #if 0 /* local variables moved into u.ah */
 
65219 int flags; /* Combined MEM_* flags from both inputs */
65220 i64 iA; /* Integer value of left operand */
65221 i64 iB; /* Integer value of right operand */
65222 double rA; /* Real value of left operand */
65223 double rB; /* Real value of right operand */
@@ -65231,10 +65247,11 @@
65231 u.ah.flags = pIn1->flags | pIn2->flags;
65232 if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
65233 if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
65234 u.ah.iA = pIn1->u.i;
65235 u.ah.iB = pIn2->u.i;
 
65236 switch( pOp->opcode ){
65237 case OP_Add: if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65238 case OP_Subtract: if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65239 case OP_Multiply: if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65240 case OP_Divide: {
@@ -65251,10 +65268,11 @@
65251 }
65252 }
65253 pOut->u.i = u.ah.iB;
65254 MemSetTypeFlag(pOut, MEM_Int);
65255 }else{
 
65256 fp_math:
65257 u.ah.rA = sqlite3VdbeRealValue(pIn1);
65258 u.ah.rB = sqlite3VdbeRealValue(pIn2);
65259 switch( pOp->opcode ){
65260 case OP_Add: u.ah.rB += u.ah.rA; break;
@@ -65282,11 +65300,11 @@
65282 if( sqlite3IsNaN(u.ah.rB) ){
65283 goto arithmetic_result_is_null;
65284 }
65285 pOut->r = u.ah.rB;
65286 MemSetTypeFlag(pOut, MEM_Real);
65287 if( (u.ah.flags & MEM_Real)==0 ){
65288 sqlite3VdbeIntegerAffinity(pOut);
65289 }
65290 #endif
65291 }
65292 break;
@@ -65843,26 +65861,31 @@
65843 /* Opcode: Permutation * * * P4 *
65844 **
65845 ** Set the permutation used by the OP_Compare operator to be the array
65846 ** of integers in P4.
65847 **
65848 ** The permutation is only valid until the next OP_Permutation, OP_Compare,
65849 ** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur
65850 ** immediately prior to the OP_Compare.
65851 */
65852 case OP_Permutation: {
65853 assert( pOp->p4type==P4_INTARRAY );
65854 assert( pOp->p4.ai );
65855 aPermute = pOp->p4.ai;
65856 break;
65857 }
65858
65859 /* Opcode: Compare P1 P2 P3 P4 *
65860 **
65861 ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
65862 ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
65863 ** the comparison for use by the next OP_Jump instruct.
 
 
 
 
 
65864 **
65865 ** P4 is a KeyInfo structure that defines collating sequences and sort
65866 ** orders for the comparison. The permutation applies to registers
65867 ** only. The KeyInfo elements are used sequentially.
65868 **
@@ -65880,10 +65903,11 @@
65880 int idx;
65881 CollSeq *pColl; /* Collating sequence to use on this term */
65882 int bRev; /* True for DESCENDING sort order */
65883 #endif /* local variables moved into u.al */
65884
 
65885 u.al.n = pOp->p3;
65886 u.al.pKeyInfo = pOp->p4.pKeyInfo;
65887 assert( u.al.n>0 );
65888 assert( u.al.pKeyInfo!=0 );
65889 u.al.p1 = pOp->p1;
@@ -66025,12 +66049,10 @@
66025
66026 /* Opcode: Once P1 P2 * * *
66027 **
66028 ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
66029 ** set the flag and fall through to the next instruction.
66030 **
66031 ** See also: JumpOnce
66032 */
66033 case OP_Once: { /* jump */
66034 assert( pOp->p1<p->nOnceFlag );
66035 if( p->aOnceFlag[pOp->p1] ){
66036 pc = pOp->p2-1;
@@ -71902,10 +71924,18 @@
71902 p->pReal = pReal;
71903 if( p->iSize>0 ){
71904 assert(p->iSize<=p->nBuf);
71905 rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
71906 }
 
 
 
 
 
 
 
 
71907 }
71908 }
71909 return rc;
71910 }
71911
@@ -72565,10 +72595,19 @@
72565 ** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
72566 **
72567 ** The result of random()%5 in the GROUP BY clause is probably different
72568 ** from the result in the result-set. We might fix this someday. Or
72569 ** then again, we might not...
 
 
 
 
 
 
 
 
 
72570 **
72571 ** The nSubquery parameter specifies how many levels of subquery the
72572 ** alias is removed from the original expression. The usually value is
72573 ** zero but it might be more if the alias is contained within a subquery
72574 ** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
@@ -72589,45 +72628,40 @@
72589 assert( iCol>=0 && iCol<pEList->nExpr );
72590 pOrig = pEList->a[iCol].pExpr;
72591 assert( pOrig!=0 );
72592 assert( pOrig->flags & EP_Resolved );
72593 db = pParse->db;
 
 
72594 if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
72595 pDup = sqlite3ExprDup(db, pOrig, 0);
72596 incrAggFunctionDepth(pDup, nSubquery);
72597 pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
72598 if( pDup==0 ) return;
72599 if( pEList->a[iCol].iAlias==0 ){
72600 pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
72601 }
72602 pDup->iTable = pEList->a[iCol].iAlias;
72603 }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
72604 pDup = sqlite3ExprDup(db, pOrig, 0);
72605 if( pDup==0 ) return;
72606 }else{
72607 char *zToken = pOrig->u.zToken;
72608 assert( zToken!=0 );
72609 pOrig->u.zToken = 0;
72610 pDup = sqlite3ExprDup(db, pOrig, 0);
72611 pOrig->u.zToken = zToken;
72612 if( pDup==0 ) return;
72613 assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
72614 pDup->flags2 |= EP2_MallocedToken;
72615 pDup->u.zToken = sqlite3DbStrDup(db, zToken);
72616 }
72617 if( pExpr->flags & EP_ExpCollate ){
72618 pDup->pColl = pExpr->pColl;
72619 pDup->flags |= EP_ExpCollate;
72620 }
72621
72622 /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
72623 ** prevents ExprDelete() from deleting the Expr structure itself,
72624 ** allowing it to be repopulated by the memcpy() on the following line.
 
 
 
72625 */
72626 ExprSetProperty(pExpr, EP_Static);
72627 sqlite3ExprDelete(db, pExpr);
72628 memcpy(pExpr, pDup, sizeof(*pExpr));
 
 
 
 
 
72629 sqlite3DbFree(db, pDup);
72630 }
72631
72632
72633 /*
@@ -72644,10 +72678,39 @@
72644 }
72645 }
72646 return 0;
72647 }
72648
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72649
72650 /*
72651 ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
72652 ** that name in the set of source tables in pSrcList and make the pExpr
72653 ** expression node refer back to that source column. The following changes
@@ -72699,44 +72762,63 @@
72699
72700 /* Initialize the node to no-match */
72701 pExpr->iTable = -1;
72702 pExpr->pTab = 0;
72703 ExprSetIrreducible(pExpr);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72704
72705 /* Start at the inner-most context and move outward until a match is found */
72706 while( pNC && cnt==0 ){
72707 ExprList *pEList;
72708 SrcList *pSrcList = pNC->pSrcList;
72709
72710 if( pSrcList ){
72711 for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
72712 Table *pTab;
72713 int iDb;
72714 Column *pCol;
72715
72716 pTab = pItem->pTab;
72717 assert( pTab!=0 && pTab->zName!=0 );
72718 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
72719 assert( pTab->nCol>0 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72720 if( zTab ){
72721 if( pItem->zAlias ){
72722 char *zTabName = pItem->zAlias;
72723 if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
72724 }else{
72725 char *zTabName = pTab->zName;
72726 if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){
72727 continue;
72728 }
72729 if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
72730 continue;
72731 }
72732 }
72733 }
72734 if( 0==(cntTab++) ){
72735 pExpr->iTable = pItem->iCursor;
72736 pExpr->pTab = pTab;
72737 pSchema = pTab->pSchema;
72738 pMatch = pItem;
72739 }
72740 for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
72741 if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
72742 /* If there has been exactly one prior match and this match
@@ -72746,21 +72828,23 @@
72746 if( cnt==1 ){
72747 if( pItem->jointype & JT_NATURAL ) continue;
72748 if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
72749 }
72750 cnt++;
72751 pExpr->iTable = pItem->iCursor;
72752 pExpr->pTab = pTab;
72753 pMatch = pItem;
72754 pSchema = pTab->pSchema;
72755 /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
72756 pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
72757 break;
72758 }
72759 }
72760 }
72761 }
 
 
 
 
 
72762
72763 #ifndef SQLITE_OMIT_TRIGGER
72764 /* If we have not already resolved the name, then maybe
72765 ** it is a new.* or old.* trigger argument reference
72766 */
@@ -73055,42 +73139,43 @@
73055 int wrong_num_args = 0; /* True if wrong number of arguments */
73056 int is_agg = 0; /* True if is an aggregate function */
73057 int auth; /* Authorization to use the function */
73058 int nId; /* Number of characters in function name */
73059 const char *zId; /* The function name. */
73060 FuncDef *pDef; /* Information about the function */
73061 u8 enc = ENC(pParse->db); /* The database encoding */
73062
73063 testcase( pExpr->op==TK_CONST_FUNC );
73064 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
73065 zId = pExpr->u.zToken;
73066 nId = sqlite3Strlen30(zId);
73067 pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
73068 if( pDef==0 ){
73069 pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
73070 if( pDef==0 ){
73071 no_such_func = 1;
73072 }else{
73073 wrong_num_args = 1;
73074 }
73075 }else{
73076 is_agg = pDef->xFunc==0;
73077 }
73078 #ifndef SQLITE_OMIT_AUTHORIZATION
73079 if( pDef ){
73080 auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
73081 if( auth!=SQLITE_OK ){
73082 if( auth==SQLITE_DENY ){
73083 sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
73084 pDef->zName);
73085 pNC->nErr++;
73086 }
73087 pExpr->op = TK_NULL;
73088 return WRC_Prune;
73089 }
73090 }
73091 #endif
 
 
73092 if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
73093 sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
73094 pNC->nErr++;
73095 is_agg = 0;
73096 }else if( no_such_func ){
@@ -73310,11 +73395,11 @@
73310 assert( pEList!=0 );
73311 for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
73312 int iCol = -1;
73313 Expr *pE, *pDup;
73314 if( pItem->done ) continue;
73315 pE = pItem->pExpr;
73316 if( sqlite3ExprIsInteger(pE, &iCol) ){
73317 if( iCol<=0 || iCol>pEList->nExpr ){
73318 resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
73319 return 1;
73320 }
@@ -73328,18 +73413,24 @@
73328 }
73329 sqlite3ExprDelete(db, pDup);
73330 }
73331 }
73332 if( iCol>0 ){
73333 CollSeq *pColl = pE->pColl;
73334 int flags = pE->flags & EP_ExpCollate;
 
 
 
 
 
 
 
 
 
 
 
73335 sqlite3ExprDelete(db, pE);
73336 pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
73337 if( pE==0 ) return 1;
73338 pE->pColl = pColl;
73339 pE->flags |= EP_IntValue | flags;
73340 pE->u.iValue = iCol;
73341 pItem->iOrderByCol = (u16)iCol;
73342 pItem->done = 1;
73343 }else{
73344 moreToDo = 1;
73345 }
@@ -73440,15 +73531,15 @@
73440 ** sqlite3ResolveOrderGroupBy() will convert the expression to a
73441 ** copy of the iCol-th result-set expression. */
73442 pItem->iOrderByCol = (u16)iCol;
73443 continue;
73444 }
73445 if( sqlite3ExprIsInteger(pE, &iCol) ){
73446 /* The ORDER BY term is an integer constant. Again, set the column
73447 ** number so that sqlite3ResolveOrderGroupBy() will convert the
73448 ** order-by term to a copy of the result-set expression */
73449 if( iCol<1 ){
73450 resolveOutOfRangeError(pParse, zType, i+1, nResult);
73451 return 1;
73452 }
73453 pItem->iOrderByCol = (u16)iCol;
73454 continue;
@@ -73521,27 +73612,10 @@
73521 if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
73522 sqlite3ResolveExprNames(&sNC, p->pOffset) ){
73523 return WRC_Abort;
73524 }
73525
73526 /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
73527 ** resolve the result-set expression list.
73528 */
73529 sNC.ncFlags = NC_AllowAgg;
73530 sNC.pSrcList = p->pSrc;
73531 sNC.pNext = pOuterNC;
73532
73533 /* Resolve names in the result set. */
73534 pEList = p->pEList;
73535 assert( pEList!=0 );
73536 for(i=0; i<pEList->nExpr; i++){
73537 Expr *pX = pEList->a[i].pExpr;
73538 if( sqlite3ResolveExprNames(&sNC, pX) ){
73539 return WRC_Abort;
73540 }
73541 }
73542
73543 /* Recursively resolve names in all subqueries
73544 */
73545 for(i=0; i<p->pSrc->nSrc; i++){
73546 struct SrcList_item *pItem = &p->pSrc->a[i];
73547 if( pItem->pSelect ){
@@ -73564,10 +73638,27 @@
73564 for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
73565 assert( pItem->isCorrelated==0 && nRef<=0 );
73566 pItem->isCorrelated = (nRef!=0);
73567 }
73568 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73569
73570 /* If there are no aggregate functions in the result-set, and no GROUP BY
73571 ** expression, do not allow aggregates in any of the other expressions.
73572 */
73573 assert( (p->selFlags & SF_Aggregate)==0 );
@@ -73798,11 +73889,13 @@
73798 ** SELECT * FROM t1 WHERE a;
73799 ** SELECT a AS b FROM t1 WHERE b;
73800 ** SELECT * FROM t1 WHERE (select a from t1);
73801 */
73802 SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
73803 int op = pExpr->op;
 
 
73804 if( op==TK_SELECT ){
73805 assert( pExpr->flags&EP_xIsSelect );
73806 return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
73807 }
73808 #ifndef SQLITE_OMIT_CAST
@@ -73823,70 +73916,98 @@
73823 }
73824 return pExpr->affinity;
73825 }
73826
73827 /*
73828 ** Set the explicit collating sequence for an expression to the
73829 ** collating sequence supplied in the second argument.
73830 */
73831 SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){
73832 if( pExpr && pColl ){
73833 pExpr->pColl = pColl;
73834 pExpr->flags |= EP_ExpCollate;
73835 }
73836 return pExpr;
73837 }
73838
73839 /*
73840 ** Set the collating sequence for expression pExpr to be the collating
73841 ** sequence named by pToken. Return a pointer to the revised expression.
73842 ** The collating sequence is marked as "explicit" using the EP_ExpCollate
73843 ** flag. An explicit collating sequence will override implicit
73844 ** collating sequences.
73845 */
73846 SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){
73847 char *zColl = 0; /* Dequoted name of collation sequence */
73848 CollSeq *pColl;
73849 sqlite3 *db = pParse->db;
73850 zColl = sqlite3NameFromToken(db, pCollName);
73851 pColl = sqlite3LocateCollSeq(pParse, zColl);
73852 sqlite3ExprSetColl(pExpr, pColl);
73853 sqlite3DbFree(db, zColl);
73854 return pExpr;
73855 }
73856
73857 /*
73858 ** Return the default collation sequence for the expression pExpr. If
73859 ** there is no default collation type, return 0.
73860 */
73861 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
73862 CollSeq *pColl = 0;
73863 Expr *p = pExpr;
73864 while( p ){
73865 int op;
73866 pColl = p->pColl;
73867 if( pColl ) break;
73868 op = p->op;
73869 if( p->pTab!=0 && (
73870 op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
73871 )){
73872 /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
73873 ** a TK_COLUMN but was previously evaluated and cached in a register */
73874 const char *zColl;
73875 int j = p->iColumn;
73876 if( j>=0 ){
73877 sqlite3 *db = pParse->db;
73878 zColl = p->pTab->aCol[j].zColl;
73879 pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
73880 pExpr->pColl = pColl;
73881 }
73882 break;
73883 }
73884 if( op!=TK_CAST && op!=TK_UPLUS ){
73885 break;
73886 }
73887 p = p->pLeft;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73888 }
73889 if( sqlite3CheckCollSeq(pParse, pColl) ){
73890 pColl = 0;
73891 }
73892 return pColl;
@@ -73986,16 +74107,14 @@
73986 Expr *pLeft,
73987 Expr *pRight
73988 ){
73989 CollSeq *pColl;
73990 assert( pLeft );
73991 if( pLeft->flags & EP_ExpCollate ){
73992 assert( pLeft->pColl );
73993 pColl = pLeft->pColl;
73994 }else if( pRight && pRight->flags & EP_ExpCollate ){
73995 assert( pRight->pColl );
73996 pColl = pRight->pColl;
73997 }else{
73998 pColl = sqlite3ExprCollSeq(pParse, pLeft);
73999 if( !pColl ){
74000 pColl = sqlite3ExprCollSeq(pParse, pRight);
74001 }
@@ -74221,21 +74340,15 @@
74221 sqlite3ExprDelete(db, pLeft);
74222 sqlite3ExprDelete(db, pRight);
74223 }else{
74224 if( pRight ){
74225 pRoot->pRight = pRight;
74226 if( pRight->flags & EP_ExpCollate ){
74227 pRoot->flags |= EP_ExpCollate;
74228 pRoot->pColl = pRight->pColl;
74229 }
74230 }
74231 if( pLeft ){
74232 pRoot->pLeft = pLeft;
74233 if( pLeft->flags & EP_ExpCollate ){
74234 pRoot->flags |= EP_ExpCollate;
74235 pRoot->pColl = pLeft->pColl;
74236 }
74237 }
74238 exprSetHeight(pRoot);
74239 }
74240 }
74241
@@ -74489,11 +74602,11 @@
74489 }else{
74490 assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
74491 assert( !ExprHasProperty(p, EP_FromJoin) );
74492 assert( (p->flags2 & EP2_MallocedToken)==0 );
74493 assert( (p->flags2 & EP2_Irreducible)==0 );
74494 if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
74495 nSize = EXPR_REDUCEDSIZE | EP_Reduced;
74496 }else{
74497 nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
74498 }
74499 }
@@ -76513,10 +76626,11 @@
76513 sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
76514 sqlite3ReleaseTempReg(pParse, r3);
76515 sqlite3ReleaseTempReg(pParse, r4);
76516 break;
76517 }
 
76518 case TK_UPLUS: {
76519 inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
76520 break;
76521 }
76522
@@ -76881,10 +76995,16 @@
76881 case TK_UPLUS: zUniOp = "UPLUS"; break;
76882 case TK_BITNOT: zUniOp = "BITNOT"; break;
76883 case TK_NOT: zUniOp = "NOT"; break;
76884 case TK_ISNULL: zUniOp = "ISNULL"; break;
76885 case TK_NOTNULL: zUniOp = "NOTNULL"; break;
 
 
 
 
 
 
76886
76887 case TK_AGG_FUNCTION:
76888 case TK_CONST_FUNC:
76889 case TK_FUNCTION: {
76890 ExprList *pFarg; /* List of function arguments */
@@ -77019,10 +77139,16 @@
77019 for(i=0; i<pList->nExpr; i++){
77020 sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
77021 sqlite3ExplainPush(pOut);
77022 sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
77023 sqlite3ExplainPop(pOut);
 
 
 
 
 
 
77024 if( i<pList->nExpr-1 ){
77025 sqlite3ExplainNL(pOut);
77026 }
77027 }
77028 sqlite3ExplainPop(pOut);
@@ -77100,10 +77226,13 @@
77100 switch( pExpr->op ){
77101 case TK_IN:
77102 case TK_REGISTER: {
77103 return WRC_Prune;
77104 }
 
 
 
77105 case TK_FUNCTION:
77106 case TK_AGG_FUNCTION:
77107 case TK_CONST_FUNC: {
77108 /* The arguments to a function have a fixed destination.
77109 ** Mark them this way to avoid generated unneeded OP_SCopy
@@ -77121,13 +77250,15 @@
77121 break;
77122 }
77123 }
77124 if( isAppropriateForFactoring(pExpr) ){
77125 int r1 = ++pParse->nMem;
77126 int r2;
77127 r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
77128 if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
 
 
77129 pExpr->op2 = pExpr->op;
77130 pExpr->op = TK_REGISTER;
77131 pExpr->iTable = r2;
77132 return WRC_Prune;
77133 }
@@ -77540,11 +77671,19 @@
77540 assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
77541 if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
77542 return 2;
77543 }
77544 if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
77545 if( pA->op!=pB->op ) return 2;
 
 
 
 
 
 
 
 
77546 if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
77547 if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
77548 if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
77549 if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
77550 if( ExprHasProperty(pA, EP_IntValue) ){
@@ -77552,15 +77691,13 @@
77552 return 2;
77553 }
77554 }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
77555 if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
77556 if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
77557 return 2;
77558 }
77559 }
77560 if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
77561 if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
77562 return 0;
77563 }
77564
77565 /*
77566 ** Compare two ExprList objects. Return 0 if they are identical and
@@ -83371,14 +83508,12 @@
83371 ** specified collation sequence names.
83372 */
83373 for(i=0; i<pList->nExpr; i++){
83374 Expr *pExpr = pList->a[i].pExpr;
83375 if( pExpr ){
83376 CollSeq *pColl = pExpr->pColl;
83377 /* Either pColl!=0 or there was an OOM failure. But if an OOM
83378 ** failure we have quit before reaching this point. */
83379 if( ALWAYS(pColl) ){
83380 nExtra += (1 + sqlite3Strlen30(pColl->zName));
83381 }
83382 }
83383 }
83384
@@ -83437,10 +83572,11 @@
83437 */
83438 for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
83439 const char *zColName = pListItem->zName;
83440 Column *pTabCol;
83441 int requestedSortOrder;
 
83442 char *zColl; /* Collation sequence name */
83443
83444 for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
83445 if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
83446 }
@@ -83449,18 +83585,15 @@
83449 pTab->zName, zColName);
83450 pParse->checkSchema = 1;
83451 goto exit_create_index;
83452 }
83453 pIndex->aiColumn[i] = j;
83454 /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
83455 ** the way the "idxlist" non-terminal is constructed by the parser,
83456 ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
83457 ** must exist or else there must have been an OOM error. But if there
83458 ** was an OOM error, we would never reach this point. */
83459 if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
83460 int nColl;
83461 zColl = pListItem->pExpr->pColl->zName;
83462 nColl = sqlite3Strlen30(zColl) + 1;
83463 assert( nExtra>=nColl );
83464 memcpy(zExtra, zColl, nColl);
83465 zColl = zExtra;
83466 zExtra += nColl;
@@ -87489,11 +87622,11 @@
87489
87490 /*
87491 ** A foreign key constraint requires that the key columns in the parent
87492 ** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
87493 ** Given that pParent is the parent table for foreign key constraint pFKey,
87494 ** search the schema a unique index on the parent key columns.
87495 **
87496 ** If successful, zero is returned. If the parent key is an INTEGER PRIMARY
87497 ** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx
87498 ** is set to point to the unique index.
87499 **
@@ -87525,11 +87658,11 @@
87525 **
87526 ** then non-zero is returned, and a "foreign key mismatch" error loaded
87527 ** into pParse. If an OOM error occurs, non-zero is returned and the
87528 ** pParse->db->mallocFailed flag is set.
87529 */
87530 static int locateFkeyIndex(
87531 Parse *pParse, /* Parse context to store any error in */
87532 Table *pParent, /* Parent table of FK constraint pFKey */
87533 FKey *pFKey, /* Foreign key to find index for */
87534 Index **ppIdx, /* OUT: Unique index on parent table */
87535 int **paiCol /* OUT: Map of index columns in pFKey */
@@ -87622,11 +87755,13 @@
87622 }
87623 }
87624
87625 if( !pIdx ){
87626 if( !pParse->disableTriggers ){
87627 sqlite3ErrorMsg(pParse, "foreign key mismatch");
 
 
87628 }
87629 sqlite3DbFree(pParse->db, aiCol);
87630 return 1;
87631 }
87632
@@ -87858,16 +87993,19 @@
87858 if( pLeft ){
87859 /* Set the collation sequence and affinity of the LHS of each TK_EQ
87860 ** expression to the parent key column defaults. */
87861 if( pIdx ){
87862 Column *pCol;
 
87863 iCol = pIdx->aiColumn[i];
87864 pCol = &pTab->aCol[iCol];
87865 if( pTab->iPKey==iCol ) iCol = -1;
87866 pLeft->iTable = regData+iCol+1;
87867 pLeft->affinity = pCol->affinity;
87868 pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl);
 
 
87869 }else{
87870 pLeft->iTable = regData;
87871 pLeft->affinity = SQLITE_AFF_INTEGER;
87872 }
87873 }
@@ -88080,11 +88218,11 @@
88080 if( pParse->disableTriggers ){
88081 pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
88082 }else{
88083 pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
88084 }
88085 if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
88086 assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
88087 if( !isIgnoreErrors || db->mallocFailed ) return;
88088 if( pTo==0 ){
88089 /* If isIgnoreErrors is true, then a table is being dropped. In this
88090 ** case SQLite runs a "DELETE FROM xxx" on the table being dropped
@@ -88160,11 +88298,11 @@
88160 /* Inserting a single row into a parent table cannot cause an immediate
88161 ** foreign key violation. So do nothing in this case. */
88162 continue;
88163 }
88164
88165 if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
88166 if( !isIgnoreErrors || db->mallocFailed ) return;
88167 continue;
88168 }
88169 assert( aiCol || pFKey->nCol==1 );
88170
@@ -88215,11 +88353,11 @@
88215 for(p=pTab->pFKey; p; p=p->pNextFrom){
88216 for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
88217 }
88218 for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
88219 Index *pIdx = 0;
88220 locateFkeyIndex(pParse, pTab, p, &pIdx, 0);
88221 if( pIdx ){
88222 for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
88223 }
88224 }
88225 }
@@ -88341,11 +88479,11 @@
88341 ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */
88342 Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */
88343 int i; /* Iterator variable */
88344 Expr *pWhen = 0; /* WHEN clause for the trigger */
88345
88346 if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
88347 assert( aiCol || pFKey->nCol==1 );
88348
88349 for(i=0; i<pFKey->nCol; i++){
88350 Token tOld = { "old", 3 }; /* Literal "old" token */
88351 Token tNew = { "new", 3 }; /* Literal "new" token */
@@ -89843,29 +89981,24 @@
89843 ExprList *pCheck = pTab->pCheck;
89844 pParse->ckBase = regData;
89845 onError = overrideError!=OE_Default ? overrideError : OE_Abort;
89846 for(i=0; i<pCheck->nExpr; i++){
89847 int allOk = sqlite3VdbeMakeLabel(v);
89848 Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0);
89849 if( !db->mallocFailed ){
89850 assert( pDup!=0 );
89851 sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL);
89852 if( onError==OE_Ignore ){
89853 sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
89854 }else{
89855 char *zConsName = pCheck->a[i].zName;
89856 if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
89857 if( zConsName ){
89858 zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
89859 }else{
89860 zConsName = 0;
89861 }
89862 sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
89863 }
89864 sqlite3VdbeResolveLabel(v, allOk);
89865 }
89866 sqlite3ExprDelete(db, pDup);
89867 }
89868 }
89869 #endif /* !defined(SQLITE_OMIT_CHECK) */
89870
89871 /* If we have an INTEGER PRIMARY KEY, make sure the primary key
@@ -92686,13 +92819,15 @@
92686 if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
92687 Table *pTab;
92688 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
92689 pTab = sqlite3FindTable(db, zRight, zDb);
92690 if( pTab ){
92691 int i;
92692 int nHidden = 0;
92693 Column *pCol;
 
 
92694 sqlite3VdbeSetNumCols(v, 6);
92695 pParse->nMem = 6;
92696 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
92697 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
92698 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
@@ -92713,12 +92848,18 @@
92713 if( pCol->zDflt ){
92714 sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
92715 }else{
92716 sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
92717 }
92718 sqlite3VdbeAddOp2(v, OP_Integer,
92719 (pCol->colFlags&COLFLAG_PRIMKEY)!=0, 6);
 
 
 
 
 
 
92720 sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
92721 }
92722 }
92723 }else
92724
@@ -92849,10 +92990,124 @@
92849 ++i;
92850 pFK = pFK->pNextFrom;
92851 }
92852 }
92853 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92854 }else
92855 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
92856
92857 #ifndef NDEBUG
92858 if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
@@ -94308,11 +94563,11 @@
94308 SrcList *pSrc, /* the FROM clause -- which tables to scan */
94309 Expr *pWhere, /* the WHERE clause */
94310 ExprList *pGroupBy, /* the GROUP BY clause */
94311 Expr *pHaving, /* the HAVING clause */
94312 ExprList *pOrderBy, /* the ORDER BY clause */
94313 int isDistinct, /* true if the DISTINCT keyword is present */
94314 Expr *pLimit, /* LIMIT value. NULL means not used */
94315 Expr *pOffset /* OFFSET value. NULL means no offset */
94316 ){
94317 Select *pNew;
94318 Select standin;
@@ -94332,11 +94587,11 @@
94332 pNew->pSrc = pSrc;
94333 pNew->pWhere = pWhere;
94334 pNew->pGroupBy = pGroupBy;
94335 pNew->pHaving = pHaving;
94336 pNew->pOrderBy = pOrderBy;
94337 pNew->selFlags = isDistinct ? SF_Distinct : 0;
94338 pNew->op = TK_SELECT;
94339 pNew->pLimit = pLimit;
94340 pNew->pOffset = pOffset;
94341 assert( pOffset==0 || pLimit!=0 );
94342 pNew->addrOpenEphm[0] = -1;
@@ -95588,13 +95843,11 @@
95588 *paCol = aCol;
95589
95590 for(i=0, pCol=aCol; i<nCol; i++, pCol++){
95591 /* Get an appropriate name for the column
95592 */
95593 p = pEList->a[i].pExpr;
95594 assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
95595 || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
95596 if( (zName = pEList->a[i].zName)!=0 ){
95597 /* If the column contains an "AS <name>" phrase, use <name> as the name */
95598 zName = sqlite3DbStrDup(db, zName);
95599 }else{
95600 Expr *pColExpr = p; /* The expression that is the result column name */
@@ -95628,10 +95881,13 @@
95628 */
95629 nName = sqlite3Strlen30(zName);
95630 for(j=cnt=0; j<i; j++){
95631 if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
95632 char *zNewName;
 
 
 
95633 zName[nName] = 0;
95634 zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
95635 sqlite3DbFree(db, zName);
95636 zName = zNewName;
95637 j = -1;
@@ -96586,16 +96842,17 @@
96586 pKeyMerge->nField = (u16)nOrderBy;
96587 pKeyMerge->enc = ENC(db);
96588 for(i=0; i<nOrderBy; i++){
96589 CollSeq *pColl;
96590 Expr *pTerm = pOrderBy->a[i].pExpr;
96591 if( pTerm->flags & EP_ExpCollate ){
96592 pColl = pTerm->pColl;
96593 }else{
96594 pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
96595 pTerm->flags |= EP_ExpCollate;
96596 pTerm->pColl = pColl;
 
96597 }
96598 pKeyMerge->aColl[i] = pColl;
96599 pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
96600 }
96601 }
@@ -96794,10 +97051,11 @@
96794 */
96795 sqlite3VdbeResolveLabel(v, labelCmpr);
96796 sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
96797 sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
96798 (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
 
96799 sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
96800
96801 /* Release temporary registers
96802 */
96803 if( regPrev ){
@@ -96861,13 +97119,10 @@
96861 }else{
96862 Expr *pNew;
96863 assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
96864 assert( pExpr->pLeft==0 && pExpr->pRight==0 );
96865 pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
96866 if( pNew && pExpr->pColl ){
96867 pNew->pColl = pExpr->pColl;
96868 }
96869 sqlite3ExprDelete(db, pExpr);
96870 pExpr = pNew;
96871 }
96872 }else{
96873 pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
@@ -97414,38 +97669,47 @@
97414 return 1;
97415 }
97416 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
97417
97418 /*
97419 ** Analyze the SELECT statement passed as an argument to see if it
97420 ** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if
97421 ** it is, or 0 otherwise. At present, a query is considered to be
97422 ** a min()/max() query if:
97423 **
97424 ** 1. There is a single object in the FROM clause.
97425 **
97426 ** 2. There is a single expression in the result set, and it is
97427 ** either min(x) or max(x), where x is a column reference.
97428 */
97429 static u8 minMaxQuery(Select *p){
97430 Expr *pExpr;
97431 ExprList *pEList = p->pEList;
97432
97433 if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
97434 pExpr = pEList->a[0].pExpr;
97435 if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
97436 if( NEVER(ExprHasProperty(pExpr, EP_xIsSelect)) ) return 0;
97437 pEList = pExpr->x.pList;
97438 if( pEList==0 || pEList->nExpr!=1 ) return 0;
97439 if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
97440 assert( !ExprHasProperty(pExpr, EP_IntValue) );
97441 if( sqlite3StrICmp(pExpr->u.zToken,"min")==0 ){
97442 return WHERE_ORDERBY_MIN;
97443 }else if( sqlite3StrICmp(pExpr->u.zToken,"max")==0 ){
97444 return WHERE_ORDERBY_MAX;
97445 }
97446 return WHERE_ORDERBY_NORMAL;
 
 
 
 
 
 
 
 
 
97447 }
97448
97449 /*
97450 ** The select statement passed as the first argument is an aggregate query.
97451 ** The second argment is the associated aggregate-info object. This
@@ -97536,10 +97800,11 @@
97536 int i, j, k;
97537 SrcList *pTabList;
97538 ExprList *pEList;
97539 struct SrcList_item *pFrom;
97540 sqlite3 *db = pParse->db;
 
97541
97542 if( db->mallocFailed ){
97543 return WRC_Abort;
97544 }
97545 if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
@@ -97621,11 +97886,11 @@
97621 **
97622 ** The first loop just checks to see if there are any "*" operators
97623 ** that need expanding.
97624 */
97625 for(k=0; k<pEList->nExpr; k++){
97626 Expr *pE = pEList->a[k].pExpr;
97627 if( pE->op==TK_ALL ) break;
97628 assert( pE->op!=TK_DOT || pE->pRight!=0 );
97629 assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
97630 if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
97631 }
@@ -97639,14 +97904,22 @@
97639 ExprList *pNew = 0;
97640 int flags = pParse->db->flags;
97641 int longNames = (flags & SQLITE_FullColNames)!=0
97642 && (flags & SQLITE_ShortColNames)==0;
97643
 
 
 
 
 
 
 
97644 for(k=0; k<pEList->nExpr; k++){
97645 Expr *pE = a[k].pExpr;
97646 assert( pE->op!=TK_DOT || pE->pRight!=0 );
97647 if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight->op!=TK_ALL) ){
 
97648 /* This particular expression does not need to be expanded.
97649 */
97650 pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
97651 if( pNew ){
97652 pNew->a[pNew->nExpr-1].zName = a[k].zName;
@@ -97657,44 +97930,56 @@
97657 a[k].pExpr = 0;
97658 }else{
97659 /* This expression is a "*" or a "TABLE.*" and needs to be
97660 ** expanded. */
97661 int tableSeen = 0; /* Set to 1 when TABLE matches */
97662 char *zTName; /* text of name of TABLE */
97663 if( pE->op==TK_DOT ){
97664 assert( pE->pLeft!=0 );
97665 assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
97666 zTName = pE->pLeft->u.zToken;
97667 }else{
97668 zTName = 0;
97669 }
97670 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
97671 Table *pTab = pFrom->pTab;
 
97672 char *zTabName = pFrom->zAlias;
 
 
97673 if( zTabName==0 ){
97674 zTabName = pTab->zName;
97675 }
97676 if( db->mallocFailed ) break;
97677 if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
97678 continue;
 
 
 
 
 
97679 }
97680 tableSeen = 1;
97681 for(j=0; j<pTab->nCol; j++){
97682 Expr *pExpr, *pRight;
97683 char *zName = pTab->aCol[j].zName;
97684 char *zColname; /* The computed column name */
97685 char *zToFree; /* Malloced string that needs to be freed */
97686 Token sColname; /* Computed column name as a token */
 
 
 
 
 
 
 
97687
97688 /* If a column is marked as 'hidden' (currently only possible
97689 ** for virtual tables), do not include it in the expanded
97690 ** result-set list.
97691 */
97692 if( IsHiddenColumn(&pTab->aCol[j]) ){
97693 assert(IsVirtual(pTab));
97694 continue;
97695 }
 
97696
97697 if( i>0 && zTName==0 ){
97698 if( (pFrom->jointype & JT_NATURAL)!=0
97699 && tableAndColumnIndex(pTabList, i, zName, 0, 0)
97700 ){
@@ -97713,10 +97998,14 @@
97713 zToFree = 0;
97714 if( longNames || pTabList->nSrc>1 ){
97715 Expr *pLeft;
97716 pLeft = sqlite3Expr(db, TK_ID, zTabName);
97717 pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
 
 
 
 
97718 if( longNames ){
97719 zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
97720 zToFree = zColname;
97721 }
97722 }else{
@@ -97724,10 +98013,22 @@
97724 }
97725 pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
97726 sColname.z = zColname;
97727 sColname.n = sqlite3Strlen30(zColname);
97728 sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
 
 
 
 
 
 
 
 
 
 
 
 
97729 sqlite3DbFree(db, zToFree);
97730 }
97731 }
97732 if( !tableSeen ){
97733 if( zTName ){
@@ -98781,15 +99082,21 @@
98781 ** index or indices to use) should place a different priority on
98782 ** satisfying the 'ORDER BY' clause than it does in other cases.
98783 ** Refer to code and comments in where.c for details.
98784 */
98785 ExprList *pMinMax = 0;
98786 u8 flag = minMaxQuery(p);
 
 
 
 
 
 
 
 
98787 if( flag ){
98788 assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
98789 assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 );
98790 pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
98791 pDel = pMinMax;
98792 if( pMinMax && !db->mallocFailed ){
98793 pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
98794 pMinMax->a[0].pExpr->op = TK_COLUMN;
98795 }
@@ -102673,11 +102980,11 @@
102673 #define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */
102674 #define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */
102675 #define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */
102676 #define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
102677 #define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
102678 #define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */
102679 #define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
102680 #define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
102681 #define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
102682 #define WHERE_IDX_ONLY 0x00400000 /* Use index only - omit table */
102683 #define WHERE_ORDERED 0x00800000 /* Output will appear in correct order */
@@ -102823,11 +103130,11 @@
102823 sqlite3DbFree(db, pOld);
102824 }
102825 pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
102826 }
102827 pTerm = &pWC->a[idx = pWC->nTerm++];
102828 pTerm->pExpr = p;
102829 pTerm->wtFlags = wtFlags;
102830 pTerm->pWC = pWC;
102831 pTerm->iParent = -1;
102832 return idx;
102833 }
@@ -102983,27 +103290,36 @@
102983
102984 /*
102985 ** Commute a comparison operator. Expressions of the form "X op Y"
102986 ** are converted into "Y op X".
102987 **
102988 ** If a collation sequence is associated with either the left or right
 
102989 ** side of the comparison, it remains associated with the same side after
102990 ** the commutation. So "Y collate NOCASE op X" becomes
102991 ** "X collate NOCASE op Y". This is because any collation sequence on
102992 ** the left hand side of a comparison overrides any collation sequence
102993 ** attached to the right. For the same reason the EP_ExpCollate flag
102994 ** is not commuted.
102995 */
102996 static void exprCommute(Parse *pParse, Expr *pExpr){
102997 u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
102998 u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
102999 assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
103000 pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
103001 pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
103002 SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
103003 pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;
103004 pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;
 
 
 
 
 
 
 
 
103005 SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
103006 if( pExpr->op>=TK_GT ){
103007 assert( TK_LT==TK_GT+2 );
103008 assert( TK_GE==TK_LE+2 );
103009 assert( TK_GT>TK_EQ );
@@ -103076,16 +103392,16 @@
103076 ** it to be useful for optimising expression pX. Store this
103077 ** value in variable pColl.
103078 */
103079 assert(pX->pLeft);
103080 pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
103081 assert(pColl || pParse->nErr);
103082
103083 for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
103084 if( NEVER(j>=pIdx->nColumn) ) return 0;
103085 }
103086 if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
103087 }
103088 return pTerm;
103089 }
103090 }
103091 }
@@ -103600,10 +103916,11 @@
103600 return;
103601 }
103602 pTerm = &pWC->a[idxTerm];
103603 pMaskSet = pWC->pMaskSet;
103604 pExpr = pTerm->pExpr;
 
103605 prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
103606 op = pExpr->op;
103607 if( op==TK_IN ){
103608 assert( pExpr->pRight==0 );
103609 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
@@ -103626,12 +103943,12 @@
103626 pTerm->prereqAll = prereqAll;
103627 pTerm->leftCursor = -1;
103628 pTerm->iParent = -1;
103629 pTerm->eOperator = 0;
103630 if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
103631 Expr *pLeft = pExpr->pLeft;
103632 Expr *pRight = pExpr->pRight;
103633 if( pLeft->op==TK_COLUMN ){
103634 pTerm->leftCursor = pLeft->iTable;
103635 pTerm->u.leftColumn = pLeft->iColumn;
103636 pTerm->eOperator = operatorMask(op);
103637 }
@@ -103655,11 +103972,11 @@
103655 }else{
103656 pDup = pExpr;
103657 pNew = pTerm;
103658 }
103659 exprCommute(pParse, pDup);
103660 pLeft = pDup->pLeft;
103661 pNew->leftCursor = pLeft->iTable;
103662 pNew->u.leftColumn = pLeft->iColumn;
103663 testcase( (prereqLeft | extraRight) != prereqLeft );
103664 pNew->prereqRight = prereqLeft | extraRight;
103665 pNew->prereqAll = prereqAll;
@@ -103734,11 +104051,11 @@
103734 Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */
103735 Expr *pNewExpr1;
103736 Expr *pNewExpr2;
103737 int idxNew1;
103738 int idxNew2;
103739 CollSeq *pColl; /* Collating sequence to use */
103740
103741 pLeft = pExpr->x.pList->a[1].pExpr;
103742 pStr2 = sqlite3ExprDup(db, pStr1, 0);
103743 if( !db->mallocFailed ){
103744 u8 c, *pC; /* Last character before the first wildcard */
@@ -103756,20 +104073,23 @@
103756
103757 c = sqlite3UpperToLower[c];
103758 }
103759 *pC = c + 1;
103760 }
103761 pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0);
 
 
103762 pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
103763 sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
103764 pStr1, 0);
103765 idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
103766 testcase( idxNew1==0 );
103767 exprAnalyze(pSrc, pWC, idxNew1);
 
103768 pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
103769 sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
103770 pStr2, 0);
103771 idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
103772 testcase( idxNew2==0 );
103773 exprAnalyze(pSrc, pWC, idxNew2);
103774 pTerm = &pWC->a[idxTerm];
103775 if( isComplete ){
@@ -103883,16 +104203,16 @@
103883 ){
103884 int i;
103885 const char *zColl = pIdx->azColl[iCol];
103886
103887 for(i=0; i<pList->nExpr; i++){
103888 Expr *p = pList->a[i].pExpr;
103889 if( p->op==TK_COLUMN
103890 && p->iColumn==pIdx->aiColumn[iCol]
103891 && p->iTable==iBase
103892 ){
103893 CollSeq *pColl = sqlite3ExprCollSeq(pParse, p);
103894 if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
103895 return i;
103896 }
103897 }
103898 }
@@ -103935,11 +104255,11 @@
103935 ** matching "col=X" expression and the column is on the same table as pIdx,
103936 ** set the corresponding bit in variable mask.
103937 */
103938 for(i=0; i<pDistinct->nExpr; i++){
103939 WhereTerm *pTerm;
103940 Expr *p = pDistinct->a[i].pExpr;
103941 if( p->op!=TK_COLUMN ) return 0;
103942 pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
103943 if( pTerm ){
103944 Expr *pX = pTerm->pExpr;
103945 CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -103987,11 +104307,11 @@
103987 /* If any of the expressions is an IPK column on table iBase, then return
103988 ** true. Note: The (p->iTable==iBase) part of this test may be false if the
103989 ** current SELECT is a correlated sub-query.
103990 */
103991 for(i=0; i<pDistinct->nExpr; i++){
103992 Expr *p = pDistinct->a[i].pExpr;
103993 if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
103994 }
103995
103996 /* Loop through all indices on the table, checking each to see if it makes
103997 ** the DISTINCT qualifier redundant. It does so if:
@@ -104464,11 +104784,11 @@
104464 for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
104465 if( pTerm->leftCursor != pSrc->iCursor ) continue;
104466 assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104467 testcase( pTerm->eOperator==WO_IN );
104468 testcase( pTerm->eOperator==WO_ISNULL );
104469 if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
104470 if( pTerm->wtFlags & TERM_VNULL ) continue;
104471 nTerm++;
104472 }
104473
104474 /* If the ORDER BY clause contains only columns in the current
@@ -104512,29 +104832,32 @@
104512 *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
104513 *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
104514 pUsage;
104515
104516 for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
 
104517 if( pTerm->leftCursor != pSrc->iCursor ) continue;
104518 assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104519 testcase( pTerm->eOperator==WO_IN );
104520 testcase( pTerm->eOperator==WO_ISNULL );
104521 if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
104522 if( pTerm->wtFlags & TERM_VNULL ) continue;
104523 pIdxCons[j].iColumn = pTerm->u.leftColumn;
104524 pIdxCons[j].iTermOffset = i;
104525 pIdxCons[j].op = (u8)pTerm->eOperator;
 
 
104526 /* The direct assignment in the previous line is possible only because
104527 ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
104528 ** following asserts verify this fact. */
104529 assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
104530 assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
104531 assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
104532 assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
104533 assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
104534 assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
104535 assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
104536 j++;
104537 }
104538 for(i=0; i<nOrderBy; i++){
104539 Expr *pExpr = pOrderBy->a[i].pExpr;
104540 pIdxOrderBy[i].iColumn = pExpr->iColumn;
@@ -104616,10 +104939,11 @@
104616 struct sqlite3_index_constraint *pIdxCons;
104617 struct sqlite3_index_constraint_usage *pUsage;
104618 WhereTerm *pTerm;
104619 int i, j;
104620 int nOrderBy;
 
104621 double rCost;
104622
104623 /* Make sure wsFlags is initialized to some sane value. Otherwise, if the
104624 ** malloc in allocateIndexInfo() fails and this function returns leaving
104625 ** wsFlags in an uninitialized state, the caller may behave unpredictably.
@@ -104650,63 +104974,91 @@
104650 ** sqlite3ViewGetColumnNames() would have picked up the error.
104651 */
104652 assert( pTab->azModuleArg && pTab->azModuleArg[0] );
104653 assert( sqlite3GetVTable(pParse->db, pTab) );
104654
104655 /* Set the aConstraint[].usable fields and initialize all
104656 ** output variables to zero.
104657 **
104658 ** aConstraint[].usable is true for constraints where the right-hand
104659 ** side contains only references to tables to the left of the current
104660 ** table. In other words, if the constraint is of the form:
104661 **
104662 ** column = expr
104663 **
104664 ** and we are evaluating a join, then the constraint on column is
104665 ** only valid if all tables referenced in expr occur to the left
104666 ** of the table containing column.
104667 **
104668 ** The aConstraints[] array contains entries for all constraints
104669 ** on the current table. That way we only have to compute it once
104670 ** even though we might try to pick the best index multiple times.
104671 ** For each attempt at picking an index, the order of tables in the
104672 ** join might be different so we have to recompute the usable flag
104673 ** each time.
104674 */
104675 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
104676 pUsage = pIdxInfo->aConstraintUsage;
104677 for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
104678 j = pIdxCons->iTermOffset;
104679 pTerm = &pWC->a[j];
104680 pIdxCons->usable = (pTerm->prereqRight&p->notReady) ? 0 : 1;
104681 }
104682 memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
104683 if( pIdxInfo->needToFreeIdxStr ){
104684 sqlite3_free(pIdxInfo->idxStr);
104685 }
104686 pIdxInfo->idxStr = 0;
104687 pIdxInfo->idxNum = 0;
104688 pIdxInfo->needToFreeIdxStr = 0;
104689 pIdxInfo->orderByConsumed = 0;
104690 /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
104691 pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
104692 nOrderBy = pIdxInfo->nOrderBy;
104693 if( !p->pOrderBy ){
104694 pIdxInfo->nOrderBy = 0;
104695 }
104696
104697 if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
104698 return;
104699 }
104700
104701 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
104702 for(i=0; i<pIdxInfo->nConstraint; i++){
104703 if( pUsage[i].argvIndex>0 ){
104704 p->cost.used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
104705 }
104706 }
104707
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104708 /* If there is an ORDER BY clause, and the selected virtual table index
104709 ** does not satisfy it, increase the cost of the scan accordingly. This
104710 ** matches the processing for non-virtual tables in bestBtreeIndex().
104711 */
104712 rCost = pIdxInfo->estimatedCost;
@@ -105273,11 +105625,11 @@
105273 WhereTerm *pConstraint; /* A constraint in the WHERE clause */
105274
105275 /* If the next term of the ORDER BY clause refers to anything other than
105276 ** a column in the "base" table, then this index will not be of any
105277 ** further use in handling the ORDER BY. */
105278 pOBExpr = pOBItem->pExpr;
105279 if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
105280 break;
105281 }
105282
105283 /* Find column number and collating sequence for the next entry
@@ -105299,11 +105651,11 @@
105299 /* Check to see if the column number and collating sequence of the
105300 ** index match the column number and collating sequence of the ORDER BY
105301 ** clause entry. Set isMatch to 1 if they both match. */
105302 if( pOBExpr->iColumn==iColumn ){
105303 if( zColl ){
105304 pColl = sqlite3ExprCollSeq(pParse, pOBExpr);
105305 if( !pColl ) pColl = db->pDfltColl;
105306 isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
105307 }else{
105308 isMatch = 1;
105309 }
@@ -105440,10 +105792,15 @@
105440 int idxEqTermMask; /* Index mask of valid equality operators */
105441 Index sPk; /* A fake index object for the primary key */
105442 tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
105443 int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
105444 int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */
 
 
 
 
 
105445
105446 /* Initialize the cost to a worst-case value */
105447 memset(&p->cost, 0, sizeof(p->cost));
105448 p->cost.rCost = SQLITE_BIG_DBL;
105449
@@ -105488,10 +105845,21 @@
105488 WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
105489 );
105490 eqTermMask = WO_EQ|WO_IN;
105491 pIdx = 0;
105492 }
 
 
 
 
 
 
 
 
 
 
 
105493
105494 /* Loop over all indices looking for the best one to use
105495 */
105496 for(; pProbe; pIdx=pProbe=pProbe->pNext){
105497 const tRowcnt * const aiRowEst = pProbe->aiRowEst;
@@ -105566,15 +105934,13 @@
105566 */
105567 int bInEst = 0; /* True if "x IN (SELECT...)" seen */
105568 int nInMul = 1; /* Number of distinct equalities to lookup */
105569 double rangeDiv = (double)1; /* Estimated reduction in search space */
105570 int nBound = 0; /* Number of range constraints seen */
105571 int bSort; /* True if external sort required */
105572 int bDist; /* True if index cannot help with DISTINCT */
105573 int bLookup = 0; /* True if not a covering index */
105574 int nPriorSat; /* ORDER BY terms satisfied by outer loops */
105575 int nOrderBy; /* Number of ORDER BY terms */
105576 WhereTerm *pTerm; /* A single term of the WHERE clause */
105577 #ifdef SQLITE_ENABLE_STAT3
105578 WhereTerm *pFirstTerm = 0; /* First term matching the index */
105579 #endif
105580
@@ -105581,20 +105947,11 @@
105581 WHERETRACE((
105582 " %s(%s):\n",
105583 pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
105584 ));
105585 memset(&pc, 0, sizeof(pc));
105586 nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
105587 if( p->i ){
105588 nPriorSat = pc.plan.nOBSat = p->aLevel[p->i-1].plan.nOBSat;
105589 bSort = nPriorSat<nOrderBy;
105590 bDist = 0;
105591 }else{
105592 nPriorSat = pc.plan.nOBSat = 0;
105593 bSort = nOrderBy>0;
105594 bDist = p->pDistinct!=0;
105595 }
105596
105597 /* Determine the values of pc.plan.nEq and nInMul */
105598 for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
105599 int j = pProbe->aiColumn[pc.plan.nEq];
105600 pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
@@ -106466,32 +106823,40 @@
106466 if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
106467 /* Case 0: The table is a virtual-table. Use the VFilter and VNext
106468 ** to access the data.
106469 */
106470 int iReg; /* P3 Value for OP_VFilter */
 
106471 sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
106472 int nConstraint = pVtabIdx->nConstraint;
106473 struct sqlite3_index_constraint_usage *aUsage =
106474 pVtabIdx->aConstraintUsage;
106475 const struct sqlite3_index_constraint *aConstraint =
106476 pVtabIdx->aConstraint;
106477
106478 sqlite3ExprCachePush(pParse);
106479 iReg = sqlite3GetTempRange(pParse, nConstraint+2);
 
106480 for(j=1; j<=nConstraint; j++){
106481 for(k=0; k<nConstraint; k++){
106482 if( aUsage[k].argvIndex==j ){
106483 int iTerm = aConstraint[k].iTermOffset;
106484 sqlite3ExprCode(pParse, pWC->a[iTerm].pExpr->pRight, iReg+j+1);
 
 
 
 
 
 
106485 break;
106486 }
106487 }
106488 if( k==nConstraint ) break;
106489 }
106490 sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
106491 sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
106492 sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrBrk, iReg, pVtabIdx->idxStr,
106493 pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
106494 pVtabIdx->needToFreeIdxStr = 0;
106495 for(j=0; j<nConstraint; j++){
106496 if( aUsage[j].omit ){
106497 int iTerm = aConstraint[j].iTermOffset;
@@ -108134,10 +108499,11 @@
108134 Expr* yy122;
108135 Select* yy159;
108136 IdList* yy180;
108137 struct {int value; int mask;} yy207;
108138 u8 yy258;
 
108139 struct LikeOp yy318;
108140 TriggerStep* yy327;
108141 ExprSpan yy342;
108142 SrcList* yy347;
108143 int yy392;
@@ -110084,22 +110450,19 @@
110084 case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
110085 case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
110086 case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
110087 case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
110088 case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
110089 case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120);
110090 case 121: /* distinct ::= */ yytestcase(yyruleno==121);
110091 case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
110092 case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
110093 {yygotominor.yy392 = 0;}
110094 break;
110095 case 29: /* ifnotexists ::= IF NOT EXISTS */
110096 case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
110097 case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
110098 case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
110099 case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
110100 case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119);
110101 case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
110102 case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
110103 {yygotominor.yy392 = 1;}
110104 break;
110105 case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
@@ -110335,12 +110698,19 @@
110335 case 116: /* multiselect_op ::= UNION ALL */
110336 {yygotominor.yy392 = TK_ALL;}
110337 break;
110338 case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
110339 {
110340 yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
110341 }
 
 
 
 
 
 
 
110342 break;
110343 case 122: /* sclp ::= selcollist COMMA */
110344 case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
110345 {yygotominor.yy442 = yymsp[-1].minor.yy442;}
110346 break;
@@ -110406,14 +110776,24 @@
110406 break;
110407 case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
110408 {
110409 if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
110410 yygotominor.yy347 = yymsp[-4].minor.yy347;
 
 
 
 
 
 
 
 
 
 
110411 }else{
110412 Select *pSubquery;
110413 sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
110414 pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,0,0,0);
110415 yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
110416 }
110417 }
110418 break;
110419 case 137: /* dbnm ::= */
@@ -110624,11 +111004,11 @@
110624 spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
110625 }
110626 break;
110627 case 194: /* expr ::= expr COLLATE ids */
110628 {
110629 yygotominor.yy342.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
110630 yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
110631 yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
110632 }
110633 break;
110634 case 195: /* expr ::= CAST LP expr AS typetoken RP */
@@ -110642,11 +111022,11 @@
110642 if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
110643 sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
110644 }
110645 yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
110646 spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
110647 if( yymsp[-2].minor.yy392 && yygotominor.yy342.pExpr ){
110648 yygotominor.yy342.pExpr->flags |= EP_Distinct;
110649 }
110650 }
110651 break;
110652 case 197: /* expr ::= ID LP STAR RP */
@@ -110883,28 +111263,20 @@
110883 case 244: /* uniqueflag ::= */
110884 {yygotominor.yy392 = OE_None;}
110885 break;
110886 case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
110887 {
110888 Expr *p = 0;
110889 if( yymsp[-1].minor.yy0.n>0 ){
110890 p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
110891 sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
110892 }
110893 yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
110894 sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
110895 sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
110896 if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
110897 }
110898 break;
110899 case 248: /* idxlist ::= nm collate sortorder */
110900 {
110901 Expr *p = 0;
110902 if( yymsp[-1].minor.yy0.n>0 ){
110903 p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
110904 sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
110905 }
110906 yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
110907 sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
110908 sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
110909 if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
110910 }
@@ -141105,10 +141477,11 @@
141105 extern int Sqlitemultiplex_Init(Tcl_Interp*);
141106 extern int SqliteSuperlock_Init(Tcl_Interp*);
141107 extern int SqlitetestSyscall_Init(Tcl_Interp*);
141108 extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
141109 extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
 
141110
141111 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141112 extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
141113 #endif
141114
@@ -141148,10 +141521,11 @@
141148 Sqlitemultiplex_Init(interp);
141149 SqliteSuperlock_Init(interp);
141150 SqlitetestSyscall_Init(interp);
141151 Sqlitetestfuzzer_Init(interp);
141152 Sqlitetestwholenumber_Init(interp);
 
141153
141154 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141155 Sqlitetestfts3_Init(interp);
141156 #endif
141157
141158
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.7.16. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -671,13 +671,13 @@
671 **
672 ** See also: [sqlite3_libversion()],
673 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674 ** [sqlite_version()] and [sqlite_source_id()].
675 */
676 #define SQLITE_VERSION "3.7.16"
677 #define SQLITE_VERSION_NUMBER 3007016
678 #define SQLITE_SOURCE_ID "2012-12-08 06:46:05 e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0"
679
680 /*
681 ** CAPI3REF: Run-Time Library Version Numbers
682 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
683 **
@@ -2162,11 +2162,11 @@
2162 ** database connection is opened. By default, URI handling is globally
2163 ** disabled. The default value may be changed by compiling with the
2164 ** [SQLITE_USE_URI] symbol defined.
2165 **
2166 ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
2167 ** <dd> This option takes a single integer argument which is interpreted as
2168 ** a boolean in order to enable or disable the use of covering indices for
2169 ** full table scans in the query optimizer. The default setting is determined
2170 ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
2171 ** if that compile-time option is omitted.
2172 ** The ability to disable the use of covering indices for full table scans
@@ -10573,24 +10573,24 @@
10573 ** and the value of Index.onError indicate the which conflict resolution
10574 ** algorithm to employ whenever an attempt is made to insert a non-unique
10575 ** element.
10576 */
10577 struct Index {
10578 char *zName; /* Name of this index */
10579 int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10580 tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */
10581 Table *pTable; /* The SQL table being indexed */
10582 char *zColAff; /* String defining the affinity of each column */
10583 Index *pNext; /* The next index associated with the same table */
10584 Schema *pSchema; /* Schema containing this index */
10585 u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
10586 char **azColl; /* Array of collation sequence names for index */
10587 int tnum; /* DB Page containing root of this index */
10588 u16 nColumn; /* Number of columns in table used by this index */
10589 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10590 unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
10591 unsigned bUnordered:1; /* Use this index for == or IN queries only */
10592 #ifdef SQLITE_ENABLE_STAT3
10593 int nSample; /* Number of elements in aSample[] */
10594 tRowcnt avgEq; /* Average nEq value for key values not in aSample */
10595 IndexSample *aSample; /* Samples of the left-most key */
10596 #endif
@@ -10767,11 +10767,10 @@
10767 Expr *pRight; /* Right subnode */
10768 union {
10769 ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
10770 Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
10771 } x;
 
10772
10773 /* If the EP_Reduced flag is set in the Expr.flags mask, then no
10774 ** space is allocated for the fields below this point. An attempt to
10775 ** access them will result in a segfault or malfunction.
10776 *********************************************************************/
@@ -10803,11 +10802,11 @@
10802 #define EP_Error 0x0008 /* Expression contains one or more errors */
10803 #define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
10804 #define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
10805 #define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
10806 #define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
10807 #define EP_Collate 0x0100 /* Tree contains a TK_COLLATE opeartor */
10808 #define EP_FixedDest 0x0200 /* Result needed in a specific register */
10809 #define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
10810 #define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
10811 #define EP_Hint 0x1000 /* Not used */
10812 #define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
@@ -10861,22 +10860,31 @@
10860 ** name. An expr/name combination can be used in several ways, such
10861 ** as the list of "expr AS ID" fields following a "SELECT" or in the
10862 ** list of "ID = expr" items in an UPDATE. A list of expressions can
10863 ** also be used as the argument to a function, in which case the a.zName
10864 ** field is not used.
10865 **
10866 ** By default the Expr.zSpan field holds a human-readable description of
10867 ** the expression that is used in the generation of error messages and
10868 ** column labels. In this case, Expr.zSpan is typically the text of a
10869 ** column expression as it exists in a SELECT statement. However, if
10870 ** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name
10871 ** of the result column in the form: DATABASE.TABLE.COLUMN. This later
10872 ** form is used for name resolution with nested FROM clauses.
10873 */
10874 struct ExprList {
10875 int nExpr; /* Number of expressions on the list */
10876 int iECursor; /* VDBE Cursor associated with this ExprList */
10877 struct ExprList_item { /* For each expression in the list */
10878 Expr *pExpr; /* The list of expressions */
10879 char *zName; /* Token associated with this expression */
10880 char *zSpan; /* Original text of the expression */
10881 u8 sortOrder; /* 1 for DESC or 0 for ASC */
10882 unsigned done :1; /* A flag to indicate when processing is finished */
10883 unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
10884 u16 iOrderByCol; /* For ORDER BY, column number in result set */
10885 u16 iAlias; /* Index into Parse.aAlias[] for zName */
10886 } *a; /* Alloc a power of two greater or equal to nExpr */
10887 };
10888
10889 /*
10890 ** An instance of this structure is used by the parser to record both
@@ -11192,10 +11200,11 @@
11200 #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
11201 #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
11202 #define SF_UseSorter 0x0040 /* Sort using a sorter */
11203 #define SF_Values 0x0080 /* Synthesized from VALUES clause */
11204 #define SF_Materialize 0x0100 /* Force materialization of views */
11205 #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
11206
11207
11208 /*
11209 ** The results of a select can be distributed in several ways. The
11210 ** "SRT" prefix means "SELECT Result Type".
@@ -11420,10 +11429,11 @@
11429 #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
11430 #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
11431 #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
11432 #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
11433 #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
11434 #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
11435
11436 /*
11437 * Each trigger present in the database schema is stored as an instance of
11438 * struct Trigger.
11439 *
@@ -11904,11 +11914,11 @@
11914 SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
11915 Token*, int, int);
11916 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
11917 SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
11918 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
11919 Expr*,ExprList*,u16,Expr*,Expr*);
11920 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
11921 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
11922 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
11923 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
11924 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
@@ -12112,12 +12122,13 @@
12122 SQLITE_PRIVATE const char *sqlite3ErrStr(int);
12123 SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
12124 SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
12125 SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
12126 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
12127 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
12128 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
12129 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
12130 SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
12131 SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
12132 SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
12133 SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
12134 SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
@@ -12160,10 +12171,11 @@
12171 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
12172 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
12173 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
12174 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
12175 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
12176 SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
12177 SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
12178 SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
12179 SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
12180 SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
12181 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -12298,12 +12310,14 @@
12310 #define sqlite3FkOldmask(a,b) 0
12311 #define sqlite3FkRequired(a,b,c,d) 0
12312 #endif
12313 #ifndef SQLITE_OMIT_FOREIGN_KEY
12314 SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*);
12315 SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**);
12316 #else
12317 #define sqlite3FkDelete(a,b)
12318 #define sqlite3FkLocateIndex(a,b,c,d,e)
12319 #endif
12320
12321
12322 /*
12323 ** Available fault injectors. Should be numbered beginning with 0.
@@ -23307,15 +23321,11 @@
23321 { "pwrite64", (sqlite3_syscall_ptr)0, 0 },
23322 #endif
23323 #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
23324 aSyscall[13].pCurrent)
23325
 
23326 { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
 
 
 
23327 #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
23328
23329 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
23330 { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
23331 #else
@@ -23336,13 +23346,10 @@
23346 #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
23347
23348 { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
23349 #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
23350
 
 
 
23351 }; /* End of the overrideable system calls */
23352
23353 /*
23354 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
23355 ** "unix" VFSes. Return SQLITE_OK opon successfully updating the
@@ -23443,31 +23450,29 @@
23450 ** process that is able to write to the database will also be able to
23451 ** recover the hot journals.
23452 */
23453 static int robust_open(const char *z, int f, mode_t m){
23454 int fd;
23455 mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
 
 
 
 
 
 
 
23456 do{
23457 #if defined(O_CLOEXEC)
23458 fd = osOpen(z,f|O_CLOEXEC,m2);
23459 #else
23460 fd = osOpen(z,f,m2);
23461 #endif
23462 }while( fd<0 && errno==EINTR );
23463 if( fd>=0 ){
23464 if( m!=0 ){
23465 struct stat statbuf;
23466 if( osFstat(fd, &statbuf)==0 && (statbuf.st_mode&0777)!=m ){
23467 osFchmod(fd, m);
23468 }
23469 }
23470 #if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
23471 osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
23472 #endif
23473 }
23474 return fd;
23475 }
23476
23477 /*
23478 ** Helper functions to obtain and relinquish the global mutex. The
@@ -29889,11 +29894,11 @@
29894 };
29895 unsigned int i; /* Loop counter */
29896
29897 /* Double-check that the aSyscall[] array has been constructed
29898 ** correctly. See ticket [bb3a86e890c8e96ab] */
29899 assert( ArraySize(aSyscall)==21 );
29900
29901 /* Register all VFSes defined in the aVfs[] array */
29902 for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
29903 sqlite3_vfs_register(&aVfs[i], i==0);
29904 }
@@ -56355,11 +56360,11 @@
56360 sqlite3BtreeLeave(p);
56361 return 0;
56362 }
56363 i = PENDING_BYTE_PAGE(pBt);
56364 if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
56365 sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
56366 sCheck.errMsg.useMalloc = 2;
56367
56368 /* Check the integrity of the freelist
56369 */
56370 checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
@@ -56890,11 +56895,16 @@
56895 /*
56896 ** Parameter zSrcData points to a buffer containing the data for
56897 ** page iSrcPg from the source database. Copy this data into the
56898 ** destination database.
56899 */
56900 static int backupOnePage(
56901 sqlite3_backup *p, /* Backup handle */
56902 Pgno iSrcPg, /* Source database page to backup */
56903 const u8 *zSrcData, /* Source database page data */
56904 int bUpdate /* True for an update, false otherwise */
56905 ){
56906 Pager * const pDestPager = sqlite3BtreePager(p->pDest);
56907 const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
56908 int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
56909 const int nCopy = MIN(nSrcPgsz, nDestPgsz);
56910 const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
@@ -56963,10 +56973,13 @@
56973 ** cached parse of the page). MemPage.isInit is marked
56974 ** "MUST BE FIRST" for this purpose.
56975 */
56976 memcpy(zOut, zIn, nCopy);
56977 ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
56978 if( iOff==0 && bUpdate==0 ){
56979 sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc));
56980 }
56981 }
56982 sqlite3PagerUnref(pDestPg);
56983 }
56984
56985 return rc;
@@ -57069,11 +57082,11 @@
57082 const Pgno iSrcPg = p->iNext; /* Source page number */
57083 if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
57084 DbPage *pSrcPg; /* Source page object */
57085 rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
57086 if( rc==SQLITE_OK ){
57087 rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
57088 sqlite3PagerUnref(pSrcPg);
57089 }
57090 }
57091 p->iNext++;
57092 }
@@ -57317,11 +57330,11 @@
57330 ** the new data into the backup.
57331 */
57332 int rc;
57333 assert( p->pDestDb );
57334 sqlite3_mutex_enter(p->pDestDb->mutex);
57335 rc = backupOnePage(p, iPage, aData, 1);
57336 sqlite3_mutex_leave(p->pDestDb->mutex);
57337 assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
57338 if( rc!=SQLITE_OK ){
57339 p->rc = rc;
57340 }
@@ -59434,26 +59447,22 @@
59447 assert( pKeyInfo->aSortOrder!=0 );
59448 sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
59449 i = sqlite3Strlen30(zTemp);
59450 for(j=0; j<pKeyInfo->nField; j++){
59451 CollSeq *pColl = pKeyInfo->aColl[j];
59452 const char *zColl = pColl ? pColl->zName : "nil";
59453 int n = sqlite3Strlen30(zColl);
59454 if( i+n>nTemp-6 ){
59455 memcpy(&zTemp[i],",...",4);
59456 break;
59457 }
59458 zTemp[i++] = ',';
59459 if( pKeyInfo->aSortOrder[j] ){
59460 zTemp[i++] = '-';
59461 }
59462 memcpy(&zTemp[i], zColl, n+1);
59463 i += n;
 
 
 
 
59464 }
59465 zTemp[i++] = ')';
59466 zTemp[i] = 0;
59467 assert( i<nTemp );
59468 break;
@@ -63839,11 +63848,13 @@
63848 #ifdef SQLITE_DEBUG
63849 /*
63850 ** Print the value of a register for tracing purposes:
63851 */
63852 static void memTracePrint(FILE *out, Mem *p){
63853 if( p->flags & MEM_Invalid ){
63854 fprintf(out, " undefined");
63855 }else if( p->flags & MEM_Null ){
63856 fprintf(out, " NULL");
63857 }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
63858 fprintf(out, " si:%lld", p->u.i);
63859 }else if( p->flags & MEM_Int ){
63860 fprintf(out, " i:%lld", p->u.i);
@@ -64112,10 +64123,11 @@
64123 } af;
64124 struct OP_Concat_stack_vars {
64125 i64 nByte;
64126 } ag;
64127 struct OP_Remainder_stack_vars {
64128 char bIntint; /* Started out as two integer operands */
64129 int flags; /* Combined MEM_* flags from both inputs */
64130 i64 iA; /* Integer value of left operand */
64131 i64 iB; /* Integer value of right operand */
64132 double rA; /* Real value of left operand */
64133 double rB; /* Real value of right operand */
@@ -65021,10 +65033,13 @@
65033 pOut = &aMem[pOp->p2];
65034 assert( pOut!=pIn1 );
65035 while( 1 ){
65036 sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
65037 Deephemeralize(pOut);
65038 #ifdef SQLITE_DEBUG
65039 pOut->pScopyFrom = 0;
65040 #endif
65041 REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
65042 if( (u.ae.n--)==0 ) break;
65043 pOut++;
65044 pIn1++;
65045 }
@@ -65214,10 +65229,11 @@
65229 case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
65230 case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
65231 case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
65232 case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
65233 #if 0 /* local variables moved into u.ah */
65234 char bIntint; /* Started out as two integer operands */
65235 int flags; /* Combined MEM_* flags from both inputs */
65236 i64 iA; /* Integer value of left operand */
65237 i64 iB; /* Integer value of right operand */
65238 double rA; /* Real value of left operand */
65239 double rB; /* Real value of right operand */
@@ -65231,10 +65247,11 @@
65247 u.ah.flags = pIn1->flags | pIn2->flags;
65248 if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
65249 if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
65250 u.ah.iA = pIn1->u.i;
65251 u.ah.iB = pIn2->u.i;
65252 u.ah.bIntint = 1;
65253 switch( pOp->opcode ){
65254 case OP_Add: if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65255 case OP_Subtract: if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65256 case OP_Multiply: if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65257 case OP_Divide: {
@@ -65251,10 +65268,11 @@
65268 }
65269 }
65270 pOut->u.i = u.ah.iB;
65271 MemSetTypeFlag(pOut, MEM_Int);
65272 }else{
65273 u.ah.bIntint = 0;
65274 fp_math:
65275 u.ah.rA = sqlite3VdbeRealValue(pIn1);
65276 u.ah.rB = sqlite3VdbeRealValue(pIn2);
65277 switch( pOp->opcode ){
65278 case OP_Add: u.ah.rB += u.ah.rA; break;
@@ -65282,11 +65300,11 @@
65300 if( sqlite3IsNaN(u.ah.rB) ){
65301 goto arithmetic_result_is_null;
65302 }
65303 pOut->r = u.ah.rB;
65304 MemSetTypeFlag(pOut, MEM_Real);
65305 if( (u.ah.flags & MEM_Real)==0 && !u.ah.bIntint ){
65306 sqlite3VdbeIntegerAffinity(pOut);
65307 }
65308 #endif
65309 }
65310 break;
@@ -65843,26 +65861,31 @@
65861 /* Opcode: Permutation * * * P4 *
65862 **
65863 ** Set the permutation used by the OP_Compare operator to be the array
65864 ** of integers in P4.
65865 **
65866 ** The permutation is only valid until the next OP_Compare that has
65867 ** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
65868 ** occur immediately prior to the OP_Compare.
65869 */
65870 case OP_Permutation: {
65871 assert( pOp->p4type==P4_INTARRAY );
65872 assert( pOp->p4.ai );
65873 aPermute = pOp->p4.ai;
65874 break;
65875 }
65876
65877 /* Opcode: Compare P1 P2 P3 P4 P5
65878 **
65879 ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
65880 ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
65881 ** the comparison for use by the next OP_Jump instruct.
65882 **
65883 ** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is
65884 ** determined by the most recent OP_Permutation operator. If the
65885 ** OPFLAG_PERMUTE bit is clear, then register are compared in sequential
65886 ** order.
65887 **
65888 ** P4 is a KeyInfo structure that defines collating sequences and sort
65889 ** orders for the comparison. The permutation applies to registers
65890 ** only. The KeyInfo elements are used sequentially.
65891 **
@@ -65880,10 +65903,11 @@
65903 int idx;
65904 CollSeq *pColl; /* Collating sequence to use on this term */
65905 int bRev; /* True for DESCENDING sort order */
65906 #endif /* local variables moved into u.al */
65907
65908 if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
65909 u.al.n = pOp->p3;
65910 u.al.pKeyInfo = pOp->p4.pKeyInfo;
65911 assert( u.al.n>0 );
65912 assert( u.al.pKeyInfo!=0 );
65913 u.al.p1 = pOp->p1;
@@ -66025,12 +66049,10 @@
66049
66050 /* Opcode: Once P1 P2 * * *
66051 **
66052 ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
66053 ** set the flag and fall through to the next instruction.
 
 
66054 */
66055 case OP_Once: { /* jump */
66056 assert( pOp->p1<p->nOnceFlag );
66057 if( p->aOnceFlag[pOp->p1] ){
66058 pc = pOp->p2-1;
@@ -71902,10 +71924,18 @@
71924 p->pReal = pReal;
71925 if( p->iSize>0 ){
71926 assert(p->iSize<=p->nBuf);
71927 rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
71928 }
71929 if( rc!=SQLITE_OK ){
71930 /* If an error occurred while writing to the file, close it before
71931 ** returning. This way, SQLite uses the in-memory journal data to
71932 ** roll back changes made to the internal page-cache before this
71933 ** function was called. */
71934 sqlite3OsClose(pReal);
71935 p->pReal = 0;
71936 }
71937 }
71938 }
71939 return rc;
71940 }
71941
@@ -72565,10 +72595,19 @@
72595 ** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
72596 **
72597 ** The result of random()%5 in the GROUP BY clause is probably different
72598 ** from the result in the result-set. We might fix this someday. Or
72599 ** then again, we might not...
72600 **
72601 ** If the reference is followed by a COLLATE operator, then make sure
72602 ** the COLLATE operator is preserved. For example:
72603 **
72604 ** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
72605 **
72606 ** Should be transformed into:
72607 **
72608 ** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
72609 **
72610 ** The nSubquery parameter specifies how many levels of subquery the
72611 ** alias is removed from the original expression. The usually value is
72612 ** zero but it might be more if the alias is contained within a subquery
72613 ** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
@@ -72589,45 +72628,40 @@
72628 assert( iCol>=0 && iCol<pEList->nExpr );
72629 pOrig = pEList->a[iCol].pExpr;
72630 assert( pOrig!=0 );
72631 assert( pOrig->flags & EP_Resolved );
72632 db = pParse->db;
72633 pDup = sqlite3ExprDup(db, pOrig, 0);
72634 if( pDup==0 ) return;
72635 if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
 
72636 incrAggFunctionDepth(pDup, nSubquery);
72637 pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
72638 if( pDup==0 ) return;
72639 if( pEList->a[iCol].iAlias==0 ){
72640 pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
72641 }
72642 pDup->iTable = pEList->a[iCol].iAlias;
72643 }
72644 if( pExpr->op==TK_COLLATE ){
72645 pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72646 }
72647
72648 /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
72649 ** prevents ExprDelete() from deleting the Expr structure itself,
72650 ** allowing it to be repopulated by the memcpy() on the following line.
72651 ** The pExpr->u.zToken might point into memory that will be freed by the
72652 ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
72653 ** make a copy of the token before doing the sqlite3DbFree().
72654 */
72655 ExprSetProperty(pExpr, EP_Static);
72656 sqlite3ExprDelete(db, pExpr);
72657 memcpy(pExpr, pDup, sizeof(*pExpr));
72658 if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
72659 assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
72660 pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
72661 pExpr->flags2 |= EP2_MallocedToken;
72662 }
72663 sqlite3DbFree(db, pDup);
72664 }
72665
72666
72667 /*
@@ -72644,10 +72678,39 @@
72678 }
72679 }
72680 return 0;
72681 }
72682
72683 /*
72684 ** Subqueries stores the original database, table and column names for their
72685 ** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN".
72686 ** Check to see if the zSpan given to this routine matches the zDb, zTab,
72687 ** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will
72688 ** match anything.
72689 */
72690 SQLITE_PRIVATE int sqlite3MatchSpanName(
72691 const char *zSpan,
72692 const char *zCol,
72693 const char *zTab,
72694 const char *zDb
72695 ){
72696 int n;
72697 for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72698 if( zDb && sqlite3StrNICmp(zSpan, zDb, n)!=0 ){
72699 return 0;
72700 }
72701 zSpan += n+1;
72702 for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72703 if( zTab && sqlite3StrNICmp(zSpan, zTab, n)!=0 ){
72704 return 0;
72705 }
72706 zSpan += n+1;
72707 if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){
72708 return 0;
72709 }
72710 return 1;
72711 }
72712
72713 /*
72714 ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
72715 ** that name in the set of source tables in pSrcList and make the pExpr
72716 ** expression node refer back to that source column. The following changes
@@ -72699,44 +72762,63 @@
72762
72763 /* Initialize the node to no-match */
72764 pExpr->iTable = -1;
72765 pExpr->pTab = 0;
72766 ExprSetIrreducible(pExpr);
72767
72768 /* Translate the schema name in zDb into a pointer to the corresponding
72769 ** schema. If not found, pSchema will remain NULL and nothing will match
72770 ** resulting in an appropriate error message toward the end of this routine
72771 */
72772 if( zDb ){
72773 for(i=0; i<db->nDb; i++){
72774 assert( db->aDb[i].zName );
72775 if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
72776 pSchema = db->aDb[i].pSchema;
72777 break;
72778 }
72779 }
72780 }
72781
72782 /* Start at the inner-most context and move outward until a match is found */
72783 while( pNC && cnt==0 ){
72784 ExprList *pEList;
72785 SrcList *pSrcList = pNC->pSrcList;
72786
72787 if( pSrcList ){
72788 for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
72789 Table *pTab;
 
72790 Column *pCol;
72791
72792 pTab = pItem->pTab;
72793 assert( pTab!=0 && pTab->zName!=0 );
 
72794 assert( pTab->nCol>0 );
72795 if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
72796 ExprList *pEList = pItem->pSelect->pEList;
72797 int hit = 0;
72798 for(j=0; j<pEList->nExpr; j++){
72799 if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
72800 cnt++;
72801 cntTab = 2;
72802 pMatch = pItem;
72803 pExpr->iColumn = j;
72804 hit = 1;
72805 }
72806 }
72807 if( hit || zTab==0 ) continue;
72808 }
72809 if( zDb && pTab->pSchema!=pSchema ){
72810 continue;
72811 }
72812 if( zTab ){
72813 const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
72814 assert( zTabName!=0 );
72815 if( sqlite3StrICmp(zTabName, zTab)!=0 ){
72816 continue;
 
 
 
 
 
 
 
72817 }
72818 }
72819 if( 0==(cntTab++) ){
 
 
 
72820 pMatch = pItem;
72821 }
72822 for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
72823 if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
72824 /* If there has been exactly one prior match and this match
@@ -72746,21 +72828,23 @@
72828 if( cnt==1 ){
72829 if( pItem->jointype & JT_NATURAL ) continue;
72830 if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
72831 }
72832 cnt++;
 
 
72833 pMatch = pItem;
 
72834 /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
72835 pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
72836 break;
72837 }
72838 }
72839 }
72840 if( pMatch ){
72841 pExpr->iTable = pMatch->iCursor;
72842 pExpr->pTab = pMatch->pTab;
72843 pSchema = pExpr->pTab->pSchema;
72844 }
72845 } /* if( pSrcList ) */
72846
72847 #ifndef SQLITE_OMIT_TRIGGER
72848 /* If we have not already resolved the name, then maybe
72849 ** it is a new.* or old.* trigger argument reference
72850 */
@@ -73055,42 +73139,43 @@
73139 int wrong_num_args = 0; /* True if wrong number of arguments */
73140 int is_agg = 0; /* True if is an aggregate function */
73141 int auth; /* Authorization to use the function */
73142 int nId; /* Number of characters in function name */
73143 const char *zId; /* The function name. */
 
73144 u8 enc = ENC(pParse->db); /* The database encoding */
73145
73146 testcase( pExpr->op==TK_CONST_FUNC );
73147 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
73148 zId = pExpr->u.zToken;
73149 nId = sqlite3Strlen30(zId);
73150 if( pParse->db->init.busy==0 ){
73151 FuncDef *pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
73152 if( pDef==0 ){
73153 pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
73154 if( pDef==0 ){
73155 no_such_func = 1;
73156 }else{
73157 wrong_num_args = 1;
73158 }
73159 }else{
73160 is_agg = pDef->xFunc==0;
73161 }
73162 #ifndef SQLITE_OMIT_AUTHORIZATION
73163 if( pDef ){
73164 auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
73165 if( auth!=SQLITE_OK ){
73166 if( auth==SQLITE_DENY ){
73167 sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
73168 pDef->zName);
73169 pNC->nErr++;
73170 }
73171 pExpr->op = TK_NULL;
73172 return WRC_Prune;
73173 }
73174 }
73175 #endif
73176 }
73177 if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
73178 sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
73179 pNC->nErr++;
73180 is_agg = 0;
73181 }else if( no_such_func ){
@@ -73310,11 +73395,11 @@
73395 assert( pEList!=0 );
73396 for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
73397 int iCol = -1;
73398 Expr *pE, *pDup;
73399 if( pItem->done ) continue;
73400 pE = sqlite3ExprSkipCollate(pItem->pExpr);
73401 if( sqlite3ExprIsInteger(pE, &iCol) ){
73402 if( iCol<=0 || iCol>pEList->nExpr ){
73403 resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
73404 return 1;
73405 }
@@ -73328,18 +73413,24 @@
73413 }
73414 sqlite3ExprDelete(db, pDup);
73415 }
73416 }
73417 if( iCol>0 ){
73418 /* Convert the ORDER BY term into an integer column number iCol,
73419 ** taking care to preserve the COLLATE clause if it exists */
73420 Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
73421 if( pNew==0 ) return 1;
73422 pNew->flags |= EP_IntValue;
73423 pNew->u.iValue = iCol;
73424 if( pItem->pExpr==pE ){
73425 pItem->pExpr = pNew;
73426 }else{
73427 assert( pItem->pExpr->op==TK_COLLATE );
73428 assert( pItem->pExpr->pLeft==pE );
73429 pItem->pExpr->pLeft = pNew;
73430 }
73431 sqlite3ExprDelete(db, pE);
 
 
 
 
 
73432 pItem->iOrderByCol = (u16)iCol;
73433 pItem->done = 1;
73434 }else{
73435 moreToDo = 1;
73436 }
@@ -73440,15 +73531,15 @@
73531 ** sqlite3ResolveOrderGroupBy() will convert the expression to a
73532 ** copy of the iCol-th result-set expression. */
73533 pItem->iOrderByCol = (u16)iCol;
73534 continue;
73535 }
73536 if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
73537 /* The ORDER BY term is an integer constant. Again, set the column
73538 ** number so that sqlite3ResolveOrderGroupBy() will convert the
73539 ** order-by term to a copy of the result-set expression */
73540 if( iCol<1 || iCol>0xffff ){
73541 resolveOutOfRangeError(pParse, zType, i+1, nResult);
73542 return 1;
73543 }
73544 pItem->iOrderByCol = (u16)iCol;
73545 continue;
@@ -73521,27 +73612,10 @@
73612 if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
73613 sqlite3ResolveExprNames(&sNC, p->pOffset) ){
73614 return WRC_Abort;
73615 }
73616
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73617 /* Recursively resolve names in all subqueries
73618 */
73619 for(i=0; i<p->pSrc->nSrc; i++){
73620 struct SrcList_item *pItem = &p->pSrc->a[i];
73621 if( pItem->pSelect ){
@@ -73564,10 +73638,27 @@
73638 for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
73639 assert( pItem->isCorrelated==0 && nRef<=0 );
73640 pItem->isCorrelated = (nRef!=0);
73641 }
73642 }
73643
73644 /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
73645 ** resolve the result-set expression list.
73646 */
73647 sNC.ncFlags = NC_AllowAgg;
73648 sNC.pSrcList = p->pSrc;
73649 sNC.pNext = pOuterNC;
73650
73651 /* Resolve names in the result set. */
73652 pEList = p->pEList;
73653 assert( pEList!=0 );
73654 for(i=0; i<pEList->nExpr; i++){
73655 Expr *pX = pEList->a[i].pExpr;
73656 if( sqlite3ResolveExprNames(&sNC, pX) ){
73657 return WRC_Abort;
73658 }
73659 }
73660
73661 /* If there are no aggregate functions in the result-set, and no GROUP BY
73662 ** expression, do not allow aggregates in any of the other expressions.
73663 */
73664 assert( (p->selFlags & SF_Aggregate)==0 );
@@ -73798,11 +73889,13 @@
73889 ** SELECT * FROM t1 WHERE a;
73890 ** SELECT a AS b FROM t1 WHERE b;
73891 ** SELECT * FROM t1 WHERE (select a from t1);
73892 */
73893 SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
73894 int op;
73895 pExpr = sqlite3ExprSkipCollate(pExpr);
73896 op = pExpr->op;
73897 if( op==TK_SELECT ){
73898 assert( pExpr->flags&EP_xIsSelect );
73899 return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
73900 }
73901 #ifndef SQLITE_OMIT_CAST
@@ -73823,70 +73916,98 @@
73916 }
73917 return pExpr->affinity;
73918 }
73919
73920 /*
73921 ** Set the collating sequence for expression pExpr to be the collating
73922 ** sequence named by pToken. Return a pointer to a new Expr node that
73923 ** implements the COLLATE operator.
73924 **
73925 ** If a memory allocation error occurs, that fact is recorded in pParse->db
73926 ** and the pExpr parameter is returned unchanged.
73927 */
73928 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
73929 if( pCollName->n>0 ){
73930 Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
73931 if( pNew ){
73932 pNew->pLeft = pExpr;
73933 pNew->flags |= EP_Collate;
73934 pExpr = pNew;
73935 }
73936 }
73937 return pExpr;
73938 }
73939 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
73940 Token s;
73941 assert( zC!=0 );
73942 s.z = zC;
73943 s.n = sqlite3Strlen30(s.z);
73944 return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
73945 }
73946
73947 /*
73948 ** Skip over any TK_COLLATE and/or TK_AS operators at the root of
73949 ** an expression.
73950 */
73951 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
73952 while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
73953 pExpr = pExpr->pLeft;
73954 }
73955 return pExpr;
73956 }
73957
73958 /*
73959 ** Return the collation sequence for the expression pExpr. If
73960 ** there is no defined collating sequence, return NULL.
73961 **
73962 ** The collating sequence might be determined by a COLLATE operator
73963 ** or by the presence of a column with a defined collating sequence.
73964 ** COLLATE operators take first precedence. Left operands take
73965 ** precedence over right operands.
73966 */
73967 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
73968 sqlite3 *db = pParse->db;
73969 CollSeq *pColl = 0;
73970 Expr *p = pExpr;
73971 while( p ){
73972 int op = p->op;
73973 if( op==TK_CAST || op==TK_UPLUS ){
73974 p = p->pLeft;
73975 continue;
73976 }
73977 assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
73978 if( op==TK_COLLATE ){
73979 if( db->init.busy ){
73980 /* Do not report errors when parsing while the schema */
73981 pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0);
73982 }else{
73983 pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
73984 }
73985 break;
73986 }
73987 if( p->pTab!=0
73988 && (op==TK_AGG_COLUMN || op==TK_COLUMN
73989 || op==TK_REGISTER || op==TK_TRIGGER)
73990 ){
73991 /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
73992 ** a TK_COLUMN but was previously evaluated and cached in a register */
73993 int j = p->iColumn;
73994 if( j>=0 ){
73995 const char *zColl = p->pTab->aCol[j].zColl;
73996 pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
73997 }
73998 break;
73999 }
74000 if( p->flags & EP_Collate ){
74001 if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
74002 p = p->pLeft;
74003 }else{
74004 p = p->pRight;
74005 }
74006 }else{
74007 break;
74008 }
74009 }
74010 if( sqlite3CheckCollSeq(pParse, pColl) ){
74011 pColl = 0;
74012 }
74013 return pColl;
@@ -73986,16 +74107,14 @@
74107 Expr *pLeft,
74108 Expr *pRight
74109 ){
74110 CollSeq *pColl;
74111 assert( pLeft );
74112 if( pLeft->flags & EP_Collate ){
74113 pColl = sqlite3ExprCollSeq(pParse, pLeft);
74114 }else if( pRight && (pRight->flags & EP_Collate)!=0 ){
74115 pColl = sqlite3ExprCollSeq(pParse, pRight);
 
 
74116 }else{
74117 pColl = sqlite3ExprCollSeq(pParse, pLeft);
74118 if( !pColl ){
74119 pColl = sqlite3ExprCollSeq(pParse, pRight);
74120 }
@@ -74221,21 +74340,15 @@
74340 sqlite3ExprDelete(db, pLeft);
74341 sqlite3ExprDelete(db, pRight);
74342 }else{
74343 if( pRight ){
74344 pRoot->pRight = pRight;
74345 pRoot->flags |= EP_Collate & pRight->flags;
 
 
 
74346 }
74347 if( pLeft ){
74348 pRoot->pLeft = pLeft;
74349 pRoot->flags |= EP_Collate & pLeft->flags;
 
 
 
74350 }
74351 exprSetHeight(pRoot);
74352 }
74353 }
74354
@@ -74489,11 +74602,11 @@
74602 }else{
74603 assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
74604 assert( !ExprHasProperty(p, EP_FromJoin) );
74605 assert( (p->flags2 & EP2_MallocedToken)==0 );
74606 assert( (p->flags2 & EP2_Irreducible)==0 );
74607 if( p->pLeft || p->pRight || p->x.pList ){
74608 nSize = EXPR_REDUCEDSIZE | EP_Reduced;
74609 }else{
74610 nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
74611 }
74612 }
@@ -76513,10 +76626,11 @@
76626 sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
76627 sqlite3ReleaseTempReg(pParse, r3);
76628 sqlite3ReleaseTempReg(pParse, r4);
76629 break;
76630 }
76631 case TK_COLLATE:
76632 case TK_UPLUS: {
76633 inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
76634 break;
76635 }
76636
@@ -76881,10 +76995,16 @@
76995 case TK_UPLUS: zUniOp = "UPLUS"; break;
76996 case TK_BITNOT: zUniOp = "BITNOT"; break;
76997 case TK_NOT: zUniOp = "NOT"; break;
76998 case TK_ISNULL: zUniOp = "ISNULL"; break;
76999 case TK_NOTNULL: zUniOp = "NOTNULL"; break;
77000
77001 case TK_COLLATE: {
77002 sqlite3ExplainExpr(pOut, pExpr->pLeft);
77003 sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
77004 break;
77005 }
77006
77007 case TK_AGG_FUNCTION:
77008 case TK_CONST_FUNC:
77009 case TK_FUNCTION: {
77010 ExprList *pFarg; /* List of function arguments */
@@ -77019,10 +77139,16 @@
77139 for(i=0; i<pList->nExpr; i++){
77140 sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
77141 sqlite3ExplainPush(pOut);
77142 sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
77143 sqlite3ExplainPop(pOut);
77144 if( pList->a[i].zName ){
77145 sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
77146 }
77147 if( pList->a[i].bSpanIsTab ){
77148 sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
77149 }
77150 if( i<pList->nExpr-1 ){
77151 sqlite3ExplainNL(pOut);
77152 }
77153 }
77154 sqlite3ExplainPop(pOut);
@@ -77100,10 +77226,13 @@
77226 switch( pExpr->op ){
77227 case TK_IN:
77228 case TK_REGISTER: {
77229 return WRC_Prune;
77230 }
77231 case TK_COLLATE: {
77232 return WRC_Continue;
77233 }
77234 case TK_FUNCTION:
77235 case TK_AGG_FUNCTION:
77236 case TK_CONST_FUNC: {
77237 /* The arguments to a function have a fixed destination.
77238 ** Mark them this way to avoid generated unneeded OP_SCopy
@@ -77121,13 +77250,15 @@
77250 break;
77251 }
77252 }
77253 if( isAppropriateForFactoring(pExpr) ){
77254 int r1 = ++pParse->nMem;
77255 int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
77256 /* If r2!=r1, it means that register r1 is never used. That is harmless
77257 ** but suboptimal, so we want to know about the situation to fix it.
77258 ** Hence the following assert: */
77259 assert( r2==r1 );
77260 pExpr->op2 = pExpr->op;
77261 pExpr->op = TK_REGISTER;
77262 pExpr->iTable = r2;
77263 return WRC_Prune;
77264 }
@@ -77540,11 +77671,19 @@
77671 assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
77672 if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
77673 return 2;
77674 }
77675 if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
77676 if( pA->op!=pB->op ){
77677 if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
77678 return 1;
77679 }
77680 if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
77681 return 1;
77682 }
77683 return 2;
77684 }
77685 if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
77686 if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
77687 if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
77688 if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
77689 if( ExprHasProperty(pA, EP_IntValue) ){
@@ -77552,15 +77691,13 @@
77691 return 2;
77692 }
77693 }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
77694 if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
77695 if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
77696 return pA->op==TK_COLLATE ? 1 : 2;
77697 }
77698 }
 
 
77699 return 0;
77700 }
77701
77702 /*
77703 ** Compare two ExprList objects. Return 0 if they are identical and
@@ -83371,14 +83508,12 @@
83508 ** specified collation sequence names.
83509 */
83510 for(i=0; i<pList->nExpr; i++){
83511 Expr *pExpr = pList->a[i].pExpr;
83512 if( pExpr ){
83513 CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
83514 if( pColl ){
 
 
83515 nExtra += (1 + sqlite3Strlen30(pColl->zName));
83516 }
83517 }
83518 }
83519
@@ -83437,10 +83572,11 @@
83572 */
83573 for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
83574 const char *zColName = pListItem->zName;
83575 Column *pTabCol;
83576 int requestedSortOrder;
83577 CollSeq *pColl; /* Collating sequence */
83578 char *zColl; /* Collation sequence name */
83579
83580 for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
83581 if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
83582 }
@@ -83449,18 +83585,15 @@
83585 pTab->zName, zColName);
83586 pParse->checkSchema = 1;
83587 goto exit_create_index;
83588 }
83589 pIndex->aiColumn[i] = j;
83590 if( pListItem->pExpr
83591 && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
83592 ){
 
 
 
83593 int nColl;
83594 zColl = pColl->zName;
83595 nColl = sqlite3Strlen30(zColl) + 1;
83596 assert( nExtra>=nColl );
83597 memcpy(zExtra, zColl, nColl);
83598 zColl = zExtra;
83599 zExtra += nColl;
@@ -87489,11 +87622,11 @@
87622
87623 /*
87624 ** A foreign key constraint requires that the key columns in the parent
87625 ** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
87626 ** Given that pParent is the parent table for foreign key constraint pFKey,
87627 ** search the schema for a unique index on the parent key columns.
87628 **
87629 ** If successful, zero is returned. If the parent key is an INTEGER PRIMARY
87630 ** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx
87631 ** is set to point to the unique index.
87632 **
@@ -87525,11 +87658,11 @@
87658 **
87659 ** then non-zero is returned, and a "foreign key mismatch" error loaded
87660 ** into pParse. If an OOM error occurs, non-zero is returned and the
87661 ** pParse->db->mallocFailed flag is set.
87662 */
87663 SQLITE_PRIVATE int sqlite3FkLocateIndex(
87664 Parse *pParse, /* Parse context to store any error in */
87665 Table *pParent, /* Parent table of FK constraint pFKey */
87666 FKey *pFKey, /* Foreign key to find index for */
87667 Index **ppIdx, /* OUT: Unique index on parent table */
87668 int **paiCol /* OUT: Map of index columns in pFKey */
@@ -87622,11 +87755,13 @@
87755 }
87756 }
87757
87758 if( !pIdx ){
87759 if( !pParse->disableTriggers ){
87760 sqlite3ErrorMsg(pParse,
87761 "foreign key mismatch - \"%w\" referencing \"%w\"",
87762 pFKey->pFrom->zName, pFKey->zTo);
87763 }
87764 sqlite3DbFree(pParse->db, aiCol);
87765 return 1;
87766 }
87767
@@ -87858,16 +87993,19 @@
87993 if( pLeft ){
87994 /* Set the collation sequence and affinity of the LHS of each TK_EQ
87995 ** expression to the parent key column defaults. */
87996 if( pIdx ){
87997 Column *pCol;
87998 const char *zColl;
87999 iCol = pIdx->aiColumn[i];
88000 pCol = &pTab->aCol[iCol];
88001 if( pTab->iPKey==iCol ) iCol = -1;
88002 pLeft->iTable = regData+iCol+1;
88003 pLeft->affinity = pCol->affinity;
88004 zColl = pCol->zColl;
88005 if( zColl==0 ) zColl = db->pDfltColl->zName;
88006 pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
88007 }else{
88008 pLeft->iTable = regData;
88009 pLeft->affinity = SQLITE_AFF_INTEGER;
88010 }
88011 }
@@ -88080,11 +88218,11 @@
88218 if( pParse->disableTriggers ){
88219 pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
88220 }else{
88221 pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
88222 }
88223 if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
88224 assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
88225 if( !isIgnoreErrors || db->mallocFailed ) return;
88226 if( pTo==0 ){
88227 /* If isIgnoreErrors is true, then a table is being dropped. In this
88228 ** case SQLite runs a "DELETE FROM xxx" on the table being dropped
@@ -88160,11 +88298,11 @@
88298 /* Inserting a single row into a parent table cannot cause an immediate
88299 ** foreign key violation. So do nothing in this case. */
88300 continue;
88301 }
88302
88303 if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
88304 if( !isIgnoreErrors || db->mallocFailed ) return;
88305 continue;
88306 }
88307 assert( aiCol || pFKey->nCol==1 );
88308
@@ -88215,11 +88353,11 @@
88353 for(p=pTab->pFKey; p; p=p->pNextFrom){
88354 for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
88355 }
88356 for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
88357 Index *pIdx = 0;
88358 sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
88359 if( pIdx ){
88360 for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
88361 }
88362 }
88363 }
@@ -88341,11 +88479,11 @@
88479 ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */
88480 Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */
88481 int i; /* Iterator variable */
88482 Expr *pWhen = 0; /* WHEN clause for the trigger */
88483
88484 if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
88485 assert( aiCol || pFKey->nCol==1 );
88486
88487 for(i=0; i<pFKey->nCol; i++){
88488 Token tOld = { "old", 3 }; /* Literal "old" token */
88489 Token tNew = { "new", 3 }; /* Literal "new" token */
@@ -89843,29 +89981,24 @@
89981 ExprList *pCheck = pTab->pCheck;
89982 pParse->ckBase = regData;
89983 onError = overrideError!=OE_Default ? overrideError : OE_Abort;
89984 for(i=0; i<pCheck->nExpr; i++){
89985 int allOk = sqlite3VdbeMakeLabel(v);
89986 sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
89987 if( onError==OE_Ignore ){
89988 sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
89989 }else{
89990 char *zConsName = pCheck->a[i].zName;
89991 if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
89992 if( zConsName ){
89993 zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
89994 }else{
89995 zConsName = 0;
89996 }
89997 sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
89998 }
89999 sqlite3VdbeResolveLabel(v, allOk);
 
 
 
 
 
90000 }
90001 }
90002 #endif /* !defined(SQLITE_OMIT_CHECK) */
90003
90004 /* If we have an INTEGER PRIMARY KEY, make sure the primary key
@@ -92686,13 +92819,15 @@
92819 if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
92820 Table *pTab;
92821 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
92822 pTab = sqlite3FindTable(db, zRight, zDb);
92823 if( pTab ){
92824 int i, k;
92825 int nHidden = 0;
92826 Column *pCol;
92827 Index *pPk;
92828 for(pPk=pTab->pIndex; pPk && pPk->autoIndex!=2; pPk=pPk->pNext){}
92829 sqlite3VdbeSetNumCols(v, 6);
92830 pParse->nMem = 6;
92831 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
92832 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
92833 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
@@ -92713,12 +92848,18 @@
92848 if( pCol->zDflt ){
92849 sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
92850 }else{
92851 sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
92852 }
92853 if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
92854 k = 0;
92855 }else if( pPk==0 ){
92856 k = 1;
92857 }else{
92858 for(k=1; ALWAYS(k<=pTab->nCol) && pPk->aiColumn[k-1]!=i; k++){}
92859 }
92860 sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
92861 sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
92862 }
92863 }
92864 }else
92865
@@ -92849,10 +92990,124 @@
92990 ++i;
92991 pFK = pFK->pNextFrom;
92992 }
92993 }
92994 }
92995 }else
92996 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
92997
92998 #ifndef SQLITE_OMIT_FOREIGN_KEY
92999 if( sqlite3StrICmp(zLeft, "foreign_key_check")==0 ){
93000 FKey *pFK; /* A foreign key constraint */
93001 Table *pTab; /* Child table contain "REFERENCES" keyword */
93002 Table *pParent; /* Parent table that child points to */
93003 Index *pIdx; /* Index in the parent table */
93004 int i; /* Loop counter: Foreign key number for pTab */
93005 int j; /* Loop counter: Field of the foreign key */
93006 HashElem *k; /* Loop counter: Next table in schema */
93007 int x; /* result variable */
93008 int regResult; /* 3 registers to hold a result row */
93009 int regKey; /* Register to hold key for checking the FK */
93010 int regRow; /* Registers to hold a row from pTab */
93011 int addrTop; /* Top of a loop checking foreign keys */
93012 int addrOk; /* Jump here if the key is OK */
93013 int *aiCols; /* child to parent column mapping */
93014
93015 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
93016 regResult = pParse->nMem+1;
93017 pParse->nMem += 4;
93018 regKey = ++pParse->nMem;
93019 regRow = ++pParse->nMem;
93020 v = sqlite3GetVdbe(pParse);
93021 sqlite3VdbeSetNumCols(v, 4);
93022 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
93023 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC);
93024 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "parent", SQLITE_STATIC);
93025 sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "fkid", SQLITE_STATIC);
93026 sqlite3CodeVerifySchema(pParse, iDb);
93027 k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
93028 while( k ){
93029 if( zRight ){
93030 pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
93031 k = 0;
93032 }else{
93033 pTab = (Table*)sqliteHashData(k);
93034 k = sqliteHashNext(k);
93035 }
93036 if( pTab==0 || pTab->pFKey==0 ) continue;
93037 sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
93038 if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
93039 sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
93040 sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName,
93041 P4_TRANSIENT);
93042 for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
93043 pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
93044 if( pParent==0 ) break;
93045 pIdx = 0;
93046 sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
93047 x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
93048 if( x==0 ){
93049 if( pIdx==0 ){
93050 sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
93051 }else{
93052 KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
93053 sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
93054 sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
93055 }
93056 }else{
93057 k = 0;
93058 break;
93059 }
93060 }
93061 if( pFK ) break;
93062 if( pParse->nTab<i ) pParse->nTab = i;
93063 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0);
93064 for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
93065 pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
93066 assert( pParent!=0 );
93067 pIdx = 0;
93068 aiCols = 0;
93069 x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
93070 assert( x==0 );
93071 addrOk = sqlite3VdbeMakeLabel(v);
93072 if( pIdx==0 ){
93073 int iKey = pFK->aCol[0].iFrom;
93074 assert( iKey>=0 && iKey<pTab->nCol );
93075 if( iKey!=pTab->iPKey ){
93076 sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
93077 sqlite3ColumnDefault(v, pTab, iKey, regRow);
93078 sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk);
93079 sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
93080 sqlite3VdbeCurrentAddr(v)+3);
93081 }else{
93082 sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
93083 }
93084 sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow);
93085 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
93086 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
93087 }else{
93088 for(j=0; j<pFK->nCol; j++){
93089 sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
93090 aiCols ? aiCols[j] : pFK->aCol[0].iFrom, regRow+j);
93091 sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk);
93092 }
93093 sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey);
93094 sqlite3VdbeChangeP4(v, -1,
93095 sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
93096 sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
93097 }
93098 sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
93099 sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0,
93100 pFK->zTo, P4_TRANSIENT);
93101 sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+3);
93102 sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
93103 sqlite3VdbeResolveLabel(v, addrOk);
93104 sqlite3DbFree(db, aiCols);
93105 }
93106 sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1);
93107 sqlite3VdbeJumpHere(v, addrTop);
93108 }
93109 }else
93110 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
93111
93112 #ifndef NDEBUG
93113 if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
@@ -94308,11 +94563,11 @@
94563 SrcList *pSrc, /* the FROM clause -- which tables to scan */
94564 Expr *pWhere, /* the WHERE clause */
94565 ExprList *pGroupBy, /* the GROUP BY clause */
94566 Expr *pHaving, /* the HAVING clause */
94567 ExprList *pOrderBy, /* the ORDER BY clause */
94568 u16 selFlags, /* Flag parameters, such as SF_Distinct */
94569 Expr *pLimit, /* LIMIT value. NULL means not used */
94570 Expr *pOffset /* OFFSET value. NULL means no offset */
94571 ){
94572 Select *pNew;
94573 Select standin;
@@ -94332,11 +94587,11 @@
94587 pNew->pSrc = pSrc;
94588 pNew->pWhere = pWhere;
94589 pNew->pGroupBy = pGroupBy;
94590 pNew->pHaving = pHaving;
94591 pNew->pOrderBy = pOrderBy;
94592 pNew->selFlags = selFlags;
94593 pNew->op = TK_SELECT;
94594 pNew->pLimit = pLimit;
94595 pNew->pOffset = pOffset;
94596 assert( pOffset==0 || pLimit!=0 );
94597 pNew->addrOpenEphm[0] = -1;
@@ -95588,13 +95843,11 @@
95843 *paCol = aCol;
95844
95845 for(i=0, pCol=aCol; i<nCol; i++, pCol++){
95846 /* Get an appropriate name for the column
95847 */
95848 p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
 
 
95849 if( (zName = pEList->a[i].zName)!=0 ){
95850 /* If the column contains an "AS <name>" phrase, use <name> as the name */
95851 zName = sqlite3DbStrDup(db, zName);
95852 }else{
95853 Expr *pColExpr = p; /* The expression that is the result column name */
@@ -95628,10 +95881,13 @@
95881 */
95882 nName = sqlite3Strlen30(zName);
95883 for(j=cnt=0; j<i; j++){
95884 if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
95885 char *zNewName;
95886 int k;
95887 for(k=nName-1; k>1 && sqlite3Isdigit(zName[k]); k--){}
95888 if( zName[k]==':' ) nName = k;
95889 zName[nName] = 0;
95890 zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
95891 sqlite3DbFree(db, zName);
95892 zName = zNewName;
95893 j = -1;
@@ -96586,16 +96842,17 @@
96842 pKeyMerge->nField = (u16)nOrderBy;
96843 pKeyMerge->enc = ENC(db);
96844 for(i=0; i<nOrderBy; i++){
96845 CollSeq *pColl;
96846 Expr *pTerm = pOrderBy->a[i].pExpr;
96847 if( pTerm->flags & EP_Collate ){
96848 pColl = sqlite3ExprCollSeq(pParse, pTerm);
96849 }else{
96850 pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
96851 if( pColl==0 ) pColl = db->pDfltColl;
96852 pOrderBy->a[i].pExpr =
96853 sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
96854 }
96855 pKeyMerge->aColl[i] = pColl;
96856 pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
96857 }
96858 }
@@ -96794,10 +97051,11 @@
97051 */
97052 sqlite3VdbeResolveLabel(v, labelCmpr);
97053 sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
97054 sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
97055 (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
97056 sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
97057 sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
97058
97059 /* Release temporary registers
97060 */
97061 if( regPrev ){
@@ -96861,13 +97119,10 @@
97119 }else{
97120 Expr *pNew;
97121 assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
97122 assert( pExpr->pLeft==0 && pExpr->pRight==0 );
97123 pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
 
 
 
97124 sqlite3ExprDelete(db, pExpr);
97125 pExpr = pNew;
97126 }
97127 }else{
97128 pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
@@ -97414,38 +97669,47 @@
97669 return 1;
97670 }
97671 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
97672
97673 /*
97674 ** Based on the contents of the AggInfo structure indicated by the first
97675 ** argument, this function checks if the following are true:
97676 **
97677 ** * the query contains just a single aggregate function,
97678 ** * the aggregate function is either min() or max(), and
97679 ** * the argument to the aggregate function is a column value.
97680 **
97681 ** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX
97682 ** is returned as appropriate. Also, *ppMinMax is set to point to the
97683 ** list of arguments passed to the aggregate before returning.
97684 **
97685 ** Or, if the conditions above are not met, *ppMinMax is set to 0 and
97686 ** WHERE_ORDERBY_NORMAL is returned.
97687 */
97688 static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){
97689 int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
97690
97691 *ppMinMax = 0;
97692 if( pAggInfo->nFunc==1 ){
97693 Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */
97694 ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */
97695
97696 assert( pExpr->op==TK_AGG_FUNCTION );
97697 if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){
97698 const char *zFunc = pExpr->u.zToken;
97699 if( sqlite3StrICmp(zFunc, "min")==0 ){
97700 eRet = WHERE_ORDERBY_MIN;
97701 *ppMinMax = pEList;
97702 }else if( sqlite3StrICmp(zFunc, "max")==0 ){
97703 eRet = WHERE_ORDERBY_MAX;
97704 *ppMinMax = pEList;
97705 }
97706 }
97707 }
97708
97709 assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 );
97710 return eRet;
97711 }
97712
97713 /*
97714 ** The select statement passed as the first argument is an aggregate query.
97715 ** The second argment is the associated aggregate-info object. This
@@ -97536,10 +97800,11 @@
97800 int i, j, k;
97801 SrcList *pTabList;
97802 ExprList *pEList;
97803 struct SrcList_item *pFrom;
97804 sqlite3 *db = pParse->db;
97805 Expr *pE, *pRight, *pExpr;
97806
97807 if( db->mallocFailed ){
97808 return WRC_Abort;
97809 }
97810 if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
@@ -97621,11 +97886,11 @@
97886 **
97887 ** The first loop just checks to see if there are any "*" operators
97888 ** that need expanding.
97889 */
97890 for(k=0; k<pEList->nExpr; k++){
97891 pE = pEList->a[k].pExpr;
97892 if( pE->op==TK_ALL ) break;
97893 assert( pE->op!=TK_DOT || pE->pRight!=0 );
97894 assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
97895 if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
97896 }
@@ -97639,14 +97904,22 @@
97904 ExprList *pNew = 0;
97905 int flags = pParse->db->flags;
97906 int longNames = (flags & SQLITE_FullColNames)!=0
97907 && (flags & SQLITE_ShortColNames)==0;
97908
97909 /* When processing FROM-clause subqueries, it is always the case
97910 ** that full_column_names=OFF and short_column_names=ON. The
97911 ** sqlite3ResultSetOfSelect() routine makes it so. */
97912 assert( (p->selFlags & SF_NestedFrom)==0
97913 || ((flags & SQLITE_FullColNames)==0 &&
97914 (flags & SQLITE_ShortColNames)!=0) );
97915
97916 for(k=0; k<pEList->nExpr; k++){
97917 pE = a[k].pExpr;
97918 pRight = pE->pRight;
97919 assert( pE->op!=TK_DOT || pRight!=0 );
97920 if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
97921 /* This particular expression does not need to be expanded.
97922 */
97923 pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
97924 if( pNew ){
97925 pNew->a[pNew->nExpr-1].zName = a[k].zName;
@@ -97657,44 +97930,56 @@
97930 a[k].pExpr = 0;
97931 }else{
97932 /* This expression is a "*" or a "TABLE.*" and needs to be
97933 ** expanded. */
97934 int tableSeen = 0; /* Set to 1 when TABLE matches */
97935 char *zTName = 0; /* text of name of TABLE */
97936 if( pE->op==TK_DOT ){
97937 assert( pE->pLeft!=0 );
97938 assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
97939 zTName = pE->pLeft->u.zToken;
 
 
97940 }
97941 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
97942 Table *pTab = pFrom->pTab;
97943 Select *pSub = pFrom->pSelect;
97944 char *zTabName = pFrom->zAlias;
97945 const char *zSchemaName = 0;
97946 int iDb;
97947 if( zTabName==0 ){
97948 zTabName = pTab->zName;
97949 }
97950 if( db->mallocFailed ) break;
97951 if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
97952 pSub = 0;
97953 if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
97954 continue;
97955 }
97956 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
97957 zSchemaName = iDb>=0 ? db->aDb[iDb].zName : "*";
97958 }
 
97959 for(j=0; j<pTab->nCol; j++){
 
97960 char *zName = pTab->aCol[j].zName;
97961 char *zColname; /* The computed column name */
97962 char *zToFree; /* Malloced string that needs to be freed */
97963 Token sColname; /* Computed column name as a token */
97964
97965 assert( zName );
97966 if( zTName && pSub
97967 && sqlite3MatchSpanName(pSub->pEList->a[j].zSpan, 0, zTName, 0)==0
97968 ){
97969 continue;
97970 }
97971
97972 /* If a column is marked as 'hidden' (currently only possible
97973 ** for virtual tables), do not include it in the expanded
97974 ** result-set list.
97975 */
97976 if( IsHiddenColumn(&pTab->aCol[j]) ){
97977 assert(IsVirtual(pTab));
97978 continue;
97979 }
97980 tableSeen = 1;
97981
97982 if( i>0 && zTName==0 ){
97983 if( (pFrom->jointype & JT_NATURAL)!=0
97984 && tableAndColumnIndex(pTabList, i, zName, 0, 0)
97985 ){
@@ -97713,10 +97998,14 @@
97998 zToFree = 0;
97999 if( longNames || pTabList->nSrc>1 ){
98000 Expr *pLeft;
98001 pLeft = sqlite3Expr(db, TK_ID, zTabName);
98002 pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
98003 if( zSchemaName ){
98004 pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
98005 pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr, 0);
98006 }
98007 if( longNames ){
98008 zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
98009 zToFree = zColname;
98010 }
98011 }else{
@@ -97724,10 +98013,22 @@
98013 }
98014 pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
98015 sColname.z = zColname;
98016 sColname.n = sqlite3Strlen30(zColname);
98017 sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
98018 if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
98019 struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
98020 if( pSub ){
98021 pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan);
98022 testcase( pX->zSpan==0 );
98023 }else{
98024 pX->zSpan = sqlite3MPrintf(db, "%s.%s.%s",
98025 zSchemaName, zTabName, zColname);
98026 testcase( pX->zSpan==0 );
98027 }
98028 pX->bSpanIsTab = 1;
98029 }
98030 sqlite3DbFree(db, zToFree);
98031 }
98032 }
98033 if( !tableSeen ){
98034 if( zTName ){
@@ -98781,15 +99082,21 @@
99082 ** index or indices to use) should place a different priority on
99083 ** satisfying the 'ORDER BY' clause than it does in other cases.
99084 ** Refer to code and comments in where.c for details.
99085 */
99086 ExprList *pMinMax = 0;
99087 u8 flag = WHERE_ORDERBY_NORMAL;
99088
99089 assert( p->pGroupBy==0 );
99090 assert( flag==0 );
99091 if( p->pHaving==0 ){
99092 flag = minMaxQuery(&sAggInfo, &pMinMax);
99093 }
99094 assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) );
99095
99096 if( flag ){
99097 pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
 
 
99098 pDel = pMinMax;
99099 if( pMinMax && !db->mallocFailed ){
99100 pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
99101 pMinMax->a[0].pExpr->op = TK_COLUMN;
99102 }
@@ -102673,11 +102980,11 @@
102980 #define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */
102981 #define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */
102982 #define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */
102983 #define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
102984 #define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
102985 #define WHERE_IN_ABLE 0x080f1000 /* Able to support an IN operator */
102986 #define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
102987 #define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
102988 #define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
102989 #define WHERE_IDX_ONLY 0x00400000 /* Use index only - omit table */
102990 #define WHERE_ORDERED 0x00800000 /* Output will appear in correct order */
@@ -102823,11 +103130,11 @@
103130 sqlite3DbFree(db, pOld);
103131 }
103132 pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
103133 }
103134 pTerm = &pWC->a[idx = pWC->nTerm++];
103135 pTerm->pExpr = sqlite3ExprSkipCollate(p);
103136 pTerm->wtFlags = wtFlags;
103137 pTerm->pWC = pWC;
103138 pTerm->iParent = -1;
103139 return idx;
103140 }
@@ -102983,27 +103290,36 @@
103290
103291 /*
103292 ** Commute a comparison operator. Expressions of the form "X op Y"
103293 ** are converted into "Y op X".
103294 **
103295 ** If left/right precendence rules come into play when determining the
103296 ** collating
103297 ** side of the comparison, it remains associated with the same side after
103298 ** the commutation. So "Y collate NOCASE op X" becomes
103299 ** "X op Y". This is because any collation sequence on
103300 ** the left hand side of a comparison overrides any collation sequence
103301 ** attached to the right. For the same reason the EP_Collate flag
103302 ** is not commuted.
103303 */
103304 static void exprCommute(Parse *pParse, Expr *pExpr){
103305 u16 expRight = (pExpr->pRight->flags & EP_Collate);
103306 u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
103307 assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
103308 if( expRight==expLeft ){
103309 /* Either X and Y both have COLLATE operator or neither do */
103310 if( expRight ){
103311 /* Both X and Y have COLLATE operators. Make sure X is always
103312 ** used by clearing the EP_Collate flag from Y. */
103313 pExpr->pRight->flags &= ~EP_Collate;
103314 }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
103315 /* Neither X nor Y have COLLATE operators, but X has a non-default
103316 ** collating sequence. So add the EP_Collate marker on X to cause
103317 ** it to be searched first. */
103318 pExpr->pLeft->flags |= EP_Collate;
103319 }
103320 }
103321 SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
103322 if( pExpr->op>=TK_GT ){
103323 assert( TK_LT==TK_GT+2 );
103324 assert( TK_GE==TK_LE+2 );
103325 assert( TK_GT>TK_EQ );
@@ -103076,16 +103392,16 @@
103392 ** it to be useful for optimising expression pX. Store this
103393 ** value in variable pColl.
103394 */
103395 assert(pX->pLeft);
103396 pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
103397 if( pColl==0 ) pColl = pParse->db->pDfltColl;
103398
103399 for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
103400 if( NEVER(j>=pIdx->nColumn) ) return 0;
103401 }
103402 if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
103403 }
103404 return pTerm;
103405 }
103406 }
103407 }
@@ -103600,10 +103916,11 @@
103916 return;
103917 }
103918 pTerm = &pWC->a[idxTerm];
103919 pMaskSet = pWC->pMaskSet;
103920 pExpr = pTerm->pExpr;
103921 assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
103922 prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
103923 op = pExpr->op;
103924 if( op==TK_IN ){
103925 assert( pExpr->pRight==0 );
103926 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
@@ -103626,12 +103943,12 @@
103943 pTerm->prereqAll = prereqAll;
103944 pTerm->leftCursor = -1;
103945 pTerm->iParent = -1;
103946 pTerm->eOperator = 0;
103947 if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
103948 Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
103949 Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
103950 if( pLeft->op==TK_COLUMN ){
103951 pTerm->leftCursor = pLeft->iTable;
103952 pTerm->u.leftColumn = pLeft->iColumn;
103953 pTerm->eOperator = operatorMask(op);
103954 }
@@ -103655,11 +103972,11 @@
103972 }else{
103973 pDup = pExpr;
103974 pNew = pTerm;
103975 }
103976 exprCommute(pParse, pDup);
103977 pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
103978 pNew->leftCursor = pLeft->iTable;
103979 pNew->u.leftColumn = pLeft->iColumn;
103980 testcase( (prereqLeft | extraRight) != prereqLeft );
103981 pNew->prereqRight = prereqLeft | extraRight;
103982 pNew->prereqAll = prereqAll;
@@ -103734,11 +104051,11 @@
104051 Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */
104052 Expr *pNewExpr1;
104053 Expr *pNewExpr2;
104054 int idxNew1;
104055 int idxNew2;
104056 Token sCollSeqName; /* Name of collating sequence */
104057
104058 pLeft = pExpr->x.pList->a[1].pExpr;
104059 pStr2 = sqlite3ExprDup(db, pStr1, 0);
104060 if( !db->mallocFailed ){
104061 u8 c, *pC; /* Last character before the first wildcard */
@@ -103756,20 +104073,23 @@
104073
104074 c = sqlite3UpperToLower[c];
104075 }
104076 *pC = c + 1;
104077 }
104078 sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
104079 sCollSeqName.n = 6;
104080 pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
104081 pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
104082 sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
104083 pStr1, 0);
104084 idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
104085 testcase( idxNew1==0 );
104086 exprAnalyze(pSrc, pWC, idxNew1);
104087 pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
104088 pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
104089 sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
104090 pStr2, 0);
104091 idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
104092 testcase( idxNew2==0 );
104093 exprAnalyze(pSrc, pWC, idxNew2);
104094 pTerm = &pWC->a[idxTerm];
104095 if( isComplete ){
@@ -103883,16 +104203,16 @@
104203 ){
104204 int i;
104205 const char *zColl = pIdx->azColl[iCol];
104206
104207 for(i=0; i<pList->nExpr; i++){
104208 Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
104209 if( p->op==TK_COLUMN
104210 && p->iColumn==pIdx->aiColumn[iCol]
104211 && p->iTable==iBase
104212 ){
104213 CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
104214 if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
104215 return i;
104216 }
104217 }
104218 }
@@ -103935,11 +104255,11 @@
104255 ** matching "col=X" expression and the column is on the same table as pIdx,
104256 ** set the corresponding bit in variable mask.
104257 */
104258 for(i=0; i<pDistinct->nExpr; i++){
104259 WhereTerm *pTerm;
104260 Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
104261 if( p->op!=TK_COLUMN ) return 0;
104262 pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
104263 if( pTerm ){
104264 Expr *pX = pTerm->pExpr;
104265 CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -103987,11 +104307,11 @@
104307 /* If any of the expressions is an IPK column on table iBase, then return
104308 ** true. Note: The (p->iTable==iBase) part of this test may be false if the
104309 ** current SELECT is a correlated sub-query.
104310 */
104311 for(i=0; i<pDistinct->nExpr; i++){
104312 Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
104313 if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
104314 }
104315
104316 /* Loop through all indices on the table, checking each to see if it makes
104317 ** the DISTINCT qualifier redundant. It does so if:
@@ -104464,11 +104784,11 @@
104784 for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
104785 if( pTerm->leftCursor != pSrc->iCursor ) continue;
104786 assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104787 testcase( pTerm->eOperator==WO_IN );
104788 testcase( pTerm->eOperator==WO_ISNULL );
104789 if( pTerm->eOperator & (WO_ISNULL) ) continue;
104790 if( pTerm->wtFlags & TERM_VNULL ) continue;
104791 nTerm++;
104792 }
104793
104794 /* If the ORDER BY clause contains only columns in the current
@@ -104512,29 +104832,32 @@
104832 *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
104833 *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
104834 pUsage;
104835
104836 for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
104837 u8 op;
104838 if( pTerm->leftCursor != pSrc->iCursor ) continue;
104839 assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104840 testcase( pTerm->eOperator==WO_IN );
104841 testcase( pTerm->eOperator==WO_ISNULL );
104842 if( pTerm->eOperator & (WO_ISNULL) ) continue;
104843 if( pTerm->wtFlags & TERM_VNULL ) continue;
104844 pIdxCons[j].iColumn = pTerm->u.leftColumn;
104845 pIdxCons[j].iTermOffset = i;
104846 op = (u8)pTerm->eOperator;
104847 if( op==WO_IN ) op = WO_EQ;
104848 pIdxCons[j].op = op;
104849 /* The direct assignment in the previous line is possible only because
104850 ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
104851 ** following asserts verify this fact. */
104852 assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
104853 assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
104854 assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
104855 assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
104856 assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
104857 assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
104858 assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
104859 j++;
104860 }
104861 for(i=0; i<nOrderBy; i++){
104862 Expr *pExpr = pOrderBy->a[i].pExpr;
104863 pIdxOrderBy[i].iColumn = pExpr->iColumn;
@@ -104616,10 +104939,11 @@
104939 struct sqlite3_index_constraint *pIdxCons;
104940 struct sqlite3_index_constraint_usage *pUsage;
104941 WhereTerm *pTerm;
104942 int i, j;
104943 int nOrderBy;
104944 int bAllowIN; /* Allow IN optimizations */
104945 double rCost;
104946
104947 /* Make sure wsFlags is initialized to some sane value. Otherwise, if the
104948 ** malloc in allocateIndexInfo() fails and this function returns leaving
104949 ** wsFlags in an uninitialized state, the caller may behave unpredictably.
@@ -104650,63 +104974,91 @@
104974 ** sqlite3ViewGetColumnNames() would have picked up the error.
104975 */
104976 assert( pTab->azModuleArg && pTab->azModuleArg[0] );
104977 assert( sqlite3GetVTable(pParse->db, pTab) );
104978
104979 /* Try once or twice. On the first attempt, allow IN optimizations.
104980 ** If an IN optimization is accepted by the virtual table xBestIndex
104981 ** method, but the pInfo->aConstrainUsage.omit flag is not set, then
104982 ** the query will not work because it might allow duplicate rows in
104983 ** output. In that case, run the xBestIndex method a second time
104984 ** without the IN constraints. Usually this loop only runs once.
104985 ** The loop will exit using a "break" statement.
104986 */
104987 for(bAllowIN=1; 1; bAllowIN--){
104988 assert( bAllowIN==0 || bAllowIN==1 );
104989
104990 /* Set the aConstraint[].usable fields and initialize all
104991 ** output variables to zero.
104992 **
104993 ** aConstraint[].usable is true for constraints where the right-hand
104994 ** side contains only references to tables to the left of the current
104995 ** table. In other words, if the constraint is of the form:
104996 **
104997 ** column = expr
104998 **
104999 ** and we are evaluating a join, then the constraint on column is
105000 ** only valid if all tables referenced in expr occur to the left
105001 ** of the table containing column.
105002 **
105003 ** The aConstraints[] array contains entries for all constraints
105004 ** on the current table. That way we only have to compute it once
105005 ** even though we might try to pick the best index multiple times.
105006 ** For each attempt at picking an index, the order of tables in the
105007 ** join might be different so we have to recompute the usable flag
105008 ** each time.
105009 */
105010 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105011 pUsage = pIdxInfo->aConstraintUsage;
105012 for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105013 j = pIdxCons->iTermOffset;
105014 pTerm = &pWC->a[j];
105015 if( (pTerm->prereqRight&p->notReady)==0
105016 && (bAllowIN || pTerm->eOperator!=WO_IN)
105017 ){
105018 pIdxCons->usable = 1;
105019 }else{
105020 pIdxCons->usable = 0;
105021 }
105022 }
105023 memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
105024 if( pIdxInfo->needToFreeIdxStr ){
105025 sqlite3_free(pIdxInfo->idxStr);
105026 }
105027 pIdxInfo->idxStr = 0;
105028 pIdxInfo->idxNum = 0;
105029 pIdxInfo->needToFreeIdxStr = 0;
105030 pIdxInfo->orderByConsumed = 0;
105031 /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
105032 pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
105033 nOrderBy = pIdxInfo->nOrderBy;
105034 if( !p->pOrderBy ){
105035 pIdxInfo->nOrderBy = 0;
105036 }
105037
105038 if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
105039 return;
105040 }
105041
105042 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105043 for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105044 if( pUsage[i].argvIndex>0 ){
105045 j = pIdxCons->iTermOffset;
105046 pTerm = &pWC->a[j];
105047 p->cost.used |= pTerm->prereqRight;
105048 if( pTerm->eOperator==WO_IN && pUsage[i].omit==0 ){
105049 /* Do not attempt to use an IN constraint if the virtual table
105050 ** says that the equivalent EQ constraint cannot be safely omitted.
105051 ** If we do attempt to use such a constraint, some rows might be
105052 ** repeated in the output. */
105053 break;
105054 }
105055 }
105056 }
105057 if( i>=pIdxInfo->nConstraint ) break;
105058 }
105059
105060 /* If there is an ORDER BY clause, and the selected virtual table index
105061 ** does not satisfy it, increase the cost of the scan accordingly. This
105062 ** matches the processing for non-virtual tables in bestBtreeIndex().
105063 */
105064 rCost = pIdxInfo->estimatedCost;
@@ -105273,11 +105625,11 @@
105625 WhereTerm *pConstraint; /* A constraint in the WHERE clause */
105626
105627 /* If the next term of the ORDER BY clause refers to anything other than
105628 ** a column in the "base" table, then this index will not be of any
105629 ** further use in handling the ORDER BY. */
105630 pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr);
105631 if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
105632 break;
105633 }
105634
105635 /* Find column number and collating sequence for the next entry
@@ -105299,11 +105651,11 @@
105651 /* Check to see if the column number and collating sequence of the
105652 ** index match the column number and collating sequence of the ORDER BY
105653 ** clause entry. Set isMatch to 1 if they both match. */
105654 if( pOBExpr->iColumn==iColumn ){
105655 if( zColl ){
105656 pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr);
105657 if( !pColl ) pColl = db->pDfltColl;
105658 isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
105659 }else{
105660 isMatch = 1;
105661 }
@@ -105440,10 +105792,15 @@
105792 int idxEqTermMask; /* Index mask of valid equality operators */
105793 Index sPk; /* A fake index object for the primary key */
105794 tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
105795 int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
105796 int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */
105797 int nPriorSat; /* ORDER BY terms satisfied by outer loops */
105798 int nOrderBy; /* Number of ORDER BY terms */
105799 char bSortInit; /* Initializer for bSort in inner loop */
105800 char bDistInit; /* Initializer for bDist in inner loop */
105801
105802
105803 /* Initialize the cost to a worst-case value */
105804 memset(&p->cost, 0, sizeof(p->cost));
105805 p->cost.rCost = SQLITE_BIG_DBL;
105806
@@ -105488,10 +105845,21 @@
105845 WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
105846 );
105847 eqTermMask = WO_EQ|WO_IN;
105848 pIdx = 0;
105849 }
105850
105851 nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
105852 if( p->i ){
105853 nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
105854 bSortInit = nPriorSat<nOrderBy;
105855 bDistInit = 0;
105856 }else{
105857 nPriorSat = 0;
105858 bSortInit = nOrderBy>0;
105859 bDistInit = p->pDistinct!=0;
105860 }
105861
105862 /* Loop over all indices looking for the best one to use
105863 */
105864 for(; pProbe; pIdx=pProbe=pProbe->pNext){
105865 const tRowcnt * const aiRowEst = pProbe->aiRowEst;
@@ -105566,15 +105934,13 @@
105934 */
105935 int bInEst = 0; /* True if "x IN (SELECT...)" seen */
105936 int nInMul = 1; /* Number of distinct equalities to lookup */
105937 double rangeDiv = (double)1; /* Estimated reduction in search space */
105938 int nBound = 0; /* Number of range constraints seen */
105939 char bSort = bSortInit; /* True if external sort required */
105940 char bDist = bDistInit; /* True if index cannot help with DISTINCT */
105941 char bLookup = 0; /* True if not a covering index */
 
 
105942 WhereTerm *pTerm; /* A single term of the WHERE clause */
105943 #ifdef SQLITE_ENABLE_STAT3
105944 WhereTerm *pFirstTerm = 0; /* First term matching the index */
105945 #endif
105946
@@ -105581,20 +105947,11 @@
105947 WHERETRACE((
105948 " %s(%s):\n",
105949 pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
105950 ));
105951 memset(&pc, 0, sizeof(pc));
105952 pc.plan.nOBSat = nPriorSat;
 
 
 
 
 
 
 
 
 
105953
105954 /* Determine the values of pc.plan.nEq and nInMul */
105955 for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
105956 int j = pProbe->aiColumn[pc.plan.nEq];
105957 pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
@@ -106466,32 +106823,40 @@
106823 if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
106824 /* Case 0: The table is a virtual-table. Use the VFilter and VNext
106825 ** to access the data.
106826 */
106827 int iReg; /* P3 Value for OP_VFilter */
106828 int addrNotFound;
106829 sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
106830 int nConstraint = pVtabIdx->nConstraint;
106831 struct sqlite3_index_constraint_usage *aUsage =
106832 pVtabIdx->aConstraintUsage;
106833 const struct sqlite3_index_constraint *aConstraint =
106834 pVtabIdx->aConstraint;
106835
106836 sqlite3ExprCachePush(pParse);
106837 iReg = sqlite3GetTempRange(pParse, nConstraint+2);
106838 addrNotFound = pLevel->addrBrk;
106839 for(j=1; j<=nConstraint; j++){
106840 for(k=0; k<nConstraint; k++){
106841 if( aUsage[k].argvIndex==j ){
106842 WhereTerm *pTerm = &pWC->a[aConstraint[k].iTermOffset];
106843 int iTarget = iReg+j+1;
106844 if( pTerm->eOperator & WO_IN ){
106845 codeEqualityTerm(pParse, pTerm, pLevel, iTarget);
106846 addrNotFound = pLevel->addrNxt;
106847 }else{
106848 sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
106849 }
106850 break;
106851 }
106852 }
106853 if( k==nConstraint ) break;
106854 }
106855 sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
106856 sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
106857 sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, pVtabIdx->idxStr,
106858 pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
106859 pVtabIdx->needToFreeIdxStr = 0;
106860 for(j=0; j<nConstraint; j++){
106861 if( aUsage[j].omit ){
106862 int iTerm = aConstraint[j].iTermOffset;
@@ -108134,10 +108499,11 @@
108499 Expr* yy122;
108500 Select* yy159;
108501 IdList* yy180;
108502 struct {int value; int mask;} yy207;
108503 u8 yy258;
108504 u16 yy305;
108505 struct LikeOp yy318;
108506 TriggerStep* yy327;
108507 ExprSpan yy342;
108508 SrcList* yy347;
108509 int yy392;
@@ -110084,22 +110450,19 @@
110450 case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
110451 case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
110452 case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
110453 case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
110454 case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
 
 
110455 case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
110456 case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
110457 {yygotominor.yy392 = 0;}
110458 break;
110459 case 29: /* ifnotexists ::= IF NOT EXISTS */
110460 case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
110461 case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
110462 case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
110463 case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
 
110464 case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
110465 case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
110466 {yygotominor.yy392 = 1;}
110467 break;
110468 case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
@@ -110335,12 +110698,19 @@
110698 case 116: /* multiselect_op ::= UNION ALL */
110699 {yygotominor.yy392 = TK_ALL;}
110700 break;
110701 case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
110702 {
110703 yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy305,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
110704 }
110705 break;
110706 case 119: /* distinct ::= DISTINCT */
110707 {yygotominor.yy305 = SF_Distinct;}
110708 break;
110709 case 120: /* distinct ::= ALL */
110710 case 121: /* distinct ::= */ yytestcase(yyruleno==121);
110711 {yygotominor.yy305 = 0;}
110712 break;
110713 case 122: /* sclp ::= selcollist COMMA */
110714 case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
110715 {yygotominor.yy442 = yymsp[-1].minor.yy442;}
110716 break;
@@ -110406,14 +110776,24 @@
110776 break;
110777 case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
110778 {
110779 if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
110780 yygotominor.yy347 = yymsp[-4].minor.yy347;
110781 }else if( yymsp[-4].minor.yy347->nSrc==1 ){
110782 yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
110783 if( yygotominor.yy347 ){
110784 struct SrcList_item *pNew = &yygotominor.yy347->a[yygotominor.yy347->nSrc-1];
110785 struct SrcList_item *pOld = yymsp[-4].minor.yy347->a;
110786 pNew->zName = pOld->zName;
110787 pNew->zDatabase = pOld->zDatabase;
110788 pOld->zName = pOld->zDatabase = 0;
110789 }
110790 sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy347);
110791 }else{
110792 Select *pSubquery;
110793 sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
110794 pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,SF_NestedFrom,0,0);
110795 yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
110796 }
110797 }
110798 break;
110799 case 137: /* dbnm ::= */
@@ -110624,11 +111004,11 @@
111004 spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
111005 }
111006 break;
111007 case 194: /* expr ::= expr COLLATE ids */
111008 {
111009 yygotominor.yy342.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
111010 yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
111011 yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
111012 }
111013 break;
111014 case 195: /* expr ::= CAST LP expr AS typetoken RP */
@@ -110642,11 +111022,11 @@
111022 if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
111023 sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
111024 }
111025 yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
111026 spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
111027 if( yymsp[-2].minor.yy305 && yygotominor.yy342.pExpr ){
111028 yygotominor.yy342.pExpr->flags |= EP_Distinct;
111029 }
111030 }
111031 break;
111032 case 197: /* expr ::= ID LP STAR RP */
@@ -110883,28 +111263,20 @@
111263 case 244: /* uniqueflag ::= */
111264 {yygotominor.yy392 = OE_None;}
111265 break;
111266 case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
111267 {
111268 Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
 
 
 
 
111269 yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
111270 sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
111271 sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
111272 if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
111273 }
111274 break;
111275 case 248: /* idxlist ::= nm collate sortorder */
111276 {
111277 Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
 
 
 
 
111278 yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
111279 sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
111280 sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
111281 if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
111282 }
@@ -141105,10 +141477,11 @@
141477 extern int Sqlitemultiplex_Init(Tcl_Interp*);
141478 extern int SqliteSuperlock_Init(Tcl_Interp*);
141479 extern int SqlitetestSyscall_Init(Tcl_Interp*);
141480 extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
141481 extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
141482 extern int Sqlitetestregexp_Init(Tcl_Interp*);
141483
141484 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141485 extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
141486 #endif
141487
@@ -141148,10 +141521,11 @@
141521 Sqlitemultiplex_Init(interp);
141522 SqliteSuperlock_Init(interp);
141523 SqlitetestSyscall_Init(interp);
141524 Sqlitetestfuzzer_Init(interp);
141525 Sqlitetestwholenumber_Init(interp);
141526 Sqlitetestregexp_Init(interp);
141527
141528 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141529 Sqlitetestfts3_Init(interp);
141530 #endif
141531
141532
+844 -470
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
11
/******************************************************************************
22
** This file is an amalgamation of many separate C source files from SQLite
3
-** version 3.7.15. By combining all the individual C code files into this
3
+** version 3.7.16. By combining all the individual C code files into this
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -671,13 +671,13 @@
671671
**
672672
** See also: [sqlite3_libversion()],
673673
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674674
** [sqlite_version()] and [sqlite_source_id()].
675675
*/
676
-#define SQLITE_VERSION "3.7.15"
677
-#define SQLITE_VERSION_NUMBER 3007015
678
-#define SQLITE_SOURCE_ID "2012-10-16 23:08:28 f021559d8a23934e3bdccad5b55fc7a91d185f53"
676
+#define SQLITE_VERSION "3.7.16"
677
+#define SQLITE_VERSION_NUMBER 3007016
678
+#define SQLITE_SOURCE_ID "2012-12-08 06:46:05 e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0"
679679
680680
/*
681681
** CAPI3REF: Run-Time Library Version Numbers
682682
** KEYWORDS: sqlite3_version, sqlite3_sourceid
683683
**
@@ -2162,11 +2162,11 @@
21622162
** database connection is opened. By default, URI handling is globally
21632163
** disabled. The default value may be changed by compiling with the
21642164
** [SQLITE_USE_URI] symbol defined.
21652165
**
21662166
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
2167
-** <dd> This option taks a single integer argument which is interpreted as
2167
+** <dd> This option takes a single integer argument which is interpreted as
21682168
** a boolean in order to enable or disable the use of covering indices for
21692169
** full table scans in the query optimizer. The default setting is determined
21702170
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
21712171
** if that compile-time option is omitted.
21722172
** The ability to disable the use of covering indices for full table scans
@@ -10573,24 +10573,24 @@
1057310573
** and the value of Index.onError indicate the which conflict resolution
1057410574
** algorithm to employ whenever an attempt is made to insert a non-unique
1057510575
** element.
1057610576
*/
1057710577
struct Index {
10578
- char *zName; /* Name of this index */
10579
- int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10580
- tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
10581
- Table *pTable; /* The SQL table being indexed */
10582
- char *zColAff; /* String defining the affinity of each column */
10583
- Index *pNext; /* The next index associated with the same table */
10584
- Schema *pSchema; /* Schema containing this index */
10585
- u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
10586
- char **azColl; /* Array of collation sequence names for index */
10587
- int nColumn; /* Number of columns in the table used by this index */
10588
- int tnum; /* Page containing root of this index in database file */
10589
- u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10590
- u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
10591
- u8 bUnordered; /* Use this index for == or IN queries only */
10578
+ char *zName; /* Name of this index */
10579
+ int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10580
+ tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */
10581
+ Table *pTable; /* The SQL table being indexed */
10582
+ char *zColAff; /* String defining the affinity of each column */
10583
+ Index *pNext; /* The next index associated with the same table */
10584
+ Schema *pSchema; /* Schema containing this index */
10585
+ u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
10586
+ char **azColl; /* Array of collation sequence names for index */
10587
+ int tnum; /* DB Page containing root of this index */
10588
+ u16 nColumn; /* Number of columns in table used by this index */
10589
+ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10590
+ unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
10591
+ unsigned bUnordered:1; /* Use this index for == or IN queries only */
1059210592
#ifdef SQLITE_ENABLE_STAT3
1059310593
int nSample; /* Number of elements in aSample[] */
1059410594
tRowcnt avgEq; /* Average nEq value for key values not in aSample */
1059510595
IndexSample *aSample; /* Samples of the left-most key */
1059610596
#endif
@@ -10767,11 +10767,10 @@
1076710767
Expr *pRight; /* Right subnode */
1076810768
union {
1076910769
ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
1077010770
Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
1077110771
} x;
10772
- CollSeq *pColl; /* The collation type of the column or 0 */
1077310772
1077410773
/* If the EP_Reduced flag is set in the Expr.flags mask, then no
1077510774
** space is allocated for the fields below this point. An attempt to
1077610775
** access them will result in a segfault or malfunction.
1077710776
*********************************************************************/
@@ -10803,11 +10802,11 @@
1080310802
#define EP_Error 0x0008 /* Expression contains one or more errors */
1080410803
#define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
1080510804
#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
1080610805
#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
1080710806
#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
10808
-#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
10807
+#define EP_Collate 0x0100 /* Tree contains a TK_COLLATE opeartor */
1080910808
#define EP_FixedDest 0x0200 /* Result needed in a specific register */
1081010809
#define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
1081110810
#define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
1081210811
#define EP_Hint 0x1000 /* Not used */
1081310812
#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
@@ -10861,22 +10860,31 @@
1086110860
** name. An expr/name combination can be used in several ways, such
1086210861
** as the list of "expr AS ID" fields following a "SELECT" or in the
1086310862
** list of "ID = expr" items in an UPDATE. A list of expressions can
1086410863
** also be used as the argument to a function, in which case the a.zName
1086510864
** field is not used.
10865
+**
10866
+** By default the Expr.zSpan field holds a human-readable description of
10867
+** the expression that is used in the generation of error messages and
10868
+** column labels. In this case, Expr.zSpan is typically the text of a
10869
+** column expression as it exists in a SELECT statement. However, if
10870
+** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name
10871
+** of the result column in the form: DATABASE.TABLE.COLUMN. This later
10872
+** form is used for name resolution with nested FROM clauses.
1086610873
*/
1086710874
struct ExprList {
1086810875
int nExpr; /* Number of expressions on the list */
1086910876
int iECursor; /* VDBE Cursor associated with this ExprList */
1087010877
struct ExprList_item { /* For each expression in the list */
10871
- Expr *pExpr; /* The list of expressions */
10872
- char *zName; /* Token associated with this expression */
10873
- char *zSpan; /* Original text of the expression */
10874
- u8 sortOrder; /* 1 for DESC or 0 for ASC */
10875
- u8 done; /* A flag to indicate when processing is finished */
10876
- u16 iOrderByCol; /* For ORDER BY, column number in result set */
10877
- u16 iAlias; /* Index into Parse.aAlias[] for zName */
10878
+ Expr *pExpr; /* The list of expressions */
10879
+ char *zName; /* Token associated with this expression */
10880
+ char *zSpan; /* Original text of the expression */
10881
+ u8 sortOrder; /* 1 for DESC or 0 for ASC */
10882
+ unsigned done :1; /* A flag to indicate when processing is finished */
10883
+ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
10884
+ u16 iOrderByCol; /* For ORDER BY, column number in result set */
10885
+ u16 iAlias; /* Index into Parse.aAlias[] for zName */
1087810886
} *a; /* Alloc a power of two greater or equal to nExpr */
1087910887
};
1088010888
1088110889
/*
1088210890
** An instance of this structure is used by the parser to record both
@@ -11192,10 +11200,11 @@
1119211200
#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
1119311201
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
1119411202
#define SF_UseSorter 0x0040 /* Sort using a sorter */
1119511203
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
1119611204
#define SF_Materialize 0x0100 /* Force materialization of views */
11205
+#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
1119711206
1119811207
1119911208
/*
1120011209
** The results of a select can be distributed in several ways. The
1120111210
** "SRT" prefix means "SELECT Result Type".
@@ -11420,10 +11429,11 @@
1142011429
#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
1142111430
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
1142211431
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
1142311432
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
1142411433
#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
11434
+#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
1142511435
1142611436
/*
1142711437
* Each trigger present in the database schema is stored as an instance of
1142811438
* struct Trigger.
1142911439
*
@@ -11904,11 +11914,11 @@
1190411914
SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
1190511915
Token*, int, int);
1190611916
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
1190711917
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
1190811918
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
11909
- Expr*,ExprList*,int,Expr*,Expr*);
11919
+ Expr*,ExprList*,u16,Expr*,Expr*);
1191011920
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
1191111921
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
1191211922
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
1191311923
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
1191411924
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
@@ -12112,12 +12122,13 @@
1211212122
SQLITE_PRIVATE const char *sqlite3ErrStr(int);
1211312123
SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
1211412124
SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
1211512125
SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
1211612126
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
12117
-SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
12118
-SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
12127
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
12128
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
12129
+SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
1211912130
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
1212012131
SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
1212112132
SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
1212212133
SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
1212312134
SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
@@ -12160,10 +12171,11 @@
1216012171
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
1216112172
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
1216212173
SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
1216312174
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
1216412175
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
12176
+SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
1216512177
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
1216612178
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
1216712179
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
1216812180
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
1216912181
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -12298,12 +12310,14 @@
1229812310
#define sqlite3FkOldmask(a,b) 0
1229912311
#define sqlite3FkRequired(a,b,c,d) 0
1230012312
#endif
1230112313
#ifndef SQLITE_OMIT_FOREIGN_KEY
1230212314
SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*);
12315
+SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**);
1230312316
#else
1230412317
#define sqlite3FkDelete(a,b)
12318
+ #define sqlite3FkLocateIndex(a,b,c,d,e)
1230512319
#endif
1230612320
1230712321
1230812322
/*
1230912323
** Available fault injectors. Should be numbered beginning with 0.
@@ -23307,15 +23321,11 @@
2330723321
{ "pwrite64", (sqlite3_syscall_ptr)0, 0 },
2330823322
#endif
2330923323
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
2331023324
aSyscall[13].pCurrent)
2331123325
23312
-#if SQLITE_ENABLE_LOCKING_STYLE
2331323326
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
23314
-#else
23315
- { "fchmod", (sqlite3_syscall_ptr)0, 0 },
23316
-#endif
2331723327
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
2331823328
2331923329
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
2332023330
{ "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
2332123331
#else
@@ -23336,13 +23346,10 @@
2333623346
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
2333723347
2333823348
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
2333923349
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
2334023350
23341
- { "umask", (sqlite3_syscall_ptr)umask, 0 },
23342
-#define osUmask ((mode_t(*)(mode_t))aSyscall[21].pCurrent)
23343
-
2334423351
}; /* End of the overrideable system calls */
2334523352
2334623353
/*
2334723354
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
2334823355
** "unix" VFSes. Return SQLITE_OK opon successfully updating the
@@ -23443,31 +23450,29 @@
2344323450
** process that is able to write to the database will also be able to
2344423451
** recover the hot journals.
2344523452
*/
2344623453
static int robust_open(const char *z, int f, mode_t m){
2344723454
int fd;
23448
- mode_t m2;
23449
- mode_t origM = 0;
23450
- if( m==0 ){
23451
- m2 = SQLITE_DEFAULT_FILE_PERMISSIONS;
23452
- }else{
23453
- m2 = m;
23454
- origM = osUmask(0);
23455
- }
23455
+ mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
2345623456
do{
2345723457
#if defined(O_CLOEXEC)
2345823458
fd = osOpen(z,f|O_CLOEXEC,m2);
2345923459
#else
2346023460
fd = osOpen(z,f,m2);
2346123461
#endif
2346223462
}while( fd<0 && errno==EINTR );
23463
- if( m ){
23464
- osUmask(origM);
23465
- }
23463
+ if( fd>=0 ){
23464
+ if( m!=0 ){
23465
+ struct stat statbuf;
23466
+ if( osFstat(fd, &statbuf)==0 && (statbuf.st_mode&0777)!=m ){
23467
+ osFchmod(fd, m);
23468
+ }
23469
+ }
2346623470
#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
23467
- if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
23471
+ osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
2346823472
#endif
23473
+ }
2346923474
return fd;
2347023475
}
2347123476
2347223477
/*
2347323478
** Helper functions to obtain and relinquish the global mutex. The
@@ -29889,11 +29894,11 @@
2988929894
};
2989029895
unsigned int i; /* Loop counter */
2989129896
2989229897
/* Double-check that the aSyscall[] array has been constructed
2989329898
** correctly. See ticket [bb3a86e890c8e96ab] */
29894
- assert( ArraySize(aSyscall)==22 );
29899
+ assert( ArraySize(aSyscall)==21 );
2989529900
2989629901
/* Register all VFSes defined in the aVfs[] array */
2989729902
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
2989829903
sqlite3_vfs_register(&aVfs[i], i==0);
2989929904
}
@@ -56355,11 +56360,11 @@
5635556360
sqlite3BtreeLeave(p);
5635656361
return 0;
5635756362
}
5635856363
i = PENDING_BYTE_PAGE(pBt);
5635956364
if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
56360
- sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000);
56365
+ sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
5636156366
sCheck.errMsg.useMalloc = 2;
5636256367
5636356368
/* Check the integrity of the freelist
5636456369
*/
5636556370
checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
@@ -56890,11 +56895,16 @@
5689056895
/*
5689156896
** Parameter zSrcData points to a buffer containing the data for
5689256897
** page iSrcPg from the source database. Copy this data into the
5689356898
** destination database.
5689456899
*/
56895
-static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
56900
+static int backupOnePage(
56901
+ sqlite3_backup *p, /* Backup handle */
56902
+ Pgno iSrcPg, /* Source database page to backup */
56903
+ const u8 *zSrcData, /* Source database page data */
56904
+ int bUpdate /* True for an update, false otherwise */
56905
+){
5689656906
Pager * const pDestPager = sqlite3BtreePager(p->pDest);
5689756907
const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
5689856908
int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
5689956909
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
5690056910
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
@@ -56963,10 +56973,13 @@
5696356973
** cached parse of the page). MemPage.isInit is marked
5696456974
** "MUST BE FIRST" for this purpose.
5696556975
*/
5696656976
memcpy(zOut, zIn, nCopy);
5696756977
((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
56978
+ if( iOff==0 && bUpdate==0 ){
56979
+ sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc));
56980
+ }
5696856981
}
5696956982
sqlite3PagerUnref(pDestPg);
5697056983
}
5697156984
5697256985
return rc;
@@ -57069,11 +57082,11 @@
5706957082
const Pgno iSrcPg = p->iNext; /* Source page number */
5707057083
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
5707157084
DbPage *pSrcPg; /* Source page object */
5707257085
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
5707357086
if( rc==SQLITE_OK ){
57074
- rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg));
57087
+ rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
5707557088
sqlite3PagerUnref(pSrcPg);
5707657089
}
5707757090
}
5707857091
p->iNext++;
5707957092
}
@@ -57317,11 +57330,11 @@
5731757330
** the new data into the backup.
5731857331
*/
5731957332
int rc;
5732057333
assert( p->pDestDb );
5732157334
sqlite3_mutex_enter(p->pDestDb->mutex);
57322
- rc = backupOnePage(p, iPage, aData);
57335
+ rc = backupOnePage(p, iPage, aData, 1);
5732357336
sqlite3_mutex_leave(p->pDestDb->mutex);
5732457337
assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
5732557338
if( rc!=SQLITE_OK ){
5732657339
p->rc = rc;
5732757340
}
@@ -59434,26 +59447,22 @@
5943459447
assert( pKeyInfo->aSortOrder!=0 );
5943559448
sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
5943659449
i = sqlite3Strlen30(zTemp);
5943759450
for(j=0; j<pKeyInfo->nField; j++){
5943859451
CollSeq *pColl = pKeyInfo->aColl[j];
59439
- if( pColl ){
59440
- int n = sqlite3Strlen30(pColl->zName);
59441
- if( i+n>nTemp-6 ){
59442
- memcpy(&zTemp[i],",...",4);
59443
- break;
59444
- }
59445
- zTemp[i++] = ',';
59446
- if( pKeyInfo->aSortOrder[j] ){
59447
- zTemp[i++] = '-';
59448
- }
59449
- memcpy(&zTemp[i], pColl->zName,n+1);
59450
- i += n;
59451
- }else if( i+4<nTemp-6 ){
59452
- memcpy(&zTemp[i],",nil",4);
59453
- i += 4;
59454
- }
59452
+ const char *zColl = pColl ? pColl->zName : "nil";
59453
+ int n = sqlite3Strlen30(zColl);
59454
+ if( i+n>nTemp-6 ){
59455
+ memcpy(&zTemp[i],",...",4);
59456
+ break;
59457
+ }
59458
+ zTemp[i++] = ',';
59459
+ if( pKeyInfo->aSortOrder[j] ){
59460
+ zTemp[i++] = '-';
59461
+ }
59462
+ memcpy(&zTemp[i], zColl, n+1);
59463
+ i += n;
5945559464
}
5945659465
zTemp[i++] = ')';
5945759466
zTemp[i] = 0;
5945859467
assert( i<nTemp );
5945959468
break;
@@ -63839,11 +63848,13 @@
6383963848
#ifdef SQLITE_DEBUG
6384063849
/*
6384163850
** Print the value of a register for tracing purposes:
6384263851
*/
6384363852
static void memTracePrint(FILE *out, Mem *p){
63844
- if( p->flags & MEM_Null ){
63853
+ if( p->flags & MEM_Invalid ){
63854
+ fprintf(out, " undefined");
63855
+ }else if( p->flags & MEM_Null ){
6384563856
fprintf(out, " NULL");
6384663857
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
6384763858
fprintf(out, " si:%lld", p->u.i);
6384863859
}else if( p->flags & MEM_Int ){
6384963860
fprintf(out, " i:%lld", p->u.i);
@@ -64112,10 +64123,11 @@
6411264123
} af;
6411364124
struct OP_Concat_stack_vars {
6411464125
i64 nByte;
6411564126
} ag;
6411664127
struct OP_Remainder_stack_vars {
64128
+ char bIntint; /* Started out as two integer operands */
6411764129
int flags; /* Combined MEM_* flags from both inputs */
6411864130
i64 iA; /* Integer value of left operand */
6411964131
i64 iB; /* Integer value of right operand */
6412064132
double rA; /* Real value of left operand */
6412164133
double rB; /* Real value of right operand */
@@ -65021,10 +65033,13 @@
6502165033
pOut = &aMem[pOp->p2];
6502265034
assert( pOut!=pIn1 );
6502365035
while( 1 ){
6502465036
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
6502565037
Deephemeralize(pOut);
65038
+#ifdef SQLITE_DEBUG
65039
+ pOut->pScopyFrom = 0;
65040
+#endif
6502665041
REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
6502765042
if( (u.ae.n--)==0 ) break;
6502865043
pOut++;
6502965044
pIn1++;
6503065045
}
@@ -65214,10 +65229,11 @@
6521465229
case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
6521565230
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
6521665231
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
6521765232
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
6521865233
#if 0 /* local variables moved into u.ah */
65234
+ char bIntint; /* Started out as two integer operands */
6521965235
int flags; /* Combined MEM_* flags from both inputs */
6522065236
i64 iA; /* Integer value of left operand */
6522165237
i64 iB; /* Integer value of right operand */
6522265238
double rA; /* Real value of left operand */
6522365239
double rB; /* Real value of right operand */
@@ -65231,10 +65247,11 @@
6523165247
u.ah.flags = pIn1->flags | pIn2->flags;
6523265248
if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
6523365249
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
6523465250
u.ah.iA = pIn1->u.i;
6523565251
u.ah.iB = pIn2->u.i;
65252
+ u.ah.bIntint = 1;
6523665253
switch( pOp->opcode ){
6523765254
case OP_Add: if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
6523865255
case OP_Subtract: if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
6523965256
case OP_Multiply: if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
6524065257
case OP_Divide: {
@@ -65251,10 +65268,11 @@
6525165268
}
6525265269
}
6525365270
pOut->u.i = u.ah.iB;
6525465271
MemSetTypeFlag(pOut, MEM_Int);
6525565272
}else{
65273
+ u.ah.bIntint = 0;
6525665274
fp_math:
6525765275
u.ah.rA = sqlite3VdbeRealValue(pIn1);
6525865276
u.ah.rB = sqlite3VdbeRealValue(pIn2);
6525965277
switch( pOp->opcode ){
6526065278
case OP_Add: u.ah.rB += u.ah.rA; break;
@@ -65282,11 +65300,11 @@
6528265300
if( sqlite3IsNaN(u.ah.rB) ){
6528365301
goto arithmetic_result_is_null;
6528465302
}
6528565303
pOut->r = u.ah.rB;
6528665304
MemSetTypeFlag(pOut, MEM_Real);
65287
- if( (u.ah.flags & MEM_Real)==0 ){
65305
+ if( (u.ah.flags & MEM_Real)==0 && !u.ah.bIntint ){
6528865306
sqlite3VdbeIntegerAffinity(pOut);
6528965307
}
6529065308
#endif
6529165309
}
6529265310
break;
@@ -65843,26 +65861,31 @@
6584365861
/* Opcode: Permutation * * * P4 *
6584465862
**
6584565863
** Set the permutation used by the OP_Compare operator to be the array
6584665864
** of integers in P4.
6584765865
**
65848
-** The permutation is only valid until the next OP_Permutation, OP_Compare,
65849
-** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur
65850
-** immediately prior to the OP_Compare.
65866
+** The permutation is only valid until the next OP_Compare that has
65867
+** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
65868
+** occur immediately prior to the OP_Compare.
6585165869
*/
6585265870
case OP_Permutation: {
6585365871
assert( pOp->p4type==P4_INTARRAY );
6585465872
assert( pOp->p4.ai );
6585565873
aPermute = pOp->p4.ai;
6585665874
break;
6585765875
}
6585865876
65859
-/* Opcode: Compare P1 P2 P3 P4 *
65877
+/* Opcode: Compare P1 P2 P3 P4 P5
6586065878
**
6586165879
** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
6586265880
** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
6586365881
** the comparison for use by the next OP_Jump instruct.
65882
+**
65883
+** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is
65884
+** determined by the most recent OP_Permutation operator. If the
65885
+** OPFLAG_PERMUTE bit is clear, then register are compared in sequential
65886
+** order.
6586465887
**
6586565888
** P4 is a KeyInfo structure that defines collating sequences and sort
6586665889
** orders for the comparison. The permutation applies to registers
6586765890
** only. The KeyInfo elements are used sequentially.
6586865891
**
@@ -65880,10 +65903,11 @@
6588065903
int idx;
6588165904
CollSeq *pColl; /* Collating sequence to use on this term */
6588265905
int bRev; /* True for DESCENDING sort order */
6588365906
#endif /* local variables moved into u.al */
6588465907
65908
+ if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
6588565909
u.al.n = pOp->p3;
6588665910
u.al.pKeyInfo = pOp->p4.pKeyInfo;
6588765911
assert( u.al.n>0 );
6588865912
assert( u.al.pKeyInfo!=0 );
6588965913
u.al.p1 = pOp->p1;
@@ -66025,12 +66049,10 @@
6602566049
6602666050
/* Opcode: Once P1 P2 * * *
6602766051
**
6602866052
** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
6602966053
** set the flag and fall through to the next instruction.
66030
-**
66031
-** See also: JumpOnce
6603266054
*/
6603366055
case OP_Once: { /* jump */
6603466056
assert( pOp->p1<p->nOnceFlag );
6603566057
if( p->aOnceFlag[pOp->p1] ){
6603666058
pc = pOp->p2-1;
@@ -71902,10 +71924,18 @@
7190271924
p->pReal = pReal;
7190371925
if( p->iSize>0 ){
7190471926
assert(p->iSize<=p->nBuf);
7190571927
rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
7190671928
}
71929
+ if( rc!=SQLITE_OK ){
71930
+ /* If an error occurred while writing to the file, close it before
71931
+ ** returning. This way, SQLite uses the in-memory journal data to
71932
+ ** roll back changes made to the internal page-cache before this
71933
+ ** function was called. */
71934
+ sqlite3OsClose(pReal);
71935
+ p->pReal = 0;
71936
+ }
7190771937
}
7190871938
}
7190971939
return rc;
7191071940
}
7191171941
@@ -72565,10 +72595,19 @@
7256572595
** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
7256672596
**
7256772597
** The result of random()%5 in the GROUP BY clause is probably different
7256872598
** from the result in the result-set. We might fix this someday. Or
7256972599
** then again, we might not...
72600
+**
72601
+** If the reference is followed by a COLLATE operator, then make sure
72602
+** the COLLATE operator is preserved. For example:
72603
+**
72604
+** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
72605
+**
72606
+** Should be transformed into:
72607
+**
72608
+** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
7257072609
**
7257172610
** The nSubquery parameter specifies how many levels of subquery the
7257272611
** alias is removed from the original expression. The usually value is
7257372612
** zero but it might be more if the alias is contained within a subquery
7257472613
** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
@@ -72589,45 +72628,40 @@
7258972628
assert( iCol>=0 && iCol<pEList->nExpr );
7259072629
pOrig = pEList->a[iCol].pExpr;
7259172630
assert( pOrig!=0 );
7259272631
assert( pOrig->flags & EP_Resolved );
7259372632
db = pParse->db;
72633
+ pDup = sqlite3ExprDup(db, pOrig, 0);
72634
+ if( pDup==0 ) return;
7259472635
if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
72595
- pDup = sqlite3ExprDup(db, pOrig, 0);
7259672636
incrAggFunctionDepth(pDup, nSubquery);
7259772637
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
7259872638
if( pDup==0 ) return;
7259972639
if( pEList->a[iCol].iAlias==0 ){
7260072640
pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
7260172641
}
7260272642
pDup->iTable = pEList->a[iCol].iAlias;
72603
- }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
72604
- pDup = sqlite3ExprDup(db, pOrig, 0);
72605
- if( pDup==0 ) return;
72606
- }else{
72607
- char *zToken = pOrig->u.zToken;
72608
- assert( zToken!=0 );
72609
- pOrig->u.zToken = 0;
72610
- pDup = sqlite3ExprDup(db, pOrig, 0);
72611
- pOrig->u.zToken = zToken;
72612
- if( pDup==0 ) return;
72613
- assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
72614
- pDup->flags2 |= EP2_MallocedToken;
72615
- pDup->u.zToken = sqlite3DbStrDup(db, zToken);
72616
- }
72617
- if( pExpr->flags & EP_ExpCollate ){
72618
- pDup->pColl = pExpr->pColl;
72619
- pDup->flags |= EP_ExpCollate;
72643
+ }
72644
+ if( pExpr->op==TK_COLLATE ){
72645
+ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
7262072646
}
7262172647
7262272648
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
7262372649
** prevents ExprDelete() from deleting the Expr structure itself,
7262472650
** allowing it to be repopulated by the memcpy() on the following line.
72651
+ ** The pExpr->u.zToken might point into memory that will be freed by the
72652
+ ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
72653
+ ** make a copy of the token before doing the sqlite3DbFree().
7262572654
*/
7262672655
ExprSetProperty(pExpr, EP_Static);
7262772656
sqlite3ExprDelete(db, pExpr);
7262872657
memcpy(pExpr, pDup, sizeof(*pExpr));
72658
+ if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
72659
+ assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
72660
+ pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
72661
+ pExpr->flags2 |= EP2_MallocedToken;
72662
+ }
7262972663
sqlite3DbFree(db, pDup);
7263072664
}
7263172665
7263272666
7263372667
/*
@@ -72644,10 +72678,39 @@
7264472678
}
7264572679
}
7264672680
return 0;
7264772681
}
7264872682
72683
+/*
72684
+** Subqueries stores the original database, table and column names for their
72685
+** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN".
72686
+** Check to see if the zSpan given to this routine matches the zDb, zTab,
72687
+** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will
72688
+** match anything.
72689
+*/
72690
+SQLITE_PRIVATE int sqlite3MatchSpanName(
72691
+ const char *zSpan,
72692
+ const char *zCol,
72693
+ const char *zTab,
72694
+ const char *zDb
72695
+){
72696
+ int n;
72697
+ for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72698
+ if( zDb && sqlite3StrNICmp(zSpan, zDb, n)!=0 ){
72699
+ return 0;
72700
+ }
72701
+ zSpan += n+1;
72702
+ for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72703
+ if( zTab && sqlite3StrNICmp(zSpan, zTab, n)!=0 ){
72704
+ return 0;
72705
+ }
72706
+ zSpan += n+1;
72707
+ if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){
72708
+ return 0;
72709
+ }
72710
+ return 1;
72711
+}
7264972712
7265072713
/*
7265172714
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
7265272715
** that name in the set of source tables in pSrcList and make the pExpr
7265372716
** expression node refer back to that source column. The following changes
@@ -72699,44 +72762,63 @@
7269972762
7270072763
/* Initialize the node to no-match */
7270172764
pExpr->iTable = -1;
7270272765
pExpr->pTab = 0;
7270372766
ExprSetIrreducible(pExpr);
72767
+
72768
+ /* Translate the schema name in zDb into a pointer to the corresponding
72769
+ ** schema. If not found, pSchema will remain NULL and nothing will match
72770
+ ** resulting in an appropriate error message toward the end of this routine
72771
+ */
72772
+ if( zDb ){
72773
+ for(i=0; i<db->nDb; i++){
72774
+ assert( db->aDb[i].zName );
72775
+ if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
72776
+ pSchema = db->aDb[i].pSchema;
72777
+ break;
72778
+ }
72779
+ }
72780
+ }
7270472781
7270572782
/* Start at the inner-most context and move outward until a match is found */
7270672783
while( pNC && cnt==0 ){
7270772784
ExprList *pEList;
7270872785
SrcList *pSrcList = pNC->pSrcList;
7270972786
7271072787
if( pSrcList ){
7271172788
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
7271272789
Table *pTab;
72713
- int iDb;
7271472790
Column *pCol;
7271572791
7271672792
pTab = pItem->pTab;
7271772793
assert( pTab!=0 && pTab->zName!=0 );
72718
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
7271972794
assert( pTab->nCol>0 );
72795
+ if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
72796
+ ExprList *pEList = pItem->pSelect->pEList;
72797
+ int hit = 0;
72798
+ for(j=0; j<pEList->nExpr; j++){
72799
+ if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
72800
+ cnt++;
72801
+ cntTab = 2;
72802
+ pMatch = pItem;
72803
+ pExpr->iColumn = j;
72804
+ hit = 1;
72805
+ }
72806
+ }
72807
+ if( hit || zTab==0 ) continue;
72808
+ }
72809
+ if( zDb && pTab->pSchema!=pSchema ){
72810
+ continue;
72811
+ }
7272072812
if( zTab ){
72721
- if( pItem->zAlias ){
72722
- char *zTabName = pItem->zAlias;
72723
- if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
72724
- }else{
72725
- char *zTabName = pTab->zName;
72726
- if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){
72727
- continue;
72728
- }
72729
- if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
72730
- continue;
72731
- }
72813
+ const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
72814
+ assert( zTabName!=0 );
72815
+ if( sqlite3StrICmp(zTabName, zTab)!=0 ){
72816
+ continue;
7273272817
}
7273372818
}
7273472819
if( 0==(cntTab++) ){
72735
- pExpr->iTable = pItem->iCursor;
72736
- pExpr->pTab = pTab;
72737
- pSchema = pTab->pSchema;
7273872820
pMatch = pItem;
7273972821
}
7274072822
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
7274172823
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
7274272824
/* If there has been exactly one prior match and this match
@@ -72746,21 +72828,23 @@
7274672828
if( cnt==1 ){
7274772829
if( pItem->jointype & JT_NATURAL ) continue;
7274872830
if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
7274972831
}
7275072832
cnt++;
72751
- pExpr->iTable = pItem->iCursor;
72752
- pExpr->pTab = pTab;
7275372833
pMatch = pItem;
72754
- pSchema = pTab->pSchema;
7275572834
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
7275672835
pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
7275772836
break;
7275872837
}
7275972838
}
7276072839
}
72761
- }
72840
+ if( pMatch ){
72841
+ pExpr->iTable = pMatch->iCursor;
72842
+ pExpr->pTab = pMatch->pTab;
72843
+ pSchema = pExpr->pTab->pSchema;
72844
+ }
72845
+ } /* if( pSrcList ) */
7276272846
7276372847
#ifndef SQLITE_OMIT_TRIGGER
7276472848
/* If we have not already resolved the name, then maybe
7276572849
** it is a new.* or old.* trigger argument reference
7276672850
*/
@@ -73055,42 +73139,43 @@
7305573139
int wrong_num_args = 0; /* True if wrong number of arguments */
7305673140
int is_agg = 0; /* True if is an aggregate function */
7305773141
int auth; /* Authorization to use the function */
7305873142
int nId; /* Number of characters in function name */
7305973143
const char *zId; /* The function name. */
73060
- FuncDef *pDef; /* Information about the function */
7306173144
u8 enc = ENC(pParse->db); /* The database encoding */
7306273145
7306373146
testcase( pExpr->op==TK_CONST_FUNC );
7306473147
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
7306573148
zId = pExpr->u.zToken;
7306673149
nId = sqlite3Strlen30(zId);
73067
- pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
73068
- if( pDef==0 ){
73069
- pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
73070
- if( pDef==0 ){
73071
- no_such_func = 1;
73072
- }else{
73073
- wrong_num_args = 1;
73074
- }
73075
- }else{
73076
- is_agg = pDef->xFunc==0;
73077
- }
73078
-#ifndef SQLITE_OMIT_AUTHORIZATION
73079
- if( pDef ){
73080
- auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
73081
- if( auth!=SQLITE_OK ){
73082
- if( auth==SQLITE_DENY ){
73083
- sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
73084
- pDef->zName);
73085
- pNC->nErr++;
73086
- }
73087
- pExpr->op = TK_NULL;
73088
- return WRC_Prune;
73089
- }
73090
- }
73091
-#endif
73150
+ if( pParse->db->init.busy==0 ){
73151
+ FuncDef *pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
73152
+ if( pDef==0 ){
73153
+ pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
73154
+ if( pDef==0 ){
73155
+ no_such_func = 1;
73156
+ }else{
73157
+ wrong_num_args = 1;
73158
+ }
73159
+ }else{
73160
+ is_agg = pDef->xFunc==0;
73161
+ }
73162
+#ifndef SQLITE_OMIT_AUTHORIZATION
73163
+ if( pDef ){
73164
+ auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
73165
+ if( auth!=SQLITE_OK ){
73166
+ if( auth==SQLITE_DENY ){
73167
+ sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
73168
+ pDef->zName);
73169
+ pNC->nErr++;
73170
+ }
73171
+ pExpr->op = TK_NULL;
73172
+ return WRC_Prune;
73173
+ }
73174
+ }
73175
+#endif
73176
+ }
7309273177
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
7309373178
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
7309473179
pNC->nErr++;
7309573180
is_agg = 0;
7309673181
}else if( no_such_func ){
@@ -73310,11 +73395,11 @@
7331073395
assert( pEList!=0 );
7331173396
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
7331273397
int iCol = -1;
7331373398
Expr *pE, *pDup;
7331473399
if( pItem->done ) continue;
73315
- pE = pItem->pExpr;
73400
+ pE = sqlite3ExprSkipCollate(pItem->pExpr);
7331673401
if( sqlite3ExprIsInteger(pE, &iCol) ){
7331773402
if( iCol<=0 || iCol>pEList->nExpr ){
7331873403
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
7331973404
return 1;
7332073405
}
@@ -73328,18 +73413,24 @@
7332873413
}
7332973414
sqlite3ExprDelete(db, pDup);
7333073415
}
7333173416
}
7333273417
if( iCol>0 ){
73333
- CollSeq *pColl = pE->pColl;
73334
- int flags = pE->flags & EP_ExpCollate;
73418
+ /* Convert the ORDER BY term into an integer column number iCol,
73419
+ ** taking care to preserve the COLLATE clause if it exists */
73420
+ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
73421
+ if( pNew==0 ) return 1;
73422
+ pNew->flags |= EP_IntValue;
73423
+ pNew->u.iValue = iCol;
73424
+ if( pItem->pExpr==pE ){
73425
+ pItem->pExpr = pNew;
73426
+ }else{
73427
+ assert( pItem->pExpr->op==TK_COLLATE );
73428
+ assert( pItem->pExpr->pLeft==pE );
73429
+ pItem->pExpr->pLeft = pNew;
73430
+ }
7333573431
sqlite3ExprDelete(db, pE);
73336
- pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
73337
- if( pE==0 ) return 1;
73338
- pE->pColl = pColl;
73339
- pE->flags |= EP_IntValue | flags;
73340
- pE->u.iValue = iCol;
7334173432
pItem->iOrderByCol = (u16)iCol;
7334273433
pItem->done = 1;
7334373434
}else{
7334473435
moreToDo = 1;
7334573436
}
@@ -73440,15 +73531,15 @@
7344073531
** sqlite3ResolveOrderGroupBy() will convert the expression to a
7344173532
** copy of the iCol-th result-set expression. */
7344273533
pItem->iOrderByCol = (u16)iCol;
7344373534
continue;
7344473535
}
73445
- if( sqlite3ExprIsInteger(pE, &iCol) ){
73536
+ if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
7344673537
/* The ORDER BY term is an integer constant. Again, set the column
7344773538
** number so that sqlite3ResolveOrderGroupBy() will convert the
7344873539
** order-by term to a copy of the result-set expression */
73449
- if( iCol<1 ){
73540
+ if( iCol<1 || iCol>0xffff ){
7345073541
resolveOutOfRangeError(pParse, zType, i+1, nResult);
7345173542
return 1;
7345273543
}
7345373544
pItem->iOrderByCol = (u16)iCol;
7345473545
continue;
@@ -73521,27 +73612,10 @@
7352173612
if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
7352273613
sqlite3ResolveExprNames(&sNC, p->pOffset) ){
7352373614
return WRC_Abort;
7352473615
}
7352573616
73526
- /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
73527
- ** resolve the result-set expression list.
73528
- */
73529
- sNC.ncFlags = NC_AllowAgg;
73530
- sNC.pSrcList = p->pSrc;
73531
- sNC.pNext = pOuterNC;
73532
-
73533
- /* Resolve names in the result set. */
73534
- pEList = p->pEList;
73535
- assert( pEList!=0 );
73536
- for(i=0; i<pEList->nExpr; i++){
73537
- Expr *pX = pEList->a[i].pExpr;
73538
- if( sqlite3ResolveExprNames(&sNC, pX) ){
73539
- return WRC_Abort;
73540
- }
73541
- }
73542
-
7354373617
/* Recursively resolve names in all subqueries
7354473618
*/
7354573619
for(i=0; i<p->pSrc->nSrc; i++){
7354673620
struct SrcList_item *pItem = &p->pSrc->a[i];
7354773621
if( pItem->pSelect ){
@@ -73564,10 +73638,27 @@
7356473638
for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
7356573639
assert( pItem->isCorrelated==0 && nRef<=0 );
7356673640
pItem->isCorrelated = (nRef!=0);
7356773641
}
7356873642
}
73643
+
73644
+ /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
73645
+ ** resolve the result-set expression list.
73646
+ */
73647
+ sNC.ncFlags = NC_AllowAgg;
73648
+ sNC.pSrcList = p->pSrc;
73649
+ sNC.pNext = pOuterNC;
73650
+
73651
+ /* Resolve names in the result set. */
73652
+ pEList = p->pEList;
73653
+ assert( pEList!=0 );
73654
+ for(i=0; i<pEList->nExpr; i++){
73655
+ Expr *pX = pEList->a[i].pExpr;
73656
+ if( sqlite3ResolveExprNames(&sNC, pX) ){
73657
+ return WRC_Abort;
73658
+ }
73659
+ }
7356973660
7357073661
/* If there are no aggregate functions in the result-set, and no GROUP BY
7357173662
** expression, do not allow aggregates in any of the other expressions.
7357273663
*/
7357373664
assert( (p->selFlags & SF_Aggregate)==0 );
@@ -73798,11 +73889,13 @@
7379873889
** SELECT * FROM t1 WHERE a;
7379973890
** SELECT a AS b FROM t1 WHERE b;
7380073891
** SELECT * FROM t1 WHERE (select a from t1);
7380173892
*/
7380273893
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
73803
- int op = pExpr->op;
73894
+ int op;
73895
+ pExpr = sqlite3ExprSkipCollate(pExpr);
73896
+ op = pExpr->op;
7380473897
if( op==TK_SELECT ){
7380573898
assert( pExpr->flags&EP_xIsSelect );
7380673899
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
7380773900
}
7380873901
#ifndef SQLITE_OMIT_CAST
@@ -73823,70 +73916,98 @@
7382373916
}
7382473917
return pExpr->affinity;
7382573918
}
7382673919
7382773920
/*
73828
-** Set the explicit collating sequence for an expression to the
73829
-** collating sequence supplied in the second argument.
73830
-*/
73831
-SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){
73832
- if( pExpr && pColl ){
73833
- pExpr->pColl = pColl;
73834
- pExpr->flags |= EP_ExpCollate;
73835
- }
73836
- return pExpr;
73837
-}
73838
-
73839
-/*
73840
-** Set the collating sequence for expression pExpr to be the collating
73841
-** sequence named by pToken. Return a pointer to the revised expression.
73842
-** The collating sequence is marked as "explicit" using the EP_ExpCollate
73843
-** flag. An explicit collating sequence will override implicit
73844
-** collating sequences.
73845
-*/
73846
-SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){
73847
- char *zColl = 0; /* Dequoted name of collation sequence */
73848
- CollSeq *pColl;
73849
- sqlite3 *db = pParse->db;
73850
- zColl = sqlite3NameFromToken(db, pCollName);
73851
- pColl = sqlite3LocateCollSeq(pParse, zColl);
73852
- sqlite3ExprSetColl(pExpr, pColl);
73853
- sqlite3DbFree(db, zColl);
73854
- return pExpr;
73855
-}
73856
-
73857
-/*
73858
-** Return the default collation sequence for the expression pExpr. If
73859
-** there is no default collation type, return 0.
73860
-*/
73861
-SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
73862
- CollSeq *pColl = 0;
73863
- Expr *p = pExpr;
73864
- while( p ){
73865
- int op;
73866
- pColl = p->pColl;
73867
- if( pColl ) break;
73868
- op = p->op;
73869
- if( p->pTab!=0 && (
73870
- op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
73871
- )){
73872
- /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
73873
- ** a TK_COLUMN but was previously evaluated and cached in a register */
73874
- const char *zColl;
73875
- int j = p->iColumn;
73876
- if( j>=0 ){
73877
- sqlite3 *db = pParse->db;
73878
- zColl = p->pTab->aCol[j].zColl;
73879
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
73880
- pExpr->pColl = pColl;
73881
- }
73882
- break;
73883
- }
73884
- if( op!=TK_CAST && op!=TK_UPLUS ){
73885
- break;
73886
- }
73887
- p = p->pLeft;
73921
+** Set the collating sequence for expression pExpr to be the collating
73922
+** sequence named by pToken. Return a pointer to a new Expr node that
73923
+** implements the COLLATE operator.
73924
+**
73925
+** If a memory allocation error occurs, that fact is recorded in pParse->db
73926
+** and the pExpr parameter is returned unchanged.
73927
+*/
73928
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
73929
+ if( pCollName->n>0 ){
73930
+ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
73931
+ if( pNew ){
73932
+ pNew->pLeft = pExpr;
73933
+ pNew->flags |= EP_Collate;
73934
+ pExpr = pNew;
73935
+ }
73936
+ }
73937
+ return pExpr;
73938
+}
73939
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
73940
+ Token s;
73941
+ assert( zC!=0 );
73942
+ s.z = zC;
73943
+ s.n = sqlite3Strlen30(s.z);
73944
+ return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
73945
+}
73946
+
73947
+/*
73948
+** Skip over any TK_COLLATE and/or TK_AS operators at the root of
73949
+** an expression.
73950
+*/
73951
+SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
73952
+ while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
73953
+ pExpr = pExpr->pLeft;
73954
+ }
73955
+ return pExpr;
73956
+}
73957
+
73958
+/*
73959
+** Return the collation sequence for the expression pExpr. If
73960
+** there is no defined collating sequence, return NULL.
73961
+**
73962
+** The collating sequence might be determined by a COLLATE operator
73963
+** or by the presence of a column with a defined collating sequence.
73964
+** COLLATE operators take first precedence. Left operands take
73965
+** precedence over right operands.
73966
+*/
73967
+SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
73968
+ sqlite3 *db = pParse->db;
73969
+ CollSeq *pColl = 0;
73970
+ Expr *p = pExpr;
73971
+ while( p ){
73972
+ int op = p->op;
73973
+ if( op==TK_CAST || op==TK_UPLUS ){
73974
+ p = p->pLeft;
73975
+ continue;
73976
+ }
73977
+ assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
73978
+ if( op==TK_COLLATE ){
73979
+ if( db->init.busy ){
73980
+ /* Do not report errors when parsing while the schema */
73981
+ pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0);
73982
+ }else{
73983
+ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
73984
+ }
73985
+ break;
73986
+ }
73987
+ if( p->pTab!=0
73988
+ && (op==TK_AGG_COLUMN || op==TK_COLUMN
73989
+ || op==TK_REGISTER || op==TK_TRIGGER)
73990
+ ){
73991
+ /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
73992
+ ** a TK_COLUMN but was previously evaluated and cached in a register */
73993
+ int j = p->iColumn;
73994
+ if( j>=0 ){
73995
+ const char *zColl = p->pTab->aCol[j].zColl;
73996
+ pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
73997
+ }
73998
+ break;
73999
+ }
74000
+ if( p->flags & EP_Collate ){
74001
+ if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
74002
+ p = p->pLeft;
74003
+ }else{
74004
+ p = p->pRight;
74005
+ }
74006
+ }else{
74007
+ break;
74008
+ }
7388874009
}
7388974010
if( sqlite3CheckCollSeq(pParse, pColl) ){
7389074011
pColl = 0;
7389174012
}
7389274013
return pColl;
@@ -73986,16 +74107,14 @@
7398674107
Expr *pLeft,
7398774108
Expr *pRight
7398874109
){
7398974110
CollSeq *pColl;
7399074111
assert( pLeft );
73991
- if( pLeft->flags & EP_ExpCollate ){
73992
- assert( pLeft->pColl );
73993
- pColl = pLeft->pColl;
73994
- }else if( pRight && pRight->flags & EP_ExpCollate ){
73995
- assert( pRight->pColl );
73996
- pColl = pRight->pColl;
74112
+ if( pLeft->flags & EP_Collate ){
74113
+ pColl = sqlite3ExprCollSeq(pParse, pLeft);
74114
+ }else if( pRight && (pRight->flags & EP_Collate)!=0 ){
74115
+ pColl = sqlite3ExprCollSeq(pParse, pRight);
7399774116
}else{
7399874117
pColl = sqlite3ExprCollSeq(pParse, pLeft);
7399974118
if( !pColl ){
7400074119
pColl = sqlite3ExprCollSeq(pParse, pRight);
7400174120
}
@@ -74221,21 +74340,15 @@
7422174340
sqlite3ExprDelete(db, pLeft);
7422274341
sqlite3ExprDelete(db, pRight);
7422374342
}else{
7422474343
if( pRight ){
7422574344
pRoot->pRight = pRight;
74226
- if( pRight->flags & EP_ExpCollate ){
74227
- pRoot->flags |= EP_ExpCollate;
74228
- pRoot->pColl = pRight->pColl;
74229
- }
74345
+ pRoot->flags |= EP_Collate & pRight->flags;
7423074346
}
7423174347
if( pLeft ){
7423274348
pRoot->pLeft = pLeft;
74233
- if( pLeft->flags & EP_ExpCollate ){
74234
- pRoot->flags |= EP_ExpCollate;
74235
- pRoot->pColl = pLeft->pColl;
74236
- }
74349
+ pRoot->flags |= EP_Collate & pLeft->flags;
7423774350
}
7423874351
exprSetHeight(pRoot);
7423974352
}
7424074353
}
7424174354
@@ -74489,11 +74602,11 @@
7448974602
}else{
7449074603
assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
7449174604
assert( !ExprHasProperty(p, EP_FromJoin) );
7449274605
assert( (p->flags2 & EP2_MallocedToken)==0 );
7449374606
assert( (p->flags2 & EP2_Irreducible)==0 );
74494
- if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
74607
+ if( p->pLeft || p->pRight || p->x.pList ){
7449574608
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
7449674609
}else{
7449774610
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
7449874611
}
7449974612
}
@@ -76513,10 +76626,11 @@
7651376626
sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
7651476627
sqlite3ReleaseTempReg(pParse, r3);
7651576628
sqlite3ReleaseTempReg(pParse, r4);
7651676629
break;
7651776630
}
76631
+ case TK_COLLATE:
7651876632
case TK_UPLUS: {
7651976633
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
7652076634
break;
7652176635
}
7652276636
@@ -76881,10 +76995,16 @@
7688176995
case TK_UPLUS: zUniOp = "UPLUS"; break;
7688276996
case TK_BITNOT: zUniOp = "BITNOT"; break;
7688376997
case TK_NOT: zUniOp = "NOT"; break;
7688476998
case TK_ISNULL: zUniOp = "ISNULL"; break;
7688576999
case TK_NOTNULL: zUniOp = "NOTNULL"; break;
77000
+
77001
+ case TK_COLLATE: {
77002
+ sqlite3ExplainExpr(pOut, pExpr->pLeft);
77003
+ sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
77004
+ break;
77005
+ }
7688677006
7688777007
case TK_AGG_FUNCTION:
7688877008
case TK_CONST_FUNC:
7688977009
case TK_FUNCTION: {
7689077010
ExprList *pFarg; /* List of function arguments */
@@ -77019,10 +77139,16 @@
7701977139
for(i=0; i<pList->nExpr; i++){
7702077140
sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
7702177141
sqlite3ExplainPush(pOut);
7702277142
sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
7702377143
sqlite3ExplainPop(pOut);
77144
+ if( pList->a[i].zName ){
77145
+ sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
77146
+ }
77147
+ if( pList->a[i].bSpanIsTab ){
77148
+ sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
77149
+ }
7702477150
if( i<pList->nExpr-1 ){
7702577151
sqlite3ExplainNL(pOut);
7702677152
}
7702777153
}
7702877154
sqlite3ExplainPop(pOut);
@@ -77100,10 +77226,13 @@
7710077226
switch( pExpr->op ){
7710177227
case TK_IN:
7710277228
case TK_REGISTER: {
7710377229
return WRC_Prune;
7710477230
}
77231
+ case TK_COLLATE: {
77232
+ return WRC_Continue;
77233
+ }
7710577234
case TK_FUNCTION:
7710677235
case TK_AGG_FUNCTION:
7710777236
case TK_CONST_FUNC: {
7710877237
/* The arguments to a function have a fixed destination.
7710977238
** Mark them this way to avoid generated unneeded OP_SCopy
@@ -77121,13 +77250,15 @@
7712177250
break;
7712277251
}
7712377252
}
7712477253
if( isAppropriateForFactoring(pExpr) ){
7712577254
int r1 = ++pParse->nMem;
77126
- int r2;
77127
- r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
77128
- if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
77255
+ int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
77256
+ /* If r2!=r1, it means that register r1 is never used. That is harmless
77257
+ ** but suboptimal, so we want to know about the situation to fix it.
77258
+ ** Hence the following assert: */
77259
+ assert( r2==r1 );
7712977260
pExpr->op2 = pExpr->op;
7713077261
pExpr->op = TK_REGISTER;
7713177262
pExpr->iTable = r2;
7713277263
return WRC_Prune;
7713377264
}
@@ -77540,11 +77671,19 @@
7754077671
assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
7754177672
if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
7754277673
return 2;
7754377674
}
7754477675
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
77545
- if( pA->op!=pB->op ) return 2;
77676
+ if( pA->op!=pB->op ){
77677
+ if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
77678
+ return 1;
77679
+ }
77680
+ if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
77681
+ return 1;
77682
+ }
77683
+ return 2;
77684
+ }
7754677685
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
7754777686
if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
7754877687
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
7754977688
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
7755077689
if( ExprHasProperty(pA, EP_IntValue) ){
@@ -77552,15 +77691,13 @@
7755277691
return 2;
7755377692
}
7755477693
}else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
7755577694
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
7755677695
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
77557
- return 2;
77696
+ return pA->op==TK_COLLATE ? 1 : 2;
7755877697
}
7755977698
}
77560
- if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
77561
- if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
7756277699
return 0;
7756377700
}
7756477701
7756577702
/*
7756677703
** Compare two ExprList objects. Return 0 if they are identical and
@@ -83371,14 +83508,12 @@
8337183508
** specified collation sequence names.
8337283509
*/
8337383510
for(i=0; i<pList->nExpr; i++){
8337483511
Expr *pExpr = pList->a[i].pExpr;
8337583512
if( pExpr ){
83376
- CollSeq *pColl = pExpr->pColl;
83377
- /* Either pColl!=0 or there was an OOM failure. But if an OOM
83378
- ** failure we have quit before reaching this point. */
83379
- if( ALWAYS(pColl) ){
83513
+ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
83514
+ if( pColl ){
8338083515
nExtra += (1 + sqlite3Strlen30(pColl->zName));
8338183516
}
8338283517
}
8338383518
}
8338483519
@@ -83437,10 +83572,11 @@
8343783572
*/
8343883573
for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
8343983574
const char *zColName = pListItem->zName;
8344083575
Column *pTabCol;
8344183576
int requestedSortOrder;
83577
+ CollSeq *pColl; /* Collating sequence */
8344283578
char *zColl; /* Collation sequence name */
8344383579
8344483580
for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
8344583581
if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
8344683582
}
@@ -83449,18 +83585,15 @@
8344983585
pTab->zName, zColName);
8345083586
pParse->checkSchema = 1;
8345183587
goto exit_create_index;
8345283588
}
8345383589
pIndex->aiColumn[i] = j;
83454
- /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
83455
- ** the way the "idxlist" non-terminal is constructed by the parser,
83456
- ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
83457
- ** must exist or else there must have been an OOM error. But if there
83458
- ** was an OOM error, we would never reach this point. */
83459
- if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
83590
+ if( pListItem->pExpr
83591
+ && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
83592
+ ){
8346083593
int nColl;
83461
- zColl = pListItem->pExpr->pColl->zName;
83594
+ zColl = pColl->zName;
8346283595
nColl = sqlite3Strlen30(zColl) + 1;
8346383596
assert( nExtra>=nColl );
8346483597
memcpy(zExtra, zColl, nColl);
8346583598
zColl = zExtra;
8346683599
zExtra += nColl;
@@ -87489,11 +87622,11 @@
8748987622
8749087623
/*
8749187624
** A foreign key constraint requires that the key columns in the parent
8749287625
** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
8749387626
** Given that pParent is the parent table for foreign key constraint pFKey,
87494
-** search the schema a unique index on the parent key columns.
87627
+** search the schema for a unique index on the parent key columns.
8749587628
**
8749687629
** If successful, zero is returned. If the parent key is an INTEGER PRIMARY
8749787630
** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx
8749887631
** is set to point to the unique index.
8749987632
**
@@ -87525,11 +87658,11 @@
8752587658
**
8752687659
** then non-zero is returned, and a "foreign key mismatch" error loaded
8752787660
** into pParse. If an OOM error occurs, non-zero is returned and the
8752887661
** pParse->db->mallocFailed flag is set.
8752987662
*/
87530
-static int locateFkeyIndex(
87663
+SQLITE_PRIVATE int sqlite3FkLocateIndex(
8753187664
Parse *pParse, /* Parse context to store any error in */
8753287665
Table *pParent, /* Parent table of FK constraint pFKey */
8753387666
FKey *pFKey, /* Foreign key to find index for */
8753487667
Index **ppIdx, /* OUT: Unique index on parent table */
8753587668
int **paiCol /* OUT: Map of index columns in pFKey */
@@ -87622,11 +87755,13 @@
8762287755
}
8762387756
}
8762487757
8762587758
if( !pIdx ){
8762687759
if( !pParse->disableTriggers ){
87627
- sqlite3ErrorMsg(pParse, "foreign key mismatch");
87760
+ sqlite3ErrorMsg(pParse,
87761
+ "foreign key mismatch - \"%w\" referencing \"%w\"",
87762
+ pFKey->pFrom->zName, pFKey->zTo);
8762887763
}
8762987764
sqlite3DbFree(pParse->db, aiCol);
8763087765
return 1;
8763187766
}
8763287767
@@ -87858,16 +87993,19 @@
8785887993
if( pLeft ){
8785987994
/* Set the collation sequence and affinity of the LHS of each TK_EQ
8786087995
** expression to the parent key column defaults. */
8786187996
if( pIdx ){
8786287997
Column *pCol;
87998
+ const char *zColl;
8786387999
iCol = pIdx->aiColumn[i];
8786488000
pCol = &pTab->aCol[iCol];
8786588001
if( pTab->iPKey==iCol ) iCol = -1;
8786688002
pLeft->iTable = regData+iCol+1;
8786788003
pLeft->affinity = pCol->affinity;
87868
- pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl);
88004
+ zColl = pCol->zColl;
88005
+ if( zColl==0 ) zColl = db->pDfltColl->zName;
88006
+ pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
8786988007
}else{
8787088008
pLeft->iTable = regData;
8787188009
pLeft->affinity = SQLITE_AFF_INTEGER;
8787288010
}
8787388011
}
@@ -88080,11 +88218,11 @@
8808088218
if( pParse->disableTriggers ){
8808188219
pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
8808288220
}else{
8808388221
pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
8808488222
}
88085
- if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
88223
+ if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
8808688224
assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
8808788225
if( !isIgnoreErrors || db->mallocFailed ) return;
8808888226
if( pTo==0 ){
8808988227
/* If isIgnoreErrors is true, then a table is being dropped. In this
8809088228
** case SQLite runs a "DELETE FROM xxx" on the table being dropped
@@ -88160,11 +88298,11 @@
8816088298
/* Inserting a single row into a parent table cannot cause an immediate
8816188299
** foreign key violation. So do nothing in this case. */
8816288300
continue;
8816388301
}
8816488302
88165
- if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
88303
+ if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
8816688304
if( !isIgnoreErrors || db->mallocFailed ) return;
8816788305
continue;
8816888306
}
8816988307
assert( aiCol || pFKey->nCol==1 );
8817088308
@@ -88215,11 +88353,11 @@
8821588353
for(p=pTab->pFKey; p; p=p->pNextFrom){
8821688354
for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
8821788355
}
8821888356
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
8821988357
Index *pIdx = 0;
88220
- locateFkeyIndex(pParse, pTab, p, &pIdx, 0);
88358
+ sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
8822188359
if( pIdx ){
8822288360
for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
8822388361
}
8822488362
}
8822588363
}
@@ -88341,11 +88479,11 @@
8834188479
ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */
8834288480
Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */
8834388481
int i; /* Iterator variable */
8834488482
Expr *pWhen = 0; /* WHEN clause for the trigger */
8834588483
88346
- if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
88484
+ if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
8834788485
assert( aiCol || pFKey->nCol==1 );
8834888486
8834988487
for(i=0; i<pFKey->nCol; i++){
8835088488
Token tOld = { "old", 3 }; /* Literal "old" token */
8835188489
Token tNew = { "new", 3 }; /* Literal "new" token */
@@ -89843,29 +89981,24 @@
8984389981
ExprList *pCheck = pTab->pCheck;
8984489982
pParse->ckBase = regData;
8984589983
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
8984689984
for(i=0; i<pCheck->nExpr; i++){
8984789985
int allOk = sqlite3VdbeMakeLabel(v);
89848
- Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0);
89849
- if( !db->mallocFailed ){
89850
- assert( pDup!=0 );
89851
- sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL);
89852
- if( onError==OE_Ignore ){
89853
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
89854
- }else{
89855
- char *zConsName = pCheck->a[i].zName;
89856
- if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
89857
- if( zConsName ){
89858
- zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
89859
- }else{
89860
- zConsName = 0;
89861
- }
89862
- sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
89863
- }
89864
- sqlite3VdbeResolveLabel(v, allOk);
89865
- }
89866
- sqlite3ExprDelete(db, pDup);
89986
+ sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
89987
+ if( onError==OE_Ignore ){
89988
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
89989
+ }else{
89990
+ char *zConsName = pCheck->a[i].zName;
89991
+ if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
89992
+ if( zConsName ){
89993
+ zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
89994
+ }else{
89995
+ zConsName = 0;
89996
+ }
89997
+ sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
89998
+ }
89999
+ sqlite3VdbeResolveLabel(v, allOk);
8986790000
}
8986890001
}
8986990002
#endif /* !defined(SQLITE_OMIT_CHECK) */
8987090003
8987190004
/* If we have an INTEGER PRIMARY KEY, make sure the primary key
@@ -92686,13 +92819,15 @@
9268692819
if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
9268792820
Table *pTab;
9268892821
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
9268992822
pTab = sqlite3FindTable(db, zRight, zDb);
9269092823
if( pTab ){
92691
- int i;
92824
+ int i, k;
9269292825
int nHidden = 0;
9269392826
Column *pCol;
92827
+ Index *pPk;
92828
+ for(pPk=pTab->pIndex; pPk && pPk->autoIndex!=2; pPk=pPk->pNext){}
9269492829
sqlite3VdbeSetNumCols(v, 6);
9269592830
pParse->nMem = 6;
9269692831
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
9269792832
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
9269892833
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
@@ -92713,12 +92848,18 @@
9271392848
if( pCol->zDflt ){
9271492849
sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
9271592850
}else{
9271692851
sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
9271792852
}
92718
- sqlite3VdbeAddOp2(v, OP_Integer,
92719
- (pCol->colFlags&COLFLAG_PRIMKEY)!=0, 6);
92853
+ if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
92854
+ k = 0;
92855
+ }else if( pPk==0 ){
92856
+ k = 1;
92857
+ }else{
92858
+ for(k=1; ALWAYS(k<=pTab->nCol) && pPk->aiColumn[k-1]!=i; k++){}
92859
+ }
92860
+ sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
9272092861
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
9272192862
}
9272292863
}
9272392864
}else
9272492865
@@ -92849,10 +92990,124 @@
9284992990
++i;
9285092991
pFK = pFK->pNextFrom;
9285192992
}
9285292993
}
9285392994
}
92995
+ }else
92996
+#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
92997
+
92998
+#ifndef SQLITE_OMIT_FOREIGN_KEY
92999
+ if( sqlite3StrICmp(zLeft, "foreign_key_check")==0 ){
93000
+ FKey *pFK; /* A foreign key constraint */
93001
+ Table *pTab; /* Child table contain "REFERENCES" keyword */
93002
+ Table *pParent; /* Parent table that child points to */
93003
+ Index *pIdx; /* Index in the parent table */
93004
+ int i; /* Loop counter: Foreign key number for pTab */
93005
+ int j; /* Loop counter: Field of the foreign key */
93006
+ HashElem *k; /* Loop counter: Next table in schema */
93007
+ int x; /* result variable */
93008
+ int regResult; /* 3 registers to hold a result row */
93009
+ int regKey; /* Register to hold key for checking the FK */
93010
+ int regRow; /* Registers to hold a row from pTab */
93011
+ int addrTop; /* Top of a loop checking foreign keys */
93012
+ int addrOk; /* Jump here if the key is OK */
93013
+ int *aiCols; /* child to parent column mapping */
93014
+
93015
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
93016
+ regResult = pParse->nMem+1;
93017
+ pParse->nMem += 4;
93018
+ regKey = ++pParse->nMem;
93019
+ regRow = ++pParse->nMem;
93020
+ v = sqlite3GetVdbe(pParse);
93021
+ sqlite3VdbeSetNumCols(v, 4);
93022
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
93023
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC);
93024
+ sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "parent", SQLITE_STATIC);
93025
+ sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "fkid", SQLITE_STATIC);
93026
+ sqlite3CodeVerifySchema(pParse, iDb);
93027
+ k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
93028
+ while( k ){
93029
+ if( zRight ){
93030
+ pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
93031
+ k = 0;
93032
+ }else{
93033
+ pTab = (Table*)sqliteHashData(k);
93034
+ k = sqliteHashNext(k);
93035
+ }
93036
+ if( pTab==0 || pTab->pFKey==0 ) continue;
93037
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
93038
+ if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
93039
+ sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
93040
+ sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName,
93041
+ P4_TRANSIENT);
93042
+ for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
93043
+ pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
93044
+ if( pParent==0 ) break;
93045
+ pIdx = 0;
93046
+ sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
93047
+ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
93048
+ if( x==0 ){
93049
+ if( pIdx==0 ){
93050
+ sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
93051
+ }else{
93052
+ KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
93053
+ sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
93054
+ sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
93055
+ }
93056
+ }else{
93057
+ k = 0;
93058
+ break;
93059
+ }
93060
+ }
93061
+ if( pFK ) break;
93062
+ if( pParse->nTab<i ) pParse->nTab = i;
93063
+ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0);
93064
+ for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
93065
+ pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
93066
+ assert( pParent!=0 );
93067
+ pIdx = 0;
93068
+ aiCols = 0;
93069
+ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
93070
+ assert( x==0 );
93071
+ addrOk = sqlite3VdbeMakeLabel(v);
93072
+ if( pIdx==0 ){
93073
+ int iKey = pFK->aCol[0].iFrom;
93074
+ assert( iKey>=0 && iKey<pTab->nCol );
93075
+ if( iKey!=pTab->iPKey ){
93076
+ sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
93077
+ sqlite3ColumnDefault(v, pTab, iKey, regRow);
93078
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk);
93079
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
93080
+ sqlite3VdbeCurrentAddr(v)+3);
93081
+ }else{
93082
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
93083
+ }
93084
+ sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow);
93085
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
93086
+ sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
93087
+ }else{
93088
+ for(j=0; j<pFK->nCol; j++){
93089
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
93090
+ aiCols ? aiCols[j] : pFK->aCol[0].iFrom, regRow+j);
93091
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk);
93092
+ }
93093
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey);
93094
+ sqlite3VdbeChangeP4(v, -1,
93095
+ sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
93096
+ sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
93097
+ }
93098
+ sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
93099
+ sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0,
93100
+ pFK->zTo, P4_TRANSIENT);
93101
+ sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+3);
93102
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
93103
+ sqlite3VdbeResolveLabel(v, addrOk);
93104
+ sqlite3DbFree(db, aiCols);
93105
+ }
93106
+ sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1);
93107
+ sqlite3VdbeJumpHere(v, addrTop);
93108
+ }
9285493109
}else
9285593110
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
9285693111
9285793112
#ifndef NDEBUG
9285893113
if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
@@ -94308,11 +94563,11 @@
9430894563
SrcList *pSrc, /* the FROM clause -- which tables to scan */
9430994564
Expr *pWhere, /* the WHERE clause */
9431094565
ExprList *pGroupBy, /* the GROUP BY clause */
9431194566
Expr *pHaving, /* the HAVING clause */
9431294567
ExprList *pOrderBy, /* the ORDER BY clause */
94313
- int isDistinct, /* true if the DISTINCT keyword is present */
94568
+ u16 selFlags, /* Flag parameters, such as SF_Distinct */
9431494569
Expr *pLimit, /* LIMIT value. NULL means not used */
9431594570
Expr *pOffset /* OFFSET value. NULL means no offset */
9431694571
){
9431794572
Select *pNew;
9431894573
Select standin;
@@ -94332,11 +94587,11 @@
9433294587
pNew->pSrc = pSrc;
9433394588
pNew->pWhere = pWhere;
9433494589
pNew->pGroupBy = pGroupBy;
9433594590
pNew->pHaving = pHaving;
9433694591
pNew->pOrderBy = pOrderBy;
94337
- pNew->selFlags = isDistinct ? SF_Distinct : 0;
94592
+ pNew->selFlags = selFlags;
9433894593
pNew->op = TK_SELECT;
9433994594
pNew->pLimit = pLimit;
9434094595
pNew->pOffset = pOffset;
9434194596
assert( pOffset==0 || pLimit!=0 );
9434294597
pNew->addrOpenEphm[0] = -1;
@@ -95588,13 +95843,11 @@
9558895843
*paCol = aCol;
9558995844
9559095845
for(i=0, pCol=aCol; i<nCol; i++, pCol++){
9559195846
/* Get an appropriate name for the column
9559295847
*/
95593
- p = pEList->a[i].pExpr;
95594
- assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
95595
- || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
95848
+ p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
9559695849
if( (zName = pEList->a[i].zName)!=0 ){
9559795850
/* If the column contains an "AS <name>" phrase, use <name> as the name */
9559895851
zName = sqlite3DbStrDup(db, zName);
9559995852
}else{
9560095853
Expr *pColExpr = p; /* The expression that is the result column name */
@@ -95628,10 +95881,13 @@
9562895881
*/
9562995882
nName = sqlite3Strlen30(zName);
9563095883
for(j=cnt=0; j<i; j++){
9563195884
if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
9563295885
char *zNewName;
95886
+ int k;
95887
+ for(k=nName-1; k>1 && sqlite3Isdigit(zName[k]); k--){}
95888
+ if( zName[k]==':' ) nName = k;
9563395889
zName[nName] = 0;
9563495890
zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
9563595891
sqlite3DbFree(db, zName);
9563695892
zName = zNewName;
9563795893
j = -1;
@@ -96586,16 +96842,17 @@
9658696842
pKeyMerge->nField = (u16)nOrderBy;
9658796843
pKeyMerge->enc = ENC(db);
9658896844
for(i=0; i<nOrderBy; i++){
9658996845
CollSeq *pColl;
9659096846
Expr *pTerm = pOrderBy->a[i].pExpr;
96591
- if( pTerm->flags & EP_ExpCollate ){
96592
- pColl = pTerm->pColl;
96847
+ if( pTerm->flags & EP_Collate ){
96848
+ pColl = sqlite3ExprCollSeq(pParse, pTerm);
9659396849
}else{
9659496850
pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
96595
- pTerm->flags |= EP_ExpCollate;
96596
- pTerm->pColl = pColl;
96851
+ if( pColl==0 ) pColl = db->pDfltColl;
96852
+ pOrderBy->a[i].pExpr =
96853
+ sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
9659796854
}
9659896855
pKeyMerge->aColl[i] = pColl;
9659996856
pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
9660096857
}
9660196858
}
@@ -96794,10 +97051,11 @@
9679497051
*/
9679597052
sqlite3VdbeResolveLabel(v, labelCmpr);
9679697053
sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
9679797054
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
9679897055
(char*)pKeyMerge, P4_KEYINFO_HANDOFF);
97056
+ sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
9679997057
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
9680097058
9680197059
/* Release temporary registers
9680297060
*/
9680397061
if( regPrev ){
@@ -96861,13 +97119,10 @@
9686197119
}else{
9686297120
Expr *pNew;
9686397121
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
9686497122
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
9686597123
pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
96866
- if( pNew && pExpr->pColl ){
96867
- pNew->pColl = pExpr->pColl;
96868
- }
9686997124
sqlite3ExprDelete(db, pExpr);
9687097125
pExpr = pNew;
9687197126
}
9687297127
}else{
9687397128
pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
@@ -97414,38 +97669,47 @@
9741497669
return 1;
9741597670
}
9741697671
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
9741797672
9741897673
/*
97419
-** Analyze the SELECT statement passed as an argument to see if it
97420
-** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if
97421
-** it is, or 0 otherwise. At present, a query is considered to be
97422
-** a min()/max() query if:
97423
-**
97424
-** 1. There is a single object in the FROM clause.
97425
-**
97426
-** 2. There is a single expression in the result set, and it is
97427
-** either min(x) or max(x), where x is a column reference.
97428
-*/
97429
-static u8 minMaxQuery(Select *p){
97430
- Expr *pExpr;
97431
- ExprList *pEList = p->pEList;
97432
-
97433
- if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
97434
- pExpr = pEList->a[0].pExpr;
97435
- if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
97436
- if( NEVER(ExprHasProperty(pExpr, EP_xIsSelect)) ) return 0;
97437
- pEList = pExpr->x.pList;
97438
- if( pEList==0 || pEList->nExpr!=1 ) return 0;
97439
- if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
97440
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
97441
- if( sqlite3StrICmp(pExpr->u.zToken,"min")==0 ){
97442
- return WHERE_ORDERBY_MIN;
97443
- }else if( sqlite3StrICmp(pExpr->u.zToken,"max")==0 ){
97444
- return WHERE_ORDERBY_MAX;
97445
- }
97446
- return WHERE_ORDERBY_NORMAL;
97674
+** Based on the contents of the AggInfo structure indicated by the first
97675
+** argument, this function checks if the following are true:
97676
+**
97677
+** * the query contains just a single aggregate function,
97678
+** * the aggregate function is either min() or max(), and
97679
+** * the argument to the aggregate function is a column value.
97680
+**
97681
+** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX
97682
+** is returned as appropriate. Also, *ppMinMax is set to point to the
97683
+** list of arguments passed to the aggregate before returning.
97684
+**
97685
+** Or, if the conditions above are not met, *ppMinMax is set to 0 and
97686
+** WHERE_ORDERBY_NORMAL is returned.
97687
+*/
97688
+static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){
97689
+ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
97690
+
97691
+ *ppMinMax = 0;
97692
+ if( pAggInfo->nFunc==1 ){
97693
+ Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */
97694
+ ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */
97695
+
97696
+ assert( pExpr->op==TK_AGG_FUNCTION );
97697
+ if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){
97698
+ const char *zFunc = pExpr->u.zToken;
97699
+ if( sqlite3StrICmp(zFunc, "min")==0 ){
97700
+ eRet = WHERE_ORDERBY_MIN;
97701
+ *ppMinMax = pEList;
97702
+ }else if( sqlite3StrICmp(zFunc, "max")==0 ){
97703
+ eRet = WHERE_ORDERBY_MAX;
97704
+ *ppMinMax = pEList;
97705
+ }
97706
+ }
97707
+ }
97708
+
97709
+ assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 );
97710
+ return eRet;
9744797711
}
9744897712
9744997713
/*
9745097714
** The select statement passed as the first argument is an aggregate query.
9745197715
** The second argment is the associated aggregate-info object. This
@@ -97536,10 +97800,11 @@
9753697800
int i, j, k;
9753797801
SrcList *pTabList;
9753897802
ExprList *pEList;
9753997803
struct SrcList_item *pFrom;
9754097804
sqlite3 *db = pParse->db;
97805
+ Expr *pE, *pRight, *pExpr;
9754197806
9754297807
if( db->mallocFailed ){
9754397808
return WRC_Abort;
9754497809
}
9754597810
if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
@@ -97621,11 +97886,11 @@
9762197886
**
9762297887
** The first loop just checks to see if there are any "*" operators
9762397888
** that need expanding.
9762497889
*/
9762597890
for(k=0; k<pEList->nExpr; k++){
97626
- Expr *pE = pEList->a[k].pExpr;
97891
+ pE = pEList->a[k].pExpr;
9762797892
if( pE->op==TK_ALL ) break;
9762897893
assert( pE->op!=TK_DOT || pE->pRight!=0 );
9762997894
assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
9763097895
if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
9763197896
}
@@ -97639,14 +97904,22 @@
9763997904
ExprList *pNew = 0;
9764097905
int flags = pParse->db->flags;
9764197906
int longNames = (flags & SQLITE_FullColNames)!=0
9764297907
&& (flags & SQLITE_ShortColNames)==0;
9764397908
97909
+ /* When processing FROM-clause subqueries, it is always the case
97910
+ ** that full_column_names=OFF and short_column_names=ON. The
97911
+ ** sqlite3ResultSetOfSelect() routine makes it so. */
97912
+ assert( (p->selFlags & SF_NestedFrom)==0
97913
+ || ((flags & SQLITE_FullColNames)==0 &&
97914
+ (flags & SQLITE_ShortColNames)!=0) );
97915
+
9764497916
for(k=0; k<pEList->nExpr; k++){
97645
- Expr *pE = a[k].pExpr;
97646
- assert( pE->op!=TK_DOT || pE->pRight!=0 );
97647
- if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight->op!=TK_ALL) ){
97917
+ pE = a[k].pExpr;
97918
+ pRight = pE->pRight;
97919
+ assert( pE->op!=TK_DOT || pRight!=0 );
97920
+ if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
9764897921
/* This particular expression does not need to be expanded.
9764997922
*/
9765097923
pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
9765197924
if( pNew ){
9765297925
pNew->a[pNew->nExpr-1].zName = a[k].zName;
@@ -97657,44 +97930,56 @@
9765797930
a[k].pExpr = 0;
9765897931
}else{
9765997932
/* This expression is a "*" or a "TABLE.*" and needs to be
9766097933
** expanded. */
9766197934
int tableSeen = 0; /* Set to 1 when TABLE matches */
97662
- char *zTName; /* text of name of TABLE */
97935
+ char *zTName = 0; /* text of name of TABLE */
9766397936
if( pE->op==TK_DOT ){
9766497937
assert( pE->pLeft!=0 );
9766597938
assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
9766697939
zTName = pE->pLeft->u.zToken;
97667
- }else{
97668
- zTName = 0;
9766997940
}
9767097941
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
9767197942
Table *pTab = pFrom->pTab;
97943
+ Select *pSub = pFrom->pSelect;
9767297944
char *zTabName = pFrom->zAlias;
97945
+ const char *zSchemaName = 0;
97946
+ int iDb;
9767397947
if( zTabName==0 ){
9767497948
zTabName = pTab->zName;
9767597949
}
9767697950
if( db->mallocFailed ) break;
97677
- if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
97678
- continue;
97951
+ if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
97952
+ pSub = 0;
97953
+ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
97954
+ continue;
97955
+ }
97956
+ iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
97957
+ zSchemaName = iDb>=0 ? db->aDb[iDb].zName : "*";
9767997958
}
97680
- tableSeen = 1;
9768197959
for(j=0; j<pTab->nCol; j++){
97682
- Expr *pExpr, *pRight;
9768397960
char *zName = pTab->aCol[j].zName;
9768497961
char *zColname; /* The computed column name */
9768597962
char *zToFree; /* Malloced string that needs to be freed */
9768697963
Token sColname; /* Computed column name as a token */
97964
+
97965
+ assert( zName );
97966
+ if( zTName && pSub
97967
+ && sqlite3MatchSpanName(pSub->pEList->a[j].zSpan, 0, zTName, 0)==0
97968
+ ){
97969
+ continue;
97970
+ }
9768797971
9768897972
/* If a column is marked as 'hidden' (currently only possible
9768997973
** for virtual tables), do not include it in the expanded
9769097974
** result-set list.
9769197975
*/
9769297976
if( IsHiddenColumn(&pTab->aCol[j]) ){
9769397977
assert(IsVirtual(pTab));
9769497978
continue;
9769597979
}
97980
+ tableSeen = 1;
9769697981
9769797982
if( i>0 && zTName==0 ){
9769897983
if( (pFrom->jointype & JT_NATURAL)!=0
9769997984
&& tableAndColumnIndex(pTabList, i, zName, 0, 0)
9770097985
){
@@ -97713,10 +97998,14 @@
9771397998
zToFree = 0;
9771497999
if( longNames || pTabList->nSrc>1 ){
9771598000
Expr *pLeft;
9771698001
pLeft = sqlite3Expr(db, TK_ID, zTabName);
9771798002
pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
98003
+ if( zSchemaName ){
98004
+ pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
98005
+ pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr, 0);
98006
+ }
9771898007
if( longNames ){
9771998008
zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
9772098009
zToFree = zColname;
9772198010
}
9772298011
}else{
@@ -97724,10 +98013,22 @@
9772498013
}
9772598014
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
9772698015
sColname.z = zColname;
9772798016
sColname.n = sqlite3Strlen30(zColname);
9772898017
sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
98018
+ if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
98019
+ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
98020
+ if( pSub ){
98021
+ pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan);
98022
+ testcase( pX->zSpan==0 );
98023
+ }else{
98024
+ pX->zSpan = sqlite3MPrintf(db, "%s.%s.%s",
98025
+ zSchemaName, zTabName, zColname);
98026
+ testcase( pX->zSpan==0 );
98027
+ }
98028
+ pX->bSpanIsTab = 1;
98029
+ }
9772998030
sqlite3DbFree(db, zToFree);
9773098031
}
9773198032
}
9773298033
if( !tableSeen ){
9773398034
if( zTName ){
@@ -98781,15 +99082,21 @@
9878199082
** index or indices to use) should place a different priority on
9878299083
** satisfying the 'ORDER BY' clause than it does in other cases.
9878399084
** Refer to code and comments in where.c for details.
9878499085
*/
9878599086
ExprList *pMinMax = 0;
98786
- u8 flag = minMaxQuery(p);
99087
+ u8 flag = WHERE_ORDERBY_NORMAL;
99088
+
99089
+ assert( p->pGroupBy==0 );
99090
+ assert( flag==0 );
99091
+ if( p->pHaving==0 ){
99092
+ flag = minMaxQuery(&sAggInfo, &pMinMax);
99093
+ }
99094
+ assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) );
99095
+
9878799096
if( flag ){
98788
- assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
98789
- assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 );
98790
- pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
99097
+ pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
9879199098
pDel = pMinMax;
9879299099
if( pMinMax && !db->mallocFailed ){
9879399100
pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
9879499101
pMinMax->a[0].pExpr->op = TK_COLUMN;
9879599102
}
@@ -102673,11 +102980,11 @@
102673102980
#define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */
102674102981
#define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */
102675102982
#define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */
102676102983
#define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
102677102984
#define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
102678
-#define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */
102985
+#define WHERE_IN_ABLE 0x080f1000 /* Able to support an IN operator */
102679102986
#define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
102680102987
#define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
102681102988
#define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
102682102989
#define WHERE_IDX_ONLY 0x00400000 /* Use index only - omit table */
102683102990
#define WHERE_ORDERED 0x00800000 /* Output will appear in correct order */
@@ -102823,11 +103130,11 @@
102823103130
sqlite3DbFree(db, pOld);
102824103131
}
102825103132
pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
102826103133
}
102827103134
pTerm = &pWC->a[idx = pWC->nTerm++];
102828
- pTerm->pExpr = p;
103135
+ pTerm->pExpr = sqlite3ExprSkipCollate(p);
102829103136
pTerm->wtFlags = wtFlags;
102830103137
pTerm->pWC = pWC;
102831103138
pTerm->iParent = -1;
102832103139
return idx;
102833103140
}
@@ -102983,27 +103290,36 @@
102983103290
102984103291
/*
102985103292
** Commute a comparison operator. Expressions of the form "X op Y"
102986103293
** are converted into "Y op X".
102987103294
**
102988
-** If a collation sequence is associated with either the left or right
103295
+** If left/right precendence rules come into play when determining the
103296
+** collating
102989103297
** side of the comparison, it remains associated with the same side after
102990103298
** the commutation. So "Y collate NOCASE op X" becomes
102991
-** "X collate NOCASE op Y". This is because any collation sequence on
103299
+** "X op Y". This is because any collation sequence on
102992103300
** the left hand side of a comparison overrides any collation sequence
102993
-** attached to the right. For the same reason the EP_ExpCollate flag
103301
+** attached to the right. For the same reason the EP_Collate flag
102994103302
** is not commuted.
102995103303
*/
102996103304
static void exprCommute(Parse *pParse, Expr *pExpr){
102997
- u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
102998
- u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
103305
+ u16 expRight = (pExpr->pRight->flags & EP_Collate);
103306
+ u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
102999103307
assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
103000
- pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
103001
- pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
103002
- SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
103003
- pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;
103004
- pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;
103308
+ if( expRight==expLeft ){
103309
+ /* Either X and Y both have COLLATE operator or neither do */
103310
+ if( expRight ){
103311
+ /* Both X and Y have COLLATE operators. Make sure X is always
103312
+ ** used by clearing the EP_Collate flag from Y. */
103313
+ pExpr->pRight->flags &= ~EP_Collate;
103314
+ }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
103315
+ /* Neither X nor Y have COLLATE operators, but X has a non-default
103316
+ ** collating sequence. So add the EP_Collate marker on X to cause
103317
+ ** it to be searched first. */
103318
+ pExpr->pLeft->flags |= EP_Collate;
103319
+ }
103320
+ }
103005103321
SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
103006103322
if( pExpr->op>=TK_GT ){
103007103323
assert( TK_LT==TK_GT+2 );
103008103324
assert( TK_GE==TK_LE+2 );
103009103325
assert( TK_GT>TK_EQ );
@@ -103076,16 +103392,16 @@
103076103392
** it to be useful for optimising expression pX. Store this
103077103393
** value in variable pColl.
103078103394
*/
103079103395
assert(pX->pLeft);
103080103396
pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
103081
- assert(pColl || pParse->nErr);
103397
+ if( pColl==0 ) pColl = pParse->db->pDfltColl;
103082103398
103083103399
for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
103084103400
if( NEVER(j>=pIdx->nColumn) ) return 0;
103085103401
}
103086
- if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
103402
+ if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
103087103403
}
103088103404
return pTerm;
103089103405
}
103090103406
}
103091103407
}
@@ -103600,10 +103916,11 @@
103600103916
return;
103601103917
}
103602103918
pTerm = &pWC->a[idxTerm];
103603103919
pMaskSet = pWC->pMaskSet;
103604103920
pExpr = pTerm->pExpr;
103921
+ assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
103605103922
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
103606103923
op = pExpr->op;
103607103924
if( op==TK_IN ){
103608103925
assert( pExpr->pRight==0 );
103609103926
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
@@ -103626,12 +103943,12 @@
103626103943
pTerm->prereqAll = prereqAll;
103627103944
pTerm->leftCursor = -1;
103628103945
pTerm->iParent = -1;
103629103946
pTerm->eOperator = 0;
103630103947
if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
103631
- Expr *pLeft = pExpr->pLeft;
103632
- Expr *pRight = pExpr->pRight;
103948
+ Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
103949
+ Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
103633103950
if( pLeft->op==TK_COLUMN ){
103634103951
pTerm->leftCursor = pLeft->iTable;
103635103952
pTerm->u.leftColumn = pLeft->iColumn;
103636103953
pTerm->eOperator = operatorMask(op);
103637103954
}
@@ -103655,11 +103972,11 @@
103655103972
}else{
103656103973
pDup = pExpr;
103657103974
pNew = pTerm;
103658103975
}
103659103976
exprCommute(pParse, pDup);
103660
- pLeft = pDup->pLeft;
103977
+ pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
103661103978
pNew->leftCursor = pLeft->iTable;
103662103979
pNew->u.leftColumn = pLeft->iColumn;
103663103980
testcase( (prereqLeft | extraRight) != prereqLeft );
103664103981
pNew->prereqRight = prereqLeft | extraRight;
103665103982
pNew->prereqAll = prereqAll;
@@ -103734,11 +104051,11 @@
103734104051
Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */
103735104052
Expr *pNewExpr1;
103736104053
Expr *pNewExpr2;
103737104054
int idxNew1;
103738104055
int idxNew2;
103739
- CollSeq *pColl; /* Collating sequence to use */
104056
+ Token sCollSeqName; /* Name of collating sequence */
103740104057
103741104058
pLeft = pExpr->x.pList->a[1].pExpr;
103742104059
pStr2 = sqlite3ExprDup(db, pStr1, 0);
103743104060
if( !db->mallocFailed ){
103744104061
u8 c, *pC; /* Last character before the first wildcard */
@@ -103756,20 +104073,23 @@
103756104073
103757104074
c = sqlite3UpperToLower[c];
103758104075
}
103759104076
*pC = c + 1;
103760104077
}
103761
- pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0);
104078
+ sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
104079
+ sCollSeqName.n = 6;
104080
+ pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
103762104081
pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
103763
- sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
103764
- pStr1, 0);
104082
+ sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
104083
+ pStr1, 0);
103765104084
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
103766104085
testcase( idxNew1==0 );
103767104086
exprAnalyze(pSrc, pWC, idxNew1);
104087
+ pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
103768104088
pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
103769
- sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
103770
- pStr2, 0);
104089
+ sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
104090
+ pStr2, 0);
103771104091
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
103772104092
testcase( idxNew2==0 );
103773104093
exprAnalyze(pSrc, pWC, idxNew2);
103774104094
pTerm = &pWC->a[idxTerm];
103775104095
if( isComplete ){
@@ -103883,16 +104203,16 @@
103883104203
){
103884104204
int i;
103885104205
const char *zColl = pIdx->azColl[iCol];
103886104206
103887104207
for(i=0; i<pList->nExpr; i++){
103888
- Expr *p = pList->a[i].pExpr;
104208
+ Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
103889104209
if( p->op==TK_COLUMN
103890104210
&& p->iColumn==pIdx->aiColumn[iCol]
103891104211
&& p->iTable==iBase
103892104212
){
103893
- CollSeq *pColl = sqlite3ExprCollSeq(pParse, p);
104213
+ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
103894104214
if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
103895104215
return i;
103896104216
}
103897104217
}
103898104218
}
@@ -103935,11 +104255,11 @@
103935104255
** matching "col=X" expression and the column is on the same table as pIdx,
103936104256
** set the corresponding bit in variable mask.
103937104257
*/
103938104258
for(i=0; i<pDistinct->nExpr; i++){
103939104259
WhereTerm *pTerm;
103940
- Expr *p = pDistinct->a[i].pExpr;
104260
+ Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
103941104261
if( p->op!=TK_COLUMN ) return 0;
103942104262
pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
103943104263
if( pTerm ){
103944104264
Expr *pX = pTerm->pExpr;
103945104265
CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -103987,11 +104307,11 @@
103987104307
/* If any of the expressions is an IPK column on table iBase, then return
103988104308
** true. Note: The (p->iTable==iBase) part of this test may be false if the
103989104309
** current SELECT is a correlated sub-query.
103990104310
*/
103991104311
for(i=0; i<pDistinct->nExpr; i++){
103992
- Expr *p = pDistinct->a[i].pExpr;
104312
+ Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
103993104313
if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
103994104314
}
103995104315
103996104316
/* Loop through all indices on the table, checking each to see if it makes
103997104317
** the DISTINCT qualifier redundant. It does so if:
@@ -104464,11 +104784,11 @@
104464104784
for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
104465104785
if( pTerm->leftCursor != pSrc->iCursor ) continue;
104466104786
assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104467104787
testcase( pTerm->eOperator==WO_IN );
104468104788
testcase( pTerm->eOperator==WO_ISNULL );
104469
- if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
104789
+ if( pTerm->eOperator & (WO_ISNULL) ) continue;
104470104790
if( pTerm->wtFlags & TERM_VNULL ) continue;
104471104791
nTerm++;
104472104792
}
104473104793
104474104794
/* If the ORDER BY clause contains only columns in the current
@@ -104512,29 +104832,32 @@
104512104832
*(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
104513104833
*(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
104514104834
pUsage;
104515104835
104516104836
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
104837
+ u8 op;
104517104838
if( pTerm->leftCursor != pSrc->iCursor ) continue;
104518104839
assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104519104840
testcase( pTerm->eOperator==WO_IN );
104520104841
testcase( pTerm->eOperator==WO_ISNULL );
104521
- if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
104842
+ if( pTerm->eOperator & (WO_ISNULL) ) continue;
104522104843
if( pTerm->wtFlags & TERM_VNULL ) continue;
104523104844
pIdxCons[j].iColumn = pTerm->u.leftColumn;
104524104845
pIdxCons[j].iTermOffset = i;
104525
- pIdxCons[j].op = (u8)pTerm->eOperator;
104846
+ op = (u8)pTerm->eOperator;
104847
+ if( op==WO_IN ) op = WO_EQ;
104848
+ pIdxCons[j].op = op;
104526104849
/* The direct assignment in the previous line is possible only because
104527104850
** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
104528104851
** following asserts verify this fact. */
104529104852
assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
104530104853
assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
104531104854
assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
104532104855
assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
104533104856
assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
104534104857
assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
104535
- assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
104858
+ assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
104536104859
j++;
104537104860
}
104538104861
for(i=0; i<nOrderBy; i++){
104539104862
Expr *pExpr = pOrderBy->a[i].pExpr;
104540104863
pIdxOrderBy[i].iColumn = pExpr->iColumn;
@@ -104616,10 +104939,11 @@
104616104939
struct sqlite3_index_constraint *pIdxCons;
104617104940
struct sqlite3_index_constraint_usage *pUsage;
104618104941
WhereTerm *pTerm;
104619104942
int i, j;
104620104943
int nOrderBy;
104944
+ int bAllowIN; /* Allow IN optimizations */
104621104945
double rCost;
104622104946
104623104947
/* Make sure wsFlags is initialized to some sane value. Otherwise, if the
104624104948
** malloc in allocateIndexInfo() fails and this function returns leaving
104625104949
** wsFlags in an uninitialized state, the caller may behave unpredictably.
@@ -104650,63 +104974,91 @@
104650104974
** sqlite3ViewGetColumnNames() would have picked up the error.
104651104975
*/
104652104976
assert( pTab->azModuleArg && pTab->azModuleArg[0] );
104653104977
assert( sqlite3GetVTable(pParse->db, pTab) );
104654104978
104655
- /* Set the aConstraint[].usable fields and initialize all
104656
- ** output variables to zero.
104657
- **
104658
- ** aConstraint[].usable is true for constraints where the right-hand
104659
- ** side contains only references to tables to the left of the current
104660
- ** table. In other words, if the constraint is of the form:
104661
- **
104662
- ** column = expr
104663
- **
104664
- ** and we are evaluating a join, then the constraint on column is
104665
- ** only valid if all tables referenced in expr occur to the left
104666
- ** of the table containing column.
104667
- **
104668
- ** The aConstraints[] array contains entries for all constraints
104669
- ** on the current table. That way we only have to compute it once
104670
- ** even though we might try to pick the best index multiple times.
104671
- ** For each attempt at picking an index, the order of tables in the
104672
- ** join might be different so we have to recompute the usable flag
104673
- ** each time.
104674
- */
104675
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
104676
- pUsage = pIdxInfo->aConstraintUsage;
104677
- for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
104678
- j = pIdxCons->iTermOffset;
104679
- pTerm = &pWC->a[j];
104680
- pIdxCons->usable = (pTerm->prereqRight&p->notReady) ? 0 : 1;
104681
- }
104682
- memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
104683
- if( pIdxInfo->needToFreeIdxStr ){
104684
- sqlite3_free(pIdxInfo->idxStr);
104685
- }
104686
- pIdxInfo->idxStr = 0;
104687
- pIdxInfo->idxNum = 0;
104688
- pIdxInfo->needToFreeIdxStr = 0;
104689
- pIdxInfo->orderByConsumed = 0;
104690
- /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
104691
- pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
104692
- nOrderBy = pIdxInfo->nOrderBy;
104693
- if( !p->pOrderBy ){
104694
- pIdxInfo->nOrderBy = 0;
104695
- }
104696
-
104697
- if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
104698
- return;
104699
- }
104700
-
104701
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
104702
- for(i=0; i<pIdxInfo->nConstraint; i++){
104703
- if( pUsage[i].argvIndex>0 ){
104704
- p->cost.used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
104705
- }
104706
- }
104707
-
104979
+ /* Try once or twice. On the first attempt, allow IN optimizations.
104980
+ ** If an IN optimization is accepted by the virtual table xBestIndex
104981
+ ** method, but the pInfo->aConstrainUsage.omit flag is not set, then
104982
+ ** the query will not work because it might allow duplicate rows in
104983
+ ** output. In that case, run the xBestIndex method a second time
104984
+ ** without the IN constraints. Usually this loop only runs once.
104985
+ ** The loop will exit using a "break" statement.
104986
+ */
104987
+ for(bAllowIN=1; 1; bAllowIN--){
104988
+ assert( bAllowIN==0 || bAllowIN==1 );
104989
+
104990
+ /* Set the aConstraint[].usable fields and initialize all
104991
+ ** output variables to zero.
104992
+ **
104993
+ ** aConstraint[].usable is true for constraints where the right-hand
104994
+ ** side contains only references to tables to the left of the current
104995
+ ** table. In other words, if the constraint is of the form:
104996
+ **
104997
+ ** column = expr
104998
+ **
104999
+ ** and we are evaluating a join, then the constraint on column is
105000
+ ** only valid if all tables referenced in expr occur to the left
105001
+ ** of the table containing column.
105002
+ **
105003
+ ** The aConstraints[] array contains entries for all constraints
105004
+ ** on the current table. That way we only have to compute it once
105005
+ ** even though we might try to pick the best index multiple times.
105006
+ ** For each attempt at picking an index, the order of tables in the
105007
+ ** join might be different so we have to recompute the usable flag
105008
+ ** each time.
105009
+ */
105010
+ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105011
+ pUsage = pIdxInfo->aConstraintUsage;
105012
+ for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105013
+ j = pIdxCons->iTermOffset;
105014
+ pTerm = &pWC->a[j];
105015
+ if( (pTerm->prereqRight&p->notReady)==0
105016
+ && (bAllowIN || pTerm->eOperator!=WO_IN)
105017
+ ){
105018
+ pIdxCons->usable = 1;
105019
+ }else{
105020
+ pIdxCons->usable = 0;
105021
+ }
105022
+ }
105023
+ memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
105024
+ if( pIdxInfo->needToFreeIdxStr ){
105025
+ sqlite3_free(pIdxInfo->idxStr);
105026
+ }
105027
+ pIdxInfo->idxStr = 0;
105028
+ pIdxInfo->idxNum = 0;
105029
+ pIdxInfo->needToFreeIdxStr = 0;
105030
+ pIdxInfo->orderByConsumed = 0;
105031
+ /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
105032
+ pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
105033
+ nOrderBy = pIdxInfo->nOrderBy;
105034
+ if( !p->pOrderBy ){
105035
+ pIdxInfo->nOrderBy = 0;
105036
+ }
105037
+
105038
+ if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
105039
+ return;
105040
+ }
105041
+
105042
+ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105043
+ for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105044
+ if( pUsage[i].argvIndex>0 ){
105045
+ j = pIdxCons->iTermOffset;
105046
+ pTerm = &pWC->a[j];
105047
+ p->cost.used |= pTerm->prereqRight;
105048
+ if( pTerm->eOperator==WO_IN && pUsage[i].omit==0 ){
105049
+ /* Do not attempt to use an IN constraint if the virtual table
105050
+ ** says that the equivalent EQ constraint cannot be safely omitted.
105051
+ ** If we do attempt to use such a constraint, some rows might be
105052
+ ** repeated in the output. */
105053
+ break;
105054
+ }
105055
+ }
105056
+ }
105057
+ if( i>=pIdxInfo->nConstraint ) break;
105058
+ }
105059
+
104708105060
/* If there is an ORDER BY clause, and the selected virtual table index
104709105061
** does not satisfy it, increase the cost of the scan accordingly. This
104710105062
** matches the processing for non-virtual tables in bestBtreeIndex().
104711105063
*/
104712105064
rCost = pIdxInfo->estimatedCost;
@@ -105273,11 +105625,11 @@
105273105625
WhereTerm *pConstraint; /* A constraint in the WHERE clause */
105274105626
105275105627
/* If the next term of the ORDER BY clause refers to anything other than
105276105628
** a column in the "base" table, then this index will not be of any
105277105629
** further use in handling the ORDER BY. */
105278
- pOBExpr = pOBItem->pExpr;
105630
+ pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr);
105279105631
if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
105280105632
break;
105281105633
}
105282105634
105283105635
/* Find column number and collating sequence for the next entry
@@ -105299,11 +105651,11 @@
105299105651
/* Check to see if the column number and collating sequence of the
105300105652
** index match the column number and collating sequence of the ORDER BY
105301105653
** clause entry. Set isMatch to 1 if they both match. */
105302105654
if( pOBExpr->iColumn==iColumn ){
105303105655
if( zColl ){
105304
- pColl = sqlite3ExprCollSeq(pParse, pOBExpr);
105656
+ pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr);
105305105657
if( !pColl ) pColl = db->pDfltColl;
105306105658
isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
105307105659
}else{
105308105660
isMatch = 1;
105309105661
}
@@ -105440,10 +105792,15 @@
105440105792
int idxEqTermMask; /* Index mask of valid equality operators */
105441105793
Index sPk; /* A fake index object for the primary key */
105442105794
tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
105443105795
int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
105444105796
int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */
105797
+ int nPriorSat; /* ORDER BY terms satisfied by outer loops */
105798
+ int nOrderBy; /* Number of ORDER BY terms */
105799
+ char bSortInit; /* Initializer for bSort in inner loop */
105800
+ char bDistInit; /* Initializer for bDist in inner loop */
105801
+
105445105802
105446105803
/* Initialize the cost to a worst-case value */
105447105804
memset(&p->cost, 0, sizeof(p->cost));
105448105805
p->cost.rCost = SQLITE_BIG_DBL;
105449105806
@@ -105488,10 +105845,21 @@
105488105845
WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
105489105846
);
105490105847
eqTermMask = WO_EQ|WO_IN;
105491105848
pIdx = 0;
105492105849
}
105850
+
105851
+ nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
105852
+ if( p->i ){
105853
+ nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
105854
+ bSortInit = nPriorSat<nOrderBy;
105855
+ bDistInit = 0;
105856
+ }else{
105857
+ nPriorSat = 0;
105858
+ bSortInit = nOrderBy>0;
105859
+ bDistInit = p->pDistinct!=0;
105860
+ }
105493105861
105494105862
/* Loop over all indices looking for the best one to use
105495105863
*/
105496105864
for(; pProbe; pIdx=pProbe=pProbe->pNext){
105497105865
const tRowcnt * const aiRowEst = pProbe->aiRowEst;
@@ -105566,15 +105934,13 @@
105566105934
*/
105567105935
int bInEst = 0; /* True if "x IN (SELECT...)" seen */
105568105936
int nInMul = 1; /* Number of distinct equalities to lookup */
105569105937
double rangeDiv = (double)1; /* Estimated reduction in search space */
105570105938
int nBound = 0; /* Number of range constraints seen */
105571
- int bSort; /* True if external sort required */
105572
- int bDist; /* True if index cannot help with DISTINCT */
105573
- int bLookup = 0; /* True if not a covering index */
105574
- int nPriorSat; /* ORDER BY terms satisfied by outer loops */
105575
- int nOrderBy; /* Number of ORDER BY terms */
105939
+ char bSort = bSortInit; /* True if external sort required */
105940
+ char bDist = bDistInit; /* True if index cannot help with DISTINCT */
105941
+ char bLookup = 0; /* True if not a covering index */
105576105942
WhereTerm *pTerm; /* A single term of the WHERE clause */
105577105943
#ifdef SQLITE_ENABLE_STAT3
105578105944
WhereTerm *pFirstTerm = 0; /* First term matching the index */
105579105945
#endif
105580105946
@@ -105581,20 +105947,11 @@
105581105947
WHERETRACE((
105582105948
" %s(%s):\n",
105583105949
pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
105584105950
));
105585105951
memset(&pc, 0, sizeof(pc));
105586
- nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
105587
- if( p->i ){
105588
- nPriorSat = pc.plan.nOBSat = p->aLevel[p->i-1].plan.nOBSat;
105589
- bSort = nPriorSat<nOrderBy;
105590
- bDist = 0;
105591
- }else{
105592
- nPriorSat = pc.plan.nOBSat = 0;
105593
- bSort = nOrderBy>0;
105594
- bDist = p->pDistinct!=0;
105595
- }
105952
+ pc.plan.nOBSat = nPriorSat;
105596105953
105597105954
/* Determine the values of pc.plan.nEq and nInMul */
105598105955
for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
105599105956
int j = pProbe->aiColumn[pc.plan.nEq];
105600105957
pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
@@ -106466,32 +106823,40 @@
106466106823
if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
106467106824
/* Case 0: The table is a virtual-table. Use the VFilter and VNext
106468106825
** to access the data.
106469106826
*/
106470106827
int iReg; /* P3 Value for OP_VFilter */
106828
+ int addrNotFound;
106471106829
sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
106472106830
int nConstraint = pVtabIdx->nConstraint;
106473106831
struct sqlite3_index_constraint_usage *aUsage =
106474106832
pVtabIdx->aConstraintUsage;
106475106833
const struct sqlite3_index_constraint *aConstraint =
106476106834
pVtabIdx->aConstraint;
106477106835
106478106836
sqlite3ExprCachePush(pParse);
106479106837
iReg = sqlite3GetTempRange(pParse, nConstraint+2);
106838
+ addrNotFound = pLevel->addrBrk;
106480106839
for(j=1; j<=nConstraint; j++){
106481106840
for(k=0; k<nConstraint; k++){
106482106841
if( aUsage[k].argvIndex==j ){
106483
- int iTerm = aConstraint[k].iTermOffset;
106484
- sqlite3ExprCode(pParse, pWC->a[iTerm].pExpr->pRight, iReg+j+1);
106842
+ WhereTerm *pTerm = &pWC->a[aConstraint[k].iTermOffset];
106843
+ int iTarget = iReg+j+1;
106844
+ if( pTerm->eOperator & WO_IN ){
106845
+ codeEqualityTerm(pParse, pTerm, pLevel, iTarget);
106846
+ addrNotFound = pLevel->addrNxt;
106847
+ }else{
106848
+ sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
106849
+ }
106485106850
break;
106486106851
}
106487106852
}
106488106853
if( k==nConstraint ) break;
106489106854
}
106490106855
sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
106491106856
sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
106492
- sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrBrk, iReg, pVtabIdx->idxStr,
106857
+ sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, pVtabIdx->idxStr,
106493106858
pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
106494106859
pVtabIdx->needToFreeIdxStr = 0;
106495106860
for(j=0; j<nConstraint; j++){
106496106861
if( aUsage[j].omit ){
106497106862
int iTerm = aConstraint[j].iTermOffset;
@@ -108134,10 +108499,11 @@
108134108499
Expr* yy122;
108135108500
Select* yy159;
108136108501
IdList* yy180;
108137108502
struct {int value; int mask;} yy207;
108138108503
u8 yy258;
108504
+ u16 yy305;
108139108505
struct LikeOp yy318;
108140108506
TriggerStep* yy327;
108141108507
ExprSpan yy342;
108142108508
SrcList* yy347;
108143108509
int yy392;
@@ -110084,22 +110450,19 @@
110084110450
case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
110085110451
case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
110086110452
case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
110087110453
case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
110088110454
case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
110089
- case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120);
110090
- case 121: /* distinct ::= */ yytestcase(yyruleno==121);
110091110455
case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
110092110456
case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
110093110457
{yygotominor.yy392 = 0;}
110094110458
break;
110095110459
case 29: /* ifnotexists ::= IF NOT EXISTS */
110096110460
case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
110097110461
case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
110098110462
case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
110099110463
case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
110100
- case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119);
110101110464
case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
110102110465
case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
110103110466
{yygotominor.yy392 = 1;}
110104110467
break;
110105110468
case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
@@ -110335,12 +110698,19 @@
110335110698
case 116: /* multiselect_op ::= UNION ALL */
110336110699
{yygotominor.yy392 = TK_ALL;}
110337110700
break;
110338110701
case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
110339110702
{
110340
- yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
110703
+ yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy305,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
110341110704
}
110705
+ break;
110706
+ case 119: /* distinct ::= DISTINCT */
110707
+{yygotominor.yy305 = SF_Distinct;}
110708
+ break;
110709
+ case 120: /* distinct ::= ALL */
110710
+ case 121: /* distinct ::= */ yytestcase(yyruleno==121);
110711
+{yygotominor.yy305 = 0;}
110342110712
break;
110343110713
case 122: /* sclp ::= selcollist COMMA */
110344110714
case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
110345110715
{yygotominor.yy442 = yymsp[-1].minor.yy442;}
110346110716
break;
@@ -110406,14 +110776,24 @@
110406110776
break;
110407110777
case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
110408110778
{
110409110779
if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
110410110780
yygotominor.yy347 = yymsp[-4].minor.yy347;
110781
+ }else if( yymsp[-4].minor.yy347->nSrc==1 ){
110782
+ yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
110783
+ if( yygotominor.yy347 ){
110784
+ struct SrcList_item *pNew = &yygotominor.yy347->a[yygotominor.yy347->nSrc-1];
110785
+ struct SrcList_item *pOld = yymsp[-4].minor.yy347->a;
110786
+ pNew->zName = pOld->zName;
110787
+ pNew->zDatabase = pOld->zDatabase;
110788
+ pOld->zName = pOld->zDatabase = 0;
110789
+ }
110790
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy347);
110411110791
}else{
110412110792
Select *pSubquery;
110413110793
sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
110414
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,0,0,0);
110794
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,SF_NestedFrom,0,0);
110415110795
yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
110416110796
}
110417110797
}
110418110798
break;
110419110799
case 137: /* dbnm ::= */
@@ -110624,11 +111004,11 @@
110624111004
spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
110625111005
}
110626111006
break;
110627111007
case 194: /* expr ::= expr COLLATE ids */
110628111008
{
110629
- yygotominor.yy342.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
111009
+ yygotominor.yy342.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
110630111010
yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
110631111011
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
110632111012
}
110633111013
break;
110634111014
case 195: /* expr ::= CAST LP expr AS typetoken RP */
@@ -110642,11 +111022,11 @@
110642111022
if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
110643111023
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
110644111024
}
110645111025
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
110646111026
spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
110647
- if( yymsp[-2].minor.yy392 && yygotominor.yy342.pExpr ){
111027
+ if( yymsp[-2].minor.yy305 && yygotominor.yy342.pExpr ){
110648111028
yygotominor.yy342.pExpr->flags |= EP_Distinct;
110649111029
}
110650111030
}
110651111031
break;
110652111032
case 197: /* expr ::= ID LP STAR RP */
@@ -110883,28 +111263,20 @@
110883111263
case 244: /* uniqueflag ::= */
110884111264
{yygotominor.yy392 = OE_None;}
110885111265
break;
110886111266
case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
110887111267
{
110888
- Expr *p = 0;
110889
- if( yymsp[-1].minor.yy0.n>0 ){
110890
- p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
110891
- sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
110892
- }
111268
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
110893111269
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
110894111270
sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
110895111271
sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
110896111272
if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
110897111273
}
110898111274
break;
110899111275
case 248: /* idxlist ::= nm collate sortorder */
110900111276
{
110901
- Expr *p = 0;
110902
- if( yymsp[-1].minor.yy0.n>0 ){
110903
- p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
110904
- sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
110905
- }
111277
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
110906111278
yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
110907111279
sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
110908111280
sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
110909111281
if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
110910111282
}
@@ -141105,10 +141477,11 @@
141105141477
extern int Sqlitemultiplex_Init(Tcl_Interp*);
141106141478
extern int SqliteSuperlock_Init(Tcl_Interp*);
141107141479
extern int SqlitetestSyscall_Init(Tcl_Interp*);
141108141480
extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
141109141481
extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
141482
+ extern int Sqlitetestregexp_Init(Tcl_Interp*);
141110141483
141111141484
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141112141485
extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
141113141486
#endif
141114141487
@@ -141148,10 +141521,11 @@
141148141521
Sqlitemultiplex_Init(interp);
141149141522
SqliteSuperlock_Init(interp);
141150141523
SqlitetestSyscall_Init(interp);
141151141524
Sqlitetestfuzzer_Init(interp);
141152141525
Sqlitetestwholenumber_Init(interp);
141526
+ Sqlitetestregexp_Init(interp);
141153141527
141154141528
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141155141529
Sqlitetestfts3_Init(interp);
141156141530
#endif
141157141531
141158141532
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.7.15. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -671,13 +671,13 @@
671 **
672 ** See also: [sqlite3_libversion()],
673 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674 ** [sqlite_version()] and [sqlite_source_id()].
675 */
676 #define SQLITE_VERSION "3.7.15"
677 #define SQLITE_VERSION_NUMBER 3007015
678 #define SQLITE_SOURCE_ID "2012-10-16 23:08:28 f021559d8a23934e3bdccad5b55fc7a91d185f53"
679
680 /*
681 ** CAPI3REF: Run-Time Library Version Numbers
682 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
683 **
@@ -2162,11 +2162,11 @@
2162 ** database connection is opened. By default, URI handling is globally
2163 ** disabled. The default value may be changed by compiling with the
2164 ** [SQLITE_USE_URI] symbol defined.
2165 **
2166 ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
2167 ** <dd> This option taks a single integer argument which is interpreted as
2168 ** a boolean in order to enable or disable the use of covering indices for
2169 ** full table scans in the query optimizer. The default setting is determined
2170 ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
2171 ** if that compile-time option is omitted.
2172 ** The ability to disable the use of covering indices for full table scans
@@ -10573,24 +10573,24 @@
10573 ** and the value of Index.onError indicate the which conflict resolution
10574 ** algorithm to employ whenever an attempt is made to insert a non-unique
10575 ** element.
10576 */
10577 struct Index {
10578 char *zName; /* Name of this index */
10579 int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10580 tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
10581 Table *pTable; /* The SQL table being indexed */
10582 char *zColAff; /* String defining the affinity of each column */
10583 Index *pNext; /* The next index associated with the same table */
10584 Schema *pSchema; /* Schema containing this index */
10585 u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
10586 char **azColl; /* Array of collation sequence names for index */
10587 int nColumn; /* Number of columns in the table used by this index */
10588 int tnum; /* Page containing root of this index in database file */
10589 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10590 u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
10591 u8 bUnordered; /* Use this index for == or IN queries only */
10592 #ifdef SQLITE_ENABLE_STAT3
10593 int nSample; /* Number of elements in aSample[] */
10594 tRowcnt avgEq; /* Average nEq value for key values not in aSample */
10595 IndexSample *aSample; /* Samples of the left-most key */
10596 #endif
@@ -10767,11 +10767,10 @@
10767 Expr *pRight; /* Right subnode */
10768 union {
10769 ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
10770 Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
10771 } x;
10772 CollSeq *pColl; /* The collation type of the column or 0 */
10773
10774 /* If the EP_Reduced flag is set in the Expr.flags mask, then no
10775 ** space is allocated for the fields below this point. An attempt to
10776 ** access them will result in a segfault or malfunction.
10777 *********************************************************************/
@@ -10803,11 +10802,11 @@
10803 #define EP_Error 0x0008 /* Expression contains one or more errors */
10804 #define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
10805 #define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
10806 #define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
10807 #define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
10808 #define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
10809 #define EP_FixedDest 0x0200 /* Result needed in a specific register */
10810 #define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
10811 #define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
10812 #define EP_Hint 0x1000 /* Not used */
10813 #define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
@@ -10861,22 +10860,31 @@
10861 ** name. An expr/name combination can be used in several ways, such
10862 ** as the list of "expr AS ID" fields following a "SELECT" or in the
10863 ** list of "ID = expr" items in an UPDATE. A list of expressions can
10864 ** also be used as the argument to a function, in which case the a.zName
10865 ** field is not used.
 
 
 
 
 
 
 
 
10866 */
10867 struct ExprList {
10868 int nExpr; /* Number of expressions on the list */
10869 int iECursor; /* VDBE Cursor associated with this ExprList */
10870 struct ExprList_item { /* For each expression in the list */
10871 Expr *pExpr; /* The list of expressions */
10872 char *zName; /* Token associated with this expression */
10873 char *zSpan; /* Original text of the expression */
10874 u8 sortOrder; /* 1 for DESC or 0 for ASC */
10875 u8 done; /* A flag to indicate when processing is finished */
10876 u16 iOrderByCol; /* For ORDER BY, column number in result set */
10877 u16 iAlias; /* Index into Parse.aAlias[] for zName */
 
10878 } *a; /* Alloc a power of two greater or equal to nExpr */
10879 };
10880
10881 /*
10882 ** An instance of this structure is used by the parser to record both
@@ -11192,10 +11200,11 @@
11192 #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
11193 #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
11194 #define SF_UseSorter 0x0040 /* Sort using a sorter */
11195 #define SF_Values 0x0080 /* Synthesized from VALUES clause */
11196 #define SF_Materialize 0x0100 /* Force materialization of views */
 
11197
11198
11199 /*
11200 ** The results of a select can be distributed in several ways. The
11201 ** "SRT" prefix means "SELECT Result Type".
@@ -11420,10 +11429,11 @@
11420 #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
11421 #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
11422 #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
11423 #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
11424 #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
 
11425
11426 /*
11427 * Each trigger present in the database schema is stored as an instance of
11428 * struct Trigger.
11429 *
@@ -11904,11 +11914,11 @@
11904 SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
11905 Token*, int, int);
11906 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
11907 SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
11908 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
11909 Expr*,ExprList*,int,Expr*,Expr*);
11910 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
11911 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
11912 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
11913 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
11914 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
@@ -12112,12 +12122,13 @@
12112 SQLITE_PRIVATE const char *sqlite3ErrStr(int);
12113 SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
12114 SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
12115 SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
12116 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
12117 SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
12118 SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
 
12119 SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
12120 SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
12121 SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
12122 SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
12123 SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
@@ -12160,10 +12171,11 @@
12160 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
12161 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
12162 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
12163 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
12164 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
 
12165 SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
12166 SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
12167 SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
12168 SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
12169 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -12298,12 +12310,14 @@
12298 #define sqlite3FkOldmask(a,b) 0
12299 #define sqlite3FkRequired(a,b,c,d) 0
12300 #endif
12301 #ifndef SQLITE_OMIT_FOREIGN_KEY
12302 SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*);
 
12303 #else
12304 #define sqlite3FkDelete(a,b)
 
12305 #endif
12306
12307
12308 /*
12309 ** Available fault injectors. Should be numbered beginning with 0.
@@ -23307,15 +23321,11 @@
23307 { "pwrite64", (sqlite3_syscall_ptr)0, 0 },
23308 #endif
23309 #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
23310 aSyscall[13].pCurrent)
23311
23312 #if SQLITE_ENABLE_LOCKING_STYLE
23313 { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
23314 #else
23315 { "fchmod", (sqlite3_syscall_ptr)0, 0 },
23316 #endif
23317 #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
23318
23319 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
23320 { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
23321 #else
@@ -23336,13 +23346,10 @@
23336 #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
23337
23338 { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
23339 #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
23340
23341 { "umask", (sqlite3_syscall_ptr)umask, 0 },
23342 #define osUmask ((mode_t(*)(mode_t))aSyscall[21].pCurrent)
23343
23344 }; /* End of the overrideable system calls */
23345
23346 /*
23347 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
23348 ** "unix" VFSes. Return SQLITE_OK opon successfully updating the
@@ -23443,31 +23450,29 @@
23443 ** process that is able to write to the database will also be able to
23444 ** recover the hot journals.
23445 */
23446 static int robust_open(const char *z, int f, mode_t m){
23447 int fd;
23448 mode_t m2;
23449 mode_t origM = 0;
23450 if( m==0 ){
23451 m2 = SQLITE_DEFAULT_FILE_PERMISSIONS;
23452 }else{
23453 m2 = m;
23454 origM = osUmask(0);
23455 }
23456 do{
23457 #if defined(O_CLOEXEC)
23458 fd = osOpen(z,f|O_CLOEXEC,m2);
23459 #else
23460 fd = osOpen(z,f,m2);
23461 #endif
23462 }while( fd<0 && errno==EINTR );
23463 if( m ){
23464 osUmask(origM);
23465 }
 
 
 
 
23466 #if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
23467 if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
23468 #endif
 
23469 return fd;
23470 }
23471
23472 /*
23473 ** Helper functions to obtain and relinquish the global mutex. The
@@ -29889,11 +29894,11 @@
29889 };
29890 unsigned int i; /* Loop counter */
29891
29892 /* Double-check that the aSyscall[] array has been constructed
29893 ** correctly. See ticket [bb3a86e890c8e96ab] */
29894 assert( ArraySize(aSyscall)==22 );
29895
29896 /* Register all VFSes defined in the aVfs[] array */
29897 for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
29898 sqlite3_vfs_register(&aVfs[i], i==0);
29899 }
@@ -56355,11 +56360,11 @@
56355 sqlite3BtreeLeave(p);
56356 return 0;
56357 }
56358 i = PENDING_BYTE_PAGE(pBt);
56359 if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
56360 sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000);
56361 sCheck.errMsg.useMalloc = 2;
56362
56363 /* Check the integrity of the freelist
56364 */
56365 checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
@@ -56890,11 +56895,16 @@
56890 /*
56891 ** Parameter zSrcData points to a buffer containing the data for
56892 ** page iSrcPg from the source database. Copy this data into the
56893 ** destination database.
56894 */
56895 static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
 
 
 
 
 
56896 Pager * const pDestPager = sqlite3BtreePager(p->pDest);
56897 const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
56898 int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
56899 const int nCopy = MIN(nSrcPgsz, nDestPgsz);
56900 const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
@@ -56963,10 +56973,13 @@
56963 ** cached parse of the page). MemPage.isInit is marked
56964 ** "MUST BE FIRST" for this purpose.
56965 */
56966 memcpy(zOut, zIn, nCopy);
56967 ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
 
 
 
56968 }
56969 sqlite3PagerUnref(pDestPg);
56970 }
56971
56972 return rc;
@@ -57069,11 +57082,11 @@
57069 const Pgno iSrcPg = p->iNext; /* Source page number */
57070 if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
57071 DbPage *pSrcPg; /* Source page object */
57072 rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
57073 if( rc==SQLITE_OK ){
57074 rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg));
57075 sqlite3PagerUnref(pSrcPg);
57076 }
57077 }
57078 p->iNext++;
57079 }
@@ -57317,11 +57330,11 @@
57317 ** the new data into the backup.
57318 */
57319 int rc;
57320 assert( p->pDestDb );
57321 sqlite3_mutex_enter(p->pDestDb->mutex);
57322 rc = backupOnePage(p, iPage, aData);
57323 sqlite3_mutex_leave(p->pDestDb->mutex);
57324 assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
57325 if( rc!=SQLITE_OK ){
57326 p->rc = rc;
57327 }
@@ -59434,26 +59447,22 @@
59434 assert( pKeyInfo->aSortOrder!=0 );
59435 sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
59436 i = sqlite3Strlen30(zTemp);
59437 for(j=0; j<pKeyInfo->nField; j++){
59438 CollSeq *pColl = pKeyInfo->aColl[j];
59439 if( pColl ){
59440 int n = sqlite3Strlen30(pColl->zName);
59441 if( i+n>nTemp-6 ){
59442 memcpy(&zTemp[i],",...",4);
59443 break;
59444 }
59445 zTemp[i++] = ',';
59446 if( pKeyInfo->aSortOrder[j] ){
59447 zTemp[i++] = '-';
59448 }
59449 memcpy(&zTemp[i], pColl->zName,n+1);
59450 i += n;
59451 }else if( i+4<nTemp-6 ){
59452 memcpy(&zTemp[i],",nil",4);
59453 i += 4;
59454 }
59455 }
59456 zTemp[i++] = ')';
59457 zTemp[i] = 0;
59458 assert( i<nTemp );
59459 break;
@@ -63839,11 +63848,13 @@
63839 #ifdef SQLITE_DEBUG
63840 /*
63841 ** Print the value of a register for tracing purposes:
63842 */
63843 static void memTracePrint(FILE *out, Mem *p){
63844 if( p->flags & MEM_Null ){
 
 
63845 fprintf(out, " NULL");
63846 }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
63847 fprintf(out, " si:%lld", p->u.i);
63848 }else if( p->flags & MEM_Int ){
63849 fprintf(out, " i:%lld", p->u.i);
@@ -64112,10 +64123,11 @@
64112 } af;
64113 struct OP_Concat_stack_vars {
64114 i64 nByte;
64115 } ag;
64116 struct OP_Remainder_stack_vars {
 
64117 int flags; /* Combined MEM_* flags from both inputs */
64118 i64 iA; /* Integer value of left operand */
64119 i64 iB; /* Integer value of right operand */
64120 double rA; /* Real value of left operand */
64121 double rB; /* Real value of right operand */
@@ -65021,10 +65033,13 @@
65021 pOut = &aMem[pOp->p2];
65022 assert( pOut!=pIn1 );
65023 while( 1 ){
65024 sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
65025 Deephemeralize(pOut);
 
 
 
65026 REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
65027 if( (u.ae.n--)==0 ) break;
65028 pOut++;
65029 pIn1++;
65030 }
@@ -65214,10 +65229,11 @@
65214 case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
65215 case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
65216 case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
65217 case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
65218 #if 0 /* local variables moved into u.ah */
 
65219 int flags; /* Combined MEM_* flags from both inputs */
65220 i64 iA; /* Integer value of left operand */
65221 i64 iB; /* Integer value of right operand */
65222 double rA; /* Real value of left operand */
65223 double rB; /* Real value of right operand */
@@ -65231,10 +65247,11 @@
65231 u.ah.flags = pIn1->flags | pIn2->flags;
65232 if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
65233 if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
65234 u.ah.iA = pIn1->u.i;
65235 u.ah.iB = pIn2->u.i;
 
65236 switch( pOp->opcode ){
65237 case OP_Add: if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65238 case OP_Subtract: if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65239 case OP_Multiply: if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65240 case OP_Divide: {
@@ -65251,10 +65268,11 @@
65251 }
65252 }
65253 pOut->u.i = u.ah.iB;
65254 MemSetTypeFlag(pOut, MEM_Int);
65255 }else{
 
65256 fp_math:
65257 u.ah.rA = sqlite3VdbeRealValue(pIn1);
65258 u.ah.rB = sqlite3VdbeRealValue(pIn2);
65259 switch( pOp->opcode ){
65260 case OP_Add: u.ah.rB += u.ah.rA; break;
@@ -65282,11 +65300,11 @@
65282 if( sqlite3IsNaN(u.ah.rB) ){
65283 goto arithmetic_result_is_null;
65284 }
65285 pOut->r = u.ah.rB;
65286 MemSetTypeFlag(pOut, MEM_Real);
65287 if( (u.ah.flags & MEM_Real)==0 ){
65288 sqlite3VdbeIntegerAffinity(pOut);
65289 }
65290 #endif
65291 }
65292 break;
@@ -65843,26 +65861,31 @@
65843 /* Opcode: Permutation * * * P4 *
65844 **
65845 ** Set the permutation used by the OP_Compare operator to be the array
65846 ** of integers in P4.
65847 **
65848 ** The permutation is only valid until the next OP_Permutation, OP_Compare,
65849 ** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur
65850 ** immediately prior to the OP_Compare.
65851 */
65852 case OP_Permutation: {
65853 assert( pOp->p4type==P4_INTARRAY );
65854 assert( pOp->p4.ai );
65855 aPermute = pOp->p4.ai;
65856 break;
65857 }
65858
65859 /* Opcode: Compare P1 P2 P3 P4 *
65860 **
65861 ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
65862 ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
65863 ** the comparison for use by the next OP_Jump instruct.
 
 
 
 
 
65864 **
65865 ** P4 is a KeyInfo structure that defines collating sequences and sort
65866 ** orders for the comparison. The permutation applies to registers
65867 ** only. The KeyInfo elements are used sequentially.
65868 **
@@ -65880,10 +65903,11 @@
65880 int idx;
65881 CollSeq *pColl; /* Collating sequence to use on this term */
65882 int bRev; /* True for DESCENDING sort order */
65883 #endif /* local variables moved into u.al */
65884
 
65885 u.al.n = pOp->p3;
65886 u.al.pKeyInfo = pOp->p4.pKeyInfo;
65887 assert( u.al.n>0 );
65888 assert( u.al.pKeyInfo!=0 );
65889 u.al.p1 = pOp->p1;
@@ -66025,12 +66049,10 @@
66025
66026 /* Opcode: Once P1 P2 * * *
66027 **
66028 ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
66029 ** set the flag and fall through to the next instruction.
66030 **
66031 ** See also: JumpOnce
66032 */
66033 case OP_Once: { /* jump */
66034 assert( pOp->p1<p->nOnceFlag );
66035 if( p->aOnceFlag[pOp->p1] ){
66036 pc = pOp->p2-1;
@@ -71902,10 +71924,18 @@
71902 p->pReal = pReal;
71903 if( p->iSize>0 ){
71904 assert(p->iSize<=p->nBuf);
71905 rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
71906 }
 
 
 
 
 
 
 
 
71907 }
71908 }
71909 return rc;
71910 }
71911
@@ -72565,10 +72595,19 @@
72565 ** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
72566 **
72567 ** The result of random()%5 in the GROUP BY clause is probably different
72568 ** from the result in the result-set. We might fix this someday. Or
72569 ** then again, we might not...
 
 
 
 
 
 
 
 
 
72570 **
72571 ** The nSubquery parameter specifies how many levels of subquery the
72572 ** alias is removed from the original expression. The usually value is
72573 ** zero but it might be more if the alias is contained within a subquery
72574 ** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
@@ -72589,45 +72628,40 @@
72589 assert( iCol>=0 && iCol<pEList->nExpr );
72590 pOrig = pEList->a[iCol].pExpr;
72591 assert( pOrig!=0 );
72592 assert( pOrig->flags & EP_Resolved );
72593 db = pParse->db;
 
 
72594 if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
72595 pDup = sqlite3ExprDup(db, pOrig, 0);
72596 incrAggFunctionDepth(pDup, nSubquery);
72597 pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
72598 if( pDup==0 ) return;
72599 if( pEList->a[iCol].iAlias==0 ){
72600 pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
72601 }
72602 pDup->iTable = pEList->a[iCol].iAlias;
72603 }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
72604 pDup = sqlite3ExprDup(db, pOrig, 0);
72605 if( pDup==0 ) return;
72606 }else{
72607 char *zToken = pOrig->u.zToken;
72608 assert( zToken!=0 );
72609 pOrig->u.zToken = 0;
72610 pDup = sqlite3ExprDup(db, pOrig, 0);
72611 pOrig->u.zToken = zToken;
72612 if( pDup==0 ) return;
72613 assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
72614 pDup->flags2 |= EP2_MallocedToken;
72615 pDup->u.zToken = sqlite3DbStrDup(db, zToken);
72616 }
72617 if( pExpr->flags & EP_ExpCollate ){
72618 pDup->pColl = pExpr->pColl;
72619 pDup->flags |= EP_ExpCollate;
72620 }
72621
72622 /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
72623 ** prevents ExprDelete() from deleting the Expr structure itself,
72624 ** allowing it to be repopulated by the memcpy() on the following line.
 
 
 
72625 */
72626 ExprSetProperty(pExpr, EP_Static);
72627 sqlite3ExprDelete(db, pExpr);
72628 memcpy(pExpr, pDup, sizeof(*pExpr));
 
 
 
 
 
72629 sqlite3DbFree(db, pDup);
72630 }
72631
72632
72633 /*
@@ -72644,10 +72678,39 @@
72644 }
72645 }
72646 return 0;
72647 }
72648
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72649
72650 /*
72651 ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
72652 ** that name in the set of source tables in pSrcList and make the pExpr
72653 ** expression node refer back to that source column. The following changes
@@ -72699,44 +72762,63 @@
72699
72700 /* Initialize the node to no-match */
72701 pExpr->iTable = -1;
72702 pExpr->pTab = 0;
72703 ExprSetIrreducible(pExpr);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72704
72705 /* Start at the inner-most context and move outward until a match is found */
72706 while( pNC && cnt==0 ){
72707 ExprList *pEList;
72708 SrcList *pSrcList = pNC->pSrcList;
72709
72710 if( pSrcList ){
72711 for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
72712 Table *pTab;
72713 int iDb;
72714 Column *pCol;
72715
72716 pTab = pItem->pTab;
72717 assert( pTab!=0 && pTab->zName!=0 );
72718 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
72719 assert( pTab->nCol>0 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72720 if( zTab ){
72721 if( pItem->zAlias ){
72722 char *zTabName = pItem->zAlias;
72723 if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
72724 }else{
72725 char *zTabName = pTab->zName;
72726 if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){
72727 continue;
72728 }
72729 if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
72730 continue;
72731 }
72732 }
72733 }
72734 if( 0==(cntTab++) ){
72735 pExpr->iTable = pItem->iCursor;
72736 pExpr->pTab = pTab;
72737 pSchema = pTab->pSchema;
72738 pMatch = pItem;
72739 }
72740 for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
72741 if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
72742 /* If there has been exactly one prior match and this match
@@ -72746,21 +72828,23 @@
72746 if( cnt==1 ){
72747 if( pItem->jointype & JT_NATURAL ) continue;
72748 if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
72749 }
72750 cnt++;
72751 pExpr->iTable = pItem->iCursor;
72752 pExpr->pTab = pTab;
72753 pMatch = pItem;
72754 pSchema = pTab->pSchema;
72755 /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
72756 pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
72757 break;
72758 }
72759 }
72760 }
72761 }
 
 
 
 
 
72762
72763 #ifndef SQLITE_OMIT_TRIGGER
72764 /* If we have not already resolved the name, then maybe
72765 ** it is a new.* or old.* trigger argument reference
72766 */
@@ -73055,42 +73139,43 @@
73055 int wrong_num_args = 0; /* True if wrong number of arguments */
73056 int is_agg = 0; /* True if is an aggregate function */
73057 int auth; /* Authorization to use the function */
73058 int nId; /* Number of characters in function name */
73059 const char *zId; /* The function name. */
73060 FuncDef *pDef; /* Information about the function */
73061 u8 enc = ENC(pParse->db); /* The database encoding */
73062
73063 testcase( pExpr->op==TK_CONST_FUNC );
73064 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
73065 zId = pExpr->u.zToken;
73066 nId = sqlite3Strlen30(zId);
73067 pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
73068 if( pDef==0 ){
73069 pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
73070 if( pDef==0 ){
73071 no_such_func = 1;
73072 }else{
73073 wrong_num_args = 1;
73074 }
73075 }else{
73076 is_agg = pDef->xFunc==0;
73077 }
73078 #ifndef SQLITE_OMIT_AUTHORIZATION
73079 if( pDef ){
73080 auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
73081 if( auth!=SQLITE_OK ){
73082 if( auth==SQLITE_DENY ){
73083 sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
73084 pDef->zName);
73085 pNC->nErr++;
73086 }
73087 pExpr->op = TK_NULL;
73088 return WRC_Prune;
73089 }
73090 }
73091 #endif
 
 
73092 if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
73093 sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
73094 pNC->nErr++;
73095 is_agg = 0;
73096 }else if( no_such_func ){
@@ -73310,11 +73395,11 @@
73310 assert( pEList!=0 );
73311 for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
73312 int iCol = -1;
73313 Expr *pE, *pDup;
73314 if( pItem->done ) continue;
73315 pE = pItem->pExpr;
73316 if( sqlite3ExprIsInteger(pE, &iCol) ){
73317 if( iCol<=0 || iCol>pEList->nExpr ){
73318 resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
73319 return 1;
73320 }
@@ -73328,18 +73413,24 @@
73328 }
73329 sqlite3ExprDelete(db, pDup);
73330 }
73331 }
73332 if( iCol>0 ){
73333 CollSeq *pColl = pE->pColl;
73334 int flags = pE->flags & EP_ExpCollate;
 
 
 
 
 
 
 
 
 
 
 
73335 sqlite3ExprDelete(db, pE);
73336 pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
73337 if( pE==0 ) return 1;
73338 pE->pColl = pColl;
73339 pE->flags |= EP_IntValue | flags;
73340 pE->u.iValue = iCol;
73341 pItem->iOrderByCol = (u16)iCol;
73342 pItem->done = 1;
73343 }else{
73344 moreToDo = 1;
73345 }
@@ -73440,15 +73531,15 @@
73440 ** sqlite3ResolveOrderGroupBy() will convert the expression to a
73441 ** copy of the iCol-th result-set expression. */
73442 pItem->iOrderByCol = (u16)iCol;
73443 continue;
73444 }
73445 if( sqlite3ExprIsInteger(pE, &iCol) ){
73446 /* The ORDER BY term is an integer constant. Again, set the column
73447 ** number so that sqlite3ResolveOrderGroupBy() will convert the
73448 ** order-by term to a copy of the result-set expression */
73449 if( iCol<1 ){
73450 resolveOutOfRangeError(pParse, zType, i+1, nResult);
73451 return 1;
73452 }
73453 pItem->iOrderByCol = (u16)iCol;
73454 continue;
@@ -73521,27 +73612,10 @@
73521 if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
73522 sqlite3ResolveExprNames(&sNC, p->pOffset) ){
73523 return WRC_Abort;
73524 }
73525
73526 /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
73527 ** resolve the result-set expression list.
73528 */
73529 sNC.ncFlags = NC_AllowAgg;
73530 sNC.pSrcList = p->pSrc;
73531 sNC.pNext = pOuterNC;
73532
73533 /* Resolve names in the result set. */
73534 pEList = p->pEList;
73535 assert( pEList!=0 );
73536 for(i=0; i<pEList->nExpr; i++){
73537 Expr *pX = pEList->a[i].pExpr;
73538 if( sqlite3ResolveExprNames(&sNC, pX) ){
73539 return WRC_Abort;
73540 }
73541 }
73542
73543 /* Recursively resolve names in all subqueries
73544 */
73545 for(i=0; i<p->pSrc->nSrc; i++){
73546 struct SrcList_item *pItem = &p->pSrc->a[i];
73547 if( pItem->pSelect ){
@@ -73564,10 +73638,27 @@
73564 for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
73565 assert( pItem->isCorrelated==0 && nRef<=0 );
73566 pItem->isCorrelated = (nRef!=0);
73567 }
73568 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73569
73570 /* If there are no aggregate functions in the result-set, and no GROUP BY
73571 ** expression, do not allow aggregates in any of the other expressions.
73572 */
73573 assert( (p->selFlags & SF_Aggregate)==0 );
@@ -73798,11 +73889,13 @@
73798 ** SELECT * FROM t1 WHERE a;
73799 ** SELECT a AS b FROM t1 WHERE b;
73800 ** SELECT * FROM t1 WHERE (select a from t1);
73801 */
73802 SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
73803 int op = pExpr->op;
 
 
73804 if( op==TK_SELECT ){
73805 assert( pExpr->flags&EP_xIsSelect );
73806 return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
73807 }
73808 #ifndef SQLITE_OMIT_CAST
@@ -73823,70 +73916,98 @@
73823 }
73824 return pExpr->affinity;
73825 }
73826
73827 /*
73828 ** Set the explicit collating sequence for an expression to the
73829 ** collating sequence supplied in the second argument.
73830 */
73831 SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){
73832 if( pExpr && pColl ){
73833 pExpr->pColl = pColl;
73834 pExpr->flags |= EP_ExpCollate;
73835 }
73836 return pExpr;
73837 }
73838
73839 /*
73840 ** Set the collating sequence for expression pExpr to be the collating
73841 ** sequence named by pToken. Return a pointer to the revised expression.
73842 ** The collating sequence is marked as "explicit" using the EP_ExpCollate
73843 ** flag. An explicit collating sequence will override implicit
73844 ** collating sequences.
73845 */
73846 SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){
73847 char *zColl = 0; /* Dequoted name of collation sequence */
73848 CollSeq *pColl;
73849 sqlite3 *db = pParse->db;
73850 zColl = sqlite3NameFromToken(db, pCollName);
73851 pColl = sqlite3LocateCollSeq(pParse, zColl);
73852 sqlite3ExprSetColl(pExpr, pColl);
73853 sqlite3DbFree(db, zColl);
73854 return pExpr;
73855 }
73856
73857 /*
73858 ** Return the default collation sequence for the expression pExpr. If
73859 ** there is no default collation type, return 0.
73860 */
73861 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
73862 CollSeq *pColl = 0;
73863 Expr *p = pExpr;
73864 while( p ){
73865 int op;
73866 pColl = p->pColl;
73867 if( pColl ) break;
73868 op = p->op;
73869 if( p->pTab!=0 && (
73870 op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
73871 )){
73872 /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
73873 ** a TK_COLUMN but was previously evaluated and cached in a register */
73874 const char *zColl;
73875 int j = p->iColumn;
73876 if( j>=0 ){
73877 sqlite3 *db = pParse->db;
73878 zColl = p->pTab->aCol[j].zColl;
73879 pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
73880 pExpr->pColl = pColl;
73881 }
73882 break;
73883 }
73884 if( op!=TK_CAST && op!=TK_UPLUS ){
73885 break;
73886 }
73887 p = p->pLeft;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73888 }
73889 if( sqlite3CheckCollSeq(pParse, pColl) ){
73890 pColl = 0;
73891 }
73892 return pColl;
@@ -73986,16 +74107,14 @@
73986 Expr *pLeft,
73987 Expr *pRight
73988 ){
73989 CollSeq *pColl;
73990 assert( pLeft );
73991 if( pLeft->flags & EP_ExpCollate ){
73992 assert( pLeft->pColl );
73993 pColl = pLeft->pColl;
73994 }else if( pRight && pRight->flags & EP_ExpCollate ){
73995 assert( pRight->pColl );
73996 pColl = pRight->pColl;
73997 }else{
73998 pColl = sqlite3ExprCollSeq(pParse, pLeft);
73999 if( !pColl ){
74000 pColl = sqlite3ExprCollSeq(pParse, pRight);
74001 }
@@ -74221,21 +74340,15 @@
74221 sqlite3ExprDelete(db, pLeft);
74222 sqlite3ExprDelete(db, pRight);
74223 }else{
74224 if( pRight ){
74225 pRoot->pRight = pRight;
74226 if( pRight->flags & EP_ExpCollate ){
74227 pRoot->flags |= EP_ExpCollate;
74228 pRoot->pColl = pRight->pColl;
74229 }
74230 }
74231 if( pLeft ){
74232 pRoot->pLeft = pLeft;
74233 if( pLeft->flags & EP_ExpCollate ){
74234 pRoot->flags |= EP_ExpCollate;
74235 pRoot->pColl = pLeft->pColl;
74236 }
74237 }
74238 exprSetHeight(pRoot);
74239 }
74240 }
74241
@@ -74489,11 +74602,11 @@
74489 }else{
74490 assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
74491 assert( !ExprHasProperty(p, EP_FromJoin) );
74492 assert( (p->flags2 & EP2_MallocedToken)==0 );
74493 assert( (p->flags2 & EP2_Irreducible)==0 );
74494 if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
74495 nSize = EXPR_REDUCEDSIZE | EP_Reduced;
74496 }else{
74497 nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
74498 }
74499 }
@@ -76513,10 +76626,11 @@
76513 sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
76514 sqlite3ReleaseTempReg(pParse, r3);
76515 sqlite3ReleaseTempReg(pParse, r4);
76516 break;
76517 }
 
76518 case TK_UPLUS: {
76519 inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
76520 break;
76521 }
76522
@@ -76881,10 +76995,16 @@
76881 case TK_UPLUS: zUniOp = "UPLUS"; break;
76882 case TK_BITNOT: zUniOp = "BITNOT"; break;
76883 case TK_NOT: zUniOp = "NOT"; break;
76884 case TK_ISNULL: zUniOp = "ISNULL"; break;
76885 case TK_NOTNULL: zUniOp = "NOTNULL"; break;
 
 
 
 
 
 
76886
76887 case TK_AGG_FUNCTION:
76888 case TK_CONST_FUNC:
76889 case TK_FUNCTION: {
76890 ExprList *pFarg; /* List of function arguments */
@@ -77019,10 +77139,16 @@
77019 for(i=0; i<pList->nExpr; i++){
77020 sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
77021 sqlite3ExplainPush(pOut);
77022 sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
77023 sqlite3ExplainPop(pOut);
 
 
 
 
 
 
77024 if( i<pList->nExpr-1 ){
77025 sqlite3ExplainNL(pOut);
77026 }
77027 }
77028 sqlite3ExplainPop(pOut);
@@ -77100,10 +77226,13 @@
77100 switch( pExpr->op ){
77101 case TK_IN:
77102 case TK_REGISTER: {
77103 return WRC_Prune;
77104 }
 
 
 
77105 case TK_FUNCTION:
77106 case TK_AGG_FUNCTION:
77107 case TK_CONST_FUNC: {
77108 /* The arguments to a function have a fixed destination.
77109 ** Mark them this way to avoid generated unneeded OP_SCopy
@@ -77121,13 +77250,15 @@
77121 break;
77122 }
77123 }
77124 if( isAppropriateForFactoring(pExpr) ){
77125 int r1 = ++pParse->nMem;
77126 int r2;
77127 r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
77128 if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
 
 
77129 pExpr->op2 = pExpr->op;
77130 pExpr->op = TK_REGISTER;
77131 pExpr->iTable = r2;
77132 return WRC_Prune;
77133 }
@@ -77540,11 +77671,19 @@
77540 assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
77541 if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
77542 return 2;
77543 }
77544 if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
77545 if( pA->op!=pB->op ) return 2;
 
 
 
 
 
 
 
 
77546 if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
77547 if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
77548 if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
77549 if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
77550 if( ExprHasProperty(pA, EP_IntValue) ){
@@ -77552,15 +77691,13 @@
77552 return 2;
77553 }
77554 }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
77555 if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
77556 if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
77557 return 2;
77558 }
77559 }
77560 if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
77561 if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
77562 return 0;
77563 }
77564
77565 /*
77566 ** Compare two ExprList objects. Return 0 if they are identical and
@@ -83371,14 +83508,12 @@
83371 ** specified collation sequence names.
83372 */
83373 for(i=0; i<pList->nExpr; i++){
83374 Expr *pExpr = pList->a[i].pExpr;
83375 if( pExpr ){
83376 CollSeq *pColl = pExpr->pColl;
83377 /* Either pColl!=0 or there was an OOM failure. But if an OOM
83378 ** failure we have quit before reaching this point. */
83379 if( ALWAYS(pColl) ){
83380 nExtra += (1 + sqlite3Strlen30(pColl->zName));
83381 }
83382 }
83383 }
83384
@@ -83437,10 +83572,11 @@
83437 */
83438 for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
83439 const char *zColName = pListItem->zName;
83440 Column *pTabCol;
83441 int requestedSortOrder;
 
83442 char *zColl; /* Collation sequence name */
83443
83444 for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
83445 if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
83446 }
@@ -83449,18 +83585,15 @@
83449 pTab->zName, zColName);
83450 pParse->checkSchema = 1;
83451 goto exit_create_index;
83452 }
83453 pIndex->aiColumn[i] = j;
83454 /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
83455 ** the way the "idxlist" non-terminal is constructed by the parser,
83456 ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
83457 ** must exist or else there must have been an OOM error. But if there
83458 ** was an OOM error, we would never reach this point. */
83459 if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
83460 int nColl;
83461 zColl = pListItem->pExpr->pColl->zName;
83462 nColl = sqlite3Strlen30(zColl) + 1;
83463 assert( nExtra>=nColl );
83464 memcpy(zExtra, zColl, nColl);
83465 zColl = zExtra;
83466 zExtra += nColl;
@@ -87489,11 +87622,11 @@
87489
87490 /*
87491 ** A foreign key constraint requires that the key columns in the parent
87492 ** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
87493 ** Given that pParent is the parent table for foreign key constraint pFKey,
87494 ** search the schema a unique index on the parent key columns.
87495 **
87496 ** If successful, zero is returned. If the parent key is an INTEGER PRIMARY
87497 ** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx
87498 ** is set to point to the unique index.
87499 **
@@ -87525,11 +87658,11 @@
87525 **
87526 ** then non-zero is returned, and a "foreign key mismatch" error loaded
87527 ** into pParse. If an OOM error occurs, non-zero is returned and the
87528 ** pParse->db->mallocFailed flag is set.
87529 */
87530 static int locateFkeyIndex(
87531 Parse *pParse, /* Parse context to store any error in */
87532 Table *pParent, /* Parent table of FK constraint pFKey */
87533 FKey *pFKey, /* Foreign key to find index for */
87534 Index **ppIdx, /* OUT: Unique index on parent table */
87535 int **paiCol /* OUT: Map of index columns in pFKey */
@@ -87622,11 +87755,13 @@
87622 }
87623 }
87624
87625 if( !pIdx ){
87626 if( !pParse->disableTriggers ){
87627 sqlite3ErrorMsg(pParse, "foreign key mismatch");
 
 
87628 }
87629 sqlite3DbFree(pParse->db, aiCol);
87630 return 1;
87631 }
87632
@@ -87858,16 +87993,19 @@
87858 if( pLeft ){
87859 /* Set the collation sequence and affinity of the LHS of each TK_EQ
87860 ** expression to the parent key column defaults. */
87861 if( pIdx ){
87862 Column *pCol;
 
87863 iCol = pIdx->aiColumn[i];
87864 pCol = &pTab->aCol[iCol];
87865 if( pTab->iPKey==iCol ) iCol = -1;
87866 pLeft->iTable = regData+iCol+1;
87867 pLeft->affinity = pCol->affinity;
87868 pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl);
 
 
87869 }else{
87870 pLeft->iTable = regData;
87871 pLeft->affinity = SQLITE_AFF_INTEGER;
87872 }
87873 }
@@ -88080,11 +88218,11 @@
88080 if( pParse->disableTriggers ){
88081 pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
88082 }else{
88083 pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
88084 }
88085 if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
88086 assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
88087 if( !isIgnoreErrors || db->mallocFailed ) return;
88088 if( pTo==0 ){
88089 /* If isIgnoreErrors is true, then a table is being dropped. In this
88090 ** case SQLite runs a "DELETE FROM xxx" on the table being dropped
@@ -88160,11 +88298,11 @@
88160 /* Inserting a single row into a parent table cannot cause an immediate
88161 ** foreign key violation. So do nothing in this case. */
88162 continue;
88163 }
88164
88165 if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
88166 if( !isIgnoreErrors || db->mallocFailed ) return;
88167 continue;
88168 }
88169 assert( aiCol || pFKey->nCol==1 );
88170
@@ -88215,11 +88353,11 @@
88215 for(p=pTab->pFKey; p; p=p->pNextFrom){
88216 for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
88217 }
88218 for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
88219 Index *pIdx = 0;
88220 locateFkeyIndex(pParse, pTab, p, &pIdx, 0);
88221 if( pIdx ){
88222 for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
88223 }
88224 }
88225 }
@@ -88341,11 +88479,11 @@
88341 ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */
88342 Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */
88343 int i; /* Iterator variable */
88344 Expr *pWhen = 0; /* WHEN clause for the trigger */
88345
88346 if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
88347 assert( aiCol || pFKey->nCol==1 );
88348
88349 for(i=0; i<pFKey->nCol; i++){
88350 Token tOld = { "old", 3 }; /* Literal "old" token */
88351 Token tNew = { "new", 3 }; /* Literal "new" token */
@@ -89843,29 +89981,24 @@
89843 ExprList *pCheck = pTab->pCheck;
89844 pParse->ckBase = regData;
89845 onError = overrideError!=OE_Default ? overrideError : OE_Abort;
89846 for(i=0; i<pCheck->nExpr; i++){
89847 int allOk = sqlite3VdbeMakeLabel(v);
89848 Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0);
89849 if( !db->mallocFailed ){
89850 assert( pDup!=0 );
89851 sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL);
89852 if( onError==OE_Ignore ){
89853 sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
89854 }else{
89855 char *zConsName = pCheck->a[i].zName;
89856 if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
89857 if( zConsName ){
89858 zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
89859 }else{
89860 zConsName = 0;
89861 }
89862 sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
89863 }
89864 sqlite3VdbeResolveLabel(v, allOk);
89865 }
89866 sqlite3ExprDelete(db, pDup);
89867 }
89868 }
89869 #endif /* !defined(SQLITE_OMIT_CHECK) */
89870
89871 /* If we have an INTEGER PRIMARY KEY, make sure the primary key
@@ -92686,13 +92819,15 @@
92686 if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
92687 Table *pTab;
92688 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
92689 pTab = sqlite3FindTable(db, zRight, zDb);
92690 if( pTab ){
92691 int i;
92692 int nHidden = 0;
92693 Column *pCol;
 
 
92694 sqlite3VdbeSetNumCols(v, 6);
92695 pParse->nMem = 6;
92696 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
92697 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
92698 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
@@ -92713,12 +92848,18 @@
92713 if( pCol->zDflt ){
92714 sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
92715 }else{
92716 sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
92717 }
92718 sqlite3VdbeAddOp2(v, OP_Integer,
92719 (pCol->colFlags&COLFLAG_PRIMKEY)!=0, 6);
 
 
 
 
 
 
92720 sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
92721 }
92722 }
92723 }else
92724
@@ -92849,10 +92990,124 @@
92849 ++i;
92850 pFK = pFK->pNextFrom;
92851 }
92852 }
92853 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92854 }else
92855 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
92856
92857 #ifndef NDEBUG
92858 if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
@@ -94308,11 +94563,11 @@
94308 SrcList *pSrc, /* the FROM clause -- which tables to scan */
94309 Expr *pWhere, /* the WHERE clause */
94310 ExprList *pGroupBy, /* the GROUP BY clause */
94311 Expr *pHaving, /* the HAVING clause */
94312 ExprList *pOrderBy, /* the ORDER BY clause */
94313 int isDistinct, /* true if the DISTINCT keyword is present */
94314 Expr *pLimit, /* LIMIT value. NULL means not used */
94315 Expr *pOffset /* OFFSET value. NULL means no offset */
94316 ){
94317 Select *pNew;
94318 Select standin;
@@ -94332,11 +94587,11 @@
94332 pNew->pSrc = pSrc;
94333 pNew->pWhere = pWhere;
94334 pNew->pGroupBy = pGroupBy;
94335 pNew->pHaving = pHaving;
94336 pNew->pOrderBy = pOrderBy;
94337 pNew->selFlags = isDistinct ? SF_Distinct : 0;
94338 pNew->op = TK_SELECT;
94339 pNew->pLimit = pLimit;
94340 pNew->pOffset = pOffset;
94341 assert( pOffset==0 || pLimit!=0 );
94342 pNew->addrOpenEphm[0] = -1;
@@ -95588,13 +95843,11 @@
95588 *paCol = aCol;
95589
95590 for(i=0, pCol=aCol; i<nCol; i++, pCol++){
95591 /* Get an appropriate name for the column
95592 */
95593 p = pEList->a[i].pExpr;
95594 assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
95595 || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
95596 if( (zName = pEList->a[i].zName)!=0 ){
95597 /* If the column contains an "AS <name>" phrase, use <name> as the name */
95598 zName = sqlite3DbStrDup(db, zName);
95599 }else{
95600 Expr *pColExpr = p; /* The expression that is the result column name */
@@ -95628,10 +95881,13 @@
95628 */
95629 nName = sqlite3Strlen30(zName);
95630 for(j=cnt=0; j<i; j++){
95631 if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
95632 char *zNewName;
 
 
 
95633 zName[nName] = 0;
95634 zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
95635 sqlite3DbFree(db, zName);
95636 zName = zNewName;
95637 j = -1;
@@ -96586,16 +96842,17 @@
96586 pKeyMerge->nField = (u16)nOrderBy;
96587 pKeyMerge->enc = ENC(db);
96588 for(i=0; i<nOrderBy; i++){
96589 CollSeq *pColl;
96590 Expr *pTerm = pOrderBy->a[i].pExpr;
96591 if( pTerm->flags & EP_ExpCollate ){
96592 pColl = pTerm->pColl;
96593 }else{
96594 pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
96595 pTerm->flags |= EP_ExpCollate;
96596 pTerm->pColl = pColl;
 
96597 }
96598 pKeyMerge->aColl[i] = pColl;
96599 pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
96600 }
96601 }
@@ -96794,10 +97051,11 @@
96794 */
96795 sqlite3VdbeResolveLabel(v, labelCmpr);
96796 sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
96797 sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
96798 (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
 
96799 sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
96800
96801 /* Release temporary registers
96802 */
96803 if( regPrev ){
@@ -96861,13 +97119,10 @@
96861 }else{
96862 Expr *pNew;
96863 assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
96864 assert( pExpr->pLeft==0 && pExpr->pRight==0 );
96865 pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
96866 if( pNew && pExpr->pColl ){
96867 pNew->pColl = pExpr->pColl;
96868 }
96869 sqlite3ExprDelete(db, pExpr);
96870 pExpr = pNew;
96871 }
96872 }else{
96873 pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
@@ -97414,38 +97669,47 @@
97414 return 1;
97415 }
97416 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
97417
97418 /*
97419 ** Analyze the SELECT statement passed as an argument to see if it
97420 ** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if
97421 ** it is, or 0 otherwise. At present, a query is considered to be
97422 ** a min()/max() query if:
97423 **
97424 ** 1. There is a single object in the FROM clause.
97425 **
97426 ** 2. There is a single expression in the result set, and it is
97427 ** either min(x) or max(x), where x is a column reference.
97428 */
97429 static u8 minMaxQuery(Select *p){
97430 Expr *pExpr;
97431 ExprList *pEList = p->pEList;
97432
97433 if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
97434 pExpr = pEList->a[0].pExpr;
97435 if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
97436 if( NEVER(ExprHasProperty(pExpr, EP_xIsSelect)) ) return 0;
97437 pEList = pExpr->x.pList;
97438 if( pEList==0 || pEList->nExpr!=1 ) return 0;
97439 if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
97440 assert( !ExprHasProperty(pExpr, EP_IntValue) );
97441 if( sqlite3StrICmp(pExpr->u.zToken,"min")==0 ){
97442 return WHERE_ORDERBY_MIN;
97443 }else if( sqlite3StrICmp(pExpr->u.zToken,"max")==0 ){
97444 return WHERE_ORDERBY_MAX;
97445 }
97446 return WHERE_ORDERBY_NORMAL;
 
 
 
 
 
 
 
 
 
97447 }
97448
97449 /*
97450 ** The select statement passed as the first argument is an aggregate query.
97451 ** The second argment is the associated aggregate-info object. This
@@ -97536,10 +97800,11 @@
97536 int i, j, k;
97537 SrcList *pTabList;
97538 ExprList *pEList;
97539 struct SrcList_item *pFrom;
97540 sqlite3 *db = pParse->db;
 
97541
97542 if( db->mallocFailed ){
97543 return WRC_Abort;
97544 }
97545 if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
@@ -97621,11 +97886,11 @@
97621 **
97622 ** The first loop just checks to see if there are any "*" operators
97623 ** that need expanding.
97624 */
97625 for(k=0; k<pEList->nExpr; k++){
97626 Expr *pE = pEList->a[k].pExpr;
97627 if( pE->op==TK_ALL ) break;
97628 assert( pE->op!=TK_DOT || pE->pRight!=0 );
97629 assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
97630 if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
97631 }
@@ -97639,14 +97904,22 @@
97639 ExprList *pNew = 0;
97640 int flags = pParse->db->flags;
97641 int longNames = (flags & SQLITE_FullColNames)!=0
97642 && (flags & SQLITE_ShortColNames)==0;
97643
 
 
 
 
 
 
 
97644 for(k=0; k<pEList->nExpr; k++){
97645 Expr *pE = a[k].pExpr;
97646 assert( pE->op!=TK_DOT || pE->pRight!=0 );
97647 if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight->op!=TK_ALL) ){
 
97648 /* This particular expression does not need to be expanded.
97649 */
97650 pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
97651 if( pNew ){
97652 pNew->a[pNew->nExpr-1].zName = a[k].zName;
@@ -97657,44 +97930,56 @@
97657 a[k].pExpr = 0;
97658 }else{
97659 /* This expression is a "*" or a "TABLE.*" and needs to be
97660 ** expanded. */
97661 int tableSeen = 0; /* Set to 1 when TABLE matches */
97662 char *zTName; /* text of name of TABLE */
97663 if( pE->op==TK_DOT ){
97664 assert( pE->pLeft!=0 );
97665 assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
97666 zTName = pE->pLeft->u.zToken;
97667 }else{
97668 zTName = 0;
97669 }
97670 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
97671 Table *pTab = pFrom->pTab;
 
97672 char *zTabName = pFrom->zAlias;
 
 
97673 if( zTabName==0 ){
97674 zTabName = pTab->zName;
97675 }
97676 if( db->mallocFailed ) break;
97677 if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
97678 continue;
 
 
 
 
 
97679 }
97680 tableSeen = 1;
97681 for(j=0; j<pTab->nCol; j++){
97682 Expr *pExpr, *pRight;
97683 char *zName = pTab->aCol[j].zName;
97684 char *zColname; /* The computed column name */
97685 char *zToFree; /* Malloced string that needs to be freed */
97686 Token sColname; /* Computed column name as a token */
 
 
 
 
 
 
 
97687
97688 /* If a column is marked as 'hidden' (currently only possible
97689 ** for virtual tables), do not include it in the expanded
97690 ** result-set list.
97691 */
97692 if( IsHiddenColumn(&pTab->aCol[j]) ){
97693 assert(IsVirtual(pTab));
97694 continue;
97695 }
 
97696
97697 if( i>0 && zTName==0 ){
97698 if( (pFrom->jointype & JT_NATURAL)!=0
97699 && tableAndColumnIndex(pTabList, i, zName, 0, 0)
97700 ){
@@ -97713,10 +97998,14 @@
97713 zToFree = 0;
97714 if( longNames || pTabList->nSrc>1 ){
97715 Expr *pLeft;
97716 pLeft = sqlite3Expr(db, TK_ID, zTabName);
97717 pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
 
 
 
 
97718 if( longNames ){
97719 zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
97720 zToFree = zColname;
97721 }
97722 }else{
@@ -97724,10 +98013,22 @@
97724 }
97725 pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
97726 sColname.z = zColname;
97727 sColname.n = sqlite3Strlen30(zColname);
97728 sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
 
 
 
 
 
 
 
 
 
 
 
 
97729 sqlite3DbFree(db, zToFree);
97730 }
97731 }
97732 if( !tableSeen ){
97733 if( zTName ){
@@ -98781,15 +99082,21 @@
98781 ** index or indices to use) should place a different priority on
98782 ** satisfying the 'ORDER BY' clause than it does in other cases.
98783 ** Refer to code and comments in where.c for details.
98784 */
98785 ExprList *pMinMax = 0;
98786 u8 flag = minMaxQuery(p);
 
 
 
 
 
 
 
 
98787 if( flag ){
98788 assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
98789 assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 );
98790 pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
98791 pDel = pMinMax;
98792 if( pMinMax && !db->mallocFailed ){
98793 pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
98794 pMinMax->a[0].pExpr->op = TK_COLUMN;
98795 }
@@ -102673,11 +102980,11 @@
102673 #define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */
102674 #define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */
102675 #define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */
102676 #define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
102677 #define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
102678 #define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */
102679 #define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
102680 #define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
102681 #define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
102682 #define WHERE_IDX_ONLY 0x00400000 /* Use index only - omit table */
102683 #define WHERE_ORDERED 0x00800000 /* Output will appear in correct order */
@@ -102823,11 +103130,11 @@
102823 sqlite3DbFree(db, pOld);
102824 }
102825 pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
102826 }
102827 pTerm = &pWC->a[idx = pWC->nTerm++];
102828 pTerm->pExpr = p;
102829 pTerm->wtFlags = wtFlags;
102830 pTerm->pWC = pWC;
102831 pTerm->iParent = -1;
102832 return idx;
102833 }
@@ -102983,27 +103290,36 @@
102983
102984 /*
102985 ** Commute a comparison operator. Expressions of the form "X op Y"
102986 ** are converted into "Y op X".
102987 **
102988 ** If a collation sequence is associated with either the left or right
 
102989 ** side of the comparison, it remains associated with the same side after
102990 ** the commutation. So "Y collate NOCASE op X" becomes
102991 ** "X collate NOCASE op Y". This is because any collation sequence on
102992 ** the left hand side of a comparison overrides any collation sequence
102993 ** attached to the right. For the same reason the EP_ExpCollate flag
102994 ** is not commuted.
102995 */
102996 static void exprCommute(Parse *pParse, Expr *pExpr){
102997 u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
102998 u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
102999 assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
103000 pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
103001 pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
103002 SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
103003 pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;
103004 pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;
 
 
 
 
 
 
 
 
103005 SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
103006 if( pExpr->op>=TK_GT ){
103007 assert( TK_LT==TK_GT+2 );
103008 assert( TK_GE==TK_LE+2 );
103009 assert( TK_GT>TK_EQ );
@@ -103076,16 +103392,16 @@
103076 ** it to be useful for optimising expression pX. Store this
103077 ** value in variable pColl.
103078 */
103079 assert(pX->pLeft);
103080 pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
103081 assert(pColl || pParse->nErr);
103082
103083 for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
103084 if( NEVER(j>=pIdx->nColumn) ) return 0;
103085 }
103086 if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
103087 }
103088 return pTerm;
103089 }
103090 }
103091 }
@@ -103600,10 +103916,11 @@
103600 return;
103601 }
103602 pTerm = &pWC->a[idxTerm];
103603 pMaskSet = pWC->pMaskSet;
103604 pExpr = pTerm->pExpr;
 
103605 prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
103606 op = pExpr->op;
103607 if( op==TK_IN ){
103608 assert( pExpr->pRight==0 );
103609 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
@@ -103626,12 +103943,12 @@
103626 pTerm->prereqAll = prereqAll;
103627 pTerm->leftCursor = -1;
103628 pTerm->iParent = -1;
103629 pTerm->eOperator = 0;
103630 if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
103631 Expr *pLeft = pExpr->pLeft;
103632 Expr *pRight = pExpr->pRight;
103633 if( pLeft->op==TK_COLUMN ){
103634 pTerm->leftCursor = pLeft->iTable;
103635 pTerm->u.leftColumn = pLeft->iColumn;
103636 pTerm->eOperator = operatorMask(op);
103637 }
@@ -103655,11 +103972,11 @@
103655 }else{
103656 pDup = pExpr;
103657 pNew = pTerm;
103658 }
103659 exprCommute(pParse, pDup);
103660 pLeft = pDup->pLeft;
103661 pNew->leftCursor = pLeft->iTable;
103662 pNew->u.leftColumn = pLeft->iColumn;
103663 testcase( (prereqLeft | extraRight) != prereqLeft );
103664 pNew->prereqRight = prereqLeft | extraRight;
103665 pNew->prereqAll = prereqAll;
@@ -103734,11 +104051,11 @@
103734 Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */
103735 Expr *pNewExpr1;
103736 Expr *pNewExpr2;
103737 int idxNew1;
103738 int idxNew2;
103739 CollSeq *pColl; /* Collating sequence to use */
103740
103741 pLeft = pExpr->x.pList->a[1].pExpr;
103742 pStr2 = sqlite3ExprDup(db, pStr1, 0);
103743 if( !db->mallocFailed ){
103744 u8 c, *pC; /* Last character before the first wildcard */
@@ -103756,20 +104073,23 @@
103756
103757 c = sqlite3UpperToLower[c];
103758 }
103759 *pC = c + 1;
103760 }
103761 pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0);
 
 
103762 pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
103763 sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
103764 pStr1, 0);
103765 idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
103766 testcase( idxNew1==0 );
103767 exprAnalyze(pSrc, pWC, idxNew1);
 
103768 pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
103769 sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
103770 pStr2, 0);
103771 idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
103772 testcase( idxNew2==0 );
103773 exprAnalyze(pSrc, pWC, idxNew2);
103774 pTerm = &pWC->a[idxTerm];
103775 if( isComplete ){
@@ -103883,16 +104203,16 @@
103883 ){
103884 int i;
103885 const char *zColl = pIdx->azColl[iCol];
103886
103887 for(i=0; i<pList->nExpr; i++){
103888 Expr *p = pList->a[i].pExpr;
103889 if( p->op==TK_COLUMN
103890 && p->iColumn==pIdx->aiColumn[iCol]
103891 && p->iTable==iBase
103892 ){
103893 CollSeq *pColl = sqlite3ExprCollSeq(pParse, p);
103894 if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
103895 return i;
103896 }
103897 }
103898 }
@@ -103935,11 +104255,11 @@
103935 ** matching "col=X" expression and the column is on the same table as pIdx,
103936 ** set the corresponding bit in variable mask.
103937 */
103938 for(i=0; i<pDistinct->nExpr; i++){
103939 WhereTerm *pTerm;
103940 Expr *p = pDistinct->a[i].pExpr;
103941 if( p->op!=TK_COLUMN ) return 0;
103942 pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
103943 if( pTerm ){
103944 Expr *pX = pTerm->pExpr;
103945 CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -103987,11 +104307,11 @@
103987 /* If any of the expressions is an IPK column on table iBase, then return
103988 ** true. Note: The (p->iTable==iBase) part of this test may be false if the
103989 ** current SELECT is a correlated sub-query.
103990 */
103991 for(i=0; i<pDistinct->nExpr; i++){
103992 Expr *p = pDistinct->a[i].pExpr;
103993 if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
103994 }
103995
103996 /* Loop through all indices on the table, checking each to see if it makes
103997 ** the DISTINCT qualifier redundant. It does so if:
@@ -104464,11 +104784,11 @@
104464 for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
104465 if( pTerm->leftCursor != pSrc->iCursor ) continue;
104466 assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104467 testcase( pTerm->eOperator==WO_IN );
104468 testcase( pTerm->eOperator==WO_ISNULL );
104469 if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
104470 if( pTerm->wtFlags & TERM_VNULL ) continue;
104471 nTerm++;
104472 }
104473
104474 /* If the ORDER BY clause contains only columns in the current
@@ -104512,29 +104832,32 @@
104512 *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
104513 *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
104514 pUsage;
104515
104516 for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
 
104517 if( pTerm->leftCursor != pSrc->iCursor ) continue;
104518 assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104519 testcase( pTerm->eOperator==WO_IN );
104520 testcase( pTerm->eOperator==WO_ISNULL );
104521 if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
104522 if( pTerm->wtFlags & TERM_VNULL ) continue;
104523 pIdxCons[j].iColumn = pTerm->u.leftColumn;
104524 pIdxCons[j].iTermOffset = i;
104525 pIdxCons[j].op = (u8)pTerm->eOperator;
 
 
104526 /* The direct assignment in the previous line is possible only because
104527 ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
104528 ** following asserts verify this fact. */
104529 assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
104530 assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
104531 assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
104532 assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
104533 assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
104534 assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
104535 assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
104536 j++;
104537 }
104538 for(i=0; i<nOrderBy; i++){
104539 Expr *pExpr = pOrderBy->a[i].pExpr;
104540 pIdxOrderBy[i].iColumn = pExpr->iColumn;
@@ -104616,10 +104939,11 @@
104616 struct sqlite3_index_constraint *pIdxCons;
104617 struct sqlite3_index_constraint_usage *pUsage;
104618 WhereTerm *pTerm;
104619 int i, j;
104620 int nOrderBy;
 
104621 double rCost;
104622
104623 /* Make sure wsFlags is initialized to some sane value. Otherwise, if the
104624 ** malloc in allocateIndexInfo() fails and this function returns leaving
104625 ** wsFlags in an uninitialized state, the caller may behave unpredictably.
@@ -104650,63 +104974,91 @@
104650 ** sqlite3ViewGetColumnNames() would have picked up the error.
104651 */
104652 assert( pTab->azModuleArg && pTab->azModuleArg[0] );
104653 assert( sqlite3GetVTable(pParse->db, pTab) );
104654
104655 /* Set the aConstraint[].usable fields and initialize all
104656 ** output variables to zero.
104657 **
104658 ** aConstraint[].usable is true for constraints where the right-hand
104659 ** side contains only references to tables to the left of the current
104660 ** table. In other words, if the constraint is of the form:
104661 **
104662 ** column = expr
104663 **
104664 ** and we are evaluating a join, then the constraint on column is
104665 ** only valid if all tables referenced in expr occur to the left
104666 ** of the table containing column.
104667 **
104668 ** The aConstraints[] array contains entries for all constraints
104669 ** on the current table. That way we only have to compute it once
104670 ** even though we might try to pick the best index multiple times.
104671 ** For each attempt at picking an index, the order of tables in the
104672 ** join might be different so we have to recompute the usable flag
104673 ** each time.
104674 */
104675 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
104676 pUsage = pIdxInfo->aConstraintUsage;
104677 for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
104678 j = pIdxCons->iTermOffset;
104679 pTerm = &pWC->a[j];
104680 pIdxCons->usable = (pTerm->prereqRight&p->notReady) ? 0 : 1;
104681 }
104682 memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
104683 if( pIdxInfo->needToFreeIdxStr ){
104684 sqlite3_free(pIdxInfo->idxStr);
104685 }
104686 pIdxInfo->idxStr = 0;
104687 pIdxInfo->idxNum = 0;
104688 pIdxInfo->needToFreeIdxStr = 0;
104689 pIdxInfo->orderByConsumed = 0;
104690 /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
104691 pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
104692 nOrderBy = pIdxInfo->nOrderBy;
104693 if( !p->pOrderBy ){
104694 pIdxInfo->nOrderBy = 0;
104695 }
104696
104697 if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
104698 return;
104699 }
104700
104701 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
104702 for(i=0; i<pIdxInfo->nConstraint; i++){
104703 if( pUsage[i].argvIndex>0 ){
104704 p->cost.used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
104705 }
104706 }
104707
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104708 /* If there is an ORDER BY clause, and the selected virtual table index
104709 ** does not satisfy it, increase the cost of the scan accordingly. This
104710 ** matches the processing for non-virtual tables in bestBtreeIndex().
104711 */
104712 rCost = pIdxInfo->estimatedCost;
@@ -105273,11 +105625,11 @@
105273 WhereTerm *pConstraint; /* A constraint in the WHERE clause */
105274
105275 /* If the next term of the ORDER BY clause refers to anything other than
105276 ** a column in the "base" table, then this index will not be of any
105277 ** further use in handling the ORDER BY. */
105278 pOBExpr = pOBItem->pExpr;
105279 if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
105280 break;
105281 }
105282
105283 /* Find column number and collating sequence for the next entry
@@ -105299,11 +105651,11 @@
105299 /* Check to see if the column number and collating sequence of the
105300 ** index match the column number and collating sequence of the ORDER BY
105301 ** clause entry. Set isMatch to 1 if they both match. */
105302 if( pOBExpr->iColumn==iColumn ){
105303 if( zColl ){
105304 pColl = sqlite3ExprCollSeq(pParse, pOBExpr);
105305 if( !pColl ) pColl = db->pDfltColl;
105306 isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
105307 }else{
105308 isMatch = 1;
105309 }
@@ -105440,10 +105792,15 @@
105440 int idxEqTermMask; /* Index mask of valid equality operators */
105441 Index sPk; /* A fake index object for the primary key */
105442 tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
105443 int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
105444 int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */
 
 
 
 
 
105445
105446 /* Initialize the cost to a worst-case value */
105447 memset(&p->cost, 0, sizeof(p->cost));
105448 p->cost.rCost = SQLITE_BIG_DBL;
105449
@@ -105488,10 +105845,21 @@
105488 WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
105489 );
105490 eqTermMask = WO_EQ|WO_IN;
105491 pIdx = 0;
105492 }
 
 
 
 
 
 
 
 
 
 
 
105493
105494 /* Loop over all indices looking for the best one to use
105495 */
105496 for(; pProbe; pIdx=pProbe=pProbe->pNext){
105497 const tRowcnt * const aiRowEst = pProbe->aiRowEst;
@@ -105566,15 +105934,13 @@
105566 */
105567 int bInEst = 0; /* True if "x IN (SELECT...)" seen */
105568 int nInMul = 1; /* Number of distinct equalities to lookup */
105569 double rangeDiv = (double)1; /* Estimated reduction in search space */
105570 int nBound = 0; /* Number of range constraints seen */
105571 int bSort; /* True if external sort required */
105572 int bDist; /* True if index cannot help with DISTINCT */
105573 int bLookup = 0; /* True if not a covering index */
105574 int nPriorSat; /* ORDER BY terms satisfied by outer loops */
105575 int nOrderBy; /* Number of ORDER BY terms */
105576 WhereTerm *pTerm; /* A single term of the WHERE clause */
105577 #ifdef SQLITE_ENABLE_STAT3
105578 WhereTerm *pFirstTerm = 0; /* First term matching the index */
105579 #endif
105580
@@ -105581,20 +105947,11 @@
105581 WHERETRACE((
105582 " %s(%s):\n",
105583 pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
105584 ));
105585 memset(&pc, 0, sizeof(pc));
105586 nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
105587 if( p->i ){
105588 nPriorSat = pc.plan.nOBSat = p->aLevel[p->i-1].plan.nOBSat;
105589 bSort = nPriorSat<nOrderBy;
105590 bDist = 0;
105591 }else{
105592 nPriorSat = pc.plan.nOBSat = 0;
105593 bSort = nOrderBy>0;
105594 bDist = p->pDistinct!=0;
105595 }
105596
105597 /* Determine the values of pc.plan.nEq and nInMul */
105598 for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
105599 int j = pProbe->aiColumn[pc.plan.nEq];
105600 pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
@@ -106466,32 +106823,40 @@
106466 if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
106467 /* Case 0: The table is a virtual-table. Use the VFilter and VNext
106468 ** to access the data.
106469 */
106470 int iReg; /* P3 Value for OP_VFilter */
 
106471 sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
106472 int nConstraint = pVtabIdx->nConstraint;
106473 struct sqlite3_index_constraint_usage *aUsage =
106474 pVtabIdx->aConstraintUsage;
106475 const struct sqlite3_index_constraint *aConstraint =
106476 pVtabIdx->aConstraint;
106477
106478 sqlite3ExprCachePush(pParse);
106479 iReg = sqlite3GetTempRange(pParse, nConstraint+2);
 
106480 for(j=1; j<=nConstraint; j++){
106481 for(k=0; k<nConstraint; k++){
106482 if( aUsage[k].argvIndex==j ){
106483 int iTerm = aConstraint[k].iTermOffset;
106484 sqlite3ExprCode(pParse, pWC->a[iTerm].pExpr->pRight, iReg+j+1);
 
 
 
 
 
 
106485 break;
106486 }
106487 }
106488 if( k==nConstraint ) break;
106489 }
106490 sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
106491 sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
106492 sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrBrk, iReg, pVtabIdx->idxStr,
106493 pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
106494 pVtabIdx->needToFreeIdxStr = 0;
106495 for(j=0; j<nConstraint; j++){
106496 if( aUsage[j].omit ){
106497 int iTerm = aConstraint[j].iTermOffset;
@@ -108134,10 +108499,11 @@
108134 Expr* yy122;
108135 Select* yy159;
108136 IdList* yy180;
108137 struct {int value; int mask;} yy207;
108138 u8 yy258;
 
108139 struct LikeOp yy318;
108140 TriggerStep* yy327;
108141 ExprSpan yy342;
108142 SrcList* yy347;
108143 int yy392;
@@ -110084,22 +110450,19 @@
110084 case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
110085 case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
110086 case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
110087 case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
110088 case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
110089 case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120);
110090 case 121: /* distinct ::= */ yytestcase(yyruleno==121);
110091 case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
110092 case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
110093 {yygotominor.yy392 = 0;}
110094 break;
110095 case 29: /* ifnotexists ::= IF NOT EXISTS */
110096 case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
110097 case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
110098 case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
110099 case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
110100 case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119);
110101 case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
110102 case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
110103 {yygotominor.yy392 = 1;}
110104 break;
110105 case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
@@ -110335,12 +110698,19 @@
110335 case 116: /* multiselect_op ::= UNION ALL */
110336 {yygotominor.yy392 = TK_ALL;}
110337 break;
110338 case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
110339 {
110340 yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
110341 }
 
 
 
 
 
 
 
110342 break;
110343 case 122: /* sclp ::= selcollist COMMA */
110344 case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
110345 {yygotominor.yy442 = yymsp[-1].minor.yy442;}
110346 break;
@@ -110406,14 +110776,24 @@
110406 break;
110407 case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
110408 {
110409 if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
110410 yygotominor.yy347 = yymsp[-4].minor.yy347;
 
 
 
 
 
 
 
 
 
 
110411 }else{
110412 Select *pSubquery;
110413 sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
110414 pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,0,0,0);
110415 yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
110416 }
110417 }
110418 break;
110419 case 137: /* dbnm ::= */
@@ -110624,11 +111004,11 @@
110624 spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
110625 }
110626 break;
110627 case 194: /* expr ::= expr COLLATE ids */
110628 {
110629 yygotominor.yy342.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
110630 yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
110631 yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
110632 }
110633 break;
110634 case 195: /* expr ::= CAST LP expr AS typetoken RP */
@@ -110642,11 +111022,11 @@
110642 if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
110643 sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
110644 }
110645 yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
110646 spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
110647 if( yymsp[-2].minor.yy392 && yygotominor.yy342.pExpr ){
110648 yygotominor.yy342.pExpr->flags |= EP_Distinct;
110649 }
110650 }
110651 break;
110652 case 197: /* expr ::= ID LP STAR RP */
@@ -110883,28 +111263,20 @@
110883 case 244: /* uniqueflag ::= */
110884 {yygotominor.yy392 = OE_None;}
110885 break;
110886 case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
110887 {
110888 Expr *p = 0;
110889 if( yymsp[-1].minor.yy0.n>0 ){
110890 p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
110891 sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
110892 }
110893 yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
110894 sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
110895 sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
110896 if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
110897 }
110898 break;
110899 case 248: /* idxlist ::= nm collate sortorder */
110900 {
110901 Expr *p = 0;
110902 if( yymsp[-1].minor.yy0.n>0 ){
110903 p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
110904 sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
110905 }
110906 yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
110907 sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
110908 sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
110909 if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
110910 }
@@ -141105,10 +141477,11 @@
141105 extern int Sqlitemultiplex_Init(Tcl_Interp*);
141106 extern int SqliteSuperlock_Init(Tcl_Interp*);
141107 extern int SqlitetestSyscall_Init(Tcl_Interp*);
141108 extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
141109 extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
 
141110
141111 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141112 extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
141113 #endif
141114
@@ -141148,10 +141521,11 @@
141148 Sqlitemultiplex_Init(interp);
141149 SqliteSuperlock_Init(interp);
141150 SqlitetestSyscall_Init(interp);
141151 Sqlitetestfuzzer_Init(interp);
141152 Sqlitetestwholenumber_Init(interp);
 
141153
141154 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141155 Sqlitetestfts3_Init(interp);
141156 #endif
141157
141158
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.7.16. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -671,13 +671,13 @@
671 **
672 ** See also: [sqlite3_libversion()],
673 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674 ** [sqlite_version()] and [sqlite_source_id()].
675 */
676 #define SQLITE_VERSION "3.7.16"
677 #define SQLITE_VERSION_NUMBER 3007016
678 #define SQLITE_SOURCE_ID "2012-12-08 06:46:05 e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0"
679
680 /*
681 ** CAPI3REF: Run-Time Library Version Numbers
682 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
683 **
@@ -2162,11 +2162,11 @@
2162 ** database connection is opened. By default, URI handling is globally
2163 ** disabled. The default value may be changed by compiling with the
2164 ** [SQLITE_USE_URI] symbol defined.
2165 **
2166 ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
2167 ** <dd> This option takes a single integer argument which is interpreted as
2168 ** a boolean in order to enable or disable the use of covering indices for
2169 ** full table scans in the query optimizer. The default setting is determined
2170 ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
2171 ** if that compile-time option is omitted.
2172 ** The ability to disable the use of covering indices for full table scans
@@ -10573,24 +10573,24 @@
10573 ** and the value of Index.onError indicate the which conflict resolution
10574 ** algorithm to employ whenever an attempt is made to insert a non-unique
10575 ** element.
10576 */
10577 struct Index {
10578 char *zName; /* Name of this index */
10579 int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10580 tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */
10581 Table *pTable; /* The SQL table being indexed */
10582 char *zColAff; /* String defining the affinity of each column */
10583 Index *pNext; /* The next index associated with the same table */
10584 Schema *pSchema; /* Schema containing this index */
10585 u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
10586 char **azColl; /* Array of collation sequence names for index */
10587 int tnum; /* DB Page containing root of this index */
10588 u16 nColumn; /* Number of columns in table used by this index */
10589 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10590 unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
10591 unsigned bUnordered:1; /* Use this index for == or IN queries only */
10592 #ifdef SQLITE_ENABLE_STAT3
10593 int nSample; /* Number of elements in aSample[] */
10594 tRowcnt avgEq; /* Average nEq value for key values not in aSample */
10595 IndexSample *aSample; /* Samples of the left-most key */
10596 #endif
@@ -10767,11 +10767,10 @@
10767 Expr *pRight; /* Right subnode */
10768 union {
10769 ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
10770 Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
10771 } x;
 
10772
10773 /* If the EP_Reduced flag is set in the Expr.flags mask, then no
10774 ** space is allocated for the fields below this point. An attempt to
10775 ** access them will result in a segfault or malfunction.
10776 *********************************************************************/
@@ -10803,11 +10802,11 @@
10802 #define EP_Error 0x0008 /* Expression contains one or more errors */
10803 #define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
10804 #define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
10805 #define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
10806 #define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
10807 #define EP_Collate 0x0100 /* Tree contains a TK_COLLATE opeartor */
10808 #define EP_FixedDest 0x0200 /* Result needed in a specific register */
10809 #define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
10810 #define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
10811 #define EP_Hint 0x1000 /* Not used */
10812 #define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
@@ -10861,22 +10860,31 @@
10860 ** name. An expr/name combination can be used in several ways, such
10861 ** as the list of "expr AS ID" fields following a "SELECT" or in the
10862 ** list of "ID = expr" items in an UPDATE. A list of expressions can
10863 ** also be used as the argument to a function, in which case the a.zName
10864 ** field is not used.
10865 **
10866 ** By default the Expr.zSpan field holds a human-readable description of
10867 ** the expression that is used in the generation of error messages and
10868 ** column labels. In this case, Expr.zSpan is typically the text of a
10869 ** column expression as it exists in a SELECT statement. However, if
10870 ** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name
10871 ** of the result column in the form: DATABASE.TABLE.COLUMN. This later
10872 ** form is used for name resolution with nested FROM clauses.
10873 */
10874 struct ExprList {
10875 int nExpr; /* Number of expressions on the list */
10876 int iECursor; /* VDBE Cursor associated with this ExprList */
10877 struct ExprList_item { /* For each expression in the list */
10878 Expr *pExpr; /* The list of expressions */
10879 char *zName; /* Token associated with this expression */
10880 char *zSpan; /* Original text of the expression */
10881 u8 sortOrder; /* 1 for DESC or 0 for ASC */
10882 unsigned done :1; /* A flag to indicate when processing is finished */
10883 unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
10884 u16 iOrderByCol; /* For ORDER BY, column number in result set */
10885 u16 iAlias; /* Index into Parse.aAlias[] for zName */
10886 } *a; /* Alloc a power of two greater or equal to nExpr */
10887 };
10888
10889 /*
10890 ** An instance of this structure is used by the parser to record both
@@ -11192,10 +11200,11 @@
11200 #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
11201 #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
11202 #define SF_UseSorter 0x0040 /* Sort using a sorter */
11203 #define SF_Values 0x0080 /* Synthesized from VALUES clause */
11204 #define SF_Materialize 0x0100 /* Force materialization of views */
11205 #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
11206
11207
11208 /*
11209 ** The results of a select can be distributed in several ways. The
11210 ** "SRT" prefix means "SELECT Result Type".
@@ -11420,10 +11429,11 @@
11429 #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
11430 #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
11431 #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
11432 #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
11433 #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
11434 #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
11435
11436 /*
11437 * Each trigger present in the database schema is stored as an instance of
11438 * struct Trigger.
11439 *
@@ -11904,11 +11914,11 @@
11914 SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
11915 Token*, int, int);
11916 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
11917 SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
11918 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
11919 Expr*,ExprList*,u16,Expr*,Expr*);
11920 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
11921 SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
11922 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
11923 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
11924 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
@@ -12112,12 +12122,13 @@
12122 SQLITE_PRIVATE const char *sqlite3ErrStr(int);
12123 SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
12124 SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
12125 SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
12126 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
12127 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
12128 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
12129 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
12130 SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
12131 SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
12132 SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
12133 SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
12134 SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
@@ -12160,10 +12171,11 @@
12171 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
12172 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
12173 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
12174 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
12175 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
12176 SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
12177 SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
12178 SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
12179 SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
12180 SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
12181 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -12298,12 +12310,14 @@
12310 #define sqlite3FkOldmask(a,b) 0
12311 #define sqlite3FkRequired(a,b,c,d) 0
12312 #endif
12313 #ifndef SQLITE_OMIT_FOREIGN_KEY
12314 SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*);
12315 SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**);
12316 #else
12317 #define sqlite3FkDelete(a,b)
12318 #define sqlite3FkLocateIndex(a,b,c,d,e)
12319 #endif
12320
12321
12322 /*
12323 ** Available fault injectors. Should be numbered beginning with 0.
@@ -23307,15 +23321,11 @@
23321 { "pwrite64", (sqlite3_syscall_ptr)0, 0 },
23322 #endif
23323 #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
23324 aSyscall[13].pCurrent)
23325
 
23326 { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
 
 
 
23327 #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
23328
23329 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
23330 { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
23331 #else
@@ -23336,13 +23346,10 @@
23346 #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
23347
23348 { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
23349 #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
23350
 
 
 
23351 }; /* End of the overrideable system calls */
23352
23353 /*
23354 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
23355 ** "unix" VFSes. Return SQLITE_OK opon successfully updating the
@@ -23443,31 +23450,29 @@
23450 ** process that is able to write to the database will also be able to
23451 ** recover the hot journals.
23452 */
23453 static int robust_open(const char *z, int f, mode_t m){
23454 int fd;
23455 mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
 
 
 
 
 
 
 
23456 do{
23457 #if defined(O_CLOEXEC)
23458 fd = osOpen(z,f|O_CLOEXEC,m2);
23459 #else
23460 fd = osOpen(z,f,m2);
23461 #endif
23462 }while( fd<0 && errno==EINTR );
23463 if( fd>=0 ){
23464 if( m!=0 ){
23465 struct stat statbuf;
23466 if( osFstat(fd, &statbuf)==0 && (statbuf.st_mode&0777)!=m ){
23467 osFchmod(fd, m);
23468 }
23469 }
23470 #if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
23471 osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
23472 #endif
23473 }
23474 return fd;
23475 }
23476
23477 /*
23478 ** Helper functions to obtain and relinquish the global mutex. The
@@ -29889,11 +29894,11 @@
29894 };
29895 unsigned int i; /* Loop counter */
29896
29897 /* Double-check that the aSyscall[] array has been constructed
29898 ** correctly. See ticket [bb3a86e890c8e96ab] */
29899 assert( ArraySize(aSyscall)==21 );
29900
29901 /* Register all VFSes defined in the aVfs[] array */
29902 for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
29903 sqlite3_vfs_register(&aVfs[i], i==0);
29904 }
@@ -56355,11 +56360,11 @@
56360 sqlite3BtreeLeave(p);
56361 return 0;
56362 }
56363 i = PENDING_BYTE_PAGE(pBt);
56364 if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
56365 sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
56366 sCheck.errMsg.useMalloc = 2;
56367
56368 /* Check the integrity of the freelist
56369 */
56370 checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
@@ -56890,11 +56895,16 @@
56895 /*
56896 ** Parameter zSrcData points to a buffer containing the data for
56897 ** page iSrcPg from the source database. Copy this data into the
56898 ** destination database.
56899 */
56900 static int backupOnePage(
56901 sqlite3_backup *p, /* Backup handle */
56902 Pgno iSrcPg, /* Source database page to backup */
56903 const u8 *zSrcData, /* Source database page data */
56904 int bUpdate /* True for an update, false otherwise */
56905 ){
56906 Pager * const pDestPager = sqlite3BtreePager(p->pDest);
56907 const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
56908 int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
56909 const int nCopy = MIN(nSrcPgsz, nDestPgsz);
56910 const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
@@ -56963,10 +56973,13 @@
56973 ** cached parse of the page). MemPage.isInit is marked
56974 ** "MUST BE FIRST" for this purpose.
56975 */
56976 memcpy(zOut, zIn, nCopy);
56977 ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
56978 if( iOff==0 && bUpdate==0 ){
56979 sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc));
56980 }
56981 }
56982 sqlite3PagerUnref(pDestPg);
56983 }
56984
56985 return rc;
@@ -57069,11 +57082,11 @@
57082 const Pgno iSrcPg = p->iNext; /* Source page number */
57083 if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
57084 DbPage *pSrcPg; /* Source page object */
57085 rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
57086 if( rc==SQLITE_OK ){
57087 rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
57088 sqlite3PagerUnref(pSrcPg);
57089 }
57090 }
57091 p->iNext++;
57092 }
@@ -57317,11 +57330,11 @@
57330 ** the new data into the backup.
57331 */
57332 int rc;
57333 assert( p->pDestDb );
57334 sqlite3_mutex_enter(p->pDestDb->mutex);
57335 rc = backupOnePage(p, iPage, aData, 1);
57336 sqlite3_mutex_leave(p->pDestDb->mutex);
57337 assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
57338 if( rc!=SQLITE_OK ){
57339 p->rc = rc;
57340 }
@@ -59434,26 +59447,22 @@
59447 assert( pKeyInfo->aSortOrder!=0 );
59448 sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
59449 i = sqlite3Strlen30(zTemp);
59450 for(j=0; j<pKeyInfo->nField; j++){
59451 CollSeq *pColl = pKeyInfo->aColl[j];
59452 const char *zColl = pColl ? pColl->zName : "nil";
59453 int n = sqlite3Strlen30(zColl);
59454 if( i+n>nTemp-6 ){
59455 memcpy(&zTemp[i],",...",4);
59456 break;
59457 }
59458 zTemp[i++] = ',';
59459 if( pKeyInfo->aSortOrder[j] ){
59460 zTemp[i++] = '-';
59461 }
59462 memcpy(&zTemp[i], zColl, n+1);
59463 i += n;
 
 
 
 
59464 }
59465 zTemp[i++] = ')';
59466 zTemp[i] = 0;
59467 assert( i<nTemp );
59468 break;
@@ -63839,11 +63848,13 @@
63848 #ifdef SQLITE_DEBUG
63849 /*
63850 ** Print the value of a register for tracing purposes:
63851 */
63852 static void memTracePrint(FILE *out, Mem *p){
63853 if( p->flags & MEM_Invalid ){
63854 fprintf(out, " undefined");
63855 }else if( p->flags & MEM_Null ){
63856 fprintf(out, " NULL");
63857 }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
63858 fprintf(out, " si:%lld", p->u.i);
63859 }else if( p->flags & MEM_Int ){
63860 fprintf(out, " i:%lld", p->u.i);
@@ -64112,10 +64123,11 @@
64123 } af;
64124 struct OP_Concat_stack_vars {
64125 i64 nByte;
64126 } ag;
64127 struct OP_Remainder_stack_vars {
64128 char bIntint; /* Started out as two integer operands */
64129 int flags; /* Combined MEM_* flags from both inputs */
64130 i64 iA; /* Integer value of left operand */
64131 i64 iB; /* Integer value of right operand */
64132 double rA; /* Real value of left operand */
64133 double rB; /* Real value of right operand */
@@ -65021,10 +65033,13 @@
65033 pOut = &aMem[pOp->p2];
65034 assert( pOut!=pIn1 );
65035 while( 1 ){
65036 sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
65037 Deephemeralize(pOut);
65038 #ifdef SQLITE_DEBUG
65039 pOut->pScopyFrom = 0;
65040 #endif
65041 REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
65042 if( (u.ae.n--)==0 ) break;
65043 pOut++;
65044 pIn1++;
65045 }
@@ -65214,10 +65229,11 @@
65229 case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
65230 case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
65231 case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
65232 case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
65233 #if 0 /* local variables moved into u.ah */
65234 char bIntint; /* Started out as two integer operands */
65235 int flags; /* Combined MEM_* flags from both inputs */
65236 i64 iA; /* Integer value of left operand */
65237 i64 iB; /* Integer value of right operand */
65238 double rA; /* Real value of left operand */
65239 double rB; /* Real value of right operand */
@@ -65231,10 +65247,11 @@
65247 u.ah.flags = pIn1->flags | pIn2->flags;
65248 if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
65249 if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
65250 u.ah.iA = pIn1->u.i;
65251 u.ah.iB = pIn2->u.i;
65252 u.ah.bIntint = 1;
65253 switch( pOp->opcode ){
65254 case OP_Add: if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65255 case OP_Subtract: if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65256 case OP_Multiply: if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
65257 case OP_Divide: {
@@ -65251,10 +65268,11 @@
65268 }
65269 }
65270 pOut->u.i = u.ah.iB;
65271 MemSetTypeFlag(pOut, MEM_Int);
65272 }else{
65273 u.ah.bIntint = 0;
65274 fp_math:
65275 u.ah.rA = sqlite3VdbeRealValue(pIn1);
65276 u.ah.rB = sqlite3VdbeRealValue(pIn2);
65277 switch( pOp->opcode ){
65278 case OP_Add: u.ah.rB += u.ah.rA; break;
@@ -65282,11 +65300,11 @@
65300 if( sqlite3IsNaN(u.ah.rB) ){
65301 goto arithmetic_result_is_null;
65302 }
65303 pOut->r = u.ah.rB;
65304 MemSetTypeFlag(pOut, MEM_Real);
65305 if( (u.ah.flags & MEM_Real)==0 && !u.ah.bIntint ){
65306 sqlite3VdbeIntegerAffinity(pOut);
65307 }
65308 #endif
65309 }
65310 break;
@@ -65843,26 +65861,31 @@
65861 /* Opcode: Permutation * * * P4 *
65862 **
65863 ** Set the permutation used by the OP_Compare operator to be the array
65864 ** of integers in P4.
65865 **
65866 ** The permutation is only valid until the next OP_Compare that has
65867 ** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
65868 ** occur immediately prior to the OP_Compare.
65869 */
65870 case OP_Permutation: {
65871 assert( pOp->p4type==P4_INTARRAY );
65872 assert( pOp->p4.ai );
65873 aPermute = pOp->p4.ai;
65874 break;
65875 }
65876
65877 /* Opcode: Compare P1 P2 P3 P4 P5
65878 **
65879 ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
65880 ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
65881 ** the comparison for use by the next OP_Jump instruct.
65882 **
65883 ** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is
65884 ** determined by the most recent OP_Permutation operator. If the
65885 ** OPFLAG_PERMUTE bit is clear, then register are compared in sequential
65886 ** order.
65887 **
65888 ** P4 is a KeyInfo structure that defines collating sequences and sort
65889 ** orders for the comparison. The permutation applies to registers
65890 ** only. The KeyInfo elements are used sequentially.
65891 **
@@ -65880,10 +65903,11 @@
65903 int idx;
65904 CollSeq *pColl; /* Collating sequence to use on this term */
65905 int bRev; /* True for DESCENDING sort order */
65906 #endif /* local variables moved into u.al */
65907
65908 if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
65909 u.al.n = pOp->p3;
65910 u.al.pKeyInfo = pOp->p4.pKeyInfo;
65911 assert( u.al.n>0 );
65912 assert( u.al.pKeyInfo!=0 );
65913 u.al.p1 = pOp->p1;
@@ -66025,12 +66049,10 @@
66049
66050 /* Opcode: Once P1 P2 * * *
66051 **
66052 ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
66053 ** set the flag and fall through to the next instruction.
 
 
66054 */
66055 case OP_Once: { /* jump */
66056 assert( pOp->p1<p->nOnceFlag );
66057 if( p->aOnceFlag[pOp->p1] ){
66058 pc = pOp->p2-1;
@@ -71902,10 +71924,18 @@
71924 p->pReal = pReal;
71925 if( p->iSize>0 ){
71926 assert(p->iSize<=p->nBuf);
71927 rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
71928 }
71929 if( rc!=SQLITE_OK ){
71930 /* If an error occurred while writing to the file, close it before
71931 ** returning. This way, SQLite uses the in-memory journal data to
71932 ** roll back changes made to the internal page-cache before this
71933 ** function was called. */
71934 sqlite3OsClose(pReal);
71935 p->pReal = 0;
71936 }
71937 }
71938 }
71939 return rc;
71940 }
71941
@@ -72565,10 +72595,19 @@
72595 ** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
72596 **
72597 ** The result of random()%5 in the GROUP BY clause is probably different
72598 ** from the result in the result-set. We might fix this someday. Or
72599 ** then again, we might not...
72600 **
72601 ** If the reference is followed by a COLLATE operator, then make sure
72602 ** the COLLATE operator is preserved. For example:
72603 **
72604 ** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
72605 **
72606 ** Should be transformed into:
72607 **
72608 ** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
72609 **
72610 ** The nSubquery parameter specifies how many levels of subquery the
72611 ** alias is removed from the original expression. The usually value is
72612 ** zero but it might be more if the alias is contained within a subquery
72613 ** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
@@ -72589,45 +72628,40 @@
72628 assert( iCol>=0 && iCol<pEList->nExpr );
72629 pOrig = pEList->a[iCol].pExpr;
72630 assert( pOrig!=0 );
72631 assert( pOrig->flags & EP_Resolved );
72632 db = pParse->db;
72633 pDup = sqlite3ExprDup(db, pOrig, 0);
72634 if( pDup==0 ) return;
72635 if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
 
72636 incrAggFunctionDepth(pDup, nSubquery);
72637 pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
72638 if( pDup==0 ) return;
72639 if( pEList->a[iCol].iAlias==0 ){
72640 pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
72641 }
72642 pDup->iTable = pEList->a[iCol].iAlias;
72643 }
72644 if( pExpr->op==TK_COLLATE ){
72645 pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72646 }
72647
72648 /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
72649 ** prevents ExprDelete() from deleting the Expr structure itself,
72650 ** allowing it to be repopulated by the memcpy() on the following line.
72651 ** The pExpr->u.zToken might point into memory that will be freed by the
72652 ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
72653 ** make a copy of the token before doing the sqlite3DbFree().
72654 */
72655 ExprSetProperty(pExpr, EP_Static);
72656 sqlite3ExprDelete(db, pExpr);
72657 memcpy(pExpr, pDup, sizeof(*pExpr));
72658 if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
72659 assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
72660 pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
72661 pExpr->flags2 |= EP2_MallocedToken;
72662 }
72663 sqlite3DbFree(db, pDup);
72664 }
72665
72666
72667 /*
@@ -72644,10 +72678,39 @@
72678 }
72679 }
72680 return 0;
72681 }
72682
72683 /*
72684 ** Subqueries stores the original database, table and column names for their
72685 ** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN".
72686 ** Check to see if the zSpan given to this routine matches the zDb, zTab,
72687 ** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will
72688 ** match anything.
72689 */
72690 SQLITE_PRIVATE int sqlite3MatchSpanName(
72691 const char *zSpan,
72692 const char *zCol,
72693 const char *zTab,
72694 const char *zDb
72695 ){
72696 int n;
72697 for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72698 if( zDb && sqlite3StrNICmp(zSpan, zDb, n)!=0 ){
72699 return 0;
72700 }
72701 zSpan += n+1;
72702 for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
72703 if( zTab && sqlite3StrNICmp(zSpan, zTab, n)!=0 ){
72704 return 0;
72705 }
72706 zSpan += n+1;
72707 if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){
72708 return 0;
72709 }
72710 return 1;
72711 }
72712
72713 /*
72714 ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
72715 ** that name in the set of source tables in pSrcList and make the pExpr
72716 ** expression node refer back to that source column. The following changes
@@ -72699,44 +72762,63 @@
72762
72763 /* Initialize the node to no-match */
72764 pExpr->iTable = -1;
72765 pExpr->pTab = 0;
72766 ExprSetIrreducible(pExpr);
72767
72768 /* Translate the schema name in zDb into a pointer to the corresponding
72769 ** schema. If not found, pSchema will remain NULL and nothing will match
72770 ** resulting in an appropriate error message toward the end of this routine
72771 */
72772 if( zDb ){
72773 for(i=0; i<db->nDb; i++){
72774 assert( db->aDb[i].zName );
72775 if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
72776 pSchema = db->aDb[i].pSchema;
72777 break;
72778 }
72779 }
72780 }
72781
72782 /* Start at the inner-most context and move outward until a match is found */
72783 while( pNC && cnt==0 ){
72784 ExprList *pEList;
72785 SrcList *pSrcList = pNC->pSrcList;
72786
72787 if( pSrcList ){
72788 for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
72789 Table *pTab;
 
72790 Column *pCol;
72791
72792 pTab = pItem->pTab;
72793 assert( pTab!=0 && pTab->zName!=0 );
 
72794 assert( pTab->nCol>0 );
72795 if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
72796 ExprList *pEList = pItem->pSelect->pEList;
72797 int hit = 0;
72798 for(j=0; j<pEList->nExpr; j++){
72799 if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
72800 cnt++;
72801 cntTab = 2;
72802 pMatch = pItem;
72803 pExpr->iColumn = j;
72804 hit = 1;
72805 }
72806 }
72807 if( hit || zTab==0 ) continue;
72808 }
72809 if( zDb && pTab->pSchema!=pSchema ){
72810 continue;
72811 }
72812 if( zTab ){
72813 const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
72814 assert( zTabName!=0 );
72815 if( sqlite3StrICmp(zTabName, zTab)!=0 ){
72816 continue;
 
 
 
 
 
 
 
72817 }
72818 }
72819 if( 0==(cntTab++) ){
 
 
 
72820 pMatch = pItem;
72821 }
72822 for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
72823 if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
72824 /* If there has been exactly one prior match and this match
@@ -72746,21 +72828,23 @@
72828 if( cnt==1 ){
72829 if( pItem->jointype & JT_NATURAL ) continue;
72830 if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
72831 }
72832 cnt++;
 
 
72833 pMatch = pItem;
 
72834 /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
72835 pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
72836 break;
72837 }
72838 }
72839 }
72840 if( pMatch ){
72841 pExpr->iTable = pMatch->iCursor;
72842 pExpr->pTab = pMatch->pTab;
72843 pSchema = pExpr->pTab->pSchema;
72844 }
72845 } /* if( pSrcList ) */
72846
72847 #ifndef SQLITE_OMIT_TRIGGER
72848 /* If we have not already resolved the name, then maybe
72849 ** it is a new.* or old.* trigger argument reference
72850 */
@@ -73055,42 +73139,43 @@
73139 int wrong_num_args = 0; /* True if wrong number of arguments */
73140 int is_agg = 0; /* True if is an aggregate function */
73141 int auth; /* Authorization to use the function */
73142 int nId; /* Number of characters in function name */
73143 const char *zId; /* The function name. */
 
73144 u8 enc = ENC(pParse->db); /* The database encoding */
73145
73146 testcase( pExpr->op==TK_CONST_FUNC );
73147 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
73148 zId = pExpr->u.zToken;
73149 nId = sqlite3Strlen30(zId);
73150 if( pParse->db->init.busy==0 ){
73151 FuncDef *pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
73152 if( pDef==0 ){
73153 pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
73154 if( pDef==0 ){
73155 no_such_func = 1;
73156 }else{
73157 wrong_num_args = 1;
73158 }
73159 }else{
73160 is_agg = pDef->xFunc==0;
73161 }
73162 #ifndef SQLITE_OMIT_AUTHORIZATION
73163 if( pDef ){
73164 auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
73165 if( auth!=SQLITE_OK ){
73166 if( auth==SQLITE_DENY ){
73167 sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
73168 pDef->zName);
73169 pNC->nErr++;
73170 }
73171 pExpr->op = TK_NULL;
73172 return WRC_Prune;
73173 }
73174 }
73175 #endif
73176 }
73177 if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
73178 sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
73179 pNC->nErr++;
73180 is_agg = 0;
73181 }else if( no_such_func ){
@@ -73310,11 +73395,11 @@
73395 assert( pEList!=0 );
73396 for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
73397 int iCol = -1;
73398 Expr *pE, *pDup;
73399 if( pItem->done ) continue;
73400 pE = sqlite3ExprSkipCollate(pItem->pExpr);
73401 if( sqlite3ExprIsInteger(pE, &iCol) ){
73402 if( iCol<=0 || iCol>pEList->nExpr ){
73403 resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
73404 return 1;
73405 }
@@ -73328,18 +73413,24 @@
73413 }
73414 sqlite3ExprDelete(db, pDup);
73415 }
73416 }
73417 if( iCol>0 ){
73418 /* Convert the ORDER BY term into an integer column number iCol,
73419 ** taking care to preserve the COLLATE clause if it exists */
73420 Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
73421 if( pNew==0 ) return 1;
73422 pNew->flags |= EP_IntValue;
73423 pNew->u.iValue = iCol;
73424 if( pItem->pExpr==pE ){
73425 pItem->pExpr = pNew;
73426 }else{
73427 assert( pItem->pExpr->op==TK_COLLATE );
73428 assert( pItem->pExpr->pLeft==pE );
73429 pItem->pExpr->pLeft = pNew;
73430 }
73431 sqlite3ExprDelete(db, pE);
 
 
 
 
 
73432 pItem->iOrderByCol = (u16)iCol;
73433 pItem->done = 1;
73434 }else{
73435 moreToDo = 1;
73436 }
@@ -73440,15 +73531,15 @@
73531 ** sqlite3ResolveOrderGroupBy() will convert the expression to a
73532 ** copy of the iCol-th result-set expression. */
73533 pItem->iOrderByCol = (u16)iCol;
73534 continue;
73535 }
73536 if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
73537 /* The ORDER BY term is an integer constant. Again, set the column
73538 ** number so that sqlite3ResolveOrderGroupBy() will convert the
73539 ** order-by term to a copy of the result-set expression */
73540 if( iCol<1 || iCol>0xffff ){
73541 resolveOutOfRangeError(pParse, zType, i+1, nResult);
73542 return 1;
73543 }
73544 pItem->iOrderByCol = (u16)iCol;
73545 continue;
@@ -73521,27 +73612,10 @@
73612 if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
73613 sqlite3ResolveExprNames(&sNC, p->pOffset) ){
73614 return WRC_Abort;
73615 }
73616
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73617 /* Recursively resolve names in all subqueries
73618 */
73619 for(i=0; i<p->pSrc->nSrc; i++){
73620 struct SrcList_item *pItem = &p->pSrc->a[i];
73621 if( pItem->pSelect ){
@@ -73564,10 +73638,27 @@
73638 for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
73639 assert( pItem->isCorrelated==0 && nRef<=0 );
73640 pItem->isCorrelated = (nRef!=0);
73641 }
73642 }
73643
73644 /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
73645 ** resolve the result-set expression list.
73646 */
73647 sNC.ncFlags = NC_AllowAgg;
73648 sNC.pSrcList = p->pSrc;
73649 sNC.pNext = pOuterNC;
73650
73651 /* Resolve names in the result set. */
73652 pEList = p->pEList;
73653 assert( pEList!=0 );
73654 for(i=0; i<pEList->nExpr; i++){
73655 Expr *pX = pEList->a[i].pExpr;
73656 if( sqlite3ResolveExprNames(&sNC, pX) ){
73657 return WRC_Abort;
73658 }
73659 }
73660
73661 /* If there are no aggregate functions in the result-set, and no GROUP BY
73662 ** expression, do not allow aggregates in any of the other expressions.
73663 */
73664 assert( (p->selFlags & SF_Aggregate)==0 );
@@ -73798,11 +73889,13 @@
73889 ** SELECT * FROM t1 WHERE a;
73890 ** SELECT a AS b FROM t1 WHERE b;
73891 ** SELECT * FROM t1 WHERE (select a from t1);
73892 */
73893 SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
73894 int op;
73895 pExpr = sqlite3ExprSkipCollate(pExpr);
73896 op = pExpr->op;
73897 if( op==TK_SELECT ){
73898 assert( pExpr->flags&EP_xIsSelect );
73899 return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
73900 }
73901 #ifndef SQLITE_OMIT_CAST
@@ -73823,70 +73916,98 @@
73916 }
73917 return pExpr->affinity;
73918 }
73919
73920 /*
73921 ** Set the collating sequence for expression pExpr to be the collating
73922 ** sequence named by pToken. Return a pointer to a new Expr node that
73923 ** implements the COLLATE operator.
73924 **
73925 ** If a memory allocation error occurs, that fact is recorded in pParse->db
73926 ** and the pExpr parameter is returned unchanged.
73927 */
73928 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
73929 if( pCollName->n>0 ){
73930 Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
73931 if( pNew ){
73932 pNew->pLeft = pExpr;
73933 pNew->flags |= EP_Collate;
73934 pExpr = pNew;
73935 }
73936 }
73937 return pExpr;
73938 }
73939 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
73940 Token s;
73941 assert( zC!=0 );
73942 s.z = zC;
73943 s.n = sqlite3Strlen30(s.z);
73944 return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
73945 }
73946
73947 /*
73948 ** Skip over any TK_COLLATE and/or TK_AS operators at the root of
73949 ** an expression.
73950 */
73951 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
73952 while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
73953 pExpr = pExpr->pLeft;
73954 }
73955 return pExpr;
73956 }
73957
73958 /*
73959 ** Return the collation sequence for the expression pExpr. If
73960 ** there is no defined collating sequence, return NULL.
73961 **
73962 ** The collating sequence might be determined by a COLLATE operator
73963 ** or by the presence of a column with a defined collating sequence.
73964 ** COLLATE operators take first precedence. Left operands take
73965 ** precedence over right operands.
73966 */
73967 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
73968 sqlite3 *db = pParse->db;
73969 CollSeq *pColl = 0;
73970 Expr *p = pExpr;
73971 while( p ){
73972 int op = p->op;
73973 if( op==TK_CAST || op==TK_UPLUS ){
73974 p = p->pLeft;
73975 continue;
73976 }
73977 assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
73978 if( op==TK_COLLATE ){
73979 if( db->init.busy ){
73980 /* Do not report errors when parsing while the schema */
73981 pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0);
73982 }else{
73983 pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
73984 }
73985 break;
73986 }
73987 if( p->pTab!=0
73988 && (op==TK_AGG_COLUMN || op==TK_COLUMN
73989 || op==TK_REGISTER || op==TK_TRIGGER)
73990 ){
73991 /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
73992 ** a TK_COLUMN but was previously evaluated and cached in a register */
73993 int j = p->iColumn;
73994 if( j>=0 ){
73995 const char *zColl = p->pTab->aCol[j].zColl;
73996 pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
73997 }
73998 break;
73999 }
74000 if( p->flags & EP_Collate ){
74001 if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
74002 p = p->pLeft;
74003 }else{
74004 p = p->pRight;
74005 }
74006 }else{
74007 break;
74008 }
74009 }
74010 if( sqlite3CheckCollSeq(pParse, pColl) ){
74011 pColl = 0;
74012 }
74013 return pColl;
@@ -73986,16 +74107,14 @@
74107 Expr *pLeft,
74108 Expr *pRight
74109 ){
74110 CollSeq *pColl;
74111 assert( pLeft );
74112 if( pLeft->flags & EP_Collate ){
74113 pColl = sqlite3ExprCollSeq(pParse, pLeft);
74114 }else if( pRight && (pRight->flags & EP_Collate)!=0 ){
74115 pColl = sqlite3ExprCollSeq(pParse, pRight);
 
 
74116 }else{
74117 pColl = sqlite3ExprCollSeq(pParse, pLeft);
74118 if( !pColl ){
74119 pColl = sqlite3ExprCollSeq(pParse, pRight);
74120 }
@@ -74221,21 +74340,15 @@
74340 sqlite3ExprDelete(db, pLeft);
74341 sqlite3ExprDelete(db, pRight);
74342 }else{
74343 if( pRight ){
74344 pRoot->pRight = pRight;
74345 pRoot->flags |= EP_Collate & pRight->flags;
 
 
 
74346 }
74347 if( pLeft ){
74348 pRoot->pLeft = pLeft;
74349 pRoot->flags |= EP_Collate & pLeft->flags;
 
 
 
74350 }
74351 exprSetHeight(pRoot);
74352 }
74353 }
74354
@@ -74489,11 +74602,11 @@
74602 }else{
74603 assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
74604 assert( !ExprHasProperty(p, EP_FromJoin) );
74605 assert( (p->flags2 & EP2_MallocedToken)==0 );
74606 assert( (p->flags2 & EP2_Irreducible)==0 );
74607 if( p->pLeft || p->pRight || p->x.pList ){
74608 nSize = EXPR_REDUCEDSIZE | EP_Reduced;
74609 }else{
74610 nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
74611 }
74612 }
@@ -76513,10 +76626,11 @@
76626 sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
76627 sqlite3ReleaseTempReg(pParse, r3);
76628 sqlite3ReleaseTempReg(pParse, r4);
76629 break;
76630 }
76631 case TK_COLLATE:
76632 case TK_UPLUS: {
76633 inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
76634 break;
76635 }
76636
@@ -76881,10 +76995,16 @@
76995 case TK_UPLUS: zUniOp = "UPLUS"; break;
76996 case TK_BITNOT: zUniOp = "BITNOT"; break;
76997 case TK_NOT: zUniOp = "NOT"; break;
76998 case TK_ISNULL: zUniOp = "ISNULL"; break;
76999 case TK_NOTNULL: zUniOp = "NOTNULL"; break;
77000
77001 case TK_COLLATE: {
77002 sqlite3ExplainExpr(pOut, pExpr->pLeft);
77003 sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
77004 break;
77005 }
77006
77007 case TK_AGG_FUNCTION:
77008 case TK_CONST_FUNC:
77009 case TK_FUNCTION: {
77010 ExprList *pFarg; /* List of function arguments */
@@ -77019,10 +77139,16 @@
77139 for(i=0; i<pList->nExpr; i++){
77140 sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
77141 sqlite3ExplainPush(pOut);
77142 sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
77143 sqlite3ExplainPop(pOut);
77144 if( pList->a[i].zName ){
77145 sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
77146 }
77147 if( pList->a[i].bSpanIsTab ){
77148 sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
77149 }
77150 if( i<pList->nExpr-1 ){
77151 sqlite3ExplainNL(pOut);
77152 }
77153 }
77154 sqlite3ExplainPop(pOut);
@@ -77100,10 +77226,13 @@
77226 switch( pExpr->op ){
77227 case TK_IN:
77228 case TK_REGISTER: {
77229 return WRC_Prune;
77230 }
77231 case TK_COLLATE: {
77232 return WRC_Continue;
77233 }
77234 case TK_FUNCTION:
77235 case TK_AGG_FUNCTION:
77236 case TK_CONST_FUNC: {
77237 /* The arguments to a function have a fixed destination.
77238 ** Mark them this way to avoid generated unneeded OP_SCopy
@@ -77121,13 +77250,15 @@
77250 break;
77251 }
77252 }
77253 if( isAppropriateForFactoring(pExpr) ){
77254 int r1 = ++pParse->nMem;
77255 int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
77256 /* If r2!=r1, it means that register r1 is never used. That is harmless
77257 ** but suboptimal, so we want to know about the situation to fix it.
77258 ** Hence the following assert: */
77259 assert( r2==r1 );
77260 pExpr->op2 = pExpr->op;
77261 pExpr->op = TK_REGISTER;
77262 pExpr->iTable = r2;
77263 return WRC_Prune;
77264 }
@@ -77540,11 +77671,19 @@
77671 assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
77672 if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
77673 return 2;
77674 }
77675 if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
77676 if( pA->op!=pB->op ){
77677 if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
77678 return 1;
77679 }
77680 if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
77681 return 1;
77682 }
77683 return 2;
77684 }
77685 if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
77686 if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
77687 if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
77688 if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
77689 if( ExprHasProperty(pA, EP_IntValue) ){
@@ -77552,15 +77691,13 @@
77691 return 2;
77692 }
77693 }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
77694 if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
77695 if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
77696 return pA->op==TK_COLLATE ? 1 : 2;
77697 }
77698 }
 
 
77699 return 0;
77700 }
77701
77702 /*
77703 ** Compare two ExprList objects. Return 0 if they are identical and
@@ -83371,14 +83508,12 @@
83508 ** specified collation sequence names.
83509 */
83510 for(i=0; i<pList->nExpr; i++){
83511 Expr *pExpr = pList->a[i].pExpr;
83512 if( pExpr ){
83513 CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
83514 if( pColl ){
 
 
83515 nExtra += (1 + sqlite3Strlen30(pColl->zName));
83516 }
83517 }
83518 }
83519
@@ -83437,10 +83572,11 @@
83572 */
83573 for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
83574 const char *zColName = pListItem->zName;
83575 Column *pTabCol;
83576 int requestedSortOrder;
83577 CollSeq *pColl; /* Collating sequence */
83578 char *zColl; /* Collation sequence name */
83579
83580 for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
83581 if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
83582 }
@@ -83449,18 +83585,15 @@
83585 pTab->zName, zColName);
83586 pParse->checkSchema = 1;
83587 goto exit_create_index;
83588 }
83589 pIndex->aiColumn[i] = j;
83590 if( pListItem->pExpr
83591 && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
83592 ){
 
 
 
83593 int nColl;
83594 zColl = pColl->zName;
83595 nColl = sqlite3Strlen30(zColl) + 1;
83596 assert( nExtra>=nColl );
83597 memcpy(zExtra, zColl, nColl);
83598 zColl = zExtra;
83599 zExtra += nColl;
@@ -87489,11 +87622,11 @@
87622
87623 /*
87624 ** A foreign key constraint requires that the key columns in the parent
87625 ** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
87626 ** Given that pParent is the parent table for foreign key constraint pFKey,
87627 ** search the schema for a unique index on the parent key columns.
87628 **
87629 ** If successful, zero is returned. If the parent key is an INTEGER PRIMARY
87630 ** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx
87631 ** is set to point to the unique index.
87632 **
@@ -87525,11 +87658,11 @@
87658 **
87659 ** then non-zero is returned, and a "foreign key mismatch" error loaded
87660 ** into pParse. If an OOM error occurs, non-zero is returned and the
87661 ** pParse->db->mallocFailed flag is set.
87662 */
87663 SQLITE_PRIVATE int sqlite3FkLocateIndex(
87664 Parse *pParse, /* Parse context to store any error in */
87665 Table *pParent, /* Parent table of FK constraint pFKey */
87666 FKey *pFKey, /* Foreign key to find index for */
87667 Index **ppIdx, /* OUT: Unique index on parent table */
87668 int **paiCol /* OUT: Map of index columns in pFKey */
@@ -87622,11 +87755,13 @@
87755 }
87756 }
87757
87758 if( !pIdx ){
87759 if( !pParse->disableTriggers ){
87760 sqlite3ErrorMsg(pParse,
87761 "foreign key mismatch - \"%w\" referencing \"%w\"",
87762 pFKey->pFrom->zName, pFKey->zTo);
87763 }
87764 sqlite3DbFree(pParse->db, aiCol);
87765 return 1;
87766 }
87767
@@ -87858,16 +87993,19 @@
87993 if( pLeft ){
87994 /* Set the collation sequence and affinity of the LHS of each TK_EQ
87995 ** expression to the parent key column defaults. */
87996 if( pIdx ){
87997 Column *pCol;
87998 const char *zColl;
87999 iCol = pIdx->aiColumn[i];
88000 pCol = &pTab->aCol[iCol];
88001 if( pTab->iPKey==iCol ) iCol = -1;
88002 pLeft->iTable = regData+iCol+1;
88003 pLeft->affinity = pCol->affinity;
88004 zColl = pCol->zColl;
88005 if( zColl==0 ) zColl = db->pDfltColl->zName;
88006 pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
88007 }else{
88008 pLeft->iTable = regData;
88009 pLeft->affinity = SQLITE_AFF_INTEGER;
88010 }
88011 }
@@ -88080,11 +88218,11 @@
88218 if( pParse->disableTriggers ){
88219 pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
88220 }else{
88221 pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
88222 }
88223 if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
88224 assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
88225 if( !isIgnoreErrors || db->mallocFailed ) return;
88226 if( pTo==0 ){
88227 /* If isIgnoreErrors is true, then a table is being dropped. In this
88228 ** case SQLite runs a "DELETE FROM xxx" on the table being dropped
@@ -88160,11 +88298,11 @@
88298 /* Inserting a single row into a parent table cannot cause an immediate
88299 ** foreign key violation. So do nothing in this case. */
88300 continue;
88301 }
88302
88303 if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
88304 if( !isIgnoreErrors || db->mallocFailed ) return;
88305 continue;
88306 }
88307 assert( aiCol || pFKey->nCol==1 );
88308
@@ -88215,11 +88353,11 @@
88353 for(p=pTab->pFKey; p; p=p->pNextFrom){
88354 for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
88355 }
88356 for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
88357 Index *pIdx = 0;
88358 sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
88359 if( pIdx ){
88360 for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
88361 }
88362 }
88363 }
@@ -88341,11 +88479,11 @@
88479 ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */
88480 Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */
88481 int i; /* Iterator variable */
88482 Expr *pWhen = 0; /* WHEN clause for the trigger */
88483
88484 if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
88485 assert( aiCol || pFKey->nCol==1 );
88486
88487 for(i=0; i<pFKey->nCol; i++){
88488 Token tOld = { "old", 3 }; /* Literal "old" token */
88489 Token tNew = { "new", 3 }; /* Literal "new" token */
@@ -89843,29 +89981,24 @@
89981 ExprList *pCheck = pTab->pCheck;
89982 pParse->ckBase = regData;
89983 onError = overrideError!=OE_Default ? overrideError : OE_Abort;
89984 for(i=0; i<pCheck->nExpr; i++){
89985 int allOk = sqlite3VdbeMakeLabel(v);
89986 sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
89987 if( onError==OE_Ignore ){
89988 sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
89989 }else{
89990 char *zConsName = pCheck->a[i].zName;
89991 if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
89992 if( zConsName ){
89993 zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
89994 }else{
89995 zConsName = 0;
89996 }
89997 sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
89998 }
89999 sqlite3VdbeResolveLabel(v, allOk);
 
 
 
 
 
90000 }
90001 }
90002 #endif /* !defined(SQLITE_OMIT_CHECK) */
90003
90004 /* If we have an INTEGER PRIMARY KEY, make sure the primary key
@@ -92686,13 +92819,15 @@
92819 if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
92820 Table *pTab;
92821 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
92822 pTab = sqlite3FindTable(db, zRight, zDb);
92823 if( pTab ){
92824 int i, k;
92825 int nHidden = 0;
92826 Column *pCol;
92827 Index *pPk;
92828 for(pPk=pTab->pIndex; pPk && pPk->autoIndex!=2; pPk=pPk->pNext){}
92829 sqlite3VdbeSetNumCols(v, 6);
92830 pParse->nMem = 6;
92831 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
92832 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
92833 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
@@ -92713,12 +92848,18 @@
92848 if( pCol->zDflt ){
92849 sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
92850 }else{
92851 sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
92852 }
92853 if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
92854 k = 0;
92855 }else if( pPk==0 ){
92856 k = 1;
92857 }else{
92858 for(k=1; ALWAYS(k<=pTab->nCol) && pPk->aiColumn[k-1]!=i; k++){}
92859 }
92860 sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
92861 sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
92862 }
92863 }
92864 }else
92865
@@ -92849,10 +92990,124 @@
92990 ++i;
92991 pFK = pFK->pNextFrom;
92992 }
92993 }
92994 }
92995 }else
92996 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
92997
92998 #ifndef SQLITE_OMIT_FOREIGN_KEY
92999 if( sqlite3StrICmp(zLeft, "foreign_key_check")==0 ){
93000 FKey *pFK; /* A foreign key constraint */
93001 Table *pTab; /* Child table contain "REFERENCES" keyword */
93002 Table *pParent; /* Parent table that child points to */
93003 Index *pIdx; /* Index in the parent table */
93004 int i; /* Loop counter: Foreign key number for pTab */
93005 int j; /* Loop counter: Field of the foreign key */
93006 HashElem *k; /* Loop counter: Next table in schema */
93007 int x; /* result variable */
93008 int regResult; /* 3 registers to hold a result row */
93009 int regKey; /* Register to hold key for checking the FK */
93010 int regRow; /* Registers to hold a row from pTab */
93011 int addrTop; /* Top of a loop checking foreign keys */
93012 int addrOk; /* Jump here if the key is OK */
93013 int *aiCols; /* child to parent column mapping */
93014
93015 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
93016 regResult = pParse->nMem+1;
93017 pParse->nMem += 4;
93018 regKey = ++pParse->nMem;
93019 regRow = ++pParse->nMem;
93020 v = sqlite3GetVdbe(pParse);
93021 sqlite3VdbeSetNumCols(v, 4);
93022 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
93023 sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "rowid", SQLITE_STATIC);
93024 sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "parent", SQLITE_STATIC);
93025 sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "fkid", SQLITE_STATIC);
93026 sqlite3CodeVerifySchema(pParse, iDb);
93027 k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
93028 while( k ){
93029 if( zRight ){
93030 pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
93031 k = 0;
93032 }else{
93033 pTab = (Table*)sqliteHashData(k);
93034 k = sqliteHashNext(k);
93035 }
93036 if( pTab==0 || pTab->pFKey==0 ) continue;
93037 sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
93038 if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
93039 sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
93040 sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName,
93041 P4_TRANSIENT);
93042 for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
93043 pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
93044 if( pParent==0 ) break;
93045 pIdx = 0;
93046 sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
93047 x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
93048 if( x==0 ){
93049 if( pIdx==0 ){
93050 sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
93051 }else{
93052 KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
93053 sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
93054 sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
93055 }
93056 }else{
93057 k = 0;
93058 break;
93059 }
93060 }
93061 if( pFK ) break;
93062 if( pParse->nTab<i ) pParse->nTab = i;
93063 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0);
93064 for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
93065 pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
93066 assert( pParent!=0 );
93067 pIdx = 0;
93068 aiCols = 0;
93069 x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
93070 assert( x==0 );
93071 addrOk = sqlite3VdbeMakeLabel(v);
93072 if( pIdx==0 ){
93073 int iKey = pFK->aCol[0].iFrom;
93074 assert( iKey>=0 && iKey<pTab->nCol );
93075 if( iKey!=pTab->iPKey ){
93076 sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
93077 sqlite3ColumnDefault(v, pTab, iKey, regRow);
93078 sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk);
93079 sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
93080 sqlite3VdbeCurrentAddr(v)+3);
93081 }else{
93082 sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
93083 }
93084 sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow);
93085 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
93086 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
93087 }else{
93088 for(j=0; j<pFK->nCol; j++){
93089 sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
93090 aiCols ? aiCols[j] : pFK->aCol[0].iFrom, regRow+j);
93091 sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk);
93092 }
93093 sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey);
93094 sqlite3VdbeChangeP4(v, -1,
93095 sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
93096 sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
93097 }
93098 sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
93099 sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0,
93100 pFK->zTo, P4_TRANSIENT);
93101 sqlite3VdbeAddOp2(v, OP_Integer, i-1, regResult+3);
93102 sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4);
93103 sqlite3VdbeResolveLabel(v, addrOk);
93104 sqlite3DbFree(db, aiCols);
93105 }
93106 sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1);
93107 sqlite3VdbeJumpHere(v, addrTop);
93108 }
93109 }else
93110 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
93111
93112 #ifndef NDEBUG
93113 if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
@@ -94308,11 +94563,11 @@
94563 SrcList *pSrc, /* the FROM clause -- which tables to scan */
94564 Expr *pWhere, /* the WHERE clause */
94565 ExprList *pGroupBy, /* the GROUP BY clause */
94566 Expr *pHaving, /* the HAVING clause */
94567 ExprList *pOrderBy, /* the ORDER BY clause */
94568 u16 selFlags, /* Flag parameters, such as SF_Distinct */
94569 Expr *pLimit, /* LIMIT value. NULL means not used */
94570 Expr *pOffset /* OFFSET value. NULL means no offset */
94571 ){
94572 Select *pNew;
94573 Select standin;
@@ -94332,11 +94587,11 @@
94587 pNew->pSrc = pSrc;
94588 pNew->pWhere = pWhere;
94589 pNew->pGroupBy = pGroupBy;
94590 pNew->pHaving = pHaving;
94591 pNew->pOrderBy = pOrderBy;
94592 pNew->selFlags = selFlags;
94593 pNew->op = TK_SELECT;
94594 pNew->pLimit = pLimit;
94595 pNew->pOffset = pOffset;
94596 assert( pOffset==0 || pLimit!=0 );
94597 pNew->addrOpenEphm[0] = -1;
@@ -95588,13 +95843,11 @@
95843 *paCol = aCol;
95844
95845 for(i=0, pCol=aCol; i<nCol; i++, pCol++){
95846 /* Get an appropriate name for the column
95847 */
95848 p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
 
 
95849 if( (zName = pEList->a[i].zName)!=0 ){
95850 /* If the column contains an "AS <name>" phrase, use <name> as the name */
95851 zName = sqlite3DbStrDup(db, zName);
95852 }else{
95853 Expr *pColExpr = p; /* The expression that is the result column name */
@@ -95628,10 +95881,13 @@
95881 */
95882 nName = sqlite3Strlen30(zName);
95883 for(j=cnt=0; j<i; j++){
95884 if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
95885 char *zNewName;
95886 int k;
95887 for(k=nName-1; k>1 && sqlite3Isdigit(zName[k]); k--){}
95888 if( zName[k]==':' ) nName = k;
95889 zName[nName] = 0;
95890 zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
95891 sqlite3DbFree(db, zName);
95892 zName = zNewName;
95893 j = -1;
@@ -96586,16 +96842,17 @@
96842 pKeyMerge->nField = (u16)nOrderBy;
96843 pKeyMerge->enc = ENC(db);
96844 for(i=0; i<nOrderBy; i++){
96845 CollSeq *pColl;
96846 Expr *pTerm = pOrderBy->a[i].pExpr;
96847 if( pTerm->flags & EP_Collate ){
96848 pColl = sqlite3ExprCollSeq(pParse, pTerm);
96849 }else{
96850 pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
96851 if( pColl==0 ) pColl = db->pDfltColl;
96852 pOrderBy->a[i].pExpr =
96853 sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
96854 }
96855 pKeyMerge->aColl[i] = pColl;
96856 pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
96857 }
96858 }
@@ -96794,10 +97051,11 @@
97051 */
97052 sqlite3VdbeResolveLabel(v, labelCmpr);
97053 sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
97054 sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
97055 (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
97056 sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
97057 sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
97058
97059 /* Release temporary registers
97060 */
97061 if( regPrev ){
@@ -96861,13 +97119,10 @@
97119 }else{
97120 Expr *pNew;
97121 assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
97122 assert( pExpr->pLeft==0 && pExpr->pRight==0 );
97123 pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
 
 
 
97124 sqlite3ExprDelete(db, pExpr);
97125 pExpr = pNew;
97126 }
97127 }else{
97128 pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
@@ -97414,38 +97669,47 @@
97669 return 1;
97670 }
97671 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
97672
97673 /*
97674 ** Based on the contents of the AggInfo structure indicated by the first
97675 ** argument, this function checks if the following are true:
97676 **
97677 ** * the query contains just a single aggregate function,
97678 ** * the aggregate function is either min() or max(), and
97679 ** * the argument to the aggregate function is a column value.
97680 **
97681 ** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX
97682 ** is returned as appropriate. Also, *ppMinMax is set to point to the
97683 ** list of arguments passed to the aggregate before returning.
97684 **
97685 ** Or, if the conditions above are not met, *ppMinMax is set to 0 and
97686 ** WHERE_ORDERBY_NORMAL is returned.
97687 */
97688 static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){
97689 int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
97690
97691 *ppMinMax = 0;
97692 if( pAggInfo->nFunc==1 ){
97693 Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */
97694 ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */
97695
97696 assert( pExpr->op==TK_AGG_FUNCTION );
97697 if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){
97698 const char *zFunc = pExpr->u.zToken;
97699 if( sqlite3StrICmp(zFunc, "min")==0 ){
97700 eRet = WHERE_ORDERBY_MIN;
97701 *ppMinMax = pEList;
97702 }else if( sqlite3StrICmp(zFunc, "max")==0 ){
97703 eRet = WHERE_ORDERBY_MAX;
97704 *ppMinMax = pEList;
97705 }
97706 }
97707 }
97708
97709 assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 );
97710 return eRet;
97711 }
97712
97713 /*
97714 ** The select statement passed as the first argument is an aggregate query.
97715 ** The second argment is the associated aggregate-info object. This
@@ -97536,10 +97800,11 @@
97800 int i, j, k;
97801 SrcList *pTabList;
97802 ExprList *pEList;
97803 struct SrcList_item *pFrom;
97804 sqlite3 *db = pParse->db;
97805 Expr *pE, *pRight, *pExpr;
97806
97807 if( db->mallocFailed ){
97808 return WRC_Abort;
97809 }
97810 if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
@@ -97621,11 +97886,11 @@
97886 **
97887 ** The first loop just checks to see if there are any "*" operators
97888 ** that need expanding.
97889 */
97890 for(k=0; k<pEList->nExpr; k++){
97891 pE = pEList->a[k].pExpr;
97892 if( pE->op==TK_ALL ) break;
97893 assert( pE->op!=TK_DOT || pE->pRight!=0 );
97894 assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
97895 if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
97896 }
@@ -97639,14 +97904,22 @@
97904 ExprList *pNew = 0;
97905 int flags = pParse->db->flags;
97906 int longNames = (flags & SQLITE_FullColNames)!=0
97907 && (flags & SQLITE_ShortColNames)==0;
97908
97909 /* When processing FROM-clause subqueries, it is always the case
97910 ** that full_column_names=OFF and short_column_names=ON. The
97911 ** sqlite3ResultSetOfSelect() routine makes it so. */
97912 assert( (p->selFlags & SF_NestedFrom)==0
97913 || ((flags & SQLITE_FullColNames)==0 &&
97914 (flags & SQLITE_ShortColNames)!=0) );
97915
97916 for(k=0; k<pEList->nExpr; k++){
97917 pE = a[k].pExpr;
97918 pRight = pE->pRight;
97919 assert( pE->op!=TK_DOT || pRight!=0 );
97920 if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
97921 /* This particular expression does not need to be expanded.
97922 */
97923 pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
97924 if( pNew ){
97925 pNew->a[pNew->nExpr-1].zName = a[k].zName;
@@ -97657,44 +97930,56 @@
97930 a[k].pExpr = 0;
97931 }else{
97932 /* This expression is a "*" or a "TABLE.*" and needs to be
97933 ** expanded. */
97934 int tableSeen = 0; /* Set to 1 when TABLE matches */
97935 char *zTName = 0; /* text of name of TABLE */
97936 if( pE->op==TK_DOT ){
97937 assert( pE->pLeft!=0 );
97938 assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
97939 zTName = pE->pLeft->u.zToken;
 
 
97940 }
97941 for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
97942 Table *pTab = pFrom->pTab;
97943 Select *pSub = pFrom->pSelect;
97944 char *zTabName = pFrom->zAlias;
97945 const char *zSchemaName = 0;
97946 int iDb;
97947 if( zTabName==0 ){
97948 zTabName = pTab->zName;
97949 }
97950 if( db->mallocFailed ) break;
97951 if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
97952 pSub = 0;
97953 if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
97954 continue;
97955 }
97956 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
97957 zSchemaName = iDb>=0 ? db->aDb[iDb].zName : "*";
97958 }
 
97959 for(j=0; j<pTab->nCol; j++){
 
97960 char *zName = pTab->aCol[j].zName;
97961 char *zColname; /* The computed column name */
97962 char *zToFree; /* Malloced string that needs to be freed */
97963 Token sColname; /* Computed column name as a token */
97964
97965 assert( zName );
97966 if( zTName && pSub
97967 && sqlite3MatchSpanName(pSub->pEList->a[j].zSpan, 0, zTName, 0)==0
97968 ){
97969 continue;
97970 }
97971
97972 /* If a column is marked as 'hidden' (currently only possible
97973 ** for virtual tables), do not include it in the expanded
97974 ** result-set list.
97975 */
97976 if( IsHiddenColumn(&pTab->aCol[j]) ){
97977 assert(IsVirtual(pTab));
97978 continue;
97979 }
97980 tableSeen = 1;
97981
97982 if( i>0 && zTName==0 ){
97983 if( (pFrom->jointype & JT_NATURAL)!=0
97984 && tableAndColumnIndex(pTabList, i, zName, 0, 0)
97985 ){
@@ -97713,10 +97998,14 @@
97998 zToFree = 0;
97999 if( longNames || pTabList->nSrc>1 ){
98000 Expr *pLeft;
98001 pLeft = sqlite3Expr(db, TK_ID, zTabName);
98002 pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
98003 if( zSchemaName ){
98004 pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
98005 pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr, 0);
98006 }
98007 if( longNames ){
98008 zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
98009 zToFree = zColname;
98010 }
98011 }else{
@@ -97724,10 +98013,22 @@
98013 }
98014 pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
98015 sColname.z = zColname;
98016 sColname.n = sqlite3Strlen30(zColname);
98017 sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
98018 if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
98019 struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
98020 if( pSub ){
98021 pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan);
98022 testcase( pX->zSpan==0 );
98023 }else{
98024 pX->zSpan = sqlite3MPrintf(db, "%s.%s.%s",
98025 zSchemaName, zTabName, zColname);
98026 testcase( pX->zSpan==0 );
98027 }
98028 pX->bSpanIsTab = 1;
98029 }
98030 sqlite3DbFree(db, zToFree);
98031 }
98032 }
98033 if( !tableSeen ){
98034 if( zTName ){
@@ -98781,15 +99082,21 @@
99082 ** index or indices to use) should place a different priority on
99083 ** satisfying the 'ORDER BY' clause than it does in other cases.
99084 ** Refer to code and comments in where.c for details.
99085 */
99086 ExprList *pMinMax = 0;
99087 u8 flag = WHERE_ORDERBY_NORMAL;
99088
99089 assert( p->pGroupBy==0 );
99090 assert( flag==0 );
99091 if( p->pHaving==0 ){
99092 flag = minMaxQuery(&sAggInfo, &pMinMax);
99093 }
99094 assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) );
99095
99096 if( flag ){
99097 pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
 
 
99098 pDel = pMinMax;
99099 if( pMinMax && !db->mallocFailed ){
99100 pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
99101 pMinMax->a[0].pExpr->op = TK_COLUMN;
99102 }
@@ -102673,11 +102980,11 @@
102980 #define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */
102981 #define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */
102982 #define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */
102983 #define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
102984 #define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
102985 #define WHERE_IN_ABLE 0x080f1000 /* Able to support an IN operator */
102986 #define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
102987 #define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
102988 #define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
102989 #define WHERE_IDX_ONLY 0x00400000 /* Use index only - omit table */
102990 #define WHERE_ORDERED 0x00800000 /* Output will appear in correct order */
@@ -102823,11 +103130,11 @@
103130 sqlite3DbFree(db, pOld);
103131 }
103132 pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
103133 }
103134 pTerm = &pWC->a[idx = pWC->nTerm++];
103135 pTerm->pExpr = sqlite3ExprSkipCollate(p);
103136 pTerm->wtFlags = wtFlags;
103137 pTerm->pWC = pWC;
103138 pTerm->iParent = -1;
103139 return idx;
103140 }
@@ -102983,27 +103290,36 @@
103290
103291 /*
103292 ** Commute a comparison operator. Expressions of the form "X op Y"
103293 ** are converted into "Y op X".
103294 **
103295 ** If left/right precendence rules come into play when determining the
103296 ** collating
103297 ** side of the comparison, it remains associated with the same side after
103298 ** the commutation. So "Y collate NOCASE op X" becomes
103299 ** "X op Y". This is because any collation sequence on
103300 ** the left hand side of a comparison overrides any collation sequence
103301 ** attached to the right. For the same reason the EP_Collate flag
103302 ** is not commuted.
103303 */
103304 static void exprCommute(Parse *pParse, Expr *pExpr){
103305 u16 expRight = (pExpr->pRight->flags & EP_Collate);
103306 u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
103307 assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
103308 if( expRight==expLeft ){
103309 /* Either X and Y both have COLLATE operator or neither do */
103310 if( expRight ){
103311 /* Both X and Y have COLLATE operators. Make sure X is always
103312 ** used by clearing the EP_Collate flag from Y. */
103313 pExpr->pRight->flags &= ~EP_Collate;
103314 }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
103315 /* Neither X nor Y have COLLATE operators, but X has a non-default
103316 ** collating sequence. So add the EP_Collate marker on X to cause
103317 ** it to be searched first. */
103318 pExpr->pLeft->flags |= EP_Collate;
103319 }
103320 }
103321 SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
103322 if( pExpr->op>=TK_GT ){
103323 assert( TK_LT==TK_GT+2 );
103324 assert( TK_GE==TK_LE+2 );
103325 assert( TK_GT>TK_EQ );
@@ -103076,16 +103392,16 @@
103392 ** it to be useful for optimising expression pX. Store this
103393 ** value in variable pColl.
103394 */
103395 assert(pX->pLeft);
103396 pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
103397 if( pColl==0 ) pColl = pParse->db->pDfltColl;
103398
103399 for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
103400 if( NEVER(j>=pIdx->nColumn) ) return 0;
103401 }
103402 if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
103403 }
103404 return pTerm;
103405 }
103406 }
103407 }
@@ -103600,10 +103916,11 @@
103916 return;
103917 }
103918 pTerm = &pWC->a[idxTerm];
103919 pMaskSet = pWC->pMaskSet;
103920 pExpr = pTerm->pExpr;
103921 assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
103922 prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
103923 op = pExpr->op;
103924 if( op==TK_IN ){
103925 assert( pExpr->pRight==0 );
103926 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
@@ -103626,12 +103943,12 @@
103943 pTerm->prereqAll = prereqAll;
103944 pTerm->leftCursor = -1;
103945 pTerm->iParent = -1;
103946 pTerm->eOperator = 0;
103947 if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
103948 Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
103949 Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
103950 if( pLeft->op==TK_COLUMN ){
103951 pTerm->leftCursor = pLeft->iTable;
103952 pTerm->u.leftColumn = pLeft->iColumn;
103953 pTerm->eOperator = operatorMask(op);
103954 }
@@ -103655,11 +103972,11 @@
103972 }else{
103973 pDup = pExpr;
103974 pNew = pTerm;
103975 }
103976 exprCommute(pParse, pDup);
103977 pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
103978 pNew->leftCursor = pLeft->iTable;
103979 pNew->u.leftColumn = pLeft->iColumn;
103980 testcase( (prereqLeft | extraRight) != prereqLeft );
103981 pNew->prereqRight = prereqLeft | extraRight;
103982 pNew->prereqAll = prereqAll;
@@ -103734,11 +104051,11 @@
104051 Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */
104052 Expr *pNewExpr1;
104053 Expr *pNewExpr2;
104054 int idxNew1;
104055 int idxNew2;
104056 Token sCollSeqName; /* Name of collating sequence */
104057
104058 pLeft = pExpr->x.pList->a[1].pExpr;
104059 pStr2 = sqlite3ExprDup(db, pStr1, 0);
104060 if( !db->mallocFailed ){
104061 u8 c, *pC; /* Last character before the first wildcard */
@@ -103756,20 +104073,23 @@
104073
104074 c = sqlite3UpperToLower[c];
104075 }
104076 *pC = c + 1;
104077 }
104078 sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
104079 sCollSeqName.n = 6;
104080 pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
104081 pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
104082 sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
104083 pStr1, 0);
104084 idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
104085 testcase( idxNew1==0 );
104086 exprAnalyze(pSrc, pWC, idxNew1);
104087 pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
104088 pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
104089 sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
104090 pStr2, 0);
104091 idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
104092 testcase( idxNew2==0 );
104093 exprAnalyze(pSrc, pWC, idxNew2);
104094 pTerm = &pWC->a[idxTerm];
104095 if( isComplete ){
@@ -103883,16 +104203,16 @@
104203 ){
104204 int i;
104205 const char *zColl = pIdx->azColl[iCol];
104206
104207 for(i=0; i<pList->nExpr; i++){
104208 Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
104209 if( p->op==TK_COLUMN
104210 && p->iColumn==pIdx->aiColumn[iCol]
104211 && p->iTable==iBase
104212 ){
104213 CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
104214 if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
104215 return i;
104216 }
104217 }
104218 }
@@ -103935,11 +104255,11 @@
104255 ** matching "col=X" expression and the column is on the same table as pIdx,
104256 ** set the corresponding bit in variable mask.
104257 */
104258 for(i=0; i<pDistinct->nExpr; i++){
104259 WhereTerm *pTerm;
104260 Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
104261 if( p->op!=TK_COLUMN ) return 0;
104262 pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
104263 if( pTerm ){
104264 Expr *pX = pTerm->pExpr;
104265 CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
@@ -103987,11 +104307,11 @@
104307 /* If any of the expressions is an IPK column on table iBase, then return
104308 ** true. Note: The (p->iTable==iBase) part of this test may be false if the
104309 ** current SELECT is a correlated sub-query.
104310 */
104311 for(i=0; i<pDistinct->nExpr; i++){
104312 Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
104313 if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
104314 }
104315
104316 /* Loop through all indices on the table, checking each to see if it makes
104317 ** the DISTINCT qualifier redundant. It does so if:
@@ -104464,11 +104784,11 @@
104784 for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
104785 if( pTerm->leftCursor != pSrc->iCursor ) continue;
104786 assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104787 testcase( pTerm->eOperator==WO_IN );
104788 testcase( pTerm->eOperator==WO_ISNULL );
104789 if( pTerm->eOperator & (WO_ISNULL) ) continue;
104790 if( pTerm->wtFlags & TERM_VNULL ) continue;
104791 nTerm++;
104792 }
104793
104794 /* If the ORDER BY clause contains only columns in the current
@@ -104512,29 +104832,32 @@
104832 *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
104833 *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
104834 pUsage;
104835
104836 for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
104837 u8 op;
104838 if( pTerm->leftCursor != pSrc->iCursor ) continue;
104839 assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
104840 testcase( pTerm->eOperator==WO_IN );
104841 testcase( pTerm->eOperator==WO_ISNULL );
104842 if( pTerm->eOperator & (WO_ISNULL) ) continue;
104843 if( pTerm->wtFlags & TERM_VNULL ) continue;
104844 pIdxCons[j].iColumn = pTerm->u.leftColumn;
104845 pIdxCons[j].iTermOffset = i;
104846 op = (u8)pTerm->eOperator;
104847 if( op==WO_IN ) op = WO_EQ;
104848 pIdxCons[j].op = op;
104849 /* The direct assignment in the previous line is possible only because
104850 ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
104851 ** following asserts verify this fact. */
104852 assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
104853 assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
104854 assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
104855 assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
104856 assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
104857 assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
104858 assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
104859 j++;
104860 }
104861 for(i=0; i<nOrderBy; i++){
104862 Expr *pExpr = pOrderBy->a[i].pExpr;
104863 pIdxOrderBy[i].iColumn = pExpr->iColumn;
@@ -104616,10 +104939,11 @@
104939 struct sqlite3_index_constraint *pIdxCons;
104940 struct sqlite3_index_constraint_usage *pUsage;
104941 WhereTerm *pTerm;
104942 int i, j;
104943 int nOrderBy;
104944 int bAllowIN; /* Allow IN optimizations */
104945 double rCost;
104946
104947 /* Make sure wsFlags is initialized to some sane value. Otherwise, if the
104948 ** malloc in allocateIndexInfo() fails and this function returns leaving
104949 ** wsFlags in an uninitialized state, the caller may behave unpredictably.
@@ -104650,63 +104974,91 @@
104974 ** sqlite3ViewGetColumnNames() would have picked up the error.
104975 */
104976 assert( pTab->azModuleArg && pTab->azModuleArg[0] );
104977 assert( sqlite3GetVTable(pParse->db, pTab) );
104978
104979 /* Try once or twice. On the first attempt, allow IN optimizations.
104980 ** If an IN optimization is accepted by the virtual table xBestIndex
104981 ** method, but the pInfo->aConstrainUsage.omit flag is not set, then
104982 ** the query will not work because it might allow duplicate rows in
104983 ** output. In that case, run the xBestIndex method a second time
104984 ** without the IN constraints. Usually this loop only runs once.
104985 ** The loop will exit using a "break" statement.
104986 */
104987 for(bAllowIN=1; 1; bAllowIN--){
104988 assert( bAllowIN==0 || bAllowIN==1 );
104989
104990 /* Set the aConstraint[].usable fields and initialize all
104991 ** output variables to zero.
104992 **
104993 ** aConstraint[].usable is true for constraints where the right-hand
104994 ** side contains only references to tables to the left of the current
104995 ** table. In other words, if the constraint is of the form:
104996 **
104997 ** column = expr
104998 **
104999 ** and we are evaluating a join, then the constraint on column is
105000 ** only valid if all tables referenced in expr occur to the left
105001 ** of the table containing column.
105002 **
105003 ** The aConstraints[] array contains entries for all constraints
105004 ** on the current table. That way we only have to compute it once
105005 ** even though we might try to pick the best index multiple times.
105006 ** For each attempt at picking an index, the order of tables in the
105007 ** join might be different so we have to recompute the usable flag
105008 ** each time.
105009 */
105010 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105011 pUsage = pIdxInfo->aConstraintUsage;
105012 for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105013 j = pIdxCons->iTermOffset;
105014 pTerm = &pWC->a[j];
105015 if( (pTerm->prereqRight&p->notReady)==0
105016 && (bAllowIN || pTerm->eOperator!=WO_IN)
105017 ){
105018 pIdxCons->usable = 1;
105019 }else{
105020 pIdxCons->usable = 0;
105021 }
105022 }
105023 memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
105024 if( pIdxInfo->needToFreeIdxStr ){
105025 sqlite3_free(pIdxInfo->idxStr);
105026 }
105027 pIdxInfo->idxStr = 0;
105028 pIdxInfo->idxNum = 0;
105029 pIdxInfo->needToFreeIdxStr = 0;
105030 pIdxInfo->orderByConsumed = 0;
105031 /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
105032 pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
105033 nOrderBy = pIdxInfo->nOrderBy;
105034 if( !p->pOrderBy ){
105035 pIdxInfo->nOrderBy = 0;
105036 }
105037
105038 if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
105039 return;
105040 }
105041
105042 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105043 for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105044 if( pUsage[i].argvIndex>0 ){
105045 j = pIdxCons->iTermOffset;
105046 pTerm = &pWC->a[j];
105047 p->cost.used |= pTerm->prereqRight;
105048 if( pTerm->eOperator==WO_IN && pUsage[i].omit==0 ){
105049 /* Do not attempt to use an IN constraint if the virtual table
105050 ** says that the equivalent EQ constraint cannot be safely omitted.
105051 ** If we do attempt to use such a constraint, some rows might be
105052 ** repeated in the output. */
105053 break;
105054 }
105055 }
105056 }
105057 if( i>=pIdxInfo->nConstraint ) break;
105058 }
105059
105060 /* If there is an ORDER BY clause, and the selected virtual table index
105061 ** does not satisfy it, increase the cost of the scan accordingly. This
105062 ** matches the processing for non-virtual tables in bestBtreeIndex().
105063 */
105064 rCost = pIdxInfo->estimatedCost;
@@ -105273,11 +105625,11 @@
105625 WhereTerm *pConstraint; /* A constraint in the WHERE clause */
105626
105627 /* If the next term of the ORDER BY clause refers to anything other than
105628 ** a column in the "base" table, then this index will not be of any
105629 ** further use in handling the ORDER BY. */
105630 pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr);
105631 if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
105632 break;
105633 }
105634
105635 /* Find column number and collating sequence for the next entry
@@ -105299,11 +105651,11 @@
105651 /* Check to see if the column number and collating sequence of the
105652 ** index match the column number and collating sequence of the ORDER BY
105653 ** clause entry. Set isMatch to 1 if they both match. */
105654 if( pOBExpr->iColumn==iColumn ){
105655 if( zColl ){
105656 pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr);
105657 if( !pColl ) pColl = db->pDfltColl;
105658 isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
105659 }else{
105660 isMatch = 1;
105661 }
@@ -105440,10 +105792,15 @@
105792 int idxEqTermMask; /* Index mask of valid equality operators */
105793 Index sPk; /* A fake index object for the primary key */
105794 tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
105795 int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
105796 int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */
105797 int nPriorSat; /* ORDER BY terms satisfied by outer loops */
105798 int nOrderBy; /* Number of ORDER BY terms */
105799 char bSortInit; /* Initializer for bSort in inner loop */
105800 char bDistInit; /* Initializer for bDist in inner loop */
105801
105802
105803 /* Initialize the cost to a worst-case value */
105804 memset(&p->cost, 0, sizeof(p->cost));
105805 p->cost.rCost = SQLITE_BIG_DBL;
105806
@@ -105488,10 +105845,21 @@
105845 WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
105846 );
105847 eqTermMask = WO_EQ|WO_IN;
105848 pIdx = 0;
105849 }
105850
105851 nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
105852 if( p->i ){
105853 nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
105854 bSortInit = nPriorSat<nOrderBy;
105855 bDistInit = 0;
105856 }else{
105857 nPriorSat = 0;
105858 bSortInit = nOrderBy>0;
105859 bDistInit = p->pDistinct!=0;
105860 }
105861
105862 /* Loop over all indices looking for the best one to use
105863 */
105864 for(; pProbe; pIdx=pProbe=pProbe->pNext){
105865 const tRowcnt * const aiRowEst = pProbe->aiRowEst;
@@ -105566,15 +105934,13 @@
105934 */
105935 int bInEst = 0; /* True if "x IN (SELECT...)" seen */
105936 int nInMul = 1; /* Number of distinct equalities to lookup */
105937 double rangeDiv = (double)1; /* Estimated reduction in search space */
105938 int nBound = 0; /* Number of range constraints seen */
105939 char bSort = bSortInit; /* True if external sort required */
105940 char bDist = bDistInit; /* True if index cannot help with DISTINCT */
105941 char bLookup = 0; /* True if not a covering index */
 
 
105942 WhereTerm *pTerm; /* A single term of the WHERE clause */
105943 #ifdef SQLITE_ENABLE_STAT3
105944 WhereTerm *pFirstTerm = 0; /* First term matching the index */
105945 #endif
105946
@@ -105581,20 +105947,11 @@
105947 WHERETRACE((
105948 " %s(%s):\n",
105949 pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
105950 ));
105951 memset(&pc, 0, sizeof(pc));
105952 pc.plan.nOBSat = nPriorSat;
 
 
 
 
 
 
 
 
 
105953
105954 /* Determine the values of pc.plan.nEq and nInMul */
105955 for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
105956 int j = pProbe->aiColumn[pc.plan.nEq];
105957 pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
@@ -106466,32 +106823,40 @@
106823 if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
106824 /* Case 0: The table is a virtual-table. Use the VFilter and VNext
106825 ** to access the data.
106826 */
106827 int iReg; /* P3 Value for OP_VFilter */
106828 int addrNotFound;
106829 sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
106830 int nConstraint = pVtabIdx->nConstraint;
106831 struct sqlite3_index_constraint_usage *aUsage =
106832 pVtabIdx->aConstraintUsage;
106833 const struct sqlite3_index_constraint *aConstraint =
106834 pVtabIdx->aConstraint;
106835
106836 sqlite3ExprCachePush(pParse);
106837 iReg = sqlite3GetTempRange(pParse, nConstraint+2);
106838 addrNotFound = pLevel->addrBrk;
106839 for(j=1; j<=nConstraint; j++){
106840 for(k=0; k<nConstraint; k++){
106841 if( aUsage[k].argvIndex==j ){
106842 WhereTerm *pTerm = &pWC->a[aConstraint[k].iTermOffset];
106843 int iTarget = iReg+j+1;
106844 if( pTerm->eOperator & WO_IN ){
106845 codeEqualityTerm(pParse, pTerm, pLevel, iTarget);
106846 addrNotFound = pLevel->addrNxt;
106847 }else{
106848 sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
106849 }
106850 break;
106851 }
106852 }
106853 if( k==nConstraint ) break;
106854 }
106855 sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
106856 sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
106857 sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, pVtabIdx->idxStr,
106858 pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
106859 pVtabIdx->needToFreeIdxStr = 0;
106860 for(j=0; j<nConstraint; j++){
106861 if( aUsage[j].omit ){
106862 int iTerm = aConstraint[j].iTermOffset;
@@ -108134,10 +108499,11 @@
108499 Expr* yy122;
108500 Select* yy159;
108501 IdList* yy180;
108502 struct {int value; int mask;} yy207;
108503 u8 yy258;
108504 u16 yy305;
108505 struct LikeOp yy318;
108506 TriggerStep* yy327;
108507 ExprSpan yy342;
108508 SrcList* yy347;
108509 int yy392;
@@ -110084,22 +110450,19 @@
110450 case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
110451 case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
110452 case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
110453 case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
110454 case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
 
 
110455 case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
110456 case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
110457 {yygotominor.yy392 = 0;}
110458 break;
110459 case 29: /* ifnotexists ::= IF NOT EXISTS */
110460 case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
110461 case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
110462 case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
110463 case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
 
110464 case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
110465 case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
110466 {yygotominor.yy392 = 1;}
110467 break;
110468 case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
@@ -110335,12 +110698,19 @@
110698 case 116: /* multiselect_op ::= UNION ALL */
110699 {yygotominor.yy392 = TK_ALL;}
110700 break;
110701 case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
110702 {
110703 yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy305,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
110704 }
110705 break;
110706 case 119: /* distinct ::= DISTINCT */
110707 {yygotominor.yy305 = SF_Distinct;}
110708 break;
110709 case 120: /* distinct ::= ALL */
110710 case 121: /* distinct ::= */ yytestcase(yyruleno==121);
110711 {yygotominor.yy305 = 0;}
110712 break;
110713 case 122: /* sclp ::= selcollist COMMA */
110714 case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
110715 {yygotominor.yy442 = yymsp[-1].minor.yy442;}
110716 break;
@@ -110406,14 +110776,24 @@
110776 break;
110777 case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
110778 {
110779 if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
110780 yygotominor.yy347 = yymsp[-4].minor.yy347;
110781 }else if( yymsp[-4].minor.yy347->nSrc==1 ){
110782 yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
110783 if( yygotominor.yy347 ){
110784 struct SrcList_item *pNew = &yygotominor.yy347->a[yygotominor.yy347->nSrc-1];
110785 struct SrcList_item *pOld = yymsp[-4].minor.yy347->a;
110786 pNew->zName = pOld->zName;
110787 pNew->zDatabase = pOld->zDatabase;
110788 pOld->zName = pOld->zDatabase = 0;
110789 }
110790 sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy347);
110791 }else{
110792 Select *pSubquery;
110793 sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
110794 pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,SF_NestedFrom,0,0);
110795 yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
110796 }
110797 }
110798 break;
110799 case 137: /* dbnm ::= */
@@ -110624,11 +111004,11 @@
111004 spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
111005 }
111006 break;
111007 case 194: /* expr ::= expr COLLATE ids */
111008 {
111009 yygotominor.yy342.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
111010 yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
111011 yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
111012 }
111013 break;
111014 case 195: /* expr ::= CAST LP expr AS typetoken RP */
@@ -110642,11 +111022,11 @@
111022 if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
111023 sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
111024 }
111025 yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
111026 spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
111027 if( yymsp[-2].minor.yy305 && yygotominor.yy342.pExpr ){
111028 yygotominor.yy342.pExpr->flags |= EP_Distinct;
111029 }
111030 }
111031 break;
111032 case 197: /* expr ::= ID LP STAR RP */
@@ -110883,28 +111263,20 @@
111263 case 244: /* uniqueflag ::= */
111264 {yygotominor.yy392 = OE_None;}
111265 break;
111266 case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
111267 {
111268 Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
 
 
 
 
111269 yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
111270 sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
111271 sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
111272 if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
111273 }
111274 break;
111275 case 248: /* idxlist ::= nm collate sortorder */
111276 {
111277 Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
 
 
 
 
111278 yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
111279 sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
111280 sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
111281 if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
111282 }
@@ -141105,10 +141477,11 @@
141477 extern int Sqlitemultiplex_Init(Tcl_Interp*);
141478 extern int SqliteSuperlock_Init(Tcl_Interp*);
141479 extern int SqlitetestSyscall_Init(Tcl_Interp*);
141480 extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
141481 extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
141482 extern int Sqlitetestregexp_Init(Tcl_Interp*);
141483
141484 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141485 extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
141486 #endif
141487
@@ -141148,10 +141521,11 @@
141521 Sqlitemultiplex_Init(interp);
141522 SqliteSuperlock_Init(interp);
141523 SqlitetestSyscall_Init(interp);
141524 Sqlitetestfuzzer_Init(interp);
141525 Sqlitetestwholenumber_Init(interp);
141526 Sqlitetestregexp_Init(interp);
141527
141528 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
141529 Sqlitetestfts3_Init(interp);
141530 #endif
141531
141532
+4 -4
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105105
**
106106
** See also: [sqlite3_libversion()],
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110
-#define SQLITE_VERSION "3.7.15"
111
-#define SQLITE_VERSION_NUMBER 3007015
112
-#define SQLITE_SOURCE_ID "2012-10-16 23:08:28 f021559d8a23934e3bdccad5b55fc7a91d185f53"
110
+#define SQLITE_VERSION "3.7.16"
111
+#define SQLITE_VERSION_NUMBER 3007016
112
+#define SQLITE_SOURCE_ID "2012-12-08 06:46:05 e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
@@ -1596,11 +1596,11 @@
15961596
** database connection is opened. By default, URI handling is globally
15971597
** disabled. The default value may be changed by compiling with the
15981598
** [SQLITE_USE_URI] symbol defined.
15991599
**
16001600
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
1601
-** <dd> This option taks a single integer argument which is interpreted as
1601
+** <dd> This option takes a single integer argument which is interpreted as
16021602
** a boolean in order to enable or disable the use of covering indices for
16031603
** full table scans in the query optimizer. The default setting is determined
16041604
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
16051605
** if that compile-time option is omitted.
16061606
** The ability to disable the use of covering indices for full table scans
16071607
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105 **
106 ** See also: [sqlite3_libversion()],
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.15"
111 #define SQLITE_VERSION_NUMBER 3007015
112 #define SQLITE_SOURCE_ID "2012-10-16 23:08:28 f021559d8a23934e3bdccad5b55fc7a91d185f53"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -1596,11 +1596,11 @@
1596 ** database connection is opened. By default, URI handling is globally
1597 ** disabled. The default value may be changed by compiling with the
1598 ** [SQLITE_USE_URI] symbol defined.
1599 **
1600 ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
1601 ** <dd> This option taks a single integer argument which is interpreted as
1602 ** a boolean in order to enable or disable the use of covering indices for
1603 ** full table scans in the query optimizer. The default setting is determined
1604 ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
1605 ** if that compile-time option is omitted.
1606 ** The ability to disable the use of covering indices for full table scans
1607
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105 **
106 ** See also: [sqlite3_libversion()],
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.16"
111 #define SQLITE_VERSION_NUMBER 3007016
112 #define SQLITE_SOURCE_ID "2012-12-08 06:46:05 e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -1596,11 +1596,11 @@
1596 ** database connection is opened. By default, URI handling is globally
1597 ** disabled. The default value may be changed by compiling with the
1598 ** [SQLITE_USE_URI] symbol defined.
1599 **
1600 ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
1601 ** <dd> This option takes a single integer argument which is interpreted as
1602 ** a boolean in order to enable or disable the use of covering indices for
1603 ** full table scans in the query optimizer. The default setting is determined
1604 ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
1605 ** if that compile-time option is omitted.
1606 ** The ability to disable the use of covering indices for full table scans
1607
+4 -4
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105105
**
106106
** See also: [sqlite3_libversion()],
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110
-#define SQLITE_VERSION "3.7.15"
111
-#define SQLITE_VERSION_NUMBER 3007015
112
-#define SQLITE_SOURCE_ID "2012-10-16 23:08:28 f021559d8a23934e3bdccad5b55fc7a91d185f53"
110
+#define SQLITE_VERSION "3.7.16"
111
+#define SQLITE_VERSION_NUMBER 3007016
112
+#define SQLITE_SOURCE_ID "2012-12-08 06:46:05 e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
@@ -1596,11 +1596,11 @@
15961596
** database connection is opened. By default, URI handling is globally
15971597
** disabled. The default value may be changed by compiling with the
15981598
** [SQLITE_USE_URI] symbol defined.
15991599
**
16001600
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
1601
-** <dd> This option taks a single integer argument which is interpreted as
1601
+** <dd> This option takes a single integer argument which is interpreted as
16021602
** a boolean in order to enable or disable the use of covering indices for
16031603
** full table scans in the query optimizer. The default setting is determined
16041604
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
16051605
** if that compile-time option is omitted.
16061606
** The ability to disable the use of covering indices for full table scans
16071607
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105 **
106 ** See also: [sqlite3_libversion()],
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.15"
111 #define SQLITE_VERSION_NUMBER 3007015
112 #define SQLITE_SOURCE_ID "2012-10-16 23:08:28 f021559d8a23934e3bdccad5b55fc7a91d185f53"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -1596,11 +1596,11 @@
1596 ** database connection is opened. By default, URI handling is globally
1597 ** disabled. The default value may be changed by compiling with the
1598 ** [SQLITE_USE_URI] symbol defined.
1599 **
1600 ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
1601 ** <dd> This option taks a single integer argument which is interpreted as
1602 ** a boolean in order to enable or disable the use of covering indices for
1603 ** full table scans in the query optimizer. The default setting is determined
1604 ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
1605 ** if that compile-time option is omitted.
1606 ** The ability to disable the use of covering indices for full table scans
1607
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105 **
106 ** See also: [sqlite3_libversion()],
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.16"
111 #define SQLITE_VERSION_NUMBER 3007016
112 #define SQLITE_SOURCE_ID "2012-12-08 06:46:05 e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -1596,11 +1596,11 @@
1596 ** database connection is opened. By default, URI handling is globally
1597 ** disabled. The default value may be changed by compiling with the
1598 ** [SQLITE_USE_URI] symbol defined.
1599 **
1600 ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
1601 ** <dd> This option takes a single integer argument which is interpreted as
1602 ** a boolean in order to enable or disable the use of covering indices for
1603 ** full table scans in the query optimizer. The default setting is determined
1604 ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
1605 ** if that compile-time option is omitted.
1606 ** The ability to disable the use of covering indices for full table scans
1607
+1 -1
--- src/stat.c
+++ src/stat.c
@@ -115,11 +115,11 @@
115115
@ </td></tr>
116116
}
117117
@ <tr><th>Duration&nbsp;Of&nbsp;Project:</th><td>
118118
n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
119119
" + 0.99");
120
- @ %d(n) days or approximately %.2f(n/356.24) years.
120
+ @ %d(n) days or approximately %.2f(n/365.24) years.
121121
@ </td></tr>
122122
@ <tr><th>Project&nbsp;ID:</th><td>%h(db_get("project-code",""))</td></tr>
123123
@ <tr><th>Server&nbsp;ID:</th><td>%h(db_get("server-code",""))</td></tr>
124124
@ <tr><th>Fossil&nbsp;Version:</th><td>
125125
@ %h(RELEASE_VERSION) %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
126126
--- src/stat.c
+++ src/stat.c
@@ -115,11 +115,11 @@
115 @ </td></tr>
116 }
117 @ <tr><th>Duration&nbsp;Of&nbsp;Project:</th><td>
118 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
119 " + 0.99");
120 @ %d(n) days or approximately %.2f(n/356.24) years.
121 @ </td></tr>
122 @ <tr><th>Project&nbsp;ID:</th><td>%h(db_get("project-code",""))</td></tr>
123 @ <tr><th>Server&nbsp;ID:</th><td>%h(db_get("server-code",""))</td></tr>
124 @ <tr><th>Fossil&nbsp;Version:</th><td>
125 @ %h(RELEASE_VERSION) %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
126
--- src/stat.c
+++ src/stat.c
@@ -115,11 +115,11 @@
115 @ </td></tr>
116 }
117 @ <tr><th>Duration&nbsp;Of&nbsp;Project:</th><td>
118 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
119 " + 0.99");
120 @ %d(n) days or approximately %.2f(n/365.24) years.
121 @ </td></tr>
122 @ <tr><th>Project&nbsp;ID:</th><td>%h(db_get("project-code",""))</td></tr>
123 @ <tr><th>Server&nbsp;ID:</th><td>%h(db_get("server-code",""))</td></tr>
124 @ <tr><th>Fossil&nbsp;Version:</th><td>
125 @ %h(RELEASE_VERSION) %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
126
+18 -4
--- src/style.c
+++ src/style.c
@@ -439,11 +439,13 @@
439439
/*
440440
** The default page footer
441441
*/
442442
const char zDefaultFooter[] =
443443
@ <div class="footer">
444
-@ Fossil version $release_version $manifest_version $manifest_date
444
+@ This page was generated in about
445
+@ <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by
446
+@ Fossil version $manifest_version $manifest_date
445447
@ </div>
446448
@ </body></html>
447449
;
448450
449451
/*
@@ -586,12 +588,13 @@
586588
@ div.footer a:visited { color: white; }
587589
@ div.footer a:hover { background-color: white; color: #558195; }
588590
@
589591
@ /* verbatim blocks */
590592
@ pre.verbatim {
591
-@ background-color: #f5f5f5;
592
-@ padding: 0.5em;
593
+@ background-color: #f5f5f5;
594
+@ padding: 0.5em;
595
+@ white-space: pre-wrap;
593596
@}
594597
@
595598
@ /* The label/value pairs on (for example) the ci page */
596599
@ table.label-value th {
597600
@ vertical-align: top;
@@ -959,11 +962,11 @@
959962
@ line-height: 100%;
960963
},
961964
{ "div.sbsdiff",
962965
"side-by-side diff display",
963966
@ font-family: monospace;
964
- @ font-size: smaller;
967
+ @ font-size: xx-small;
965968
@ white-space: pre;
966969
},
967970
{ "div.udiff",
968971
"context diff display",
969972
@ font-family: monospace;
@@ -991,10 +994,21 @@
991994
},
992995
{ "span.modpending",
993996
"Moderation Pending message on timeline",
994997
@ color: #b03800;
995998
@ font-style: italic;
999
+ },
1000
+ { "pre.th1result",
1001
+ "format for th1 script results",
1002
+ @ white-space: pre-wrap;
1003
+ @ word-wrap: break-word;
1004
+ },
1005
+ { "pre.th1error",
1006
+ "format for th1 script errors",
1007
+ @ white-space: pre-wrap;
1008
+ @ word-wrap: break-word;
1009
+ @ color: red;
9961010
},
9971011
{ 0,
9981012
0,
9991013
0
10001014
}
10011015
--- src/style.c
+++ src/style.c
@@ -439,11 +439,13 @@
439 /*
440 ** The default page footer
441 */
442 const char zDefaultFooter[] =
443 @ <div class="footer">
444 @ Fossil version $release_version $manifest_version $manifest_date
 
 
445 @ </div>
446 @ </body></html>
447 ;
448
449 /*
@@ -586,12 +588,13 @@
586 @ div.footer a:visited { color: white; }
587 @ div.footer a:hover { background-color: white; color: #558195; }
588 @
589 @ /* verbatim blocks */
590 @ pre.verbatim {
591 @ background-color: #f5f5f5;
592 @ padding: 0.5em;
 
593 @}
594 @
595 @ /* The label/value pairs on (for example) the ci page */
596 @ table.label-value th {
597 @ vertical-align: top;
@@ -959,11 +962,11 @@
959 @ line-height: 100%;
960 },
961 { "div.sbsdiff",
962 "side-by-side diff display",
963 @ font-family: monospace;
964 @ font-size: smaller;
965 @ white-space: pre;
966 },
967 { "div.udiff",
968 "context diff display",
969 @ font-family: monospace;
@@ -991,10 +994,21 @@
991 },
992 { "span.modpending",
993 "Moderation Pending message on timeline",
994 @ color: #b03800;
995 @ font-style: italic;
 
 
 
 
 
 
 
 
 
 
 
996 },
997 { 0,
998 0,
999 0
1000 }
1001
--- src/style.c
+++ src/style.c
@@ -439,11 +439,13 @@
439 /*
440 ** The default page footer
441 */
442 const char zDefaultFooter[] =
443 @ <div class="footer">
444 @ This page was generated in about
445 @ <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by
446 @ Fossil version $manifest_version $manifest_date
447 @ </div>
448 @ </body></html>
449 ;
450
451 /*
@@ -586,12 +588,13 @@
588 @ div.footer a:visited { color: white; }
589 @ div.footer a:hover { background-color: white; color: #558195; }
590 @
591 @ /* verbatim blocks */
592 @ pre.verbatim {
593 @ background-color: #f5f5f5;
594 @ padding: 0.5em;
595 @ white-space: pre-wrap;
596 @}
597 @
598 @ /* The label/value pairs on (for example) the ci page */
599 @ table.label-value th {
600 @ vertical-align: top;
@@ -959,11 +962,11 @@
962 @ line-height: 100%;
963 },
964 { "div.sbsdiff",
965 "side-by-side diff display",
966 @ font-family: monospace;
967 @ font-size: xx-small;
968 @ white-space: pre;
969 },
970 { "div.udiff",
971 "context diff display",
972 @ font-family: monospace;
@@ -991,10 +994,21 @@
994 },
995 { "span.modpending",
996 "Moderation Pending message on timeline",
997 @ color: #b03800;
998 @ font-style: italic;
999 },
1000 { "pre.th1result",
1001 "format for th1 script results",
1002 @ white-space: pre-wrap;
1003 @ word-wrap: break-word;
1004 },
1005 { "pre.th1error",
1006 "format for th1 script errors",
1007 @ white-space: pre-wrap;
1008 @ word-wrap: break-word;
1009 @ color: red;
1010 },
1011 { 0,
1012 0,
1013 0
1014 }
1015
+7 -2
--- src/th_main.c
+++ src/th_main.c
@@ -611,10 +611,11 @@
611611
int nSql;
612612
const char *zTail;
613613
int n, i;
614614
int res = TH_OK;
615615
int nVar;
616
+ char *zErr = 0;
616617
617618
if( argc!=3 ){
618619
return Th_WrongNumArgs(interp, "query SQL CODE");
619620
}
620621
if( g.db==0 ){
@@ -622,13 +623,17 @@
622623
return TH_ERROR;
623624
}
624625
zSql = argv[1];
625626
nSql = argl[1];
626627
while( res==TH_OK && nSql>0 ){
628
+ zErr = 0;
629
+ sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr);
627630
rc = sqlite3_prepare_v2(g.db, argv[1], argl[1], &pStmt, &zTail);
628
- if( rc!=0 ){
629
- Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1);
631
+ sqlite3_set_authorizer(g.db, 0, 0);
632
+ if( rc!=0 || zErr!=0 ){
633
+ Th_ErrorMessage(interp, "SQL error: ",
634
+ zErr ? zErr : sqlite3_errmsg(g.db), -1);
630635
return TH_ERROR;
631636
}
632637
n = (int)(zTail - zSql);
633638
zSql += n;
634639
nSql -= n;
635640
--- src/th_main.c
+++ src/th_main.c
@@ -611,10 +611,11 @@
611 int nSql;
612 const char *zTail;
613 int n, i;
614 int res = TH_OK;
615 int nVar;
 
616
617 if( argc!=3 ){
618 return Th_WrongNumArgs(interp, "query SQL CODE");
619 }
620 if( g.db==0 ){
@@ -622,13 +623,17 @@
622 return TH_ERROR;
623 }
624 zSql = argv[1];
625 nSql = argl[1];
626 while( res==TH_OK && nSql>0 ){
 
 
627 rc = sqlite3_prepare_v2(g.db, argv[1], argl[1], &pStmt, &zTail);
628 if( rc!=0 ){
629 Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1);
 
 
630 return TH_ERROR;
631 }
632 n = (int)(zTail - zSql);
633 zSql += n;
634 nSql -= n;
635
--- src/th_main.c
+++ src/th_main.c
@@ -611,10 +611,11 @@
611 int nSql;
612 const char *zTail;
613 int n, i;
614 int res = TH_OK;
615 int nVar;
616 char *zErr = 0;
617
618 if( argc!=3 ){
619 return Th_WrongNumArgs(interp, "query SQL CODE");
620 }
621 if( g.db==0 ){
@@ -622,13 +623,17 @@
623 return TH_ERROR;
624 }
625 zSql = argv[1];
626 nSql = argl[1];
627 while( res==TH_OK && nSql>0 ){
628 zErr = 0;
629 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr);
630 rc = sqlite3_prepare_v2(g.db, argv[1], argl[1], &pStmt, &zTail);
631 sqlite3_set_authorizer(g.db, 0, 0);
632 if( rc!=0 || zErr!=0 ){
633 Th_ErrorMessage(interp, "SQL error: ",
634 zErr ? zErr : sqlite3_errmsg(g.db), -1);
635 return TH_ERROR;
636 }
637 n = (int)(zTail - zSql);
638 zSql += n;
639 nSql -= n;
640
+7 -2
--- src/th_main.c
+++ src/th_main.c
@@ -611,10 +611,11 @@
611611
int nSql;
612612
const char *zTail;
613613
int n, i;
614614
int res = TH_OK;
615615
int nVar;
616
+ char *zErr = 0;
616617
617618
if( argc!=3 ){
618619
return Th_WrongNumArgs(interp, "query SQL CODE");
619620
}
620621
if( g.db==0 ){
@@ -622,13 +623,17 @@
622623
return TH_ERROR;
623624
}
624625
zSql = argv[1];
625626
nSql = argl[1];
626627
while( res==TH_OK && nSql>0 ){
628
+ zErr = 0;
629
+ sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr);
627630
rc = sqlite3_prepare_v2(g.db, argv[1], argl[1], &pStmt, &zTail);
628
- if( rc!=0 ){
629
- Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1);
631
+ sqlite3_set_authorizer(g.db, 0, 0);
632
+ if( rc!=0 || zErr!=0 ){
633
+ Th_ErrorMessage(interp, "SQL error: ",
634
+ zErr ? zErr : sqlite3_errmsg(g.db), -1);
630635
return TH_ERROR;
631636
}
632637
n = (int)(zTail - zSql);
633638
zSql += n;
634639
nSql -= n;
635640
--- src/th_main.c
+++ src/th_main.c
@@ -611,10 +611,11 @@
611 int nSql;
612 const char *zTail;
613 int n, i;
614 int res = TH_OK;
615 int nVar;
 
616
617 if( argc!=3 ){
618 return Th_WrongNumArgs(interp, "query SQL CODE");
619 }
620 if( g.db==0 ){
@@ -622,13 +623,17 @@
622 return TH_ERROR;
623 }
624 zSql = argv[1];
625 nSql = argl[1];
626 while( res==TH_OK && nSql>0 ){
 
 
627 rc = sqlite3_prepare_v2(g.db, argv[1], argl[1], &pStmt, &zTail);
628 if( rc!=0 ){
629 Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1);
 
 
630 return TH_ERROR;
631 }
632 n = (int)(zTail - zSql);
633 zSql += n;
634 nSql -= n;
635
--- src/th_main.c
+++ src/th_main.c
@@ -611,10 +611,11 @@
611 int nSql;
612 const char *zTail;
613 int n, i;
614 int res = TH_OK;
615 int nVar;
616 char *zErr = 0;
617
618 if( argc!=3 ){
619 return Th_WrongNumArgs(interp, "query SQL CODE");
620 }
621 if( g.db==0 ){
@@ -622,13 +623,17 @@
623 return TH_ERROR;
624 }
625 zSql = argv[1];
626 nSql = argl[1];
627 while( res==TH_OK && nSql>0 ){
628 zErr = 0;
629 sqlite3_set_authorizer(g.db, report_query_authorizer, (void*)&zErr);
630 rc = sqlite3_prepare_v2(g.db, argv[1], argl[1], &pStmt, &zTail);
631 sqlite3_set_authorizer(g.db, 0, 0);
632 if( rc!=0 || zErr!=0 ){
633 Th_ErrorMessage(interp, "SQL error: ",
634 zErr ? zErr : sqlite3_errmsg(g.db), -1);
635 return TH_ERROR;
636 }
637 n = (int)(zTail - zSql);
638 zSql += n;
639 nSql -= n;
640
+11 -32
--- src/timeline.c
+++ src/timeline.c
@@ -211,19 +211,20 @@
211211
if( tmFlags & TIMELINE_GRAPH ){
212212
pGraph = graph_init();
213213
/* style is not moved to css, because this is
214214
** a technical div for the timeline graph
215215
*/
216
- @ <div id="canvas" style="position:relative;width:1px;height:1px;"
216
+ @ <div id="canvas" style="position:relative;height:0px;width:0px;"
217217
@ onclick="clickOnGraph(event)"></div>
218218
}
219219
db_static_prepare(&qbranch,
220220
"SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid",
221221
TAG_BRANCH
222222
);
223223
224
- @ <table id="timelineTable" class="timelineTable">
224
+ @ <table id="timelineTable" class="timelineTable"
225
+ @ onclick="clickOnGraph(event)">
225226
blob_zero(&comment);
226227
while( db_step(pQuery)==SQLITE_ROW ){
227228
int rid = db_column_int(pQuery, 0);
228229
const char *zUuid = db_column_text(pQuery, 1);
229230
int isLeaf = db_column_int(pQuery, 5);
@@ -426,10 +427,12 @@
426427
" (SELECT uuid FROM blob WHERE rid=fid),"
427428
" (SELECT uuid FROM blob WHERE rid=pid),"
428429
" (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm"
429430
" FROM mlink"
430431
" WHERE mid=:mid AND (pid!=fid OR pfnid>0)"
432
+ " AND (fid>0 OR"
433
+ " fnid NOT IN (SELECT pfnid FROM mlink WHERE mid=:mid))"
431434
" ORDER BY 3 /*sort*/"
432435
);
433436
fchngQueryInit = 1;
434437
}
435438
db_bind_int(&fchngQuery, ":mid", rid);
@@ -725,42 +728,16 @@
725728
@ for(var i in rowinfo){
726729
@ rowinfo[i].y = absoluteY("m"+rowinfo[i].id) + 10 - canvasY;
727730
@ rowinfo[i].x = left + rowinfo[i].r*railPitch;
728731
@ }
729732
@ var btm = absoluteY("grbtm") + 10 - canvasY;
730
-#if 0
731
- @ if( btm<32768 ){
732
- @ canvasDiv.innerHTML = '<canvas id="timeline-canvas" '+
733
- @ 'style="position:absolute;left:'+(left-5)+'px;"' +
734
- @ ' width="'+width+'" height="'+btm+'"><'+'/canvas>';
735
- @ realCanvas = gebi('timeline-canvas');
736
- @ }else{
737
- @ realCanvas = 0;
738
- @ }
739
- @ var context;
740
- @ if( realCanvas && realCanvas.getContext
741
- @ && (context = realCanvas.getContext('2d'))) {
742
- @ drawBox = function(color,x0,y0,x1,y1) {
743
- @ if( y0>32767 || y1>32767 ) return;
744
- @ if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
745
- @ if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
746
- @ if(isNaN(x0) || isNaN(y0) || isNaN(x1) || isNaN(y1)) return;
747
- @ context.fillStyle = color;
748
- @ context.fillRect(x0-left+5,y0,x1-x0+1,y1-y0+1);
749
- @ };
750
- @ }
751
-#endif
752733
@ for(var i in rowinfo){
753734
@ drawNode(rowinfo[i], left, btm);
754735
@ }
755736
@ if( selRow!=null ) clickOnRow(selRow);
756737
@ }
757738
@ function clickOnGraph(event){
758
-#ifdef OMIT_IE8_SUPPORT
759
- @ var x=event.clientX-absoluteX("canvas")+window.pageXOffset;
760
- @ var y=event.clientY-absoluteY("canvas")+window.pageYOffset;
761
-#else
762739
@ var x=event.clientX-absoluteX("canvas");
763740
@ var y=event.clientY-absoluteY("canvas");
764741
@ if(window.pageXOffset!=null){
765742
@ x += window.pageXOffset;
766743
@ y += window.pageYOffset;
@@ -768,16 +745,18 @@
768745
@ var d = window.document.documentElement;
769746
@ if(document.compatMode!="CSS1Compat") d = d.body;
770747
@ x += d.scrollLeft;
771748
@ y += d.scrollTop;
772749
@ }
773
-#endif
750
+ if( P("clicktest")!=0 ){
751
+ @ alert("click at "+x+","+y)
752
+ }
774753
@ for(var i in rowinfo){
775754
@ p = rowinfo[i];
776
- @ if( p.y<y-10 ) continue;
777
- @ if( p.y>y+10 ) break;
778
- @ if( p.x>x-10 && p.x<x+10 ){
755
+ @ if( p.y<y-11 ) continue;
756
+ @ if( p.y>y+9 ) break;
757
+ @ if( p.x>x-11 && p.x<x+9 ){
779758
@ clickOnRow(p);
780759
@ break;
781760
@ }
782761
@ }
783762
@ }
784763
785764
ADDED src/unicode.c
--- src/timeline.c
+++ src/timeline.c
@@ -211,19 +211,20 @@
211 if( tmFlags & TIMELINE_GRAPH ){
212 pGraph = graph_init();
213 /* style is not moved to css, because this is
214 ** a technical div for the timeline graph
215 */
216 @ <div id="canvas" style="position:relative;width:1px;height:1px;"
217 @ onclick="clickOnGraph(event)"></div>
218 }
219 db_static_prepare(&qbranch,
220 "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid",
221 TAG_BRANCH
222 );
223
224 @ <table id="timelineTable" class="timelineTable">
 
225 blob_zero(&comment);
226 while( db_step(pQuery)==SQLITE_ROW ){
227 int rid = db_column_int(pQuery, 0);
228 const char *zUuid = db_column_text(pQuery, 1);
229 int isLeaf = db_column_int(pQuery, 5);
@@ -426,10 +427,12 @@
426 " (SELECT uuid FROM blob WHERE rid=fid),"
427 " (SELECT uuid FROM blob WHERE rid=pid),"
428 " (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm"
429 " FROM mlink"
430 " WHERE mid=:mid AND (pid!=fid OR pfnid>0)"
 
 
431 " ORDER BY 3 /*sort*/"
432 );
433 fchngQueryInit = 1;
434 }
435 db_bind_int(&fchngQuery, ":mid", rid);
@@ -725,42 +728,16 @@
725 @ for(var i in rowinfo){
726 @ rowinfo[i].y = absoluteY("m"+rowinfo[i].id) + 10 - canvasY;
727 @ rowinfo[i].x = left + rowinfo[i].r*railPitch;
728 @ }
729 @ var btm = absoluteY("grbtm") + 10 - canvasY;
730 #if 0
731 @ if( btm<32768 ){
732 @ canvasDiv.innerHTML = '<canvas id="timeline-canvas" '+
733 @ 'style="position:absolute;left:'+(left-5)+'px;"' +
734 @ ' width="'+width+'" height="'+btm+'"><'+'/canvas>';
735 @ realCanvas = gebi('timeline-canvas');
736 @ }else{
737 @ realCanvas = 0;
738 @ }
739 @ var context;
740 @ if( realCanvas && realCanvas.getContext
741 @ && (context = realCanvas.getContext('2d'))) {
742 @ drawBox = function(color,x0,y0,x1,y1) {
743 @ if( y0>32767 || y1>32767 ) return;
744 @ if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
745 @ if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
746 @ if(isNaN(x0) || isNaN(y0) || isNaN(x1) || isNaN(y1)) return;
747 @ context.fillStyle = color;
748 @ context.fillRect(x0-left+5,y0,x1-x0+1,y1-y0+1);
749 @ };
750 @ }
751 #endif
752 @ for(var i in rowinfo){
753 @ drawNode(rowinfo[i], left, btm);
754 @ }
755 @ if( selRow!=null ) clickOnRow(selRow);
756 @ }
757 @ function clickOnGraph(event){
758 #ifdef OMIT_IE8_SUPPORT
759 @ var x=event.clientX-absoluteX("canvas")+window.pageXOffset;
760 @ var y=event.clientY-absoluteY("canvas")+window.pageYOffset;
761 #else
762 @ var x=event.clientX-absoluteX("canvas");
763 @ var y=event.clientY-absoluteY("canvas");
764 @ if(window.pageXOffset!=null){
765 @ x += window.pageXOffset;
766 @ y += window.pageYOffset;
@@ -768,16 +745,18 @@
768 @ var d = window.document.documentElement;
769 @ if(document.compatMode!="CSS1Compat") d = d.body;
770 @ x += d.scrollLeft;
771 @ y += d.scrollTop;
772 @ }
773 #endif
 
 
774 @ for(var i in rowinfo){
775 @ p = rowinfo[i];
776 @ if( p.y<y-10 ) continue;
777 @ if( p.y>y+10 ) break;
778 @ if( p.x>x-10 && p.x<x+10 ){
779 @ clickOnRow(p);
780 @ break;
781 @ }
782 @ }
783 @ }
784
785 DDED src/unicode.c
--- src/timeline.c
+++ src/timeline.c
@@ -211,19 +211,20 @@
211 if( tmFlags & TIMELINE_GRAPH ){
212 pGraph = graph_init();
213 /* style is not moved to css, because this is
214 ** a technical div for the timeline graph
215 */
216 @ <div id="canvas" style="position:relative;height:0px;width:0px;"
217 @ onclick="clickOnGraph(event)"></div>
218 }
219 db_static_prepare(&qbranch,
220 "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=:rid",
221 TAG_BRANCH
222 );
223
224 @ <table id="timelineTable" class="timelineTable"
225 @ onclick="clickOnGraph(event)">
226 blob_zero(&comment);
227 while( db_step(pQuery)==SQLITE_ROW ){
228 int rid = db_column_int(pQuery, 0);
229 const char *zUuid = db_column_text(pQuery, 1);
230 int isLeaf = db_column_int(pQuery, 5);
@@ -426,10 +427,12 @@
427 " (SELECT uuid FROM blob WHERE rid=fid),"
428 " (SELECT uuid FROM blob WHERE rid=pid),"
429 " (SELECT name FROM filename WHERE fnid=mlink.pfnid) AS oldnm"
430 " FROM mlink"
431 " WHERE mid=:mid AND (pid!=fid OR pfnid>0)"
432 " AND (fid>0 OR"
433 " fnid NOT IN (SELECT pfnid FROM mlink WHERE mid=:mid))"
434 " ORDER BY 3 /*sort*/"
435 );
436 fchngQueryInit = 1;
437 }
438 db_bind_int(&fchngQuery, ":mid", rid);
@@ -725,42 +728,16 @@
728 @ for(var i in rowinfo){
729 @ rowinfo[i].y = absoluteY("m"+rowinfo[i].id) + 10 - canvasY;
730 @ rowinfo[i].x = left + rowinfo[i].r*railPitch;
731 @ }
732 @ var btm = absoluteY("grbtm") + 10 - canvasY;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
733 @ for(var i in rowinfo){
734 @ drawNode(rowinfo[i], left, btm);
735 @ }
736 @ if( selRow!=null ) clickOnRow(selRow);
737 @ }
738 @ function clickOnGraph(event){
 
 
 
 
739 @ var x=event.clientX-absoluteX("canvas");
740 @ var y=event.clientY-absoluteY("canvas");
741 @ if(window.pageXOffset!=null){
742 @ x += window.pageXOffset;
743 @ y += window.pageYOffset;
@@ -768,16 +745,18 @@
745 @ var d = window.document.documentElement;
746 @ if(document.compatMode!="CSS1Compat") d = d.body;
747 @ x += d.scrollLeft;
748 @ y += d.scrollTop;
749 @ }
750 if( P("clicktest")!=0 ){
751 @ alert("click at "+x+","+y)
752 }
753 @ for(var i in rowinfo){
754 @ p = rowinfo[i];
755 @ if( p.y<y-11 ) continue;
756 @ if( p.y>y+9 ) break;
757 @ if( p.x>x-11 && p.x<x+9 ){
758 @ clickOnRow(p);
759 @ break;
760 @ }
761 @ }
762 @ }
763
764 DDED src/unicode.c
+528
--- a/src/unicode.c
+++ b/src/unicode.c
@@ -0,0 +1,528 @@
1
+/*
2
+*8028020F606809F8C0B, 0x03600001,
3
+ 0x03ECA401,
4
+ 0x03F88033,
5
+ 0x03FC6807,
6
+ 0x03FFE405,
7
+ 0x0406400C,
8
+ 0x040E7C01,
9
+ 0x04247C01,
10
+ 0x0428E003,
11
+ 0x042B9402 0x043D18 0x0441FC04, 0x0442C012,
12
+ 0x04450004, 0x04451402,
13
+ 0x044B7C0C, 0x044C0004,
14
+ 0x044D2C03, 0x0FC01, 0x00320404,
15
+ 0x00335402,
16
+ 0x00351803,
17
+ 0x0035E401,
18
+ 0x00376008,
19
+ 0x00391C09,
20
+ 6, 0x003AEC02C80331, 0x00AF2835,
21
+ 0x00B39406,
22
+ 0x00B5F
23
+ 0x00BC00D6,
24
+ 0x00C0D802,
25
+ 0x00C64002,
26
+ 0x00C94001,
27
+ 0x01370040,
28
+ 0x029A7802,
29
+ 0x02A00801,
30
+ 0x02A1D004,2A3E003,
31
+ 0x02A57C01,
32
+3/fts302A8A40E,
33
+ 0x02A9EC03,
34
+ 0x02AB0401,
35
+ 0x02AF8C0B,
36
+ 0x03EC7801, 0x03ECA
37
+ 0x03F8001A,
38
+ 0x03FC040F,
39
+ 0x03FFA 0x0421DC02,
40
+ 0x00292C03,
41
+ 0x042B2001,
42
+ 0x 0x002AF001,
43
+ 0x04471409,*
44
+*8028 0x002BC002,
45
+ 0x002D1C02, 0x002D2C03,
46
+ 0x002E0801, 0x002EF805,
47
+ 0x002FCC08, 0x00300004,
48
+ 0x00315402, 0x00318802,
49
+ 0x0032F807, 0x00331803,
50
+ 0x00340403, 0x0034F807688, 61700351803, 0x00352804,
51
+ 0x0035E401, 0x00360802,
52
+ 0x00376008, 0x0037C803,
53
+ 0x00391C09, 0x00396802,
54
+ 0x003B2006, 0x003C041F,
55
+ 0x003E6424, 0x003EF80F,
56
+ 0x00415804, 0x00417803,
57
+ 0x0042080C, 0x00423C01,
58
+ 0x004E400A, 0
59
+ **, 'y', 'y', 'a', 'c0x005F6004,
60
+ 0x0062A401, 0x0064800C,
61
+ 0x00677822, 0x00685C05,
62
+ 0x0069FC01, 0x006A8007,
63
+
64
+ 0x006FF004, 0x00709014,, 0x03600001,
65
+ 0x03ECA401,
66
+ 0x03F88033,
67
+ 0x03FC6807,
68
+ 0x03FFE405,
69
+ 0x0406400C
70
+ 0x007FB403, 0x007FF402,
71
+ 0 007FB403, 0x007FF402,
72
+ 0x00822805, 0x0082801F,
73
+ 0x00842002, 0x00845001,
74
+ 0x00const static84A401,
75
+ 0x00852804, 0x00853C01, 0x00862802, 0x0086426F, 0x00900027,
76
+ 0x009E53E0, 0x00ADD820,
77
+ 00391C09,
78
+ 6, 0x003AEC02C80331, 8, 0x00AFB004, 0x00B394060x05BE3C000B5F
79
+ 0x00BC00D6,
80
+ 0x00C0 0x00B5C001, 0x00B5FC01,
81
+ 00C94001,
82
+ 0x0137005, 0x00BA001A, 0x00C0A807, 0x00C0DC01,
83
+ 0x00C05, 0x00181816,
84
+ 0x001B9C07,2A00801,
85
+ 0x02A0D8
86
+ 0x001CC01B,x0472A40E,
87
+ 0x02A380
88
+ 0x00206C09,
89
+ 0x02A8A40E, 0x02
90
+ 0x00217x03600001,
91
+ 0x03EC7801, 0x03ECA401,
92
+ 0x03F8001A, 0x03F88033,
93
+ 0x03FC040F, 0x03FC6807,
94
+ 0x03FFA007, 0x03FFE405,
95
+ 0x04063003, 0x0406400C,
96
+ 0x040DD805, 0x040E7C01,
97
+ 0x0421DC02, 0x04247C01,
98
+ 0x04d', 'e', 'e', 'g', 'h', 'i 0x04283004, 0x0428E003,
99
+ 0x042B2001, 0x042B9402,
100
+ 0x04400003, 0x0440E016,
101
+ 0x04449C0E, 0x04450004,
102
+ 0x04471409, 0x04476C01,
103
+ 0F606809F8C0B, 0x03600001,
104
+ 0x044D2C03, 0x044D5C01,
105
+ 0x0450D412, 0x04512C05,
106
+ 0x04531801, 0x0456BC07,
107
+ 0x0459800D, 0x045AAC0D,
108
+ 040DD805,
109
+ 0x0421DC02,
110
+ 41FC04,
111
+ 0x04450004,
112
+ 0x0
113
+ 0x0471C9800D,
114
+ 0x0468040A, 0x0468CC07,46A7805, 0x0470BC08,4724816, 0x0472A40E,
115
+ 0x0474FC07, 0x04751C01,
116
+ 0x047BCC06, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC05C01, 0x00358802, 0x0035E401,
117
+ 01, 0x006A8007,
118
+ 0 0x00376008,
119
+ 709014,, 0x03600001,
120
+ 0x00391C09,
121
+ 807,
122
+ 0x03FFE405,
123
+ 0x003B2006,
124
+ 0x00822805, 0x008 0x003E6424,
125
+ 849C01, 0x0084A401,
126
+ 0x00415804,
127
+ 86426F, 0x00900027,
128
+ 0x0042080C,
129
+ 6, 0x003AEC02C80331, 0x004E400A,
130
+ 0x00BC00D6,
131
+ 0x00 0x005BAC03,
132
+ 0x0137005, 0x00BA001 0x005ED023,
133
+ 0x00C64002,
134
+ A401, 0x0064800C,
135
+ 0x00677822, 0x00685C05,
136
+ 0x0069FC01, 0x006A8007,
137
+ 0x006CD011, 0x006D6823,
138
+ 0x006FF004, 0x007090140442C012,
139
+/*
140
+*8028020F606809F8C0B, 0x0360809F8C0B, 0x03600001,
141
+ 0x 0x0077F004, 0x007EF401,
142
+ 0x007FB403, 0x007FF402,
143
+ 0x00822805, 0x0082801F,
144
+ 0x00842002, 0x00845001,
145
+ 0x00849C01, 0x0084A401,
146
+ 0x00852804, 0x00853C016C011, 0x00672002,
147
+
148
+ 0x0069FC01, 0x006A8007,
149
+ 0x006CD011, 0x006D6823,
150
+ 0x006FF004, 0x00709014,
151
+ 0x00734019, 0x0073B401,, 0x03600001,
152
+ 0x03ECA401
153
+ 0x007FB403, 0x007FFEC01, 0x0 0x02A6CC1B, 0x02A77802,
154
+
155
+ 0x00822805, 0x0082801E,05BE3C000842002, 0x00845001,
156
+ 0x00849C01, 0x0084A401,
157
+ 0x00852804, 0x00853C01 0x040400
158
+ 0x0092704E, 0x0406400C, 0x040F4
159
+ 0x00AEF40C, 0x00AF28082CE407,
160
+ 0x0441FC04, 0x0442C012,
161
+ 0x0445CC03, 0x04460003,
162
+ 0x04477403, 0x0448B012,
163
+ 0F606809F8C0B, 0x03600001,
164
+ 0x044D8802,8, 1168660, 186, 6},
165
+ {7976, 18686, 8}, {8008, 18687, 8}, {8040,86, 8}, {8104, 18686, 2},
166
+ {8122,0, 1},
167
+ {8136,86, 2},
168
+ {8154, 15{8170, 154, 2},
169
+ {8172, 18848, 2}, {81860, 112, 1},
170
+ {8491, 1140836, 1},
171
+ {11364, 1104, 1},
172
+ {11374, 1060, 1}, {11376, 1029846209, 84, 0, 86},
173
+{42930, 86},
174
+ {43888, 92 30204,
175
+ 54793, 54809,
176
+ 8028020F606809F020F606809F8C0B, 65268, 65341,
177
+ 65436, 65439,
178
+ 65482, 65488,
179
+ bRemoveDiacritic ));/446, 1},
180
+ 4, 8},
181
+ {7960, 184, 4980A, 0x02A51C0D,
182
+ , 184, 8}, {79 0x02A79401,
183
+ {8040,{8088, 184, 0x02A9DC03,
184
+ 2}, {8122, 16 0x02AAF802,
185
+ 0, 1}, {8136, 0x02AD6C01,
186
+
187
+ {81868, 182
188
+ 0x037FFC01,
189
+
190
+ {11363, 136, 1}, 0x03F7F002,
191
+ 1506, 0, 1},*8028020F0E, 0x03F8C02 {42877, 94, 1},
192
+ {42893, 86, 1},
193
+ {42922, 80, 1},
194
+ {42925, 82, 1},
195
+ {42929, 840, 831, 68, 1},
196
+ {429325268, 65341, 65373,
197
+ 65450,
198
+ 65506,
199
+ 8028020F606809F8C0B, 0x03600001,
200
+ 03600001,
201
+ 0x03ECA401,
202
+ 0x03F88033,
203
+ 0x03FC6807,
204
+ 0x03FFE405,
205
+ 0x0406400C,
206
+ 0x040E7C01,
207
+ 0x04247C01,
208
+ 0x0428E003,
209
+ 0x042B9402 0x043D18 0x0441FC04, 0x0442C012,
210
+ 0x04450004, 0x04451402,
211
+ 0x044B7C0C, 0x044C00sizeof(aEntry)/sizeof(aEntry[0] 0x0035E401,
212
+ 0x00376008,
213
+ 0x00391C09,
214
+ 6, 0x003AEC02C80331, 0x00AF2835,
215
+ 0x00B39406,
216
+ 0x00B5F
217
+ 0x00B4, 0x04473401, 0x0448B012, 0x044B7C0C,
218
+ 0x044C0403, 0x044CF001, 0x044CF807, 0x044DC005, 0x0452C014,
219
+ 8687, 8}, {8040,86, 8}, 186, 8}, {8104, 1868 {8136,86, 2},
220
+ {8154, 15{8170, 154, 2},
221
+ {8172, 18848, 2}, {81860, 112, 1},
222
+ {8491, 1140836, 1},
223
+ {11364, 1104, 1},
224
+ B5{11374, 1060, 1}, {11376, 1029846209, 84, 1},
225
+ {42930, 86},
226
+ {43888, 92 30204,
227
+ 54793, 54809,
228
+ 8028020F606809F020F606809F8C0B, 65268, 65341,
229
+ A34007, 0x07BBC002,
230
+
231
+ 0x07C34425, 0x07C4401F, 0x04247C01,
232
+ 0x0428E003,
233
+ 0x042B9402 0x043D18 0x0441FC04, 0x0442C012,
234
+ 0x04450004, 0x04451402,
235
+ 0x044B7C0C, 0x044C00sizeof(aEntry)/sizeof(aEntry[0] 0x0035E401,
236
+ 0x00376008,
237
+ 0x00391C09,
238
+ 6, 0x003AEC02C80331, 0x00AF2835,
239
+ 0x00B39406,
240
+ 0x00B5F
241
+ 0x00BC00D6,
242
+ 0x00C0D802,
243
+ 0x00C64002,
244
+ 0x00C94001,
245
+ 0x01370040,
246
+ 0x029A7802,
247
+ 0x02A00801,
248
+ 0x02A1D004,2A3E003,
249
+ 0x02A57C01,
250
+ 0x02A8A40E,
251
+ 0x02A9EC03,
252
+ 0x02AB0401,
253
+ 0x02AF8C0B,
254
+ 0x03EC7801, 0x03ECA
255
+ 0x03F8001A,
256
+ 0x03FC040F,
257
+ 0x03FFA007,
258
+ 0x04063003,
259
+ 0x040DD805,
260
+ 0x0421DC02,
261
+ 0x04283004,
262
+ 0x042B2001,
263
+ 0x04349004,
264
+ 0x0441FC04,
265
+ 0x04450004,
266
+ 0x04471409,*
267
+*8028020F606809F8C0, 0x03600001,
268
+
269
+ 0x044D2C03,
270
+ 0x0450D412,
271
+ 0x04531801,
272
+ 0x0459800D,
273
+ 0x0468040A, 0x0468CC07,46A7805, 0x0470BC08,4724816, 0x0472A40E,
274
+ 0x0474FC07, 0x04751C01,
275
+ 0x047BCC06, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010,
276
+ 442E, 0x05BE3C04, 0x06F27008,
277
+
278
+ 0x075B0401, 0x075B6C01,
279
+ 0x075D3C01, 0x075DBC01,
280
+ 0x0760028C, 0x076A6C05,
281
+ 0x07806C07, 0x07808C02, 0x07809805, 0x07A34007, 0x07A51007,
282
+
283
+ 0x07C0C064, 0x07C2800F,
284
+ 0x07C4405C, 0x07C5C03D,
285
+ 0x07C94A,
286
+ 0x07DC0074, 0x07DE0059
287
+ 0x07E18028,402F, 0x07E50031,
288
+ 0x07E5CC04, 0x07E5E801, 0x07E5F027, 0x07E6C00A, 0x07E70003,
289
+ 0x07E74030, 0x07E9800E, 0x38000401, 0x38008060,){896, 3912, 3928,
290
+
291
+ 4408, 4424, 447
292
+ 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
293
+ 36, 61880, 61914, 61948, 61998, 62122,
294
+ 62154, 62200, 62218, 62302, 62364
295
+ 62554,
296
+ 62924char aChar[] = {
297
+ '\0', '/*
298
+*8028'u', 'y', 'y', 'a', 'c',
299
+ 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
300
+ 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
301
+ 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
302
+ 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
303
+ '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
304
+ 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
305
+ 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
306
+ 'e', 'i', 'o', 'u', return (
307
+*8028020F606809F8C0B,09F8C0B, 0x0360b2058, 1},
308
+ {503, 1704627678, 1},
309
+ {981, 1828284, 1, 24},
310
+ {10081009, 174, 1}, {108846862, 1},
311
+ {7297,*8028020F606809F8C0B, 0x03600001,
312
+ sizeof(aDia)/sizeof(aDia[0]
313
+ 0x040DD805,
314
+ 0x0421DC02,
315
+ 0x04283004,
316
+ 0x042B2001,
317
+ 0x04349004,
318
+ 0x0441FC04,
319
+ 0x04450004,
320
+ 0x04471409,*
321
+*8028020F606809F8C0, 0x03600001,
322
+
323
+ 0x044D2C03,
324
+ 0x0450D412,
325
+ 0x04531801,
326
+ 0x0459800D,
327
+ 0x0468040A, 0x0468CC07,46A7805, 0x0470BC08,4724816, 0x0472A40E,
328
+ 0x0474FC07, 0x04751C01,
329
+ 0x047BCC06, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010,
330
+ 442E, 0x05BE3C04, 0x06F27008,
331
+
332
+ 0x075B0401, 0x075B6C01,
333
+ 0x075D3C01, 0x075DBC01,
334
+ 0x0760028C, 0x076A6C05,
335
+ 0x07806C07, 0x07808C02, 0x07809805, 0x07A34007, 0x07A51007,
336
+
337
+ 0x07C0C064, 0x07C2800F,
338
+ 0x07C4405C, 0x07C5C03D,
339
+ 0x07C94A,
340
+ 0x07DC0074, 0x07DE0059
341
+ 0x07E18028,402F, 0x07E50031,
342
+ 0x07E5CC04, 0x07E5E801, 0x07E5F027, 0x07E6C00A, 0x07E70003,
343
+ 0x07E74030, 0x07E9800E, 0x38000401, 0x38008060,){896, 3912, 3928,
344
+
345
+ 4408, 4424, 447
346
+ 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
347
+ 36, 61880, 61914, 61948, 61998, 62122,
348
+ 62154, 62200, 62218, 62302, 62364
349
+ 62554,
350
+ 62924char aChar[] = {
351
+ '\0', '/*
352
+*8028'u', 'y', 'y', 'a', 'c',
353
+ 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
354
+ 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
355
+ 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
356
+ 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
357
+ '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
358
+ 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
359
+ 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
360
+ ';e', 'i', 'o', 'u', return (
361
+*8028020F606809F8C0B,09F8C0B, 0x0360b2058, 1},
362
+ {503, 1704627678, 1},
363
+ {981, 1828284, 1, 24},
364
+ {10081009, 174, 1}, {108846862, 1},
365
+ {7297,*8028020F606809F8C0B, 0x03600001,
366
+ 0x03ECA401,
367
+ 0x03F88033,
368
+ 0x03FC6807,
369
+ 0x03FFE405,
370
+ 0x0406400C,
371
+ 0x040E7C01,
372
+ 0x04247C01,
373
+ 0x0428E003,
374
+ 0x042B9402 0x043D18 0x0441FC04, 0x0442C012,
375
+ 0x04450004, 0x04451402,
376
+ 0x044B7C0C, 0x044C0004,
377
+ 0x044D2C03, 0x0600001,
378
+ 0x03ECA402, 1324, 1},
379
+ {7304, 96, 1}, {7312, 138, 43}, {7357, 13867838, 1168660, 186, 6},
380
+ {7976, 18686, 8}, {8008, 18687, 8}, {8040,86, 8}, {8104, 18686, 2},
381
+ {8122,0, 1},
382
+ {8136,86, 2},
383
+ {8154, 15{8170, 154, 2},
384
+ {8172, 18848, 2}, {81860, 112, 1},
385
+ {8491, 1140836, 1},
386
+ {11364, 1104, 1},
387
+ {11374, 1060, 1}, {11376, 1029846209, 84, 1},
388
+ {42930, 86},
389
+ {43888, 92 30204,
390
+ 54793, 54809,
391
+ 8028020F606809F020F606809F8C0B, 65268, 65341,
392
+ 65436, 65439,
393
+ 65482, 65488,
394
+ bRemoveDiacritic ));count(aEntry
395
+ {42925, 82, 1},
396
+sizeof(aEntry)/sizeof(aEntry[0] 0x0456E020,
397
+ 7976, 18686, 8}, {8008,AAC0D, 0x045C740F, 0x045CF004,
398
+
399
+ 0x05BD442E, 0x05BE3C04,
400
+ 0x0744A4C0, 0x07480046,
401
+ 0x075BEC01, 0x075C5401, 'm', 75E2401, 0x075EA401,05BE3C0076A840F, 0x07A340078},
402
+ {8120, 184, 2}, {8122, 160, 2}, {8124, 182, 1},
403
+ {8126, 120, 1}, {82B},
404
+ {8170,6, 2},
405
+ B{81868, 1827A, 0x07D5EC29, 0x07D6952C, 0x07DB800D,
406
+ 0x07DBC004, 0x07DC0074,247C01,
407
+7E1400A, 0x07E18028, 0x07E24,
408
+ 0x044D2C03, 0x0600001,
409
+ 0x03ECA402, 1324, 1},
410
+ {7304, 96, 1}, {7312, 138, 43}, {7357, 13867838, 1168660, 186, 6},
411
+ {7976, 18686, 8}, {8008, 18687, 8}, {8040,86, 8}, {8104, 18686, 2},
412
+ {8122,0, 1},
413
+ {8136,86, 2},
414
+ {8154, 15{8170, 154, 2},
415
+ {8172, 18848, 2}, {81860, 112, 1},
416
+ {8491, 1140836, 1},
417
+ {11364, 1104, 1},
418
+ {11374, 1060, 1}, {11376, 1029846209, 84, 1},
419
+ {42930, 86},
420
+ {43888, 92 30204,
421
+ 54793, 54809,
422
+ 8028020F606809F020F606809F8C0B, 65268, 65341,
423
+ 65436, 65439,
424
+ 65482, 65488,
425
+ bRemoveDiacritic ));/446, 1},
426
+ 4, 8},
427
+ {7960, 184, 6},7976, 184, 8}, {7992, 184, 88008, 184, 6},{8025, 185, 8}, {8040,{8088, 184, 8}, {8104, 184, 8},
428
+ {8120, 184, 2}, {8122, 160, 2}, {8124, 182, 1},
429
+ {8126, 120, 1}, {8136, 1582, 1},
430
+ {8152,4, 2},
431
+ {8170,6, 2},
432
+ {81868, 182
433
+
434
+ {8544, 8, 16},
435
+ {11264, 24, 47},
436
+ {11363, 136, 1},
437
+ {11373, 104, 1},
438
+
439
+
440
+ {11506, 0, 1},*8028020F606606809F8C0B, 0x03600001,
441
+ {42877, 94, 1},
442
+ {42893, 86, 1},
443
+ {42922, 80, 1},
444
+ {42925, 82, 1},
445
+ {42929, 840, 831, 68, 1},
446
+ {429325268, 65341, 65373,
447
+ 65450,
448
+ 65506,
449
+ 8028020F606809F8C0B, 0x03600001,
450
+ 03600001,
451
+ 0x03ECA401,
452
+ 0x03F88033,
453
+ 0x03FC6807,
454
+ 0x03FFE405,
455
+ 0x0406400C,
456
+ 0x040E7C01,
457
+ 0x04247C01,
458
+ 0x0428E003,
459
+ 0x042B9402 0x043D18 0x0441FC04, 0x0442C012,
460
+ 0x04450004, 0x04451402,
461
+ 0x044B7C0C, 0x044C00sizeof(aEntry)/sizeof(aEntry[0] 0x0035E401,
462
+ 0x00376008,
463
+ 0x00391C09,
464
+ 6, 0x003AEC02C80331, 0x00AF2835,
465
+ 0x00B39406,
466
+ 0x00B5F
467
+ 0x00BC00D6,
468
+ 0x00C0D802,
469
+ 0x00C64002,
470
+ 0x00C94001,
471
+ 0x01370040,
472
+ 0x029A7802,
473
+ 0x02A00801,
474
+ 0x02A1D004,2A3E003,
475
+ 0x02A57C01,
476
+ 0x02A8A40E,
477
+ 0x02A9EC03,
478
+ 0x02AB0401,
479
+ 0x02AF8C0B,
480
+ 0x03EC7801, 0x03ECA
481
+ 0x03F8001A,
482
+ 0x03FC040F,
483
+ 0x03FFA007,
484
+ 0x04063003,
485
+ 0x040DD805,
486
+ 0x0421DC02,
487
+ 0x04283004,
488
+ 0x042B2001,
489
+ 0x04349004,
490
+ 0x0441FC04,
491
+ 0x04450004,
492
+ 0x04471409,*
493
+*8028020F606809F8C0, 0x03600001,
494
+
495
+ 0x044D2C03,
496
+ 0x0450D412,
497
+ 0x04531801,
498
+ 0x0459800D,
499
+ 0x0468040A, 0x0468CC07,46A7805, 0x0470BC08,4724816, 0x0472A40E,
500
+ 0x0474FC07, 0x04751C01,
501
+ 0x047BCC06, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010,
502
+ 442E, 0x05BE3C04, 0x06F27008,
503
+
504
+ 0x075B0401, 0x075B6C01,
505
+ 0x075D3C01, 0x075DBC01,
506
+ 0x0760028C, 0x076A6C05,
507
+ 0x07806C07, 0x07808C02, 0x07809805, 0x07A34007, 0x07A51007,
508
+
509
+ 0x07C0C064, 0x07C2800F,
510
+ 0x07C4405C, 0x07C5C03D,
511
+ 0x07C94A,
512
+ 0x07DC0074, 0x07DE0059
513
+ 0x07E18028,402F, 0x07E50031,
514
+ 0x07E5CC04, 0x07E5E801, 0x07E5F027, 0x07E6C00A, 0x07E70003,
515
+ 0x07E74030, 0x07E9800E, 0x38000401, 0x38008060,){896, 3912, 3928,
516
+
517
+ 4408, 4424, 447
518
+ 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
519
+ 36, 61880, 61914, 61948, 61998, 62122,
520
+ 62154, 62200, 62218, 62302, 62364
521
+ 62554,
522
+ 62924char aChar[] = {
523
+ '\0', '/*
524
+*8028'u', 'y', 'y', 'a', 'c',
525
+ 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
526
+ 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
527
+ 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
528
+ 'u', 's', 't', 'h'
--- a/src/unicode.c
+++ b/src/unicode.c
@@ -0,0 +1,528 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/unicode.c
+++ b/src/unicode.c
@@ -0,0 +1,528 @@
1 /*
2 *8028020F606809F8C0B, 0x03600001,
3 0x03ECA401,
4 0x03F88033,
5 0x03FC6807,
6 0x03FFE405,
7 0x0406400C,
8 0x040E7C01,
9 0x04247C01,
10 0x0428E003,
11 0x042B9402 0x043D18 0x0441FC04, 0x0442C012,
12 0x04450004, 0x04451402,
13 0x044B7C0C, 0x044C0004,
14 0x044D2C03, 0x0FC01, 0x00320404,
15 0x00335402,
16 0x00351803,
17 0x0035E401,
18 0x00376008,
19 0x00391C09,
20 6, 0x003AEC02C80331, 0x00AF2835,
21 0x00B39406,
22 0x00B5F
23 0x00BC00D6,
24 0x00C0D802,
25 0x00C64002,
26 0x00C94001,
27 0x01370040,
28 0x029A7802,
29 0x02A00801,
30 0x02A1D004,2A3E003,
31 0x02A57C01,
32 3/fts302A8A40E,
33 0x02A9EC03,
34 0x02AB0401,
35 0x02AF8C0B,
36 0x03EC7801, 0x03ECA
37 0x03F8001A,
38 0x03FC040F,
39 0x03FFA 0x0421DC02,
40 0x00292C03,
41 0x042B2001,
42 0x 0x002AF001,
43 0x04471409,*
44 *8028 0x002BC002,
45 0x002D1C02, 0x002D2C03,
46 0x002E0801, 0x002EF805,
47 0x002FCC08, 0x00300004,
48 0x00315402, 0x00318802,
49 0x0032F807, 0x00331803,
50 0x00340403, 0x0034F807688, 61700351803, 0x00352804,
51 0x0035E401, 0x00360802,
52 0x00376008, 0x0037C803,
53 0x00391C09, 0x00396802,
54 0x003B2006, 0x003C041F,
55 0x003E6424, 0x003EF80F,
56 0x00415804, 0x00417803,
57 0x0042080C, 0x00423C01,
58 0x004E400A, 0
59 **, 'y', 'y', 'a', 'c0x005F6004,
60 0x0062A401, 0x0064800C,
61 0x00677822, 0x00685C05,
62 0x0069FC01, 0x006A8007,
63
64 0x006FF004, 0x00709014,, 0x03600001,
65 0x03ECA401,
66 0x03F88033,
67 0x03FC6807,
68 0x03FFE405,
69 0x0406400C
70 0x007FB403, 0x007FF402,
71 0 007FB403, 0x007FF402,
72 0x00822805, 0x0082801F,
73 0x00842002, 0x00845001,
74 0x00const static84A401,
75 0x00852804, 0x00853C01, 0x00862802, 0x0086426F, 0x00900027,
76 0x009E53E0, 0x00ADD820,
77 00391C09,
78 6, 0x003AEC02C80331, 8, 0x00AFB004, 0x00B394060x05BE3C000B5F
79 0x00BC00D6,
80 0x00C0 0x00B5C001, 0x00B5FC01,
81 00C94001,
82 0x0137005, 0x00BA001A, 0x00C0A807, 0x00C0DC01,
83 0x00C05, 0x00181816,
84 0x001B9C07,2A00801,
85 0x02A0D8
86 0x001CC01B,x0472A40E,
87 0x02A380
88 0x00206C09,
89 0x02A8A40E, 0x02
90 0x00217x03600001,
91 0x03EC7801, 0x03ECA401,
92 0x03F8001A, 0x03F88033,
93 0x03FC040F, 0x03FC6807,
94 0x03FFA007, 0x03FFE405,
95 0x04063003, 0x0406400C,
96 0x040DD805, 0x040E7C01,
97 0x0421DC02, 0x04247C01,
98 0x04d', 'e', 'e', 'g', 'h', 'i 0x04283004, 0x0428E003,
99 0x042B2001, 0x042B9402,
100 0x04400003, 0x0440E016,
101 0x04449C0E, 0x04450004,
102 0x04471409, 0x04476C01,
103 0F606809F8C0B, 0x03600001,
104 0x044D2C03, 0x044D5C01,
105 0x0450D412, 0x04512C05,
106 0x04531801, 0x0456BC07,
107 0x0459800D, 0x045AAC0D,
108 040DD805,
109 0x0421DC02,
110 41FC04,
111 0x04450004,
112 0x0
113 0x0471C9800D,
114 0x0468040A, 0x0468CC07,46A7805, 0x0470BC08,4724816, 0x0472A40E,
115 0x0474FC07, 0x04751C01,
116 0x047BCC06, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC05C01, 0x00358802, 0x0035E401,
117 01, 0x006A8007,
118 0 0x00376008,
119 709014,, 0x03600001,
120 0x00391C09,
121 807,
122 0x03FFE405,
123 0x003B2006,
124 0x00822805, 0x008 0x003E6424,
125 849C01, 0x0084A401,
126 0x00415804,
127 86426F, 0x00900027,
128 0x0042080C,
129 6, 0x003AEC02C80331, 0x004E400A,
130 0x00BC00D6,
131 0x00 0x005BAC03,
132 0x0137005, 0x00BA001 0x005ED023,
133 0x00C64002,
134 A401, 0x0064800C,
135 0x00677822, 0x00685C05,
136 0x0069FC01, 0x006A8007,
137 0x006CD011, 0x006D6823,
138 0x006FF004, 0x007090140442C012,
139 /*
140 *8028020F606809F8C0B, 0x0360809F8C0B, 0x03600001,
141 0x 0x0077F004, 0x007EF401,
142 0x007FB403, 0x007FF402,
143 0x00822805, 0x0082801F,
144 0x00842002, 0x00845001,
145 0x00849C01, 0x0084A401,
146 0x00852804, 0x00853C016C011, 0x00672002,
147
148 0x0069FC01, 0x006A8007,
149 0x006CD011, 0x006D6823,
150 0x006FF004, 0x00709014,
151 0x00734019, 0x0073B401,, 0x03600001,
152 0x03ECA401
153 0x007FB403, 0x007FFEC01, 0x0 0x02A6CC1B, 0x02A77802,
154
155 0x00822805, 0x0082801E,05BE3C000842002, 0x00845001,
156 0x00849C01, 0x0084A401,
157 0x00852804, 0x00853C01 0x040400
158 0x0092704E, 0x0406400C, 0x040F4
159 0x00AEF40C, 0x00AF28082CE407,
160 0x0441FC04, 0x0442C012,
161 0x0445CC03, 0x04460003,
162 0x04477403, 0x0448B012,
163 0F606809F8C0B, 0x03600001,
164 0x044D8802,8, 1168660, 186, 6},
165 {7976, 18686, 8}, {8008, 18687, 8}, {8040,86, 8}, {8104, 18686, 2},
166 {8122,0, 1},
167 {8136,86, 2},
168 {8154, 15{8170, 154, 2},
169 {8172, 18848, 2}, {81860, 112, 1},
170 {8491, 1140836, 1},
171 {11364, 1104, 1},
172 {11374, 1060, 1}, {11376, 1029846209, 84, 0, 86},
173 {42930, 86},
174 {43888, 92 30204,
175 54793, 54809,
176 8028020F606809F020F606809F8C0B, 65268, 65341,
177 65436, 65439,
178 65482, 65488,
179 bRemoveDiacritic ));/446, 1},
180 4, 8},
181 {7960, 184, 4980A, 0x02A51C0D,
182 , 184, 8}, {79 0x02A79401,
183 {8040,{8088, 184, 0x02A9DC03,
184 2}, {8122, 16 0x02AAF802,
185 0, 1}, {8136, 0x02AD6C01,
186
187 {81868, 182
188 0x037FFC01,
189
190 {11363, 136, 1}, 0x03F7F002,
191 1506, 0, 1},*8028020F0E, 0x03F8C02 {42877, 94, 1},
192 {42893, 86, 1},
193 {42922, 80, 1},
194 {42925, 82, 1},
195 {42929, 840, 831, 68, 1},
196 {429325268, 65341, 65373,
197 65450,
198 65506,
199 8028020F606809F8C0B, 0x03600001,
200 03600001,
201 0x03ECA401,
202 0x03F88033,
203 0x03FC6807,
204 0x03FFE405,
205 0x0406400C,
206 0x040E7C01,
207 0x04247C01,
208 0x0428E003,
209 0x042B9402 0x043D18 0x0441FC04, 0x0442C012,
210 0x04450004, 0x04451402,
211 0x044B7C0C, 0x044C00sizeof(aEntry)/sizeof(aEntry[0] 0x0035E401,
212 0x00376008,
213 0x00391C09,
214 6, 0x003AEC02C80331, 0x00AF2835,
215 0x00B39406,
216 0x00B5F
217 0x00B4, 0x04473401, 0x0448B012, 0x044B7C0C,
218 0x044C0403, 0x044CF001, 0x044CF807, 0x044DC005, 0x0452C014,
219 8687, 8}, {8040,86, 8}, 186, 8}, {8104, 1868 {8136,86, 2},
220 {8154, 15{8170, 154, 2},
221 {8172, 18848, 2}, {81860, 112, 1},
222 {8491, 1140836, 1},
223 {11364, 1104, 1},
224 B5{11374, 1060, 1}, {11376, 1029846209, 84, 1},
225 {42930, 86},
226 {43888, 92 30204,
227 54793, 54809,
228 8028020F606809F020F606809F8C0B, 65268, 65341,
229 A34007, 0x07BBC002,
230
231 0x07C34425, 0x07C4401F, 0x04247C01,
232 0x0428E003,
233 0x042B9402 0x043D18 0x0441FC04, 0x0442C012,
234 0x04450004, 0x04451402,
235 0x044B7C0C, 0x044C00sizeof(aEntry)/sizeof(aEntry[0] 0x0035E401,
236 0x00376008,
237 0x00391C09,
238 6, 0x003AEC02C80331, 0x00AF2835,
239 0x00B39406,
240 0x00B5F
241 0x00BC00D6,
242 0x00C0D802,
243 0x00C64002,
244 0x00C94001,
245 0x01370040,
246 0x029A7802,
247 0x02A00801,
248 0x02A1D004,2A3E003,
249 0x02A57C01,
250 0x02A8A40E,
251 0x02A9EC03,
252 0x02AB0401,
253 0x02AF8C0B,
254 0x03EC7801, 0x03ECA
255 0x03F8001A,
256 0x03FC040F,
257 0x03FFA007,
258 0x04063003,
259 0x040DD805,
260 0x0421DC02,
261 0x04283004,
262 0x042B2001,
263 0x04349004,
264 0x0441FC04,
265 0x04450004,
266 0x04471409,*
267 *8028020F606809F8C0, 0x03600001,
268
269 0x044D2C03,
270 0x0450D412,
271 0x04531801,
272 0x0459800D,
273 0x0468040A, 0x0468CC07,46A7805, 0x0470BC08,4724816, 0x0472A40E,
274 0x0474FC07, 0x04751C01,
275 0x047BCC06, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010,
276 442E, 0x05BE3C04, 0x06F27008,
277
278 0x075B0401, 0x075B6C01,
279 0x075D3C01, 0x075DBC01,
280 0x0760028C, 0x076A6C05,
281 0x07806C07, 0x07808C02, 0x07809805, 0x07A34007, 0x07A51007,
282
283 0x07C0C064, 0x07C2800F,
284 0x07C4405C, 0x07C5C03D,
285 0x07C94A,
286 0x07DC0074, 0x07DE0059
287 0x07E18028,402F, 0x07E50031,
288 0x07E5CC04, 0x07E5E801, 0x07E5F027, 0x07E6C00A, 0x07E70003,
289 0x07E74030, 0x07E9800E, 0x38000401, 0x38008060,){896, 3912, 3928,
290
291 4408, 4424, 447
292 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
293 36, 61880, 61914, 61948, 61998, 62122,
294 62154, 62200, 62218, 62302, 62364
295 62554,
296 62924char aChar[] = {
297 '\0', '/*
298 *8028'u', 'y', 'y', 'a', 'c',
299 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
300 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
301 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
302 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
303 '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
304 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
305 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
306 'e', 'i', 'o', 'u', return (
307 *8028020F606809F8C0B,09F8C0B, 0x0360b2058, 1},
308 {503, 1704627678, 1},
309 {981, 1828284, 1, 24},
310 {10081009, 174, 1}, {108846862, 1},
311 {7297,*8028020F606809F8C0B, 0x03600001,
312 sizeof(aDia)/sizeof(aDia[0]
313 0x040DD805,
314 0x0421DC02,
315 0x04283004,
316 0x042B2001,
317 0x04349004,
318 0x0441FC04,
319 0x04450004,
320 0x04471409,*
321 *8028020F606809F8C0, 0x03600001,
322
323 0x044D2C03,
324 0x0450D412,
325 0x04531801,
326 0x0459800D,
327 0x0468040A, 0x0468CC07,46A7805, 0x0470BC08,4724816, 0x0472A40E,
328 0x0474FC07, 0x04751C01,
329 0x047BCC06, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010,
330 442E, 0x05BE3C04, 0x06F27008,
331
332 0x075B0401, 0x075B6C01,
333 0x075D3C01, 0x075DBC01,
334 0x0760028C, 0x076A6C05,
335 0x07806C07, 0x07808C02, 0x07809805, 0x07A34007, 0x07A51007,
336
337 0x07C0C064, 0x07C2800F,
338 0x07C4405C, 0x07C5C03D,
339 0x07C94A,
340 0x07DC0074, 0x07DE0059
341 0x07E18028,402F, 0x07E50031,
342 0x07E5CC04, 0x07E5E801, 0x07E5F027, 0x07E6C00A, 0x07E70003,
343 0x07E74030, 0x07E9800E, 0x38000401, 0x38008060,){896, 3912, 3928,
344
345 4408, 4424, 447
346 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
347 36, 61880, 61914, 61948, 61998, 62122,
348 62154, 62200, 62218, 62302, 62364
349 62554,
350 62924char aChar[] = {
351 '\0', '/*
352 *8028'u', 'y', 'y', 'a', 'c',
353 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
354 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
355 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
356 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
357 '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
358 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
359 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
360 ';e', 'i', 'o', 'u', return (
361 *8028020F606809F8C0B,09F8C0B, 0x0360b2058, 1},
362 {503, 1704627678, 1},
363 {981, 1828284, 1, 24},
364 {10081009, 174, 1}, {108846862, 1},
365 {7297,*8028020F606809F8C0B, 0x03600001,
366 0x03ECA401,
367 0x03F88033,
368 0x03FC6807,
369 0x03FFE405,
370 0x0406400C,
371 0x040E7C01,
372 0x04247C01,
373 0x0428E003,
374 0x042B9402 0x043D18 0x0441FC04, 0x0442C012,
375 0x04450004, 0x04451402,
376 0x044B7C0C, 0x044C0004,
377 0x044D2C03, 0x0600001,
378 0x03ECA402, 1324, 1},
379 {7304, 96, 1}, {7312, 138, 43}, {7357, 13867838, 1168660, 186, 6},
380 {7976, 18686, 8}, {8008, 18687, 8}, {8040,86, 8}, {8104, 18686, 2},
381 {8122,0, 1},
382 {8136,86, 2},
383 {8154, 15{8170, 154, 2},
384 {8172, 18848, 2}, {81860, 112, 1},
385 {8491, 1140836, 1},
386 {11364, 1104, 1},
387 {11374, 1060, 1}, {11376, 1029846209, 84, 1},
388 {42930, 86},
389 {43888, 92 30204,
390 54793, 54809,
391 8028020F606809F020F606809F8C0B, 65268, 65341,
392 65436, 65439,
393 65482, 65488,
394 bRemoveDiacritic ));count(aEntry
395 {42925, 82, 1},
396 sizeof(aEntry)/sizeof(aEntry[0] 0x0456E020,
397 7976, 18686, 8}, {8008,AAC0D, 0x045C740F, 0x045CF004,
398
399 0x05BD442E, 0x05BE3C04,
400 0x0744A4C0, 0x07480046,
401 0x075BEC01, 0x075C5401, 'm', 75E2401, 0x075EA401,05BE3C0076A840F, 0x07A340078},
402 {8120, 184, 2}, {8122, 160, 2}, {8124, 182, 1},
403 {8126, 120, 1}, {82B},
404 {8170,6, 2},
405 B{81868, 1827A, 0x07D5EC29, 0x07D6952C, 0x07DB800D,
406 0x07DBC004, 0x07DC0074,247C01,
407 7E1400A, 0x07E18028, 0x07E24,
408 0x044D2C03, 0x0600001,
409 0x03ECA402, 1324, 1},
410 {7304, 96, 1}, {7312, 138, 43}, {7357, 13867838, 1168660, 186, 6},
411 {7976, 18686, 8}, {8008, 18687, 8}, {8040,86, 8}, {8104, 18686, 2},
412 {8122,0, 1},
413 {8136,86, 2},
414 {8154, 15{8170, 154, 2},
415 {8172, 18848, 2}, {81860, 112, 1},
416 {8491, 1140836, 1},
417 {11364, 1104, 1},
418 {11374, 1060, 1}, {11376, 1029846209, 84, 1},
419 {42930, 86},
420 {43888, 92 30204,
421 54793, 54809,
422 8028020F606809F020F606809F8C0B, 65268, 65341,
423 65436, 65439,
424 65482, 65488,
425 bRemoveDiacritic ));/446, 1},
426 4, 8},
427 {7960, 184, 6},7976, 184, 8}, {7992, 184, 88008, 184, 6},{8025, 185, 8}, {8040,{8088, 184, 8}, {8104, 184, 8},
428 {8120, 184, 2}, {8122, 160, 2}, {8124, 182, 1},
429 {8126, 120, 1}, {8136, 1582, 1},
430 {8152,4, 2},
431 {8170,6, 2},
432 {81868, 182
433
434 {8544, 8, 16},
435 {11264, 24, 47},
436 {11363, 136, 1},
437 {11373, 104, 1},
438
439
440 {11506, 0, 1},*8028020F606606809F8C0B, 0x03600001,
441 {42877, 94, 1},
442 {42893, 86, 1},
443 {42922, 80, 1},
444 {42925, 82, 1},
445 {42929, 840, 831, 68, 1},
446 {429325268, 65341, 65373,
447 65450,
448 65506,
449 8028020F606809F8C0B, 0x03600001,
450 03600001,
451 0x03ECA401,
452 0x03F88033,
453 0x03FC6807,
454 0x03FFE405,
455 0x0406400C,
456 0x040E7C01,
457 0x04247C01,
458 0x0428E003,
459 0x042B9402 0x043D18 0x0441FC04, 0x0442C012,
460 0x04450004, 0x04451402,
461 0x044B7C0C, 0x044C00sizeof(aEntry)/sizeof(aEntry[0] 0x0035E401,
462 0x00376008,
463 0x00391C09,
464 6, 0x003AEC02C80331, 0x00AF2835,
465 0x00B39406,
466 0x00B5F
467 0x00BC00D6,
468 0x00C0D802,
469 0x00C64002,
470 0x00C94001,
471 0x01370040,
472 0x029A7802,
473 0x02A00801,
474 0x02A1D004,2A3E003,
475 0x02A57C01,
476 0x02A8A40E,
477 0x02A9EC03,
478 0x02AB0401,
479 0x02AF8C0B,
480 0x03EC7801, 0x03ECA
481 0x03F8001A,
482 0x03FC040F,
483 0x03FFA007,
484 0x04063003,
485 0x040DD805,
486 0x0421DC02,
487 0x04283004,
488 0x042B2001,
489 0x04349004,
490 0x0441FC04,
491 0x04450004,
492 0x04471409,*
493 *8028020F606809F8C0, 0x03600001,
494
495 0x044D2C03,
496 0x0450D412,
497 0x04531801,
498 0x0459800D,
499 0x0468040A, 0x0468CC07,46A7805, 0x0470BC08,4724816, 0x0472A40E,
500 0x0474FC07, 0x04751C01,
501 0x047BCC06, 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010,
502 442E, 0x05BE3C04, 0x06F27008,
503
504 0x075B0401, 0x075B6C01,
505 0x075D3C01, 0x075DBC01,
506 0x0760028C, 0x076A6C05,
507 0x07806C07, 0x07808C02, 0x07809805, 0x07A34007, 0x07A51007,
508
509 0x07C0C064, 0x07C2800F,
510 0x07C4405C, 0x07C5C03D,
511 0x07C94A,
512 0x07DC0074, 0x07DE0059
513 0x07E18028,402F, 0x07E50031,
514 0x07E5CC04, 0x07E5E801, 0x07E5F027, 0x07E6C00A, 0x07E70003,
515 0x07E74030, 0x07E9800E, 0x38000401, 0x38008060,){896, 3912, 3928,
516
517 4408, 4424, 447
518 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
519 36, 61880, 61914, 61948, 61998, 62122,
520 62154, 62200, 62218, 62302, 62364
521 62554,
522 62924char aChar[] = {
523 '\0', '/*
524 *8028'u', 'y', 'y', 'a', 'c',
525 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
526 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
527 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
528 'u', 's', 't', 'h'
+10 -5
--- src/update.c
+++ src/update.c
@@ -715,14 +715,18 @@
715715
int vid;
716716
vid = db_lget_int("checkout", 0);
717717
vfile_check_signature(vid, 0);
718718
db_multi_exec(
719719
"DELETE FROM vmerge;"
720
- "INSERT INTO torevert "
721
- "SELECT pathname"
722
- " FROM vfile "
723
- " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;"
720
+ "INSERT OR IGNORE INTO torevert "
721
+ " SELECT pathname"
722
+ " FROM vfile "
723
+ " WHERE chnged OR deleted OR rid=0 OR pathname!=origname "
724
+ " UNION ALL "
725
+ " SELECT origname"
726
+ " FROM vfile"
727
+ " WHERE origname!=pathname;"
724728
);
725729
}
726730
blob_zero(&record);
727731
db_prepare(&q, "SELECT name FROM torevert");
728732
if( zRevision==0 ){
@@ -736,11 +740,12 @@
736740
zFile = db_column_text(&q, 0);
737741
zFull = mprintf("%/%/", g.zLocalRoot, zFile);
738742
errCode = historical_version_of_file(zRevision, zFile, &record,
739743
&isLink, &isExe, 0, 2);
740744
if( errCode==2 ){
741
- if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){
745
+ if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q OR origname=%Q",
746
+ zFile, zFile)==0 ){
742747
fossil_print("UNMANAGE: %s\n", zFile);
743748
}else{
744749
undo_save(zFile);
745750
file_delete(zFull);
746751
fossil_print("DELETE: %s\n", zFile);
747752
--- src/update.c
+++ src/update.c
@@ -715,14 +715,18 @@
715 int vid;
716 vid = db_lget_int("checkout", 0);
717 vfile_check_signature(vid, 0);
718 db_multi_exec(
719 "DELETE FROM vmerge;"
720 "INSERT INTO torevert "
721 "SELECT pathname"
722 " FROM vfile "
723 " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;"
 
 
 
 
724 );
725 }
726 blob_zero(&record);
727 db_prepare(&q, "SELECT name FROM torevert");
728 if( zRevision==0 ){
@@ -736,11 +740,12 @@
736 zFile = db_column_text(&q, 0);
737 zFull = mprintf("%/%/", g.zLocalRoot, zFile);
738 errCode = historical_version_of_file(zRevision, zFile, &record,
739 &isLink, &isExe, 0, 2);
740 if( errCode==2 ){
741 if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){
 
742 fossil_print("UNMANAGE: %s\n", zFile);
743 }else{
744 undo_save(zFile);
745 file_delete(zFull);
746 fossil_print("DELETE: %s\n", zFile);
747
--- src/update.c
+++ src/update.c
@@ -715,14 +715,18 @@
715 int vid;
716 vid = db_lget_int("checkout", 0);
717 vfile_check_signature(vid, 0);
718 db_multi_exec(
719 "DELETE FROM vmerge;"
720 "INSERT OR IGNORE INTO torevert "
721 " SELECT pathname"
722 " FROM vfile "
723 " WHERE chnged OR deleted OR rid=0 OR pathname!=origname "
724 " UNION ALL "
725 " SELECT origname"
726 " FROM vfile"
727 " WHERE origname!=pathname;"
728 );
729 }
730 blob_zero(&record);
731 db_prepare(&q, "SELECT name FROM torevert");
732 if( zRevision==0 ){
@@ -736,11 +740,12 @@
740 zFile = db_column_text(&q, 0);
741 zFull = mprintf("%/%/", g.zLocalRoot, zFile);
742 errCode = historical_version_of_file(zRevision, zFile, &record,
743 &isLink, &isExe, 0, 2);
744 if( errCode==2 ){
745 if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q OR origname=%Q",
746 zFile, zFile)==0 ){
747 fossil_print("UNMANAGE: %s\n", zFile);
748 }else{
749 undo_save(zFile);
750 file_delete(zFull);
751 fossil_print("DELETE: %s\n", zFile);
752
+7 -3
--- src/user.c
+++ src/user.c
@@ -303,15 +303,17 @@
303303
**
304304
** (2) If the local database is open, check in VVAR.
305305
**
306306
** (3) Check the default user in the repository
307307
**
308
-** (4) Try the USER environment variable.
308
+** (4) Try the FOSSIL_USER environment variable.
309
+**
310
+** (5) Try the USER environment variable.
309311
**
310
-** (5) Try the USERNAME environment variable.
312
+** (6) Try the USERNAME environment variable.
311313
**
312
-** (6) Check if the user can be extracted from the remote URL.
314
+** (7) Check if the user can be extracted from the remote URL.
313315
**
314316
** The user name is stored in g.zLogin. The uid is in g.userUid.
315317
*/
316318
void user_select(void){
317319
char *zUrl;
@@ -326,10 +328,12 @@
326328
}
327329
328330
if( g.localOpen && attempt_user(db_lget("default-user",0)) ) return;
329331
330332
if( attempt_user(db_get("default-user", 0)) ) return;
333
+
334
+ if( attempt_user(fossil_getenv("FOSSIL_USER")) ) return;
331335
332336
if( attempt_user(fossil_getenv("USER")) ) return;
333337
334338
if( attempt_user(fossil_getenv("USERNAME")) ) return;
335339
336340
--- src/user.c
+++ src/user.c
@@ -303,15 +303,17 @@
303 **
304 ** (2) If the local database is open, check in VVAR.
305 **
306 ** (3) Check the default user in the repository
307 **
308 ** (4) Try the USER environment variable.
 
 
309 **
310 ** (5) Try the USERNAME environment variable.
311 **
312 ** (6) Check if the user can be extracted from the remote URL.
313 **
314 ** The user name is stored in g.zLogin. The uid is in g.userUid.
315 */
316 void user_select(void){
317 char *zUrl;
@@ -326,10 +328,12 @@
326 }
327
328 if( g.localOpen && attempt_user(db_lget("default-user",0)) ) return;
329
330 if( attempt_user(db_get("default-user", 0)) ) return;
 
 
331
332 if( attempt_user(fossil_getenv("USER")) ) return;
333
334 if( attempt_user(fossil_getenv("USERNAME")) ) return;
335
336
--- src/user.c
+++ src/user.c
@@ -303,15 +303,17 @@
303 **
304 ** (2) If the local database is open, check in VVAR.
305 **
306 ** (3) Check the default user in the repository
307 **
308 ** (4) Try the FOSSIL_USER environment variable.
309 **
310 ** (5) Try the USER environment variable.
311 **
312 ** (6) Try the USERNAME environment variable.
313 **
314 ** (7) Check if the user can be extracted from the remote URL.
315 **
316 ** The user name is stored in g.zLogin. The uid is in g.userUid.
317 */
318 void user_select(void){
319 char *zUrl;
@@ -326,10 +328,12 @@
328 }
329
330 if( g.localOpen && attempt_user(db_lget("default-user",0)) ) return;
331
332 if( attempt_user(db_get("default-user", 0)) ) return;
333
334 if( attempt_user(fossil_getenv("FOSSIL_USER")) ) return;
335
336 if( attempt_user(fossil_getenv("USER")) ) return;
337
338 if( attempt_user(fossil_getenv("USERNAME")) ) return;
339
340
+3 -3
--- src/utf8.c
+++ src/utf8.c
@@ -101,11 +101,11 @@
101101
#else
102102
/* No-op on unix */
103103
#endif
104104
}
105105
106
-#if defined(__APPLE__)
106
+#if defined(__APPLE__) && !defined(WITHOUT_ICONV)
107107
# include <iconv.h>
108108
#endif
109109
110110
/*
111111
** Translate text from the filename character set into
@@ -120,11 +120,11 @@
120120
if( zUtf==0 ){
121121
return 0;
122122
}
123123
WideCharToMultiByte(CP_UTF8, 0, zFilename, -1, zUtf, nByte, 0, 0);
124124
return zUtf;
125
-#elif defined(__APPLE__)
125
+#elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
126126
char *zIn = (char*)zFilename;
127127
char *zOut;
128128
iconv_t cd;
129129
size_t n, x;
130130
for(n=0; zIn[n]>0 && zIn[n]<=0x7f; n++){}
@@ -157,11 +157,11 @@
157157
** fossil_filename_to_utf8().
158158
*/
159159
void fossil_filename_free(char *pOld){
160160
#if defined(_WIN32)
161161
sqlite3_free(pOld);
162
-#elif defined(__APPLE__)
162
+#elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
163163
fossil_free(pOld);
164164
#else
165165
/* No-op on all other unix */
166166
#endif
167167
}
168168
--- src/utf8.c
+++ src/utf8.c
@@ -101,11 +101,11 @@
101 #else
102 /* No-op on unix */
103 #endif
104 }
105
106 #if defined(__APPLE__)
107 # include <iconv.h>
108 #endif
109
110 /*
111 ** Translate text from the filename character set into
@@ -120,11 +120,11 @@
120 if( zUtf==0 ){
121 return 0;
122 }
123 WideCharToMultiByte(CP_UTF8, 0, zFilename, -1, zUtf, nByte, 0, 0);
124 return zUtf;
125 #elif defined(__APPLE__)
126 char *zIn = (char*)zFilename;
127 char *zOut;
128 iconv_t cd;
129 size_t n, x;
130 for(n=0; zIn[n]>0 && zIn[n]<=0x7f; n++){}
@@ -157,11 +157,11 @@
157 ** fossil_filename_to_utf8().
158 */
159 void fossil_filename_free(char *pOld){
160 #if defined(_WIN32)
161 sqlite3_free(pOld);
162 #elif defined(__APPLE__)
163 fossil_free(pOld);
164 #else
165 /* No-op on all other unix */
166 #endif
167 }
168
--- src/utf8.c
+++ src/utf8.c
@@ -101,11 +101,11 @@
101 #else
102 /* No-op on unix */
103 #endif
104 }
105
106 #if defined(__APPLE__) && !defined(WITHOUT_ICONV)
107 # include <iconv.h>
108 #endif
109
110 /*
111 ** Translate text from the filename character set into
@@ -120,11 +120,11 @@
120 if( zUtf==0 ){
121 return 0;
122 }
123 WideCharToMultiByte(CP_UTF8, 0, zFilename, -1, zUtf, nByte, 0, 0);
124 return zUtf;
125 #elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
126 char *zIn = (char*)zFilename;
127 char *zOut;
128 iconv_t cd;
129 size_t n, x;
130 for(n=0; zIn[n]>0 && zIn[n]<=0x7f; n++){}
@@ -157,11 +157,11 @@
157 ** fossil_filename_to_utf8().
158 */
159 void fossil_filename_free(char *pOld){
160 #if defined(_WIN32)
161 sqlite3_free(pOld);
162 #elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
163 fossil_free(pOld);
164 #else
165 /* No-op on all other unix */
166 #endif
167 }
168
+1 -1
--- src/wiki.c
+++ src/wiki.c
@@ -667,11 +667,11 @@
667667
if( rid2 && (pW2 = manifest_get(rid2, CFTYPE_WIKI))!=0 ){
668668
blob_init(&w2, pW2->zWiki, -1);
669669
}
670670
blob_zero(&d);
671671
diffFlags = construct_diff_flags(1,0);
672
- text_diff(&w2, &w1, &d, diffFlags | DIFF_HTML | DIFF_LINENO);
672
+ text_diff(&w2, &w1, &d, 0, diffFlags | DIFF_HTML | DIFF_LINENO);
673673
@ <div class="udiff">
674674
@ %s(blob_str(&d))
675675
@ </div>
676676
manifest_destroy(pW1);
677677
manifest_destroy(pW2);
678678
--- src/wiki.c
+++ src/wiki.c
@@ -667,11 +667,11 @@
667 if( rid2 && (pW2 = manifest_get(rid2, CFTYPE_WIKI))!=0 ){
668 blob_init(&w2, pW2->zWiki, -1);
669 }
670 blob_zero(&d);
671 diffFlags = construct_diff_flags(1,0);
672 text_diff(&w2, &w1, &d, diffFlags | DIFF_HTML | DIFF_LINENO);
673 @ <div class="udiff">
674 @ %s(blob_str(&d))
675 @ </div>
676 manifest_destroy(pW1);
677 manifest_destroy(pW2);
678
--- src/wiki.c
+++ src/wiki.c
@@ -667,11 +667,11 @@
667 if( rid2 && (pW2 = manifest_get(rid2, CFTYPE_WIKI))!=0 ){
668 blob_init(&w2, pW2->zWiki, -1);
669 }
670 blob_zero(&d);
671 diffFlags = construct_diff_flags(1,0);
672 text_diff(&w2, &w1, &d, 0, diffFlags | DIFF_HTML | DIFF_LINENO);
673 @ <div class="udiff">
674 @ %s(blob_str(&d))
675 @ </div>
676 manifest_destroy(pW1);
677 manifest_destroy(pW2);
678
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -18,10 +18,33 @@
1818
* <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"
1919
target="testwindow">Large diff of sqlite3.c</a>. This diff was very
2020
slow prior to the preformance enhancement change [9e15437e97].
2121
* <a href="../../../info/bda00cbada#chunk42" target="testwindow">
2222
A difficult indentation change.
23
+ * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"
24
+ target="testwindow">Another tricky indentation.</a> Notice especially
25
+ lines 59398 and 59407 on the left.
26
+ * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"
27
+ target="testwindow">Inverse of the previous.</a>
28
+ * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk24"
29
+ target="testwindow">A complex change</a> that is difficult to align, and
30
+ hence falls back to the "delete left and insert right" strategy.
31
+ * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk24"
32
+ target="testwindow">Inverse of the previous.</a>
33
+ * <a href="../../../fdiff?v1=21f9a00fe2fa4a17&v2=d5c4ff0532bd89c3#chunk5"
34
+ target="testwindow">sqlite3.c changes</a>
35
+ that are difficult to align.
36
+ * <a href="../../../fdiff?v2=21f9a00fe2fa4a17&v1=d5c4ff0532bd89c3#chunk5"
37
+ target="testwindow">sqlite3.c changes inverted.</a>
2338
2439
External:
2540
2641
* <a href="http://www.sqlite.org/src/fdiff?v1=aafcb21a74e41f9a&v2=a6d127dd05daf0f9#chunk3" target="testwindow">
2742
Code indentation change.</a>
43
+ * <a href="http://www.sqlite.org/src/info/52e755943f" target="testwindow">
44
+ A complex change (chunk 1) in which the alignment becomes so complex
45
+ that it is better for clarity to abandon it and just show the left
46
+ and right sides contiguously.</a>
47
+ * <a href="http://www.sqlite.org/src/info/3d65c70343#chunk5"
48
+ target="testwindow">
49
+ An indentation change. See especially lines 2313 and 2317 on the right,
50
+ that their green indentation addition is left-justified.</a>
2851
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -18,10 +18,33 @@
18 * <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"
19 target="testwindow">Large diff of sqlite3.c</a>. This diff was very
20 slow prior to the preformance enhancement change [9e15437e97].
21 * <a href="../../../info/bda00cbada#chunk42" target="testwindow">
22 A difficult indentation change.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
24 External:
25
26 * <a href="http://www.sqlite.org/src/fdiff?v1=aafcb21a74e41f9a&v2=a6d127dd05daf0f9#chunk3" target="testwindow">
27 Code indentation change.</a>
 
 
 
 
 
 
 
 
28
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -18,10 +18,33 @@
18 * <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"
19 target="testwindow">Large diff of sqlite3.c</a>. This diff was very
20 slow prior to the preformance enhancement change [9e15437e97].
21 * <a href="../../../info/bda00cbada#chunk42" target="testwindow">
22 A difficult indentation change.
23 * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"
24 target="testwindow">Another tricky indentation.</a> Notice especially
25 lines 59398 and 59407 on the left.
26 * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"
27 target="testwindow">Inverse of the previous.</a>
28 * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk24"
29 target="testwindow">A complex change</a> that is difficult to align, and
30 hence falls back to the "delete left and insert right" strategy.
31 * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk24"
32 target="testwindow">Inverse of the previous.</a>
33 * <a href="../../../fdiff?v1=21f9a00fe2fa4a17&v2=d5c4ff0532bd89c3#chunk5"
34 target="testwindow">sqlite3.c changes</a>
35 that are difficult to align.
36 * <a href="../../../fdiff?v2=21f9a00fe2fa4a17&v1=d5c4ff0532bd89c3#chunk5"
37 target="testwindow">sqlite3.c changes inverted.</a>
38
39 External:
40
41 * <a href="http://www.sqlite.org/src/fdiff?v1=aafcb21a74e41f9a&v2=a6d127dd05daf0f9#chunk3" target="testwindow">
42 Code indentation change.</a>
43 * <a href="http://www.sqlite.org/src/info/52e755943f" target="testwindow">
44 A complex change (chunk 1) in which the alignment becomes so complex
45 that it is better for clarity to abandon it and just show the left
46 and right sides contiguously.</a>
47 * <a href="http://www.sqlite.org/src/info/3d65c70343#chunk5"
48 target="testwindow">
49 An indentation change. See especially lines 2313 and 2317 on the right,
50 that their green indentation addition is left-justified.</a>
51
+16 -4
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
2626
TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
2727
LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
2828
2929
SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0
3030
31
-SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c update_.c url_.c user_.c utf8_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
31
+SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
3232
33
-OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
33
+OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
3434
3535
3636
RC=$(DMDIR)\bin\rcc
3737
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
3838
@@ -46,11 +46,11 @@
4646
4747
$(OBJDIR)\fossil.res: $B\win\fossil.rc
4848
$(RC) $(RCFLAGS) -o$@ $**
4949
5050
$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
51
- +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_tag json_timeline json_user json_wiki leaf login main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo update url user utf8 verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
51
+ +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_tag json_timeline json_user json_wiki leaf login main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
5252
+echo fossil >> $@
5353
+echo fossil >> $@
5454
+echo $(LIBS) >> $@
5555
+echo. >> $@
5656
+echo fossil >> $@
@@ -523,10 +523,16 @@
523523
$(OBJDIR)\rebuild$O : rebuild_.c rebuild.h
524524
$(TCC) -o$@ -c rebuild_.c
525525
526526
rebuild_.c : $(SRCDIR)\rebuild.c
527527
+translate$E $** > $@
528
+
529
+$(OBJDIR)\regexp$O : regexp_.c regexp.h
530
+ $(TCC) -o$@ -c regexp_.c
531
+
532
+regexp_.c : $(SRCDIR)\regexp.c
533
+ +translate$E $** > $@
528534
529535
$(OBJDIR)\report$O : report_.c report.h
530536
$(TCC) -o$@ -c report_.c
531537
532538
report_.c : $(SRCDIR)\report.c
@@ -643,10 +649,16 @@
643649
$(OBJDIR)\undo$O : undo_.c undo.h
644650
$(TCC) -o$@ -c undo_.c
645651
646652
undo_.c : $(SRCDIR)\undo.c
647653
+translate$E $** > $@
654
+
655
+$(OBJDIR)\unicode$O : unicode_.c unicode.h
656
+ $(TCC) -o$@ -c unicode_.c
657
+
658
+unicode_.c : $(SRCDIR)\unicode.c
659
+ +translate$E $** > $@
648660
649661
$(OBJDIR)\update$O : update_.c update.h
650662
$(TCC) -o$@ -c update_.c
651663
652664
update_.c : $(SRCDIR)\update.c
@@ -723,7 +735,7 @@
723735
724736
zip_.c : $(SRCDIR)\zip.c
725737
+translate$E $** > $@
726738
727739
headers: makeheaders$E page_index.h VERSION.h
728
- +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
740
+ +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
729741
@copy /Y nul: headers
730742
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
26 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
27 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
28
29 SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0
30
31 SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c update_.c url_.c user_.c utf8_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
32
33 OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
34
35
36 RC=$(DMDIR)\bin\rcc
37 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
38
@@ -46,11 +46,11 @@
46
47 $(OBJDIR)\fossil.res: $B\win\fossil.rc
48 $(RC) $(RCFLAGS) -o$@ $**
49
50 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
51 +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_tag json_timeline json_user json_wiki leaf login main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo update url user utf8 verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
52 +echo fossil >> $@
53 +echo fossil >> $@
54 +echo $(LIBS) >> $@
55 +echo. >> $@
56 +echo fossil >> $@
@@ -523,10 +523,16 @@
523 $(OBJDIR)\rebuild$O : rebuild_.c rebuild.h
524 $(TCC) -o$@ -c rebuild_.c
525
526 rebuild_.c : $(SRCDIR)\rebuild.c
527 +translate$E $** > $@
 
 
 
 
 
 
528
529 $(OBJDIR)\report$O : report_.c report.h
530 $(TCC) -o$@ -c report_.c
531
532 report_.c : $(SRCDIR)\report.c
@@ -643,10 +649,16 @@
643 $(OBJDIR)\undo$O : undo_.c undo.h
644 $(TCC) -o$@ -c undo_.c
645
646 undo_.c : $(SRCDIR)\undo.c
647 +translate$E $** > $@
 
 
 
 
 
 
648
649 $(OBJDIR)\update$O : update_.c update.h
650 $(TCC) -o$@ -c update_.c
651
652 update_.c : $(SRCDIR)\update.c
@@ -723,7 +735,7 @@
723
724 zip_.c : $(SRCDIR)\zip.c
725 +translate$E $** > $@
726
727 headers: makeheaders$E page_index.h VERSION.h
728 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
729 @copy /Y nul: headers
730
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
26 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
27 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
28
29 SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0
30
31 SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
32
33 OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
34
35
36 RC=$(DMDIR)\bin\rcc
37 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
38
@@ -46,11 +46,11 @@
46
47 $(OBJDIR)\fossil.res: $B\win\fossil.rc
48 $(RC) $(RCFLAGS) -o$@ $**
49
50 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
51 +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_tag json_timeline json_user json_wiki leaf login main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
52 +echo fossil >> $@
53 +echo fossil >> $@
54 +echo $(LIBS) >> $@
55 +echo. >> $@
56 +echo fossil >> $@
@@ -523,10 +523,16 @@
523 $(OBJDIR)\rebuild$O : rebuild_.c rebuild.h
524 $(TCC) -o$@ -c rebuild_.c
525
526 rebuild_.c : $(SRCDIR)\rebuild.c
527 +translate$E $** > $@
528
529 $(OBJDIR)\regexp$O : regexp_.c regexp.h
530 $(TCC) -o$@ -c regexp_.c
531
532 regexp_.c : $(SRCDIR)\regexp.c
533 +translate$E $** > $@
534
535 $(OBJDIR)\report$O : report_.c report.h
536 $(TCC) -o$@ -c report_.c
537
538 report_.c : $(SRCDIR)\report.c
@@ -643,10 +649,16 @@
649 $(OBJDIR)\undo$O : undo_.c undo.h
650 $(TCC) -o$@ -c undo_.c
651
652 undo_.c : $(SRCDIR)\undo.c
653 +translate$E $** > $@
654
655 $(OBJDIR)\unicode$O : unicode_.c unicode.h
656 $(TCC) -o$@ -c unicode_.c
657
658 unicode_.c : $(SRCDIR)\unicode.c
659 +translate$E $** > $@
660
661 $(OBJDIR)\update$O : update_.c update.h
662 $(TCC) -o$@ -c update_.c
663
664 update_.c : $(SRCDIR)\update.c
@@ -723,7 +735,7 @@
735
736 zip_.c : $(SRCDIR)\zip.c
737 +translate$E $** > $@
738
739 headers: makeheaders$E page_index.h VERSION.h
740 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
741 @copy /Y nul: headers
742
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -73,11 +73,11 @@
7373
7474
#### Check if the workaround for the MinGW command line handling needs to
7575
# be enabled by default.
7676
#
7777
ifndef BROKEN_MINGW_CMDLINE
78
-ifeq ($(PREFIX),)
78
+ifeq (,$(findstring w64-mingw32,$(PREFIX)))
7979
BROKEN_MINGW_CMDLINE = 1
8080
endif
8181
endif
8282
8383
#### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331331
$(SRCDIR)/pivot.c \
332332
$(SRCDIR)/popen.c \
333333
$(SRCDIR)/pqueue.c \
334334
$(SRCDIR)/printf.c \
335335
$(SRCDIR)/rebuild.c \
336
+ $(SRCDIR)/regexp.c \
336337
$(SRCDIR)/report.c \
337338
$(SRCDIR)/rss.c \
338339
$(SRCDIR)/schema.c \
339340
$(SRCDIR)/search.c \
340341
$(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
351352
$(SRCDIR)/th_main.c \
352353
$(SRCDIR)/timeline.c \
353354
$(SRCDIR)/tkt.c \
354355
$(SRCDIR)/tktsetup.c \
355356
$(SRCDIR)/undo.c \
357
+ $(SRCDIR)/unicode.c \
356358
$(SRCDIR)/update.c \
357359
$(SRCDIR)/url.c \
358360
$(SRCDIR)/user.c \
359361
$(SRCDIR)/utf8.c \
360362
$(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
435437
$(OBJDIR)/pivot_.c \
436438
$(OBJDIR)/popen_.c \
437439
$(OBJDIR)/pqueue_.c \
438440
$(OBJDIR)/printf_.c \
439441
$(OBJDIR)/rebuild_.c \
442
+ $(OBJDIR)/regexp_.c \
440443
$(OBJDIR)/report_.c \
441444
$(OBJDIR)/rss_.c \
442445
$(OBJDIR)/schema_.c \
443446
$(OBJDIR)/search_.c \
444447
$(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
455458
$(OBJDIR)/th_main_.c \
456459
$(OBJDIR)/timeline_.c \
457460
$(OBJDIR)/tkt_.c \
458461
$(OBJDIR)/tktsetup_.c \
459462
$(OBJDIR)/undo_.c \
463
+ $(OBJDIR)/unicode_.c \
460464
$(OBJDIR)/update_.c \
461465
$(OBJDIR)/url_.c \
462466
$(OBJDIR)/user_.c \
463467
$(OBJDIR)/utf8_.c \
464468
$(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
539543
$(OBJDIR)/pivot.o \
540544
$(OBJDIR)/popen.o \
541545
$(OBJDIR)/pqueue.o \
542546
$(OBJDIR)/printf.o \
543547
$(OBJDIR)/rebuild.o \
548
+ $(OBJDIR)/regexp.o \
544549
$(OBJDIR)/report.o \
545550
$(OBJDIR)/rss.o \
546551
$(OBJDIR)/schema.o \
547552
$(OBJDIR)/search.o \
548553
$(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
559564
$(OBJDIR)/th_main.o \
560565
$(OBJDIR)/timeline.o \
561566
$(OBJDIR)/tkt.o \
562567
$(OBJDIR)/tktsetup.o \
563568
$(OBJDIR)/undo.o \
569
+ $(OBJDIR)/unicode.o \
564570
$(OBJDIR)/update.o \
565571
$(OBJDIR)/url.o \
566572
$(OBJDIR)/user.o \
567573
$(OBJDIR)/utf8.o \
568574
$(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
756762
$(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
757763
$(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
758764
$(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
759765
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
760766
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
767
+ $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
761768
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
762769
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
763770
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
764771
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
765772
$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
776783
$(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
777784
$(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
778785
$(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
779786
$(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
780787
$(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
788
+ $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
781789
$(OBJDIR)/update_.c:$(OBJDIR)/update.h \
782790
$(OBJDIR)/url_.c:$(OBJDIR)/url.h \
783791
$(OBJDIR)/user_.c:$(OBJDIR)/user.h \
784792
$(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
785793
$(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
13491357
13501358
$(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
13511359
$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
13521360
13531361
$(OBJDIR)/rebuild.h: $(OBJDIR)/headers
1362
+
1363
+$(OBJDIR)/regexp_.c: $(SRCDIR)/regexp.c $(OBJDIR)/translate
1364
+ $(TRANSLATE) $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c
1365
+
1366
+$(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
1367
+ $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
1368
+
1369
+$(OBJDIR)/regexp.h: $(OBJDIR)/headers
13541370
13551371
$(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
13561372
$(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
13571373
13581374
$(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
15091525
15101526
$(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
15111527
$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
15121528
15131529
$(OBJDIR)/undo.h: $(OBJDIR)/headers
1530
+
1531
+$(OBJDIR)/unicode_.c: $(SRCDIR)/unicode.c $(OBJDIR)/translate
1532
+ $(TRANSLATE) $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c
1533
+
1534
+$(OBJDIR)/unicode.o: $(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
1535
+ $(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c
1536
+
1537
+$(OBJDIR)/unicode.h: $(OBJDIR)/headers
15141538
15151539
$(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
15161540
$(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
15171541
15181542
$(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
15191543
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -73,11 +73,11 @@
73
74 #### Check if the workaround for the MinGW command line handling needs to
75 # be enabled by default.
76 #
77 ifndef BROKEN_MINGW_CMDLINE
78 ifeq ($(PREFIX),)
79 BROKEN_MINGW_CMDLINE = 1
80 endif
81 endif
82
83 #### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331 $(SRCDIR)/pivot.c \
332 $(SRCDIR)/popen.c \
333 $(SRCDIR)/pqueue.c \
334 $(SRCDIR)/printf.c \
335 $(SRCDIR)/rebuild.c \
 
336 $(SRCDIR)/report.c \
337 $(SRCDIR)/rss.c \
338 $(SRCDIR)/schema.c \
339 $(SRCDIR)/search.c \
340 $(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
351 $(SRCDIR)/th_main.c \
352 $(SRCDIR)/timeline.c \
353 $(SRCDIR)/tkt.c \
354 $(SRCDIR)/tktsetup.c \
355 $(SRCDIR)/undo.c \
 
356 $(SRCDIR)/update.c \
357 $(SRCDIR)/url.c \
358 $(SRCDIR)/user.c \
359 $(SRCDIR)/utf8.c \
360 $(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
435 $(OBJDIR)/pivot_.c \
436 $(OBJDIR)/popen_.c \
437 $(OBJDIR)/pqueue_.c \
438 $(OBJDIR)/printf_.c \
439 $(OBJDIR)/rebuild_.c \
 
440 $(OBJDIR)/report_.c \
441 $(OBJDIR)/rss_.c \
442 $(OBJDIR)/schema_.c \
443 $(OBJDIR)/search_.c \
444 $(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
455 $(OBJDIR)/th_main_.c \
456 $(OBJDIR)/timeline_.c \
457 $(OBJDIR)/tkt_.c \
458 $(OBJDIR)/tktsetup_.c \
459 $(OBJDIR)/undo_.c \
 
460 $(OBJDIR)/update_.c \
461 $(OBJDIR)/url_.c \
462 $(OBJDIR)/user_.c \
463 $(OBJDIR)/utf8_.c \
464 $(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
539 $(OBJDIR)/pivot.o \
540 $(OBJDIR)/popen.o \
541 $(OBJDIR)/pqueue.o \
542 $(OBJDIR)/printf.o \
543 $(OBJDIR)/rebuild.o \
 
544 $(OBJDIR)/report.o \
545 $(OBJDIR)/rss.o \
546 $(OBJDIR)/schema.o \
547 $(OBJDIR)/search.o \
548 $(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
559 $(OBJDIR)/th_main.o \
560 $(OBJDIR)/timeline.o \
561 $(OBJDIR)/tkt.o \
562 $(OBJDIR)/tktsetup.o \
563 $(OBJDIR)/undo.o \
 
564 $(OBJDIR)/update.o \
565 $(OBJDIR)/url.o \
566 $(OBJDIR)/user.o \
567 $(OBJDIR)/utf8.o \
568 $(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
756 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
757 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
758 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
759 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
760 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
 
761 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
762 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
763 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
764 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
765 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
776 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
777 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
778 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
779 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
780 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
 
781 $(OBJDIR)/update_.c:$(OBJDIR)/update.h \
782 $(OBJDIR)/url_.c:$(OBJDIR)/url.h \
783 $(OBJDIR)/user_.c:$(OBJDIR)/user.h \
784 $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
785 $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
1349
1350 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
1351 $(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
1352
1353 $(OBJDIR)/rebuild.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1354
1355 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
1356 $(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
1357
1358 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
1509
1510 $(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
1511 $(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
1512
1513 $(OBJDIR)/undo.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1514
1515 $(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
1516 $(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
1517
1518 $(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
1519
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -73,11 +73,11 @@
73
74 #### Check if the workaround for the MinGW command line handling needs to
75 # be enabled by default.
76 #
77 ifndef BROKEN_MINGW_CMDLINE
78 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
79 BROKEN_MINGW_CMDLINE = 1
80 endif
81 endif
82
83 #### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331 $(SRCDIR)/pivot.c \
332 $(SRCDIR)/popen.c \
333 $(SRCDIR)/pqueue.c \
334 $(SRCDIR)/printf.c \
335 $(SRCDIR)/rebuild.c \
336 $(SRCDIR)/regexp.c \
337 $(SRCDIR)/report.c \
338 $(SRCDIR)/rss.c \
339 $(SRCDIR)/schema.c \
340 $(SRCDIR)/search.c \
341 $(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
352 $(SRCDIR)/th_main.c \
353 $(SRCDIR)/timeline.c \
354 $(SRCDIR)/tkt.c \
355 $(SRCDIR)/tktsetup.c \
356 $(SRCDIR)/undo.c \
357 $(SRCDIR)/unicode.c \
358 $(SRCDIR)/update.c \
359 $(SRCDIR)/url.c \
360 $(SRCDIR)/user.c \
361 $(SRCDIR)/utf8.c \
362 $(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
437 $(OBJDIR)/pivot_.c \
438 $(OBJDIR)/popen_.c \
439 $(OBJDIR)/pqueue_.c \
440 $(OBJDIR)/printf_.c \
441 $(OBJDIR)/rebuild_.c \
442 $(OBJDIR)/regexp_.c \
443 $(OBJDIR)/report_.c \
444 $(OBJDIR)/rss_.c \
445 $(OBJDIR)/schema_.c \
446 $(OBJDIR)/search_.c \
447 $(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
458 $(OBJDIR)/th_main_.c \
459 $(OBJDIR)/timeline_.c \
460 $(OBJDIR)/tkt_.c \
461 $(OBJDIR)/tktsetup_.c \
462 $(OBJDIR)/undo_.c \
463 $(OBJDIR)/unicode_.c \
464 $(OBJDIR)/update_.c \
465 $(OBJDIR)/url_.c \
466 $(OBJDIR)/user_.c \
467 $(OBJDIR)/utf8_.c \
468 $(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
543 $(OBJDIR)/pivot.o \
544 $(OBJDIR)/popen.o \
545 $(OBJDIR)/pqueue.o \
546 $(OBJDIR)/printf.o \
547 $(OBJDIR)/rebuild.o \
548 $(OBJDIR)/regexp.o \
549 $(OBJDIR)/report.o \
550 $(OBJDIR)/rss.o \
551 $(OBJDIR)/schema.o \
552 $(OBJDIR)/search.o \
553 $(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
564 $(OBJDIR)/th_main.o \
565 $(OBJDIR)/timeline.o \
566 $(OBJDIR)/tkt.o \
567 $(OBJDIR)/tktsetup.o \
568 $(OBJDIR)/undo.o \
569 $(OBJDIR)/unicode.o \
570 $(OBJDIR)/update.o \
571 $(OBJDIR)/url.o \
572 $(OBJDIR)/user.o \
573 $(OBJDIR)/utf8.o \
574 $(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
762 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
763 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
764 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
765 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
766 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
767 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
768 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
769 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
770 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
771 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
772 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
783 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
784 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
785 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
786 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
787 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
788 $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
789 $(OBJDIR)/update_.c:$(OBJDIR)/update.h \
790 $(OBJDIR)/url_.c:$(OBJDIR)/url.h \
791 $(OBJDIR)/user_.c:$(OBJDIR)/user.h \
792 $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
793 $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
1357
1358 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
1359 $(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
1360
1361 $(OBJDIR)/rebuild.h: $(OBJDIR)/headers
1362
1363 $(OBJDIR)/regexp_.c: $(SRCDIR)/regexp.c $(OBJDIR)/translate
1364 $(TRANSLATE) $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c
1365
1366 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
1367 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
1368
1369 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
1370
1371 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
1372 $(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
1373
1374 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
1525
1526 $(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
1527 $(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
1528
1529 $(OBJDIR)/undo.h: $(OBJDIR)/headers
1530
1531 $(OBJDIR)/unicode_.c: $(SRCDIR)/unicode.c $(OBJDIR)/translate
1532 $(TRANSLATE) $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c
1533
1534 $(OBJDIR)/unicode.o: $(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
1535 $(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c
1536
1537 $(OBJDIR)/unicode.h: $(OBJDIR)/headers
1538
1539 $(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
1540 $(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
1541
1542 $(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
1543
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -73,11 +73,11 @@
7373
7474
#### Check if the workaround for the MinGW command line handling needs to
7575
# be enabled by default.
7676
#
7777
ifndef BROKEN_MINGW_CMDLINE
78
-ifeq ($(PREFIX),)
78
+ifeq (,$(findstring w64-mingw32,$(PREFIX)))
7979
BROKEN_MINGW_CMDLINE = 1
8080
endif
8181
endif
8282
8383
#### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331331
$(SRCDIR)/pivot.c \
332332
$(SRCDIR)/popen.c \
333333
$(SRCDIR)/pqueue.c \
334334
$(SRCDIR)/printf.c \
335335
$(SRCDIR)/rebuild.c \
336
+ $(SRCDIR)/regexp.c \
336337
$(SRCDIR)/report.c \
337338
$(SRCDIR)/rss.c \
338339
$(SRCDIR)/schema.c \
339340
$(SRCDIR)/search.c \
340341
$(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
351352
$(SRCDIR)/th_main.c \
352353
$(SRCDIR)/timeline.c \
353354
$(SRCDIR)/tkt.c \
354355
$(SRCDIR)/tktsetup.c \
355356
$(SRCDIR)/undo.c \
357
+ $(SRCDIR)/unicode.c \
356358
$(SRCDIR)/update.c \
357359
$(SRCDIR)/url.c \
358360
$(SRCDIR)/user.c \
359361
$(SRCDIR)/utf8.c \
360362
$(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
435437
$(OBJDIR)/pivot_.c \
436438
$(OBJDIR)/popen_.c \
437439
$(OBJDIR)/pqueue_.c \
438440
$(OBJDIR)/printf_.c \
439441
$(OBJDIR)/rebuild_.c \
442
+ $(OBJDIR)/regexp_.c \
440443
$(OBJDIR)/report_.c \
441444
$(OBJDIR)/rss_.c \
442445
$(OBJDIR)/schema_.c \
443446
$(OBJDIR)/search_.c \
444447
$(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
455458
$(OBJDIR)/th_main_.c \
456459
$(OBJDIR)/timeline_.c \
457460
$(OBJDIR)/tkt_.c \
458461
$(OBJDIR)/tktsetup_.c \
459462
$(OBJDIR)/undo_.c \
463
+ $(OBJDIR)/unicode_.c \
460464
$(OBJDIR)/update_.c \
461465
$(OBJDIR)/url_.c \
462466
$(OBJDIR)/user_.c \
463467
$(OBJDIR)/utf8_.c \
464468
$(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
539543
$(OBJDIR)/pivot.o \
540544
$(OBJDIR)/popen.o \
541545
$(OBJDIR)/pqueue.o \
542546
$(OBJDIR)/printf.o \
543547
$(OBJDIR)/rebuild.o \
548
+ $(OBJDIR)/regexp.o \
544549
$(OBJDIR)/report.o \
545550
$(OBJDIR)/rss.o \
546551
$(OBJDIR)/schema.o \
547552
$(OBJDIR)/search.o \
548553
$(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
559564
$(OBJDIR)/th_main.o \
560565
$(OBJDIR)/timeline.o \
561566
$(OBJDIR)/tkt.o \
562567
$(OBJDIR)/tktsetup.o \
563568
$(OBJDIR)/undo.o \
569
+ $(OBJDIR)/unicode.o \
564570
$(OBJDIR)/update.o \
565571
$(OBJDIR)/url.o \
566572
$(OBJDIR)/user.o \
567573
$(OBJDIR)/utf8.o \
568574
$(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
756762
$(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
757763
$(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
758764
$(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
759765
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
760766
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
767
+ $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
761768
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
762769
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
763770
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
764771
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
765772
$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
776783
$(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
777784
$(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
778785
$(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
779786
$(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
780787
$(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
788
+ $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
781789
$(OBJDIR)/update_.c:$(OBJDIR)/update.h \
782790
$(OBJDIR)/url_.c:$(OBJDIR)/url.h \
783791
$(OBJDIR)/user_.c:$(OBJDIR)/user.h \
784792
$(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
785793
$(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
13491357
13501358
$(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
13511359
$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
13521360
13531361
$(OBJDIR)/rebuild.h: $(OBJDIR)/headers
1362
+
1363
+$(OBJDIR)/regexp_.c: $(SRCDIR)/regexp.c $(OBJDIR)/translate
1364
+ $(TRANSLATE) $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c
1365
+
1366
+$(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
1367
+ $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
1368
+
1369
+$(OBJDIR)/regexp.h: $(OBJDIR)/headers
13541370
13551371
$(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
13561372
$(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
13571373
13581374
$(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
15091525
15101526
$(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
15111527
$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
15121528
15131529
$(OBJDIR)/undo.h: $(OBJDIR)/headers
1530
+
1531
+$(OBJDIR)/unicode_.c: $(SRCDIR)/unicode.c $(OBJDIR)/translate
1532
+ $(TRANSLATE) $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c
1533
+
1534
+$(OBJDIR)/unicode.o: $(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
1535
+ $(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c
1536
+
1537
+$(OBJDIR)/unicode.h: $(OBJDIR)/headers
15141538
15151539
$(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
15161540
$(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
15171541
15181542
$(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
15191543
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -73,11 +73,11 @@
73
74 #### Check if the workaround for the MinGW command line handling needs to
75 # be enabled by default.
76 #
77 ifndef BROKEN_MINGW_CMDLINE
78 ifeq ($(PREFIX),)
79 BROKEN_MINGW_CMDLINE = 1
80 endif
81 endif
82
83 #### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331 $(SRCDIR)/pivot.c \
332 $(SRCDIR)/popen.c \
333 $(SRCDIR)/pqueue.c \
334 $(SRCDIR)/printf.c \
335 $(SRCDIR)/rebuild.c \
 
336 $(SRCDIR)/report.c \
337 $(SRCDIR)/rss.c \
338 $(SRCDIR)/schema.c \
339 $(SRCDIR)/search.c \
340 $(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
351 $(SRCDIR)/th_main.c \
352 $(SRCDIR)/timeline.c \
353 $(SRCDIR)/tkt.c \
354 $(SRCDIR)/tktsetup.c \
355 $(SRCDIR)/undo.c \
 
356 $(SRCDIR)/update.c \
357 $(SRCDIR)/url.c \
358 $(SRCDIR)/user.c \
359 $(SRCDIR)/utf8.c \
360 $(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
435 $(OBJDIR)/pivot_.c \
436 $(OBJDIR)/popen_.c \
437 $(OBJDIR)/pqueue_.c \
438 $(OBJDIR)/printf_.c \
439 $(OBJDIR)/rebuild_.c \
 
440 $(OBJDIR)/report_.c \
441 $(OBJDIR)/rss_.c \
442 $(OBJDIR)/schema_.c \
443 $(OBJDIR)/search_.c \
444 $(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
455 $(OBJDIR)/th_main_.c \
456 $(OBJDIR)/timeline_.c \
457 $(OBJDIR)/tkt_.c \
458 $(OBJDIR)/tktsetup_.c \
459 $(OBJDIR)/undo_.c \
 
460 $(OBJDIR)/update_.c \
461 $(OBJDIR)/url_.c \
462 $(OBJDIR)/user_.c \
463 $(OBJDIR)/utf8_.c \
464 $(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
539 $(OBJDIR)/pivot.o \
540 $(OBJDIR)/popen.o \
541 $(OBJDIR)/pqueue.o \
542 $(OBJDIR)/printf.o \
543 $(OBJDIR)/rebuild.o \
 
544 $(OBJDIR)/report.o \
545 $(OBJDIR)/rss.o \
546 $(OBJDIR)/schema.o \
547 $(OBJDIR)/search.o \
548 $(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
559 $(OBJDIR)/th_main.o \
560 $(OBJDIR)/timeline.o \
561 $(OBJDIR)/tkt.o \
562 $(OBJDIR)/tktsetup.o \
563 $(OBJDIR)/undo.o \
 
564 $(OBJDIR)/update.o \
565 $(OBJDIR)/url.o \
566 $(OBJDIR)/user.o \
567 $(OBJDIR)/utf8.o \
568 $(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
756 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
757 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
758 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
759 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
760 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
 
761 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
762 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
763 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
764 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
765 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
776 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
777 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
778 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
779 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
780 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
 
781 $(OBJDIR)/update_.c:$(OBJDIR)/update.h \
782 $(OBJDIR)/url_.c:$(OBJDIR)/url.h \
783 $(OBJDIR)/user_.c:$(OBJDIR)/user.h \
784 $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
785 $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
1349
1350 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
1351 $(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
1352
1353 $(OBJDIR)/rebuild.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1354
1355 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
1356 $(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
1357
1358 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
1509
1510 $(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
1511 $(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
1512
1513 $(OBJDIR)/undo.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1514
1515 $(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
1516 $(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
1517
1518 $(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
1519
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -73,11 +73,11 @@
73
74 #### Check if the workaround for the MinGW command line handling needs to
75 # be enabled by default.
76 #
77 ifndef BROKEN_MINGW_CMDLINE
78 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
79 BROKEN_MINGW_CMDLINE = 1
80 endif
81 endif
82
83 #### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331 $(SRCDIR)/pivot.c \
332 $(SRCDIR)/popen.c \
333 $(SRCDIR)/pqueue.c \
334 $(SRCDIR)/printf.c \
335 $(SRCDIR)/rebuild.c \
336 $(SRCDIR)/regexp.c \
337 $(SRCDIR)/report.c \
338 $(SRCDIR)/rss.c \
339 $(SRCDIR)/schema.c \
340 $(SRCDIR)/search.c \
341 $(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
352 $(SRCDIR)/th_main.c \
353 $(SRCDIR)/timeline.c \
354 $(SRCDIR)/tkt.c \
355 $(SRCDIR)/tktsetup.c \
356 $(SRCDIR)/undo.c \
357 $(SRCDIR)/unicode.c \
358 $(SRCDIR)/update.c \
359 $(SRCDIR)/url.c \
360 $(SRCDIR)/user.c \
361 $(SRCDIR)/utf8.c \
362 $(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
437 $(OBJDIR)/pivot_.c \
438 $(OBJDIR)/popen_.c \
439 $(OBJDIR)/pqueue_.c \
440 $(OBJDIR)/printf_.c \
441 $(OBJDIR)/rebuild_.c \
442 $(OBJDIR)/regexp_.c \
443 $(OBJDIR)/report_.c \
444 $(OBJDIR)/rss_.c \
445 $(OBJDIR)/schema_.c \
446 $(OBJDIR)/search_.c \
447 $(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
458 $(OBJDIR)/th_main_.c \
459 $(OBJDIR)/timeline_.c \
460 $(OBJDIR)/tkt_.c \
461 $(OBJDIR)/tktsetup_.c \
462 $(OBJDIR)/undo_.c \
463 $(OBJDIR)/unicode_.c \
464 $(OBJDIR)/update_.c \
465 $(OBJDIR)/url_.c \
466 $(OBJDIR)/user_.c \
467 $(OBJDIR)/utf8_.c \
468 $(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
543 $(OBJDIR)/pivot.o \
544 $(OBJDIR)/popen.o \
545 $(OBJDIR)/pqueue.o \
546 $(OBJDIR)/printf.o \
547 $(OBJDIR)/rebuild.o \
548 $(OBJDIR)/regexp.o \
549 $(OBJDIR)/report.o \
550 $(OBJDIR)/rss.o \
551 $(OBJDIR)/schema.o \
552 $(OBJDIR)/search.o \
553 $(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
564 $(OBJDIR)/th_main.o \
565 $(OBJDIR)/timeline.o \
566 $(OBJDIR)/tkt.o \
567 $(OBJDIR)/tktsetup.o \
568 $(OBJDIR)/undo.o \
569 $(OBJDIR)/unicode.o \
570 $(OBJDIR)/update.o \
571 $(OBJDIR)/url.o \
572 $(OBJDIR)/user.o \
573 $(OBJDIR)/utf8.o \
574 $(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
762 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
763 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
764 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
765 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
766 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
767 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
768 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
769 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
770 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
771 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
772 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
783 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
784 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
785 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
786 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
787 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
788 $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
789 $(OBJDIR)/update_.c:$(OBJDIR)/update.h \
790 $(OBJDIR)/url_.c:$(OBJDIR)/url.h \
791 $(OBJDIR)/user_.c:$(OBJDIR)/user.h \
792 $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
793 $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
1357
1358 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
1359 $(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
1360
1361 $(OBJDIR)/rebuild.h: $(OBJDIR)/headers
1362
1363 $(OBJDIR)/regexp_.c: $(SRCDIR)/regexp.c $(OBJDIR)/translate
1364 $(TRANSLATE) $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c
1365
1366 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
1367 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
1368
1369 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
1370
1371 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
1372 $(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
1373
1374 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
1525
1526 $(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
1527 $(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
1528
1529 $(OBJDIR)/undo.h: $(OBJDIR)/headers
1530
1531 $(OBJDIR)/unicode_.c: $(SRCDIR)/unicode.c $(OBJDIR)/translate
1532 $(TRANSLATE) $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c
1533
1534 $(OBJDIR)/unicode.o: $(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
1535 $(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c
1536
1537 $(OBJDIR)/unicode.h: $(OBJDIR)/headers
1538
1539 $(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
1540 $(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
1541
1542 $(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
1543
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -73,11 +73,11 @@
7373
7474
#### Check if the workaround for the MinGW command line handling needs to
7575
# be enabled by default.
7676
#
7777
ifndef BROKEN_MINGW_CMDLINE
78
-ifeq ($(PREFIX),)
78
+ifeq (,$(findstring w64-mingw32,$(PREFIX)))
7979
BROKEN_MINGW_CMDLINE = 1
8080
endif
8181
endif
8282
8383
#### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331331
$(SRCDIR)/pivot.c \
332332
$(SRCDIR)/popen.c \
333333
$(SRCDIR)/pqueue.c \
334334
$(SRCDIR)/printf.c \
335335
$(SRCDIR)/rebuild.c \
336
+ $(SRCDIR)/regexp.c \
336337
$(SRCDIR)/report.c \
337338
$(SRCDIR)/rss.c \
338339
$(SRCDIR)/schema.c \
339340
$(SRCDIR)/search.c \
340341
$(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
351352
$(SRCDIR)/th_main.c \
352353
$(SRCDIR)/timeline.c \
353354
$(SRCDIR)/tkt.c \
354355
$(SRCDIR)/tktsetup.c \
355356
$(SRCDIR)/undo.c \
357
+ $(SRCDIR)/unicode.c \
356358
$(SRCDIR)/update.c \
357359
$(SRCDIR)/url.c \
358360
$(SRCDIR)/user.c \
359361
$(SRCDIR)/utf8.c \
360362
$(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
435437
$(OBJDIR)/pivot_.c \
436438
$(OBJDIR)/popen_.c \
437439
$(OBJDIR)/pqueue_.c \
438440
$(OBJDIR)/printf_.c \
439441
$(OBJDIR)/rebuild_.c \
442
+ $(OBJDIR)/regexp_.c \
440443
$(OBJDIR)/report_.c \
441444
$(OBJDIR)/rss_.c \
442445
$(OBJDIR)/schema_.c \
443446
$(OBJDIR)/search_.c \
444447
$(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
455458
$(OBJDIR)/th_main_.c \
456459
$(OBJDIR)/timeline_.c \
457460
$(OBJDIR)/tkt_.c \
458461
$(OBJDIR)/tktsetup_.c \
459462
$(OBJDIR)/undo_.c \
463
+ $(OBJDIR)/unicode_.c \
460464
$(OBJDIR)/update_.c \
461465
$(OBJDIR)/url_.c \
462466
$(OBJDIR)/user_.c \
463467
$(OBJDIR)/utf8_.c \
464468
$(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
539543
$(OBJDIR)/pivot.o \
540544
$(OBJDIR)/popen.o \
541545
$(OBJDIR)/pqueue.o \
542546
$(OBJDIR)/printf.o \
543547
$(OBJDIR)/rebuild.o \
548
+ $(OBJDIR)/regexp.o \
544549
$(OBJDIR)/report.o \
545550
$(OBJDIR)/rss.o \
546551
$(OBJDIR)/schema.o \
547552
$(OBJDIR)/search.o \
548553
$(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
559564
$(OBJDIR)/th_main.o \
560565
$(OBJDIR)/timeline.o \
561566
$(OBJDIR)/tkt.o \
562567
$(OBJDIR)/tktsetup.o \
563568
$(OBJDIR)/undo.o \
569
+ $(OBJDIR)/unicode.o \
564570
$(OBJDIR)/update.o \
565571
$(OBJDIR)/url.o \
566572
$(OBJDIR)/user.o \
567573
$(OBJDIR)/utf8.o \
568574
$(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
756762
$(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
757763
$(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
758764
$(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
759765
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
760766
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
767
+ $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
761768
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
762769
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
763770
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
764771
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
765772
$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
776783
$(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
777784
$(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
778785
$(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
779786
$(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
780787
$(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
788
+ $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
781789
$(OBJDIR)/update_.c:$(OBJDIR)/update.h \
782790
$(OBJDIR)/url_.c:$(OBJDIR)/url.h \
783791
$(OBJDIR)/user_.c:$(OBJDIR)/user.h \
784792
$(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
785793
$(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
13491357
13501358
$(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
13511359
$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
13521360
13531361
$(OBJDIR)/rebuild.h: $(OBJDIR)/headers
1362
+
1363
+$(OBJDIR)/regexp_.c: $(SRCDIR)/regexp.c $(OBJDIR)/translate
1364
+ $(TRANSLATE) $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c
1365
+
1366
+$(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
1367
+ $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
1368
+
1369
+$(OBJDIR)/regexp.h: $(OBJDIR)/headers
13541370
13551371
$(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
13561372
$(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
13571373
13581374
$(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
15091525
15101526
$(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
15111527
$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
15121528
15131529
$(OBJDIR)/undo.h: $(OBJDIR)/headers
1530
+
1531
+$(OBJDIR)/unicode_.c: $(SRCDIR)/unicode.c $(OBJDIR)/translate
1532
+ $(TRANSLATE) $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c
1533
+
1534
+$(OBJDIR)/unicode.o: $(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
1535
+ $(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c
1536
+
1537
+$(OBJDIR)/unicode.h: $(OBJDIR)/headers
15141538
15151539
$(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
15161540
$(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
15171541
15181542
$(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
15191543
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -73,11 +73,11 @@
73
74 #### Check if the workaround for the MinGW command line handling needs to
75 # be enabled by default.
76 #
77 ifndef BROKEN_MINGW_CMDLINE
78 ifeq ($(PREFIX),)
79 BROKEN_MINGW_CMDLINE = 1
80 endif
81 endif
82
83 #### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331 $(SRCDIR)/pivot.c \
332 $(SRCDIR)/popen.c \
333 $(SRCDIR)/pqueue.c \
334 $(SRCDIR)/printf.c \
335 $(SRCDIR)/rebuild.c \
 
336 $(SRCDIR)/report.c \
337 $(SRCDIR)/rss.c \
338 $(SRCDIR)/schema.c \
339 $(SRCDIR)/search.c \
340 $(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
351 $(SRCDIR)/th_main.c \
352 $(SRCDIR)/timeline.c \
353 $(SRCDIR)/tkt.c \
354 $(SRCDIR)/tktsetup.c \
355 $(SRCDIR)/undo.c \
 
356 $(SRCDIR)/update.c \
357 $(SRCDIR)/url.c \
358 $(SRCDIR)/user.c \
359 $(SRCDIR)/utf8.c \
360 $(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
435 $(OBJDIR)/pivot_.c \
436 $(OBJDIR)/popen_.c \
437 $(OBJDIR)/pqueue_.c \
438 $(OBJDIR)/printf_.c \
439 $(OBJDIR)/rebuild_.c \
 
440 $(OBJDIR)/report_.c \
441 $(OBJDIR)/rss_.c \
442 $(OBJDIR)/schema_.c \
443 $(OBJDIR)/search_.c \
444 $(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
455 $(OBJDIR)/th_main_.c \
456 $(OBJDIR)/timeline_.c \
457 $(OBJDIR)/tkt_.c \
458 $(OBJDIR)/tktsetup_.c \
459 $(OBJDIR)/undo_.c \
 
460 $(OBJDIR)/update_.c \
461 $(OBJDIR)/url_.c \
462 $(OBJDIR)/user_.c \
463 $(OBJDIR)/utf8_.c \
464 $(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
539 $(OBJDIR)/pivot.o \
540 $(OBJDIR)/popen.o \
541 $(OBJDIR)/pqueue.o \
542 $(OBJDIR)/printf.o \
543 $(OBJDIR)/rebuild.o \
 
544 $(OBJDIR)/report.o \
545 $(OBJDIR)/rss.o \
546 $(OBJDIR)/schema.o \
547 $(OBJDIR)/search.o \
548 $(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
559 $(OBJDIR)/th_main.o \
560 $(OBJDIR)/timeline.o \
561 $(OBJDIR)/tkt.o \
562 $(OBJDIR)/tktsetup.o \
563 $(OBJDIR)/undo.o \
 
564 $(OBJDIR)/update.o \
565 $(OBJDIR)/url.o \
566 $(OBJDIR)/user.o \
567 $(OBJDIR)/utf8.o \
568 $(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
756 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
757 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
758 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
759 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
760 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
 
761 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
762 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
763 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
764 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
765 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
776 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
777 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
778 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
779 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
780 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
 
781 $(OBJDIR)/update_.c:$(OBJDIR)/update.h \
782 $(OBJDIR)/url_.c:$(OBJDIR)/url.h \
783 $(OBJDIR)/user_.c:$(OBJDIR)/user.h \
784 $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
785 $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
1349
1350 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
1351 $(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
1352
1353 $(OBJDIR)/rebuild.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1354
1355 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
1356 $(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
1357
1358 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
1509
1510 $(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
1511 $(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
1512
1513 $(OBJDIR)/undo.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1514
1515 $(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
1516 $(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
1517
1518 $(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
1519
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -73,11 +73,11 @@
73
74 #### Check if the workaround for the MinGW command line handling needs to
75 # be enabled by default.
76 #
77 ifndef BROKEN_MINGW_CMDLINE
78 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
79 BROKEN_MINGW_CMDLINE = 1
80 endif
81 endif
82
83 #### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331 $(SRCDIR)/pivot.c \
332 $(SRCDIR)/popen.c \
333 $(SRCDIR)/pqueue.c \
334 $(SRCDIR)/printf.c \
335 $(SRCDIR)/rebuild.c \
336 $(SRCDIR)/regexp.c \
337 $(SRCDIR)/report.c \
338 $(SRCDIR)/rss.c \
339 $(SRCDIR)/schema.c \
340 $(SRCDIR)/search.c \
341 $(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
352 $(SRCDIR)/th_main.c \
353 $(SRCDIR)/timeline.c \
354 $(SRCDIR)/tkt.c \
355 $(SRCDIR)/tktsetup.c \
356 $(SRCDIR)/undo.c \
357 $(SRCDIR)/unicode.c \
358 $(SRCDIR)/update.c \
359 $(SRCDIR)/url.c \
360 $(SRCDIR)/user.c \
361 $(SRCDIR)/utf8.c \
362 $(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
437 $(OBJDIR)/pivot_.c \
438 $(OBJDIR)/popen_.c \
439 $(OBJDIR)/pqueue_.c \
440 $(OBJDIR)/printf_.c \
441 $(OBJDIR)/rebuild_.c \
442 $(OBJDIR)/regexp_.c \
443 $(OBJDIR)/report_.c \
444 $(OBJDIR)/rss_.c \
445 $(OBJDIR)/schema_.c \
446 $(OBJDIR)/search_.c \
447 $(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
458 $(OBJDIR)/th_main_.c \
459 $(OBJDIR)/timeline_.c \
460 $(OBJDIR)/tkt_.c \
461 $(OBJDIR)/tktsetup_.c \
462 $(OBJDIR)/undo_.c \
463 $(OBJDIR)/unicode_.c \
464 $(OBJDIR)/update_.c \
465 $(OBJDIR)/url_.c \
466 $(OBJDIR)/user_.c \
467 $(OBJDIR)/utf8_.c \
468 $(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
543 $(OBJDIR)/pivot.o \
544 $(OBJDIR)/popen.o \
545 $(OBJDIR)/pqueue.o \
546 $(OBJDIR)/printf.o \
547 $(OBJDIR)/rebuild.o \
548 $(OBJDIR)/regexp.o \
549 $(OBJDIR)/report.o \
550 $(OBJDIR)/rss.o \
551 $(OBJDIR)/schema.o \
552 $(OBJDIR)/search.o \
553 $(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
564 $(OBJDIR)/th_main.o \
565 $(OBJDIR)/timeline.o \
566 $(OBJDIR)/tkt.o \
567 $(OBJDIR)/tktsetup.o \
568 $(OBJDIR)/undo.o \
569 $(OBJDIR)/unicode.o \
570 $(OBJDIR)/update.o \
571 $(OBJDIR)/url.o \
572 $(OBJDIR)/user.o \
573 $(OBJDIR)/utf8.o \
574 $(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
762 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
763 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
764 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
765 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
766 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
767 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
768 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
769 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
770 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
771 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
772 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
783 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
784 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
785 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
786 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
787 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
788 $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
789 $(OBJDIR)/update_.c:$(OBJDIR)/update.h \
790 $(OBJDIR)/url_.c:$(OBJDIR)/url.h \
791 $(OBJDIR)/user_.c:$(OBJDIR)/user.h \
792 $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
793 $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
1357
1358 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
1359 $(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
1360
1361 $(OBJDIR)/rebuild.h: $(OBJDIR)/headers
1362
1363 $(OBJDIR)/regexp_.c: $(SRCDIR)/regexp.c $(OBJDIR)/translate
1364 $(TRANSLATE) $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c
1365
1366 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
1367 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
1368
1369 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
1370
1371 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
1372 $(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
1373
1374 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
1525
1526 $(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
1527 $(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
1528
1529 $(OBJDIR)/undo.h: $(OBJDIR)/headers
1530
1531 $(OBJDIR)/unicode_.c: $(SRCDIR)/unicode.c $(OBJDIR)/translate
1532 $(TRANSLATE) $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c
1533
1534 $(OBJDIR)/unicode.o: $(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
1535 $(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c
1536
1537 $(OBJDIR)/unicode.h: $(OBJDIR)/headers
1538
1539 $(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
1540 $(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
1541
1542 $(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
1543
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -73,11 +73,11 @@
7373
7474
#### Check if the workaround for the MinGW command line handling needs to
7575
# be enabled by default.
7676
#
7777
ifndef BROKEN_MINGW_CMDLINE
78
-ifeq ($(PREFIX),)
78
+ifeq (,$(findstring w64-mingw32,$(PREFIX)))
7979
BROKEN_MINGW_CMDLINE = 1
8080
endif
8181
endif
8282
8383
#### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331331
$(SRCDIR)/pivot.c \
332332
$(SRCDIR)/popen.c \
333333
$(SRCDIR)/pqueue.c \
334334
$(SRCDIR)/printf.c \
335335
$(SRCDIR)/rebuild.c \
336
+ $(SRCDIR)/regexp.c \
336337
$(SRCDIR)/report.c \
337338
$(SRCDIR)/rss.c \
338339
$(SRCDIR)/schema.c \
339340
$(SRCDIR)/search.c \
340341
$(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
351352
$(SRCDIR)/th_main.c \
352353
$(SRCDIR)/timeline.c \
353354
$(SRCDIR)/tkt.c \
354355
$(SRCDIR)/tktsetup.c \
355356
$(SRCDIR)/undo.c \
357
+ $(SRCDIR)/unicode.c \
356358
$(SRCDIR)/update.c \
357359
$(SRCDIR)/url.c \
358360
$(SRCDIR)/user.c \
359361
$(SRCDIR)/utf8.c \
360362
$(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
435437
$(OBJDIR)/pivot_.c \
436438
$(OBJDIR)/popen_.c \
437439
$(OBJDIR)/pqueue_.c \
438440
$(OBJDIR)/printf_.c \
439441
$(OBJDIR)/rebuild_.c \
442
+ $(OBJDIR)/regexp_.c \
440443
$(OBJDIR)/report_.c \
441444
$(OBJDIR)/rss_.c \
442445
$(OBJDIR)/schema_.c \
443446
$(OBJDIR)/search_.c \
444447
$(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
455458
$(OBJDIR)/th_main_.c \
456459
$(OBJDIR)/timeline_.c \
457460
$(OBJDIR)/tkt_.c \
458461
$(OBJDIR)/tktsetup_.c \
459462
$(OBJDIR)/undo_.c \
463
+ $(OBJDIR)/unicode_.c \
460464
$(OBJDIR)/update_.c \
461465
$(OBJDIR)/url_.c \
462466
$(OBJDIR)/user_.c \
463467
$(OBJDIR)/utf8_.c \
464468
$(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
539543
$(OBJDIR)/pivot.o \
540544
$(OBJDIR)/popen.o \
541545
$(OBJDIR)/pqueue.o \
542546
$(OBJDIR)/printf.o \
543547
$(OBJDIR)/rebuild.o \
548
+ $(OBJDIR)/regexp.o \
544549
$(OBJDIR)/report.o \
545550
$(OBJDIR)/rss.o \
546551
$(OBJDIR)/schema.o \
547552
$(OBJDIR)/search.o \
548553
$(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
559564
$(OBJDIR)/th_main.o \
560565
$(OBJDIR)/timeline.o \
561566
$(OBJDIR)/tkt.o \
562567
$(OBJDIR)/tktsetup.o \
563568
$(OBJDIR)/undo.o \
569
+ $(OBJDIR)/unicode.o \
564570
$(OBJDIR)/update.o \
565571
$(OBJDIR)/url.o \
566572
$(OBJDIR)/user.o \
567573
$(OBJDIR)/utf8.o \
568574
$(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
756762
$(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
757763
$(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
758764
$(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
759765
$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
760766
$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
767
+ $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
761768
$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
762769
$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
763770
$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
764771
$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
765772
$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
776783
$(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
777784
$(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
778785
$(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
779786
$(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
780787
$(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
788
+ $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
781789
$(OBJDIR)/update_.c:$(OBJDIR)/update.h \
782790
$(OBJDIR)/url_.c:$(OBJDIR)/url.h \
783791
$(OBJDIR)/user_.c:$(OBJDIR)/user.h \
784792
$(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
785793
$(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
13491357
13501358
$(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
13511359
$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
13521360
13531361
$(OBJDIR)/rebuild.h: $(OBJDIR)/headers
1362
+
1363
+$(OBJDIR)/regexp_.c: $(SRCDIR)/regexp.c $(OBJDIR)/translate
1364
+ $(TRANSLATE) $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c
1365
+
1366
+$(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
1367
+ $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
1368
+
1369
+$(OBJDIR)/regexp.h: $(OBJDIR)/headers
13541370
13551371
$(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
13561372
$(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
13571373
13581374
$(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
15091525
15101526
$(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
15111527
$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
15121528
15131529
$(OBJDIR)/undo.h: $(OBJDIR)/headers
1530
+
1531
+$(OBJDIR)/unicode_.c: $(SRCDIR)/unicode.c $(OBJDIR)/translate
1532
+ $(TRANSLATE) $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c
1533
+
1534
+$(OBJDIR)/unicode.o: $(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
1535
+ $(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c
1536
+
1537
+$(OBJDIR)/unicode.h: $(OBJDIR)/headers
15141538
15151539
$(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
15161540
$(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
15171541
15181542
$(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
15191543
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -73,11 +73,11 @@
73
74 #### Check if the workaround for the MinGW command line handling needs to
75 # be enabled by default.
76 #
77 ifndef BROKEN_MINGW_CMDLINE
78 ifeq ($(PREFIX),)
79 BROKEN_MINGW_CMDLINE = 1
80 endif
81 endif
82
83 #### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331 $(SRCDIR)/pivot.c \
332 $(SRCDIR)/popen.c \
333 $(SRCDIR)/pqueue.c \
334 $(SRCDIR)/printf.c \
335 $(SRCDIR)/rebuild.c \
 
336 $(SRCDIR)/report.c \
337 $(SRCDIR)/rss.c \
338 $(SRCDIR)/schema.c \
339 $(SRCDIR)/search.c \
340 $(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
351 $(SRCDIR)/th_main.c \
352 $(SRCDIR)/timeline.c \
353 $(SRCDIR)/tkt.c \
354 $(SRCDIR)/tktsetup.c \
355 $(SRCDIR)/undo.c \
 
356 $(SRCDIR)/update.c \
357 $(SRCDIR)/url.c \
358 $(SRCDIR)/user.c \
359 $(SRCDIR)/utf8.c \
360 $(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
435 $(OBJDIR)/pivot_.c \
436 $(OBJDIR)/popen_.c \
437 $(OBJDIR)/pqueue_.c \
438 $(OBJDIR)/printf_.c \
439 $(OBJDIR)/rebuild_.c \
 
440 $(OBJDIR)/report_.c \
441 $(OBJDIR)/rss_.c \
442 $(OBJDIR)/schema_.c \
443 $(OBJDIR)/search_.c \
444 $(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
455 $(OBJDIR)/th_main_.c \
456 $(OBJDIR)/timeline_.c \
457 $(OBJDIR)/tkt_.c \
458 $(OBJDIR)/tktsetup_.c \
459 $(OBJDIR)/undo_.c \
 
460 $(OBJDIR)/update_.c \
461 $(OBJDIR)/url_.c \
462 $(OBJDIR)/user_.c \
463 $(OBJDIR)/utf8_.c \
464 $(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
539 $(OBJDIR)/pivot.o \
540 $(OBJDIR)/popen.o \
541 $(OBJDIR)/pqueue.o \
542 $(OBJDIR)/printf.o \
543 $(OBJDIR)/rebuild.o \
 
544 $(OBJDIR)/report.o \
545 $(OBJDIR)/rss.o \
546 $(OBJDIR)/schema.o \
547 $(OBJDIR)/search.o \
548 $(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
559 $(OBJDIR)/th_main.o \
560 $(OBJDIR)/timeline.o \
561 $(OBJDIR)/tkt.o \
562 $(OBJDIR)/tktsetup.o \
563 $(OBJDIR)/undo.o \
 
564 $(OBJDIR)/update.o \
565 $(OBJDIR)/url.o \
566 $(OBJDIR)/user.o \
567 $(OBJDIR)/utf8.o \
568 $(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
756 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
757 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
758 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
759 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
760 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
 
761 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
762 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
763 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
764 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
765 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
776 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
777 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
778 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
779 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
780 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
 
781 $(OBJDIR)/update_.c:$(OBJDIR)/update.h \
782 $(OBJDIR)/url_.c:$(OBJDIR)/url.h \
783 $(OBJDIR)/user_.c:$(OBJDIR)/user.h \
784 $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
785 $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
1349
1350 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
1351 $(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
1352
1353 $(OBJDIR)/rebuild.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1354
1355 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
1356 $(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
1357
1358 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
1509
1510 $(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
1511 $(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
1512
1513 $(OBJDIR)/undo.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1514
1515 $(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
1516 $(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
1517
1518 $(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
1519
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -73,11 +73,11 @@
73
74 #### Check if the workaround for the MinGW command line handling needs to
75 # be enabled by default.
76 #
77 ifndef BROKEN_MINGW_CMDLINE
78 ifeq (,$(findstring w64-mingw32,$(PREFIX)))
79 BROKEN_MINGW_CMDLINE = 1
80 endif
81 endif
82
83 #### The directories where the zlib include and library files are located.
@@ -331,10 +331,11 @@
331 $(SRCDIR)/pivot.c \
332 $(SRCDIR)/popen.c \
333 $(SRCDIR)/pqueue.c \
334 $(SRCDIR)/printf.c \
335 $(SRCDIR)/rebuild.c \
336 $(SRCDIR)/regexp.c \
337 $(SRCDIR)/report.c \
338 $(SRCDIR)/rss.c \
339 $(SRCDIR)/schema.c \
340 $(SRCDIR)/search.c \
341 $(SRCDIR)/setup.c \
@@ -351,10 +352,11 @@
352 $(SRCDIR)/th_main.c \
353 $(SRCDIR)/timeline.c \
354 $(SRCDIR)/tkt.c \
355 $(SRCDIR)/tktsetup.c \
356 $(SRCDIR)/undo.c \
357 $(SRCDIR)/unicode.c \
358 $(SRCDIR)/update.c \
359 $(SRCDIR)/url.c \
360 $(SRCDIR)/user.c \
361 $(SRCDIR)/utf8.c \
362 $(SRCDIR)/verify.c \
@@ -435,10 +437,11 @@
437 $(OBJDIR)/pivot_.c \
438 $(OBJDIR)/popen_.c \
439 $(OBJDIR)/pqueue_.c \
440 $(OBJDIR)/printf_.c \
441 $(OBJDIR)/rebuild_.c \
442 $(OBJDIR)/regexp_.c \
443 $(OBJDIR)/report_.c \
444 $(OBJDIR)/rss_.c \
445 $(OBJDIR)/schema_.c \
446 $(OBJDIR)/search_.c \
447 $(OBJDIR)/setup_.c \
@@ -455,10 +458,11 @@
458 $(OBJDIR)/th_main_.c \
459 $(OBJDIR)/timeline_.c \
460 $(OBJDIR)/tkt_.c \
461 $(OBJDIR)/tktsetup_.c \
462 $(OBJDIR)/undo_.c \
463 $(OBJDIR)/unicode_.c \
464 $(OBJDIR)/update_.c \
465 $(OBJDIR)/url_.c \
466 $(OBJDIR)/user_.c \
467 $(OBJDIR)/utf8_.c \
468 $(OBJDIR)/verify_.c \
@@ -539,10 +543,11 @@
543 $(OBJDIR)/pivot.o \
544 $(OBJDIR)/popen.o \
545 $(OBJDIR)/pqueue.o \
546 $(OBJDIR)/printf.o \
547 $(OBJDIR)/rebuild.o \
548 $(OBJDIR)/regexp.o \
549 $(OBJDIR)/report.o \
550 $(OBJDIR)/rss.o \
551 $(OBJDIR)/schema.o \
552 $(OBJDIR)/search.o \
553 $(OBJDIR)/setup.o \
@@ -559,10 +564,11 @@
564 $(OBJDIR)/th_main.o \
565 $(OBJDIR)/timeline.o \
566 $(OBJDIR)/tkt.o \
567 $(OBJDIR)/tktsetup.o \
568 $(OBJDIR)/undo.o \
569 $(OBJDIR)/unicode.o \
570 $(OBJDIR)/update.o \
571 $(OBJDIR)/url.o \
572 $(OBJDIR)/user.o \
573 $(OBJDIR)/utf8.o \
574 $(OBJDIR)/verify.o \
@@ -756,10 +762,11 @@
762 $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
763 $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
764 $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
765 $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
766 $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
767 $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
768 $(OBJDIR)/report_.c:$(OBJDIR)/report.h \
769 $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
770 $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
771 $(OBJDIR)/search_.c:$(OBJDIR)/search.h \
772 $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
@@ -776,10 +783,11 @@
783 $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \
784 $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h \
785 $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h \
786 $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h \
787 $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h \
788 $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h \
789 $(OBJDIR)/update_.c:$(OBJDIR)/update.h \
790 $(OBJDIR)/url_.c:$(OBJDIR)/url.h \
791 $(OBJDIR)/user_.c:$(OBJDIR)/user.h \
792 $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h \
793 $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h \
@@ -1349,10 +1357,18 @@
1357
1358 $(OBJDIR)/rebuild.o: $(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
1359 $(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c
1360
1361 $(OBJDIR)/rebuild.h: $(OBJDIR)/headers
1362
1363 $(OBJDIR)/regexp_.c: $(SRCDIR)/regexp.c $(OBJDIR)/translate
1364 $(TRANSLATE) $(SRCDIR)/regexp.c >$(OBJDIR)/regexp_.c
1365
1366 $(OBJDIR)/regexp.o: $(OBJDIR)/regexp_.c $(OBJDIR)/regexp.h $(SRCDIR)/config.h
1367 $(XTCC) -o $(OBJDIR)/regexp.o -c $(OBJDIR)/regexp_.c
1368
1369 $(OBJDIR)/regexp.h: $(OBJDIR)/headers
1370
1371 $(OBJDIR)/report_.c: $(SRCDIR)/report.c $(OBJDIR)/translate
1372 $(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c
1373
1374 $(OBJDIR)/report.o: $(OBJDIR)/report_.c $(OBJDIR)/report.h $(SRCDIR)/config.h
@@ -1509,10 +1525,18 @@
1525
1526 $(OBJDIR)/undo.o: $(OBJDIR)/undo_.c $(OBJDIR)/undo.h $(SRCDIR)/config.h
1527 $(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c
1528
1529 $(OBJDIR)/undo.h: $(OBJDIR)/headers
1530
1531 $(OBJDIR)/unicode_.c: $(SRCDIR)/unicode.c $(OBJDIR)/translate
1532 $(TRANSLATE) $(SRCDIR)/unicode.c >$(OBJDIR)/unicode_.c
1533
1534 $(OBJDIR)/unicode.o: $(OBJDIR)/unicode_.c $(OBJDIR)/unicode.h $(SRCDIR)/config.h
1535 $(XTCC) -o $(OBJDIR)/unicode.o -c $(OBJDIR)/unicode_.c
1536
1537 $(OBJDIR)/unicode.h: $(OBJDIR)/headers
1538
1539 $(OBJDIR)/update_.c: $(SRCDIR)/update.c $(OBJDIR)/translate
1540 $(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c
1541
1542 $(OBJDIR)/update.o: $(OBJDIR)/update_.c $(OBJDIR)/update.h $(SRCDIR)/config.h
1543
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -107,10 +107,11 @@
107107
pivot_.c \
108108
popen_.c \
109109
pqueue_.c \
110110
printf_.c \
111111
rebuild_.c \
112
+ regexp_.c \
112113
report_.c \
113114
rss_.c \
114115
schema_.c \
115116
search_.c \
116117
setup_.c \
@@ -127,10 +128,11 @@
127128
th_main_.c \
128129
timeline_.c \
129130
tkt_.c \
130131
tktsetup_.c \
131132
undo_.c \
133
+ unicode_.c \
132134
update_.c \
133135
url_.c \
134136
user_.c \
135137
utf8_.c \
136138
verify_.c \
@@ -210,10 +212,11 @@
210212
$(OX)\pivot$O \
211213
$(OX)\popen$O \
212214
$(OX)\pqueue$O \
213215
$(OX)\printf$O \
214216
$(OX)\rebuild$O \
217
+ $(OX)\regexp$O \
215218
$(OX)\report$O \
216219
$(OX)\rss$O \
217220
$(OX)\schema$O \
218221
$(OX)\search$O \
219222
$(OX)\setup$O \
@@ -230,10 +233,11 @@
230233
$(OX)\th_main$O \
231234
$(OX)\timeline$O \
232235
$(OX)\tkt$O \
233236
$(OX)\tktsetup$O \
234237
$(OX)\undo$O \
238
+ $(OX)\unicode$O \
235239
$(OX)\update$O \
236240
$(OX)\url$O \
237241
$(OX)\user$O \
238242
$(OX)\utf8$O \
239243
$(OX)\verify$O \
@@ -330,10 +334,11 @@
330334
echo $(OX)\pivot.obj >> $@
331335
echo $(OX)\popen.obj >> $@
332336
echo $(OX)\pqueue.obj >> $@
333337
echo $(OX)\printf.obj >> $@
334338
echo $(OX)\rebuild.obj >> $@
339
+ echo $(OX)\regexp.obj >> $@
335340
echo $(OX)\report.obj >> $@
336341
echo $(OX)\rss.obj >> $@
337342
echo $(OX)\schema.obj >> $@
338343
echo $(OX)\search.obj >> $@
339344
echo $(OX)\setup.obj >> $@
@@ -354,10 +359,11 @@
354359
echo $(OX)\th_main.obj >> $@
355360
echo $(OX)\timeline.obj >> $@
356361
echo $(OX)\tkt.obj >> $@
357362
echo $(OX)\tktsetup.obj >> $@
358363
echo $(OX)\undo.obj >> $@
364
+ echo $(OX)\unicode.obj >> $@
359365
echo $(OX)\update.obj >> $@
360366
echo $(OX)\url.obj >> $@
361367
echo $(OX)\user.obj >> $@
362368
echo $(OX)\utf8.obj >> $@
363369
echo $(OX)\verify.obj >> $@
@@ -853,10 +859,16 @@
853859
$(OX)\rebuild$O : rebuild_.c rebuild.h
854860
$(TCC) /Fo$@ -c rebuild_.c
855861
856862
rebuild_.c : $(SRCDIR)\rebuild.c
857863
translate$E $** > $@
864
+
865
+$(OX)\regexp$O : regexp_.c regexp.h
866
+ $(TCC) /Fo$@ -c regexp_.c
867
+
868
+regexp_.c : $(SRCDIR)\regexp.c
869
+ translate$E $** > $@
858870
859871
$(OX)\report$O : report_.c report.h
860872
$(TCC) /Fo$@ -c report_.c
861873
862874
report_.c : $(SRCDIR)\report.c
@@ -973,10 +985,16 @@
973985
$(OX)\undo$O : undo_.c undo.h
974986
$(TCC) /Fo$@ -c undo_.c
975987
976988
undo_.c : $(SRCDIR)\undo.c
977989
translate$E $** > $@
990
+
991
+$(OX)\unicode$O : unicode_.c unicode.h
992
+ $(TCC) /Fo$@ -c unicode_.c
993
+
994
+unicode_.c : $(SRCDIR)\unicode.c
995
+ translate$E $** > $@
978996
979997
$(OX)\update$O : update_.c update.h
980998
$(TCC) /Fo$@ -c update_.c
981999
9821000
update_.c : $(SRCDIR)\update.c
@@ -1122,10 +1140,11 @@
11221140
pivot_.c:pivot.h \
11231141
popen_.c:popen.h \
11241142
pqueue_.c:pqueue.h \
11251143
printf_.c:printf.h \
11261144
rebuild_.c:rebuild.h \
1145
+ regexp_.c:regexp.h \
11271146
report_.c:report.h \
11281147
rss_.c:rss.h \
11291148
schema_.c:schema.h \
11301149
search_.c:search.h \
11311150
setup_.c:setup.h \
@@ -1142,10 +1161,11 @@
11421161
th_main_.c:th_main.h \
11431162
timeline_.c:timeline.h \
11441163
tkt_.c:tkt.h \
11451164
tktsetup_.c:tktsetup.h \
11461165
undo_.c:undo.h \
1166
+ unicode_.c:unicode.h \
11471167
update_.c:update.h \
11481168
url_.c:url.h \
11491169
user_.c:user.h \
11501170
utf8_.c:utf8.h \
11511171
verify_.c:verify.h \
11521172
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -107,10 +107,11 @@
107 pivot_.c \
108 popen_.c \
109 pqueue_.c \
110 printf_.c \
111 rebuild_.c \
 
112 report_.c \
113 rss_.c \
114 schema_.c \
115 search_.c \
116 setup_.c \
@@ -127,10 +128,11 @@
127 th_main_.c \
128 timeline_.c \
129 tkt_.c \
130 tktsetup_.c \
131 undo_.c \
 
132 update_.c \
133 url_.c \
134 user_.c \
135 utf8_.c \
136 verify_.c \
@@ -210,10 +212,11 @@
210 $(OX)\pivot$O \
211 $(OX)\popen$O \
212 $(OX)\pqueue$O \
213 $(OX)\printf$O \
214 $(OX)\rebuild$O \
 
215 $(OX)\report$O \
216 $(OX)\rss$O \
217 $(OX)\schema$O \
218 $(OX)\search$O \
219 $(OX)\setup$O \
@@ -230,10 +233,11 @@
230 $(OX)\th_main$O \
231 $(OX)\timeline$O \
232 $(OX)\tkt$O \
233 $(OX)\tktsetup$O \
234 $(OX)\undo$O \
 
235 $(OX)\update$O \
236 $(OX)\url$O \
237 $(OX)\user$O \
238 $(OX)\utf8$O \
239 $(OX)\verify$O \
@@ -330,10 +334,11 @@
330 echo $(OX)\pivot.obj >> $@
331 echo $(OX)\popen.obj >> $@
332 echo $(OX)\pqueue.obj >> $@
333 echo $(OX)\printf.obj >> $@
334 echo $(OX)\rebuild.obj >> $@
 
335 echo $(OX)\report.obj >> $@
336 echo $(OX)\rss.obj >> $@
337 echo $(OX)\schema.obj >> $@
338 echo $(OX)\search.obj >> $@
339 echo $(OX)\setup.obj >> $@
@@ -354,10 +359,11 @@
354 echo $(OX)\th_main.obj >> $@
355 echo $(OX)\timeline.obj >> $@
356 echo $(OX)\tkt.obj >> $@
357 echo $(OX)\tktsetup.obj >> $@
358 echo $(OX)\undo.obj >> $@
 
359 echo $(OX)\update.obj >> $@
360 echo $(OX)\url.obj >> $@
361 echo $(OX)\user.obj >> $@
362 echo $(OX)\utf8.obj >> $@
363 echo $(OX)\verify.obj >> $@
@@ -853,10 +859,16 @@
853 $(OX)\rebuild$O : rebuild_.c rebuild.h
854 $(TCC) /Fo$@ -c rebuild_.c
855
856 rebuild_.c : $(SRCDIR)\rebuild.c
857 translate$E $** > $@
 
 
 
 
 
 
858
859 $(OX)\report$O : report_.c report.h
860 $(TCC) /Fo$@ -c report_.c
861
862 report_.c : $(SRCDIR)\report.c
@@ -973,10 +985,16 @@
973 $(OX)\undo$O : undo_.c undo.h
974 $(TCC) /Fo$@ -c undo_.c
975
976 undo_.c : $(SRCDIR)\undo.c
977 translate$E $** > $@
 
 
 
 
 
 
978
979 $(OX)\update$O : update_.c update.h
980 $(TCC) /Fo$@ -c update_.c
981
982 update_.c : $(SRCDIR)\update.c
@@ -1122,10 +1140,11 @@
1122 pivot_.c:pivot.h \
1123 popen_.c:popen.h \
1124 pqueue_.c:pqueue.h \
1125 printf_.c:printf.h \
1126 rebuild_.c:rebuild.h \
 
1127 report_.c:report.h \
1128 rss_.c:rss.h \
1129 schema_.c:schema.h \
1130 search_.c:search.h \
1131 setup_.c:setup.h \
@@ -1142,10 +1161,11 @@
1142 th_main_.c:th_main.h \
1143 timeline_.c:timeline.h \
1144 tkt_.c:tkt.h \
1145 tktsetup_.c:tktsetup.h \
1146 undo_.c:undo.h \
 
1147 update_.c:update.h \
1148 url_.c:url.h \
1149 user_.c:user.h \
1150 utf8_.c:utf8.h \
1151 verify_.c:verify.h \
1152
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -107,10 +107,11 @@
107 pivot_.c \
108 popen_.c \
109 pqueue_.c \
110 printf_.c \
111 rebuild_.c \
112 regexp_.c \
113 report_.c \
114 rss_.c \
115 schema_.c \
116 search_.c \
117 setup_.c \
@@ -127,10 +128,11 @@
128 th_main_.c \
129 timeline_.c \
130 tkt_.c \
131 tktsetup_.c \
132 undo_.c \
133 unicode_.c \
134 update_.c \
135 url_.c \
136 user_.c \
137 utf8_.c \
138 verify_.c \
@@ -210,10 +212,11 @@
212 $(OX)\pivot$O \
213 $(OX)\popen$O \
214 $(OX)\pqueue$O \
215 $(OX)\printf$O \
216 $(OX)\rebuild$O \
217 $(OX)\regexp$O \
218 $(OX)\report$O \
219 $(OX)\rss$O \
220 $(OX)\schema$O \
221 $(OX)\search$O \
222 $(OX)\setup$O \
@@ -230,10 +233,11 @@
233 $(OX)\th_main$O \
234 $(OX)\timeline$O \
235 $(OX)\tkt$O \
236 $(OX)\tktsetup$O \
237 $(OX)\undo$O \
238 $(OX)\unicode$O \
239 $(OX)\update$O \
240 $(OX)\url$O \
241 $(OX)\user$O \
242 $(OX)\utf8$O \
243 $(OX)\verify$O \
@@ -330,10 +334,11 @@
334 echo $(OX)\pivot.obj >> $@
335 echo $(OX)\popen.obj >> $@
336 echo $(OX)\pqueue.obj >> $@
337 echo $(OX)\printf.obj >> $@
338 echo $(OX)\rebuild.obj >> $@
339 echo $(OX)\regexp.obj >> $@
340 echo $(OX)\report.obj >> $@
341 echo $(OX)\rss.obj >> $@
342 echo $(OX)\schema.obj >> $@
343 echo $(OX)\search.obj >> $@
344 echo $(OX)\setup.obj >> $@
@@ -354,10 +359,11 @@
359 echo $(OX)\th_main.obj >> $@
360 echo $(OX)\timeline.obj >> $@
361 echo $(OX)\tkt.obj >> $@
362 echo $(OX)\tktsetup.obj >> $@
363 echo $(OX)\undo.obj >> $@
364 echo $(OX)\unicode.obj >> $@
365 echo $(OX)\update.obj >> $@
366 echo $(OX)\url.obj >> $@
367 echo $(OX)\user.obj >> $@
368 echo $(OX)\utf8.obj >> $@
369 echo $(OX)\verify.obj >> $@
@@ -853,10 +859,16 @@
859 $(OX)\rebuild$O : rebuild_.c rebuild.h
860 $(TCC) /Fo$@ -c rebuild_.c
861
862 rebuild_.c : $(SRCDIR)\rebuild.c
863 translate$E $** > $@
864
865 $(OX)\regexp$O : regexp_.c regexp.h
866 $(TCC) /Fo$@ -c regexp_.c
867
868 regexp_.c : $(SRCDIR)\regexp.c
869 translate$E $** > $@
870
871 $(OX)\report$O : report_.c report.h
872 $(TCC) /Fo$@ -c report_.c
873
874 report_.c : $(SRCDIR)\report.c
@@ -973,10 +985,16 @@
985 $(OX)\undo$O : undo_.c undo.h
986 $(TCC) /Fo$@ -c undo_.c
987
988 undo_.c : $(SRCDIR)\undo.c
989 translate$E $** > $@
990
991 $(OX)\unicode$O : unicode_.c unicode.h
992 $(TCC) /Fo$@ -c unicode_.c
993
994 unicode_.c : $(SRCDIR)\unicode.c
995 translate$E $** > $@
996
997 $(OX)\update$O : update_.c update.h
998 $(TCC) /Fo$@ -c update_.c
999
1000 update_.c : $(SRCDIR)\update.c
@@ -1122,10 +1140,11 @@
1140 pivot_.c:pivot.h \
1141 popen_.c:popen.h \
1142 pqueue_.c:pqueue.h \
1143 printf_.c:printf.h \
1144 rebuild_.c:rebuild.h \
1145 regexp_.c:regexp.h \
1146 report_.c:report.h \
1147 rss_.c:rss.h \
1148 schema_.c:schema.h \
1149 search_.c:search.h \
1150 setup_.c:setup.h \
@@ -1142,10 +1161,11 @@
1161 th_main_.c:th_main.h \
1162 timeline_.c:timeline.h \
1163 tkt_.c:tkt.h \
1164 tktsetup_.c:tktsetup.h \
1165 undo_.c:undo.h \
1166 unicode_.c:unicode.h \
1167 update_.c:update.h \
1168 url_.c:url.h \
1169 user_.c:user.h \
1170 utf8_.c:utf8.h \
1171 verify_.c:verify.h \
1172
--- win/fossil.rc
+++ win/fossil.rc
@@ -109,10 +109,13 @@
109109
#endif
110110
#endif
111111
#ifdef FOSSIL_ENABLE_JSON
112112
VALUE "JsonEnabled", "Yes, cson\0"
113113
#endif
114
+#ifdef FOSSIL_ENABLE_MARKDOWN
115
+ VALUE "MarkdownEnabled", "Yes\0"
116
+#endif
114117
END
115118
END
116119
BLOCK "VarFileInfo"
117120
BEGIN
118121
VALUE "Translation", 0x409, 0x4B0
119122
--- win/fossil.rc
+++ win/fossil.rc
@@ -109,10 +109,13 @@
109 #endif
110 #endif
111 #ifdef FOSSIL_ENABLE_JSON
112 VALUE "JsonEnabled", "Yes, cson\0"
113 #endif
 
 
 
114 END
115 END
116 BLOCK "VarFileInfo"
117 BEGIN
118 VALUE "Translation", 0x409, 0x4B0
119
--- win/fossil.rc
+++ win/fossil.rc
@@ -109,10 +109,13 @@
109 #endif
110 #endif
111 #ifdef FOSSIL_ENABLE_JSON
112 VALUE "JsonEnabled", "Yes, cson\0"
113 #endif
114 #ifdef FOSSIL_ENABLE_MARKDOWN
115 VALUE "MarkdownEnabled", "Yes\0"
116 #endif
117 END
118 END
119 BLOCK "VarFileInfo"
120 BEGIN
121 VALUE "Translation", 0x409, 0x4B0
122
--- win/fossil.rc
+++ win/fossil.rc
@@ -109,10 +109,13 @@
109109
#endif
110110
#endif
111111
#ifdef FOSSIL_ENABLE_JSON
112112
VALUE "JsonEnabled", "Yes, cson\0"
113113
#endif
114
+#ifdef FOSSIL_ENABLE_MARKDOWN
115
+ VALUE "MarkdownEnabled", "Yes\0"
116
+#endif
114117
END
115118
END
116119
BLOCK "VarFileInfo"
117120
BEGIN
118121
VALUE "Translation", 0x409, 0x4B0
119122
--- win/fossil.rc
+++ win/fossil.rc
@@ -109,10 +109,13 @@
109 #endif
110 #endif
111 #ifdef FOSSIL_ENABLE_JSON
112 VALUE "JsonEnabled", "Yes, cson\0"
113 #endif
 
 
 
114 END
115 END
116 BLOCK "VarFileInfo"
117 BEGIN
118 VALUE "Translation", 0x409, 0x4B0
119
--- win/fossil.rc
+++ win/fossil.rc
@@ -109,10 +109,13 @@
109 #endif
110 #endif
111 #ifdef FOSSIL_ENABLE_JSON
112 VALUE "JsonEnabled", "Yes, cson\0"
113 #endif
114 #ifdef FOSSIL_ENABLE_MARKDOWN
115 VALUE "MarkdownEnabled", "Yes\0"
116 #endif
117 END
118 END
119 BLOCK "VarFileInfo"
120 BEGIN
121 VALUE "Translation", 0x409, 0x4B0
122
+398 -204
--- win/include/dirent.h
+++ win/include/dirent.h
@@ -20,21 +20,24 @@
2020
* IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
2121
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2222
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2323
* OTHER DEALINGS IN THE SOFTWARE.
2424
*
25
+ *
26
+ * Version 1.13, Dec 12 2012, Toni Ronkko
27
+ * Use traditional 8+3 file name if the name cannot be represented in the
28
+ * default ANSI code page. Now compiles again with MSVC 6.0. Thanks to
29
+ * Konstantin Khomoutov for testing.
2530
*
2631
* Version 1.12.1, Oct 1 2012, Toni Ronkko
2732
* Bug fix: renamed wide-character DIR structure _wDIR to _WDIR (with
2833
* capital W) in order to maintain compatibility with MingW.
2934
*
3035
* Version 1.12, Sep 30 2012, Toni Ronkko
31
- * Define PATH_MAX and NAME_MAX.
32
- *
33
- * Added wide-character variants _wDIR, _wdirent, _wopendir(),
34
- * _wreaddir(), _wclosedir() and _wrewinddir(). Thanks to Edgar Buerkle
35
- * and Jan Nijtmans for ideas and code.
36
+ * Define PATH_MAX and NAME_MAX. Added wide-character variants _wDIR,
37
+ * _wdirent, _wopendir(), _wreaddir(), _wclosedir() and _wrewinddir().
38
+ * Thanks to Edgar Buerkle and Jan Nijtmans for ideas and code.
3639
*
3740
* Do not include windows.h. This allows dirent.h to be integrated more
3841
* easily into programs using winsock. Thanks to Fernando Azaldegui.
3942
*
4043
* Version 1.11, Mar 15, 2011, Toni Ronkko
@@ -88,48 +91,72 @@
8891
*****************************************************************************/
8992
#ifndef DIRENT_H
9093
#define DIRENT_H
9194
9295
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
93
-#define _X86_
96
+# define _X86_
9497
#endif
9598
#include <stdio.h>
9699
#include <stdarg.h>
97100
#include <windef.h>
98101
#include <winbase.h>
99102
#include <wchar.h>
100
-#include <winnls.h>
101103
#include <string.h>
102104
#include <stdlib.h>
105
+#include <malloc.h>
103106
#include <sys/types.h>
104107
#include <sys/stat.h>
105108
#include <errno.h>
106109
107
-/* Windows 8 wide-character string functions */
108
-#if (_WIN32_WINNT >= 0x0602)
109
-# include <stringapiset.h>
110
-#endif
110
+/* Indicates that d_type field is available in dirent structure */
111
+#define _DIRENT_HAVE_D_TYPE
112
+
113
+/* Indicates that d_namlen field is available in dirent structure */
114
+#define _DIRENT_HAVE_D_NAMLEN
111115
112116
/* Entries missing from MSVC 6.0 */
113117
#if !defined(FILE_ATTRIBUTE_DEVICE)
114
-# define FILE_ATTRIBUTE_DEVICE 0x40
118
+# define FILE_ATTRIBUTE_DEVICE 0x40
115119
#endif
116120
117121
/* File type and permission flags for stat() */
118
-#if defined(_MSC_VER) && !defined(S_IREAD)
122
+#if !defined(S_IFMT)
119123
# define S_IFMT _S_IFMT /* File type mask */
124
+#endif
125
+#if !defined(S_IFDIR)
120126
# define S_IFDIR _S_IFDIR /* Directory */
127
+#endif
128
+#if !defined(S_IFCHR)
121129
# define S_IFCHR _S_IFCHR /* Character device */
130
+#endif
131
+#if !defined(S_IFFIFO)
122132
# define S_IFFIFO _S_IFFIFO /* Pipe */
133
+#endif
134
+#if !defined(S_IFREG)
123135
# define S_IFREG _S_IFREG /* Regular file */
136
+#endif
137
+#if !defined(S_IREAD)
124138
# define S_IREAD _S_IREAD /* Read permission */
139
+#endif
140
+#if !defined(S_IWRITE)
125141
# define S_IWRITE _S_IWRITE /* Write permission */
142
+#endif
143
+#if !defined(S_IEXEC)
126144
# define S_IEXEC _S_IEXEC /* Execute permission */
127145
#endif
128
-#define S_IFBLK 0 /* Block device */
129
-#define S_IFLNK 0 /* Link */
130
-#define S_IFSOCK 0 /* Socket */
146
+#if !defined(S_IFIFO)
147
+# define S_IFIFO _S_IFIFO /* Pipe */
148
+#endif
149
+#if !defined(S_IFBLK)
150
+# define S_IFBLK 0 /* Block device */
151
+#endif
152
+#if !defined(S_IFLNK)
153
+# define S_IFLNK 0 /* Link */
154
+#endif
155
+#if !defined(S_IFSOCK)
156
+# define S_IFSOCK 0 /* Socket */
157
+#endif
131158
132159
#if defined(_MSC_VER)
133160
# define S_IRUSR S_IREAD /* Read user */
134161
# define S_IWUSR S_IWRITE /* Write user */
135162
# define S_IXUSR 0 /* Execute user */
@@ -139,18 +166,26 @@
139166
# define S_IROTH 0 /* Read others */
140167
# define S_IWOTH 0 /* Write others */
141168
# define S_IXOTH 0 /* Execute others */
142169
#endif
143170
144
-/* Indicates that d_type field is available in dirent structure */
145
-#define _DIRENT_HAVE_D_TYPE
171
+/* Maximum length of file name */
172
+#if !defined(PATH_MAX)
173
+# define PATH_MAX MAX_PATH
174
+#endif
175
+#if !defined(FILENAME_MAX)
176
+# define FILENAME_MAX MAX_PATH
177
+#endif
178
+#if !defined(NAME_MAX)
179
+# define NAME_MAX FILENAME_MAX
180
+#endif
146181
147182
/* File type flags for d_type */
148183
#define DT_UNKNOWN 0
149184
#define DT_REG S_IFREG
150185
#define DT_DIR S_IFDIR
151
-#define DT_FIFO S_IFFIFO
186
+#define DT_FIFO S_IFIFO
152187
#define DT_SOCK S_IFSOCK
153188
#define DT_CHR S_IFCHR
154189
#define DT_BLK S_IFBLK
155190
156191
/* Macros for converting between st_mode and d_type */
@@ -161,41 +196,31 @@
161196
* File type macros. Note that block devices, sockets and links cannot be
162197
* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
163198
* only defined for compatibility. These macros should always return false
164199
* on Windows.
165200
*/
166
-#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)
201
+#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
167202
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
168203
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
169204
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
170205
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
171206
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
172207
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
173208
174
-/* For compatiblity with Unix */
175
-#if !defined(PATH_MAX)
176
-# define PATH_MAX MAX_PATH
177
-#endif
178
-#if !defined(FILENAME_MAX)
179
-# define FILENAME_MAX MAX_PATH
180
-#endif
181
-#if !defined(NAME_MAX)
182
-# define NAME_MAX FILENAME_MAX
183
-#endif
184
-
185
-/* Set errno variable */
186
-#if defined(_MSC_VER)
187
-#define DIRENT_SET_ERRNO(x) _set_errno (x)
188
-#else
189
-#define DIRENT_SET_ERRNO(x) (errno = (x))
190
-#endif
209
+/* Return the exact length of d_namlen without zero terminator */
210
+#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
211
+
212
+/* Return number of bytes needed to store d_namlen */
213
+#define _D_ALLOC_NAMLEN(p) (PATH_MAX + 1)
214
+
191215
192216
#ifdef __cplusplus
193217
extern "C" {
194218
#endif
195219
196
-/* Wide-character versions */
220
+
221
+/* Wide-character version */
197222
struct _wdirent {
198223
long d_ino; /* Always zero */
199224
unsigned short d_reclen; /* Structure size */
200225
size_t d_namlen; /* Length of name without \0 */
201226
int d_type; /* File type */
@@ -203,11 +228,11 @@
203228
};
204229
typedef struct _wdirent _wdirent;
205230
206231
struct _WDIR {
207232
struct _wdirent ent; /* Current directory entry */
208
- WIN32_FIND_DATAW find_data; /* Private file data */
233
+ WIN32_FIND_DATAW data; /* Private file data */
209234
int cached; /* True if data is valid */
210235
HANDLE handle; /* Win32 search handle */
211236
wchar_t *patt; /* Initial directory name */
212237
};
213238
typedef struct _WDIR _WDIR;
@@ -214,10 +239,11 @@
214239
215240
static _WDIR *_wopendir (const wchar_t *dirname);
216241
static struct _wdirent *_wreaddir (_WDIR *dirp);
217242
static int _wclosedir (_WDIR *dirp);
218243
static void _wrewinddir (_WDIR* dirp);
244
+
219245
220246
/* For compatibility with Symbian */
221247
#define wdirent _wdirent
222248
#define WDIR _WDIR
223249
#define wopendir _wopendir
@@ -246,10 +272,30 @@
246272
static struct dirent *readdir (DIR *dirp);
247273
static int closedir (DIR *dirp);
248274
static void rewinddir (DIR* dirp);
249275
250276
277
+/* Internal utility functions */
278
+static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
279
+static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
280
+
281
+static int dirent_mbstowcs_s(
282
+ size_t *pReturnValue,
283
+ wchar_t *wcstr,
284
+ size_t sizeInWords,
285
+ const char *mbstr,
286
+ size_t count);
287
+
288
+static int dirent_wcstombs_s(
289
+ size_t *pReturnValue,
290
+ char *mbstr,
291
+ size_t sizeInBytes,
292
+ const wchar_t *wcstr,
293
+ size_t count);
294
+
295
+static void dirent_set_errno (int error);
296
+
251297
/*
252298
* Open directory stream DIRNAME for read and return a pointer to the
253299
* internal working area that is used to retrieve individual directory
254300
* entries.
255301
*/
@@ -256,31 +302,38 @@
256302
static _WDIR*
257303
_wopendir(
258304
const wchar_t *dirname)
259305
{
260306
_WDIR *dirp = NULL;
261
- int error = 0;
307
+ int error;
308
+
309
+ /* Must have directory name */
310
+ if (dirname == NULL || dirname[0] == '\0') {
311
+ dirent_set_errno (ENOENT);
312
+ return NULL;
313
+ }
262314
263315
/* Allocate new _WDIR structure */
264316
dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
265317
if (dirp != NULL) {
266318
DWORD n;
267319
268320
/* Reset _WDIR structure */
269321
dirp->handle = INVALID_HANDLE_VALUE;
270322
dirp->patt = NULL;
323
+ dirp->cached = 0;
271324
272325
/* Compute the length of full path plus zero terminator */
273326
n = GetFullPathNameW (dirname, 0, NULL, NULL);
274327
275
- /* Allocate room for full path and search patterns */
328
+ /* Allocate room for absolute directory name and search pattern */
276329
dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
277330
if (dirp->patt) {
278331
279332
/*
280333
* Convert relative directory name to an absolute one. This
281
- * allows rewinddir() to function correctly when the current
334
+ * allows rewinddir() to function correctly even when current
282335
* working directory is changed between opendir() and rewinddir().
283336
*/
284337
n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
285338
if (n > 0) {
286339
wchar_t *p;
@@ -303,25 +356,22 @@
303356
}
304357
*p++ = '*';
305358
*p = '\0';
306359
307360
/* Open directory stream and retrieve the first entry */
308
- dirp->handle = FindFirstFileW (dirp->patt, &dirp->find_data);
309
- if (dirp->handle != INVALID_HANDLE_VALUE) {
310
-
311
- /* Directory entry is now waiting in memory */
312
- dirp->cached = 1;
313
-
361
+ if (dirent_first (dirp)) {
362
+ /* Directory stream opened successfully */
363
+ error = 0;
314364
} else {
315
- /* Search pattern is not a directory name? */
316
- DIRENT_SET_ERRNO (ENOENT);
365
+ /* Cannot retrieve first entry */
317366
error = 1;
367
+ dirent_set_errno (ENOENT);
318368
}
319369
320370
} else {
321
- /* Cannot convert directory name to wide character string */
322
- DIRENT_SET_ERRNO (ENOENT);
371
+ /* Cannot retrieve full path name */
372
+ dirent_set_errno (ENOENT);
323373
error = 1;
324374
}
325375
326376
} else {
327377
/* Cannot allocate memory for search pattern */
@@ -350,70 +400,59 @@
350400
*/
351401
static struct _wdirent*
352402
_wreaddir(
353403
_WDIR *dirp)
354404
{
355
- DWORD attr;
356
- errno_t error;
357
-
358
- /* Get next directory entry */
359
- if (dirp->cached != 0) {
360
- /* A valid directory entry already in memory */
361
- dirp->cached = 0;
362
- } else {
363
- /* Get the next directory entry from stream */
364
- if (dirp->handle == INVALID_HANDLE_VALUE) {
365
- return NULL;
366
- }
367
- if (FindNextFileW (dirp->handle, &dirp->find_data) == FALSE) {
368
- /* The very last entry has been processed or an error occured */
369
- FindClose (dirp->handle);
370
- dirp->handle = INVALID_HANDLE_VALUE;
371
- return NULL;
372
- }
373
- }
374
-
375
- /* Copy file name as a wide-character string */
376
- error = wcsncpy_s(
377
- dirp->ent.d_name, /* Destination string */
378
- PATH_MAX, /* Size of dest in words */
379
- dirp->find_data.cFileName, /* Source string */
380
- PATH_MAX + 1); /* Max # of chars to copy */
381
- if (!error) {
382
-
383
- /* Compute the length of name */
384
- dirp->ent.d_namlen = wcsnlen (dirp->ent.d_name, PATH_MAX);
385
-
386
- /* Determine file type */
387
- attr = dirp->find_data.dwFileAttributes;
405
+ WIN32_FIND_DATAW *datap;
406
+ struct _wdirent *entp;
407
+
408
+ /* Read next directory entry */
409
+ datap = dirent_next (dirp);
410
+ if (datap) {
411
+ size_t n;
412
+ DWORD attr;
413
+
414
+ /* Pointer to directory entry to return */
415
+ entp = &dirp->ent;
416
+
417
+ /*
418
+ * Copy file name as wide-character string. If the file name is too
419
+ * long to fit in to the destination buffer, then truncate file name
420
+ * to PATH_MAX characters and zero-terminate the buffer.
421
+ */
422
+ n = 0;
423
+ while (n < PATH_MAX && datap->cFileName[n] != 0) {
424
+ entp->d_name[n] = datap->cFileName[n];
425
+ n++;
426
+ }
427
+ dirp->ent.d_name[n] = 0;
428
+
429
+ /* Length of file name excluding zero terminator */
430
+ entp->d_namlen = n;
431
+
432
+ /* File type */
433
+ attr = datap->dwFileAttributes;
388434
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
389
- dirp->ent.d_type = DT_CHR;
435
+ entp->d_type = DT_CHR;
390436
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
391
- dirp->ent.d_type = DT_DIR;
437
+ entp->d_type = DT_DIR;
392438
} else {
393
- dirp->ent.d_type = DT_REG;
439
+ entp->d_type = DT_REG;
394440
}
395441
396442
/* Reset dummy fields */
397
- dirp->ent.d_ino = 0;
398
- dirp->ent.d_reclen = sizeof (dirp->ent);
443
+ entp->d_ino = 0;
444
+ entp->d_reclen = sizeof (struct _wdirent);
399445
400446
} else {
401447
402
- /*
403
- * Cannot copy file name from find_data to ent. Construct a
404
- * dummy _wdirent structure to pass error to caller.
405
- */
406
- dirp->ent.d_name[0] = '?';
407
- dirp->ent.d_name[1] = '\0';
408
- dirp->ent.d_namlen = 1;
409
- dirp->ent.d_type = DT_UNKNOWN;
410
- dirp->ent.d_ino = 0;
411
- dirp->ent.d_reclen = 0;
448
+ /* Last directory entry read */
449
+ entp = NULL;
450
+
412451
}
413452
414
- return &dirp->ent;
453
+ return entp;
415454
}
416455
417456
/*
418457
* Close directory stream opened by opendir() function. This invalidates the
419458
* DIR structure as well as any directory entry read previously by
@@ -442,11 +481,11 @@
442481
free (dirp);
443482
ok = /*success*/0;
444483
445484
} else {
446485
/* Invalid directory stream */
447
- DIRENT_SET_ERRNO (EBADF);
486
+ dirent_set_errno (EBADF);
448487
ok = /*failure*/-1;
449488
}
450489
return ok;
451490
}
452491
@@ -456,26 +495,81 @@
456495
*/
457496
static void
458497
_wrewinddir(
459498
_WDIR* dirp)
460499
{
461
- if (dirp != NULL) {
462
- /* release search handle */
500
+ if (dirp) {
501
+ /* Release existing search handle */
463502
if (dirp->handle != INVALID_HANDLE_VALUE) {
464503
FindClose (dirp->handle);
465504
}
466505
467
- /* Open new search handle and retrieve the first directory entry */
468
- dirp->handle = FindFirstFileW (dirp->patt, &dirp->find_data);
469
- if (dirp->handle != INVALID_HANDLE_VALUE) {
470
- /* a directory entry is now waiting in memory */
471
- dirp->cached = 1;
506
+ /* Open new search handle */
507
+ dirent_first (dirp);
508
+ }
509
+}
510
+
511
+/* Get first directory entry (internal) */
512
+static WIN32_FIND_DATAW*
513
+dirent_first(
514
+ _WDIR *dirp)
515
+{
516
+ WIN32_FIND_DATAW *datap;
517
+
518
+ /* Open directory and retrieve the first entry */
519
+ dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
520
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
521
+
522
+ /* a directory entry is now waiting in memory */
523
+ datap = &dirp->data;
524
+ dirp->cached = 1;
525
+
526
+ } else {
527
+
528
+ /* Failed to re-open directory: no directory entry in memory */
529
+ dirp->cached = 0;
530
+ datap = NULL;
531
+
532
+ }
533
+ return datap;
534
+}
535
+
536
+/* Get next directory entry (internal) */
537
+static WIN32_FIND_DATAW*
538
+dirent_next(
539
+ _WDIR *dirp)
540
+{
541
+ WIN32_FIND_DATAW *p;
542
+
543
+ /* Get next directory entry */
544
+ if (dirp->cached != 0) {
545
+
546
+ /* A valid directory entry already in memory */
547
+ p = &dirp->data;
548
+ dirp->cached = 0;
549
+
550
+ } else if (dirp->handle != INVALID_HANDLE_VALUE) {
551
+
552
+ /* Get the next directory entry from stream */
553
+ if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
554
+ /* Got a file */
555
+ p = &dirp->data;
472556
} else {
473
- /* Failed to re-open directory: no directory entry in memory */
474
- dirp->cached = 0;
557
+ /* The very last entry has been processed or an error occured */
558
+ FindClose (dirp->handle);
559
+ dirp->handle = INVALID_HANDLE_VALUE;
560
+ p = NULL;
475561
}
562
+
563
+ } else {
564
+
565
+ /* End of directory stream reached */
566
+ p = NULL;
567
+
476568
}
569
+
570
+ return p;
477571
}
478572
479573
/*
480574
* Open directory stream using plain old C-string.
481575
*/
@@ -482,58 +576,34 @@
482576
static DIR*
483577
opendir(
484578
const char *dirname)
485579
{
486580
struct DIR *dirp;
487
- errno_t error = 0;
581
+ int error;
488582
489583
/* Must have directory name */
490
- if (dirname == NULL) {
491
- DIRENT_SET_ERRNO (ENOENT);
584
+ if (dirname == NULL || dirname[0] == '\0') {
585
+ dirent_set_errno (ENOENT);
492586
return NULL;
493587
}
494588
495
- /* Allocate memory for multi-byte string directory structures */
589
+ /* Allocate memory for DIR structure */
496590
dirp = (DIR*) malloc (sizeof (struct DIR));
497591
if (dirp) {
498592
wchar_t wname[PATH_MAX + 1];
499593
size_t n;
500594
501
- /*
502
- * Convert directory name to wide-character string.
503
- *
504
- * Be ware of the return schemantics of MultiByteToWideChar() --
505
- * the function basically returns the number of characters written to
506
- * output buffer or zero if the conversion fails. However, the
507
- * function does not necessarily zero-terminate the output
508
- * buffer and may return 0xFFFD if the string contains invalid
509
- * characters!
510
- */
511
- n = MultiByteToWideChar(
512
- CP_ACP, /* Input code page */
513
- MB_PRECOMPOSED, /* Conversion flags */
514
- dirname, /* Input string */
515
- -1, /* Length of input string */
516
- wname, /* Output buffer */
517
- PATH_MAX); /* Size of output buffer */
518
- if (n > 0 && n < PATH_MAX) {
519
-
520
- /* Zero-terminate output buffer */
521
- wname[n] = '\0';
522
-
523
- /* Open directory stream with wide-character string file name */
595
+ /* Convert directory name to wide-character string */
596
+ error = dirent_mbstowcs_s(
597
+ &n, wname, PATH_MAX + 1, dirname, PATH_MAX);
598
+ if (!error) {
599
+
600
+ /* Open directory stream using wide-character name */
524601
dirp->wdirp = _wopendir (wname);
525602
if (dirp->wdirp) {
526
-
527
- /* Initialize directory structure */
528
- dirp->ent.d_name[0] = '\0';
529
- dirp->ent.d_namlen = 0;
530
- dirp->ent.d_type = 0;
531
- dirp->ent.d_ino = 0;
532
- dirp->ent.d_reclen = 0;
533
-
534
-
603
+ /* Directory stream opened */
604
+ error = 0;
535605
} else {
536606
/* Failed to open directory stream */
537607
error = 1;
538608
}
539609
@@ -562,95 +632,99 @@
562632
}
563633
564634
/*
565635
* Read next directory entry.
566636
*
567
- * When working with console, please note that file names returned by
568
- * readdir() are represented in the default ANSI code page while the
569
- * console typically runs on another code page. Thus, non-ASCII characters
570
- * will not usually display correctly. The problem can be fixed in two ways:
571
- * (1) change the character set of console to 1252 using chcp utility and use
572
- * Lucida Console font, or (2) always use _cprintf function when writing to
573
- * console. The _cprinf() will re-encode ANSI strings to the console code
574
- * page so non-ASCII characters will display correcly.
637
+ * When working with text consoles, please note that file names returned by
638
+ * readdir() are represented in the default ANSI code page while any output to
639
+ * console is typically formatted on another code page. Thus, non-ASCII
640
+ * characters in file names will not usually display correctly on console. The
641
+ * problem can be fixed in two ways: (1) change the character set of console
642
+ * to 1252 using chcp utility and use Lucida Console font, or (2) use
643
+ * _cprintf function when writing to console. The _cprinf() will re-encode
644
+ * ANSI strings to the console code page so many non-ASCII characters will
645
+ * display correcly.
575646
*/
576647
static struct dirent*
577648
readdir(
578649
DIR *dirp)
579650
{
580
- struct dirent *p;
581
- struct _wdirent *wp;
651
+ WIN32_FIND_DATAW *datap;
652
+ struct dirent *entp;
582653
583
- /* Read next directory entry using wide-character string functions */
584
- wp = _wreaddir (dirp->wdirp);
585
- if (wp) {
654
+ /* Read next directory entry */
655
+ datap = dirent_next (dirp->wdirp);
656
+ if (datap) {
586657
size_t n;
658
+ int error;
659
+
660
+ /* Attempt to convert file name to multi-byte string */
661
+ error = dirent_wcstombs_s(
662
+ &n, dirp->ent.d_name, MAX_PATH + 1, datap->cFileName, MAX_PATH);
587663
588664
/*
589
- * Convert file name to multi-byte string.
590
- *
591
- * Be ware of the return schemantics of WideCharToMultiByte() --
592
- * the function basically returns the number of bytes
593
- * written to output buffer or zero if the conversion fails.
594
- * However, the function does not necessarily zero-terminate the
595
- * buffer and it may even return 0xFFFD the string contains
596
- * invalid characters!
665
+ * If the file name cannot be represented by a multi-byte string,
666
+ * then attempt to use old 8+3 file name. This allows traditional
667
+ * Unix-code to access some file names despite of unicode
668
+ * characters, although file names may seem unfamiliar to the user.
669
+ *
670
+ * Be ware that the code below cannot come up with a short file
671
+ * name unless the file system provides one. At least
672
+ * VirtualBox shared folders fail to do this.
597673
*/
598
- n = WideCharToMultiByte(
599
- CP_ACP, /* Output code page */
600
- 0, /* Conversion flags */
601
- wp->d_name, /* Input string */
602
- wp->d_namlen, /* Length of input string */
603
- dirp->ent.d_name, /* Output buffer */
604
- PATH_MAX, /* Size of output buffer */
605
- NULL, /* Replacement character */
606
- NULL); /* If chars were replaced */
607
- if (n > 0 && n < PATH_MAX) {
608
-
609
- /* Zero-terminate buffer */
610
- dirp->ent.d_name[n] = '\0';
674
+ if (error && datap->cAlternateFileName[0] != '\0') {
675
+ error = dirent_wcstombs_s(
676
+ &n, dirp->ent.d_name, MAX_PATH + 1, datap->cAlternateFileName,
677
+ sizeof (datap->cAlternateFileName) /
678
+ sizeof (datap->cAlternateFileName[0]));
679
+ }
680
+
681
+ if (!error) {
682
+ DWORD attr;
611683
612684
/* Initialize directory entry for return */
613
- p = &dirp->ent;
685
+ entp = &dirp->ent;
614686
615
- /* Compute length */
616
- p->d_namlen = strnlen (dirp->ent.d_name, PATH_MAX);
687
+ /* Length of file name excluding zero terminator */
688
+ entp->d_namlen = n - 1;
617689
618
- /* Copy file attributes */
619
- p->d_type = wp->d_type;
690
+ /* File attributes */
691
+ attr = datap->dwFileAttributes;
692
+ if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
693
+ entp->d_type = DT_CHR;
694
+ } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
695
+ entp->d_type = DT_DIR;
696
+ } else {
697
+ entp->d_type = DT_REG;
698
+ }
620699
621700
/* Reset dummy fields */
622
- p->d_ino = 0;
623
- p->d_reclen = sizeof (dirp->ent);
624
-
701
+ entp->d_ino = 0;
702
+ entp->d_reclen = sizeof (struct dirent);
625703
626704
} else {
627
-
628705
/*
629706
* Cannot convert file name to multi-byte string so construct
630707
* an errornous directory entry and return that. Note that
631708
* we cannot return NULL as that would stop the processing
632709
* of directory entries completely.
633710
*/
634
- p = &dirp->ent;
635
- p->d_name[0] = '?';
636
- p->d_name[1] = '\0';
637
- p->d_namlen = 1;
638
- p->d_type = DT_UNKNOWN;
639
- p->d_ino = 0;
640
- p->d_reclen = 0;
641
-
711
+ entp = &dirp->ent;
712
+ entp->d_name[0] = '?';
713
+ entp->d_name[1] = '\0';
714
+ entp->d_namlen = 1;
715
+ entp->d_type = DT_UNKNOWN;
716
+ entp->d_ino = 0;
717
+ entp->d_reclen = 0;
642718
}
643719
644720
} else {
645
-
646
- /* End of directory stream */
647
- p = NULL;
648
-
721
+ /* No more directory entries */
722
+ entp = NULL;
649723
}
650724
651
- return p;
725
+ return entp;
652726
}
653727
654728
/*
655729
* Close directory stream.
656730
*/
@@ -667,13 +741,15 @@
667741
668742
/* Release multi-byte character version */
669743
free (dirp);
670744
671745
} else {
746
+
672747
/* Invalid directory stream */
673
- DIRENT_SET_ERRNO (EBADF);
748
+ dirent_set_errno (EBADF);
674749
ok = /*failure*/-1;
750
+
675751
}
676752
return ok;
677753
}
678754
679755
/*
@@ -684,12 +760,130 @@
684760
DIR* dirp)
685761
{
686762
/* Rewind wide-character string directory stream */
687763
_wrewinddir (dirp->wdirp);
688764
}
765
+
766
+/* Convert multi-byte string to wide character string */
767
+static int
768
+dirent_mbstowcs_s(
769
+ size_t *pReturnValue,
770
+ wchar_t *wcstr,
771
+ size_t sizeInWords,
772
+ const char *mbstr,
773
+ size_t count)
774
+{
775
+ int error;
776
+
777
+#if defined(_MSC_VER) && _MSC_VER >= 1400
778
+
779
+ /* Microsoft Visual Studio 2005 or later */
780
+ error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
781
+
782
+#else
783
+
784
+ /* Older Visual Studio or non-Microsoft compiler */
785
+ size_t n;
786
+
787
+ /* Convert to wide-character string */
788
+ n = mbstowcs (wcstr, mbstr, count);
789
+ if (n < sizeInWords) {
790
+
791
+ /* Zero-terminate output buffer */
792
+ if (wcstr) {
793
+ wcstr[n] = 0;
794
+ }
795
+
796
+ /* Length of resuting multi-byte string WITH zero terminator */
797
+ if (pReturnValue) {
798
+ *pReturnValue = n + 1;
799
+ }
800
+
801
+ /* Success */
802
+ error = 0;
803
+
804
+ } else {
805
+
806
+ /* Could not convert string */
807
+ error = 1;
808
+
809
+ }
810
+
811
+#endif
812
+
813
+ return error;
814
+}
815
+
816
+/* Convert wide-character string to multi-byte string */
817
+static int
818
+dirent_wcstombs_s(
819
+ size_t *pReturnValue,
820
+ char *mbstr,
821
+ size_t sizeInBytes,
822
+ const wchar_t *wcstr,
823
+ size_t count)
824
+{
825
+ int error;
826
+
827
+#if defined(_MSC_VER) && _MSC_VER >= 1400
828
+
829
+ /* Microsoft Visual Studio 2005 or later */
830
+ error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
831
+
832
+#else
833
+
834
+ /* Older Visual Studio or non-Microsoft compiler */
835
+ size_t n;
836
+
837
+ /* Convert to multi-byte string */
838
+ n = wcstombs (mbstr, wcstr, count);
839
+ if (n < sizeInBytes) {
840
+
841
+ /* Zero-terminate output buffer */
842
+ if (mbstr) {
843
+ mbstr[n] = '\0';
844
+ }
845
+
846
+ /* Lenght of resulting multi-bytes string WITH zero-terminator */
847
+ if (pReturnValue) {
848
+ *pReturnValue = n + 1;
849
+ }
850
+
851
+ /* Success */
852
+ error = 0;
853
+
854
+ } else {
855
+
856
+ /* Cannot convert string */
857
+ error = 1;
858
+
859
+ }
860
+
861
+#endif
862
+
863
+ return error;
864
+}
865
+
866
+/* Set errno variable */
867
+static void
868
+dirent_set_errno(
869
+ int error)
870
+{
871
+#if defined(_MSC_VER)
872
+
873
+ /* Microsoft Visual Studio */
874
+ _set_errno (error);
875
+
876
+#else
877
+
878
+ /* Non-Microsoft compiler */
879
+ errno = error;
880
+
881
+#endif
882
+}
689883
690884
691885
#ifdef __cplusplus
692886
}
693887
#endif
694888
#endif /*DIRENT_H*/
695889
696890
--- win/include/dirent.h
+++ win/include/dirent.h
@@ -20,21 +20,24 @@
20 * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 *
 
 
 
 
 
25 *
26 * Version 1.12.1, Oct 1 2012, Toni Ronkko
27 * Bug fix: renamed wide-character DIR structure _wDIR to _WDIR (with
28 * capital W) in order to maintain compatibility with MingW.
29 *
30 * Version 1.12, Sep 30 2012, Toni Ronkko
31 * Define PATH_MAX and NAME_MAX.
32 *
33 * Added wide-character variants _wDIR, _wdirent, _wopendir(),
34 * _wreaddir(), _wclosedir() and _wrewinddir(). Thanks to Edgar Buerkle
35 * and Jan Nijtmans for ideas and code.
36 *
37 * Do not include windows.h. This allows dirent.h to be integrated more
38 * easily into programs using winsock. Thanks to Fernando Azaldegui.
39 *
40 * Version 1.11, Mar 15, 2011, Toni Ronkko
@@ -88,48 +91,72 @@
88 *****************************************************************************/
89 #ifndef DIRENT_H
90 #define DIRENT_H
91
92 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
93 #define _X86_
94 #endif
95 #include <stdio.h>
96 #include <stdarg.h>
97 #include <windef.h>
98 #include <winbase.h>
99 #include <wchar.h>
100 #include <winnls.h>
101 #include <string.h>
102 #include <stdlib.h>
 
103 #include <sys/types.h>
104 #include <sys/stat.h>
105 #include <errno.h>
106
107 /* Windows 8 wide-character string functions */
108 #if (_WIN32_WINNT >= 0x0602)
109 # include <stringapiset.h>
110 #endif
 
111
112 /* Entries missing from MSVC 6.0 */
113 #if !defined(FILE_ATTRIBUTE_DEVICE)
114 # define FILE_ATTRIBUTE_DEVICE 0x40
115 #endif
116
117 /* File type and permission flags for stat() */
118 #if defined(_MSC_VER) && !defined(S_IREAD)
119 # define S_IFMT _S_IFMT /* File type mask */
 
 
120 # define S_IFDIR _S_IFDIR /* Directory */
 
 
121 # define S_IFCHR _S_IFCHR /* Character device */
 
 
122 # define S_IFFIFO _S_IFFIFO /* Pipe */
 
 
123 # define S_IFREG _S_IFREG /* Regular file */
 
 
124 # define S_IREAD _S_IREAD /* Read permission */
 
 
125 # define S_IWRITE _S_IWRITE /* Write permission */
 
 
126 # define S_IEXEC _S_IEXEC /* Execute permission */
127 #endif
128 #define S_IFBLK 0 /* Block device */
129 #define S_IFLNK 0 /* Link */
130 #define S_IFSOCK 0 /* Socket */
 
 
 
 
 
 
 
 
 
131
132 #if defined(_MSC_VER)
133 # define S_IRUSR S_IREAD /* Read user */
134 # define S_IWUSR S_IWRITE /* Write user */
135 # define S_IXUSR 0 /* Execute user */
@@ -139,18 +166,26 @@
139 # define S_IROTH 0 /* Read others */
140 # define S_IWOTH 0 /* Write others */
141 # define S_IXOTH 0 /* Execute others */
142 #endif
143
144 /* Indicates that d_type field is available in dirent structure */
145 #define _DIRENT_HAVE_D_TYPE
 
 
 
 
 
 
 
 
146
147 /* File type flags for d_type */
148 #define DT_UNKNOWN 0
149 #define DT_REG S_IFREG
150 #define DT_DIR S_IFDIR
151 #define DT_FIFO S_IFFIFO
152 #define DT_SOCK S_IFSOCK
153 #define DT_CHR S_IFCHR
154 #define DT_BLK S_IFBLK
155
156 /* Macros for converting between st_mode and d_type */
@@ -161,41 +196,31 @@
161 * File type macros. Note that block devices, sockets and links cannot be
162 * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
163 * only defined for compatibility. These macros should always return false
164 * on Windows.
165 */
166 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)
167 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
168 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
169 #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
170 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
171 #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
172 #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
173
174 /* For compatiblity with Unix */
175 #if !defined(PATH_MAX)
176 # define PATH_MAX MAX_PATH
177 #endif
178 #if !defined(FILENAME_MAX)
179 # define FILENAME_MAX MAX_PATH
180 #endif
181 #if !defined(NAME_MAX)
182 # define NAME_MAX FILENAME_MAX
183 #endif
184
185 /* Set errno variable */
186 #if defined(_MSC_VER)
187 #define DIRENT_SET_ERRNO(x) _set_errno (x)
188 #else
189 #define DIRENT_SET_ERRNO(x) (errno = (x))
190 #endif
191
192 #ifdef __cplusplus
193 extern "C" {
194 #endif
195
196 /* Wide-character versions */
 
197 struct _wdirent {
198 long d_ino; /* Always zero */
199 unsigned short d_reclen; /* Structure size */
200 size_t d_namlen; /* Length of name without \0 */
201 int d_type; /* File type */
@@ -203,11 +228,11 @@
203 };
204 typedef struct _wdirent _wdirent;
205
206 struct _WDIR {
207 struct _wdirent ent; /* Current directory entry */
208 WIN32_FIND_DATAW find_data; /* Private file data */
209 int cached; /* True if data is valid */
210 HANDLE handle; /* Win32 search handle */
211 wchar_t *patt; /* Initial directory name */
212 };
213 typedef struct _WDIR _WDIR;
@@ -214,10 +239,11 @@
214
215 static _WDIR *_wopendir (const wchar_t *dirname);
216 static struct _wdirent *_wreaddir (_WDIR *dirp);
217 static int _wclosedir (_WDIR *dirp);
218 static void _wrewinddir (_WDIR* dirp);
 
219
220 /* For compatibility with Symbian */
221 #define wdirent _wdirent
222 #define WDIR _WDIR
223 #define wopendir _wopendir
@@ -246,10 +272,30 @@
246 static struct dirent *readdir (DIR *dirp);
247 static int closedir (DIR *dirp);
248 static void rewinddir (DIR* dirp);
249
250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251 /*
252 * Open directory stream DIRNAME for read and return a pointer to the
253 * internal working area that is used to retrieve individual directory
254 * entries.
255 */
@@ -256,31 +302,38 @@
256 static _WDIR*
257 _wopendir(
258 const wchar_t *dirname)
259 {
260 _WDIR *dirp = NULL;
261 int error = 0;
 
 
 
 
 
 
262
263 /* Allocate new _WDIR structure */
264 dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
265 if (dirp != NULL) {
266 DWORD n;
267
268 /* Reset _WDIR structure */
269 dirp->handle = INVALID_HANDLE_VALUE;
270 dirp->patt = NULL;
 
271
272 /* Compute the length of full path plus zero terminator */
273 n = GetFullPathNameW (dirname, 0, NULL, NULL);
274
275 /* Allocate room for full path and search patterns */
276 dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
277 if (dirp->patt) {
278
279 /*
280 * Convert relative directory name to an absolute one. This
281 * allows rewinddir() to function correctly when the current
282 * working directory is changed between opendir() and rewinddir().
283 */
284 n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
285 if (n > 0) {
286 wchar_t *p;
@@ -303,25 +356,22 @@
303 }
304 *p++ = '*';
305 *p = '\0';
306
307 /* Open directory stream and retrieve the first entry */
308 dirp->handle = FindFirstFileW (dirp->patt, &dirp->find_data);
309 if (dirp->handle != INVALID_HANDLE_VALUE) {
310
311 /* Directory entry is now waiting in memory */
312 dirp->cached = 1;
313
314 } else {
315 /* Search pattern is not a directory name? */
316 DIRENT_SET_ERRNO (ENOENT);
317 error = 1;
 
318 }
319
320 } else {
321 /* Cannot convert directory name to wide character string */
322 DIRENT_SET_ERRNO (ENOENT);
323 error = 1;
324 }
325
326 } else {
327 /* Cannot allocate memory for search pattern */
@@ -350,70 +400,59 @@
350 */
351 static struct _wdirent*
352 _wreaddir(
353 _WDIR *dirp)
354 {
355 DWORD attr;
356 errno_t error;
357
358 /* Get next directory entry */
359 if (dirp->cached != 0) {
360 /* A valid directory entry already in memory */
361 dirp->cached = 0;
362 } else {
363 /* Get the next directory entry from stream */
364 if (dirp->handle == INVALID_HANDLE_VALUE) {
365 return NULL;
366 }
367 if (FindNextFileW (dirp->handle, &dirp->find_data) == FALSE) {
368 /* The very last entry has been processed or an error occured */
369 FindClose (dirp->handle);
370 dirp->handle = INVALID_HANDLE_VALUE;
371 return NULL;
372 }
373 }
374
375 /* Copy file name as a wide-character string */
376 error = wcsncpy_s(
377 dirp->ent.d_name, /* Destination string */
378 PATH_MAX, /* Size of dest in words */
379 dirp->find_data.cFileName, /* Source string */
380 PATH_MAX + 1); /* Max # of chars to copy */
381 if (!error) {
382
383 /* Compute the length of name */
384 dirp->ent.d_namlen = wcsnlen (dirp->ent.d_name, PATH_MAX);
385
386 /* Determine file type */
387 attr = dirp->find_data.dwFileAttributes;
388 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
389 dirp->ent.d_type = DT_CHR;
390 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
391 dirp->ent.d_type = DT_DIR;
392 } else {
393 dirp->ent.d_type = DT_REG;
394 }
395
396 /* Reset dummy fields */
397 dirp->ent.d_ino = 0;
398 dirp->ent.d_reclen = sizeof (dirp->ent);
399
400 } else {
401
402 /*
403 * Cannot copy file name from find_data to ent. Construct a
404 * dummy _wdirent structure to pass error to caller.
405 */
406 dirp->ent.d_name[0] = '?';
407 dirp->ent.d_name[1] = '\0';
408 dirp->ent.d_namlen = 1;
409 dirp->ent.d_type = DT_UNKNOWN;
410 dirp->ent.d_ino = 0;
411 dirp->ent.d_reclen = 0;
412 }
413
414 return &dirp->ent;
415 }
416
417 /*
418 * Close directory stream opened by opendir() function. This invalidates the
419 * DIR structure as well as any directory entry read previously by
@@ -442,11 +481,11 @@
442 free (dirp);
443 ok = /*success*/0;
444
445 } else {
446 /* Invalid directory stream */
447 DIRENT_SET_ERRNO (EBADF);
448 ok = /*failure*/-1;
449 }
450 return ok;
451 }
452
@@ -456,26 +495,81 @@
456 */
457 static void
458 _wrewinddir(
459 _WDIR* dirp)
460 {
461 if (dirp != NULL) {
462 /* release search handle */
463 if (dirp->handle != INVALID_HANDLE_VALUE) {
464 FindClose (dirp->handle);
465 }
466
467 /* Open new search handle and retrieve the first directory entry */
468 dirp->handle = FindFirstFileW (dirp->patt, &dirp->find_data);
469 if (dirp->handle != INVALID_HANDLE_VALUE) {
470 /* a directory entry is now waiting in memory */
471 dirp->cached = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
472 } else {
473 /* Failed to re-open directory: no directory entry in memory */
474 dirp->cached = 0;
 
 
475 }
 
 
 
 
 
 
476 }
 
 
477 }
478
479 /*
480 * Open directory stream using plain old C-string.
481 */
@@ -482,58 +576,34 @@
482 static DIR*
483 opendir(
484 const char *dirname)
485 {
486 struct DIR *dirp;
487 errno_t error = 0;
488
489 /* Must have directory name */
490 if (dirname == NULL) {
491 DIRENT_SET_ERRNO (ENOENT);
492 return NULL;
493 }
494
495 /* Allocate memory for multi-byte string directory structures */
496 dirp = (DIR*) malloc (sizeof (struct DIR));
497 if (dirp) {
498 wchar_t wname[PATH_MAX + 1];
499 size_t n;
500
501 /*
502 * Convert directory name to wide-character string.
503 *
504 * Be ware of the return schemantics of MultiByteToWideChar() --
505 * the function basically returns the number of characters written to
506 * output buffer or zero if the conversion fails. However, the
507 * function does not necessarily zero-terminate the output
508 * buffer and may return 0xFFFD if the string contains invalid
509 * characters!
510 */
511 n = MultiByteToWideChar(
512 CP_ACP, /* Input code page */
513 MB_PRECOMPOSED, /* Conversion flags */
514 dirname, /* Input string */
515 -1, /* Length of input string */
516 wname, /* Output buffer */
517 PATH_MAX); /* Size of output buffer */
518 if (n > 0 && n < PATH_MAX) {
519
520 /* Zero-terminate output buffer */
521 wname[n] = '\0';
522
523 /* Open directory stream with wide-character string file name */
524 dirp->wdirp = _wopendir (wname);
525 if (dirp->wdirp) {
526
527 /* Initialize directory structure */
528 dirp->ent.d_name[0] = '\0';
529 dirp->ent.d_namlen = 0;
530 dirp->ent.d_type = 0;
531 dirp->ent.d_ino = 0;
532 dirp->ent.d_reclen = 0;
533
534
535 } else {
536 /* Failed to open directory stream */
537 error = 1;
538 }
539
@@ -562,95 +632,99 @@
562 }
563
564 /*
565 * Read next directory entry.
566 *
567 * When working with console, please note that file names returned by
568 * readdir() are represented in the default ANSI code page while the
569 * console typically runs on another code page. Thus, non-ASCII characters
570 * will not usually display correctly. The problem can be fixed in two ways:
571 * (1) change the character set of console to 1252 using chcp utility and use
572 * Lucida Console font, or (2) always use _cprintf function when writing to
573 * console. The _cprinf() will re-encode ANSI strings to the console code
574 * page so non-ASCII characters will display correcly.
 
575 */
576 static struct dirent*
577 readdir(
578 DIR *dirp)
579 {
580 struct dirent *p;
581 struct _wdirent *wp;
582
583 /* Read next directory entry using wide-character string functions */
584 wp = _wreaddir (dirp->wdirp);
585 if (wp) {
586 size_t n;
 
 
 
 
 
587
588 /*
589 * Convert file name to multi-byte string.
590 *
591 * Be ware of the return schemantics of WideCharToMultiByte() --
592 * the function basically returns the number of bytes
593 * written to output buffer or zero if the conversion fails.
594 * However, the function does not necessarily zero-terminate the
595 * buffer and it may even return 0xFFFD the string contains
596 * invalid characters!
597 */
598 n = WideCharToMultiByte(
599 CP_ACP, /* Output code page */
600 0, /* Conversion flags */
601 wp->d_name, /* Input string */
602 wp->d_namlen, /* Length of input string */
603 dirp->ent.d_name, /* Output buffer */
604 PATH_MAX, /* Size of output buffer */
605 NULL, /* Replacement character */
606 NULL); /* If chars were replaced */
607 if (n > 0 && n < PATH_MAX) {
608
609 /* Zero-terminate buffer */
610 dirp->ent.d_name[n] = '\0';
611
612 /* Initialize directory entry for return */
613 p = &dirp->ent;
614
615 /* Compute length */
616 p->d_namlen = strnlen (dirp->ent.d_name, PATH_MAX);
617
618 /* Copy file attributes */
619 p->d_type = wp->d_type;
 
 
 
 
 
 
 
620
621 /* Reset dummy fields */
622 p->d_ino = 0;
623 p->d_reclen = sizeof (dirp->ent);
624
625
626 } else {
627
628 /*
629 * Cannot convert file name to multi-byte string so construct
630 * an errornous directory entry and return that. Note that
631 * we cannot return NULL as that would stop the processing
632 * of directory entries completely.
633 */
634 p = &dirp->ent;
635 p->d_name[0] = '?';
636 p->d_name[1] = '\0';
637 p->d_namlen = 1;
638 p->d_type = DT_UNKNOWN;
639 p->d_ino = 0;
640 p->d_reclen = 0;
641
642 }
643
644 } else {
645
646 /* End of directory stream */
647 p = NULL;
648
649 }
650
651 return p;
652 }
653
654 /*
655 * Close directory stream.
656 */
@@ -667,13 +741,15 @@
667
668 /* Release multi-byte character version */
669 free (dirp);
670
671 } else {
 
672 /* Invalid directory stream */
673 DIRENT_SET_ERRNO (EBADF);
674 ok = /*failure*/-1;
 
675 }
676 return ok;
677 }
678
679 /*
@@ -684,12 +760,130 @@
684 DIR* dirp)
685 {
686 /* Rewind wide-character string directory stream */
687 _wrewinddir (dirp->wdirp);
688 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
689
690
691 #ifdef __cplusplus
692 }
693 #endif
694 #endif /*DIRENT_H*/
695
696
--- win/include/dirent.h
+++ win/include/dirent.h
@@ -20,21 +20,24 @@
20 * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 *
25 *
26 * Version 1.13, Dec 12 2012, Toni Ronkko
27 * Use traditional 8+3 file name if the name cannot be represented in the
28 * default ANSI code page. Now compiles again with MSVC 6.0. Thanks to
29 * Konstantin Khomoutov for testing.
30 *
31 * Version 1.12.1, Oct 1 2012, Toni Ronkko
32 * Bug fix: renamed wide-character DIR structure _wDIR to _WDIR (with
33 * capital W) in order to maintain compatibility with MingW.
34 *
35 * Version 1.12, Sep 30 2012, Toni Ronkko
36 * Define PATH_MAX and NAME_MAX. Added wide-character variants _wDIR,
37 * _wdirent, _wopendir(), _wreaddir(), _wclosedir() and _wrewinddir().
38 * Thanks to Edgar Buerkle and Jan Nijtmans for ideas and code.
 
 
39 *
40 * Do not include windows.h. This allows dirent.h to be integrated more
41 * easily into programs using winsock. Thanks to Fernando Azaldegui.
42 *
43 * Version 1.11, Mar 15, 2011, Toni Ronkko
@@ -88,48 +91,72 @@
91 *****************************************************************************/
92 #ifndef DIRENT_H
93 #define DIRENT_H
94
95 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
96 # define _X86_
97 #endif
98 #include <stdio.h>
99 #include <stdarg.h>
100 #include <windef.h>
101 #include <winbase.h>
102 #include <wchar.h>
 
103 #include <string.h>
104 #include <stdlib.h>
105 #include <malloc.h>
106 #include <sys/types.h>
107 #include <sys/stat.h>
108 #include <errno.h>
109
110 /* Indicates that d_type field is available in dirent structure */
111 #define _DIRENT_HAVE_D_TYPE
112
113 /* Indicates that d_namlen field is available in dirent structure */
114 #define _DIRENT_HAVE_D_NAMLEN
115
116 /* Entries missing from MSVC 6.0 */
117 #if !defined(FILE_ATTRIBUTE_DEVICE)
118 # define FILE_ATTRIBUTE_DEVICE 0x40
119 #endif
120
121 /* File type and permission flags for stat() */
122 #if !defined(S_IFMT)
123 # define S_IFMT _S_IFMT /* File type mask */
124 #endif
125 #if !defined(S_IFDIR)
126 # define S_IFDIR _S_IFDIR /* Directory */
127 #endif
128 #if !defined(S_IFCHR)
129 # define S_IFCHR _S_IFCHR /* Character device */
130 #endif
131 #if !defined(S_IFFIFO)
132 # define S_IFFIFO _S_IFFIFO /* Pipe */
133 #endif
134 #if !defined(S_IFREG)
135 # define S_IFREG _S_IFREG /* Regular file */
136 #endif
137 #if !defined(S_IREAD)
138 # define S_IREAD _S_IREAD /* Read permission */
139 #endif
140 #if !defined(S_IWRITE)
141 # define S_IWRITE _S_IWRITE /* Write permission */
142 #endif
143 #if !defined(S_IEXEC)
144 # define S_IEXEC _S_IEXEC /* Execute permission */
145 #endif
146 #if !defined(S_IFIFO)
147 # define S_IFIFO _S_IFIFO /* Pipe */
148 #endif
149 #if !defined(S_IFBLK)
150 # define S_IFBLK 0 /* Block device */
151 #endif
152 #if !defined(S_IFLNK)
153 # define S_IFLNK 0 /* Link */
154 #endif
155 #if !defined(S_IFSOCK)
156 # define S_IFSOCK 0 /* Socket */
157 #endif
158
159 #if defined(_MSC_VER)
160 # define S_IRUSR S_IREAD /* Read user */
161 # define S_IWUSR S_IWRITE /* Write user */
162 # define S_IXUSR 0 /* Execute user */
@@ -139,18 +166,26 @@
166 # define S_IROTH 0 /* Read others */
167 # define S_IWOTH 0 /* Write others */
168 # define S_IXOTH 0 /* Execute others */
169 #endif
170
171 /* Maximum length of file name */
172 #if !defined(PATH_MAX)
173 # define PATH_MAX MAX_PATH
174 #endif
175 #if !defined(FILENAME_MAX)
176 # define FILENAME_MAX MAX_PATH
177 #endif
178 #if !defined(NAME_MAX)
179 # define NAME_MAX FILENAME_MAX
180 #endif
181
182 /* File type flags for d_type */
183 #define DT_UNKNOWN 0
184 #define DT_REG S_IFREG
185 #define DT_DIR S_IFDIR
186 #define DT_FIFO S_IFIFO
187 #define DT_SOCK S_IFSOCK
188 #define DT_CHR S_IFCHR
189 #define DT_BLK S_IFBLK
190
191 /* Macros for converting between st_mode and d_type */
@@ -161,41 +196,31 @@
196 * File type macros. Note that block devices, sockets and links cannot be
197 * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
198 * only defined for compatibility. These macros should always return false
199 * on Windows.
200 */
201 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
202 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
203 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
204 #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
205 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
206 #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
207 #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
208
209 /* Return the exact length of d_namlen without zero terminator */
210 #define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
211
212 /* Return number of bytes needed to store d_namlen */
213 #define _D_ALLOC_NAMLEN(p) (PATH_MAX + 1)
214
 
 
 
 
 
 
 
 
 
 
 
215
216 #ifdef __cplusplus
217 extern "C" {
218 #endif
219
220
221 /* Wide-character version */
222 struct _wdirent {
223 long d_ino; /* Always zero */
224 unsigned short d_reclen; /* Structure size */
225 size_t d_namlen; /* Length of name without \0 */
226 int d_type; /* File type */
@@ -203,11 +228,11 @@
228 };
229 typedef struct _wdirent _wdirent;
230
231 struct _WDIR {
232 struct _wdirent ent; /* Current directory entry */
233 WIN32_FIND_DATAW data; /* Private file data */
234 int cached; /* True if data is valid */
235 HANDLE handle; /* Win32 search handle */
236 wchar_t *patt; /* Initial directory name */
237 };
238 typedef struct _WDIR _WDIR;
@@ -214,10 +239,11 @@
239
240 static _WDIR *_wopendir (const wchar_t *dirname);
241 static struct _wdirent *_wreaddir (_WDIR *dirp);
242 static int _wclosedir (_WDIR *dirp);
243 static void _wrewinddir (_WDIR* dirp);
244
245
246 /* For compatibility with Symbian */
247 #define wdirent _wdirent
248 #define WDIR _WDIR
249 #define wopendir _wopendir
@@ -246,10 +272,30 @@
272 static struct dirent *readdir (DIR *dirp);
273 static int closedir (DIR *dirp);
274 static void rewinddir (DIR* dirp);
275
276
277 /* Internal utility functions */
278 static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
279 static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
280
281 static int dirent_mbstowcs_s(
282 size_t *pReturnValue,
283 wchar_t *wcstr,
284 size_t sizeInWords,
285 const char *mbstr,
286 size_t count);
287
288 static int dirent_wcstombs_s(
289 size_t *pReturnValue,
290 char *mbstr,
291 size_t sizeInBytes,
292 const wchar_t *wcstr,
293 size_t count);
294
295 static void dirent_set_errno (int error);
296
297 /*
298 * Open directory stream DIRNAME for read and return a pointer to the
299 * internal working area that is used to retrieve individual directory
300 * entries.
301 */
@@ -256,31 +302,38 @@
302 static _WDIR*
303 _wopendir(
304 const wchar_t *dirname)
305 {
306 _WDIR *dirp = NULL;
307 int error;
308
309 /* Must have directory name */
310 if (dirname == NULL || dirname[0] == '\0') {
311 dirent_set_errno (ENOENT);
312 return NULL;
313 }
314
315 /* Allocate new _WDIR structure */
316 dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
317 if (dirp != NULL) {
318 DWORD n;
319
320 /* Reset _WDIR structure */
321 dirp->handle = INVALID_HANDLE_VALUE;
322 dirp->patt = NULL;
323 dirp->cached = 0;
324
325 /* Compute the length of full path plus zero terminator */
326 n = GetFullPathNameW (dirname, 0, NULL, NULL);
327
328 /* Allocate room for absolute directory name and search pattern */
329 dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
330 if (dirp->patt) {
331
332 /*
333 * Convert relative directory name to an absolute one. This
334 * allows rewinddir() to function correctly even when current
335 * working directory is changed between opendir() and rewinddir().
336 */
337 n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
338 if (n > 0) {
339 wchar_t *p;
@@ -303,25 +356,22 @@
356 }
357 *p++ = '*';
358 *p = '\0';
359
360 /* Open directory stream and retrieve the first entry */
361 if (dirent_first (dirp)) {
362 /* Directory stream opened successfully */
363 error = 0;
 
 
 
364 } else {
365 /* Cannot retrieve first entry */
 
366 error = 1;
367 dirent_set_errno (ENOENT);
368 }
369
370 } else {
371 /* Cannot retrieve full path name */
372 dirent_set_errno (ENOENT);
373 error = 1;
374 }
375
376 } else {
377 /* Cannot allocate memory for search pattern */
@@ -350,70 +400,59 @@
400 */
401 static struct _wdirent*
402 _wreaddir(
403 _WDIR *dirp)
404 {
405 WIN32_FIND_DATAW *datap;
406 struct _wdirent *entp;
407
408 /* Read next directory entry */
409 datap = dirent_next (dirp);
410 if (datap) {
411 size_t n;
412 DWORD attr;
413
414 /* Pointer to directory entry to return */
415 entp = &dirp->ent;
416
417 /*
418 * Copy file name as wide-character string. If the file name is too
419 * long to fit in to the destination buffer, then truncate file name
420 * to PATH_MAX characters and zero-terminate the buffer.
421 */
422 n = 0;
423 while (n < PATH_MAX && datap->cFileName[n] != 0) {
424 entp->d_name[n] = datap->cFileName[n];
425 n++;
426 }
427 dirp->ent.d_name[n] = 0;
428
429 /* Length of file name excluding zero terminator */
430 entp->d_namlen = n;
431
432 /* File type */
433 attr = datap->dwFileAttributes;
 
 
 
 
434 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
435 entp->d_type = DT_CHR;
436 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
437 entp->d_type = DT_DIR;
438 } else {
439 entp->d_type = DT_REG;
440 }
441
442 /* Reset dummy fields */
443 entp->d_ino = 0;
444 entp->d_reclen = sizeof (struct _wdirent);
445
446 } else {
447
448 /* Last directory entry read */
449 entp = NULL;
450
 
 
 
 
 
 
 
451 }
452
453 return entp;
454 }
455
456 /*
457 * Close directory stream opened by opendir() function. This invalidates the
458 * DIR structure as well as any directory entry read previously by
@@ -442,11 +481,11 @@
481 free (dirp);
482 ok = /*success*/0;
483
484 } else {
485 /* Invalid directory stream */
486 dirent_set_errno (EBADF);
487 ok = /*failure*/-1;
488 }
489 return ok;
490 }
491
@@ -456,26 +495,81 @@
495 */
496 static void
497 _wrewinddir(
498 _WDIR* dirp)
499 {
500 if (dirp) {
501 /* Release existing search handle */
502 if (dirp->handle != INVALID_HANDLE_VALUE) {
503 FindClose (dirp->handle);
504 }
505
506 /* Open new search handle */
507 dirent_first (dirp);
508 }
509 }
510
511 /* Get first directory entry (internal) */
512 static WIN32_FIND_DATAW*
513 dirent_first(
514 _WDIR *dirp)
515 {
516 WIN32_FIND_DATAW *datap;
517
518 /* Open directory and retrieve the first entry */
519 dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
520 if (dirp->handle != INVALID_HANDLE_VALUE) {
521
522 /* a directory entry is now waiting in memory */
523 datap = &dirp->data;
524 dirp->cached = 1;
525
526 } else {
527
528 /* Failed to re-open directory: no directory entry in memory */
529 dirp->cached = 0;
530 datap = NULL;
531
532 }
533 return datap;
534 }
535
536 /* Get next directory entry (internal) */
537 static WIN32_FIND_DATAW*
538 dirent_next(
539 _WDIR *dirp)
540 {
541 WIN32_FIND_DATAW *p;
542
543 /* Get next directory entry */
544 if (dirp->cached != 0) {
545
546 /* A valid directory entry already in memory */
547 p = &dirp->data;
548 dirp->cached = 0;
549
550 } else if (dirp->handle != INVALID_HANDLE_VALUE) {
551
552 /* Get the next directory entry from stream */
553 if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
554 /* Got a file */
555 p = &dirp->data;
556 } else {
557 /* The very last entry has been processed or an error occured */
558 FindClose (dirp->handle);
559 dirp->handle = INVALID_HANDLE_VALUE;
560 p = NULL;
561 }
562
563 } else {
564
565 /* End of directory stream reached */
566 p = NULL;
567
568 }
569
570 return p;
571 }
572
573 /*
574 * Open directory stream using plain old C-string.
575 */
@@ -482,58 +576,34 @@
576 static DIR*
577 opendir(
578 const char *dirname)
579 {
580 struct DIR *dirp;
581 int error;
582
583 /* Must have directory name */
584 if (dirname == NULL || dirname[0] == '\0') {
585 dirent_set_errno (ENOENT);
586 return NULL;
587 }
588
589 /* Allocate memory for DIR structure */
590 dirp = (DIR*) malloc (sizeof (struct DIR));
591 if (dirp) {
592 wchar_t wname[PATH_MAX + 1];
593 size_t n;
594
595 /* Convert directory name to wide-character string */
596 error = dirent_mbstowcs_s(
597 &n, wname, PATH_MAX + 1, dirname, PATH_MAX);
598 if (!error) {
599
600 /* Open directory stream using wide-character name */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601 dirp->wdirp = _wopendir (wname);
602 if (dirp->wdirp) {
603 /* Directory stream opened */
604 error = 0;
 
 
 
 
 
 
 
605 } else {
606 /* Failed to open directory stream */
607 error = 1;
608 }
609
@@ -562,95 +632,99 @@
632 }
633
634 /*
635 * Read next directory entry.
636 *
637 * When working with text consoles, please note that file names returned by
638 * readdir() are represented in the default ANSI code page while any output to
639 * console is typically formatted on another code page. Thus, non-ASCII
640 * characters in file names will not usually display correctly on console. The
641 * problem can be fixed in two ways: (1) change the character set of console
642 * to 1252 using chcp utility and use Lucida Console font, or (2) use
643 * _cprintf function when writing to console. The _cprinf() will re-encode
644 * ANSI strings to the console code page so many non-ASCII characters will
645 * display correcly.
646 */
647 static struct dirent*
648 readdir(
649 DIR *dirp)
650 {
651 WIN32_FIND_DATAW *datap;
652 struct dirent *entp;
653
654 /* Read next directory entry */
655 datap = dirent_next (dirp->wdirp);
656 if (datap) {
657 size_t n;
658 int error;
659
660 /* Attempt to convert file name to multi-byte string */
661 error = dirent_wcstombs_s(
662 &n, dirp->ent.d_name, MAX_PATH + 1, datap->cFileName, MAX_PATH);
663
664 /*
665 * If the file name cannot be represented by a multi-byte string,
666 * then attempt to use old 8+3 file name. This allows traditional
667 * Unix-code to access some file names despite of unicode
668 * characters, although file names may seem unfamiliar to the user.
669 *
670 * Be ware that the code below cannot come up with a short file
671 * name unless the file system provides one. At least
672 * VirtualBox shared folders fail to do this.
673 */
674 if (error && datap->cAlternateFileName[0] != '\0') {
675 error = dirent_wcstombs_s(
676 &n, dirp->ent.d_name, MAX_PATH + 1, datap->cAlternateFileName,
677 sizeof (datap->cAlternateFileName) /
678 sizeof (datap->cAlternateFileName[0]));
679 }
680
681 if (!error) {
682 DWORD attr;
 
 
 
 
683
684 /* Initialize directory entry for return */
685 entp = &dirp->ent;
686
687 /* Length of file name excluding zero terminator */
688 entp->d_namlen = n - 1;
689
690 /* File attributes */
691 attr = datap->dwFileAttributes;
692 if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
693 entp->d_type = DT_CHR;
694 } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
695 entp->d_type = DT_DIR;
696 } else {
697 entp->d_type = DT_REG;
698 }
699
700 /* Reset dummy fields */
701 entp->d_ino = 0;
702 entp->d_reclen = sizeof (struct dirent);
 
703
704 } else {
 
705 /*
706 * Cannot convert file name to multi-byte string so construct
707 * an errornous directory entry and return that. Note that
708 * we cannot return NULL as that would stop the processing
709 * of directory entries completely.
710 */
711 entp = &dirp->ent;
712 entp->d_name[0] = '?';
713 entp->d_name[1] = '\0';
714 entp->d_namlen = 1;
715 entp->d_type = DT_UNKNOWN;
716 entp->d_ino = 0;
717 entp->d_reclen = 0;
 
718 }
719
720 } else {
721 /* No more directory entries */
722 entp = NULL;
 
 
723 }
724
725 return entp;
726 }
727
728 /*
729 * Close directory stream.
730 */
@@ -667,13 +741,15 @@
741
742 /* Release multi-byte character version */
743 free (dirp);
744
745 } else {
746
747 /* Invalid directory stream */
748 dirent_set_errno (EBADF);
749 ok = /*failure*/-1;
750
751 }
752 return ok;
753 }
754
755 /*
@@ -684,12 +760,130 @@
760 DIR* dirp)
761 {
762 /* Rewind wide-character string directory stream */
763 _wrewinddir (dirp->wdirp);
764 }
765
766 /* Convert multi-byte string to wide character string */
767 static int
768 dirent_mbstowcs_s(
769 size_t *pReturnValue,
770 wchar_t *wcstr,
771 size_t sizeInWords,
772 const char *mbstr,
773 size_t count)
774 {
775 int error;
776
777 #if defined(_MSC_VER) && _MSC_VER >= 1400
778
779 /* Microsoft Visual Studio 2005 or later */
780 error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
781
782 #else
783
784 /* Older Visual Studio or non-Microsoft compiler */
785 size_t n;
786
787 /* Convert to wide-character string */
788 n = mbstowcs (wcstr, mbstr, count);
789 if (n < sizeInWords) {
790
791 /* Zero-terminate output buffer */
792 if (wcstr) {
793 wcstr[n] = 0;
794 }
795
796 /* Length of resuting multi-byte string WITH zero terminator */
797 if (pReturnValue) {
798 *pReturnValue = n + 1;
799 }
800
801 /* Success */
802 error = 0;
803
804 } else {
805
806 /* Could not convert string */
807 error = 1;
808
809 }
810
811 #endif
812
813 return error;
814 }
815
816 /* Convert wide-character string to multi-byte string */
817 static int
818 dirent_wcstombs_s(
819 size_t *pReturnValue,
820 char *mbstr,
821 size_t sizeInBytes,
822 const wchar_t *wcstr,
823 size_t count)
824 {
825 int error;
826
827 #if defined(_MSC_VER) && _MSC_VER >= 1400
828
829 /* Microsoft Visual Studio 2005 or later */
830 error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
831
832 #else
833
834 /* Older Visual Studio or non-Microsoft compiler */
835 size_t n;
836
837 /* Convert to multi-byte string */
838 n = wcstombs (mbstr, wcstr, count);
839 if (n < sizeInBytes) {
840
841 /* Zero-terminate output buffer */
842 if (mbstr) {
843 mbstr[n] = '\0';
844 }
845
846 /* Lenght of resulting multi-bytes string WITH zero-terminator */
847 if (pReturnValue) {
848 *pReturnValue = n + 1;
849 }
850
851 /* Success */
852 error = 0;
853
854 } else {
855
856 /* Cannot convert string */
857 error = 1;
858
859 }
860
861 #endif
862
863 return error;
864 }
865
866 /* Set errno variable */
867 static void
868 dirent_set_errno(
869 int error)
870 {
871 #if defined(_MSC_VER)
872
873 /* Microsoft Visual Studio */
874 _set_errno (error);
875
876 #else
877
878 /* Non-Microsoft compiler */
879 errno = error;
880
881 #endif
882 }
883
884
885 #ifdef __cplusplus
886 }
887 #endif
888 #endif /*DIRENT_H*/
889
890
+29 -28
--- www/build.wiki
+++ www/build.wiki
@@ -1,6 +1,6 @@
1
-<title>Building and Installing Fossil</title>
1
+<title>Compiling and Installing Fossil</title>
22
33
<h2>0.0 Using A Pre-compiled Binary</h2>
44
55
<p>Released versions of fossil come with
66
<a href="http://www.fossil-scm.org/download.html">pre-compiled binaries and
@@ -25,33 +25,29 @@
2525
2626
<p><hr>
2727
2828
<h2>1.0 Obtaining The Source Code</h2>
2929
30
-<p>Fossil is self-hosting, so you can obtain a ZIP archive containing
31
-a snapshot of the <em>latest</em> version directly from fossil's own fossil
32
-repository. Additionally, source archives of <em>released</em> versions of
30
+<p>Fossil is self-hosting, so you can obtain a ZIP archive or tarball
31
+containing a snapshot of the <em>latest</em> version directly from
32
+Fossil's own fossil repository. Additionally, source archives of
33
+<em>released</em> versions of
3334
fossil are available from the <a href="http://www.fossil-scm.org/download.html">downloads page</a>.
3435
To obtain a development version of fossil, follow these steps:</p>
3536
3637
<ol>
3738
<li><p>Point your web browser at
3839
<a href="http://www.fossil-scm.org/">
39
-http://www.fossil-scm.org/</a>. Click on the "Login" menu button.</p></li>
40
-
41
-<li><p>Log in as anonymous. The password is shown on screen.
42
-The reason for requiring this login is to prevent spiders from
43
-walking the entire website, downloading ZIP archives
44
-of every historical version, and thereby soaking up all our bandwidth.</p></li>
40
+http://www.fossil-scm.org/</a>.</p></li>
4541
4642
<li><p>Click on the
4743
<a href="http://www.fossil-scm.org/fossil/timeline">Timeline</a>
4844
link at the top of the page.</p></li>
4945
50
-<li><p>Select a version of of fossil you want to download. Click on its
51
-link. Note that you must successfully log in as "anonymous" in step 1
52
-above in order to see the link to the detailed version information.</p></li>
46
+<li><p>Select a version of of Fossil you want to download. The latest
47
+version on the trunk branch is usually a good choice. Click on its
48
+link.</p></li>
5349
5450
<li><p>Finally, click on one of the
5551
"Zip Archive" or "Tarball" links, according to your preference.
5652
These link will build a ZIP archive or a gzip-compressed tarball of the
5753
complete source code and download it to your browser.
@@ -59,11 +55,11 @@
5955
6056
<h2>2.0 Compiling</h2>
6157
6258
<ol>
6359
<li value="6">
64
-<p>Unpack the ZIP or tarball you downloaded into that directory then
60
+<p>Unpack the ZIP or tarball you downloaded then
6561
<b>cd</b> into the directory created.</p></li>
6662
6763
<li><i>(Optional, unix only)</i>
6864
Run <b>./configure</b> to construct a makefile.
6965
@@ -79,12 +75,12 @@
7975
<li><p>
8076
Other configuration options can be seen by running
8177
<b>./configure --help</b>
8278
</ol>
8379
84
-<li><p>Run make to build the "fossil" or "fossil.exe" executable. The
85
-details depend on your platform and compiler.
80
+<li><p>Run "<b>make</b>" to build the "fossil" or "fossil.exe" executable.
81
+The details depend on your platform and compiler.
8682
8783
<ol type="a">
8884
<li><p><i>Unix</i> → the configure-generated Makefile should work on
8985
all unix and unix-like systems. Simply type "<b>make</b>".
9086
@@ -102,16 +98,10 @@
10298
change to the "win/" subdirectory ("<b>cd win</b>") then run
10399
"<b>nmake /f Makefile.msc</b>".
104100
</ol>
105101
</ol>
106102
107
-<p>Note that Fossil requires the "zlib" compression library. This library
108
-is available by default on most unix systems, but it will typically have to
109
-be installed separately on windows systems. For windows builds, you may
110
-need to edit the makefile to tell it exactly where zlib is located on your
111
-system.</p>
112
-
113103
<h2>3.0 Installing</h2>
114104
115105
<ol>
116106
<li value="9">
117107
<p>The finished binary is named "fossil" (or "fossil.exe" on windows).
@@ -124,11 +114,22 @@
124114
To uninstall, just delete the binary.</p>
125115
</ol>
126116
127117
<h2>4.0 Additional Considerations</h2>
128118
129
-</nowiki>
130
- * If the makefiles that come with Fossil do not work for
131
- you, or for some other reason you want to know how to build
132
- Fossil manually, then refer to the
133
- [./makefile.wiki | Fossil Build Process] document which describes
134
- in detail what the makefiles do behind the scenes.
119
+<ul>
120
+<li><p>
121
+ If the makefiles that come with Fossil do not work for
122
+ you, or for some other reason you want to know how to build
123
+ Fossil manually, then refer to the
124
+ [./makefile.wiki | Fossil Build Process] document which describes
125
+ in detail what the makefiles do behind the scenes.
126
+
127
+<li><p>
128
+ To build on older Macs (circa 2002, MacOS 10.2) edit the Makefile
129
+ generated by configure to add the following lines:
130
+ <blockquote><pre>
131
+ TCC += -DSQLITE_WITHOUT_ZONEMALLOC
132
+ TCC += -DWITHOUT_ICONV
133
+ TCC += -Dsocketlen_t=int
134
+ </pre></blockquote>
135
+</ul>
135136
--- www/build.wiki
+++ www/build.wiki
@@ -1,6 +1,6 @@
1 <title>Building and Installing Fossil</title>
2
3 <h2>0.0 Using A Pre-compiled Binary</h2>
4
5 <p>Released versions of fossil come with
6 <a href="http://www.fossil-scm.org/download.html">pre-compiled binaries and
@@ -25,33 +25,29 @@
25
26 <p><hr>
27
28 <h2>1.0 Obtaining The Source Code</h2>
29
30 <p>Fossil is self-hosting, so you can obtain a ZIP archive containing
31 a snapshot of the <em>latest</em> version directly from fossil's own fossil
32 repository. Additionally, source archives of <em>released</em> versions of
 
33 fossil are available from the <a href="http://www.fossil-scm.org/download.html">downloads page</a>.
34 To obtain a development version of fossil, follow these steps:</p>
35
36 <ol>
37 <li><p>Point your web browser at
38 <a href="http://www.fossil-scm.org/">
39 http://www.fossil-scm.org/</a>. Click on the "Login" menu button.</p></li>
40
41 <li><p>Log in as anonymous. The password is shown on screen.
42 The reason for requiring this login is to prevent spiders from
43 walking the entire website, downloading ZIP archives
44 of every historical version, and thereby soaking up all our bandwidth.</p></li>
45
46 <li><p>Click on the
47 <a href="http://www.fossil-scm.org/fossil/timeline">Timeline</a>
48 link at the top of the page.</p></li>
49
50 <li><p>Select a version of of fossil you want to download. Click on its
51 link. Note that you must successfully log in as "anonymous" in step 1
52 above in order to see the link to the detailed version information.</p></li>
53
54 <li><p>Finally, click on one of the
55 "Zip Archive" or "Tarball" links, according to your preference.
56 These link will build a ZIP archive or a gzip-compressed tarball of the
57 complete source code and download it to your browser.
@@ -59,11 +55,11 @@
59
60 <h2>2.0 Compiling</h2>
61
62 <ol>
63 <li value="6">
64 <p>Unpack the ZIP or tarball you downloaded into that directory then
65 <b>cd</b> into the directory created.</p></li>
66
67 <li><i>(Optional, unix only)</i>
68 Run <b>./configure</b> to construct a makefile.
69
@@ -79,12 +75,12 @@
79 <li><p>
80 Other configuration options can be seen by running
81 <b>./configure --help</b>
82 </ol>
83
84 <li><p>Run make to build the "fossil" or "fossil.exe" executable. The
85 details depend on your platform and compiler.
86
87 <ol type="a">
88 <li><p><i>Unix</i> → the configure-generated Makefile should work on
89 all unix and unix-like systems. Simply type "<b>make</b>".
90
@@ -102,16 +98,10 @@
102 change to the "win/" subdirectory ("<b>cd win</b>") then run
103 "<b>nmake /f Makefile.msc</b>".
104 </ol>
105 </ol>
106
107 <p>Note that Fossil requires the "zlib" compression library. This library
108 is available by default on most unix systems, but it will typically have to
109 be installed separately on windows systems. For windows builds, you may
110 need to edit the makefile to tell it exactly where zlib is located on your
111 system.</p>
112
113 <h2>3.0 Installing</h2>
114
115 <ol>
116 <li value="9">
117 <p>The finished binary is named "fossil" (or "fossil.exe" on windows).
@@ -124,11 +114,22 @@
124 To uninstall, just delete the binary.</p>
125 </ol>
126
127 <h2>4.0 Additional Considerations</h2>
128
129 </nowiki>
130 * If the makefiles that come with Fossil do not work for
131 you, or for some other reason you want to know how to build
132 Fossil manually, then refer to the
133 [./makefile.wiki | Fossil Build Process] document which describes
134 in detail what the makefiles do behind the scenes.
 
 
 
 
 
 
 
 
 
 
 
135
--- www/build.wiki
+++ www/build.wiki
@@ -1,6 +1,6 @@
1 <title>Compiling and Installing Fossil</title>
2
3 <h2>0.0 Using A Pre-compiled Binary</h2>
4
5 <p>Released versions of fossil come with
6 <a href="http://www.fossil-scm.org/download.html">pre-compiled binaries and
@@ -25,33 +25,29 @@
25
26 <p><hr>
27
28 <h2>1.0 Obtaining The Source Code</h2>
29
30 <p>Fossil is self-hosting, so you can obtain a ZIP archive or tarball
31 containing a snapshot of the <em>latest</em> version directly from
32 Fossil's own fossil repository. Additionally, source archives of
33 <em>released</em> versions of
34 fossil are available from the <a href="http://www.fossil-scm.org/download.html">downloads page</a>.
35 To obtain a development version of fossil, follow these steps:</p>
36
37 <ol>
38 <li><p>Point your web browser at
39 <a href="http://www.fossil-scm.org/">
40 http://www.fossil-scm.org/</a>.</p></li>
 
 
 
 
 
41
42 <li><p>Click on the
43 <a href="http://www.fossil-scm.org/fossil/timeline">Timeline</a>
44 link at the top of the page.</p></li>
45
46 <li><p>Select a version of of Fossil you want to download. The latest
47 version on the trunk branch is usually a good choice. Click on its
48 link.</p></li>
49
50 <li><p>Finally, click on one of the
51 "Zip Archive" or "Tarball" links, according to your preference.
52 These link will build a ZIP archive or a gzip-compressed tarball of the
53 complete source code and download it to your browser.
@@ -59,11 +55,11 @@
55
56 <h2>2.0 Compiling</h2>
57
58 <ol>
59 <li value="6">
60 <p>Unpack the ZIP or tarball you downloaded then
61 <b>cd</b> into the directory created.</p></li>
62
63 <li><i>(Optional, unix only)</i>
64 Run <b>./configure</b> to construct a makefile.
65
@@ -79,12 +75,12 @@
75 <li><p>
76 Other configuration options can be seen by running
77 <b>./configure --help</b>
78 </ol>
79
80 <li><p>Run "<b>make</b>" to build the "fossil" or "fossil.exe" executable.
81 The details depend on your platform and compiler.
82
83 <ol type="a">
84 <li><p><i>Unix</i> → the configure-generated Makefile should work on
85 all unix and unix-like systems. Simply type "<b>make</b>".
86
@@ -102,16 +98,10 @@
98 change to the "win/" subdirectory ("<b>cd win</b>") then run
99 "<b>nmake /f Makefile.msc</b>".
100 </ol>
101 </ol>
102
 
 
 
 
 
 
103 <h2>3.0 Installing</h2>
104
105 <ol>
106 <li value="9">
107 <p>The finished binary is named "fossil" (or "fossil.exe" on windows).
@@ -124,11 +114,22 @@
114 To uninstall, just delete the binary.</p>
115 </ol>
116
117 <h2>4.0 Additional Considerations</h2>
118
119 <ul>
120 <li><p>
121 If the makefiles that come with Fossil do not work for
122 you, or for some other reason you want to know how to build
123 Fossil manually, then refer to the
124 [./makefile.wiki | Fossil Build Process] document which describes
125 in detail what the makefiles do behind the scenes.
126
127 <li><p>
128 To build on older Macs (circa 2002, MacOS 10.2) edit the Makefile
129 generated by configure to add the following lines:
130 <blockquote><pre>
131 TCC += -DSQLITE_WITHOUT_ZONEMALLOC
132 TCC += -DWITHOUT_ICONV
133 TCC += -Dsocketlen_t=int
134 </pre></blockquote>
135 </ul>
136
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -14,12 +14,11 @@
1414
<li> Special names:
1515
<ul>
1616
<li> <b>tip</b>
1717
<li> <b>current</b>
1818
<li> <b>next</b>
19
-<li> <b>previous</b>
20
-<li> <b>ckout</b>
19
+<li> <b>previous</b> or <b>prev</b>
2120
</ul>
2221
</ul>
2322
</td></tr>
2423
</table>
2524
Many Fossil [/help|commands] and [./webui.wiki | web-interface] URLs accept
@@ -194,12 +193,12 @@
194193
equivalent to the timestamp tag "5000-01-01".
195194
196195
If the command is being run from a working check-out (not against a bare
197196
repository) then a few extra tags apply. The "current" tag means the
198197
current check-out. The "next" tag means the youngest child of the
199
-current check-out. And the "previous" tag means the primary (non-merge)
200
-parent of the current check-out.
198
+current check-out. And the "previous" or "prev" tag means the primary
199
+(non-merge) parent of the current check-out.
201200
202201
<h2>Additional Examples</h2>
203202
204203
To view the changes in the most recent check-in prior to the version currently
205204
checked out:
206205
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -14,12 +14,11 @@
14 <li> Special names:
15 <ul>
16 <li> <b>tip</b>
17 <li> <b>current</b>
18 <li> <b>next</b>
19 <li> <b>previous</b>
20 <li> <b>ckout</b>
21 </ul>
22 </ul>
23 </td></tr>
24 </table>
25 Many Fossil [/help|commands] and [./webui.wiki | web-interface] URLs accept
@@ -194,12 +193,12 @@
194 equivalent to the timestamp tag "5000-01-01".
195
196 If the command is being run from a working check-out (not against a bare
197 repository) then a few extra tags apply. The "current" tag means the
198 current check-out. The "next" tag means the youngest child of the
199 current check-out. And the "previous" tag means the primary (non-merge)
200 parent of the current check-out.
201
202 <h2>Additional Examples</h2>
203
204 To view the changes in the most recent check-in prior to the version currently
205 checked out:
206
--- www/checkin_names.wiki
+++ www/checkin_names.wiki
@@ -14,12 +14,11 @@
14 <li> Special names:
15 <ul>
16 <li> <b>tip</b>
17 <li> <b>current</b>
18 <li> <b>next</b>
19 <li> <b>previous</b> or <b>prev</b>
 
20 </ul>
21 </ul>
22 </td></tr>
23 </table>
24 Many Fossil [/help|commands] and [./webui.wiki | web-interface] URLs accept
@@ -194,12 +193,12 @@
193 equivalent to the timestamp tag "5000-01-01".
194
195 If the command is being run from a working check-out (not against a bare
196 repository) then a few extra tags apply. The "current" tag means the
197 current check-out. The "next" tag means the youngest child of the
198 current check-out. And the "previous" or "prev" tag means the primary
199 (non-merge) parent of the current check-out.
200
201 <h2>Additional Examples</h2>
202
203 To view the changes in the most recent check-in prior to the version currently
204 checked out:
205
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -75,8 +75,8 @@
7575
the checklist and/or the automated test scripts to cover their additions.
7676
7777
7878
<h2>5.0 See Also</h2>
7979
80
- * [./build.wiki | How To Build And Install Fossil]
80
+ * [./build.wiki | How To Compile And Install Fossil]
8181
* [./makefile.wiki | The Fossil Build Process]
8282
* [./tech_overview.wiki | A Technical Overview of Fossil]
8383
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -75,8 +75,8 @@
75 the checklist and/or the automated test scripts to cover their additions.
76
77
78 <h2>5.0 See Also</h2>
79
80 * [./build.wiki | How To Build And Install Fossil]
81 * [./makefile.wiki | The Fossil Build Process]
82 * [./tech_overview.wiki | A Technical Overview of Fossil]
83
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -75,8 +75,8 @@
75 the checklist and/or the automated test scripts to cover their additions.
76
77
78 <h2>5.0 See Also</h2>
79
80 * [./build.wiki | How To Compile And Install Fossil]
81 * [./makefile.wiki | The Fossil Build Process]
82 * [./tech_overview.wiki | A Technical Overview of Fossil]
83
+1 -1
--- www/index.wiki
+++ www/index.wiki
@@ -115,11 +115,11 @@
115115
[./quotes.wiki | Quotes] about Fossil and other DVCSes.
116116
* [./faq.wiki | FAQ]
117117
* The [./concepts.wiki | concepts] behind fossil
118118
* [./quickstart.wiki | Quick Start] guide to using fossil
119119
* [./qandc.wiki | Questions &amp; Criticisms] directed at fossil.
120
- * [./build.wiki | Building And Installing]
120
+ * [./build.wiki | Compiling and Installing]
121121
* Fossil supports [./embeddeddoc.wiki | embedded documentation]
122122
that is versioned along with project source code.
123123
* Fossil uses an [./fileformat.wiki | enduring file format] that is
124124
designed to be readable, searchable, and extensible by people
125125
not yet born.
126126
--- www/index.wiki
+++ www/index.wiki
@@ -115,11 +115,11 @@
115 [./quotes.wiki | Quotes] about Fossil and other DVCSes.
116 * [./faq.wiki | FAQ]
117 * The [./concepts.wiki | concepts] behind fossil
118 * [./quickstart.wiki | Quick Start] guide to using fossil
119 * [./qandc.wiki | Questions &amp; Criticisms] directed at fossil.
120 * [./build.wiki | Building And Installing]
121 * Fossil supports [./embeddeddoc.wiki | embedded documentation]
122 that is versioned along with project source code.
123 * Fossil uses an [./fileformat.wiki | enduring file format] that is
124 designed to be readable, searchable, and extensible by people
125 not yet born.
126
--- www/index.wiki
+++ www/index.wiki
@@ -115,11 +115,11 @@
115 [./quotes.wiki | Quotes] about Fossil and other DVCSes.
116 * [./faq.wiki | FAQ]
117 * The [./concepts.wiki | concepts] behind fossil
118 * [./quickstart.wiki | Quick Start] guide to using fossil
119 * [./qandc.wiki | Questions &amp; Criticisms] directed at fossil.
120 * [./build.wiki | Compiling and Installing]
121 * Fossil supports [./embeddeddoc.wiki | embedded documentation]
122 that is versioned along with project source code.
123 * Fossil uses an [./fileformat.wiki | enduring file format] that is
124 designed to be readable, searchable, and extensible by people
125 not yet born.
126
+2 -2
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -7,11 +7,11 @@
77
#
88
99
set doclist {
1010
bugtheory.wiki {Bug Tracking In Fossil}
1111
branching.wiki {Branching, Forking, Merging, and Tagging}
12
- build.wiki {Building and Installing Fossil}
12
+ build.wiki {Compiling and Installing Fossil}
1313
checkin_names.wiki {Checkin And Version Names}
1414
checkin.wiki {Check-in Checklist}
1515
changes.wiki {Fossil Changelog}
1616
copyright-release.html {Contributor License Agreement}
1717
concepts.wiki {Fossil Core Concepts}
@@ -77,11 +77,11 @@
7777
puts $out {
7878
<h2>Primary Documents:</h2>
7979
<ul>
8080
<li> [./quickstart.wiki | Quick-start Guide]
8181
<li> [./faq.wiki | FAQ]
82
-<li> [./build.wiki | Building and installing Fossil]
82
+<li> [./build.wiki | Compiling and installing Fossil]
8383
<li> [../COPYRIGHT-BSD2.txt | License]
8484
<li> [http://www.fossil-scm.org/schimpf-book/home | Jim Schimpf's book]
8585
<li> [/help | Command-line help]
8686
</ul>
8787
<a name="pindex"></a>
8888
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -7,11 +7,11 @@
7 #
8
9 set doclist {
10 bugtheory.wiki {Bug Tracking In Fossil}
11 branching.wiki {Branching, Forking, Merging, and Tagging}
12 build.wiki {Building and Installing Fossil}
13 checkin_names.wiki {Checkin And Version Names}
14 checkin.wiki {Check-in Checklist}
15 changes.wiki {Fossil Changelog}
16 copyright-release.html {Contributor License Agreement}
17 concepts.wiki {Fossil Core Concepts}
@@ -77,11 +77,11 @@
77 puts $out {
78 <h2>Primary Documents:</h2>
79 <ul>
80 <li> [./quickstart.wiki | Quick-start Guide]
81 <li> [./faq.wiki | FAQ]
82 <li> [./build.wiki | Building and installing Fossil]
83 <li> [../COPYRIGHT-BSD2.txt | License]
84 <li> [http://www.fossil-scm.org/schimpf-book/home | Jim Schimpf's book]
85 <li> [/help | Command-line help]
86 </ul>
87 <a name="pindex"></a>
88
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -7,11 +7,11 @@
7 #
8
9 set doclist {
10 bugtheory.wiki {Bug Tracking In Fossil}
11 branching.wiki {Branching, Forking, Merging, and Tagging}
12 build.wiki {Compiling and Installing Fossil}
13 checkin_names.wiki {Checkin And Version Names}
14 checkin.wiki {Check-in Checklist}
15 changes.wiki {Fossil Changelog}
16 copyright-release.html {Contributor License Agreement}
17 concepts.wiki {Fossil Core Concepts}
@@ -77,11 +77,11 @@
77 puts $out {
78 <h2>Primary Documents:</h2>
79 <ul>
80 <li> [./quickstart.wiki | Quick-start Guide]
81 <li> [./faq.wiki | FAQ]
82 <li> [./build.wiki | Compiling and installing Fossil]
83 <li> [../COPYRIGHT-BSD2.txt | License]
84 <li> [http://www.fossil-scm.org/schimpf-book/home | Jim Schimpf's book]
85 <li> [/help | Command-line help]
86 </ul>
87 <a name="pindex"></a>
88
--- www/permutedindex.wiki
+++ www/permutedindex.wiki
@@ -2,11 +2,11 @@
22
33
<h2>Primary Documents:</h2>
44
<ul>
55
<li> [./quickstart.wiki | Quick-start Guide]
66
<li> [./faq.wiki | FAQ]
7
-<li> [./build.wiki | Building and installing Fossil]
7
+<li> [./build.wiki | Compiling and installing Fossil]
88
<li> [../COPYRIGHT-BSD2.txt | License]
99
<li> [http://www.fossil-scm.org/schimpf-book/home | Jim Schimpf's book]
1010
<li> [/help | Command-line help]
1111
</ul>
1212
<a name="pindex"></a>
@@ -19,20 +19,20 @@
1919
<li><a href="password.wiki">Authentication &mdash; Password Management And</a></li>
2020
<li><a href="private.wiki">Branches &mdash; Creating, Syncing, and Deleting Private</a></li>
2121
<li><a href="branching.wiki">Branching, Forking, Merging, and Tagging</a></li>
2222
<li><a href="bugtheory.wiki">Bug Tracking In Fossil</a></li>
2323
<li><a href="makefile.wiki">Build Process &mdash; The Fossil</a></li>
24
-<li><a href="build.wiki">Building and Installing Fossil</a></li>
2524
<li><a href="changes.wiki">Changelog &mdash; Fossil</a></li>
2625
<li><a href="checkin.wiki">Check-in Checklist</a></li>
2726
<li><a href="checkin_names.wiki">Checkin And Version Names</a></li>
2827
<li><a href="checkin.wiki">Checklist &mdash; Check-in</a></li>
2928
<li><a href="../test/release-checklist.wiki">Checklist &mdash; Pre-Release Testing</a></li>
3029
<li><a href="foss-cklist.wiki">Checklist For Successful Open-Source Projects</a></li>
3130
<li><a href="selfcheck.wiki">Checks &mdash; Fossil Repository Integrity Self</a></li>
3231
<li><a href="contribute.wiki">Code or Documentation To The Fossil Project &mdash; Contributing</a></li>
3332
<li><a href="style.wiki">Code Style Guidelines &mdash; Source</a></li>
33
+<li><a href="build.wiki">Compiling and Installing Fossil</a></li>
3434
<li><a href="concepts.wiki">Concepts &mdash; Fossil Core</a></li>
3535
<li><a href="server.wiki">Configure A Fossil Server &mdash; How To</a></li>
3636
<li><a href="shunning.wiki">Content From Fossil &mdash; Shunning: Deleting</a></li>
3737
<li><a href="contribute.wiki">Contributing Code or Documentation To The Fossil Project</a></li>
3838
<li><a href="copyright-release.html">Contributor License Agreement</a></li>
@@ -84,11 +84,11 @@
8484
<li><a href="selfhost.wiki">Hosting Repositories &mdash; Fossil Self</a></li>
8585
<li><a href="server.wiki">How To Configure A Fossil Server</a></li>
8686
<li><a href="newrepo.wiki">How To Create A New Fossil Repository</a></li>
8787
<li><a href="tech_overview.wiki">Implementation Of Fossil &mdash; A Technical Overview Of The Design And</a></li>
8888
<li><a href="inout.wiki">Import And Export To And From Git</a></li>
89
-<li><a href="build.wiki">Installing Fossil &mdash; Building and</a></li>
89
+<li><a href="build.wiki">Installing Fossil &mdash; Compiling and</a></li>
9090
<li><a href="selfcheck.wiki">Integrity Self Checks &mdash; Fossil Repository</a></li>
9191
<li><a href="webui.wiki">Interface &mdash; The Fossil Web</a></li>
9292
<li><a href="copyright-release.html">License Agreement &mdash; Contributor</a></li>
9393
<li><a href="password.wiki">Management And Authentication &mdash; Password</a></li>
9494
<li><a href="branching.wiki">Merging, and Tagging &mdash; Branching, Forking,</a></li>
9595
--- www/permutedindex.wiki
+++ www/permutedindex.wiki
@@ -2,11 +2,11 @@
2
3 <h2>Primary Documents:</h2>
4 <ul>
5 <li> [./quickstart.wiki | Quick-start Guide]
6 <li> [./faq.wiki | FAQ]
7 <li> [./build.wiki | Building and installing Fossil]
8 <li> [../COPYRIGHT-BSD2.txt | License]
9 <li> [http://www.fossil-scm.org/schimpf-book/home | Jim Schimpf's book]
10 <li> [/help | Command-line help]
11 </ul>
12 <a name="pindex"></a>
@@ -19,20 +19,20 @@
19 <li><a href="password.wiki">Authentication &mdash; Password Management And</a></li>
20 <li><a href="private.wiki">Branches &mdash; Creating, Syncing, and Deleting Private</a></li>
21 <li><a href="branching.wiki">Branching, Forking, Merging, and Tagging</a></li>
22 <li><a href="bugtheory.wiki">Bug Tracking In Fossil</a></li>
23 <li><a href="makefile.wiki">Build Process &mdash; The Fossil</a></li>
24 <li><a href="build.wiki">Building and Installing Fossil</a></li>
25 <li><a href="changes.wiki">Changelog &mdash; Fossil</a></li>
26 <li><a href="checkin.wiki">Check-in Checklist</a></li>
27 <li><a href="checkin_names.wiki">Checkin And Version Names</a></li>
28 <li><a href="checkin.wiki">Checklist &mdash; Check-in</a></li>
29 <li><a href="../test/release-checklist.wiki">Checklist &mdash; Pre-Release Testing</a></li>
30 <li><a href="foss-cklist.wiki">Checklist For Successful Open-Source Projects</a></li>
31 <li><a href="selfcheck.wiki">Checks &mdash; Fossil Repository Integrity Self</a></li>
32 <li><a href="contribute.wiki">Code or Documentation To The Fossil Project &mdash; Contributing</a></li>
33 <li><a href="style.wiki">Code Style Guidelines &mdash; Source</a></li>
 
34 <li><a href="concepts.wiki">Concepts &mdash; Fossil Core</a></li>
35 <li><a href="server.wiki">Configure A Fossil Server &mdash; How To</a></li>
36 <li><a href="shunning.wiki">Content From Fossil &mdash; Shunning: Deleting</a></li>
37 <li><a href="contribute.wiki">Contributing Code or Documentation To The Fossil Project</a></li>
38 <li><a href="copyright-release.html">Contributor License Agreement</a></li>
@@ -84,11 +84,11 @@
84 <li><a href="selfhost.wiki">Hosting Repositories &mdash; Fossil Self</a></li>
85 <li><a href="server.wiki">How To Configure A Fossil Server</a></li>
86 <li><a href="newrepo.wiki">How To Create A New Fossil Repository</a></li>
87 <li><a href="tech_overview.wiki">Implementation Of Fossil &mdash; A Technical Overview Of The Design And</a></li>
88 <li><a href="inout.wiki">Import And Export To And From Git</a></li>
89 <li><a href="build.wiki">Installing Fossil &mdash; Building and</a></li>
90 <li><a href="selfcheck.wiki">Integrity Self Checks &mdash; Fossil Repository</a></li>
91 <li><a href="webui.wiki">Interface &mdash; The Fossil Web</a></li>
92 <li><a href="copyright-release.html">License Agreement &mdash; Contributor</a></li>
93 <li><a href="password.wiki">Management And Authentication &mdash; Password</a></li>
94 <li><a href="branching.wiki">Merging, and Tagging &mdash; Branching, Forking,</a></li>
95
--- www/permutedindex.wiki
+++ www/permutedindex.wiki
@@ -2,11 +2,11 @@
2
3 <h2>Primary Documents:</h2>
4 <ul>
5 <li> [./quickstart.wiki | Quick-start Guide]
6 <li> [./faq.wiki | FAQ]
7 <li> [./build.wiki | Compiling and installing Fossil]
8 <li> [../COPYRIGHT-BSD2.txt | License]
9 <li> [http://www.fossil-scm.org/schimpf-book/home | Jim Schimpf's book]
10 <li> [/help | Command-line help]
11 </ul>
12 <a name="pindex"></a>
@@ -19,20 +19,20 @@
19 <li><a href="password.wiki">Authentication &mdash; Password Management And</a></li>
20 <li><a href="private.wiki">Branches &mdash; Creating, Syncing, and Deleting Private</a></li>
21 <li><a href="branching.wiki">Branching, Forking, Merging, and Tagging</a></li>
22 <li><a href="bugtheory.wiki">Bug Tracking In Fossil</a></li>
23 <li><a href="makefile.wiki">Build Process &mdash; The Fossil</a></li>
 
24 <li><a href="changes.wiki">Changelog &mdash; Fossil</a></li>
25 <li><a href="checkin.wiki">Check-in Checklist</a></li>
26 <li><a href="checkin_names.wiki">Checkin And Version Names</a></li>
27 <li><a href="checkin.wiki">Checklist &mdash; Check-in</a></li>
28 <li><a href="../test/release-checklist.wiki">Checklist &mdash; Pre-Release Testing</a></li>
29 <li><a href="foss-cklist.wiki">Checklist For Successful Open-Source Projects</a></li>
30 <li><a href="selfcheck.wiki">Checks &mdash; Fossil Repository Integrity Self</a></li>
31 <li><a href="contribute.wiki">Code or Documentation To The Fossil Project &mdash; Contributing</a></li>
32 <li><a href="style.wiki">Code Style Guidelines &mdash; Source</a></li>
33 <li><a href="build.wiki">Compiling and Installing Fossil</a></li>
34 <li><a href="concepts.wiki">Concepts &mdash; Fossil Core</a></li>
35 <li><a href="server.wiki">Configure A Fossil Server &mdash; How To</a></li>
36 <li><a href="shunning.wiki">Content From Fossil &mdash; Shunning: Deleting</a></li>
37 <li><a href="contribute.wiki">Contributing Code or Documentation To The Fossil Project</a></li>
38 <li><a href="copyright-release.html">Contributor License Agreement</a></li>
@@ -84,11 +84,11 @@
84 <li><a href="selfhost.wiki">Hosting Repositories &mdash; Fossil Self</a></li>
85 <li><a href="server.wiki">How To Configure A Fossil Server</a></li>
86 <li><a href="newrepo.wiki">How To Create A New Fossil Repository</a></li>
87 <li><a href="tech_overview.wiki">Implementation Of Fossil &mdash; A Technical Overview Of The Design And</a></li>
88 <li><a href="inout.wiki">Import And Export To And From Git</a></li>
89 <li><a href="build.wiki">Installing Fossil &mdash; Compiling and</a></li>
90 <li><a href="selfcheck.wiki">Integrity Self Checks &mdash; Fossil Repository</a></li>
91 <li><a href="webui.wiki">Interface &mdash; The Fossil Web</a></li>
92 <li><a href="copyright-release.html">License Agreement &mdash; Contributor</a></li>
93 <li><a href="password.wiki">Management And Authentication &mdash; Password</a></li>
94 <li><a href="branching.wiki">Merging, and Tagging &mdash; Branching, Forking,</a></li>
95
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -7,11 +7,11 @@
77
<h2>Installing</h2>
88
99
<p>Fossil is a single self-contained C program. You need to
1010
either download a
1111
<a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
12
- or <a href="build.wiki">build it yourself</a> from sources.
12
+ or <a href="build.wiki">compile it yourself</a> from sources.
1313
Install fossil by putting the fossil binary
1414
someplace on your $PATH.</p>
1515
1616
<a name="fslclone"></a>
1717
<h2>General Work Flow</h2>
1818
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -7,11 +7,11 @@
7 <h2>Installing</h2>
8
9 <p>Fossil is a single self-contained C program. You need to
10 either download a
11 <a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
12 or <a href="build.wiki">build it yourself</a> from sources.
13 Install fossil by putting the fossil binary
14 someplace on your $PATH.</p>
15
16 <a name="fslclone"></a>
17 <h2>General Work Flow</h2>
18
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -7,11 +7,11 @@
7 <h2>Installing</h2>
8
9 <p>Fossil is a single self-contained C program. You need to
10 either download a
11 <a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
12 or <a href="build.wiki">compile it yourself</a> from sources.
13 Install fossil by putting the fossil binary
14 someplace on your $PATH.</p>
15
16 <a name="fslclone"></a>
17 <h2>General Work Flow</h2>
18

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button