Check-in [626a317e5c]
Not logged in

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

Overview
SHA1 Hash:626a317e5cea1ff0819994ad2c2a6fdd869bb0c1
Date: 2012-04-19 14:34:59
User: martin.weber
Comment:Catch up w/ trunk & document --case-sensitive option in the add and addremove commands.
Tags And Properties
Changes

Changes to src/add.c

194 194 ** the "--dotfiles" option to the command-line. 195 195 ** 196 196 ** The --ignore option is a comma-separate list of glob patterns for files 197 197 ** to be excluded. Example: '*.o,*.obj,*.exe' If the --ignore option 198 198 ** does not appear on the command line then the "ignore-glob" setting is 199 199 ** used. 200 200 ** 201 +** The --case-sensitive option determines whether or not filenames should 202 +** be treated case sensitive or not. If the option is not given, the default 203 +** depends on the global setting, or the operating system default, if not set. 204 +** 201 205 ** Options: 202 206 ** 203 -** --dotfiles include files beginning with a dot (".") 204 -** --ignore <CSG> ignore files matching patterns from the 205 -** comma separated list of glob patterns. 207 +** --case-sensitive <BOOL> override case-sensitive setting 208 +** --dotfiles include files beginning with a dot (".") 209 +** --ignore <CSG> ignore files matching patterns from the 210 +** comma separated list of glob patterns. 206 211 ** 207 212 ** See also: addremove, rm 208 213 */ 209 214 void add_cmd(void){ 210 215 int i; /* Loop counter */ 211 216 int vid; /* Currently checked out version */ 212 217 int nRoot; /* Full path characters in g.zLocalRoot */ ................................................................................ 406 411 ** 407 412 ** The command does not "commit". You must run the "commit" separately 408 413 ** as a separate step. 409 414 ** 410 415 ** Files and directories whose names begin with "." are ignored unless 411 416 ** the --dotfiles option is used. 412 417 ** 413 -** The --ignore option overrides the "ignore-glob" setting. See 418 +** The --ignore option overrides the "ignore-glob" setting, as does the 419 +** --case-sensitive option with the "case-sensitive" setting. See the 414 420 ** documentation on the "settings" command for further information. 415 421 ** 416 422 ** The --test option shows what would happen without actually doing anything. 417 423 ** 418 424 ** This command can be used to track third party software. 419 425 ** 420 426 ** Options: 421 -** --dotfiles include files beginning with a dot (".") 422 -** --ignore <CSG> ignore files matching patterns from the 423 -** comma separated list of glob patterns. 424 -** --test If given, show what would be done without doing so. 427 +** --case-sensitive <BOOL> override case-sensitive setting 428 +** --dotfiles include files beginning with a dot (".") 429 +** --ignore <CSG> ignore files matching patterns from the 430 +** comma separated list of glob patterns. 431 +** --test If given, display instead of run actions 425 432 ** 426 433 ** See also: add, rm 427 434 */ 428 435 void addremove_cmd(void){ 429 436 Blob path; 430 437 const char *zIgnoreFlag = find_option("ignore",0,1); 431 438 int allFlag = find_option("dotfiles",0,0)!=0;

Changes to src/attach.c

236 236 Blob manifest; 237 237 Blob cksum; 238 238 char *zUUID; 239 239 const char *zComment; 240 240 char *zDate; 241 241 int rid; 242 242 int i, n; 243 + int addCompress = 0; 244 + Manifest *pManifest; 243 245 244 246 db_begin_transaction(); 245 247 blob_init(&content, aContent, szContent); 248 + pManifest = manifest_parse(&content, 0); 249 + manifest_destroy(pManifest); 250 + blob_init(&content, aContent, szContent); 251 + if( pManifest ){ 252 + blob_compress(&content, &content); 253 + addCompress = 1; 254 + } 246 255 rid = content_put(&content); 247 256 zUUID = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); 248 257 blob_zero(&manifest); 249 258 for(i=n=0; zName[i]; i++){ 250 259 if( zName[i]=='/' || zName[i]=='\\' ) n = i; 251 260 } 252 261 zName += n; 253 262 if( zName[0]==0 ) zName = "unknown"; 254 - blob_appendf(&manifest, "A %F %F %s\n", zName, zTarget, zUUID); 263 + blob_appendf(&manifest, "A %F%s %F %s\n", 264 + zName, addCompress ? ".gz" : "", zTarget, zUUID); 255 265 zComment = PD("comment", ""); 256 266 while( fossil_isspace(zComment[0]) ) zComment++; 257 267 n = strlen(zComment); 258 268 while( n>0 && fossil_isspace(zComment[n-1]) ){ n--; } 259 269 if( n>0 ){ 260 270 blob_appendf(&manifest, "C %F\n", zComment); 261 271 }

Changes to src/login.c

383 383 /* 384 384 ** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent 385 385 ** is a manually operated browser or a bot. When in doubt, assume a bot. 386 386 ** Return true if we believe the agent is a real person. 387 387 */ 388 388 static int isHuman(const char *zAgent){ 389 389 int i; 390 - if( zAgent==0 ) return 0; /* If not UserAgent, the probably a bot */ 390 + if( zAgent==0 ) return 0; /* If not UserAgent, then probably a bot */ 391 391 for(i=0; zAgent[i]; i++){ 392 392 if( prefix_match("bot", zAgent+i) ) return 0; 393 393 if( prefix_match("spider", zAgent+i) ) return 0; 394 394 if( prefix_match("crawl", zAgent+i) ) return 0; 395 395 /* If a URI appears in the User-Agent, it is probably a bot */ 396 396 if( memcmp("http", zAgent+i,4)==0 ) return 0; 397 397 }

Changes to src/manifest.c

332 332 ** The file consists of zero or more cards, one card per line. 333 333 ** (Except: the content of the W card can extend of multiple lines.) 334 334 ** Each card is divided into tokens by a single space character. 335 335 ** The first token is a single upper-case letter which is the card type. 336 336 ** The card type determines the other parameters to the card. 337 337 ** Cards must occur in lexicographical order. 338 338 */ 339 -static Manifest *manifest_parse(Blob *pContent, int rid){ 339 +Manifest *manifest_parse(Blob *pContent, int rid){ 340 340 Manifest *p; 341 341 int seenZ = 0; 342 342 int i, lineNo=0; 343 343 ManifestText x; 344 344 char cPrevType = 0; 345 345 char cType; 346 346 char *z; 347 347 int n; 348 348 char *zUuid; 349 349 int sz = 0; 350 350 int isRepeat; 351 351 static Bag seen; 352 352 353 - if( bag_find(&seen, rid) ){ 353 + if( rid==0 ){ 354 + isRepeat = 1; 355 + }else if( bag_find(&seen, rid) ){ 354 356 isRepeat = 1; 355 357 }else{ 356 358 isRepeat = 0; 357 359 bag_insert(&seen, rid); 358 360 } 359 361 360 362 /* Every control artifact ends with a '\n' character. Exit early

Changes to src/shell.c

417 417 */ 418 418 struct callback_data { 419 419 sqlite3 *db; /* The database */ 420 420 int echoOn; /* True to echo input commands */ 421 421 int statsOn; /* True to display memory stats before each finalize */ 422 422 int cnt; /* Number of records displayed so far */ 423 423 FILE *out; /* Write results here */ 424 + FILE *traceOut; /* Output for sqlite3_trace() */ 424 425 int nErr; /* Number of errors seen */ 425 426 int mode; /* An output mode setting */ 426 427 int writableSchema; /* True if PRAGMA writable_schema=ON */ 427 428 int showHeader; /* True to show column names in List or Column mode */ 428 429 char *zDestTable; /* Name of destination table when MODE_Insert */ 429 430 char separator[20]; /* Separator character for MODE_List */ 430 431 int colWidth[100]; /* Requested width of each column when in column mode*/ ................................................................................ 1305 1306 1306 1307 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0); 1307 1308 /* Always quote the table name, even if it appears to be pure ascii, 1308 1309 ** in case it is a keyword. Ex: INSERT INTO "table" ... */ 1309 1310 zTmp = appendText(zTmp, zTable, '"'); 1310 1311 if( zTmp ){ 1311 1312 zSelect = appendText(zSelect, zTmp, '\''); 1313 + free(zTmp); 1312 1314 } 1313 1315 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0); 1314 1316 rc = sqlite3_step(pTableInfo); 1315 1317 while( rc==SQLITE_ROW ){ 1316 1318 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1); 1317 1319 zSelect = appendText(zSelect, "quote(", 0); 1318 1320 zSelect = appendText(zSelect, zText, '"'); ................................................................................ 1333 1335 zSelect = appendText(zSelect, zTable, '"'); 1334 1336 1335 1337 rc = run_table_dump_query(p, zSelect, zPrepStmt); 1336 1338 if( rc==SQLITE_CORRUPT ){ 1337 1339 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0); 1338 1340 run_table_dump_query(p, zSelect, 0); 1339 1341 } 1340 - if( zSelect ) free(zSelect); 1342 + free(zSelect); 1341 1343 } 1342 1344 return 0; 1343 1345 } 1344 1346 1345 1347 /* 1346 1348 ** Run zQuery. Use dump_callback() as the callback routine so that 1347 1349 ** the contents of the query are output as SQL statements. ................................................................................ 1363 1365 if( zErr ){ 1364 1366 fprintf(p->out, "/****** %s ******/\n", zErr); 1365 1367 sqlite3_free(zErr); 1366 1368 zErr = 0; 1367 1369 } 1368 1370 zQ2 = malloc( len+100 ); 1369 1371 if( zQ2==0 ) return rc; 1370 - sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery); 1372 + sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery); 1371 1373 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); 1372 1374 if( rc ){ 1373 1375 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr); 1374 1376 }else{ 1375 1377 rc = SQLITE_CORRUPT; 1376 1378 } 1377 1379 sqlite3_free(zErr); ................................................................................ 1429 1431 ".separator STRING Change separator used by output mode and .import\n" 1430 1432 ".show Show the current values for various settings\n" 1431 1433 ".stats ON|OFF Turn stats on or off\n" 1432 1434 ".tables ?TABLE? List names of tables\n" 1433 1435 " If TABLE specified, only list tables matching\n" 1434 1436 " LIKE pattern TABLE.\n" 1435 1437 ".timeout MS Try opening locked tables for MS milliseconds\n" 1438 + ".trace FILE|off Output each SQL statement as it is run\n" 1436 1439 ".vfsname ?AUX? Print the name of the VFS stack\n" 1437 1440 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" 1438 1441 ; 1439 1442 1440 1443 static char zTimerHelp[] = 1441 1444 ".timer ON|OFF Turn the CPU timer measurement on or off\n" 1442 1445 ; ................................................................................ 1517 1520 if( strcmp(zArg,"on")==0 ){ 1518 1521 val = 1; 1519 1522 }else if( strcmp(zArg,"yes")==0 ){ 1520 1523 val = 1; 1521 1524 } 1522 1525 return val; 1523 1526 } 1527 + 1528 +/* 1529 +** Close an output file, assuming it is not stderr or stdout 1530 +*/ 1531 +static void output_file_close(FILE *f){ 1532 + if( f && f!=stdout && f!=stderr ) fclose(f); 1533 +} 1534 + 1535 +/* 1536 +** Try to open an output file. The names "stdout" and "stderr" are 1537 +** recognized and do the right thing. NULL is returned if the output 1538 +** filename is "off". 1539 +*/ 1540 +static FILE *output_file_open(const char *zFile){ 1541 + FILE *f; 1542 + if( strcmp(zFile,"stdout")==0 ){ 1543 + f = stdout; 1544 + }else if( strcmp(zFile, "stderr")==0 ){ 1545 + f = stderr; 1546 + }else if( strcmp(zFile, "off")==0 ){ 1547 + f = 0; 1548 + }else{ 1549 + f = fopen(zFile, "wb"); 1550 + if( f==0 ){ 1551 + fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); 1552 + } 1553 + } 1554 + return f; 1555 +} 1556 + 1557 +/* 1558 +** A routine for handling output from sqlite3_trace(). 1559 +*/ 1560 +static void sql_trace_callback(void *pArg, const char *z){ 1561 + FILE *f = (FILE*)pArg; 1562 + if( f ) fprintf(f, "%s\n", z); 1563 +} 1564 + 1565 +/* 1566 +** A no-op routine that runs with the ".breakpoint" doc-command. This is 1567 +** a useful spot to set a debugger breakpoint. 1568 +*/ 1569 +static void test_breakpoint(void){ 1570 + static int nCall = 0; 1571 + nCall++; 1572 +} 1524 1573 1525 1574 /* 1526 1575 ** If an input line begins with "." then invoke this routine to 1527 1576 ** process that line. 1528 1577 ** 1529 1578 ** Return 1 on error, 2 to exit, and 0 otherwise. 1530 1579 */ ................................................................................ 1596 1645 } 1597 1646 sqlite3_close(pDest); 1598 1647 }else 1599 1648 1600 1649 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){ 1601 1650 bail_on_error = booleanValue(azArg[1]); 1602 1651 }else 1652 + 1653 + /* The undocumented ".breakpoint" command causes a call to the no-op 1654 + ** routine named test_breakpoint(). 1655 + */ 1656 + if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){ 1657 + test_breakpoint(); 1658 + }else 1603 1659 1604 1660 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){ 1605 1661 struct callback_data data; 1606 1662 char *zErrMsg = 0; 1607 1663 open_db(p); 1608 1664 memcpy(&data, p, sizeof(data)); 1609 1665 data.showHeader = 1; ................................................................................ 1928 1984 rc = 1; 1929 1985 } 1930 1986 }else 1931 1987 #endif 1932 1988 1933 1989 if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){ 1934 1990 const char *zFile = azArg[1]; 1935 - if( p->pLog && p->pLog!=stdout && p->pLog!=stderr ){ 1936 - fclose(p->pLog); 1937 - p->pLog = 0; 1938 - } 1939 - if( strcmp(zFile,"stdout")==0 ){ 1940 - p->pLog = stdout; 1941 - }else if( strcmp(zFile, "stderr")==0 ){ 1942 - p->pLog = stderr; 1943 - }else if( strcmp(zFile, "off")==0 ){ 1944 - p->pLog = 0; 1945 - }else{ 1946 - p->pLog = fopen(zFile, "w"); 1947 - if( p->pLog==0 ){ 1948 - fprintf(stderr, "Error: cannot open \"%s\"\n", zFile); 1949 - } 1950 - } 1991 + output_file_close(p->pLog); 1992 + p->pLog = output_file_open(zFile); 1951 1993 }else 1952 1994 1953 1995 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){ 1954 1996 int n2 = strlen30(azArg[1]); 1955 1997 if( (n2==4 && strncmp(azArg[1],"line",n2)==0) 1956 1998 || 1957 1999 (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){ ................................................................................ 1996 2038 1997 2039 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) { 1998 2040 sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue, 1999 2041 "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); 2000 2042 }else 2001 2043 2002 2044 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){ 2003 - if( p->out!=stdout ){ 2004 - if( p->outfile[0]=='|' ){ 2005 - pclose(p->out); 2006 - }else{ 2007 - fclose(p->out); 2008 - } 2045 + if( p->outfile[0]=='|' ){ 2046 + pclose(p->out); 2047 + }else{ 2048 + output_file_close(p->out); 2009 2049 } 2010 - if( strcmp(azArg[1],"stdout")==0 ){ 2011 - p->out = stdout; 2012 - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout"); 2013 - }else if( azArg[1][0]=='|' ){ 2050 + p->outfile[0] = 0; 2051 + if( azArg[1][0]=='|' ){ 2014 2052 p->out = popen(&azArg[1][1], "w"); 2015 2053 if( p->out==0 ){ 2016 2054 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]); 2017 2055 p->out = stdout; 2018 2056 rc = 1; 2019 2057 }else{ 2020 2058 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); 2021 2059 } 2022 2060 }else{ 2023 - p->out = fopen(azArg[1], "wb"); 2061 + p->out = output_file_open(azArg[1]); 2024 2062 if( p->out==0 ){ 2025 - fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]); 2063 + if( strcmp(azArg[1],"off")!=0 ){ 2064 + fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]); 2065 + } 2026 2066 p->out = stdout; 2027 2067 rc = 1; 2028 2068 } else { 2029 - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); 2069 + sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); 2030 2070 } 2031 2071 } 2032 2072 }else 2033 2073 2034 2074 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){ 2035 2075 if( nArg >= 2) { 2036 2076 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); ................................................................................ 2392 2432 2393 2433 if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 2394 2434 && nArg==2 2395 2435 ){ 2396 2436 enableTimer = booleanValue(azArg[1]); 2397 2437 }else 2398 2438 2439 + if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){ 2440 + output_file_close(p->traceOut); 2441 + p->traceOut = output_file_open(azArg[1]); 2442 +#ifndef SQLITE_OMIT_TRACE 2443 + if( p->traceOut==0 ){ 2444 + sqlite3_trace(p->db, 0, 0); 2445 + }else{ 2446 + sqlite3_trace(p->db, sql_trace_callback, p->traceOut); 2447 + } 2448 +#endif 2449 + }else 2450 + 2399 2451 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ 2400 2452 printf("SQLite %s %s\n" /*extra-version-info*/, 2401 2453 sqlite3_libversion(), sqlite3_sourceid()); 2402 2454 }else 2403 2455 2404 2456 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ 2405 2457 const char *zDbName = nArg==2 ? azArg[1] : "main"; ................................................................................ 2603 2655 } 2604 2656 free(zLine); 2605 2657 return errCnt; 2606 2658 } 2607 2659 2608 2660 /* 2609 2661 ** Return a pathname which is the user's home directory. A 2610 -** 0 return indicates an error of some kind. Space to hold the 2611 -** resulting string is obtained from malloc(). The calling 2612 -** function should free the result. 2662 +** 0 return indicates an error of some kind. 2613 2663 */ 2614 2664 static char *find_home_dir(void){ 2615 - char *home_dir = NULL; 2665 + static char *home_dir = NULL; 2666 + if( home_dir ) return home_dir; 2616 2667 2617 2668 #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL) 2618 2669 struct passwd *pwent; 2619 2670 uid_t uid = getuid(); 2620 2671 if( (pwent=getpwuid(uid)) != NULL) { 2621 2672 home_dir = pwent->pw_dir; 2622 2673 } 2623 2674 #endif 2624 2675 2625 2676 #if defined(_WIN32_WCE) 2626 2677 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() 2627 2678 */ 2628 - home_dir = strdup("/"); 2679 + home_dir = "/"; 2629 2680 #else 2630 2681 2631 2682 #if defined(_WIN32) || defined(WIN32) || defined(__OS2__) 2632 2683 if (!home_dir) { 2633 2684 home_dir = getenv("USERPROFILE"); 2634 2685 } 2635 2686 #endif ................................................................................ 2677 2728 struct callback_data *p, /* Configuration data */ 2678 2729 const char *sqliterc_override /* Name of config file. NULL to use default */ 2679 2730 ){ 2680 2731 char *home_dir = NULL; 2681 2732 const char *sqliterc = sqliterc_override; 2682 2733 char *zBuf = 0; 2683 2734 FILE *in = NULL; 2684 - int nBuf; 2685 2735 int rc = 0; 2686 2736 2687 2737 if (sqliterc == NULL) { 2688 2738 home_dir = find_home_dir(); 2689 2739 if( home_dir==0 ){ 2690 2740 #if !defined(__RTP__) && !defined(_WRS_KERNEL) 2691 2741 fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0); 2692 2742 #endif 2693 2743 return 1; 2694 2744 } 2695 - nBuf = strlen30(home_dir) + 16; 2696 - zBuf = malloc( nBuf ); 2697 - if( zBuf==0 ){ 2698 - fprintf(stderr,"%s: Error: out of memory\n",Argv0); 2699 - return 1; 2700 - } 2701 - sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir); 2702 - free(home_dir); 2703 - sqliterc = (const char*)zBuf; 2745 + zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); 2746 + sqliterc = zBuf; 2704 2747 } 2705 2748 in = fopen(sqliterc,"rb"); 2706 2749 if( in ){ 2707 2750 if( stdin_is_interactive ){ 2708 2751 fprintf(stderr,"-- Loading resources from %s\n",sqliterc); 2709 2752 } 2710 2753 rc = process_input(p,in); 2711 2754 fclose(in); 2712 2755 } 2713 - free(zBuf); 2756 + sqlite3_free(zBuf); 2714 2757 return rc; 2715 2758 } 2716 2759 2717 2760 /* 2718 2761 ** Show available command line options 2719 2762 */ 2720 2763 static const char zOptions[] = ................................................................................ 3053 3096 #endif 3054 3097 rc = process_input(&data, 0); 3055 3098 if( zHistory ){ 3056 3099 stifle_history(100); 3057 3100 write_history(zHistory); 3058 3101 free(zHistory); 3059 3102 } 3060 - free(zHome); 3061 3103 }else{ 3062 3104 rc = process_input(&data, stdin); 3063 3105 } 3064 3106 } 3065 3107 set_table_name(&data, 0); 3066 3108 if( data.db ){ 3067 3109 sqlite3_close(data.db); 3068 3110 } 3069 3111 return rc; 3070 3112 }

Changes to src/sqlite3.c

655 655 ** 656 656 ** See also: [sqlite3_libversion()], 657 657 ** [sqlite3_libversion_number()], [sqlite3_sourceid()], 658 658 ** [sqlite_version()] and [sqlite_source_id()]. 659 659 */ 660 660 #define SQLITE_VERSION "3.7.12" 661 661 #define SQLITE_VERSION_NUMBER 3007012 662 -#define SQLITE_SOURCE_ID "2012-03-31 19:12:23 af602d87736b52802a4e760ffeeaa28112b99d9a" 662 +#define SQLITE_SOURCE_ID "2012-04-17 09:09:33 8e2363ad76446e863d03ead91fd621e59d5cb495" 663 663 664 664 /* 665 665 ** CAPI3REF: Run-Time Library Version Numbers 666 666 ** KEYWORDS: sqlite3_version, sqlite3_sourceid 667 667 ** 668 668 ** These interfaces provide the same information as the [SQLITE_VERSION], 669 669 ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros ................................................................................ 2093 2093 ** connection is opened. If it is globally disabled, filenames are 2094 2094 ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the 2095 2095 ** database connection is opened. By default, URI handling is globally 2096 2096 ** disabled. The default value may be changed by compiling with the 2097 2097 ** [SQLITE_USE_URI] symbol defined. 2098 2098 ** 2099 2099 ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] 2100 -** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFNIG_GETPCACHE 2100 +** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE 2101 2101 ** <dd> These options are obsolete and should not be used by new code. 2102 2102 ** They are retained for backwards compatibility but are now no-ops. 2103 2103 ** </dl> 2104 2104 */ 2105 2105 #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ 2106 2106 #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ 2107 2107 #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ ................................................................................ 7531 7531 ** R-Tree geometry query as follows: 7532 7532 ** 7533 7533 ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) 7534 7534 */ 7535 7535 SQLITE_API int sqlite3_rtree_geometry_callback( 7536 7536 sqlite3 *db, 7537 7537 const char *zGeom, 7538 - int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes), 7538 +#ifdef SQLITE_RTREE_INT_ONLY 7539 + int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), 7540 +#else 7541 + int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), 7542 +#endif 7539 7543 void *pContext 7540 7544 ); 7541 7545 7542 7546 7543 7547 /* 7544 7548 ** A pointer to a structure of the following type is passed as the first 7545 7549 ** argument to callbacks registered using rtree_geometry_callback(). ................................................................................ 10931 10935 SrcList *pSrcList; /* One or more tables used to resolve names */ 10932 10936 ExprList *pEList; /* Optional list of named expressions */ 10933 10937 int nRef; /* Number of names resolved by this context */ 10934 10938 int nErr; /* Number of errors encountered while resolving names */ 10935 10939 u8 allowAgg; /* Aggregate functions allowed here */ 10936 10940 u8 hasAgg; /* True if aggregates are seen */ 10937 10941 u8 isCheck; /* True if resolving names in a CHECK constraint */ 10938 - int nDepth; /* Depth of subquery recursion. 1 for no recursion */ 10939 10942 AggInfo *pAggInfo; /* Information about aggregates at this level */ 10940 10943 NameContext *pNext; /* Next outer name context. NULL for outermost */ 10941 10944 }; 10942 10945 10943 10946 /* 10944 10947 ** An instance of the following structure contains all information 10945 10948 ** needed to generate code for a single SELECT statement. ................................................................................ 11397 11400 struct Walker { 11398 11401 int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ 11399 11402 int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ 11400 11403 Parse *pParse; /* Parser context. */ 11401 11404 union { /* Extra data for callback */ 11402 11405 NameContext *pNC; /* Naming context */ 11403 11406 int i; /* Integer value */ 11407 + SrcList *pSrcList; /* FROM clause */ 11404 11408 } u; 11405 11409 }; 11406 11410 11407 11411 /* Forward declarations */ 11408 11412 SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); 11409 11413 SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); 11410 11414 SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); ................................................................................ 11765 11769 SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int); 11766 11770 SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int); 11767 11771 SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); 11768 11772 SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); 11769 11773 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); 11770 11774 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); 11771 11775 SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*); 11772 -SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int); 11776 +SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8); 11773 11777 SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*); 11774 11778 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); 11775 11779 SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void); 11776 11780 SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); 11777 11781 SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); 11778 11782 SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); 11779 11783 ................................................................................ 24993 24997 ** Default permissions when creating a new file 24994 24998 */ 24995 24999 #ifndef SQLITE_DEFAULT_FILE_PERMISSIONS 24996 25000 # define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 24997 25001 #endif 24998 25002 24999 25003 /* 25000 - ** Default permissions when creating auto proxy dir 25001 - */ 25004 +** Default permissions when creating auto proxy dir 25005 +*/ 25002 25006 #ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 25003 25007 # define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755 25004 25008 #endif 25005 25009 25006 25010 /* 25007 25011 ** Maximum supported path-length. 25008 25012 */ ................................................................................ 25548 25552 if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; 25549 25553 } 25550 25554 return 0; 25551 25555 } 25552 25556 25553 25557 /* 25554 25558 ** Invoke open(). Do so multiple times, until it either succeeds or 25555 -** files for some reason other than EINTR. 25559 +** fails for some reason other than EINTR. 25556 25560 ** 25557 25561 ** If the file creation mode "m" is 0 then set it to the default for 25558 25562 ** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally 25559 25563 ** 0644) as modified by the system umask. If m is not 0, then 25560 25564 ** make the file creation mode be exactly m ignoring the umask. 25561 25565 ** 25562 25566 ** The m parameter will be non-zero only when creating -wal, -journal, ................................................................................ 25564 25568 ** permissions as their original database, unadulterated by the umask. 25565 25569 ** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a 25566 25570 ** transaction crashes and leaves behind hot journals, then any 25567 25571 ** process that is able to write to the database will also be able to 25568 25572 ** recover the hot journals. 25569 25573 */ 25570 25574 static int robust_open(const char *z, int f, mode_t m){ 25571 - int rc; 25575 + int fd; 25572 25576 mode_t m2; 25573 25577 mode_t origM = 0; 25574 25578 if( m==0 ){ 25575 25579 m2 = SQLITE_DEFAULT_FILE_PERMISSIONS; 25576 25580 }else{ 25577 25581 m2 = m; 25578 25582 origM = osUmask(0); 25579 25583 } 25580 - do{ rc = osOpen(z,f,m2); }while( rc<0 && errno==EINTR ); 25584 + do{ 25585 +#if defined(O_CLOEXEC) 25586 + fd = osOpen(z,f|O_CLOEXEC,m2); 25587 +#else 25588 + fd = osOpen(z,f,m2); 25589 +#endif 25590 + }while( fd<0 && errno==EINTR ); 25581 25591 if( m ){ 25582 25592 osUmask(origM); 25583 25593 } 25584 - return rc; 25594 +#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0) 25595 + if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); 25596 +#endif 25597 + return fd; 25585 25598 } 25586 25599 25587 25600 /* 25588 25601 ** Helper functions to obtain and relinquish the global mutex. The 25589 25602 ** global mutex is used to protect the unixInodeInfo and 25590 25603 ** vxworksFileId objects used by this file, all of which may be 25591 25604 ** shared by multiple threads. ................................................................................ 28372 28385 28373 28386 sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); 28374 28387 for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--); 28375 28388 if( ii>0 ){ 28376 28389 zDirname[ii] = '\0'; 28377 28390 fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); 28378 28391 if( fd>=0 ){ 28379 -#ifdef FD_CLOEXEC 28380 - osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); 28381 -#endif 28382 28392 OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); 28383 28393 } 28384 28394 } 28385 28395 *pFd = fd; 28386 28396 return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)); 28387 28397 } 28388 28398 ................................................................................ 28457 28467 SimulateIOError( return SQLITE_IOERR_TRUNCATE ); 28458 28468 28459 28469 /* If the user has configured a chunk-size for this file, truncate the 28460 28470 ** file so that it consists of an integer number of chunks (i.e. the 28461 28471 ** actual file size after the operation may be larger than the requested 28462 28472 ** size). 28463 28473 */ 28464 - if( pFile->szChunk ){ 28474 + if( pFile->szChunk>0 ){ 28465 28475 nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; 28466 28476 } 28467 28477 28468 28478 rc = robust_ftruncate(pFile->h, (off_t)nByte); 28469 28479 if( rc ){ 28470 28480 pFile->lastErrno = errno; 28471 28481 return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); ................................................................................ 30219 30229 } 30220 30230 #if SQLITE_ENABLE_LOCKING_STYLE 30221 30231 else{ 30222 30232 p->openFlags = openFlags; 30223 30233 } 30224 30234 #endif 30225 30235 30226 -#ifdef FD_CLOEXEC 30227 - osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); 30228 -#endif 30229 - 30230 30236 noLock = eType!=SQLITE_OPEN_MAIN_DB; 30231 30237 30232 30238 30233 30239 #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE 30234 30240 if( fstatfs(fd, &fsInfo) == -1 ){ 30235 30241 ((unixFile*)pFile)->lastErrno = errno; 30236 30242 robust_close(p, fd, __LINE__); ................................................................................ 37999 38005 ** The number of rowset entries per allocation chunk. 38000 38006 */ 38001 38007 #define ROWSET_ENTRY_PER_CHUNK \ 38002 38008 ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry)) 38003 38009 38004 38010 /* 38005 38011 ** Each entry in a RowSet is an instance of the following object. 38012 +** 38013 +** This same object is reused to store a linked list of trees of RowSetEntry 38014 +** objects. In that alternative use, pRight points to the next entry 38015 +** in the list, pLeft points to the tree, and v is unused. The 38016 +** RowSet.pForest value points to the head of this forest list. 38006 38017 */ 38007 38018 struct RowSetEntry { 38008 38019 i64 v; /* ROWID value for this entry */ 38009 38020 struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */ 38010 38021 struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */ 38011 38022 }; 38012 38023 ................................................................................ 38028 38039 */ 38029 38040 struct RowSet { 38030 38041 struct RowSetChunk *pChunk; /* List of all chunk allocations */ 38031 38042 sqlite3 *db; /* The database connection */ 38032 38043 struct RowSetEntry *pEntry; /* List of entries using pRight */ 38033 38044 struct RowSetEntry *pLast; /* Last entry on the pEntry list */ 38034 38045 struct RowSetEntry *pFresh; /* Source of new entry objects */ 38035 - struct RowSetEntry *pTree; /* Binary tree of entries */ 38046 + struct RowSetEntry *pForest; /* List of binary trees of entries */ 38036 38047 u16 nFresh; /* Number of objects on pFresh */ 38037 - u8 isSorted; /* True if pEntry is sorted */ 38048 + u8 rsFlags; /* Various flags */ 38038 38049 u8 iBatch; /* Current insert batch */ 38039 38050 }; 38040 38051 38052 +/* 38053 +** Allowed values for RowSet.rsFlags 38054 +*/ 38055 +#define ROWSET_SORTED 0x01 /* True if RowSet.pEntry is sorted */ 38056 +#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ 38057 + 38041 38058 /* 38042 38059 ** Turn bulk memory into a RowSet object. N bytes of memory 38043 38060 ** are available at pSpace. The db pointer is used as a memory context 38044 38061 ** for any subsequent allocations that need to occur. 38045 38062 ** Return a pointer to the new RowSet object. 38046 38063 ** 38047 38064 ** It must be the case that N is sufficient to make a Rowset. If not ................................................................................ 38054 38071 RowSet *p; 38055 38072 assert( N >= ROUND8(sizeof(*p)) ); 38056 38073 p = pSpace; 38057 38074 p->pChunk = 0; 38058 38075 p->db = db; 38059 38076 p->pEntry = 0; 38060 38077 p->pLast = 0; 38061 - p->pTree = 0; 38078 + p->pForest = 0; 38062 38079 p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); 38063 38080 p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); 38064 - p->isSorted = 1; 38081 + p->rsFlags = ROWSET_SORTED; 38065 38082 p->iBatch = 0; 38066 38083 return p; 38067 38084 } 38068 38085 38069 38086 /* 38070 38087 ** Deallocate all chunks from a RowSet. This frees all memory that 38071 38088 ** the RowSet has allocated over its lifetime. This routine is ................................................................................ 38077 38094 pNextChunk = pChunk->pNextChunk; 38078 38095 sqlite3DbFree(p->db, pChunk); 38079 38096 } 38080 38097 p->pChunk = 0; 38081 38098 p->nFresh = 0; 38082 38099 p->pEntry = 0; 38083 38100 p->pLast = 0; 38084 - p->pTree = 0; 38085 - p->isSorted = 1; 38101 + p->pForest = 0; 38102 + p->rsFlags = ROWSET_SORTED; 38103 +} 38104 + 38105 +/* 38106 +** Allocate a new RowSetEntry object that is associated with the 38107 +** given RowSet. Return a pointer to the new and completely uninitialized 38108 +** objected. 38109 +** 38110 +** In an OOM situation, the RowSet.db->mallocFailed flag is set and this 38111 +** routine returns NULL. 38112 +*/ 38113 +static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ 38114 + assert( p!=0 ); 38115 + if( p->nFresh==0 ){ 38116 + struct RowSetChunk *pNew; 38117 + pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew)); 38118 + if( pNew==0 ){ 38119 + return 0; 38120 + } 38121 + pNew->pNextChunk = p->pChunk; 38122 + p->pChunk = pNew; 38123 + p->pFresh = pNew->aEntry; 38124 + p->nFresh = ROWSET_ENTRY_PER_CHUNK; 38125 + } 38126 + p->nFresh--; 38127 + return p->pFresh++; 38086 38128 } 38087 38129 38088 38130 /* 38089 38131 ** Insert a new value into a RowSet. 38090 38132 ** 38091 38133 ** The mallocFailed flag of the database connection is set if a 38092 38134 ** memory allocation fails. 38093 38135 */ 38094 38136 SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){ 38095 38137 struct RowSetEntry *pEntry; /* The new entry */ 38096 38138 struct RowSetEntry *pLast; /* The last prior entry */ 38097 - assert( p!=0 ); 38098 - if( p->nFresh==0 ){ 38099 - struct RowSetChunk *pNew; 38100 - pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew)); 38101 - if( pNew==0 ){ 38102 - return; 38103 - } 38104 - pNew->pNextChunk = p->pChunk; 38105 - p->pChunk = pNew; 38106 - p->pFresh = pNew->aEntry; 38107 - p->nFresh = ROWSET_ENTRY_PER_CHUNK; 38108 - } 38109 - pEntry = p->pFresh++; 38110 - p->nFresh--; 38139 + 38140 + /* This routine is never called after sqlite3RowSetNext() */ 38141 + assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); 38142 + 38143 + pEntry = rowSetEntryAlloc(p); 38144 + if( pEntry==0 ) return; 38111 38145 pEntry->v = rowid; 38112 38146 pEntry->pRight = 0; 38113 38147 pLast = p->pLast; 38114 38148 if( pLast ){ 38115 - if( p->isSorted && rowid<=pLast->v ){ 38116 - p->isSorted = 0; 38149 + if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){ 38150 + p->rsFlags &= ~ROWSET_SORTED; 38117 38151 } 38118 38152 pLast->pRight = pEntry; 38119 38153 }else{ 38120 - assert( p->pEntry==0 ); /* Fires if INSERT after SMALLEST */ 38121 38154 p->pEntry = pEntry; 38122 38155 } 38123 38156 p->pLast = pEntry; 38124 38157 } 38125 38158 38126 38159 /* 38127 38160 ** Merge two lists of RowSetEntry objects. Remove duplicates. 38128 38161 ** 38129 38162 ** The input lists are connected via pRight pointers and are 38130 38163 ** assumed to each already be in sorted order. 38131 38164 */ 38132 -static struct RowSetEntry *rowSetMerge( 38165 +static struct RowSetEntry *rowSetEntryMerge( 38133 38166 struct RowSetEntry *pA, /* First sorted list to be merged */ 38134 38167 struct RowSetEntry *pB /* Second sorted list to be merged */ 38135 38168 ){ 38136 38169 struct RowSetEntry head; 38137 38170 struct RowSetEntry *pTail; 38138 38171 38139 38172 pTail = &head; ................................................................................ 38159 38192 assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v ); 38160 38193 pTail->pRight = pB; 38161 38194 } 38162 38195 return head.pRight; 38163 38196 } 38164 38197 38165 38198 /* 38166 -** Sort all elements on the pEntry list of the RowSet into ascending order. 38199 +** Sort all elements on the list of RowSetEntry objects into order of 38200 +** increasing v. 38167 38201 */ 38168 -static void rowSetSort(RowSet *p){ 38202 +static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){ 38169 38203 unsigned int i; 38170 - struct RowSetEntry *pEntry; 38171 - struct RowSetEntry *aBucket[40]; 38204 + struct RowSetEntry *pNext, *aBucket[40]; 38172 38205 38173 - assert( p->isSorted==0 ); 38174 38206 memset(aBucket, 0, sizeof(aBucket)); 38175 - while( p->pEntry ){ 38176 - pEntry = p->pEntry; 38177 - p->pEntry = pEntry->pRight; 38178 - pEntry->pRight = 0; 38207 + while( pIn ){ 38208 + pNext = pIn->pRight; 38209 + pIn->pRight = 0; 38179 38210 for(i=0; aBucket[i]; i++){ 38180 - pEntry = rowSetMerge(aBucket[i], pEntry); 38211 + pIn = rowSetEntryMerge(aBucket[i], pIn); 38181 38212 aBucket[i] = 0; 38182 38213 } 38183 - aBucket[i] = pEntry; 38214 + aBucket[i] = pIn; 38215 + pIn = pNext; 38184 38216 } 38185 - pEntry = 0; 38217 + pIn = 0; 38186 38218 for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){ 38187 - pEntry = rowSetMerge(pEntry, aBucket[i]); 38219 + pIn = rowSetEntryMerge(pIn, aBucket[i]); 38188 38220 } 38189 - p->pEntry = pEntry; 38190 - p->pLast = 0; 38191 - p->isSorted = 1; 38221 + return pIn; 38192 38222 } 38193 38223 38194 38224 38195 38225 /* 38196 38226 ** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects. 38197 38227 ** Convert this tree into a linked list connected by the pRight pointers 38198 38228 ** and return pointers to the first and last elements of the new list. ................................................................................ 38278 38308 p->pLeft = pLeft; 38279 38309 p->pRight = rowSetNDeepTree(&pList, iDepth); 38280 38310 } 38281 38311 return p; 38282 38312 } 38283 38313 38284 38314 /* 38285 -** Convert the list in p->pEntry into a sorted list if it is not 38286 -** sorted already. If there is a binary tree on p->pTree, then 38287 -** convert it into a list too and merge it into the p->pEntry list. 38315 +** Take all the entries on p->pEntry and on the trees in p->pForest and 38316 +** sort them all together into one big ordered list on p->pEntry. 38317 +** 38318 +** This routine should only be called once in the life of a RowSet. 38288 38319 */ 38289 38320 static void rowSetToList(RowSet *p){ 38290 - if( !p->isSorted ){ 38291 - rowSetSort(p); 38321 + 38322 + /* This routine is called only once */ 38323 + assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); 38324 + 38325 + if( (p->rsFlags & ROWSET_SORTED)==0 ){ 38326 + p->pEntry = rowSetEntrySort(p->pEntry); 38292 38327 } 38293 - if( p->pTree ){ 38294 - struct RowSetEntry *pHead, *pTail; 38295 - rowSetTreeToList(p->pTree, &pHead, &pTail); 38296 - p->pTree = 0; 38297 - p->pEntry = rowSetMerge(p->pEntry, pHead); 38328 + 38329 + /* While this module could theoretically support it, sqlite3RowSetNext() 38330 + ** is never called after sqlite3RowSetText() for the same RowSet. So 38331 + ** there is never a forest to deal with. Should this change, simply 38332 + ** remove the assert() and the #if 0. */ 38333 + assert( p->pForest==0 ); 38334 +#if 0 38335 + while( p->pForest ){ 38336 + struct RowSetEntry *pTree = p->pForest->pLeft; 38337 + if( pTree ){ 38338 + struct RowSetEntry *pHead, *pTail; 38339 + rowSetTreeToList(pTree, &pHead, &pTail); 38340 + p->pEntry = rowSetEntryMerge(p->pEntry, pHead); 38341 + } 38342 + p->pForest = p->pForest->pRight; 38298 38343 } 38344 +#endif 38345 + p->rsFlags |= ROWSET_NEXT; /* Verify this routine is never called again */ 38299 38346 } 38300 38347 38301 38348 /* 38302 38349 ** Extract the smallest element from the RowSet. 38303 38350 ** Write the element into *pRowid. Return 1 on success. Return 38304 38351 ** 0 if the RowSet is already empty. 38305 38352 ** 38306 38353 ** After this routine has been called, the sqlite3RowSetInsert() 38307 38354 ** routine may not be called again. 38308 38355 */ 38309 38356 SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ 38310 - rowSetToList(p); 38357 + assert( p!=0 ); 38358 + 38359 + /* Merge the forest into a single sorted list on first call */ 38360 + if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p); 38361 + 38362 + /* Return the next entry on the list */ 38311 38363 if( p->pEntry ){ 38312 38364 *pRowid = p->pEntry->v; 38313 38365 p->pEntry = p->pEntry->pRight; 38314 38366 if( p->pEntry==0 ){ 38315 38367 sqlite3RowSetClear(p); 38316 38368 } 38317 38369 return 1; ................................................................................ 38319 38371 return 0; 38320 38372 } 38321 38373 } 38322 38374 38323 38375 /* 38324 38376 ** Check to see if element iRowid was inserted into the the rowset as 38325 38377 ** part of any insert batch prior to iBatch. Return 1 or 0. 38378 +** 38379 +** If this is the first test of a new batch and if there exist entires 38380 +** on pRowSet->pEntry, then sort those entires into the forest at 38381 +** pRowSet->pForest so that they can be tested. 38326 38382 */ 38327 38383 SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){ 38328 - struct RowSetEntry *p; 38384 + struct RowSetEntry *p, *pTree; 38385 + 38386 + /* This routine is never called after sqlite3RowSetNext() */ 38387 + assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); 38388 + 38389 + /* Sort entries into the forest on the first test of a new batch 38390 + */ 38329 38391 if( iBatch!=pRowSet->iBatch ){ 38330 - if( pRowSet->pEntry ){ 38331 - rowSetToList(pRowSet); 38332 - pRowSet->pTree = rowSetListToTree(pRowSet->pEntry); 38392 + p = pRowSet->pEntry; 38393 + if( p ){ 38394 + struct RowSetEntry **ppPrevTree = &pRowSet->pForest; 38395 + if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ 38396 + p = rowSetEntrySort(p); 38397 + } 38398 + for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ 38399 + ppPrevTree = &pTree->pRight; 38400 + if( pTree->pLeft==0 ){ 38401 + pTree->pLeft = rowSetListToTree(p); 38402 + break; 38403 + }else{ 38404 + struct RowSetEntry *pAux, *pTail; 38405 + rowSetTreeToList(pTree->pLeft, &pAux, &pTail); 38406 + pTree->pLeft = 0; 38407 + p = rowSetEntryMerge(pAux, p); 38408 + } 38409 + } 38410 + if( pTree==0 ){ 38411 + *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet); 38412 + if( pTree ){ 38413 + pTree->v = 0; 38414 + pTree->pRight = 0; 38415 + pTree->pLeft = rowSetListToTree(p); 38416 + } 38417 + } 38333 38418 pRowSet->pEntry = 0; 38334 38419 pRowSet->pLast = 0; 38420 + pRowSet->rsFlags |= ROWSET_SORTED; 38335 38421 } 38336 38422 pRowSet->iBatch = iBatch; 38337 38423 } 38338 - p = pRowSet->pTree; 38339 - while( p ){ 38340 - if( p->v<iRowid ){ 38341 - p = p->pRight; 38342 - }else if( p->v>iRowid ){ 38343 - p = p->pLeft; 38344 - }else{ 38345 - return 1; 38424 + 38425 + /* Test to see if the iRowid value appears anywhere in the forest. 38426 + ** Return 1 if it does and 0 if not. 38427 + */ 38428 + for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ 38429 + p = pTree->pLeft; 38430 + while( p ){ 38431 + if( p->v<iRowid ){ 38432 + p = p->pRight; 38433 + }else if( p->v>iRowid ){ 38434 + p = p->pLeft; 38435 + }else{ 38436 + return 1; 38437 + } 38346 38438 } 38347 38439 } 38348 38440 return 0; 38349 38441 } 38350 38442 38351 38443 /************** End of rowset.c **********************************************/ 38352 38444 /************** Begin file pager.c *******************************************/ ................................................................................ 49146 49238 #define ISAUTOVACUUM 0 49147 49239 #endif 49148 49240 49149 49241 49150 49242 /* 49151 49243 ** This structure is passed around through all the sanity checking routines 49152 49244 ** in order to keep track of some global state information. 49245 +** 49246 +** The aRef[] array is allocated so that there is 1 bit for each page in 49247 +** the database. As the integrity-check proceeds, for each page used in 49248 +** the database the corresponding bit is set. This allows integrity-check to 49249 +** detect pages that are used twice and orphaned pages (both of which 49250 +** indicate corruption). 49153 49251 */ 49154 49252 typedef struct IntegrityCk IntegrityCk; 49155 49253 struct IntegrityCk { 49156 49254 BtShared *pBt; /* The tree being checked out */ 49157 49255 Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ 49158 - int *anRef; /* Number of times each page is referenced */ 49256 + u8 *aPgRef; /* 1 bit per page in the db (see above) */ 49159 49257 Pgno nPage; /* Number of pages in the database */ 49160 49258 int mxErr; /* Stop accumulating errors when this reaches zero */ 49161 49259 int nErr; /* Number of messages written to zErrMsg so far */ 49162 49260 int mallocFailed; /* A memory allocation error has occurred */ 49163 49261 StrAccum errMsg; /* Accumulate the error message text here */ 49164 49262 }; 49165 49263 ................................................................................ 56996 57094 if( pCheck->errMsg.mallocFailed ){ 56997 57095 pCheck->mallocFailed = 1; 56998 57096 } 56999 57097 } 57000 57098 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ 57001 57099 57002 57100 #ifndef SQLITE_OMIT_INTEGRITY_CHECK 57101 + 57102 +/* 57103 +** Return non-zero if the bit in the IntegrityCk.aPgRef[] array that 57104 +** corresponds to page iPg is already set. 57105 +*/ 57106 +static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ 57107 + assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); 57108 + return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); 57109 +} 57110 + 57111 +/* 57112 +** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg. 57113 +*/ 57114 +static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ 57115 + assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); 57116 + pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); 57117 +} 57118 + 57119 + 57003 57120 /* 57004 57121 ** Add 1 to the reference count for page iPage. If this is the second 57005 57122 ** reference to the page, add an error message to pCheck->zErrMsg. 57006 57123 ** Return 1 if there are 2 ore more references to the page and 0 if 57007 57124 ** if this is the first reference to the page. 57008 57125 ** 57009 57126 ** Also check that the page number is in bounds. ................................................................................ 57010 57127 */ 57011 57128 static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){ 57012 57129 if( iPage==0 ) return 1; 57013 57130 if( iPage>pCheck->nPage ){ 57014 57131 checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage); 57015 57132 return 1; 57016 57133 } 57017 - if( pCheck->anRef[iPage]==1 ){ 57134 + if( getPageReferenced(pCheck, iPage) ){ 57018 57135 checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage); 57019 57136 return 1; 57020 57137 } 57021 - return (pCheck->anRef[iPage]++)>1; 57138 + setPageReferenced(pCheck, iPage); 57139 + return 0; 57022 57140 } 57023 57141 57024 57142 #ifndef SQLITE_OMIT_AUTOVACUUM 57025 57143 /* 57026 57144 ** Check that the entry in the pointer-map for page iChild maps to 57027 57145 ** page iParent, pointer type ptrType. If not, append an error message 57028 57146 ** to pCheck. ................................................................................ 57390 57508 sCheck.nErr = 0; 57391 57509 sCheck.mallocFailed = 0; 57392 57510 *pnErr = 0; 57393 57511 if( sCheck.nPage==0 ){ 57394 57512 sqlite3BtreeLeave(p); 57395 57513 return 0; 57396 57514 } 57397 - sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); 57398 - if( !sCheck.anRef ){ 57515 + 57516 + sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); 57517 + if( !sCheck.aPgRef ){ 57399 57518 *pnErr = 1; 57400 57519 sqlite3BtreeLeave(p); 57401 57520 return 0; 57402 57521 } 57403 - for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; } 57404 57522 i = PENDING_BYTE_PAGE(pBt); 57405 - if( i<=sCheck.nPage ){ 57406 - sCheck.anRef[i] = 1; 57407 - } 57523 + if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); 57408 57524 sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000); 57409 57525 sCheck.errMsg.useMalloc = 2; 57410 57526 57411 57527 /* Check the integrity of the freelist 57412 57528 */ 57413 57529 checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), 57414 57530 get4byte(&pBt->pPage1->aData[36]), "Main freelist: "); ................................................................................ 57425 57541 checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL); 57426 57542 } 57427 57543 57428 57544 /* Make sure every page in the file is referenced 57429 57545 */ 57430 57546 for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ 57431 57547 #ifdef SQLITE_OMIT_AUTOVACUUM 57432 - if( sCheck.anRef[i]==0 ){ 57548 + if( getPageReferenced(&sCheck, i)==0 ){ 57433 57549 checkAppendMsg(&sCheck, 0, "Page %d is never used", i); 57434 57550 } 57435 57551 #else 57436 57552 /* If the database supports auto-vacuum, make sure no tables contain 57437 57553 ** references to pointer-map pages. 57438 57554 */ 57439 - if( sCheck.anRef[i]==0 && 57555 + if( getPageReferenced(&sCheck, i)==0 && 57440 57556 (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ 57441 57557 checkAppendMsg(&sCheck, 0, "Page %d is never used", i); 57442 57558 } 57443 - if( sCheck.anRef[i]!=0 && 57559 + if( getPageReferenced(&sCheck, i)!=0 && 57444 57560 (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ 57445 57561 checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i); 57446 57562 } 57447 57563 #endif 57448 57564 } 57449 57565 57450 57566 /* Make sure this analysis did not leave any unref() pages. ................................................................................ 57457 57573 nRef, sqlite3PagerRefcount(pBt->pPager) 57458 57574 ); 57459 57575 } 57460 57576 57461 57577 /* Clean up and report errors. 57462 57578 */ 57463 57579 sqlite3BtreeLeave(p); 57464 - sqlite3_free(sCheck.anRef); 57580 + sqlite3_free(sCheck.aPgRef); 57465 57581 if( sCheck.mallocFailed ){ 57466 57582 sqlite3StrAccumReset(&sCheck.errMsg); 57467 57583 *pnErr = sCheck.nErr+1; 57468 57584 return 0; 57469 57585 } 57470 57586 *pnErr = sCheck.nErr; 57471 57587 if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); ................................................................................ 73805 73921 73806 73922 testcase( pExpr->op==TK_CONST_FUNC ); 73807 73923 assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); 73808 73924 zId = pExpr->u.zToken; 73809 73925 nId = sqlite3Strlen30(zId); 73810 73926 pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); 73811 73927 if( pDef==0 ){ 73812 - pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); 73928 + pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0); 73813 73929 if( pDef==0 ){ 73814 73930 no_such_func = 1; 73815 73931 }else{ 73816 73932 wrong_num_args = 1; 73817 73933 } 73818 73934 }else{ 73819 73935 is_agg = pDef->xFunc==0; ................................................................................ 78275 78391 if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2; 78276 78392 if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2; 78277 78393 if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2; 78278 78394 if( ExprHasProperty(pA, EP_IntValue) ){ 78279 78395 if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ 78280 78396 return 2; 78281 78397 } 78282 - }else if( pA->op!=TK_COLUMN && pA->u.zToken ){ 78398 + }else if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ 78283 78399 if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2; 78284 78400 if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ 78285 78401 return 2; 78286 78402 } 78287 78403 } 78288 78404 if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1; 78289 78405 if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2; ................................................................................ 78311 78427 Expr *pExprA = pA->a[i].pExpr; 78312 78428 Expr *pExprB = pB->a[i].pExpr; 78313 78429 if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; 78314 78430 if( sqlite3ExprCompare(pExprA, pExprB) ) return 1; 78315 78431 } 78316 78432 return 0; 78317 78433 } 78434 + 78435 +/* 78436 +** This is the expression callback for sqlite3FunctionUsesOtherSrc(). 78437 +** 78438 +** Determine if an expression references any table other than one of the 78439 +** tables in pWalker->u.pSrcList and abort if it does. 78440 +*/ 78441 +static int exprUsesOtherSrc(Walker *pWalker, Expr *pExpr){ 78442 + if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){ 78443 + int i; 78444 + SrcList *pSrc = pWalker->u.pSrcList; 78445 + for(i=0; i<pSrc->nSrc; i++){ 78446 + if( pExpr->iTable==pSrc->a[i].iCursor ) return WRC_Continue; 78447 + } 78448 + return WRC_Abort; 78449 + }else{ 78450 + return WRC_Continue; 78451 + } 78452 +} 78453 + 78454 +/* 78455 +** Determine if any of the arguments to the pExpr Function references 78456 +** any SrcList other than pSrcList. Return true if they do. Return 78457 +** false if pExpr has no argument or has only constant arguments or 78458 +** only references tables named in pSrcList. 78459 +*/ 78460 +static int sqlite3FunctionUsesOtherSrc(Expr *pExpr, SrcList *pSrcList){ 78461 + Walker w; 78462 + assert( pExpr->op==TK_AGG_FUNCTION ); 78463 + memset(&w, 0, sizeof(w)); 78464 + w.xExprCallback = exprUsesOtherSrc; 78465 + w.u.pSrcList = pSrcList; 78466 + if( sqlite3WalkExprList(&w, pExpr->x.pList)!=WRC_Continue ) return 1; 78467 + return 0; 78468 +} 78318 78469 78319 78470 /* 78320 78471 ** Add a new element to the pAggInfo->aCol[] array. Return the index of 78321 78472 ** the new element. Return a negative number if malloc fails. 78322 78473 */ 78323 78474 static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ 78324 78475 int i; ................................................................................ 78427 78578 break; 78428 78579 } /* endif pExpr->iTable==pItem->iCursor */ 78429 78580 } /* end loop over pSrcList */ 78430 78581 } 78431 78582 return WRC_Prune; 78432 78583 } 78433 78584 case TK_AGG_FUNCTION: { 78434 - /* The pNC->nDepth==0 test causes aggregate functions in subqueries 78435 - ** to be ignored */ 78436 - if( pNC->nDepth==0 ){ 78585 + if( !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList) ){ 78437 78586 /* Check to see if pExpr is a duplicate of another aggregate 78438 78587 ** function that is already in the pAggInfo structure 78439 78588 */ 78440 78589 struct AggInfo_func *pItem = pAggInfo->aFunc; 78441 78590 for(i=0; i<pAggInfo->nFunc; i++, pItem++){ 78442 78591 if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){ 78443 78592 break; ................................................................................ 78473 78622 return WRC_Prune; 78474 78623 } 78475 78624 } 78476 78625 } 78477 78626 return WRC_Continue; 78478 78627 } 78479 78628 static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ 78480 - NameContext *pNC = pWalker->u.pNC; 78481 - if( pNC->nDepth==0 ){ 78482 - pNC->nDepth++; 78483 - sqlite3WalkSelect(pWalker, pSelect); 78484 - pNC->nDepth--; 78485 - return WRC_Prune; 78486 - }else{ 78487 - return WRC_Continue; 78488 - } 78629 + return WRC_Continue; 78489 78630 } 78490 78631 78491 78632 /* 78492 78633 ** Analyze the given expression looking for aggregate functions and 78493 78634 ** for variables that need to be added to the pParse->aAgg[] array. 78494 78635 ** Make additional entries to the pParse->aAgg[] array as necessary. 78495 78636 ** 78496 78637 ** This routine should only be called after the expression has been 78497 78638 ** analyzed by sqlite3ResolveExprNames(). 78498 78639 */ 78499 78640 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ 78500 78641 Walker w; 78642 + memset(&w, 0, sizeof(w)); 78501 78643 w.xExprCallback = analyzeAggregate; 78502 78644 w.xSelectCallback = analyzeAggregatesInSelect; 78503 78645 w.u.pNC = pNC; 78504 78646 assert( pNC->pSrcList!=0 ); 78505 78647 sqlite3WalkExpr(&w, pExpr); 78506 78648 } 78507 78649 ................................................................................ 85397 85539 } 85398 85540 85399 85541 /* During the search for the best function definition, this procedure 85400 85542 ** is called to test how well the function passed as the first argument 85401 85543 ** matches the request for a function with nArg arguments in a system 85402 85544 ** that uses encoding enc. The value returned indicates how well the 85403 85545 ** request is matched. A higher value indicates a better match. 85546 +** 85547 +** If nArg is -1 that means to only return a match (non-zero) if p->nArg 85548 +** is also -1. In other words, we are searching for a function that 85549 +** takes a variable number of arguments. 85550 +** 85551 +** If nArg is -2 that means that we are searching for any function 85552 +** regardless of the number of arguments it uses, so return a positive 85553 +** match score for any 85404 85554 ** 85405 85555 ** The returned value is always between 0 and 6, as follows: 85406 85556 ** 85407 -** 0: Not a match, or if nArg<0 and the function is has no implementation. 85408 -** 1: A variable arguments function that prefers UTF-8 when a UTF-16 85409 -** encoding is requested, or vice versa. 85410 -** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is 85411 -** requested, or vice versa. 85412 -** 3: A variable arguments function using the same text encoding. 85413 -** 4: A function with the exact number of arguments requested that 85414 -** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa. 85415 -** 5: A function with the exact number of arguments requested that 85416 -** prefers UTF-16LE when UTF-16BE is requested, or vice versa. 85417 -** 6: An exact match. 85418 -** 85419 -*/ 85420 -static int matchQuality(FuncDef *p, int nArg, u8 enc){ 85421 - int match = 0; 85422 - if( p->nArg==-1 || p->nArg==nArg 85423 - || (nArg==-1 && (p->xFunc!=0 || p->xStep!=0)) 85424 - ){ 85557 +** 0: Not a match. 85558 +** 1: UTF8/16 conversion required and function takes any number of arguments. 85559 +** 2: UTF16 byte order change required and function takes any number of args. 85560 +** 3: encoding matches and function takes any number of arguments 85561 +** 4: UTF8/16 conversion required - argument count matches exactly 85562 +** 5: UTF16 byte order conversion required - argument count matches exactly 85563 +** 6: Perfect match: encoding and argument count match exactly. 85564 +** 85565 +** If nArg==(-2) then any function with a non-null xStep or xFunc is 85566 +** a perfect match and any function with both xStep and xFunc NULL is 85567 +** a non-match. 85568 +*/ 85569 +#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */ 85570 +static int matchQuality( 85571 + FuncDef *p, /* The function we are evaluating for match quality */ 85572 + int nArg, /* Desired number of arguments. (-1)==any */ 85573 + u8 enc /* Desired text encoding */ 85574 +){ 85575 + int match; 85576 + 85577 + /* nArg of -2 is a special case */ 85578 + if( nArg==(-2) ) return (p->xFunc==0 && p->xStep==0) ? 0 : FUNC_PERFECT_MATCH; 85579 + 85580 + /* Wrong number of arguments means "no match" */ 85581 + if( p->nArg!=nArg && p->nArg>=0 ) return 0; 85582 + 85583 + /* Give a better score to a function with a specific number of arguments 85584 + ** than to function that accepts any number of arguments. */ 85585 + if( p->nArg==nArg ){ 85586 + match = 4; 85587 + }else{ 85425 85588 match = 1; 85426 - if( p->nArg==nArg || nArg==-1 ){ 85427 - match = 4; 85428 - } 85429 - if( enc==p->iPrefEnc ){ 85430 - match += 2; 85431 - } 85432 - else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) || 85433 - (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){ 85434 - match += 1; 85435 - } 85436 85589 } 85590 + 85591 + /* Bonus points if the text encoding matches */ 85592 + if( enc==p->iPrefEnc ){ 85593 + match += 2; /* Exact encoding match */ 85594 + }else if( (enc & p->iPrefEnc & 2)!=0 ){ 85595 + match += 1; /* Both are UTF16, but with different byte orders */ 85596 + } 85597 + 85437 85598 return match; 85438 85599 } 85439 85600 85440 85601 /* 85441 85602 ** Search a FuncDefHash for a function with the given name. Return 85442 85603 ** a pointer to the matching FuncDef if found, or 0 if there is no match. 85443 85604 */ ................................................................................ 85485 85646 ** Locate a user function given a name, a number of arguments and a flag 85486 85647 ** indicating whether the function prefers UTF-16 over UTF-8. Return a 85487 85648 ** pointer to the FuncDef structure that defines that function, or return 85488 85649 ** NULL if the function does not exist. 85489 85650 ** 85490 85651 ** If the createFlag argument is true, then a new (blank) FuncDef 85491 85652 ** structure is created and liked into the "db" structure if a 85492 -** no matching function previously existed. When createFlag is true 85493 -** and the nArg parameter is -1, then only a function that accepts 85494 -** any number of arguments will be returned. 85653 +** no matching function previously existed. 85495 85654 ** 85496 -** If createFlag is false and nArg is -1, then the first valid 85497 -** function found is returned. A function is valid if either xFunc 85498 -** or xStep is non-zero. 85655 +** If nArg is -2, then the first valid function found is returned. A 85656 +** function is valid if either xFunc or xStep is non-zero. The nArg==(-2) 85657 +** case is used to see if zName is a valid function name for some number 85658 +** of arguments. If nArg is -2, then createFlag must be 0. 85499 85659 ** 85500 85660 ** If createFlag is false, then a function with the required name and 85501 85661 ** number of arguments may be returned even if the eTextRep flag does not 85502 85662 ** match that requested. 85503 85663 */ 85504 85664 SQLITE_PRIVATE FuncDef *sqlite3FindFunction( 85505 85665 sqlite3 *db, /* An open database */ 85506 85666 const char *zName, /* Name of the function. Not null-terminated */ 85507 85667 int nName, /* Number of characters in the name */ 85508 85668 int nArg, /* Number of arguments. -1 means any number */ 85509 85669 u8 enc, /* Preferred text encoding */ 85510 - int createFlag /* Create new entry if true and does not otherwise exist */ 85670 + u8 createFlag /* Create new entry if true and does not otherwise exist */ 85511 85671 ){ 85512 85672 FuncDef *p; /* Iterator variable */ 85513 85673 FuncDef *pBest = 0; /* Best match found so far */ 85514 85674 int bestScore = 0; /* Score of best match */ 85515 85675 int h; /* Hash value */ 85516 85676 85517 - 85677 + assert( nArg>=(-2) ); 85678 + assert( nArg>=(-1) || createFlag==0 ); 85518 85679 assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); 85519 85680 h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a); 85520 85681 85521 85682 /* First search for a match amongst the application-defined functions. 85522 85683 */ 85523 85684 p = functionSearch(&db->aFunc, h, zName, nName); 85524 85685 while( p ){ ................................................................................ 85556 85717 } 85557 85718 } 85558 85719 85559 85720 /* If the createFlag parameter is true and the search did not reveal an 85560 85721 ** exact match for the name, number of arguments and encoding, then add a 85561 85722 ** new entry to the hash table and return it. 85562 85723 */ 85563 - if( createFlag && (bestScore<6 || pBest->nArg!=nArg) && 85724 + if( createFlag && bestScore<FUNC_PERFECT_MATCH && 85564 85725 (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ 85565 85726 pBest->zName = (char *)&pBest[1]; 85566 85727 pBest->nArg = (u16)nArg; 85567 85728 pBest->iPrefEnc = enc; 85568 85729 memcpy(pBest->zName, zName, nName); 85569 85730 pBest->zName[nName] = 0; 85570 85731 sqlite3FuncDefInsert(&db->aFunc, pBest); ................................................................................ 97524 97685 } 97525 97686 } 97526 97687 97527 97688 /***** If we reach this point, flattening is permitted. *****/ 97528 97689 97529 97690 /* Authorize the subquery */ 97530 97691 pParse->zAuthContext = pSubitem->zName; 97531 - sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); 97692 + TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); 97693 + testcase( i==SQLITE_DENY ); 97532 97694 pParse->zAuthContext = zSavedAuthContext; 97533 97695 97534 97696 /* If the sub-query is a compound SELECT statement, then (by restrictions 97535 97697 ** 17 and 18 above) it must be a UNION ALL and the parent query must 97536 97698 ** be of the form: 97537 97699 ** 97538 97700 ** SELECT <expr-list> FROM (<sub-query>) <where-clause> ................................................................................ 129047 129209 } 129048 129210 129049 129211 /* Advance to the next output block */ 129050 129212 pLeaf->iBlock++; 129051 129213 pLeaf->key.n = 0; 129052 129214 pLeaf->block.n = 0; 129053 129215 129054 - nPrefix = 0; 129055 129216 nSuffix = nTerm; 129056 129217 nSpace = 1; 129057 129218 nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; 129058 129219 nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; 129059 129220 } 129060 129221 129061 129222 blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc); ................................................................................ 132382 132543 int eCoordType; 132383 132544 }; 132384 132545 132385 132546 /* Possible values for eCoordType: */ 132386 132547 #define RTREE_COORD_REAL32 0 132387 132548 #define RTREE_COORD_INT32 1 132388 132549 132550 +/* 132551 +** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will 132552 +** only deal with integer coordinates. No floating point operations 132553 +** will be done. 132554 +*/ 132555 +#ifdef SQLITE_RTREE_INT_ONLY 132556 + typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ 132557 + typedef int RtreeValue; /* Low accuracy coordinate */ 132558 +#else 132559 + typedef double RtreeDValue; /* High accuracy coordinate */ 132560 + typedef float RtreeValue; /* Low accuracy coordinate */ 132561 +#endif 132562 + 132389 132563 /* 132390 132564 ** The minimum number of cells allowed for a node is a third of the 132391 132565 ** maximum. In Gutman's notation: 132392 132566 ** 132393 132567 ** m = M/3 132394 132568 ** 132395 132569 ** If an R*-tree "Reinsert" operation is required, the same number of ................................................................................ 132417 132591 int iCell; /* Index of current cell in pNode */ 132418 132592 int iStrategy; /* Copy of idxNum search parameter */ 132419 132593 int nConstraint; /* Number of entries in aConstraint */ 132420 132594 RtreeConstraint *aConstraint; /* Search constraints. */ 132421 132595 }; 132422 132596 132423 132597 union RtreeCoord { 132424 - float f; 132598 + RtreeValue f; 132425 132599 int i; 132426 132600 }; 132427 132601 132428 132602 /* 132429 132603 ** The argument is an RtreeCoord. Return the value stored within the RtreeCoord 132430 -** formatted as a double. This macro assumes that local variable pRtree points 132431 -** to the Rtree structure associated with the RtreeCoord. 132604 +** formatted as a RtreeDValue (double or int64). This macro assumes that local 132605 +** variable pRtree points to the Rtree structure associated with the 132606 +** RtreeCoord. 132432 132607 */ 132433 -#define DCOORD(coord) ( \ 132434 - (pRtree->eCoordType==RTREE_COORD_REAL32) ? \ 132435 - ((double)coord.f) : \ 132436 - ((double)coord.i) \ 132437 -) 132608 +#ifdef SQLITE_RTREE_INT_ONLY 132609 +# define DCOORD(coord) ((RtreeDValue)coord.i) 132610 +#else 132611 +# define DCOORD(coord) ( \ 132612 + (pRtree->eCoordType==RTREE_COORD_REAL32) ? \ 132613 + ((double)coord.f) : \ 132614 + ((double)coord.i) \ 132615 + ) 132616 +#endif 132438 132617 132439 132618 /* 132440 132619 ** A search constraint. 132441 132620 */ 132442 132621 struct RtreeConstraint { 132443 132622 int iCoord; /* Index of constrained coordinate */ 132444 132623 int op; /* Constraining operation */ 132445 - double rValue; /* Constraint value. */ 132446 - int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *); 132624 + RtreeDValue rValue; /* Constraint value. */ 132625 + int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); 132447 132626 sqlite3_rtree_geometry *pGeom; /* Constraint callback argument for a MATCH */ 132448 132627 }; 132449 132628 132450 132629 /* Possible values for RtreeConstraint.op */ 132451 132630 #define RTREE_EQ 0x41 132452 132631 #define RTREE_LE 0x42 132453 132632 #define RTREE_LT 0x43 ................................................................................ 132487 132666 /* 132488 132667 ** An instance of this structure must be supplied as a blob argument to 132489 132668 ** the right-hand-side of an SQL MATCH operator used to constrain an 132490 132669 ** r-tree query. 132491 132670 */ 132492 132671 struct RtreeMatchArg { 132493 132672 u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ 132494 - int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *); 132673 + int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *); 132495 132674 void *pContext; 132496 132675 int nParam; 132497 - double aParam[1]; 132676 + RtreeDValue aParam[1]; 132498 132677 }; 132499 132678 132500 132679 /* 132501 132680 ** When a geometry callback is created (see sqlite3_rtree_geometry_callback), 132502 132681 ** a single instance of the following structure is allocated. It is used 132503 132682 ** as the context for the user-function created by by s_r_g_c(). The object 132504 132683 ** is eventually deleted by the destructor mechanism provided by 132505 132684 ** sqlite3_create_function_v2() (which is called by s_r_g_c() to create 132506 132685 ** the geometry callback function). 132507 132686 */ 132508 132687 struct RtreeGeomCallback { 132509 - int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *); 132688 + int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); 132510 132689 void *pContext; 132511 132690 }; 132512 132691 132513 132692 #ifndef MAX 132514 132693 # define MAX(x,y) ((x) < (y) ? (y) : (x)) 132515 132694 #endif 132516 132695 #ifndef MIN ................................................................................ 133068 133247 static int testRtreeGeom( 133069 133248 Rtree *pRtree, /* R-Tree object */ 133070 133249 RtreeConstraint *pConstraint, /* MATCH constraint to test */ 133071 133250 RtreeCell *pCell, /* Cell to test */ 133072 133251 int *pbRes /* OUT: Test result */ 133073 133252 ){ 133074 133253 int i; 133075 - double aCoord[RTREE_MAX_DIMENSIONS*2]; 133254 + RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2]; 133076 133255 int nCoord = pRtree->nDim*2; 133077 133256 133078 133257 assert( pConstraint->op==RTREE_MATCH ); 133079 133258 assert( pConstraint->pGeom ); 133080 133259 133081 133260 for(i=0; i<nCoord; i++){ 133082 133261 aCoord[i] = DCOORD(pCell->aCoord[i]); ................................................................................ 133098 133277 int ii; 133099 133278 int bRes = 0; 133100 133279 int rc = SQLITE_OK; 133101 133280 133102 133281 nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); 133103 133282 for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){ 133104 133283 RtreeConstraint *p = &pCursor->aConstraint[ii]; 133105 - double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]); 133106 - double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]); 133284 + RtreeDValue cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]); 133285 + RtreeDValue cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]); 133107 133286 133108 133287 assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 133109 133288 || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH 133110 133289 ); 133111 133290 133112 133291 switch( p->op ){ 133113 133292 case RTREE_LE: case RTREE_LT: ................................................................................ 133151 133330 RtreeCell cell; 133152 133331 int ii; 133153 133332 *pbEof = 0; 133154 133333 133155 133334 nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell); 133156 133335 for(ii=0; ii<pCursor->nConstraint; ii++){ 133157 133336 RtreeConstraint *p = &pCursor->aConstraint[ii]; 133158 - double coord = DCOORD(cell.aCoord[p->iCoord]); 133337 + RtreeDValue coord = DCOORD(cell.aCoord[p->iCoord]); 133159 133338 int res; 133160 133339 assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 133161 133340 || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH 133162 133341 ); 133163 133342 switch( p->op ){ 133164 133343 case RTREE_LE: res = (coord<=p->rValue); break; 133165 133344 case RTREE_LT: res = (coord<p->rValue); break; ................................................................................ 133349 133528 133350 133529 if( i==0 ){ 133351 133530 i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell); 133352 133531 sqlite3_result_int64(ctx, iRowid); 133353 133532 }else{ 133354 133533 RtreeCoord c; 133355 133534 nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c); 133535 +#ifndef SQLITE_RTREE_INT_ONLY 133356 133536 if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ 133357 133537 sqlite3_result_double(ctx, c.f); 133358 - }else{ 133538 + }else 133539 +#endif 133540 + { 133359 133541 assert( pRtree->eCoordType==RTREE_COORD_INT32 ); 133360 133542 sqlite3_result_int(ctx, c.i); 133361 133543 } 133362 133544 } 133363 133545 133364 133546 return SQLITE_OK; 133365 133547 } ................................................................................ 133398 133580 133399 133581 /* Check that value is actually a blob. */ 133400 133582 if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; 133401 133583 133402 133584 /* Check that the blob is roughly the right size. */ 133403 133585 nBlob = sqlite3_value_bytes(pValue); 133404 133586 if( nBlob<(int)sizeof(RtreeMatchArg) 133405 - || ((nBlob-sizeof(RtreeMatchArg))%sizeof(double))!=0 133587 + || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0 133406 133588 ){ 133407 133589 return SQLITE_ERROR; 133408 133590 } 133409 133591 133410 133592 pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc( 133411 133593 sizeof(sqlite3_rtree_geometry) + nBlob 133412 133594 ); 133413 133595 if( !pGeom ) return SQLITE_NOMEM; 133414 133596 memset(pGeom, 0, sizeof(sqlite3_rtree_geometry)); 133415 133597 p = (RtreeMatchArg *)&pGeom[1]; 133416 133598 133417 133599 memcpy(p, sqlite3_value_blob(pValue), nBlob); 133418 133600 if( p->magic!=RTREE_GEOMETRY_MAGIC 133419 - || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(double)) 133601 + || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(RtreeDValue)) 133420 133602 ){ 133421 133603 sqlite3_free(pGeom); 133422 133604 return SQLITE_ERROR; 133423 133605 } 133424 133606 133425 133607 pGeom->pContext = p->pContext; 133426 133608 pGeom->nParam = p->nParam; ................................................................................ 133484 133666 ** an sqlite3_rtree_geometry_callback() SQL user function. 133485 133667 */ 133486 133668 rc = deserializeGeometry(argv[ii], p); 133487 133669 if( rc!=SQLITE_OK ){ 133488 133670 break; 133489 133671 } 133490 133672 }else{ 133673 +#ifdef SQLITE_RTREE_INT_ONLY 133674 + p->rValue = sqlite3_value_int64(argv[ii]); 133675 +#else 133491 133676 p->rValue = sqlite3_value_double(argv[ii]); 133677 +#endif 133492 133678 } 133493 133679 } 133494 133680 } 133495 133681 } 133496 133682 133497 133683 if( rc==SQLITE_OK ){ 133498 133684 pCsr->pNode = 0; ................................................................................ 133618 133804 pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1)); 133619 133805 return rc; 133620 133806 } 133621 133807 133622 133808 /* 133623 133809 ** Return the N-dimensional volumn of the cell stored in *p. 133624 133810 */ 133625 -static float cellArea(Rtree *pRtree, RtreeCell *p){ 133626 - float area = 1.0; 133811 +static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ 133812 + RtreeDValue area = (RtreeDValue)1; 133627 133813 int ii; 133628 133814 for(ii=0; ii<(pRtree->nDim*2); ii+=2){ 133629 - area = (float)(area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]))); 133815 + area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]))); 133630 133816 } 133631 133817 return area; 133632 133818 } 133633 133819 133634 133820 /* 133635 133821 ** Return the margin length of cell p. The margin length is the sum 133636 133822 ** of the objects size in each dimension. 133637 133823 */ 133638 -static float cellMargin(Rtree *pRtree, RtreeCell *p){ 133639 - float margin = 0.0; 133824 +static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){ 133825 + RtreeDValue margin = (RtreeDValue)0; 133640 133826 int ii; 133641 133827 for(ii=0; ii<(pRtree->nDim*2); ii+=2){ 133642 - margin += (float)(DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); 133828 + margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); 133643 133829 } 133644 133830 return margin; 133645 133831 } 133646 133832 133647 133833 /* 133648 133834 ** Store the union of cells p1 and p2 in p1. 133649 133835 */ ................................................................................ 133680 133866 } 133681 133867 return 1; 133682 133868 } 133683 133869 133684 133870 /* 133685 133871 ** Return the amount cell p would grow by if it were unioned with pCell. 133686 133872 */ 133687 -static float cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ 133688 - float area; 133873 +static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ 133874 + RtreeDValue area; 133689 133875 RtreeCell cell; 133690 133876 memcpy(&cell, p, sizeof(RtreeCell)); 133691 133877 area = cellArea(pRtree, &cell); 133692 133878 cellUnion(pRtree, &cell, pCell); 133693 133879 return (cellArea(pRtree, &cell)-area); 133694 133880 } 133695 133881 133696 133882 #if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT 133697 -static float cellOverlap( 133883 +static RtreeDValue cellOverlap( 133698 133884 Rtree *pRtree, 133699 133885 RtreeCell *p, 133700 133886 RtreeCell *aCell, 133701 133887 int nCell, 133702 133888 int iExclude 133703 133889 ){ 133704 133890 int ii; 133705 - float overlap = 0.0; 133891 + RtreeDValue overlap = 0.0; 133706 133892 for(ii=0; ii<nCell; ii++){ 133707 133893 #if VARIANT_RSTARTREE_CHOOSESUBTREE 133708 133894 if( ii!=iExclude ) 133709 133895 #else 133710 133896 assert( iExclude==-1 ); 133711 133897 UNUSED_PARAMETER(iExclude); 133712 133898 #endif 133713 133899 { 133714 133900 int jj; 133715 - float o = 1.0; 133901 + RtreeDValue o = (RtreeDValue)1; 133716 133902 for(jj=0; jj<(pRtree->nDim*2); jj+=2){ 133717 - double x1; 133718 - double x2; 133903 + RtreeDValue x1, x2; 133719 133904 133720 133905 x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); 133721 133906 x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); 133722 133907 133723 133908 if( x2<x1 ){ 133724 133909 o = 0.0; 133725 133910 break; 133726 133911 }else{ 133727 - o = o * (float)(x2-x1); 133912 + o = o * (x2-x1); 133728 133913 } 133729 133914 } 133730 133915 overlap += o; 133731 133916 } 133732 133917 } 133733 133918 return overlap; 133734 133919 } 133735 133920 #endif 133736 133921 133737 133922 #if VARIANT_RSTARTREE_CHOOSESUBTREE 133738 -static float cellOverlapEnlargement( 133923 +static RtreeDValue cellOverlapEnlargement( 133739 133924 Rtree *pRtree, 133740 133925 RtreeCell *p, 133741 133926 RtreeCell *pInsert, 133742 133927 RtreeCell *aCell, 133743 133928 int nCell, 133744 133929 int iExclude 133745 133930 ){ 133746 - double before; 133747 - double after; 133931 + RtreeDValue before, after; 133748 133932 before = cellOverlap(pRtree, p, aCell, nCell, iExclude); 133749 133933 cellUnion(pRtree, p, pInsert); 133750 133934 after = cellOverlap(pRtree, p, aCell, nCell, iExclude); 133751 - return (float)(after-before); 133935 + return (after-before); 133752 133936 } 133753 133937 #endif 133754 133938 133755 133939 133756 133940 /* 133757 133941 ** This function implements the ChooseLeaf algorithm from Gutman[84]. 133758 133942 ** ChooseSubTree in r*tree terminology. ................................................................................ 133768 133952 RtreeNode *pNode; 133769 133953 rc = nodeAcquire(pRtree, 1, 0, &pNode); 133770 133954 133771 133955 for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ 133772 133956 int iCell; 133773 133957 sqlite3_int64 iBest = 0; 133774 133958 133775 - float fMinGrowth = 0.0; 133776 - float fMinArea = 0.0; 133959 + RtreeDValue fMinGrowth = 0.0; 133960 + RtreeDValue fMinArea = 0.0; 133777 133961 #if VARIANT_RSTARTREE_CHOOSESUBTREE 133778 - float fMinOverlap = 0.0; 133779 - float overlap; 133962 + RtreeDValue fMinOverlap = 0.0; 133963 + RtreeDValue overlap; 133780 133964 #endif 133781 133965 133782 133966 int nCell = NCELL(pNode); 133783 133967 RtreeCell cell; 133784 133968 RtreeNode *pChild; 133785 133969 133786 133970 RtreeCell *aCell = 0; ................................................................................ 133803 133987 133804 133988 /* Select the child node which will be enlarged the least if pCell 133805 133989 ** is inserted into it. Resolve ties by choosing the entry with 133806 133990 ** the smallest area. 133807 133991 */ 133808 133992 for(iCell=0; iCell<nCell; iCell++){ 133809 133993 int bBest = 0; 133810 - float growth; 133811 - float area; 133994 + RtreeDValue growth; 133995 + RtreeDValue area; 133812 133996 nodeGetCell(pRtree, pNode, iCell, &cell); 133813 133997 growth = cellGrowth(pRtree, &cell, pCell); 133814 133998 area = cellArea(pRtree, &cell); 133815 133999 133816 134000 #if VARIANT_RSTARTREE_CHOOSESUBTREE 133817 134001 if( ii==(pRtree->iDepth-1) ){ 133818 134002 overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell); ................................................................................ 133931 134115 int nCell, 133932 134116 int *piLeftSeed, 133933 134117 int *piRightSeed 133934 134118 ){ 133935 134119 int i; 133936 134120 int iLeftSeed = 0; 133937 134121 int iRightSeed = 1; 133938 - float maxNormalInnerWidth = 0.0; 134122 + RtreeDValue maxNormalInnerWidth = (RtreeDValue)0; 133939 134123 133940 134124 /* Pick two "seed" cells from the array of cells. The algorithm used 133941 134125 ** here is the LinearPickSeeds algorithm from Gutman[1984]. The 133942 134126 ** indices of the two seed cells in the array are stored in local 133943 134127 ** variables iLeftSeek and iRightSeed. 133944 134128 */ 133945 134129 for(i=0; i<pRtree->nDim; i++){ 133946 - float x1 = DCOORD(aCell[0].aCoord[i*2]); 133947 - float x2 = DCOORD(aCell[0].aCoord[i*2+1]); 133948 - float x3 = x1; 133949 - float x4 = x2; 134130 + RtreeDValue x1 = DCOORD(aCell[0].aCoord[i*2]); 134131 + RtreeDValue x2 = DCOORD(aCell[0].aCoord[i*2+1]); 134132 + RtreeDValue x3 = x1; 134133 + RtreeDValue x4 = x2; 133950 134134 int jj; 133951 134135 133952 134136 int iCellLeft = 0; 133953 134137 int iCellRight = 0; 133954 134138 133955 134139 for(jj=1; jj<nCell; jj++){ 133956 - float left = DCOORD(aCell[jj].aCoord[i*2]); 133957 - float right = DCOORD(aCell[jj].aCoord[i*2+1]); 134140 + RtreeDValue left = DCOORD(aCell[jj].aCoord[i*2]); 134141 + RtreeDValue right = DCOORD(aCell[jj].aCoord[i*2+1]); 133958 134142 133959 134143 if( left<x1 ) x1 = left; 133960 134144 if( right>x4 ) x4 = right; 133961 134145 if( left>x3 ){ 133962 134146 x3 = left; 133963 134147 iCellRight = jj; 133964 134148 } ................................................................................ 133965 134149 if( right<x2 ){ 133966 134150 x2 = right; 133967 134151 iCellLeft = jj; 133968 134152 } 133969 134153 } 133970 134154 133971 134155 if( x4!=x1 ){ 133972 - float normalwidth = (x3 - x2) / (x4 - x1); 134156 + RtreeDValue normalwidth = (x3 - x2) / (x4 - x1); 133973 134157 if( normalwidth>maxNormalInnerWidth ){ 133974 134158 iLeftSeed = iCellLeft; 133975 134159 iRightSeed = iCellRight; 133976 134160 } 133977 134161 } 133978 134162 } 133979 134163 ................................................................................ 133994 134178 RtreeCell *pLeftBox, 133995 134179 RtreeCell *pRightBox, 133996 134180 int *aiUsed 133997 134181 ){ 133998 134182 #define FABS(a) ((a)<0.0?-1.0*(a):(a)) 133999 134183 134000 134184 int iSelect = -1; 134001 - float fDiff; 134185 + RtreeDValue fDiff; 134002 134186 int ii; 134003 134187 for(ii=0; ii<nCell; ii++){ 134004 134188 if( aiUsed[ii]==0 ){ 134005 - float left = cellGrowth(pRtree, pLeftBox, &aCell[ii]); 134006 - float right = cellGrowth(pRtree, pLeftBox, &aCell[ii]); 134007 - float diff = FABS(right-left); 134189 + RtreeDValue left = cellGrowth(pRtree, pLeftBox, &aCell[ii]); 134190 + RtreeDValue right = cellGrowth(pRtree, pLeftBox, &aCell[ii]); 134191 + RtreeDValue diff = FABS(right-left); 134008 134192 if( iSelect<0 || diff>fDiff ){ 134009 134193 fDiff = diff; 134010 134194 iSelect = ii; 134011 134195 } 134012 134196 } 134013 134197 } 134014 134198 aiUsed[iSelect] = 1; ................................................................................ 134027 134211 int *piRightSeed 134028 134212 ){ 134029 134213 int ii; 134030 134214 int jj; 134031 134215 134032 134216 int iLeftSeed = 0; 134033 134217 int iRightSeed = 1; 134034 - float fWaste = 0.0; 134218 + RtreeDValue fWaste = 0.0; 134035 134219 134036 134220 for(ii=0; ii<nCell; ii++){ 134037 134221 for(jj=ii+1; jj<nCell; jj++){ 134038 - float right = cellArea(pRtree, &aCell[jj]); 134039 - float growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]); 134040 - float waste = growth - right; 134222 + RtreeDValue right = cellArea(pRtree, &aCell[jj]); 134223 + RtreeDValue growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]); 134224 + RtreeDValue waste = growth - right; 134041 134225 134042 134226 if( waste>fWaste ){ 134043 134227 iLeftSeed = ii; 134044 134228 iRightSeed = jj; 134045 134229 fWaste = waste; 134046 134230 } 134047 134231 } ................................................................................ 134068 134252 ** 134069 134253 ** The aSpare array is used as temporary working space by the 134070 134254 ** sorting algorithm. 134071 134255 */ 134072 134256 static void SortByDistance( 134073 134257 int *aIdx, 134074 134258 int nIdx, 134075 - float *aDistance, 134259 + RtreeDValue *aDistance, 134076 134260 int *aSpare 134077 134261 ){ 134078 134262 if( nIdx>1 ){ 134079 134263 int iLeft = 0; 134080 134264 int iRight = 0; 134081 134265 134082 134266 int nLeft = nIdx/2; ................................................................................ 134094 134278 if( iLeft==nLeft ){ 134095 134279 aIdx[iLeft+iRight] = aRight[iRight]; 134096 134280 iRight++; 134097 134281 }else if( iRight==nRight ){ 134098 134282 aIdx[iLeft+iRight] = aLeft[iLeft]; 134099 134283 iLeft++; 134100 134284 }else{ 134101 - float fLeft = aDistance[aLeft[iLeft]]; 134102 - float fRight = aDistance[aRight[iRight]]; 134285 + RtreeDValue fLeft = aDistance[aLeft[iLeft]]; 134286 + RtreeDValue fRight = aDistance[aRight[iRight]]; 134103 134287 if( fLeft<fRight ){ 134104 134288 aIdx[iLeft+iRight] = aLeft[iLeft]; 134105 134289 iLeft++; 134106 134290 }else{ 134107 134291 aIdx[iLeft+iRight] = aRight[iRight]; 134108 134292 iRight++; 134109 134293 } ................................................................................ 134111 134295 } 134112 134296 134113 134297 #if 0 134114 134298 /* Check that the sort worked */ 134115 134299 { 134116 134300 int jj; 134117 134301 for(jj=1; jj<nIdx; jj++){ 134118 - float left = aDistance[aIdx[jj-1]]; 134119 - float right = aDistance[aIdx[jj]]; 134302 + RtreeDValue left = aDistance[aIdx[jj-1]]; 134303 + RtreeDValue right = aDistance[aIdx[jj]]; 134120 134304 assert( left<=right ); 134121 134305 } 134122 134306 } 134123 134307 #endif 134124 134308 } 134125 134309 } 134126 134310 ................................................................................ 134155 134339 134156 134340 SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare); 134157 134341 SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare); 134158 134342 134159 134343 memcpy(aSpare, aLeft, sizeof(int)*nLeft); 134160 134344 aLeft = aSpare; 134161 134345 while( iLeft<nLeft || iRight<nRight ){ 134162 - double xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]); 134163 - double xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]); 134164 - double xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]); 134165 - double xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]); 134346 + RtreeDValue xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]); 134347 + RtreeDValue xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]); 134348 + RtreeDValue xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]); 134349 + RtreeDValue xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]); 134166 134350 if( (iLeft!=nLeft) && ((iRight==nRight) 134167 134351 || (xleft1<xright1) 134168 134352 || (xleft1==xright1 && xleft2<xright2) 134169 134353 )){ 134170 134354 aIdx[iLeft+iRight] = aLeft[iLeft]; 134171 134355 iLeft++; 134172 134356 }else{ ................................................................................ 134176 134360 } 134177 134361 134178 134362 #if 0 134179 134363 /* Check that the sort worked */ 134180 134364 { 134181 134365 int jj; 134182 134366 for(jj=1; jj<nIdx; jj++){ 134183 - float xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2]; 134184 - float xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1]; 134185 - float xright1 = aCell[aIdx[jj]].aCoord[iDim*2]; 134186 - float xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1]; 134367 + RtreeDValue xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2]; 134368 + RtreeDValue xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1]; 134369 + RtreeDValue xright1 = aCell[aIdx[jj]].aCoord[iDim*2]; 134370 + RtreeDValue xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1]; 134187 134371 assert( xleft1<=xright1 && (xleft1<xright1 || xleft2<=xright2) ); 134188 134372 } 134189 134373 } 134190 134374 #endif 134191 134375 } 134192 134376 } 134193 134377 ................................................................................ 134206 134390 ){ 134207 134391 int **aaSorted; 134208 134392 int *aSpare; 134209 134393 int ii; 134210 134394 134211 134395 int iBestDim = 0; 134212 134396 int iBestSplit = 0; 134213 - float fBestMargin = 0.0; 134397 + RtreeDValue fBestMargin = 0.0; 134214 134398 134215 134399 int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); 134216 134400 134217 134401 aaSorted = (int **)sqlite3_malloc(nByte); 134218 134402 if( !aaSorted ){ 134219 134403 return SQLITE_NOMEM; 134220 134404 } ................................................................................ 134227 134411 for(jj=0; jj<nCell; jj++){ 134228 134412 aaSorted[ii][jj] = jj; 134229 134413 } 134230 134414 SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare); 134231 134415 } 134232 134416 134233 134417 for(ii=0; ii<pRtree->nDim; ii++){ 134234 - float margin = 0.0; 134235 - float fBestOverlap = 0.0; 134236 - float fBestArea = 0.0; 134418 + RtreeDValue margin = 0.0; 134419 + RtreeDValue fBestOverlap = 0.0; 134420 + RtreeDValue fBestArea = 0.0; 134237 134421 int iBestLeft = 0; 134238 134422 int nLeft; 134239 134423 134240 134424 for( 134241 134425 nLeft=RTREE_MINCELLS(pRtree); 134242 134426 nLeft<=(nCell-RTREE_MINCELLS(pRtree)); 134243 134427 nLeft++ 134244 134428 ){ 134245 134429 RtreeCell left; 134246 134430 RtreeCell right; 134247 134431 int kk; 134248 - float overlap; 134249 - float area; 134432 + RtreeDValue overlap; 134433 + RtreeDValue area; 134250 134434 134251 134435 memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell)); 134252 134436 memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell)); 134253 134437 for(kk=1; kk<(nCell-1); kk++){ 134254 134438 if( kk<nLeft ){ 134255 134439 cellUnion(pRtree, &left, &aCell[aaSorted[ii][kk]]); 134256 134440 }else{ ................................................................................ 134325 134509 nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]); 134326 134510 aiUsed[iLeftSeed] = 1; 134327 134511 aiUsed[iRightSeed] = 1; 134328 134512 134329 134513 for(i=nCell-2; i>0; i--){ 134330 134514 RtreeCell *pNext; 134331 134515 pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed); 134332 - float diff = 134516 + RtreeDValue diff = 134333 134517 cellGrowth(pRtree, pBboxLeft, pNext) - 134334 134518 cellGrowth(pRtree, pBboxRight, pNext) 134335 134519 ; 134336 134520 if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i) 134337 134521 || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i)) 134338 134522 ){ 134339 134523 nodeInsertCell(pRtree, pRight, pNext); ................................................................................ 134658 134842 RtreeNode *pNode, 134659 134843 RtreeCell *pCell, 134660 134844 int iHeight 134661 134845 ){ 134662 134846 int *aOrder; 134663 134847 int *aSpare; 134664 134848 RtreeCell *aCell; 134665 - float *aDistance; 134849 + RtreeDValue *aDistance; 134666 134850 int nCell; 134667 - float aCenterCoord[RTREE_MAX_DIMENSIONS]; 134851 + RtreeDValue aCenterCoord[RTREE_MAX_DIMENSIONS]; 134668 134852 int iDim; 134669 134853 int ii; 134670 134854 int rc = SQLITE_OK; 134855 + int n; 134671 134856 134672 - memset(aCenterCoord, 0, sizeof(float)*RTREE_MAX_DIMENSIONS); 134857 + memset(aCenterCoord, 0, sizeof(RtreeDValue)*RTREE_MAX_DIMENSIONS); 134673 134858 134674 134859 nCell = NCELL(pNode)+1; 134860 + n = (nCell+1)&(~1); 134675 134861 134676 134862 /* Allocate the buffers used by this operation. The allocation is 134677 134863 ** relinquished before this function returns. 134678 134864 */ 134679 - aCell = (RtreeCell *)sqlite3_malloc(nCell * ( 134680 - sizeof(RtreeCell) + /* aCell array */ 134681 - sizeof(int) + /* aOrder array */ 134682 - sizeof(int) + /* aSpare array */ 134683 - sizeof(float) /* aDistance array */ 134865 + aCell = (RtreeCell *)sqlite3_malloc(n * ( 134866 + sizeof(RtreeCell) + /* aCell array */ 134867 + sizeof(int) + /* aOrder array */ 134868 + sizeof(int) + /* aSpare array */ 134869 + sizeof(RtreeDValue) /* aDistance array */ 134684 134870 )); 134685 134871 if( !aCell ){ 134686 134872 return SQLITE_NOMEM; 134687 134873 } 134688 - aOrder = (int *)&aCell[nCell]; 134689 - aSpare = (int *)&aOrder[nCell]; 134690 - aDistance = (float *)&aSpare[nCell]; 134874 + aOrder = (int *)&aCell[n]; 134875 + aSpare = (int *)&aOrder[n]; 134876 + aDistance = (RtreeDValue *)&aSpare[n]; 134691 134877 134692 134878 for(ii=0; ii<nCell; ii++){ 134693 134879 if( ii==(nCell-1) ){ 134694 134880 memcpy(&aCell[ii], pCell, sizeof(RtreeCell)); 134695 134881 }else{ 134696 134882 nodeGetCell(pRtree, pNode, ii, &aCell[ii]); 134697 134883 } 134698 134884 aOrder[ii] = ii; 134699 134885 for(iDim=0; iDim<pRtree->nDim; iDim++){ 134700 - aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2]); 134701 - aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2+1]); 134886 + aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); 134887 + aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); 134702 134888 } 134703 134889 } 134704 134890 for(iDim=0; iDim<pRtree->nDim; iDim++){ 134705 - aCenterCoord[iDim] = (float)(aCenterCoord[iDim]/((float)nCell*2.0)); 134891 + aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2)); 134706 134892 } 134707 134893 134708 134894 for(ii=0; ii<nCell; ii++){ 134709 134895 aDistance[ii] = 0.0; 134710 134896 for(iDim=0; iDim<pRtree->nDim; iDim++){ 134711 - float coord = (float)(DCOORD(aCell[ii].aCoord[iDim*2+1]) - 134712 - DCOORD(aCell[ii].aCoord[iDim*2])); 134897 + RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - 134898 + DCOORD(aCell[ii].aCoord[iDim*2])); 134713 134899 aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); 134714 134900 } 134715 134901 } 134716 134902 134717 134903 SortByDistance(aOrder, nCell, aDistance, aSpare); 134718 134904 nodeZero(pRtree, pNode); 134719 134905 ................................................................................ 134947 135133 ** conflict-handling mode specified by the user. 134948 135134 */ 134949 135135 if( nData>1 ){ 134950 135136 int ii; 134951 135137 134952 135138 /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */ 134953 135139 assert( nData==(pRtree->nDim*2 + 3) ); 135140 +#ifndef SQLITE_RTREE_INT_ONLY 134954 135141 if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ 134955 135142 for(ii=0; ii<(pRtree->nDim*2); ii+=2){ 134956 - cell.aCoord[ii].f = (float)sqlite3_value_double(azData[ii+3]); 134957 - cell.aCoord[ii+1].f = (float)sqlite3_value_double(azData[ii+4]); 135143 + cell.aCoord[ii].f = (RtreeValue)sqlite3_value_double(azData[ii+3]); 135144 + cell.aCoord[ii+1].f = (RtreeValue)sqlite3_value_double(azData[ii+4]); 134958 135145 if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){ 134959 135146 rc = SQLITE_CONSTRAINT; 134960 135147 goto constraint; 134961 135148 } 134962 135149 } 134963 - }else{ 135150 + }else 135151 +#endif 135152 + { 134964 135153 for(ii=0; ii<(pRtree->nDim*2); ii+=2){ 134965 135154 cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]); 134966 135155 cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]); 134967 135156 if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){ 134968 135157 rc = SQLITE_CONSTRAINT; 134969 135158 goto constraint; 134970 135159 } ................................................................................ 135354 135543 RtreeCell cell; 135355 135544 int jj; 135356 135545 135357 135546 nodeGetCell(&tree, &node, ii, &cell); 135358 135547 sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid); 135359 135548 nCell = (int)strlen(zCell); 135360 135549 for(jj=0; jj<tree.nDim*2; jj++){ 135361 - sqlite3_snprintf(512-nCell,&zCell[nCell]," %f",(double)cell.aCoord[jj].f); 135550 +#ifndef SQLITE_RTREE_INT_ONLY 135551 + sqlite3_snprintf(512-nCell,&zCell[nCell], " %f", 135552 + (double)cell.aCoord[jj].f); 135553 +#else 135554 + sqlite3_snprintf(512-nCell,&zCell[nCell], " %d", 135555 + cell.aCoord[jj].i); 135556 +#endif 135362 135557 nCell = (int)strlen(zCell); 135363 135558 } 135364 135559 135365 135560 if( zText ){ 135366 135561 char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell); 135367 135562 sqlite3_free(zText); 135368 135563 zText = zTextNew; ................................................................................ 135396 135591 int rc; 135397 135592 135398 135593 rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); 135399 135594 if( rc==SQLITE_OK ){ 135400 135595 rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); 135401 135596 } 135402 135597 if( rc==SQLITE_OK ){ 135598 +#ifdef SQLITE_RTREE_INT_ONLY 135599 + void *c = (void *)RTREE_COORD_INT32; 135600 +#else 135403 135601 void *c = (void *)RTREE_COORD_REAL32; 135602 +#endif 135404 135603 rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0); 135405 135604 } 135406 135605 if( rc==SQLITE_OK ){ 135407 135606 void *c = (void *)RTREE_COORD_INT32; 135408 135607 rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0); 135409 135608 } 135410 135609 ................................................................................ 135430 135629 ** table MATCH operators. 135431 135630 */ 135432 135631 static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ 135433 135632 RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); 135434 135633 RtreeMatchArg *pBlob; 135435 135634 int nBlob; 135436 135635 135437 - nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(double); 135636 + nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue); 135438 135637 pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob); 135439 135638 if( !pBlob ){ 135440 135639 sqlite3_result_error_nomem(ctx); 135441 135640 }else{ 135442 135641 int i; 135443 135642 pBlob->magic = RTREE_GEOMETRY_MAGIC; 135444 135643 pBlob->xGeom = pGeomCtx->xGeom; 135445 135644 pBlob->pContext = pGeomCtx->pContext; 135446 135645 pBlob->nParam = nArg; 135447 135646 for(i=0; i<nArg; i++){ 135647 +#ifdef SQLITE_RTREE_INT_ONLY 135648 + pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); 135649 +#else 135448 135650 pBlob->aParam[i] = sqlite3_value_double(aArg[i]); 135651 +#endif 135449 135652 } 135450 135653 sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free); 135451 135654 } 135452 135655 } 135453 135656 135454 135657 /* 135455 135658 ** Register a new geometry function for use with the r-tree MATCH operator. 135456 135659 */ 135457 135660 SQLITE_API int sqlite3_rtree_geometry_callback( 135458 135661 sqlite3 *db, 135459 135662 const char *zGeom, 135460 - int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *), 135663 + int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue *, int *), 135461 135664 void *pContext 135462 135665 ){ 135463 135666 RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ 135464 135667 135465 135668 /* Allocate and populate the context object. */ 135466 135669 pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); 135467 135670 if( !pGeomCtx ) return SQLITE_NOMEM;

Changes to src/sqlite3.h

105 105 ** 106 106 ** See also: [sqlite3_libversion()], 107 107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()], 108 108 ** [sqlite_version()] and [sqlite_source_id()]. 109 109 */ 110 110 #define SQLITE_VERSION "3.7.12" 111 111 #define SQLITE_VERSION_NUMBER 3007012 112 -#define SQLITE_SOURCE_ID "2012-03-31 19:12:23 af602d87736b52802a4e760ffeeaa28112b99d9a" 112 +#define SQLITE_SOURCE_ID "2012-04-17 09:09:33 8e2363ad76446e863d03ead91fd621e59d5cb495" 113 113 114 114 /* 115 115 ** CAPI3REF: Run-Time Library Version Numbers 116 116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid 117 117 ** 118 118 ** These interfaces provide the same information as the [SQLITE_VERSION], 119 119 ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros ................................................................................ 1543 1543 ** connection is opened. If it is globally disabled, filenames are 1544 1544 ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the 1545 1545 ** database connection is opened. By default, URI handling is globally 1546 1546 ** disabled. The default value may be changed by compiling with the 1547 1547 ** [SQLITE_USE_URI] symbol defined. 1548 1548 ** 1549 1549 ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] 1550 -** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFNIG_GETPCACHE 1550 +** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE 1551 1551 ** <dd> These options are obsolete and should not be used by new code. 1552 1552 ** They are retained for backwards compatibility but are now no-ops. 1553 1553 ** </dl> 1554 1554 */ 1555 1555 #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ 1556 1556 #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ 1557 1557 #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ ................................................................................ 6981 6981 ** R-Tree geometry query as follows: 6982 6982 ** 6983 6983 ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) 6984 6984 */ 6985 6985 SQLITE_API int sqlite3_rtree_geometry_callback( 6986 6986 sqlite3 *db, 6987 6987 const char *zGeom, 6988 - int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes), 6988 +#ifdef SQLITE_RTREE_INT_ONLY 6989 + int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), 6990 +#else 6991 + int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), 6992 +#endif 6989 6993 void *pContext 6990 6994 ); 6991 6995 6992 6996 6993 6997 /* 6994 6998 ** A pointer to a structure of the following type is passed as the first 6995 6999 ** argument to callbacks registered using rtree_geometry_callback().