Fossil SCM

Merged in latest trunk to simplify code review and ease potential upcoming merge to trunk.

stephan 2022-04-19 11:41 UTC markdown-footnotes merge
Commit 8a4b099fb42efb62dad7d4bde8d7e4532d93f521e0269d5a1c8b0e3614175f29
81 files changed +1 -1 +244 -230 +662 -117 +2271 -1115 +232 -45 +3 -3 +2 +1 -1 +5 -4 +1 -1 +1 -1 +46 -93 +118 -6 +3 -4 +193 -34 +72 -12 +1 +26 -15 -3 +7 -2 +200 -27 +11 -8 +27 -9 +3 -3 +23 -17 +200 -6 +8 -17 -4 +27 -6 +11 -2 +9 -7 +57 -49 +57 -49 +4 -1 +14 -11 +14 -11 +1 -2 +20 -13 +12 -3 +46 -16 +110 -42 +3 -3 +8 -5 +43 -29 +43 -29 +7 -1 +13 -9 +3 -3 +2 -2 +5 -6 +4 -2 +19 +17 -8 +2 -2 +3 +1 -1 +74 -216 +15 -12 +3 -1 -1 -196 +3 -1 +34 -32 +46 -9 +3 -3 +65 -66 +1 -1 +43 -20 +1 -1 +1 -1 +2 +5 -14 +6 -1 +73 +34 -25 +4 -4 +16 -11 +8 -8 +1 -1 +1 -1 +6 -5
+1 -1
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1
-2.18
1
+2.19
22
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 2.18
2
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 2.19
2
+244 -230
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -124,10 +124,19 @@
124124
#include <assert.h>
125125
#define count(X) (sizeof(X)/sizeof(X[0]))
126126
#ifndef M_PI
127127
# define M_PI 3.1415926535897932385
128128
#endif
129
+
130
+/* Limit the number of tokens in a single script to avoid run-away
131
+** macro expansion attacks. See forum post
132
+** https://pikchr.org/home/forumpost/ef8684c6955a411a
133
+*/
134
+#ifndef PIKCHR_TOKEN_LIMIT
135
+# define PIKCHR_TOKEN_LIMIT 100000
136
+#endif
137
+
129138
130139
/* Tag intentionally unused parameters with this macro to prevent
131140
** compiler warnings with -Wextra */
132141
#define UNUSED_PARAMETER(X) (void)(X)
133142
@@ -341,10 +350,11 @@
341350
/* Each call to the pikchr() subroutine uses an instance of the following
342351
** object to pass around context to all of its subroutines.
343352
*/
344353
struct Pik {
345354
unsigned nErr; /* Number of errors seen */
355
+ unsigned nToken; /* Number of tokens parsed */
346356
PToken sIn; /* Input Pikchr-language text */
347357
char *zOut; /* Result accumulates here */
348358
unsigned int nOut; /* Bytes written to zOut[] so far */
349359
unsigned int nOutAlloc; /* Space allocated to zOut[] */
350360
unsigned char eDir; /* Current direction */
@@ -479,11 +489,11 @@
479489
static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
480490
static PNum pik_dist(PPoint*,PPoint*);
481491
static void pik_add_macro(Pik*,PToken *pId,PToken *pCode);
482492
483493
484
-#line 510 "pikchr.c"
494
+#line 520 "pikchr.c"
485495
/**************** End of %include directives **********************************/
486496
/* These constants specify the various numeric values for terminal symbols.
487497
***************** Begin token definitions *************************************/
488498
#ifndef T_ID
489499
#define T_ID 1
@@ -1708,22 +1718,22 @@
17081718
** inside the C code.
17091719
*/
17101720
/********* Begin destructor definitions ***************************************/
17111721
case 99: /* statement_list */
17121722
{
1713
-#line 499 "pikchr.y"
1723
+#line 509 "pikchr.y"
17141724
pik_elist_free(p,(yypminor->yy227));
1715
-#line 1740 "pikchr.c"
1725
+#line 1750 "pikchr.c"
17161726
}
17171727
break;
17181728
case 100: /* statement */
17191729
case 101: /* unnamed_statement */
17201730
case 102: /* basetype */
17211731
{
1722
-#line 501 "pikchr.y"
1732
+#line 511 "pikchr.y"
17231733
pik_elem_free(p,(yypminor->yy36));
1724
-#line 1749 "pikchr.c"
1734
+#line 1759 "pikchr.c"
17251735
}
17261736
break;
17271737
/********* End destructor definitions *****************************************/
17281738
default: break; /* If no destructor action specified: do nothing */
17291739
}
@@ -1937,14 +1947,14 @@
19371947
#endif
19381948
while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
19391949
/* Here code is inserted which will execute if the parser
19401950
** stack every overflows */
19411951
/******** Begin %stack_overflow code ******************************************/
1942
-#line 533 "pikchr.y"
1952
+#line 543 "pikchr.y"
19431953
19441954
pik_error(p, 0, "parser stack overflow");
1945
-#line 1970 "pikchr.c"
1955
+#line 1980 "pikchr.c"
19461956
/******** End %stack_overflow code ********************************************/
19471957
pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
19481958
pik_parserCTX_STORE
19491959
}
19501960
@@ -2420,619 +2430,619 @@
24202430
** break;
24212431
*/
24222432
/********** Begin reduce actions **********************************************/
24232433
YYMINORTYPE yylhsminor;
24242434
case 0: /* document ::= statement_list */
2425
-#line 537 "pikchr.y"
2435
+#line 547 "pikchr.y"
24262436
{pik_render(p,yymsp[0].minor.yy227);}
2427
-#line 2452 "pikchr.c"
2437
+#line 2462 "pikchr.c"
24282438
break;
24292439
case 1: /* statement_list ::= statement */
2430
-#line 540 "pikchr.y"
2440
+#line 550 "pikchr.y"
24312441
{ yylhsminor.yy227 = pik_elist_append(p,0,yymsp[0].minor.yy36); }
2432
-#line 2457 "pikchr.c"
2442
+#line 2467 "pikchr.c"
24332443
yymsp[0].minor.yy227 = yylhsminor.yy227;
24342444
break;
24352445
case 2: /* statement_list ::= statement_list EOL statement */
2436
-#line 542 "pikchr.y"
2446
+#line 552 "pikchr.y"
24372447
{ yylhsminor.yy227 = pik_elist_append(p,yymsp[-2].minor.yy227,yymsp[0].minor.yy36); }
2438
-#line 2463 "pikchr.c"
2448
+#line 2473 "pikchr.c"
24392449
yymsp[-2].minor.yy227 = yylhsminor.yy227;
24402450
break;
24412451
case 3: /* statement ::= */
2442
-#line 545 "pikchr.y"
2452
+#line 555 "pikchr.y"
24432453
{ yymsp[1].minor.yy36 = 0; }
2444
-#line 2469 "pikchr.c"
2454
+#line 2479 "pikchr.c"
24452455
break;
24462456
case 4: /* statement ::= direction */
2447
-#line 546 "pikchr.y"
2457
+#line 556 "pikchr.y"
24482458
{ pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy36=0; }
2449
-#line 2474 "pikchr.c"
2459
+#line 2484 "pikchr.c"
24502460
yymsp[0].minor.yy36 = yylhsminor.yy36;
24512461
break;
24522462
case 5: /* statement ::= lvalue ASSIGN rvalue */
2453
-#line 547 "pikchr.y"
2463
+#line 557 "pikchr.y"
24542464
{pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy153,&yymsp[-1].minor.yy0); yylhsminor.yy36=0;}
2455
-#line 2480 "pikchr.c"
2465
+#line 2490 "pikchr.c"
24562466
yymsp[-2].minor.yy36 = yylhsminor.yy36;
24572467
break;
24582468
case 6: /* statement ::= PLACENAME COLON unnamed_statement */
2459
-#line 549 "pikchr.y"
2469
+#line 559 "pikchr.y"
24602470
{ yylhsminor.yy36 = yymsp[0].minor.yy36; pik_elem_setname(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0); }
2461
-#line 2486 "pikchr.c"
2471
+#line 2496 "pikchr.c"
24622472
yymsp[-2].minor.yy36 = yylhsminor.yy36;
24632473
break;
24642474
case 7: /* statement ::= PLACENAME COLON position */
2465
-#line 551 "pikchr.y"
2475
+#line 561 "pikchr.y"
24662476
{ yylhsminor.yy36 = pik_elem_new(p,0,0,0);
24672477
if(yylhsminor.yy36){ yylhsminor.yy36->ptAt = yymsp[0].minor.yy79; pik_elem_setname(p,yylhsminor.yy36,&yymsp[-2].minor.yy0); }}
2468
-#line 2493 "pikchr.c"
2478
+#line 2503 "pikchr.c"
24692479
yymsp[-2].minor.yy36 = yylhsminor.yy36;
24702480
break;
24712481
case 8: /* statement ::= unnamed_statement */
2472
-#line 553 "pikchr.y"
2482
+#line 563 "pikchr.y"
24732483
{yylhsminor.yy36 = yymsp[0].minor.yy36;}
2474
-#line 2499 "pikchr.c"
2484
+#line 2509 "pikchr.c"
24752485
yymsp[0].minor.yy36 = yylhsminor.yy36;
24762486
break;
24772487
case 9: /* statement ::= print prlist */
2478
-#line 554 "pikchr.y"
2488
+#line 564 "pikchr.y"
24792489
{pik_append(p,"<br>\n",5); yymsp[-1].minor.yy36=0;}
2480
-#line 2505 "pikchr.c"
2490
+#line 2515 "pikchr.c"
24812491
break;
24822492
case 10: /* statement ::= ASSERT LP expr EQ expr RP */
2483
-#line 559 "pikchr.y"
2493
+#line 569 "pikchr.y"
24842494
{yymsp[-5].minor.yy36=pik_assert(p,yymsp[-3].minor.yy153,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy153);}
2485
-#line 2510 "pikchr.c"
2495
+#line 2520 "pikchr.c"
24862496
break;
24872497
case 11: /* statement ::= ASSERT LP position EQ position RP */
2488
-#line 561 "pikchr.y"
2498
+#line 571 "pikchr.y"
24892499
{yymsp[-5].minor.yy36=pik_position_assert(p,&yymsp[-3].minor.yy79,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy79);}
2490
-#line 2515 "pikchr.c"
2500
+#line 2525 "pikchr.c"
24912501
break;
24922502
case 12: /* statement ::= DEFINE ID CODEBLOCK */
2493
-#line 562 "pikchr.y"
2503
+#line 572 "pikchr.y"
24942504
{yymsp[-2].minor.yy36=0; pik_add_macro(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
2495
-#line 2520 "pikchr.c"
2505
+#line 2530 "pikchr.c"
24962506
break;
24972507
case 13: /* rvalue ::= PLACENAME */
2498
-#line 573 "pikchr.y"
2508
+#line 583 "pikchr.y"
24992509
{yylhsminor.yy153 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2500
-#line 2525 "pikchr.c"
2510
+#line 2535 "pikchr.c"
25012511
yymsp[0].minor.yy153 = yylhsminor.yy153;
25022512
break;
25032513
case 14: /* pritem ::= FILL */
25042514
case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15);
25052515
case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16);
2506
-#line 578 "pikchr.y"
2516
+#line 588 "pikchr.y"
25072517
{pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2508
-#line 2533 "pikchr.c"
2518
+#line 2543 "pikchr.c"
25092519
break;
25102520
case 17: /* pritem ::= rvalue */
2511
-#line 581 "pikchr.y"
2521
+#line 591 "pikchr.y"
25122522
{pik_append_num(p,"",yymsp[0].minor.yy153);}
2513
-#line 2538 "pikchr.c"
2523
+#line 2548 "pikchr.c"
25142524
break;
25152525
case 18: /* pritem ::= STRING */
2516
-#line 582 "pikchr.y"
2526
+#line 592 "pikchr.y"
25172527
{pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2518
-#line 2543 "pikchr.c"
2528
+#line 2553 "pikchr.c"
25192529
break;
25202530
case 19: /* prsep ::= COMMA */
2521
-#line 583 "pikchr.y"
2531
+#line 593 "pikchr.y"
25222532
{pik_append(p, " ", 1);}
2523
-#line 2548 "pikchr.c"
2533
+#line 2558 "pikchr.c"
25242534
break;
25252535
case 20: /* unnamed_statement ::= basetype attribute_list */
2526
-#line 586 "pikchr.y"
2536
+#line 596 "pikchr.y"
25272537
{yylhsminor.yy36 = yymsp[-1].minor.yy36; pik_after_adding_attributes(p,yylhsminor.yy36);}
2528
-#line 2553 "pikchr.c"
2538
+#line 2563 "pikchr.c"
25292539
yymsp[-1].minor.yy36 = yylhsminor.yy36;
25302540
break;
25312541
case 21: /* basetype ::= CLASSNAME */
2532
-#line 588 "pikchr.y"
2542
+#line 598 "pikchr.y"
25332543
{yylhsminor.yy36 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2534
-#line 2559 "pikchr.c"
2544
+#line 2569 "pikchr.c"
25352545
yymsp[0].minor.yy36 = yylhsminor.yy36;
25362546
break;
25372547
case 22: /* basetype ::= STRING textposition */
2538
-#line 590 "pikchr.y"
2548
+#line 600 "pikchr.y"
25392549
{yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy164; yylhsminor.yy36 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2540
-#line 2565 "pikchr.c"
2550
+#line 2575 "pikchr.c"
25412551
yymsp[-1].minor.yy36 = yylhsminor.yy36;
25422552
break;
25432553
case 23: /* basetype ::= LB savelist statement_list RB */
2544
-#line 592 "pikchr.y"
2554
+#line 602 "pikchr.y"
25452555
{ p->list = yymsp[-2].minor.yy227; yymsp[-3].minor.yy36 = pik_elem_new(p,0,0,yymsp[-1].minor.yy227); if(yymsp[-3].minor.yy36) yymsp[-3].minor.yy36->errTok = yymsp[0].minor.yy0; }
2546
-#line 2571 "pikchr.c"
2556
+#line 2581 "pikchr.c"
25472557
break;
25482558
case 24: /* savelist ::= */
2549
-#line 597 "pikchr.y"
2559
+#line 607 "pikchr.y"
25502560
{yymsp[1].minor.yy227 = p->list; p->list = 0;}
2551
-#line 2576 "pikchr.c"
2561
+#line 2586 "pikchr.c"
25522562
break;
25532563
case 25: /* relexpr ::= expr */
2554
-#line 604 "pikchr.y"
2564
+#line 614 "pikchr.y"
25552565
{yylhsminor.yy10.rAbs = yymsp[0].minor.yy153; yylhsminor.yy10.rRel = 0;}
2556
-#line 2581 "pikchr.c"
2566
+#line 2591 "pikchr.c"
25572567
yymsp[0].minor.yy10 = yylhsminor.yy10;
25582568
break;
25592569
case 26: /* relexpr ::= expr PERCENT */
2560
-#line 605 "pikchr.y"
2570
+#line 615 "pikchr.y"
25612571
{yylhsminor.yy10.rAbs = 0; yylhsminor.yy10.rRel = yymsp[-1].minor.yy153/100;}
2562
-#line 2587 "pikchr.c"
2572
+#line 2597 "pikchr.c"
25632573
yymsp[-1].minor.yy10 = yylhsminor.yy10;
25642574
break;
25652575
case 27: /* optrelexpr ::= */
2566
-#line 607 "pikchr.y"
2576
+#line 617 "pikchr.y"
25672577
{yymsp[1].minor.yy10.rAbs = 0; yymsp[1].minor.yy10.rRel = 1.0;}
2568
-#line 2593 "pikchr.c"
2578
+#line 2603 "pikchr.c"
25692579
break;
25702580
case 28: /* attribute_list ::= relexpr alist */
2571
-#line 609 "pikchr.y"
2581
+#line 619 "pikchr.y"
25722582
{pik_add_direction(p,0,&yymsp[-1].minor.yy10);}
2573
-#line 2598 "pikchr.c"
2583
+#line 2608 "pikchr.c"
25742584
break;
25752585
case 29: /* attribute ::= numproperty relexpr */
2576
-#line 613 "pikchr.y"
2586
+#line 623 "pikchr.y"
25772587
{ pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy10); }
2578
-#line 2603 "pikchr.c"
2588
+#line 2613 "pikchr.c"
25792589
break;
25802590
case 30: /* attribute ::= dashproperty expr */
2581
-#line 614 "pikchr.y"
2591
+#line 624 "pikchr.y"
25822592
{ pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy153); }
2583
-#line 2608 "pikchr.c"
2593
+#line 2618 "pikchr.c"
25842594
break;
25852595
case 31: /* attribute ::= dashproperty */
2586
-#line 615 "pikchr.y"
2596
+#line 625 "pikchr.y"
25872597
{ pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2588
-#line 2613 "pikchr.c"
2598
+#line 2623 "pikchr.c"
25892599
break;
25902600
case 32: /* attribute ::= colorproperty rvalue */
2591
-#line 616 "pikchr.y"
2601
+#line 626 "pikchr.y"
25922602
{ pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy153); }
2593
-#line 2618 "pikchr.c"
2603
+#line 2628 "pikchr.c"
25942604
break;
25952605
case 33: /* attribute ::= go direction optrelexpr */
2596
-#line 617 "pikchr.y"
2606
+#line 627 "pikchr.y"
25972607
{ pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy10);}
2598
-#line 2623 "pikchr.c"
2608
+#line 2633 "pikchr.c"
25992609
break;
26002610
case 34: /* attribute ::= go direction even position */
2601
-#line 618 "pikchr.y"
2611
+#line 628 "pikchr.y"
26022612
{pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy79);}
2603
-#line 2628 "pikchr.c"
2613
+#line 2638 "pikchr.c"
26042614
break;
26052615
case 35: /* attribute ::= CLOSE */
2606
-#line 619 "pikchr.y"
2616
+#line 629 "pikchr.y"
26072617
{ pik_close_path(p,&yymsp[0].minor.yy0); }
2608
-#line 2633 "pikchr.c"
2618
+#line 2643 "pikchr.c"
26092619
break;
26102620
case 36: /* attribute ::= CHOP */
2611
-#line 620 "pikchr.y"
2621
+#line 630 "pikchr.y"
26122622
{ p->cur->bChop = 1; }
2613
-#line 2638 "pikchr.c"
2623
+#line 2648 "pikchr.c"
26142624
break;
26152625
case 37: /* attribute ::= FROM position */
2616
-#line 621 "pikchr.y"
2626
+#line 631 "pikchr.y"
26172627
{ pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy79); }
2618
-#line 2643 "pikchr.c"
2628
+#line 2653 "pikchr.c"
26192629
break;
26202630
case 38: /* attribute ::= TO position */
2621
-#line 622 "pikchr.y"
2631
+#line 632 "pikchr.y"
26222632
{ pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy79); }
2623
-#line 2648 "pikchr.c"
2633
+#line 2658 "pikchr.c"
26242634
break;
26252635
case 39: /* attribute ::= THEN */
2626
-#line 623 "pikchr.y"
2636
+#line 633 "pikchr.y"
26272637
{ pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2628
-#line 2653 "pikchr.c"
2638
+#line 2663 "pikchr.c"
26292639
break;
26302640
case 40: /* attribute ::= THEN optrelexpr HEADING expr */
26312641
case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42);
2632
-#line 625 "pikchr.y"
2642
+#line 635 "pikchr.y"
26332643
{pik_move_hdg(p,&yymsp[-2].minor.yy10,&yymsp[-1].minor.yy0,yymsp[0].minor.yy153,0,&yymsp[-3].minor.yy0);}
2634
-#line 2659 "pikchr.c"
2644
+#line 2669 "pikchr.c"
26352645
break;
26362646
case 41: /* attribute ::= THEN optrelexpr EDGEPT */
26372647
case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43);
2638
-#line 626 "pikchr.y"
2648
+#line 636 "pikchr.y"
26392649
{pik_move_hdg(p,&yymsp[-1].minor.yy10,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2640
-#line 2665 "pikchr.c"
2650
+#line 2675 "pikchr.c"
26412651
break;
26422652
case 44: /* attribute ::= AT position */
2643
-#line 631 "pikchr.y"
2653
+#line 641 "pikchr.y"
26442654
{ pik_set_at(p,0,&yymsp[0].minor.yy79,&yymsp[-1].minor.yy0); }
2645
-#line 2670 "pikchr.c"
2655
+#line 2680 "pikchr.c"
26462656
break;
26472657
case 45: /* attribute ::= SAME */
2648
-#line 633 "pikchr.y"
2658
+#line 643 "pikchr.y"
26492659
{pik_same(p,0,&yymsp[0].minor.yy0);}
2650
-#line 2675 "pikchr.c"
2660
+#line 2685 "pikchr.c"
26512661
break;
26522662
case 46: /* attribute ::= SAME AS object */
2653
-#line 634 "pikchr.y"
2663
+#line 644 "pikchr.y"
26542664
{pik_same(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0);}
2655
-#line 2680 "pikchr.c"
2665
+#line 2690 "pikchr.c"
26562666
break;
26572667
case 47: /* attribute ::= STRING textposition */
2658
-#line 635 "pikchr.y"
2668
+#line 645 "pikchr.y"
26592669
{pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy164);}
2660
-#line 2685 "pikchr.c"
2670
+#line 2695 "pikchr.c"
26612671
break;
26622672
case 48: /* attribute ::= FIT */
2663
-#line 636 "pikchr.y"
2673
+#line 646 "pikchr.y"
26642674
{pik_size_to_fit(p,&yymsp[0].minor.yy0,3); }
2665
-#line 2690 "pikchr.c"
2675
+#line 2700 "pikchr.c"
26662676
break;
26672677
case 49: /* attribute ::= BEHIND object */
2668
-#line 637 "pikchr.y"
2678
+#line 647 "pikchr.y"
26692679
{pik_behind(p,yymsp[0].minor.yy36);}
2670
-#line 2695 "pikchr.c"
2680
+#line 2705 "pikchr.c"
26712681
break;
26722682
case 50: /* withclause ::= DOT_E edge AT position */
26732683
case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51);
2674
-#line 645 "pikchr.y"
2684
+#line 655 "pikchr.y"
26752685
{ pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy79,&yymsp[-1].minor.yy0); }
2676
-#line 2701 "pikchr.c"
2686
+#line 2711 "pikchr.c"
26772687
break;
26782688
case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2679
-#line 649 "pikchr.y"
2689
+#line 659 "pikchr.y"
26802690
{yylhsminor.yy0 = yymsp[0].minor.yy0;}
2681
-#line 2706 "pikchr.c"
2691
+#line 2716 "pikchr.c"
26822692
yymsp[0].minor.yy0 = yylhsminor.yy0;
26832693
break;
26842694
case 53: /* boolproperty ::= CW */
2685
-#line 660 "pikchr.y"
2695
+#line 670 "pikchr.y"
26862696
{p->cur->cw = 1;}
2687
-#line 2712 "pikchr.c"
2697
+#line 2722 "pikchr.c"
26882698
break;
26892699
case 54: /* boolproperty ::= CCW */
2690
-#line 661 "pikchr.y"
2700
+#line 671 "pikchr.y"
26912701
{p->cur->cw = 0;}
2692
-#line 2717 "pikchr.c"
2702
+#line 2727 "pikchr.c"
26932703
break;
26942704
case 55: /* boolproperty ::= LARROW */
2695
-#line 662 "pikchr.y"
2705
+#line 672 "pikchr.y"
26962706
{p->cur->larrow=1; p->cur->rarrow=0; }
2697
-#line 2722 "pikchr.c"
2707
+#line 2732 "pikchr.c"
26982708
break;
26992709
case 56: /* boolproperty ::= RARROW */
2700
-#line 663 "pikchr.y"
2710
+#line 673 "pikchr.y"
27012711
{p->cur->larrow=0; p->cur->rarrow=1; }
2702
-#line 2727 "pikchr.c"
2712
+#line 2737 "pikchr.c"
27032713
break;
27042714
case 57: /* boolproperty ::= LRARROW */
2705
-#line 664 "pikchr.y"
2715
+#line 674 "pikchr.y"
27062716
{p->cur->larrow=1; p->cur->rarrow=1; }
2707
-#line 2732 "pikchr.c"
2717
+#line 2742 "pikchr.c"
27082718
break;
27092719
case 58: /* boolproperty ::= INVIS */
2710
-#line 665 "pikchr.y"
2720
+#line 675 "pikchr.y"
27112721
{p->cur->sw = 0.0;}
2712
-#line 2737 "pikchr.c"
2722
+#line 2747 "pikchr.c"
27132723
break;
27142724
case 59: /* boolproperty ::= THICK */
2715
-#line 666 "pikchr.y"
2725
+#line 676 "pikchr.y"
27162726
{p->cur->sw *= 1.5;}
2717
-#line 2742 "pikchr.c"
2727
+#line 2752 "pikchr.c"
27182728
break;
27192729
case 60: /* boolproperty ::= THIN */
2720
-#line 667 "pikchr.y"
2730
+#line 677 "pikchr.y"
27212731
{p->cur->sw *= 0.67;}
2722
-#line 2747 "pikchr.c"
2732
+#line 2757 "pikchr.c"
27232733
break;
27242734
case 61: /* boolproperty ::= SOLID */
2725
-#line 668 "pikchr.y"
2735
+#line 678 "pikchr.y"
27262736
{p->cur->sw = pik_value(p,"thickness",9,0);
27272737
p->cur->dotted = p->cur->dashed = 0.0;}
2728
-#line 2753 "pikchr.c"
2738
+#line 2763 "pikchr.c"
27292739
break;
27302740
case 62: /* textposition ::= */
2731
-#line 671 "pikchr.y"
2741
+#line 681 "pikchr.y"
27322742
{yymsp[1].minor.yy164 = 0;}
2733
-#line 2758 "pikchr.c"
2743
+#line 2768 "pikchr.c"
27342744
break;
27352745
case 63: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2736
-#line 674 "pikchr.y"
2746
+#line 684 "pikchr.y"
27372747
{yylhsminor.yy164 = (short int)pik_text_position(yymsp[-1].minor.yy164,&yymsp[0].minor.yy0);}
2738
-#line 2763 "pikchr.c"
2748
+#line 2773 "pikchr.c"
27392749
yymsp[-1].minor.yy164 = yylhsminor.yy164;
27402750
break;
27412751
case 64: /* position ::= expr COMMA expr */
2742
-#line 677 "pikchr.y"
2752
+#line 687 "pikchr.y"
27432753
{yylhsminor.yy79.x=yymsp[-2].minor.yy153; yylhsminor.yy79.y=yymsp[0].minor.yy153;}
2744
-#line 2769 "pikchr.c"
2754
+#line 2779 "pikchr.c"
27452755
yymsp[-2].minor.yy79 = yylhsminor.yy79;
27462756
break;
27472757
case 65: /* position ::= place PLUS expr COMMA expr */
2748
-#line 679 "pikchr.y"
2758
+#line 689 "pikchr.y"
27492759
{yylhsminor.yy79.x=yymsp[-4].minor.yy79.x+yymsp[-2].minor.yy153; yylhsminor.yy79.y=yymsp[-4].minor.yy79.y+yymsp[0].minor.yy153;}
2750
-#line 2775 "pikchr.c"
2760
+#line 2785 "pikchr.c"
27512761
yymsp[-4].minor.yy79 = yylhsminor.yy79;
27522762
break;
27532763
case 66: /* position ::= place MINUS expr COMMA expr */
2754
-#line 680 "pikchr.y"
2764
+#line 690 "pikchr.y"
27552765
{yylhsminor.yy79.x=yymsp[-4].minor.yy79.x-yymsp[-2].minor.yy153; yylhsminor.yy79.y=yymsp[-4].minor.yy79.y-yymsp[0].minor.yy153;}
2756
-#line 2781 "pikchr.c"
2766
+#line 2791 "pikchr.c"
27572767
yymsp[-4].minor.yy79 = yylhsminor.yy79;
27582768
break;
27592769
case 67: /* position ::= place PLUS LP expr COMMA expr RP */
2760
-#line 682 "pikchr.y"
2770
+#line 692 "pikchr.y"
27612771
{yylhsminor.yy79.x=yymsp[-6].minor.yy79.x+yymsp[-3].minor.yy153; yylhsminor.yy79.y=yymsp[-6].minor.yy79.y+yymsp[-1].minor.yy153;}
2762
-#line 2787 "pikchr.c"
2772
+#line 2797 "pikchr.c"
27632773
yymsp[-6].minor.yy79 = yylhsminor.yy79;
27642774
break;
27652775
case 68: /* position ::= place MINUS LP expr COMMA expr RP */
2766
-#line 684 "pikchr.y"
2776
+#line 694 "pikchr.y"
27672777
{yylhsminor.yy79.x=yymsp[-6].minor.yy79.x-yymsp[-3].minor.yy153; yylhsminor.yy79.y=yymsp[-6].minor.yy79.y-yymsp[-1].minor.yy153;}
2768
-#line 2793 "pikchr.c"
2778
+#line 2803 "pikchr.c"
27692779
yymsp[-6].minor.yy79 = yylhsminor.yy79;
27702780
break;
27712781
case 69: /* position ::= LP position COMMA position RP */
2772
-#line 685 "pikchr.y"
2782
+#line 695 "pikchr.y"
27732783
{yymsp[-4].minor.yy79.x=yymsp[-3].minor.yy79.x; yymsp[-4].minor.yy79.y=yymsp[-1].minor.yy79.y;}
2774
-#line 2799 "pikchr.c"
2784
+#line 2809 "pikchr.c"
27752785
break;
27762786
case 70: /* position ::= LP position RP */
2777
-#line 686 "pikchr.y"
2787
+#line 696 "pikchr.y"
27782788
{yymsp[-2].minor.yy79=yymsp[-1].minor.yy79;}
2779
-#line 2804 "pikchr.c"
2789
+#line 2814 "pikchr.c"
27802790
break;
27812791
case 71: /* position ::= expr between position AND position */
2782
-#line 688 "pikchr.y"
2792
+#line 698 "pikchr.y"
27832793
{yylhsminor.yy79 = pik_position_between(yymsp[-4].minor.yy153,yymsp[-2].minor.yy79,yymsp[0].minor.yy79);}
2784
-#line 2809 "pikchr.c"
2794
+#line 2819 "pikchr.c"
27852795
yymsp[-4].minor.yy79 = yylhsminor.yy79;
27862796
break;
27872797
case 72: /* position ::= expr LT position COMMA position GT */
2788
-#line 690 "pikchr.y"
2798
+#line 700 "pikchr.y"
27892799
{yylhsminor.yy79 = pik_position_between(yymsp[-5].minor.yy153,yymsp[-3].minor.yy79,yymsp[-1].minor.yy79);}
2790
-#line 2815 "pikchr.c"
2800
+#line 2825 "pikchr.c"
27912801
yymsp[-5].minor.yy79 = yylhsminor.yy79;
27922802
break;
27932803
case 73: /* position ::= expr ABOVE position */
2794
-#line 691 "pikchr.y"
2804
+#line 701 "pikchr.y"
27952805
{yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.y += yymsp[-2].minor.yy153;}
2796
-#line 2821 "pikchr.c"
2806
+#line 2831 "pikchr.c"
27972807
yymsp[-2].minor.yy79 = yylhsminor.yy79;
27982808
break;
27992809
case 74: /* position ::= expr BELOW position */
2800
-#line 692 "pikchr.y"
2810
+#line 702 "pikchr.y"
28012811
{yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.y -= yymsp[-2].minor.yy153;}
2802
-#line 2827 "pikchr.c"
2812
+#line 2837 "pikchr.c"
28032813
yymsp[-2].minor.yy79 = yylhsminor.yy79;
28042814
break;
28052815
case 75: /* position ::= expr LEFT OF position */
2806
-#line 693 "pikchr.y"
2816
+#line 703 "pikchr.y"
28072817
{yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.x -= yymsp[-3].minor.yy153;}
2808
-#line 2833 "pikchr.c"
2818
+#line 2843 "pikchr.c"
28092819
yymsp[-3].minor.yy79 = yylhsminor.yy79;
28102820
break;
28112821
case 76: /* position ::= expr RIGHT OF position */
2812
-#line 694 "pikchr.y"
2822
+#line 704 "pikchr.y"
28132823
{yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.x += yymsp[-3].minor.yy153;}
2814
-#line 2839 "pikchr.c"
2824
+#line 2849 "pikchr.c"
28152825
yymsp[-3].minor.yy79 = yylhsminor.yy79;
28162826
break;
28172827
case 77: /* position ::= expr ON HEADING EDGEPT OF position */
2818
-#line 696 "pikchr.y"
2828
+#line 706 "pikchr.y"
28192829
{yylhsminor.yy79 = pik_position_at_hdg(yymsp[-5].minor.yy153,&yymsp[-2].minor.yy0,yymsp[0].minor.yy79);}
2820
-#line 2845 "pikchr.c"
2830
+#line 2855 "pikchr.c"
28212831
yymsp[-5].minor.yy79 = yylhsminor.yy79;
28222832
break;
28232833
case 78: /* position ::= expr HEADING EDGEPT OF position */
2824
-#line 698 "pikchr.y"
2834
+#line 708 "pikchr.y"
28252835
{yylhsminor.yy79 = pik_position_at_hdg(yymsp[-4].minor.yy153,&yymsp[-2].minor.yy0,yymsp[0].minor.yy79);}
2826
-#line 2851 "pikchr.c"
2836
+#line 2861 "pikchr.c"
28272837
yymsp[-4].minor.yy79 = yylhsminor.yy79;
28282838
break;
28292839
case 79: /* position ::= expr EDGEPT OF position */
2830
-#line 700 "pikchr.y"
2840
+#line 710 "pikchr.y"
28312841
{yylhsminor.yy79 = pik_position_at_hdg(yymsp[-3].minor.yy153,&yymsp[-2].minor.yy0,yymsp[0].minor.yy79);}
2832
-#line 2857 "pikchr.c"
2842
+#line 2867 "pikchr.c"
28332843
yymsp[-3].minor.yy79 = yylhsminor.yy79;
28342844
break;
28352845
case 80: /* position ::= expr ON HEADING expr FROM position */
2836
-#line 702 "pikchr.y"
2846
+#line 712 "pikchr.y"
28372847
{yylhsminor.yy79 = pik_position_at_angle(yymsp[-5].minor.yy153,yymsp[-2].minor.yy153,yymsp[0].minor.yy79);}
2838
-#line 2863 "pikchr.c"
2848
+#line 2873 "pikchr.c"
28392849
yymsp[-5].minor.yy79 = yylhsminor.yy79;
28402850
break;
28412851
case 81: /* position ::= expr HEADING expr FROM position */
2842
-#line 704 "pikchr.y"
2852
+#line 714 "pikchr.y"
28432853
{yylhsminor.yy79 = pik_position_at_angle(yymsp[-4].minor.yy153,yymsp[-2].minor.yy153,yymsp[0].minor.yy79);}
2844
-#line 2869 "pikchr.c"
2854
+#line 2879 "pikchr.c"
28452855
yymsp[-4].minor.yy79 = yylhsminor.yy79;
28462856
break;
28472857
case 82: /* place ::= edge OF object */
2848
-#line 716 "pikchr.y"
2858
+#line 726 "pikchr.y"
28492859
{yylhsminor.yy79 = pik_place_of_elem(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0);}
2850
-#line 2875 "pikchr.c"
2860
+#line 2885 "pikchr.c"
28512861
yymsp[-2].minor.yy79 = yylhsminor.yy79;
28522862
break;
28532863
case 83: /* place2 ::= object */
2854
-#line 717 "pikchr.y"
2864
+#line 727 "pikchr.y"
28552865
{yylhsminor.yy79 = pik_place_of_elem(p,yymsp[0].minor.yy36,0);}
2856
-#line 2881 "pikchr.c"
2866
+#line 2891 "pikchr.c"
28572867
yymsp[0].minor.yy79 = yylhsminor.yy79;
28582868
break;
28592869
case 84: /* place2 ::= object DOT_E edge */
2860
-#line 718 "pikchr.y"
2870
+#line 728 "pikchr.y"
28612871
{yylhsminor.yy79 = pik_place_of_elem(p,yymsp[-2].minor.yy36,&yymsp[0].minor.yy0);}
2862
-#line 2887 "pikchr.c"
2872
+#line 2897 "pikchr.c"
28632873
yymsp[-2].minor.yy79 = yylhsminor.yy79;
28642874
break;
28652875
case 85: /* place2 ::= NTH VERTEX OF object */
2866
-#line 719 "pikchr.y"
2876
+#line 729 "pikchr.y"
28672877
{yylhsminor.yy79 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy36);}
2868
-#line 2893 "pikchr.c"
2878
+#line 2903 "pikchr.c"
28692879
yymsp[-3].minor.yy79 = yylhsminor.yy79;
28702880
break;
28712881
case 86: /* object ::= nth */
2872
-#line 731 "pikchr.y"
2882
+#line 741 "pikchr.y"
28732883
{yylhsminor.yy36 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2874
-#line 2899 "pikchr.c"
2884
+#line 2909 "pikchr.c"
28752885
yymsp[0].minor.yy36 = yylhsminor.yy36;
28762886
break;
28772887
case 87: /* object ::= nth OF|IN object */
2878
-#line 732 "pikchr.y"
2888
+#line 742 "pikchr.y"
28792889
{yylhsminor.yy36 = pik_find_nth(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0);}
2880
-#line 2905 "pikchr.c"
2890
+#line 2915 "pikchr.c"
28812891
yymsp[-2].minor.yy36 = yylhsminor.yy36;
28822892
break;
28832893
case 88: /* objectname ::= THIS */
2884
-#line 734 "pikchr.y"
2894
+#line 744 "pikchr.y"
28852895
{yymsp[0].minor.yy36 = p->cur;}
2886
-#line 2911 "pikchr.c"
2896
+#line 2921 "pikchr.c"
28872897
break;
28882898
case 89: /* objectname ::= PLACENAME */
2889
-#line 735 "pikchr.y"
2899
+#line 745 "pikchr.y"
28902900
{yylhsminor.yy36 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2891
-#line 2916 "pikchr.c"
2901
+#line 2926 "pikchr.c"
28922902
yymsp[0].minor.yy36 = yylhsminor.yy36;
28932903
break;
28942904
case 90: /* objectname ::= objectname DOT_U PLACENAME */
2895
-#line 737 "pikchr.y"
2905
+#line 747 "pikchr.y"
28962906
{yylhsminor.yy36 = pik_find_byname(p,yymsp[-2].minor.yy36,&yymsp[0].minor.yy0);}
2897
-#line 2922 "pikchr.c"
2907
+#line 2932 "pikchr.c"
28982908
yymsp[-2].minor.yy36 = yylhsminor.yy36;
28992909
break;
29002910
case 91: /* nth ::= NTH CLASSNAME */
2901
-#line 739 "pikchr.y"
2911
+#line 749 "pikchr.y"
29022912
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2903
-#line 2928 "pikchr.c"
2913
+#line 2938 "pikchr.c"
29042914
yymsp[-1].minor.yy0 = yylhsminor.yy0;
29052915
break;
29062916
case 92: /* nth ::= NTH LAST CLASSNAME */
2907
-#line 740 "pikchr.y"
2917
+#line 750 "pikchr.y"
29082918
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2909
-#line 2934 "pikchr.c"
2919
+#line 2944 "pikchr.c"
29102920
yymsp[-2].minor.yy0 = yylhsminor.yy0;
29112921
break;
29122922
case 93: /* nth ::= LAST CLASSNAME */
2913
-#line 741 "pikchr.y"
2923
+#line 751 "pikchr.y"
29142924
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2915
-#line 2940 "pikchr.c"
2925
+#line 2950 "pikchr.c"
29162926
break;
29172927
case 94: /* nth ::= LAST */
2918
-#line 742 "pikchr.y"
2928
+#line 752 "pikchr.y"
29192929
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2920
-#line 2945 "pikchr.c"
2930
+#line 2955 "pikchr.c"
29212931
yymsp[0].minor.yy0 = yylhsminor.yy0;
29222932
break;
29232933
case 95: /* nth ::= NTH LB RB */
2924
-#line 743 "pikchr.y"
2934
+#line 753 "pikchr.y"
29252935
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2926
-#line 2951 "pikchr.c"
2936
+#line 2961 "pikchr.c"
29272937
yymsp[-2].minor.yy0 = yylhsminor.yy0;
29282938
break;
29292939
case 96: /* nth ::= NTH LAST LB RB */
2930
-#line 744 "pikchr.y"
2940
+#line 754 "pikchr.y"
29312941
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2932
-#line 2957 "pikchr.c"
2942
+#line 2967 "pikchr.c"
29332943
yymsp[-3].minor.yy0 = yylhsminor.yy0;
29342944
break;
29352945
case 97: /* nth ::= LAST LB RB */
2936
-#line 745 "pikchr.y"
2946
+#line 755 "pikchr.y"
29372947
{yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2938
-#line 2963 "pikchr.c"
2948
+#line 2973 "pikchr.c"
29392949
break;
29402950
case 98: /* expr ::= expr PLUS expr */
2941
-#line 747 "pikchr.y"
2951
+#line 757 "pikchr.y"
29422952
{yylhsminor.yy153=yymsp[-2].minor.yy153+yymsp[0].minor.yy153;}
2943
-#line 2968 "pikchr.c"
2953
+#line 2978 "pikchr.c"
29442954
yymsp[-2].minor.yy153 = yylhsminor.yy153;
29452955
break;
29462956
case 99: /* expr ::= expr MINUS expr */
2947
-#line 748 "pikchr.y"
2957
+#line 758 "pikchr.y"
29482958
{yylhsminor.yy153=yymsp[-2].minor.yy153-yymsp[0].minor.yy153;}
2949
-#line 2974 "pikchr.c"
2959
+#line 2984 "pikchr.c"
29502960
yymsp[-2].minor.yy153 = yylhsminor.yy153;
29512961
break;
29522962
case 100: /* expr ::= expr STAR expr */
2953
-#line 749 "pikchr.y"
2963
+#line 759 "pikchr.y"
29542964
{yylhsminor.yy153=yymsp[-2].minor.yy153*yymsp[0].minor.yy153;}
2955
-#line 2980 "pikchr.c"
2965
+#line 2990 "pikchr.c"
29562966
yymsp[-2].minor.yy153 = yylhsminor.yy153;
29572967
break;
29582968
case 101: /* expr ::= expr SLASH expr */
2959
-#line 750 "pikchr.y"
2969
+#line 760 "pikchr.y"
29602970
{
29612971
if( yymsp[0].minor.yy153==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy153 = 0.0; }
29622972
else{ yylhsminor.yy153 = yymsp[-2].minor.yy153/yymsp[0].minor.yy153; }
29632973
}
2964
-#line 2989 "pikchr.c"
2974
+#line 2999 "pikchr.c"
29652975
yymsp[-2].minor.yy153 = yylhsminor.yy153;
29662976
break;
29672977
case 102: /* expr ::= MINUS expr */
2968
-#line 754 "pikchr.y"
2978
+#line 764 "pikchr.y"
29692979
{yymsp[-1].minor.yy153=-yymsp[0].minor.yy153;}
2970
-#line 2995 "pikchr.c"
2980
+#line 3005 "pikchr.c"
29712981
break;
29722982
case 103: /* expr ::= PLUS expr */
2973
-#line 755 "pikchr.y"
2983
+#line 765 "pikchr.y"
29742984
{yymsp[-1].minor.yy153=yymsp[0].minor.yy153;}
2975
-#line 3000 "pikchr.c"
2985
+#line 3010 "pikchr.c"
29762986
break;
29772987
case 104: /* expr ::= LP expr RP */
2978
-#line 756 "pikchr.y"
2988
+#line 766 "pikchr.y"
29792989
{yymsp[-2].minor.yy153=yymsp[-1].minor.yy153;}
2980
-#line 3005 "pikchr.c"
2990
+#line 3015 "pikchr.c"
29812991
break;
29822992
case 105: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2983
-#line 757 "pikchr.y"
2993
+#line 767 "pikchr.y"
29842994
{yymsp[-2].minor.yy153=pik_get_var(p,&yymsp[-1].minor.yy0);}
2985
-#line 3010 "pikchr.c"
2995
+#line 3020 "pikchr.c"
29862996
break;
29872997
case 106: /* expr ::= NUMBER */
2988
-#line 758 "pikchr.y"
2998
+#line 768 "pikchr.y"
29892999
{yylhsminor.yy153=pik_atof(&yymsp[0].minor.yy0);}
2990
-#line 3015 "pikchr.c"
3000
+#line 3025 "pikchr.c"
29913001
yymsp[0].minor.yy153 = yylhsminor.yy153;
29923002
break;
29933003
case 107: /* expr ::= ID */
2994
-#line 759 "pikchr.y"
3004
+#line 769 "pikchr.y"
29953005
{yylhsminor.yy153=pik_get_var(p,&yymsp[0].minor.yy0);}
2996
-#line 3021 "pikchr.c"
3006
+#line 3031 "pikchr.c"
29973007
yymsp[0].minor.yy153 = yylhsminor.yy153;
29983008
break;
29993009
case 108: /* expr ::= FUNC1 LP expr RP */
3000
-#line 760 "pikchr.y"
3010
+#line 770 "pikchr.y"
30013011
{yylhsminor.yy153 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy153,0.0);}
3002
-#line 3027 "pikchr.c"
3012
+#line 3037 "pikchr.c"
30033013
yymsp[-3].minor.yy153 = yylhsminor.yy153;
30043014
break;
30053015
case 109: /* expr ::= FUNC2 LP expr COMMA expr RP */
3006
-#line 761 "pikchr.y"
3016
+#line 771 "pikchr.y"
30073017
{yylhsminor.yy153 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy153,yymsp[-1].minor.yy153);}
3008
-#line 3033 "pikchr.c"
3018
+#line 3043 "pikchr.c"
30093019
yymsp[-5].minor.yy153 = yylhsminor.yy153;
30103020
break;
30113021
case 110: /* expr ::= DIST LP position COMMA position RP */
3012
-#line 762 "pikchr.y"
3022
+#line 772 "pikchr.y"
30133023
{yymsp[-5].minor.yy153 = pik_dist(&yymsp[-3].minor.yy79,&yymsp[-1].minor.yy79);}
3014
-#line 3039 "pikchr.c"
3024
+#line 3049 "pikchr.c"
30153025
break;
30163026
case 111: /* expr ::= place2 DOT_XY X */
3017
-#line 763 "pikchr.y"
3027
+#line 773 "pikchr.y"
30183028
{yylhsminor.yy153 = yymsp[-2].minor.yy79.x;}
3019
-#line 3044 "pikchr.c"
3029
+#line 3054 "pikchr.c"
30203030
yymsp[-2].minor.yy153 = yylhsminor.yy153;
30213031
break;
30223032
case 112: /* expr ::= place2 DOT_XY Y */
3023
-#line 764 "pikchr.y"
3033
+#line 774 "pikchr.y"
30243034
{yylhsminor.yy153 = yymsp[-2].minor.yy79.y;}
3025
-#line 3050 "pikchr.c"
3035
+#line 3060 "pikchr.c"
30263036
yymsp[-2].minor.yy153 = yylhsminor.yy153;
30273037
break;
30283038
case 113: /* expr ::= object DOT_L numproperty */
30293039
case 114: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==114);
30303040
case 115: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==115);
3031
-#line 765 "pikchr.y"
3041
+#line 775 "pikchr.y"
30323042
{yylhsminor.yy153=pik_property_of(yymsp[-2].minor.yy36,&yymsp[0].minor.yy0);}
3033
-#line 3058 "pikchr.c"
3043
+#line 3068 "pikchr.c"
30343044
yymsp[-2].minor.yy153 = yylhsminor.yy153;
30353045
break;
30363046
default:
30373047
/* (116) lvalue ::= ID */ yytestcase(yyruleno==116);
30383048
/* (117) lvalue ::= FILL */ yytestcase(yyruleno==117);
@@ -3131,19 +3141,19 @@
31313141
){
31323142
pik_parserARG_FETCH
31333143
pik_parserCTX_FETCH
31343144
#define TOKEN yyminor
31353145
/************ Begin %syntax_error code ****************************************/
3136
-#line 525 "pikchr.y"
3146
+#line 535 "pikchr.y"
31373147
31383148
if( TOKEN.z && TOKEN.z[0] ){
31393149
pik_error(p, &TOKEN, "syntax error");
31403150
}else{
31413151
pik_error(p, 0, "syntax error");
31423152
}
31433153
UNUSED_PARAMETER(yymajor);
3144
-#line 3169 "pikchr.c"
3154
+#line 3179 "pikchr.c"
31453155
/************ End %syntax_error code ******************************************/
31463156
pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
31473157
pik_parserCTX_STORE
31483158
}
31493159
@@ -3372,11 +3382,11 @@
33723382
#else
33733383
(void)iToken;
33743384
return 0;
33753385
#endif
33763386
}
3377
-#line 770 "pikchr.y"
3387
+#line 780 "pikchr.y"
33783388
33793389
33803390
33813391
/* Chart of the 148 official CSS color names with their
33823392
** corresponding RGB values thru Color Module Level 4:
@@ -6645,11 +6655,11 @@
66456655
/* Compute one of the built-in functions
66466656
*/
66476657
static PNum pik_func(Pik *p, PToken *pFunc, PNum x, PNum y){
66486658
PNum v = 0.0;
66496659
switch( pFunc->eCode ){
6650
- case FN_ABS: v = v<0.0 ? -v : v; break;
6660
+ case FN_ABS: v = x<0.0 ? -x : x; break;
66516661
case FN_COS: v = cos(x); break;
66526662
case FN_INT: v = rint(x); break;
66536663
case FN_SIN: v = sin(x); break;
66546664
case FN_SQRT:
66556665
if( x<0.0 ){
@@ -7744,10 +7754,14 @@
77447754
printf("******** Token %s (%d): \"%.*s\" **************\n",
77457755
yyTokenName[token.eType], token.eType,
77467756
(int)(isspace(token.z[0]) ? 0 : sz), token.z);
77477757
#endif
77487758
token.n = (unsigned short)(sz & 0xffff);
7759
+ if( p->nToken++ > PIKCHR_TOKEN_LIMIT ){
7760
+ pik_error(p, &token, "script is too complex");
7761
+ break;
7762
+ }
77497763
pik_parser(pParser, token.eType, token);
77507764
}
77517765
}
77527766
}
77537767
@@ -8081,6 +8095,6 @@
80818095
80828096
80838097
#endif /* PIKCHR_TCL */
80848098
80858099
8086
-#line 8111 "pikchr.c"
8100
+#line 8125 "pikchr.c"
80878101
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -124,10 +124,19 @@
124 #include <assert.h>
125 #define count(X) (sizeof(X)/sizeof(X[0]))
126 #ifndef M_PI
127 # define M_PI 3.1415926535897932385
128 #endif
 
 
 
 
 
 
 
 
 
129
130 /* Tag intentionally unused parameters with this macro to prevent
131 ** compiler warnings with -Wextra */
132 #define UNUSED_PARAMETER(X) (void)(X)
133
@@ -341,10 +350,11 @@
341 /* Each call to the pikchr() subroutine uses an instance of the following
342 ** object to pass around context to all of its subroutines.
343 */
344 struct Pik {
345 unsigned nErr; /* Number of errors seen */
 
346 PToken sIn; /* Input Pikchr-language text */
347 char *zOut; /* Result accumulates here */
348 unsigned int nOut; /* Bytes written to zOut[] so far */
349 unsigned int nOutAlloc; /* Space allocated to zOut[] */
350 unsigned char eDir; /* Current direction */
@@ -479,11 +489,11 @@
479 static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
480 static PNum pik_dist(PPoint*,PPoint*);
481 static void pik_add_macro(Pik*,PToken *pId,PToken *pCode);
482
483
484 #line 510 "pikchr.c"
485 /**************** End of %include directives **********************************/
486 /* These constants specify the various numeric values for terminal symbols.
487 ***************** Begin token definitions *************************************/
488 #ifndef T_ID
489 #define T_ID 1
@@ -1708,22 +1718,22 @@
1708 ** inside the C code.
1709 */
1710 /********* Begin destructor definitions ***************************************/
1711 case 99: /* statement_list */
1712 {
1713 #line 499 "pikchr.y"
1714 pik_elist_free(p,(yypminor->yy227));
1715 #line 1740 "pikchr.c"
1716 }
1717 break;
1718 case 100: /* statement */
1719 case 101: /* unnamed_statement */
1720 case 102: /* basetype */
1721 {
1722 #line 501 "pikchr.y"
1723 pik_elem_free(p,(yypminor->yy36));
1724 #line 1749 "pikchr.c"
1725 }
1726 break;
1727 /********* End destructor definitions *****************************************/
1728 default: break; /* If no destructor action specified: do nothing */
1729 }
@@ -1937,14 +1947,14 @@
1937 #endif
1938 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1939 /* Here code is inserted which will execute if the parser
1940 ** stack every overflows */
1941 /******** Begin %stack_overflow code ******************************************/
1942 #line 533 "pikchr.y"
1943
1944 pik_error(p, 0, "parser stack overflow");
1945 #line 1970 "pikchr.c"
1946 /******** End %stack_overflow code ********************************************/
1947 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
1948 pik_parserCTX_STORE
1949 }
1950
@@ -2420,619 +2430,619 @@
2420 ** break;
2421 */
2422 /********** Begin reduce actions **********************************************/
2423 YYMINORTYPE yylhsminor;
2424 case 0: /* document ::= statement_list */
2425 #line 537 "pikchr.y"
2426 {pik_render(p,yymsp[0].minor.yy227);}
2427 #line 2452 "pikchr.c"
2428 break;
2429 case 1: /* statement_list ::= statement */
2430 #line 540 "pikchr.y"
2431 { yylhsminor.yy227 = pik_elist_append(p,0,yymsp[0].minor.yy36); }
2432 #line 2457 "pikchr.c"
2433 yymsp[0].minor.yy227 = yylhsminor.yy227;
2434 break;
2435 case 2: /* statement_list ::= statement_list EOL statement */
2436 #line 542 "pikchr.y"
2437 { yylhsminor.yy227 = pik_elist_append(p,yymsp[-2].minor.yy227,yymsp[0].minor.yy36); }
2438 #line 2463 "pikchr.c"
2439 yymsp[-2].minor.yy227 = yylhsminor.yy227;
2440 break;
2441 case 3: /* statement ::= */
2442 #line 545 "pikchr.y"
2443 { yymsp[1].minor.yy36 = 0; }
2444 #line 2469 "pikchr.c"
2445 break;
2446 case 4: /* statement ::= direction */
2447 #line 546 "pikchr.y"
2448 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy36=0; }
2449 #line 2474 "pikchr.c"
2450 yymsp[0].minor.yy36 = yylhsminor.yy36;
2451 break;
2452 case 5: /* statement ::= lvalue ASSIGN rvalue */
2453 #line 547 "pikchr.y"
2454 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy153,&yymsp[-1].minor.yy0); yylhsminor.yy36=0;}
2455 #line 2480 "pikchr.c"
2456 yymsp[-2].minor.yy36 = yylhsminor.yy36;
2457 break;
2458 case 6: /* statement ::= PLACENAME COLON unnamed_statement */
2459 #line 549 "pikchr.y"
2460 { yylhsminor.yy36 = yymsp[0].minor.yy36; pik_elem_setname(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0); }
2461 #line 2486 "pikchr.c"
2462 yymsp[-2].minor.yy36 = yylhsminor.yy36;
2463 break;
2464 case 7: /* statement ::= PLACENAME COLON position */
2465 #line 551 "pikchr.y"
2466 { yylhsminor.yy36 = pik_elem_new(p,0,0,0);
2467 if(yylhsminor.yy36){ yylhsminor.yy36->ptAt = yymsp[0].minor.yy79; pik_elem_setname(p,yylhsminor.yy36,&yymsp[-2].minor.yy0); }}
2468 #line 2493 "pikchr.c"
2469 yymsp[-2].minor.yy36 = yylhsminor.yy36;
2470 break;
2471 case 8: /* statement ::= unnamed_statement */
2472 #line 553 "pikchr.y"
2473 {yylhsminor.yy36 = yymsp[0].minor.yy36;}
2474 #line 2499 "pikchr.c"
2475 yymsp[0].minor.yy36 = yylhsminor.yy36;
2476 break;
2477 case 9: /* statement ::= print prlist */
2478 #line 554 "pikchr.y"
2479 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy36=0;}
2480 #line 2505 "pikchr.c"
2481 break;
2482 case 10: /* statement ::= ASSERT LP expr EQ expr RP */
2483 #line 559 "pikchr.y"
2484 {yymsp[-5].minor.yy36=pik_assert(p,yymsp[-3].minor.yy153,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy153);}
2485 #line 2510 "pikchr.c"
2486 break;
2487 case 11: /* statement ::= ASSERT LP position EQ position RP */
2488 #line 561 "pikchr.y"
2489 {yymsp[-5].minor.yy36=pik_position_assert(p,&yymsp[-3].minor.yy79,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy79);}
2490 #line 2515 "pikchr.c"
2491 break;
2492 case 12: /* statement ::= DEFINE ID CODEBLOCK */
2493 #line 562 "pikchr.y"
2494 {yymsp[-2].minor.yy36=0; pik_add_macro(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
2495 #line 2520 "pikchr.c"
2496 break;
2497 case 13: /* rvalue ::= PLACENAME */
2498 #line 573 "pikchr.y"
2499 {yylhsminor.yy153 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2500 #line 2525 "pikchr.c"
2501 yymsp[0].minor.yy153 = yylhsminor.yy153;
2502 break;
2503 case 14: /* pritem ::= FILL */
2504 case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15);
2505 case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16);
2506 #line 578 "pikchr.y"
2507 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2508 #line 2533 "pikchr.c"
2509 break;
2510 case 17: /* pritem ::= rvalue */
2511 #line 581 "pikchr.y"
2512 {pik_append_num(p,"",yymsp[0].minor.yy153);}
2513 #line 2538 "pikchr.c"
2514 break;
2515 case 18: /* pritem ::= STRING */
2516 #line 582 "pikchr.y"
2517 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2518 #line 2543 "pikchr.c"
2519 break;
2520 case 19: /* prsep ::= COMMA */
2521 #line 583 "pikchr.y"
2522 {pik_append(p, " ", 1);}
2523 #line 2548 "pikchr.c"
2524 break;
2525 case 20: /* unnamed_statement ::= basetype attribute_list */
2526 #line 586 "pikchr.y"
2527 {yylhsminor.yy36 = yymsp[-1].minor.yy36; pik_after_adding_attributes(p,yylhsminor.yy36);}
2528 #line 2553 "pikchr.c"
2529 yymsp[-1].minor.yy36 = yylhsminor.yy36;
2530 break;
2531 case 21: /* basetype ::= CLASSNAME */
2532 #line 588 "pikchr.y"
2533 {yylhsminor.yy36 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2534 #line 2559 "pikchr.c"
2535 yymsp[0].minor.yy36 = yylhsminor.yy36;
2536 break;
2537 case 22: /* basetype ::= STRING textposition */
2538 #line 590 "pikchr.y"
2539 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy164; yylhsminor.yy36 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2540 #line 2565 "pikchr.c"
2541 yymsp[-1].minor.yy36 = yylhsminor.yy36;
2542 break;
2543 case 23: /* basetype ::= LB savelist statement_list RB */
2544 #line 592 "pikchr.y"
2545 { p->list = yymsp[-2].minor.yy227; yymsp[-3].minor.yy36 = pik_elem_new(p,0,0,yymsp[-1].minor.yy227); if(yymsp[-3].minor.yy36) yymsp[-3].minor.yy36->errTok = yymsp[0].minor.yy0; }
2546 #line 2571 "pikchr.c"
2547 break;
2548 case 24: /* savelist ::= */
2549 #line 597 "pikchr.y"
2550 {yymsp[1].minor.yy227 = p->list; p->list = 0;}
2551 #line 2576 "pikchr.c"
2552 break;
2553 case 25: /* relexpr ::= expr */
2554 #line 604 "pikchr.y"
2555 {yylhsminor.yy10.rAbs = yymsp[0].minor.yy153; yylhsminor.yy10.rRel = 0;}
2556 #line 2581 "pikchr.c"
2557 yymsp[0].minor.yy10 = yylhsminor.yy10;
2558 break;
2559 case 26: /* relexpr ::= expr PERCENT */
2560 #line 605 "pikchr.y"
2561 {yylhsminor.yy10.rAbs = 0; yylhsminor.yy10.rRel = yymsp[-1].minor.yy153/100;}
2562 #line 2587 "pikchr.c"
2563 yymsp[-1].minor.yy10 = yylhsminor.yy10;
2564 break;
2565 case 27: /* optrelexpr ::= */
2566 #line 607 "pikchr.y"
2567 {yymsp[1].minor.yy10.rAbs = 0; yymsp[1].minor.yy10.rRel = 1.0;}
2568 #line 2593 "pikchr.c"
2569 break;
2570 case 28: /* attribute_list ::= relexpr alist */
2571 #line 609 "pikchr.y"
2572 {pik_add_direction(p,0,&yymsp[-1].minor.yy10);}
2573 #line 2598 "pikchr.c"
2574 break;
2575 case 29: /* attribute ::= numproperty relexpr */
2576 #line 613 "pikchr.y"
2577 { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy10); }
2578 #line 2603 "pikchr.c"
2579 break;
2580 case 30: /* attribute ::= dashproperty expr */
2581 #line 614 "pikchr.y"
2582 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy153); }
2583 #line 2608 "pikchr.c"
2584 break;
2585 case 31: /* attribute ::= dashproperty */
2586 #line 615 "pikchr.y"
2587 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2588 #line 2613 "pikchr.c"
2589 break;
2590 case 32: /* attribute ::= colorproperty rvalue */
2591 #line 616 "pikchr.y"
2592 { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy153); }
2593 #line 2618 "pikchr.c"
2594 break;
2595 case 33: /* attribute ::= go direction optrelexpr */
2596 #line 617 "pikchr.y"
2597 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy10);}
2598 #line 2623 "pikchr.c"
2599 break;
2600 case 34: /* attribute ::= go direction even position */
2601 #line 618 "pikchr.y"
2602 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy79);}
2603 #line 2628 "pikchr.c"
2604 break;
2605 case 35: /* attribute ::= CLOSE */
2606 #line 619 "pikchr.y"
2607 { pik_close_path(p,&yymsp[0].minor.yy0); }
2608 #line 2633 "pikchr.c"
2609 break;
2610 case 36: /* attribute ::= CHOP */
2611 #line 620 "pikchr.y"
2612 { p->cur->bChop = 1; }
2613 #line 2638 "pikchr.c"
2614 break;
2615 case 37: /* attribute ::= FROM position */
2616 #line 621 "pikchr.y"
2617 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy79); }
2618 #line 2643 "pikchr.c"
2619 break;
2620 case 38: /* attribute ::= TO position */
2621 #line 622 "pikchr.y"
2622 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy79); }
2623 #line 2648 "pikchr.c"
2624 break;
2625 case 39: /* attribute ::= THEN */
2626 #line 623 "pikchr.y"
2627 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2628 #line 2653 "pikchr.c"
2629 break;
2630 case 40: /* attribute ::= THEN optrelexpr HEADING expr */
2631 case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42);
2632 #line 625 "pikchr.y"
2633 {pik_move_hdg(p,&yymsp[-2].minor.yy10,&yymsp[-1].minor.yy0,yymsp[0].minor.yy153,0,&yymsp[-3].minor.yy0);}
2634 #line 2659 "pikchr.c"
2635 break;
2636 case 41: /* attribute ::= THEN optrelexpr EDGEPT */
2637 case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43);
2638 #line 626 "pikchr.y"
2639 {pik_move_hdg(p,&yymsp[-1].minor.yy10,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2640 #line 2665 "pikchr.c"
2641 break;
2642 case 44: /* attribute ::= AT position */
2643 #line 631 "pikchr.y"
2644 { pik_set_at(p,0,&yymsp[0].minor.yy79,&yymsp[-1].minor.yy0); }
2645 #line 2670 "pikchr.c"
2646 break;
2647 case 45: /* attribute ::= SAME */
2648 #line 633 "pikchr.y"
2649 {pik_same(p,0,&yymsp[0].minor.yy0);}
2650 #line 2675 "pikchr.c"
2651 break;
2652 case 46: /* attribute ::= SAME AS object */
2653 #line 634 "pikchr.y"
2654 {pik_same(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0);}
2655 #line 2680 "pikchr.c"
2656 break;
2657 case 47: /* attribute ::= STRING textposition */
2658 #line 635 "pikchr.y"
2659 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy164);}
2660 #line 2685 "pikchr.c"
2661 break;
2662 case 48: /* attribute ::= FIT */
2663 #line 636 "pikchr.y"
2664 {pik_size_to_fit(p,&yymsp[0].minor.yy0,3); }
2665 #line 2690 "pikchr.c"
2666 break;
2667 case 49: /* attribute ::= BEHIND object */
2668 #line 637 "pikchr.y"
2669 {pik_behind(p,yymsp[0].minor.yy36);}
2670 #line 2695 "pikchr.c"
2671 break;
2672 case 50: /* withclause ::= DOT_E edge AT position */
2673 case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51);
2674 #line 645 "pikchr.y"
2675 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy79,&yymsp[-1].minor.yy0); }
2676 #line 2701 "pikchr.c"
2677 break;
2678 case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2679 #line 649 "pikchr.y"
2680 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2681 #line 2706 "pikchr.c"
2682 yymsp[0].minor.yy0 = yylhsminor.yy0;
2683 break;
2684 case 53: /* boolproperty ::= CW */
2685 #line 660 "pikchr.y"
2686 {p->cur->cw = 1;}
2687 #line 2712 "pikchr.c"
2688 break;
2689 case 54: /* boolproperty ::= CCW */
2690 #line 661 "pikchr.y"
2691 {p->cur->cw = 0;}
2692 #line 2717 "pikchr.c"
2693 break;
2694 case 55: /* boolproperty ::= LARROW */
2695 #line 662 "pikchr.y"
2696 {p->cur->larrow=1; p->cur->rarrow=0; }
2697 #line 2722 "pikchr.c"
2698 break;
2699 case 56: /* boolproperty ::= RARROW */
2700 #line 663 "pikchr.y"
2701 {p->cur->larrow=0; p->cur->rarrow=1; }
2702 #line 2727 "pikchr.c"
2703 break;
2704 case 57: /* boolproperty ::= LRARROW */
2705 #line 664 "pikchr.y"
2706 {p->cur->larrow=1; p->cur->rarrow=1; }
2707 #line 2732 "pikchr.c"
2708 break;
2709 case 58: /* boolproperty ::= INVIS */
2710 #line 665 "pikchr.y"
2711 {p->cur->sw = 0.0;}
2712 #line 2737 "pikchr.c"
2713 break;
2714 case 59: /* boolproperty ::= THICK */
2715 #line 666 "pikchr.y"
2716 {p->cur->sw *= 1.5;}
2717 #line 2742 "pikchr.c"
2718 break;
2719 case 60: /* boolproperty ::= THIN */
2720 #line 667 "pikchr.y"
2721 {p->cur->sw *= 0.67;}
2722 #line 2747 "pikchr.c"
2723 break;
2724 case 61: /* boolproperty ::= SOLID */
2725 #line 668 "pikchr.y"
2726 {p->cur->sw = pik_value(p,"thickness",9,0);
2727 p->cur->dotted = p->cur->dashed = 0.0;}
2728 #line 2753 "pikchr.c"
2729 break;
2730 case 62: /* textposition ::= */
2731 #line 671 "pikchr.y"
2732 {yymsp[1].minor.yy164 = 0;}
2733 #line 2758 "pikchr.c"
2734 break;
2735 case 63: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2736 #line 674 "pikchr.y"
2737 {yylhsminor.yy164 = (short int)pik_text_position(yymsp[-1].minor.yy164,&yymsp[0].minor.yy0);}
2738 #line 2763 "pikchr.c"
2739 yymsp[-1].minor.yy164 = yylhsminor.yy164;
2740 break;
2741 case 64: /* position ::= expr COMMA expr */
2742 #line 677 "pikchr.y"
2743 {yylhsminor.yy79.x=yymsp[-2].minor.yy153; yylhsminor.yy79.y=yymsp[0].minor.yy153;}
2744 #line 2769 "pikchr.c"
2745 yymsp[-2].minor.yy79 = yylhsminor.yy79;
2746 break;
2747 case 65: /* position ::= place PLUS expr COMMA expr */
2748 #line 679 "pikchr.y"
2749 {yylhsminor.yy79.x=yymsp[-4].minor.yy79.x+yymsp[-2].minor.yy153; yylhsminor.yy79.y=yymsp[-4].minor.yy79.y+yymsp[0].minor.yy153;}
2750 #line 2775 "pikchr.c"
2751 yymsp[-4].minor.yy79 = yylhsminor.yy79;
2752 break;
2753 case 66: /* position ::= place MINUS expr COMMA expr */
2754 #line 680 "pikchr.y"
2755 {yylhsminor.yy79.x=yymsp[-4].minor.yy79.x-yymsp[-2].minor.yy153; yylhsminor.yy79.y=yymsp[-4].minor.yy79.y-yymsp[0].minor.yy153;}
2756 #line 2781 "pikchr.c"
2757 yymsp[-4].minor.yy79 = yylhsminor.yy79;
2758 break;
2759 case 67: /* position ::= place PLUS LP expr COMMA expr RP */
2760 #line 682 "pikchr.y"
2761 {yylhsminor.yy79.x=yymsp[-6].minor.yy79.x+yymsp[-3].minor.yy153; yylhsminor.yy79.y=yymsp[-6].minor.yy79.y+yymsp[-1].minor.yy153;}
2762 #line 2787 "pikchr.c"
2763 yymsp[-6].minor.yy79 = yylhsminor.yy79;
2764 break;
2765 case 68: /* position ::= place MINUS LP expr COMMA expr RP */
2766 #line 684 "pikchr.y"
2767 {yylhsminor.yy79.x=yymsp[-6].minor.yy79.x-yymsp[-3].minor.yy153; yylhsminor.yy79.y=yymsp[-6].minor.yy79.y-yymsp[-1].minor.yy153;}
2768 #line 2793 "pikchr.c"
2769 yymsp[-6].minor.yy79 = yylhsminor.yy79;
2770 break;
2771 case 69: /* position ::= LP position COMMA position RP */
2772 #line 685 "pikchr.y"
2773 {yymsp[-4].minor.yy79.x=yymsp[-3].minor.yy79.x; yymsp[-4].minor.yy79.y=yymsp[-1].minor.yy79.y;}
2774 #line 2799 "pikchr.c"
2775 break;
2776 case 70: /* position ::= LP position RP */
2777 #line 686 "pikchr.y"
2778 {yymsp[-2].minor.yy79=yymsp[-1].minor.yy79;}
2779 #line 2804 "pikchr.c"
2780 break;
2781 case 71: /* position ::= expr between position AND position */
2782 #line 688 "pikchr.y"
2783 {yylhsminor.yy79 = pik_position_between(yymsp[-4].minor.yy153,yymsp[-2].minor.yy79,yymsp[0].minor.yy79);}
2784 #line 2809 "pikchr.c"
2785 yymsp[-4].minor.yy79 = yylhsminor.yy79;
2786 break;
2787 case 72: /* position ::= expr LT position COMMA position GT */
2788 #line 690 "pikchr.y"
2789 {yylhsminor.yy79 = pik_position_between(yymsp[-5].minor.yy153,yymsp[-3].minor.yy79,yymsp[-1].minor.yy79);}
2790 #line 2815 "pikchr.c"
2791 yymsp[-5].minor.yy79 = yylhsminor.yy79;
2792 break;
2793 case 73: /* position ::= expr ABOVE position */
2794 #line 691 "pikchr.y"
2795 {yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.y += yymsp[-2].minor.yy153;}
2796 #line 2821 "pikchr.c"
2797 yymsp[-2].minor.yy79 = yylhsminor.yy79;
2798 break;
2799 case 74: /* position ::= expr BELOW position */
2800 #line 692 "pikchr.y"
2801 {yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.y -= yymsp[-2].minor.yy153;}
2802 #line 2827 "pikchr.c"
2803 yymsp[-2].minor.yy79 = yylhsminor.yy79;
2804 break;
2805 case 75: /* position ::= expr LEFT OF position */
2806 #line 693 "pikchr.y"
2807 {yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.x -= yymsp[-3].minor.yy153;}
2808 #line 2833 "pikchr.c"
2809 yymsp[-3].minor.yy79 = yylhsminor.yy79;
2810 break;
2811 case 76: /* position ::= expr RIGHT OF position */
2812 #line 694 "pikchr.y"
2813 {yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.x += yymsp[-3].minor.yy153;}
2814 #line 2839 "pikchr.c"
2815 yymsp[-3].minor.yy79 = yylhsminor.yy79;
2816 break;
2817 case 77: /* position ::= expr ON HEADING EDGEPT OF position */
2818 #line 696 "pikchr.y"
2819 {yylhsminor.yy79 = pik_position_at_hdg(yymsp[-5].minor.yy153,&yymsp[-2].minor.yy0,yymsp[0].minor.yy79);}
2820 #line 2845 "pikchr.c"
2821 yymsp[-5].minor.yy79 = yylhsminor.yy79;
2822 break;
2823 case 78: /* position ::= expr HEADING EDGEPT OF position */
2824 #line 698 "pikchr.y"
2825 {yylhsminor.yy79 = pik_position_at_hdg(yymsp[-4].minor.yy153,&yymsp[-2].minor.yy0,yymsp[0].minor.yy79);}
2826 #line 2851 "pikchr.c"
2827 yymsp[-4].minor.yy79 = yylhsminor.yy79;
2828 break;
2829 case 79: /* position ::= expr EDGEPT OF position */
2830 #line 700 "pikchr.y"
2831 {yylhsminor.yy79 = pik_position_at_hdg(yymsp[-3].minor.yy153,&yymsp[-2].minor.yy0,yymsp[0].minor.yy79);}
2832 #line 2857 "pikchr.c"
2833 yymsp[-3].minor.yy79 = yylhsminor.yy79;
2834 break;
2835 case 80: /* position ::= expr ON HEADING expr FROM position */
2836 #line 702 "pikchr.y"
2837 {yylhsminor.yy79 = pik_position_at_angle(yymsp[-5].minor.yy153,yymsp[-2].minor.yy153,yymsp[0].minor.yy79);}
2838 #line 2863 "pikchr.c"
2839 yymsp[-5].minor.yy79 = yylhsminor.yy79;
2840 break;
2841 case 81: /* position ::= expr HEADING expr FROM position */
2842 #line 704 "pikchr.y"
2843 {yylhsminor.yy79 = pik_position_at_angle(yymsp[-4].minor.yy153,yymsp[-2].minor.yy153,yymsp[0].minor.yy79);}
2844 #line 2869 "pikchr.c"
2845 yymsp[-4].minor.yy79 = yylhsminor.yy79;
2846 break;
2847 case 82: /* place ::= edge OF object */
2848 #line 716 "pikchr.y"
2849 {yylhsminor.yy79 = pik_place_of_elem(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0);}
2850 #line 2875 "pikchr.c"
2851 yymsp[-2].minor.yy79 = yylhsminor.yy79;
2852 break;
2853 case 83: /* place2 ::= object */
2854 #line 717 "pikchr.y"
2855 {yylhsminor.yy79 = pik_place_of_elem(p,yymsp[0].minor.yy36,0);}
2856 #line 2881 "pikchr.c"
2857 yymsp[0].minor.yy79 = yylhsminor.yy79;
2858 break;
2859 case 84: /* place2 ::= object DOT_E edge */
2860 #line 718 "pikchr.y"
2861 {yylhsminor.yy79 = pik_place_of_elem(p,yymsp[-2].minor.yy36,&yymsp[0].minor.yy0);}
2862 #line 2887 "pikchr.c"
2863 yymsp[-2].minor.yy79 = yylhsminor.yy79;
2864 break;
2865 case 85: /* place2 ::= NTH VERTEX OF object */
2866 #line 719 "pikchr.y"
2867 {yylhsminor.yy79 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy36);}
2868 #line 2893 "pikchr.c"
2869 yymsp[-3].minor.yy79 = yylhsminor.yy79;
2870 break;
2871 case 86: /* object ::= nth */
2872 #line 731 "pikchr.y"
2873 {yylhsminor.yy36 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2874 #line 2899 "pikchr.c"
2875 yymsp[0].minor.yy36 = yylhsminor.yy36;
2876 break;
2877 case 87: /* object ::= nth OF|IN object */
2878 #line 732 "pikchr.y"
2879 {yylhsminor.yy36 = pik_find_nth(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0);}
2880 #line 2905 "pikchr.c"
2881 yymsp[-2].minor.yy36 = yylhsminor.yy36;
2882 break;
2883 case 88: /* objectname ::= THIS */
2884 #line 734 "pikchr.y"
2885 {yymsp[0].minor.yy36 = p->cur;}
2886 #line 2911 "pikchr.c"
2887 break;
2888 case 89: /* objectname ::= PLACENAME */
2889 #line 735 "pikchr.y"
2890 {yylhsminor.yy36 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2891 #line 2916 "pikchr.c"
2892 yymsp[0].minor.yy36 = yylhsminor.yy36;
2893 break;
2894 case 90: /* objectname ::= objectname DOT_U PLACENAME */
2895 #line 737 "pikchr.y"
2896 {yylhsminor.yy36 = pik_find_byname(p,yymsp[-2].minor.yy36,&yymsp[0].minor.yy0);}
2897 #line 2922 "pikchr.c"
2898 yymsp[-2].minor.yy36 = yylhsminor.yy36;
2899 break;
2900 case 91: /* nth ::= NTH CLASSNAME */
2901 #line 739 "pikchr.y"
2902 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2903 #line 2928 "pikchr.c"
2904 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2905 break;
2906 case 92: /* nth ::= NTH LAST CLASSNAME */
2907 #line 740 "pikchr.y"
2908 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2909 #line 2934 "pikchr.c"
2910 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2911 break;
2912 case 93: /* nth ::= LAST CLASSNAME */
2913 #line 741 "pikchr.y"
2914 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2915 #line 2940 "pikchr.c"
2916 break;
2917 case 94: /* nth ::= LAST */
2918 #line 742 "pikchr.y"
2919 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2920 #line 2945 "pikchr.c"
2921 yymsp[0].minor.yy0 = yylhsminor.yy0;
2922 break;
2923 case 95: /* nth ::= NTH LB RB */
2924 #line 743 "pikchr.y"
2925 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2926 #line 2951 "pikchr.c"
2927 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2928 break;
2929 case 96: /* nth ::= NTH LAST LB RB */
2930 #line 744 "pikchr.y"
2931 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2932 #line 2957 "pikchr.c"
2933 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2934 break;
2935 case 97: /* nth ::= LAST LB RB */
2936 #line 745 "pikchr.y"
2937 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2938 #line 2963 "pikchr.c"
2939 break;
2940 case 98: /* expr ::= expr PLUS expr */
2941 #line 747 "pikchr.y"
2942 {yylhsminor.yy153=yymsp[-2].minor.yy153+yymsp[0].minor.yy153;}
2943 #line 2968 "pikchr.c"
2944 yymsp[-2].minor.yy153 = yylhsminor.yy153;
2945 break;
2946 case 99: /* expr ::= expr MINUS expr */
2947 #line 748 "pikchr.y"
2948 {yylhsminor.yy153=yymsp[-2].minor.yy153-yymsp[0].minor.yy153;}
2949 #line 2974 "pikchr.c"
2950 yymsp[-2].minor.yy153 = yylhsminor.yy153;
2951 break;
2952 case 100: /* expr ::= expr STAR expr */
2953 #line 749 "pikchr.y"
2954 {yylhsminor.yy153=yymsp[-2].minor.yy153*yymsp[0].minor.yy153;}
2955 #line 2980 "pikchr.c"
2956 yymsp[-2].minor.yy153 = yylhsminor.yy153;
2957 break;
2958 case 101: /* expr ::= expr SLASH expr */
2959 #line 750 "pikchr.y"
2960 {
2961 if( yymsp[0].minor.yy153==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy153 = 0.0; }
2962 else{ yylhsminor.yy153 = yymsp[-2].minor.yy153/yymsp[0].minor.yy153; }
2963 }
2964 #line 2989 "pikchr.c"
2965 yymsp[-2].minor.yy153 = yylhsminor.yy153;
2966 break;
2967 case 102: /* expr ::= MINUS expr */
2968 #line 754 "pikchr.y"
2969 {yymsp[-1].minor.yy153=-yymsp[0].minor.yy153;}
2970 #line 2995 "pikchr.c"
2971 break;
2972 case 103: /* expr ::= PLUS expr */
2973 #line 755 "pikchr.y"
2974 {yymsp[-1].minor.yy153=yymsp[0].minor.yy153;}
2975 #line 3000 "pikchr.c"
2976 break;
2977 case 104: /* expr ::= LP expr RP */
2978 #line 756 "pikchr.y"
2979 {yymsp[-2].minor.yy153=yymsp[-1].minor.yy153;}
2980 #line 3005 "pikchr.c"
2981 break;
2982 case 105: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2983 #line 757 "pikchr.y"
2984 {yymsp[-2].minor.yy153=pik_get_var(p,&yymsp[-1].minor.yy0);}
2985 #line 3010 "pikchr.c"
2986 break;
2987 case 106: /* expr ::= NUMBER */
2988 #line 758 "pikchr.y"
2989 {yylhsminor.yy153=pik_atof(&yymsp[0].minor.yy0);}
2990 #line 3015 "pikchr.c"
2991 yymsp[0].minor.yy153 = yylhsminor.yy153;
2992 break;
2993 case 107: /* expr ::= ID */
2994 #line 759 "pikchr.y"
2995 {yylhsminor.yy153=pik_get_var(p,&yymsp[0].minor.yy0);}
2996 #line 3021 "pikchr.c"
2997 yymsp[0].minor.yy153 = yylhsminor.yy153;
2998 break;
2999 case 108: /* expr ::= FUNC1 LP expr RP */
3000 #line 760 "pikchr.y"
3001 {yylhsminor.yy153 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy153,0.0);}
3002 #line 3027 "pikchr.c"
3003 yymsp[-3].minor.yy153 = yylhsminor.yy153;
3004 break;
3005 case 109: /* expr ::= FUNC2 LP expr COMMA expr RP */
3006 #line 761 "pikchr.y"
3007 {yylhsminor.yy153 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy153,yymsp[-1].minor.yy153);}
3008 #line 3033 "pikchr.c"
3009 yymsp[-5].minor.yy153 = yylhsminor.yy153;
3010 break;
3011 case 110: /* expr ::= DIST LP position COMMA position RP */
3012 #line 762 "pikchr.y"
3013 {yymsp[-5].minor.yy153 = pik_dist(&yymsp[-3].minor.yy79,&yymsp[-1].minor.yy79);}
3014 #line 3039 "pikchr.c"
3015 break;
3016 case 111: /* expr ::= place2 DOT_XY X */
3017 #line 763 "pikchr.y"
3018 {yylhsminor.yy153 = yymsp[-2].minor.yy79.x;}
3019 #line 3044 "pikchr.c"
3020 yymsp[-2].minor.yy153 = yylhsminor.yy153;
3021 break;
3022 case 112: /* expr ::= place2 DOT_XY Y */
3023 #line 764 "pikchr.y"
3024 {yylhsminor.yy153 = yymsp[-2].minor.yy79.y;}
3025 #line 3050 "pikchr.c"
3026 yymsp[-2].minor.yy153 = yylhsminor.yy153;
3027 break;
3028 case 113: /* expr ::= object DOT_L numproperty */
3029 case 114: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==114);
3030 case 115: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==115);
3031 #line 765 "pikchr.y"
3032 {yylhsminor.yy153=pik_property_of(yymsp[-2].minor.yy36,&yymsp[0].minor.yy0);}
3033 #line 3058 "pikchr.c"
3034 yymsp[-2].minor.yy153 = yylhsminor.yy153;
3035 break;
3036 default:
3037 /* (116) lvalue ::= ID */ yytestcase(yyruleno==116);
3038 /* (117) lvalue ::= FILL */ yytestcase(yyruleno==117);
@@ -3131,19 +3141,19 @@
3131 ){
3132 pik_parserARG_FETCH
3133 pik_parserCTX_FETCH
3134 #define TOKEN yyminor
3135 /************ Begin %syntax_error code ****************************************/
3136 #line 525 "pikchr.y"
3137
3138 if( TOKEN.z && TOKEN.z[0] ){
3139 pik_error(p, &TOKEN, "syntax error");
3140 }else{
3141 pik_error(p, 0, "syntax error");
3142 }
3143 UNUSED_PARAMETER(yymajor);
3144 #line 3169 "pikchr.c"
3145 /************ End %syntax_error code ******************************************/
3146 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
3147 pik_parserCTX_STORE
3148 }
3149
@@ -3372,11 +3382,11 @@
3372 #else
3373 (void)iToken;
3374 return 0;
3375 #endif
3376 }
3377 #line 770 "pikchr.y"
3378
3379
3380
3381 /* Chart of the 148 official CSS color names with their
3382 ** corresponding RGB values thru Color Module Level 4:
@@ -6645,11 +6655,11 @@
6645 /* Compute one of the built-in functions
6646 */
6647 static PNum pik_func(Pik *p, PToken *pFunc, PNum x, PNum y){
6648 PNum v = 0.0;
6649 switch( pFunc->eCode ){
6650 case FN_ABS: v = v<0.0 ? -v : v; break;
6651 case FN_COS: v = cos(x); break;
6652 case FN_INT: v = rint(x); break;
6653 case FN_SIN: v = sin(x); break;
6654 case FN_SQRT:
6655 if( x<0.0 ){
@@ -7744,10 +7754,14 @@
7744 printf("******** Token %s (%d): \"%.*s\" **************\n",
7745 yyTokenName[token.eType], token.eType,
7746 (int)(isspace(token.z[0]) ? 0 : sz), token.z);
7747 #endif
7748 token.n = (unsigned short)(sz & 0xffff);
 
 
 
 
7749 pik_parser(pParser, token.eType, token);
7750 }
7751 }
7752 }
7753
@@ -8081,6 +8095,6 @@
8081
8082
8083 #endif /* PIKCHR_TCL */
8084
8085
8086 #line 8111 "pikchr.c"
8087
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -124,10 +124,19 @@
124 #include <assert.h>
125 #define count(X) (sizeof(X)/sizeof(X[0]))
126 #ifndef M_PI
127 # define M_PI 3.1415926535897932385
128 #endif
129
130 /* Limit the number of tokens in a single script to avoid run-away
131 ** macro expansion attacks. See forum post
132 ** https://pikchr.org/home/forumpost/ef8684c6955a411a
133 */
134 #ifndef PIKCHR_TOKEN_LIMIT
135 # define PIKCHR_TOKEN_LIMIT 100000
136 #endif
137
138
139 /* Tag intentionally unused parameters with this macro to prevent
140 ** compiler warnings with -Wextra */
141 #define UNUSED_PARAMETER(X) (void)(X)
142
@@ -341,10 +350,11 @@
350 /* Each call to the pikchr() subroutine uses an instance of the following
351 ** object to pass around context to all of its subroutines.
352 */
353 struct Pik {
354 unsigned nErr; /* Number of errors seen */
355 unsigned nToken; /* Number of tokens parsed */
356 PToken sIn; /* Input Pikchr-language text */
357 char *zOut; /* Result accumulates here */
358 unsigned int nOut; /* Bytes written to zOut[] so far */
359 unsigned int nOutAlloc; /* Space allocated to zOut[] */
360 unsigned char eDir; /* Current direction */
@@ -479,11 +489,11 @@
489 static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
490 static PNum pik_dist(PPoint*,PPoint*);
491 static void pik_add_macro(Pik*,PToken *pId,PToken *pCode);
492
493
494 #line 520 "pikchr.c"
495 /**************** End of %include directives **********************************/
496 /* These constants specify the various numeric values for terminal symbols.
497 ***************** Begin token definitions *************************************/
498 #ifndef T_ID
499 #define T_ID 1
@@ -1708,22 +1718,22 @@
1718 ** inside the C code.
1719 */
1720 /********* Begin destructor definitions ***************************************/
1721 case 99: /* statement_list */
1722 {
1723 #line 509 "pikchr.y"
1724 pik_elist_free(p,(yypminor->yy227));
1725 #line 1750 "pikchr.c"
1726 }
1727 break;
1728 case 100: /* statement */
1729 case 101: /* unnamed_statement */
1730 case 102: /* basetype */
1731 {
1732 #line 511 "pikchr.y"
1733 pik_elem_free(p,(yypminor->yy36));
1734 #line 1759 "pikchr.c"
1735 }
1736 break;
1737 /********* End destructor definitions *****************************************/
1738 default: break; /* If no destructor action specified: do nothing */
1739 }
@@ -1937,14 +1947,14 @@
1947 #endif
1948 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1949 /* Here code is inserted which will execute if the parser
1950 ** stack every overflows */
1951 /******** Begin %stack_overflow code ******************************************/
1952 #line 543 "pikchr.y"
1953
1954 pik_error(p, 0, "parser stack overflow");
1955 #line 1980 "pikchr.c"
1956 /******** End %stack_overflow code ********************************************/
1957 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
1958 pik_parserCTX_STORE
1959 }
1960
@@ -2420,619 +2430,619 @@
2430 ** break;
2431 */
2432 /********** Begin reduce actions **********************************************/
2433 YYMINORTYPE yylhsminor;
2434 case 0: /* document ::= statement_list */
2435 #line 547 "pikchr.y"
2436 {pik_render(p,yymsp[0].minor.yy227);}
2437 #line 2462 "pikchr.c"
2438 break;
2439 case 1: /* statement_list ::= statement */
2440 #line 550 "pikchr.y"
2441 { yylhsminor.yy227 = pik_elist_append(p,0,yymsp[0].minor.yy36); }
2442 #line 2467 "pikchr.c"
2443 yymsp[0].minor.yy227 = yylhsminor.yy227;
2444 break;
2445 case 2: /* statement_list ::= statement_list EOL statement */
2446 #line 552 "pikchr.y"
2447 { yylhsminor.yy227 = pik_elist_append(p,yymsp[-2].minor.yy227,yymsp[0].minor.yy36); }
2448 #line 2473 "pikchr.c"
2449 yymsp[-2].minor.yy227 = yylhsminor.yy227;
2450 break;
2451 case 3: /* statement ::= */
2452 #line 555 "pikchr.y"
2453 { yymsp[1].minor.yy36 = 0; }
2454 #line 2479 "pikchr.c"
2455 break;
2456 case 4: /* statement ::= direction */
2457 #line 556 "pikchr.y"
2458 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy36=0; }
2459 #line 2484 "pikchr.c"
2460 yymsp[0].minor.yy36 = yylhsminor.yy36;
2461 break;
2462 case 5: /* statement ::= lvalue ASSIGN rvalue */
2463 #line 557 "pikchr.y"
2464 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy153,&yymsp[-1].minor.yy0); yylhsminor.yy36=0;}
2465 #line 2490 "pikchr.c"
2466 yymsp[-2].minor.yy36 = yylhsminor.yy36;
2467 break;
2468 case 6: /* statement ::= PLACENAME COLON unnamed_statement */
2469 #line 559 "pikchr.y"
2470 { yylhsminor.yy36 = yymsp[0].minor.yy36; pik_elem_setname(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0); }
2471 #line 2496 "pikchr.c"
2472 yymsp[-2].minor.yy36 = yylhsminor.yy36;
2473 break;
2474 case 7: /* statement ::= PLACENAME COLON position */
2475 #line 561 "pikchr.y"
2476 { yylhsminor.yy36 = pik_elem_new(p,0,0,0);
2477 if(yylhsminor.yy36){ yylhsminor.yy36->ptAt = yymsp[0].minor.yy79; pik_elem_setname(p,yylhsminor.yy36,&yymsp[-2].minor.yy0); }}
2478 #line 2503 "pikchr.c"
2479 yymsp[-2].minor.yy36 = yylhsminor.yy36;
2480 break;
2481 case 8: /* statement ::= unnamed_statement */
2482 #line 563 "pikchr.y"
2483 {yylhsminor.yy36 = yymsp[0].minor.yy36;}
2484 #line 2509 "pikchr.c"
2485 yymsp[0].minor.yy36 = yylhsminor.yy36;
2486 break;
2487 case 9: /* statement ::= print prlist */
2488 #line 564 "pikchr.y"
2489 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy36=0;}
2490 #line 2515 "pikchr.c"
2491 break;
2492 case 10: /* statement ::= ASSERT LP expr EQ expr RP */
2493 #line 569 "pikchr.y"
2494 {yymsp[-5].minor.yy36=pik_assert(p,yymsp[-3].minor.yy153,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy153);}
2495 #line 2520 "pikchr.c"
2496 break;
2497 case 11: /* statement ::= ASSERT LP position EQ position RP */
2498 #line 571 "pikchr.y"
2499 {yymsp[-5].minor.yy36=pik_position_assert(p,&yymsp[-3].minor.yy79,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy79);}
2500 #line 2525 "pikchr.c"
2501 break;
2502 case 12: /* statement ::= DEFINE ID CODEBLOCK */
2503 #line 572 "pikchr.y"
2504 {yymsp[-2].minor.yy36=0; pik_add_macro(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
2505 #line 2530 "pikchr.c"
2506 break;
2507 case 13: /* rvalue ::= PLACENAME */
2508 #line 583 "pikchr.y"
2509 {yylhsminor.yy153 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2510 #line 2535 "pikchr.c"
2511 yymsp[0].minor.yy153 = yylhsminor.yy153;
2512 break;
2513 case 14: /* pritem ::= FILL */
2514 case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15);
2515 case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16);
2516 #line 588 "pikchr.y"
2517 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2518 #line 2543 "pikchr.c"
2519 break;
2520 case 17: /* pritem ::= rvalue */
2521 #line 591 "pikchr.y"
2522 {pik_append_num(p,"",yymsp[0].minor.yy153);}
2523 #line 2548 "pikchr.c"
2524 break;
2525 case 18: /* pritem ::= STRING */
2526 #line 592 "pikchr.y"
2527 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2528 #line 2553 "pikchr.c"
2529 break;
2530 case 19: /* prsep ::= COMMA */
2531 #line 593 "pikchr.y"
2532 {pik_append(p, " ", 1);}
2533 #line 2558 "pikchr.c"
2534 break;
2535 case 20: /* unnamed_statement ::= basetype attribute_list */
2536 #line 596 "pikchr.y"
2537 {yylhsminor.yy36 = yymsp[-1].minor.yy36; pik_after_adding_attributes(p,yylhsminor.yy36);}
2538 #line 2563 "pikchr.c"
2539 yymsp[-1].minor.yy36 = yylhsminor.yy36;
2540 break;
2541 case 21: /* basetype ::= CLASSNAME */
2542 #line 598 "pikchr.y"
2543 {yylhsminor.yy36 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2544 #line 2569 "pikchr.c"
2545 yymsp[0].minor.yy36 = yylhsminor.yy36;
2546 break;
2547 case 22: /* basetype ::= STRING textposition */
2548 #line 600 "pikchr.y"
2549 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy164; yylhsminor.yy36 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2550 #line 2575 "pikchr.c"
2551 yymsp[-1].minor.yy36 = yylhsminor.yy36;
2552 break;
2553 case 23: /* basetype ::= LB savelist statement_list RB */
2554 #line 602 "pikchr.y"
2555 { p->list = yymsp[-2].minor.yy227; yymsp[-3].minor.yy36 = pik_elem_new(p,0,0,yymsp[-1].minor.yy227); if(yymsp[-3].minor.yy36) yymsp[-3].minor.yy36->errTok = yymsp[0].minor.yy0; }
2556 #line 2581 "pikchr.c"
2557 break;
2558 case 24: /* savelist ::= */
2559 #line 607 "pikchr.y"
2560 {yymsp[1].minor.yy227 = p->list; p->list = 0;}
2561 #line 2586 "pikchr.c"
2562 break;
2563 case 25: /* relexpr ::= expr */
2564 #line 614 "pikchr.y"
2565 {yylhsminor.yy10.rAbs = yymsp[0].minor.yy153; yylhsminor.yy10.rRel = 0;}
2566 #line 2591 "pikchr.c"
2567 yymsp[0].minor.yy10 = yylhsminor.yy10;
2568 break;
2569 case 26: /* relexpr ::= expr PERCENT */
2570 #line 615 "pikchr.y"
2571 {yylhsminor.yy10.rAbs = 0; yylhsminor.yy10.rRel = yymsp[-1].minor.yy153/100;}
2572 #line 2597 "pikchr.c"
2573 yymsp[-1].minor.yy10 = yylhsminor.yy10;
2574 break;
2575 case 27: /* optrelexpr ::= */
2576 #line 617 "pikchr.y"
2577 {yymsp[1].minor.yy10.rAbs = 0; yymsp[1].minor.yy10.rRel = 1.0;}
2578 #line 2603 "pikchr.c"
2579 break;
2580 case 28: /* attribute_list ::= relexpr alist */
2581 #line 619 "pikchr.y"
2582 {pik_add_direction(p,0,&yymsp[-1].minor.yy10);}
2583 #line 2608 "pikchr.c"
2584 break;
2585 case 29: /* attribute ::= numproperty relexpr */
2586 #line 623 "pikchr.y"
2587 { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy10); }
2588 #line 2613 "pikchr.c"
2589 break;
2590 case 30: /* attribute ::= dashproperty expr */
2591 #line 624 "pikchr.y"
2592 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy153); }
2593 #line 2618 "pikchr.c"
2594 break;
2595 case 31: /* attribute ::= dashproperty */
2596 #line 625 "pikchr.y"
2597 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2598 #line 2623 "pikchr.c"
2599 break;
2600 case 32: /* attribute ::= colorproperty rvalue */
2601 #line 626 "pikchr.y"
2602 { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy153); }
2603 #line 2628 "pikchr.c"
2604 break;
2605 case 33: /* attribute ::= go direction optrelexpr */
2606 #line 627 "pikchr.y"
2607 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy10);}
2608 #line 2633 "pikchr.c"
2609 break;
2610 case 34: /* attribute ::= go direction even position */
2611 #line 628 "pikchr.y"
2612 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy79);}
2613 #line 2638 "pikchr.c"
2614 break;
2615 case 35: /* attribute ::= CLOSE */
2616 #line 629 "pikchr.y"
2617 { pik_close_path(p,&yymsp[0].minor.yy0); }
2618 #line 2643 "pikchr.c"
2619 break;
2620 case 36: /* attribute ::= CHOP */
2621 #line 630 "pikchr.y"
2622 { p->cur->bChop = 1; }
2623 #line 2648 "pikchr.c"
2624 break;
2625 case 37: /* attribute ::= FROM position */
2626 #line 631 "pikchr.y"
2627 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy79); }
2628 #line 2653 "pikchr.c"
2629 break;
2630 case 38: /* attribute ::= TO position */
2631 #line 632 "pikchr.y"
2632 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy79); }
2633 #line 2658 "pikchr.c"
2634 break;
2635 case 39: /* attribute ::= THEN */
2636 #line 633 "pikchr.y"
2637 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2638 #line 2663 "pikchr.c"
2639 break;
2640 case 40: /* attribute ::= THEN optrelexpr HEADING expr */
2641 case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42);
2642 #line 635 "pikchr.y"
2643 {pik_move_hdg(p,&yymsp[-2].minor.yy10,&yymsp[-1].minor.yy0,yymsp[0].minor.yy153,0,&yymsp[-3].minor.yy0);}
2644 #line 2669 "pikchr.c"
2645 break;
2646 case 41: /* attribute ::= THEN optrelexpr EDGEPT */
2647 case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43);
2648 #line 636 "pikchr.y"
2649 {pik_move_hdg(p,&yymsp[-1].minor.yy10,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2650 #line 2675 "pikchr.c"
2651 break;
2652 case 44: /* attribute ::= AT position */
2653 #line 641 "pikchr.y"
2654 { pik_set_at(p,0,&yymsp[0].minor.yy79,&yymsp[-1].minor.yy0); }
2655 #line 2680 "pikchr.c"
2656 break;
2657 case 45: /* attribute ::= SAME */
2658 #line 643 "pikchr.y"
2659 {pik_same(p,0,&yymsp[0].minor.yy0);}
2660 #line 2685 "pikchr.c"
2661 break;
2662 case 46: /* attribute ::= SAME AS object */
2663 #line 644 "pikchr.y"
2664 {pik_same(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0);}
2665 #line 2690 "pikchr.c"
2666 break;
2667 case 47: /* attribute ::= STRING textposition */
2668 #line 645 "pikchr.y"
2669 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy164);}
2670 #line 2695 "pikchr.c"
2671 break;
2672 case 48: /* attribute ::= FIT */
2673 #line 646 "pikchr.y"
2674 {pik_size_to_fit(p,&yymsp[0].minor.yy0,3); }
2675 #line 2700 "pikchr.c"
2676 break;
2677 case 49: /* attribute ::= BEHIND object */
2678 #line 647 "pikchr.y"
2679 {pik_behind(p,yymsp[0].minor.yy36);}
2680 #line 2705 "pikchr.c"
2681 break;
2682 case 50: /* withclause ::= DOT_E edge AT position */
2683 case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51);
2684 #line 655 "pikchr.y"
2685 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy79,&yymsp[-1].minor.yy0); }
2686 #line 2711 "pikchr.c"
2687 break;
2688 case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2689 #line 659 "pikchr.y"
2690 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2691 #line 2716 "pikchr.c"
2692 yymsp[0].minor.yy0 = yylhsminor.yy0;
2693 break;
2694 case 53: /* boolproperty ::= CW */
2695 #line 670 "pikchr.y"
2696 {p->cur->cw = 1;}
2697 #line 2722 "pikchr.c"
2698 break;
2699 case 54: /* boolproperty ::= CCW */
2700 #line 671 "pikchr.y"
2701 {p->cur->cw = 0;}
2702 #line 2727 "pikchr.c"
2703 break;
2704 case 55: /* boolproperty ::= LARROW */
2705 #line 672 "pikchr.y"
2706 {p->cur->larrow=1; p->cur->rarrow=0; }
2707 #line 2732 "pikchr.c"
2708 break;
2709 case 56: /* boolproperty ::= RARROW */
2710 #line 673 "pikchr.y"
2711 {p->cur->larrow=0; p->cur->rarrow=1; }
2712 #line 2737 "pikchr.c"
2713 break;
2714 case 57: /* boolproperty ::= LRARROW */
2715 #line 674 "pikchr.y"
2716 {p->cur->larrow=1; p->cur->rarrow=1; }
2717 #line 2742 "pikchr.c"
2718 break;
2719 case 58: /* boolproperty ::= INVIS */
2720 #line 675 "pikchr.y"
2721 {p->cur->sw = 0.0;}
2722 #line 2747 "pikchr.c"
2723 break;
2724 case 59: /* boolproperty ::= THICK */
2725 #line 676 "pikchr.y"
2726 {p->cur->sw *= 1.5;}
2727 #line 2752 "pikchr.c"
2728 break;
2729 case 60: /* boolproperty ::= THIN */
2730 #line 677 "pikchr.y"
2731 {p->cur->sw *= 0.67;}
2732 #line 2757 "pikchr.c"
2733 break;
2734 case 61: /* boolproperty ::= SOLID */
2735 #line 678 "pikchr.y"
2736 {p->cur->sw = pik_value(p,"thickness",9,0);
2737 p->cur->dotted = p->cur->dashed = 0.0;}
2738 #line 2763 "pikchr.c"
2739 break;
2740 case 62: /* textposition ::= */
2741 #line 681 "pikchr.y"
2742 {yymsp[1].minor.yy164 = 0;}
2743 #line 2768 "pikchr.c"
2744 break;
2745 case 63: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2746 #line 684 "pikchr.y"
2747 {yylhsminor.yy164 = (short int)pik_text_position(yymsp[-1].minor.yy164,&yymsp[0].minor.yy0);}
2748 #line 2773 "pikchr.c"
2749 yymsp[-1].minor.yy164 = yylhsminor.yy164;
2750 break;
2751 case 64: /* position ::= expr COMMA expr */
2752 #line 687 "pikchr.y"
2753 {yylhsminor.yy79.x=yymsp[-2].minor.yy153; yylhsminor.yy79.y=yymsp[0].minor.yy153;}
2754 #line 2779 "pikchr.c"
2755 yymsp[-2].minor.yy79 = yylhsminor.yy79;
2756 break;
2757 case 65: /* position ::= place PLUS expr COMMA expr */
2758 #line 689 "pikchr.y"
2759 {yylhsminor.yy79.x=yymsp[-4].minor.yy79.x+yymsp[-2].minor.yy153; yylhsminor.yy79.y=yymsp[-4].minor.yy79.y+yymsp[0].minor.yy153;}
2760 #line 2785 "pikchr.c"
2761 yymsp[-4].minor.yy79 = yylhsminor.yy79;
2762 break;
2763 case 66: /* position ::= place MINUS expr COMMA expr */
2764 #line 690 "pikchr.y"
2765 {yylhsminor.yy79.x=yymsp[-4].minor.yy79.x-yymsp[-2].minor.yy153; yylhsminor.yy79.y=yymsp[-4].minor.yy79.y-yymsp[0].minor.yy153;}
2766 #line 2791 "pikchr.c"
2767 yymsp[-4].minor.yy79 = yylhsminor.yy79;
2768 break;
2769 case 67: /* position ::= place PLUS LP expr COMMA expr RP */
2770 #line 692 "pikchr.y"
2771 {yylhsminor.yy79.x=yymsp[-6].minor.yy79.x+yymsp[-3].minor.yy153; yylhsminor.yy79.y=yymsp[-6].minor.yy79.y+yymsp[-1].minor.yy153;}
2772 #line 2797 "pikchr.c"
2773 yymsp[-6].minor.yy79 = yylhsminor.yy79;
2774 break;
2775 case 68: /* position ::= place MINUS LP expr COMMA expr RP */
2776 #line 694 "pikchr.y"
2777 {yylhsminor.yy79.x=yymsp[-6].minor.yy79.x-yymsp[-3].minor.yy153; yylhsminor.yy79.y=yymsp[-6].minor.yy79.y-yymsp[-1].minor.yy153;}
2778 #line 2803 "pikchr.c"
2779 yymsp[-6].minor.yy79 = yylhsminor.yy79;
2780 break;
2781 case 69: /* position ::= LP position COMMA position RP */
2782 #line 695 "pikchr.y"
2783 {yymsp[-4].minor.yy79.x=yymsp[-3].minor.yy79.x; yymsp[-4].minor.yy79.y=yymsp[-1].minor.yy79.y;}
2784 #line 2809 "pikchr.c"
2785 break;
2786 case 70: /* position ::= LP position RP */
2787 #line 696 "pikchr.y"
2788 {yymsp[-2].minor.yy79=yymsp[-1].minor.yy79;}
2789 #line 2814 "pikchr.c"
2790 break;
2791 case 71: /* position ::= expr between position AND position */
2792 #line 698 "pikchr.y"
2793 {yylhsminor.yy79 = pik_position_between(yymsp[-4].minor.yy153,yymsp[-2].minor.yy79,yymsp[0].minor.yy79);}
2794 #line 2819 "pikchr.c"
2795 yymsp[-4].minor.yy79 = yylhsminor.yy79;
2796 break;
2797 case 72: /* position ::= expr LT position COMMA position GT */
2798 #line 700 "pikchr.y"
2799 {yylhsminor.yy79 = pik_position_between(yymsp[-5].minor.yy153,yymsp[-3].minor.yy79,yymsp[-1].minor.yy79);}
2800 #line 2825 "pikchr.c"
2801 yymsp[-5].minor.yy79 = yylhsminor.yy79;
2802 break;
2803 case 73: /* position ::= expr ABOVE position */
2804 #line 701 "pikchr.y"
2805 {yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.y += yymsp[-2].minor.yy153;}
2806 #line 2831 "pikchr.c"
2807 yymsp[-2].minor.yy79 = yylhsminor.yy79;
2808 break;
2809 case 74: /* position ::= expr BELOW position */
2810 #line 702 "pikchr.y"
2811 {yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.y -= yymsp[-2].minor.yy153;}
2812 #line 2837 "pikchr.c"
2813 yymsp[-2].minor.yy79 = yylhsminor.yy79;
2814 break;
2815 case 75: /* position ::= expr LEFT OF position */
2816 #line 703 "pikchr.y"
2817 {yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.x -= yymsp[-3].minor.yy153;}
2818 #line 2843 "pikchr.c"
2819 yymsp[-3].minor.yy79 = yylhsminor.yy79;
2820 break;
2821 case 76: /* position ::= expr RIGHT OF position */
2822 #line 704 "pikchr.y"
2823 {yylhsminor.yy79=yymsp[0].minor.yy79; yylhsminor.yy79.x += yymsp[-3].minor.yy153;}
2824 #line 2849 "pikchr.c"
2825 yymsp[-3].minor.yy79 = yylhsminor.yy79;
2826 break;
2827 case 77: /* position ::= expr ON HEADING EDGEPT OF position */
2828 #line 706 "pikchr.y"
2829 {yylhsminor.yy79 = pik_position_at_hdg(yymsp[-5].minor.yy153,&yymsp[-2].minor.yy0,yymsp[0].minor.yy79);}
2830 #line 2855 "pikchr.c"
2831 yymsp[-5].minor.yy79 = yylhsminor.yy79;
2832 break;
2833 case 78: /* position ::= expr HEADING EDGEPT OF position */
2834 #line 708 "pikchr.y"
2835 {yylhsminor.yy79 = pik_position_at_hdg(yymsp[-4].minor.yy153,&yymsp[-2].minor.yy0,yymsp[0].minor.yy79);}
2836 #line 2861 "pikchr.c"
2837 yymsp[-4].minor.yy79 = yylhsminor.yy79;
2838 break;
2839 case 79: /* position ::= expr EDGEPT OF position */
2840 #line 710 "pikchr.y"
2841 {yylhsminor.yy79 = pik_position_at_hdg(yymsp[-3].minor.yy153,&yymsp[-2].minor.yy0,yymsp[0].minor.yy79);}
2842 #line 2867 "pikchr.c"
2843 yymsp[-3].minor.yy79 = yylhsminor.yy79;
2844 break;
2845 case 80: /* position ::= expr ON HEADING expr FROM position */
2846 #line 712 "pikchr.y"
2847 {yylhsminor.yy79 = pik_position_at_angle(yymsp[-5].minor.yy153,yymsp[-2].minor.yy153,yymsp[0].minor.yy79);}
2848 #line 2873 "pikchr.c"
2849 yymsp[-5].minor.yy79 = yylhsminor.yy79;
2850 break;
2851 case 81: /* position ::= expr HEADING expr FROM position */
2852 #line 714 "pikchr.y"
2853 {yylhsminor.yy79 = pik_position_at_angle(yymsp[-4].minor.yy153,yymsp[-2].minor.yy153,yymsp[0].minor.yy79);}
2854 #line 2879 "pikchr.c"
2855 yymsp[-4].minor.yy79 = yylhsminor.yy79;
2856 break;
2857 case 82: /* place ::= edge OF object */
2858 #line 726 "pikchr.y"
2859 {yylhsminor.yy79 = pik_place_of_elem(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0);}
2860 #line 2885 "pikchr.c"
2861 yymsp[-2].minor.yy79 = yylhsminor.yy79;
2862 break;
2863 case 83: /* place2 ::= object */
2864 #line 727 "pikchr.y"
2865 {yylhsminor.yy79 = pik_place_of_elem(p,yymsp[0].minor.yy36,0);}
2866 #line 2891 "pikchr.c"
2867 yymsp[0].minor.yy79 = yylhsminor.yy79;
2868 break;
2869 case 84: /* place2 ::= object DOT_E edge */
2870 #line 728 "pikchr.y"
2871 {yylhsminor.yy79 = pik_place_of_elem(p,yymsp[-2].minor.yy36,&yymsp[0].minor.yy0);}
2872 #line 2897 "pikchr.c"
2873 yymsp[-2].minor.yy79 = yylhsminor.yy79;
2874 break;
2875 case 85: /* place2 ::= NTH VERTEX OF object */
2876 #line 729 "pikchr.y"
2877 {yylhsminor.yy79 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy36);}
2878 #line 2903 "pikchr.c"
2879 yymsp[-3].minor.yy79 = yylhsminor.yy79;
2880 break;
2881 case 86: /* object ::= nth */
2882 #line 741 "pikchr.y"
2883 {yylhsminor.yy36 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2884 #line 2909 "pikchr.c"
2885 yymsp[0].minor.yy36 = yylhsminor.yy36;
2886 break;
2887 case 87: /* object ::= nth OF|IN object */
2888 #line 742 "pikchr.y"
2889 {yylhsminor.yy36 = pik_find_nth(p,yymsp[0].minor.yy36,&yymsp[-2].minor.yy0);}
2890 #line 2915 "pikchr.c"
2891 yymsp[-2].minor.yy36 = yylhsminor.yy36;
2892 break;
2893 case 88: /* objectname ::= THIS */
2894 #line 744 "pikchr.y"
2895 {yymsp[0].minor.yy36 = p->cur;}
2896 #line 2921 "pikchr.c"
2897 break;
2898 case 89: /* objectname ::= PLACENAME */
2899 #line 745 "pikchr.y"
2900 {yylhsminor.yy36 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2901 #line 2926 "pikchr.c"
2902 yymsp[0].minor.yy36 = yylhsminor.yy36;
2903 break;
2904 case 90: /* objectname ::= objectname DOT_U PLACENAME */
2905 #line 747 "pikchr.y"
2906 {yylhsminor.yy36 = pik_find_byname(p,yymsp[-2].minor.yy36,&yymsp[0].minor.yy0);}
2907 #line 2932 "pikchr.c"
2908 yymsp[-2].minor.yy36 = yylhsminor.yy36;
2909 break;
2910 case 91: /* nth ::= NTH CLASSNAME */
2911 #line 749 "pikchr.y"
2912 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2913 #line 2938 "pikchr.c"
2914 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2915 break;
2916 case 92: /* nth ::= NTH LAST CLASSNAME */
2917 #line 750 "pikchr.y"
2918 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2919 #line 2944 "pikchr.c"
2920 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2921 break;
2922 case 93: /* nth ::= LAST CLASSNAME */
2923 #line 751 "pikchr.y"
2924 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2925 #line 2950 "pikchr.c"
2926 break;
2927 case 94: /* nth ::= LAST */
2928 #line 752 "pikchr.y"
2929 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2930 #line 2955 "pikchr.c"
2931 yymsp[0].minor.yy0 = yylhsminor.yy0;
2932 break;
2933 case 95: /* nth ::= NTH LB RB */
2934 #line 753 "pikchr.y"
2935 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2936 #line 2961 "pikchr.c"
2937 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2938 break;
2939 case 96: /* nth ::= NTH LAST LB RB */
2940 #line 754 "pikchr.y"
2941 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2942 #line 2967 "pikchr.c"
2943 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2944 break;
2945 case 97: /* nth ::= LAST LB RB */
2946 #line 755 "pikchr.y"
2947 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2948 #line 2973 "pikchr.c"
2949 break;
2950 case 98: /* expr ::= expr PLUS expr */
2951 #line 757 "pikchr.y"
2952 {yylhsminor.yy153=yymsp[-2].minor.yy153+yymsp[0].minor.yy153;}
2953 #line 2978 "pikchr.c"
2954 yymsp[-2].minor.yy153 = yylhsminor.yy153;
2955 break;
2956 case 99: /* expr ::= expr MINUS expr */
2957 #line 758 "pikchr.y"
2958 {yylhsminor.yy153=yymsp[-2].minor.yy153-yymsp[0].minor.yy153;}
2959 #line 2984 "pikchr.c"
2960 yymsp[-2].minor.yy153 = yylhsminor.yy153;
2961 break;
2962 case 100: /* expr ::= expr STAR expr */
2963 #line 759 "pikchr.y"
2964 {yylhsminor.yy153=yymsp[-2].minor.yy153*yymsp[0].minor.yy153;}
2965 #line 2990 "pikchr.c"
2966 yymsp[-2].minor.yy153 = yylhsminor.yy153;
2967 break;
2968 case 101: /* expr ::= expr SLASH expr */
2969 #line 760 "pikchr.y"
2970 {
2971 if( yymsp[0].minor.yy153==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy153 = 0.0; }
2972 else{ yylhsminor.yy153 = yymsp[-2].minor.yy153/yymsp[0].minor.yy153; }
2973 }
2974 #line 2999 "pikchr.c"
2975 yymsp[-2].minor.yy153 = yylhsminor.yy153;
2976 break;
2977 case 102: /* expr ::= MINUS expr */
2978 #line 764 "pikchr.y"
2979 {yymsp[-1].minor.yy153=-yymsp[0].minor.yy153;}
2980 #line 3005 "pikchr.c"
2981 break;
2982 case 103: /* expr ::= PLUS expr */
2983 #line 765 "pikchr.y"
2984 {yymsp[-1].minor.yy153=yymsp[0].minor.yy153;}
2985 #line 3010 "pikchr.c"
2986 break;
2987 case 104: /* expr ::= LP expr RP */
2988 #line 766 "pikchr.y"
2989 {yymsp[-2].minor.yy153=yymsp[-1].minor.yy153;}
2990 #line 3015 "pikchr.c"
2991 break;
2992 case 105: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2993 #line 767 "pikchr.y"
2994 {yymsp[-2].minor.yy153=pik_get_var(p,&yymsp[-1].minor.yy0);}
2995 #line 3020 "pikchr.c"
2996 break;
2997 case 106: /* expr ::= NUMBER */
2998 #line 768 "pikchr.y"
2999 {yylhsminor.yy153=pik_atof(&yymsp[0].minor.yy0);}
3000 #line 3025 "pikchr.c"
3001 yymsp[0].minor.yy153 = yylhsminor.yy153;
3002 break;
3003 case 107: /* expr ::= ID */
3004 #line 769 "pikchr.y"
3005 {yylhsminor.yy153=pik_get_var(p,&yymsp[0].minor.yy0);}
3006 #line 3031 "pikchr.c"
3007 yymsp[0].minor.yy153 = yylhsminor.yy153;
3008 break;
3009 case 108: /* expr ::= FUNC1 LP expr RP */
3010 #line 770 "pikchr.y"
3011 {yylhsminor.yy153 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy153,0.0);}
3012 #line 3037 "pikchr.c"
3013 yymsp[-3].minor.yy153 = yylhsminor.yy153;
3014 break;
3015 case 109: /* expr ::= FUNC2 LP expr COMMA expr RP */
3016 #line 771 "pikchr.y"
3017 {yylhsminor.yy153 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy153,yymsp[-1].minor.yy153);}
3018 #line 3043 "pikchr.c"
3019 yymsp[-5].minor.yy153 = yylhsminor.yy153;
3020 break;
3021 case 110: /* expr ::= DIST LP position COMMA position RP */
3022 #line 772 "pikchr.y"
3023 {yymsp[-5].minor.yy153 = pik_dist(&yymsp[-3].minor.yy79,&yymsp[-1].minor.yy79);}
3024 #line 3049 "pikchr.c"
3025 break;
3026 case 111: /* expr ::= place2 DOT_XY X */
3027 #line 773 "pikchr.y"
3028 {yylhsminor.yy153 = yymsp[-2].minor.yy79.x;}
3029 #line 3054 "pikchr.c"
3030 yymsp[-2].minor.yy153 = yylhsminor.yy153;
3031 break;
3032 case 112: /* expr ::= place2 DOT_XY Y */
3033 #line 774 "pikchr.y"
3034 {yylhsminor.yy153 = yymsp[-2].minor.yy79.y;}
3035 #line 3060 "pikchr.c"
3036 yymsp[-2].minor.yy153 = yylhsminor.yy153;
3037 break;
3038 case 113: /* expr ::= object DOT_L numproperty */
3039 case 114: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==114);
3040 case 115: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==115);
3041 #line 775 "pikchr.y"
3042 {yylhsminor.yy153=pik_property_of(yymsp[-2].minor.yy36,&yymsp[0].minor.yy0);}
3043 #line 3068 "pikchr.c"
3044 yymsp[-2].minor.yy153 = yylhsminor.yy153;
3045 break;
3046 default:
3047 /* (116) lvalue ::= ID */ yytestcase(yyruleno==116);
3048 /* (117) lvalue ::= FILL */ yytestcase(yyruleno==117);
@@ -3131,19 +3141,19 @@
3141 ){
3142 pik_parserARG_FETCH
3143 pik_parserCTX_FETCH
3144 #define TOKEN yyminor
3145 /************ Begin %syntax_error code ****************************************/
3146 #line 535 "pikchr.y"
3147
3148 if( TOKEN.z && TOKEN.z[0] ){
3149 pik_error(p, &TOKEN, "syntax error");
3150 }else{
3151 pik_error(p, 0, "syntax error");
3152 }
3153 UNUSED_PARAMETER(yymajor);
3154 #line 3179 "pikchr.c"
3155 /************ End %syntax_error code ******************************************/
3156 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
3157 pik_parserCTX_STORE
3158 }
3159
@@ -3372,11 +3382,11 @@
3382 #else
3383 (void)iToken;
3384 return 0;
3385 #endif
3386 }
3387 #line 780 "pikchr.y"
3388
3389
3390
3391 /* Chart of the 148 official CSS color names with their
3392 ** corresponding RGB values thru Color Module Level 4:
@@ -6645,11 +6655,11 @@
6655 /* Compute one of the built-in functions
6656 */
6657 static PNum pik_func(Pik *p, PToken *pFunc, PNum x, PNum y){
6658 PNum v = 0.0;
6659 switch( pFunc->eCode ){
6660 case FN_ABS: v = x<0.0 ? -x : x; break;
6661 case FN_COS: v = cos(x); break;
6662 case FN_INT: v = rint(x); break;
6663 case FN_SIN: v = sin(x); break;
6664 case FN_SQRT:
6665 if( x<0.0 ){
@@ -7744,10 +7754,14 @@
7754 printf("******** Token %s (%d): \"%.*s\" **************\n",
7755 yyTokenName[token.eType], token.eType,
7756 (int)(isspace(token.z[0]) ? 0 : sz), token.z);
7757 #endif
7758 token.n = (unsigned short)(sz & 0xffff);
7759 if( p->nToken++ > PIKCHR_TOKEN_LIMIT ){
7760 pik_error(p, &token, "script is too complex");
7761 break;
7762 }
7763 pik_parser(pParser, token.eType, token);
7764 }
7765 }
7766 }
7767
@@ -8081,6 +8095,6 @@
8095
8096
8097 #endif /* PIKCHR_TCL */
8098
8099
8100 #line 8125 "pikchr.c"
8101
+662 -117
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -39,14 +39,14 @@
3939
** Optionally #include a user-defined header, whereby compilation options
4040
** may be set prior to where they take effect, but after platform setup.
4141
** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include
4242
** file. Note that this macro has a like effect on sqlite3.c compilation.
4343
*/
44
+# define SHELL_STRINGIFY_(f) #f
45
+# define SHELL_STRINGIFY(f) SHELL_STRINGIFY_(f)
4446
#ifdef SQLITE_CUSTOM_INCLUDE
45
-# define INC_STRINGIFY_(f) #f
46
-# define INC_STRINGIFY(f) INC_STRINGIFY_(f)
47
-# include INC_STRINGIFY(SQLITE_CUSTOM_INCLUDE)
47
+# include SHELL_STRINGIFY(SQLITE_CUSTOM_INCLUDE)
4848
#endif
4949
5050
/*
5151
** Determine if we are dealing with WinRT, which provides only a subset of
5252
** the full Win32 API.
@@ -1401,11 +1401,11 @@
14011401
** sha3_query(Y,SIZE)
14021402
**
14031403
** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
14041404
** X is NULL.
14051405
**
1406
-** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
1406
+** The sha3_query(Y) function evaluates all queries in the SQL statements of Y
14071407
** and returns a hash of their results.
14081408
**
14091409
** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
14101410
** is used. If SIZE is included it must be one of the integers 224, 256,
14111411
** 384, or 512, to determine SHA3 hash variant that is computed.
@@ -5449,11 +5449,11 @@
54495449
unsigned int i;
54505450
int rc = SQLITE_OK;
54515451
SQLITE_EXTENSION_INIT2(pApi);
54525452
(void)pzErrMsg; /* Unused parameter */
54535453
for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
5454
- rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
5454
+ rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
54555455
SQLITE_UTF8|SQLITE_INNOCUOUS,
54565456
(void*)&aFunc[i].iAux,
54575457
aFunc[i].xFunc, 0, 0);
54585458
}
54595459
return rc;
@@ -7962,13 +7962,18 @@
79627962
zFile = pTab->zFile;
79637963
}else if( idxNum==0 ){
79647964
zipfileCursorErr(pCsr, "zipfile() function requires an argument");
79657965
return SQLITE_ERROR;
79667966
}else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
7967
+ static const u8 aEmptyBlob = 0;
79677968
const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
79687969
int nBlob = sqlite3_value_bytes(argv[0]);
79697970
assert( pTab->pFirstEntry==0 );
7971
+ if( aBlob==0 ){
7972
+ aBlob = &aEmptyBlob;
7973
+ nBlob = 0;
7974
+ }
79707975
rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
79717976
pCsr->pFreeEntry = pTab->pFirstEntry;
79727977
pTab->pFirstEntry = pTab->pLastEntry = 0;
79737978
if( rc!=SQLITE_OK ) return rc;
79747979
bInMemory = 1;
@@ -8870,10 +8875,14 @@
88708875
0, /* xSync */
88718876
zipfileCommit, /* xCommit */
88728877
zipfileRollback, /* xRollback */
88738878
zipfileFindFunction, /* xFindMethod */
88748879
0, /* xRename */
8880
+ 0, /* xSavepoint */
8881
+ 0, /* xRelease */
8882
+ 0, /* xRollback */
8883
+ 0 /* xShadowName */
88758884
};
88768885
88778886
int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
88788887
if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
88798888
if( rc==SQLITE_OK ){
@@ -12143,10 +12152,19 @@
1214312152
EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
1214412153
EQPGraphRow *pLast; /* Last element of the pRow list */
1214512154
char zPrefix[100]; /* Graph prefix */
1214612155
};
1214712156
12157
+/* Parameters affecting columnar mode result display (defaulting together) */
12158
+typedef struct ColModeOpts {
12159
+ int iWrap; /* In columnar modes, wrap lines reaching this limit */
12160
+ u8 bQuote; /* Quote results for .mode box and table */
12161
+ u8 bWordWrap; /* In columnar modes, wrap at word boundaries */
12162
+} ColModeOpts;
12163
+#define ColModeOpts_default { 60, 0, 0 }
12164
+#define ColModeOpts_default_qbox { 60, 1, 0 }
12165
+
1214812166
/*
1214912167
** State information about the database connection is contained in an
1215012168
** instance of the following structure.
1215112169
*/
1215212170
typedef struct ShellState ShellState;
@@ -12161,10 +12179,11 @@
1216112179
u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
1216212180
u8 nEqpLevel; /* Depth of the EQP output graph */
1216312181
u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
1216412182
u8 bSafeMode; /* True to prohibit unsafe operations */
1216512183
u8 bSafeModePersist; /* The long-term value of bSafeMode */
12184
+ ColModeOpts cmOpts; /* Option values affecting columnar mode output */
1216612185
unsigned statsOn; /* True to display memory stats before each finalize */
1216712186
unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */
1216812187
int inputNesting; /* Track nesting level of .read and other redirects */
1216912188
int outCount; /* Revert to stdout when reaching zero */
1217012189
int cnt; /* Number of records displayed so far */
@@ -13378,11 +13397,16 @@
1337813397
if( ur==0x7ff0000000000000LL ){
1337913398
raw_printf(p->out, "1e999");
1338013399
}else if( ur==0xfff0000000000000LL ){
1338113400
raw_printf(p->out, "-1e999");
1338213401
}else{
13383
- sqlite3_snprintf(50,z,"%!.20g", r);
13402
+ sqlite3_int64 ir = (sqlite3_int64)r;
13403
+ if( r==(double)ir ){
13404
+ sqlite3_snprintf(50,z,"%lld.0", ir);
13405
+ }else{
13406
+ sqlite3_snprintf(50,z,"%!.20g", r);
13407
+ }
1338413408
raw_printf(p->out, "%s", z);
1338513409
}
1338613410
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1338713411
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1338813412
int nBlob = sqlite3_column_bytes(p->pStmt, i);
@@ -13704,21 +13728,28 @@
1370413728
/*
1370513729
** Allocate space and save off string indicating current error.
1370613730
*/
1370713731
static char *save_err_msg(
1370813732
sqlite3 *db, /* Database to query */
13709
- const char *zWhen, /* Qualifier (format) wrapper */
13733
+ const char *zPhase, /* When the error occcurs */
1371013734
int rc, /* Error code returned from API */
1371113735
const char *zSql /* SQL string, or NULL */
1371213736
){
1371313737
char *zErr;
1371413738
char *zContext;
13715
- if( zWhen==0 ) zWhen = "%s (%d)%s";
13739
+ sqlite3_str *pStr = sqlite3_str_new(0);
13740
+ sqlite3_str_appendf(pStr, "%s, %s", zPhase, sqlite3_errmsg(db));
13741
+ if( rc>1 ){
13742
+ sqlite3_str_appendf(pStr, " (%d)", rc);
13743
+ }
1371613744
zContext = shell_error_context(zSql, db);
13717
- zErr = sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc, zContext);
13745
+ if( zContext ){
13746
+ sqlite3_str_appendall(pStr, zContext);
13747
+ sqlite3_free(zContext);
13748
+ }
13749
+ zErr = sqlite3_str_finish(pStr);
1371813750
shell_check_oom(zErr);
13719
- sqlite3_free(zContext);
1372013751
return zErr;
1372113752
}
1372213753
1372313754
#ifdef __linux__
1372413755
/*
@@ -14241,11 +14272,138 @@
1424114272
utf8_printf(p->out, "%s", zSep3);
1424214273
}
1424314274
fputs("\n", p->out);
1424414275
}
1424514276
14277
+/*
14278
+** z[] is a line of text that is to be displayed the .mode box or table or
14279
+** similar tabular formats. z[] might contain control characters such
14280
+** as \n, \t, \f, or \r.
14281
+**
14282
+** Compute characters to display on the first line of z[]. Stop at the
14283
+** first \r, \n, or \f. Expand \t into spaces. Return a copy (obtained
14284
+** from malloc()) of that first line, which caller should free sometime.
14285
+** Write anything to display on the next line into *pzTail. If this is
14286
+** the last line, write a NULL into *pzTail. (*pzTail is not allocated.)
14287
+*/
14288
+static char *translateForDisplayAndDup(
14289
+ const unsigned char *z, /* Input text to be transformed */
14290
+ const unsigned char **pzTail, /* OUT: Tail of the input for next line */
14291
+ int mxWidth, /* Max width. 0 means no limit */
14292
+ u8 bWordWrap /* If true, avoid breaking mid-word */
14293
+){
14294
+ int i; /* Input bytes consumed */
14295
+ int j; /* Output bytes generated */
14296
+ int k; /* Input bytes to be displayed */
14297
+ int n; /* Output column number */
14298
+ unsigned char *zOut; /* Output text */
1424614299
14300
+ if( z==0 ){
14301
+ *pzTail = 0;
14302
+ return 0;
14303
+ }
14304
+ if( mxWidth<0 ) mxWidth = -mxWidth;
14305
+ if( mxWidth==0 ) mxWidth = 1000000;
14306
+ i = j = n = 0;
14307
+ while( n<mxWidth ){
14308
+ if( z[i]>=' ' ){
14309
+ n++;
14310
+ do{ i++; j++; }while( (z[i]&0xc0)==0x80 );
14311
+ continue;
14312
+ }
14313
+ if( z[i]=='\t' ){
14314
+ do{
14315
+ n++;
14316
+ j++;
14317
+ }while( (n&7)!=0 && n<mxWidth );
14318
+ i++;
14319
+ continue;
14320
+ }
14321
+ break;
14322
+ }
14323
+ if( n>=mxWidth && bWordWrap ){
14324
+ /* Perhaps try to back up to a better place to break the line */
14325
+ for(k=i; k>i/2; k--){
14326
+ if( isspace(z[k-1]) ) break;
14327
+ }
14328
+ if( k<=i/2 ){
14329
+ for(k=i; k>i/2; k--){
14330
+ if( isalnum(z[k-1])!=isalnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
14331
+ }
14332
+ }
14333
+ if( k<=i/2 ){
14334
+ k = i;
14335
+ }else{
14336
+ i = k;
14337
+ while( z[i]==' ' ) i++;
14338
+ }
14339
+ }else{
14340
+ k = i;
14341
+ }
14342
+ if( n>=mxWidth && z[i]>=' ' ){
14343
+ *pzTail = &z[i];
14344
+ }else if( z[i]=='\r' && z[i+1]=='\n' ){
14345
+ *pzTail = z[i+2] ? &z[i+2] : 0;
14346
+ }else if( z[i]==0 || z[i+1]==0 ){
14347
+ *pzTail = 0;
14348
+ }else{
14349
+ *pzTail = &z[i+1];
14350
+ }
14351
+ zOut = malloc( j+1 );
14352
+ shell_check_oom(zOut);
14353
+ i = j = n = 0;
14354
+ while( i<k ){
14355
+ if( z[i]>=' ' ){
14356
+ n++;
14357
+ do{ zOut[j++] = z[i++]; }while( (z[i]&0xc0)==0x80 );
14358
+ continue;
14359
+ }
14360
+ if( z[i]=='\t' ){
14361
+ do{
14362
+ n++;
14363
+ zOut[j++] = ' ';
14364
+ }while( (n&7)!=0 && n<mxWidth );
14365
+ i++;
14366
+ continue;
14367
+ }
14368
+ break;
14369
+ }
14370
+ zOut[j] = 0;
14371
+ return (char*)zOut;
14372
+}
14373
+
14374
+/* Extract the value of the i-th current column for pStmt as an SQL literal
14375
+** value. Memory is obtained from sqlite3_malloc64() and must be freed by
14376
+** the caller.
14377
+*/
14378
+static char *quoted_column(sqlite3_stmt *pStmt, int i){
14379
+ switch( sqlite3_column_type(pStmt, i) ){
14380
+ case SQLITE_NULL: {
14381
+ return sqlite3_mprintf("NULL");
14382
+ }
14383
+ case SQLITE_INTEGER:
14384
+ case SQLITE_FLOAT: {
14385
+ return sqlite3_mprintf("%s",sqlite3_column_text(pStmt,i));
14386
+ }
14387
+ case SQLITE_TEXT: {
14388
+ return sqlite3_mprintf("%Q",sqlite3_column_text(pStmt,i));
14389
+ }
14390
+ case SQLITE_BLOB: {
14391
+ int j;
14392
+ sqlite3_str *pStr = sqlite3_str_new(0);
14393
+ const unsigned char *a = sqlite3_column_blob(pStmt,i);
14394
+ int n = sqlite3_column_bytes(pStmt,i);
14395
+ sqlite3_str_append(pStr, "x'", 2);
14396
+ for(j=0; j<n; j++){
14397
+ sqlite3_str_appendf(pStr, "%02x", a[j]);
14398
+ }
14399
+ sqlite3_str_append(pStr, "'", 1);
14400
+ return sqlite3_str_finish(pStr);
14401
+ }
14402
+ }
14403
+ return 0; /* Not reached */
14404
+}
1424714405
1424814406
/*
1424914407
** Run a prepared statement and output the result in one of the
1425014408
** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
1425114409
** or MODE_Box.
@@ -14261,39 +14419,41 @@
1426114419
){
1426214420
sqlite3_int64 nRow = 0;
1426314421
int nColumn = 0;
1426414422
char **azData = 0;
1426514423
sqlite3_int64 nAlloc = 0;
14424
+ char *abRowDiv = 0;
14425
+ const unsigned char *uz;
1426614426
const char *z;
14427
+ char **azQuoted = 0;
1426714428
int rc;
1426814429
sqlite3_int64 i, nData;
1426914430
int j, nTotal, w, n;
1427014431
const char *colSep = 0;
1427114432
const char *rowSep = 0;
14433
+ const unsigned char **azNextLine = 0;
14434
+ int bNextLine = 0;
14435
+ int bMultiLineRowExists = 0;
14436
+ int bw = p->cmOpts.bWordWrap;
1427214437
1427314438
rc = sqlite3_step(pStmt);
1427414439
if( rc!=SQLITE_ROW ) return;
1427514440
nColumn = sqlite3_column_count(pStmt);
1427614441
nAlloc = nColumn*4;
1427714442
if( nAlloc<=0 ) nAlloc = 1;
1427814443
azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
1427914444
shell_check_oom(azData);
14280
- for(i=0; i<nColumn; i++){
14281
- azData[i] = strdup(sqlite3_column_name(pStmt,i));
14282
- }
14283
- do{
14284
- if( (nRow+2)*nColumn >= nAlloc ){
14285
- nAlloc *= 2;
14286
- azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
14287
- shell_check_oom(azData);
14288
- }
14289
- nRow++;
14290
- for(i=0; i<nColumn; i++){
14291
- z = (const char*)sqlite3_column_text(pStmt,i);
14292
- azData[nRow*nColumn + i] = z ? strdup(z) : 0;
14293
- }
14294
- }while( sqlite3_step(pStmt)==SQLITE_ROW );
14445
+ azNextLine = sqlite3_malloc64( nColumn*sizeof(char*) );
14446
+ shell_check_oom((void*)azNextLine);
14447
+ memset((void*)azNextLine, 0, nColumn*sizeof(char*) );
14448
+ if( p->cmOpts.bQuote ){
14449
+ azQuoted = sqlite3_malloc64( nColumn*sizeof(char*) );
14450
+ shell_check_oom(azQuoted);
14451
+ memset(azQuoted, 0, nColumn*sizeof(char*) );
14452
+ }
14453
+ abRowDiv = sqlite3_malloc64( nAlloc/nColumn );
14454
+ shell_check_oom(abRowDiv);
1429514455
if( nColumn>p->nWidth ){
1429614456
p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int));
1429714457
shell_check_oom(p->colWidth);
1429814458
for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
1429914459
p->nWidth = nColumn;
@@ -14303,10 +14463,56 @@
1430314463
for(i=0; i<nColumn; i++){
1430414464
w = p->colWidth[i];
1430514465
if( w<0 ) w = -w;
1430614466
p->actualWidth[i] = w;
1430714467
}
14468
+ for(i=0; i<nColumn; i++){
14469
+ const unsigned char *zNotUsed;
14470
+ int wx = p->colWidth[i];
14471
+ if( wx==0 ){
14472
+ wx = p->cmOpts.iWrap;
14473
+ }
14474
+ if( wx<0 ) wx = -wx;
14475
+ uz = (const unsigned char*)sqlite3_column_name(pStmt,i);
14476
+ azData[i] = translateForDisplayAndDup(uz, &zNotUsed, wx, bw);
14477
+ }
14478
+ do{
14479
+ int useNextLine = bNextLine;
14480
+ bNextLine = 0;
14481
+ if( (nRow+2)*nColumn >= nAlloc ){
14482
+ nAlloc *= 2;
14483
+ azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
14484
+ shell_check_oom(azData);
14485
+ abRowDiv = sqlite3_realloc64(abRowDiv, nAlloc/nColumn);
14486
+ shell_check_oom(abRowDiv);
14487
+ }
14488
+ abRowDiv[nRow] = 1;
14489
+ nRow++;
14490
+ for(i=0; i<nColumn; i++){
14491
+ int wx = p->colWidth[i];
14492
+ if( wx==0 ){
14493
+ wx = p->cmOpts.iWrap;
14494
+ }
14495
+ if( wx<0 ) wx = -wx;
14496
+ if( useNextLine ){
14497
+ uz = azNextLine[i];
14498
+ }else if( p->cmOpts.bQuote ){
14499
+ sqlite3_free(azQuoted[i]);
14500
+ azQuoted[i] = quoted_column(pStmt,i);
14501
+ uz = (const unsigned char*)azQuoted[i];
14502
+ }else{
14503
+ uz = (const unsigned char*)sqlite3_column_text(pStmt,i);
14504
+ }
14505
+ azData[nRow*nColumn + i]
14506
+ = translateForDisplayAndDup(uz, &azNextLine[i], wx, bw);
14507
+ if( azNextLine[i] ){
14508
+ bNextLine = 1;
14509
+ abRowDiv[nRow-1] = 0;
14510
+ bMultiLineRowExists = 1;
14511
+ }
14512
+ }
14513
+ }while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW );
1430814514
nTotal = nColumn*(nRow+1);
1430914515
for(i=0; i<nTotal; i++){
1431014516
z = azData[i];
1431114517
if( z==0 ) z = p->nullValue;
1431214518
n = strlenChar(z);
@@ -14385,10 +14591,19 @@
1438514591
w = p->actualWidth[j];
1438614592
if( p->colWidth[j]<0 ) w = -w;
1438714593
utf8_width_print(p->out, w, z);
1438814594
if( j==nColumn-1 ){
1438914595
utf8_printf(p->out, "%s", rowSep);
14596
+ if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1<nTotal ){
14597
+ if( p->cMode==MODE_Table ){
14598
+ print_row_separator(p, nColumn, "+");
14599
+ }else if( p->cMode==MODE_Box ){
14600
+ print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
14601
+ }else if( p->cMode==MODE_Column ){
14602
+ raw_printf(p->out, "\n");
14603
+ }
14604
+ }
1439014605
j = -1;
1439114606
if( seenInterrupt ) goto columnar_end;
1439214607
}else{
1439314608
utf8_printf(p->out, "%s", colSep);
1439414609
}
@@ -14403,10 +14618,16 @@
1440314618
utf8_printf(p->out, "Interrupt\n");
1440414619
}
1440514620
nData = (nRow+1)*nColumn;
1440614621
for(i=0; i<nData; i++) free(azData[i]);
1440714622
sqlite3_free(azData);
14623
+ sqlite3_free((void*)azNextLine);
14624
+ sqlite3_free(abRowDiv);
14625
+ if( azQuoted ){
14626
+ for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]);
14627
+ sqlite3_free(azQuoted);
14628
+ }
1440814629
}
1440914630
1441014631
/*
1441114632
** Run a prepared statement
1441214633
*/
@@ -14655,11 +14876,11 @@
1465514876
while( zSql[0] && (SQLITE_OK == rc) ){
1465614877
static const char *zStmtSql;
1465714878
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1465814879
if( SQLITE_OK != rc ){
1465914880
if( pzErrMsg ){
14660
- *pzErrMsg = save_err_msg(db, "in prepare, %s (%d)%s", rc, zSql);
14881
+ *pzErrMsg = save_err_msg(db, "in prepare", rc, zSql);
1466114882
}
1466214883
}else{
1466314884
if( !pStmt ){
1466414885
/* this happens for a comment or white-space */
1466514886
zSql = zLeftover;
@@ -14771,11 +14992,11 @@
1477114992
if( rc!=SQLITE_NOMEM ) rc = rc2;
1477214993
if( rc==SQLITE_OK ){
1477314994
zSql = zLeftover;
1477414995
while( IsSpace(zSql[0]) ) zSql++;
1477514996
}else if( pzErrMsg ){
14776
- *pzErrMsg = save_err_msg(db, "stepping, %s (%d)", rc, 0);
14997
+ *pzErrMsg = save_err_msg(db, "stepping", rc, 0);
1477714998
}
1477814999
1477915000
/* clear saved stmt handle */
1478015001
if( pArg ){
1478115002
pArg->pStmt = NULL;
@@ -15110,10 +15331,11 @@
1511015331
#endif
1511115332
#ifndef SQLITE_OMIT_AUTHORIZATION
1511215333
".auth ON|OFF Show authorizer callbacks",
1511315334
#endif
1511415335
".backup ?DB? FILE Backup DB (default \"main\") to FILE",
15336
+ " Options:",
1511515337
" --append Use the appendvfs",
1511615338
" --async Write to FILE without journal and fsync()",
1511715339
".bail on|off Stop after hitting an error. Default OFF",
1511815340
".binary on|off Turn binary output on or off. Default OFF",
1511915341
".cd DIRECTORY Change the working directory to DIRECTORY",
@@ -15180,27 +15402,35 @@
1518015402
" fkey-indexes Find missing foreign key indexes",
1518115403
#ifndef SQLITE_OMIT_LOAD_EXTENSION
1518215404
".load FILE ?ENTRY? Load an extension library",
1518315405
#endif
1518415406
".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
15185
- ".mode MODE ?TABLE? Set output mode",
15407
+ ".mode MODE ?OPTIONS? Set output mode",
1518615408
" MODE is one of:",
15187
- " ascii Columns/rows delimited by 0x1F and 0x1E",
15188
- " box Tables using unicode box-drawing characters",
15189
- " csv Comma-separated values",
15190
- " column Output in columns. (See .width)",
15191
- " html HTML <table> code",
15192
- " insert SQL insert statements for TABLE",
15193
- " json Results in a JSON array",
15194
- " line One value per line",
15195
- " list Values delimited by \"|\"",
15196
- " markdown Markdown table format",
15197
- " quote Escape answers as for SQL",
15198
- " table ASCII-art table",
15199
- " tabs Tab-separated values",
15200
- " tcl TCL list elements",
15201
- ".nonce STRING Disable safe mode for one command if the nonce matches",
15409
+ " ascii Columns/rows delimited by 0x1F and 0x1E",
15410
+ " box Tables using unicode box-drawing characters",
15411
+ " csv Comma-separated values",
15412
+ " column Output in columns. (See .width)",
15413
+ " html HTML <table> code",
15414
+ " insert SQL insert statements for TABLE",
15415
+ " json Results in a JSON array",
15416
+ " line One value per line",
15417
+ " list Values delimited by \"|\"",
15418
+ " markdown Markdown table format",
15419
+ " qbox Shorthand for \"box --width 60 --quote\"",
15420
+ " quote Escape answers as for SQL",
15421
+ " table ASCII-art table",
15422
+ " tabs Tab-separated values",
15423
+ " tcl TCL list elements",
15424
+ " OPTIONS: (for columnar modes or insert mode):",
15425
+ " --wrap N Wrap output lines to no longer than N characters",
15426
+ " --wordwrap B Wrap or not at word boundaries per B (on/off)",
15427
+ " --ww Shorthand for \"--wordwrap 1\"",
15428
+ " --quote Quote output text as SQL literals",
15429
+ " --noquote Do not quote output text",
15430
+ " TABLE The name of SQL table used for \"insert\" mode",
15431
+ ".nonce STRING Suspend safe mode for one command if nonce matches",
1520215432
".nullvalue STRING Use STRING in place of NULL values",
1520315433
".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
1520415434
" If FILE begins with '|' then open as a pipe",
1520515435
" --bom Put a UTF8 byte-order mark at the beginning",
1520615436
" -e Send output to the system text editor",
@@ -15249,11 +15479,11 @@
1524915479
" --lost-and-found TABLE Alternative name for the lost-and-found table",
1525015480
" --no-rowids Do not attempt to recover rowid values",
1525115481
" that are not also INTEGER PRIMARY KEYs",
1525215482
#endif
1525315483
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
15254
- ".save FILE Write in-memory database into FILE",
15484
+ ".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)",
1525515485
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
1525615486
".schema ?PATTERN? Show the CREATE statements matching PATTERN",
1525715487
" Options:",
1525815488
" --indent Try to pretty-print the schema",
1525915489
" --nosys Omit objects whose names start with \"sqlite_\"",
@@ -15853,12 +16083,14 @@
1585316083
sqlite3_series_init(p->db, 0, 0);
1585416084
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
1585516085
sqlite3_dbdata_init(p->db, 0, 0);
1585616086
#endif
1585716087
#ifdef SQLITE_HAVE_ZLIB
15858
- sqlite3_zipfile_init(p->db, 0, 0);
15859
- sqlite3_sqlar_init(p->db, 0, 0);
16088
+ if( !p->bSafeModePersist ){
16089
+ sqlite3_zipfile_init(p->db, 0, 0);
16090
+ sqlite3_sqlar_init(p->db, 0, 0);
16091
+ }
1586016092
#endif
1586116093
sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
1586216094
shellAddSchemaName, 0, 0);
1586316095
sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
1586416096
shellModuleSchema, 0, 0);
@@ -16613,14 +16845,14 @@
1661316845
}
1661416846
1661516847
/*
1661616848
** Run an SQL command and return the single integer result.
1661716849
*/
16618
-static int db_int(ShellState *p, const char *zSql){
16850
+static int db_int(sqlite3 *db, const char *zSql){
1661916851
sqlite3_stmt *pStmt;
1662016852
int res = 0;
16621
- sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
16853
+ sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
1662216854
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
1662316855
res = sqlite3_column_int(pStmt,0);
1662416856
}
1662516857
sqlite3_finalize(pStmt);
1662616858
return res;
@@ -16721,11 +16953,11 @@
1672116953
}else{
1672216954
zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
1672316955
}
1672416956
for(i=0; i<ArraySize(aQuery); i++){
1672516957
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
16726
- int val = db_int(p, zSql);
16958
+ int val = db_int(p->db, zSql);
1672716959
sqlite3_free(zSql);
1672816960
utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
1672916961
}
1673016962
sqlite3_free(zSchemaTab);
1673116963
sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
@@ -18084,10 +18316,11 @@
1808418316
*pRc = SQLITE_NOMEM;
1808518317
}
1808618318
}
1808718319
return z;
1808818320
}
18321
+
1808918322
1809018323
/*
1809118324
** When running the ".recover" command, each output table, and the special
1809218325
** orphaned row table if it is required, is represented by an instance
1809318326
** of the following struct.
@@ -18681,10 +18914,225 @@
1868118914
sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
1868218915
return rc;
1868318916
}
1868418917
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
1868518918
18919
+
18920
+/*
18921
+ * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it.
18922
+ * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE,
18923
+ * close db and set it to 0, and return the columns spec, to later
18924
+ * be sqlite3_free()'ed by the caller.
18925
+ * The return is 0 when either:
18926
+ * (a) The db was not initialized and zCol==0 (There are no columns.)
18927
+ * (b) zCol!=0 (Column was added, db initialized as needed.)
18928
+ * The 3rd argument, pRenamed, references an out parameter. If the
18929
+ * pointer is non-zero, its referent will be set to a summary of renames
18930
+ * done if renaming was necessary, or set to 0 if none was done. The out
18931
+ * string (if any) must be sqlite3_free()'ed by the caller.
18932
+ */
18933
+#ifdef SHELL_DEBUG
18934
+#define rc_err_oom_die(rc) \
18935
+ if( rc==SQLITE_NOMEM ) shell_check_oom(0); \
18936
+ else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \
18937
+ fprintf(stderr,"E:%d\n",rc), assert(0)
18938
+#else
18939
+static void rc_err_oom_die(int rc){
18940
+ if( rc==SQLITE_NOMEM ) shell_check_oom(0);
18941
+ assert(rc==SQLITE_OK||rc==SQLITE_DONE);
18942
+}
18943
+#endif
18944
+
18945
+#ifdef SHELL_COLFIX_DB /* If this is set, the DB can be in a file. */
18946
+static char zCOL_DB[] = SHELL_STRINGIFY(SHELL_COLFIX_DB);
18947
+#else /* Otherwise, memory is faster/better for the transient DB. */
18948
+static const char *zCOL_DB = ":memory:";
18949
+#endif
18950
+
18951
+/* Define character (as C string) to separate generated column ordinal
18952
+ * from protected part of incoming column names. This defaults to "_"
18953
+ * so that incoming column identifiers that did not need not be quoted
18954
+ * remain usable without being quoted. It must be one character.
18955
+ */
18956
+#ifndef SHELL_AUTOCOLUMN_SEP
18957
+# define AUTOCOLUMN_SEP "_"
18958
+#else
18959
+# define AUTOCOLUMN_SEP SHELL_STRINGIFY(SHELL_AUTOCOLUMN_SEP)
18960
+#endif
18961
+
18962
+static char *zAutoColumn(const char *zColNew, sqlite3 **pDb, char **pzRenamed){
18963
+ /* Queries and D{D,M}L used here */
18964
+ static const char * const zTabMake = "\
18965
+CREATE TABLE ColNames(\
18966
+ cpos INTEGER PRIMARY KEY,\
18967
+ name TEXT, nlen INT, chop INT, reps INT, suff TEXT);\
18968
+CREATE VIEW RepeatedNames AS \
18969
+SELECT DISTINCT t.name FROM ColNames t \
18970
+WHERE t.name COLLATE NOCASE IN (\
18971
+ SELECT o.name FROM ColNames o WHERE o.cpos<>t.cpos\
18972
+);\
18973
+";
18974
+ static const char * const zTabFill = "\
18975
+INSERT INTO ColNames(name,nlen,chop,reps,suff)\
18976
+ VALUES(iif(length(?1)>0,?1,'?'),max(length(?1),1),0,0,'')\
18977
+";
18978
+ static const char * const zHasDupes = "\
18979
+SELECT count(DISTINCT (substring(name,1,nlen-chop)||suff) COLLATE NOCASE)\
18980
+ <count(name) FROM ColNames\
18981
+";
18982
+#ifdef SHELL_COLUMN_RENAME_CLEAN
18983
+ static const char * const zDedoctor = "\
18984
+UPDATE ColNames SET chop=iif(\
18985
+ (substring(name,nlen,1) BETWEEN '0' AND '9')\
18986
+ AND (rtrim(name,'0123456790') glob '*"AUTOCOLUMN_SEP"'),\
18987
+ nlen-length(rtrim(name, '"AUTOCOLUMN_SEP"0123456789')),\
18988
+ 0\
18989
+)\
18990
+";
18991
+#endif
18992
+ static const char * const zSetReps = "\
18993
+UPDATE ColNames AS t SET reps=\
18994
+(SELECT count(*) FROM ColNames d \
18995
+ WHERE substring(t.name,1,t.nlen-t.chop)=substring(d.name,1,d.nlen-d.chop)\
18996
+ COLLATE NOCASE\
18997
+)\
18998
+";
18999
+#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19000
+ static const char * const zColDigits = "\
19001
+SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
19002
+";
19003
+#endif
19004
+ static const char * const zRenameRank =
19005
+#ifdef SHELL_COLUMN_RENAME_CLEAN
19006
+ "UPDATE ColNames AS t SET suff="
19007
+ "iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')"
19008
+#else /* ...RENAME_MINIMAL_ONE_PASS */
19009
+"WITH Lzn(nlz) AS (" /* Find minimum extraneous leading 0's for uniqueness */
19010
+" SELECT 0 AS nlz"
19011
+" UNION"
19012
+" SELECT nlz+1 AS nlz FROM Lzn"
19013
+" WHERE EXISTS("
19014
+" SELECT 1"
19015
+" FROM ColNames t, ColNames o"
19016
+" WHERE"
19017
+" iif(t.name IN (SELECT * FROM RepeatedNames),"
19018
+" printf('%s"AUTOCOLUMN_SEP"%s',"
19019
+" t.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,t.cpos),2)),"
19020
+" t.name"
19021
+" )"
19022
+" ="
19023
+" iif(o.name IN (SELECT * FROM RepeatedNames),"
19024
+" printf('%s"AUTOCOLUMN_SEP"%s',"
19025
+" o.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,o.cpos),2)),"
19026
+" o.name"
19027
+" )"
19028
+" COLLATE NOCASE"
19029
+" AND o.cpos<>t.cpos"
19030
+" GROUP BY t.cpos"
19031
+" )"
19032
+") UPDATE Colnames AS t SET"
19033
+" chop = 0," /* No chopping, never touch incoming names. */
19034
+" suff = iif(name IN (SELECT * FROM RepeatedNames),"
19035
+" printf('"AUTOCOLUMN_SEP"%s', substring("
19036
+" printf('%.*c%0.*d',(SELECT max(nlz) FROM Lzn)+1,'0',1,t.cpos),2)),"
19037
+" ''"
19038
+" )"
19039
+#endif
19040
+ ;
19041
+ static const char * const zCollectVar = "\
19042
+SELECT\
19043
+ '('||x'0a'\
19044
+ || group_concat(\
19045
+ cname||' TEXT',\
19046
+ ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
19047
+ ||')' AS ColsSpec \
19048
+FROM (\
19049
+ SELECT cpos, printf('\"%w\"',printf('%.*s%s', nlen-chop,name,suff)) AS cname \
19050
+ FROM ColNames ORDER BY cpos\
19051
+)";
19052
+ static const char * const zRenamesDone =
19053
+ "SELECT group_concat("
19054
+ " printf('\"%w\" to \"%w\"',name,printf('%.*s%s', nlen-chop, name, suff)),"
19055
+ " ','||x'0a')"
19056
+ "FROM ColNames WHERE suff<>'' OR chop!=0"
19057
+ ;
19058
+ int rc;
19059
+ sqlite3_stmt *pStmt = 0;
19060
+ assert(pDb!=0);
19061
+ if( zColNew ){
19062
+ /* Add initial or additional column. Init db if necessary. */
19063
+ if( *pDb==0 ){
19064
+ if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0;
19065
+#ifdef SHELL_COLFIX_DB
19066
+ if(*zCOL_DB!=':')
19067
+ sqlite3_exec(*pDb,"drop table if exists ColNames;"
19068
+ "drop view if exists RepeatedNames;",0,0,0);
19069
+#endif
19070
+ rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0);
19071
+ rc_err_oom_die(rc);
19072
+ }
19073
+ assert(*pDb!=0);
19074
+ rc = sqlite3_prepare_v2(*pDb, zTabFill, -1, &pStmt, 0);
19075
+ rc_err_oom_die(rc);
19076
+ rc = sqlite3_bind_text(pStmt, 1, zColNew, -1, 0);
19077
+ rc_err_oom_die(rc);
19078
+ rc = sqlite3_step(pStmt);
19079
+ rc_err_oom_die(rc);
19080
+ sqlite3_finalize(pStmt);
19081
+ return 0;
19082
+ }else if( *pDb==0 ){
19083
+ return 0;
19084
+ }else{
19085
+ /* Formulate the columns spec, close the DB, zero *pDb. */
19086
+ char *zColsSpec = 0;
19087
+ int hasDupes = db_int(*pDb, zHasDupes);
19088
+#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19089
+ int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
19090
+#else
19091
+# define nDigits 2
19092
+#endif
19093
+ if( hasDupes ){
19094
+#ifdef SHELL_COLUMN_RENAME_CLEAN
19095
+ rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
19096
+ rc_err_oom_die(rc);
19097
+#endif
19098
+ rc = sqlite3_exec(*pDb, zSetReps, 0, 0, 0);
19099
+ rc_err_oom_die(rc);
19100
+ rc = sqlite3_prepare_v2(*pDb, zRenameRank, -1, &pStmt, 0);
19101
+ rc_err_oom_die(rc);
19102
+ sqlite3_bind_int(pStmt, 1, nDigits);
19103
+ rc = sqlite3_step(pStmt);
19104
+ sqlite3_finalize(pStmt);
19105
+ assert(rc==SQLITE_DONE);
19106
+ }
19107
+ assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */
19108
+ rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0);
19109
+ rc_err_oom_die(rc);
19110
+ rc = sqlite3_step(pStmt);
19111
+ if( rc==SQLITE_ROW ){
19112
+ zColsSpec = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
19113
+ }else{
19114
+ zColsSpec = 0;
19115
+ }
19116
+ if( pzRenamed!=0 ){
19117
+ if( !hasDupes ) *pzRenamed = 0;
19118
+ else{
19119
+ sqlite3_finalize(pStmt);
19120
+ if( SQLITE_OK==sqlite3_prepare_v2(*pDb, zRenamesDone, -1, &pStmt, 0)
19121
+ && SQLITE_ROW==sqlite3_step(pStmt) ){
19122
+ *pzRenamed = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
19123
+ }else
19124
+ *pzRenamed = 0;
19125
+ }
19126
+ }
19127
+ sqlite3_finalize(pStmt);
19128
+ sqlite3_close(*pDb);
19129
+ *pDb = 0;
19130
+ return zColsSpec;
19131
+ }
19132
+}
19133
+
1868619134
/*
1868719135
** If an input line begins with "." then invoke this routine to
1868819136
** process that line.
1868919137
**
1869019138
** Return 1 on error, 2 to exit, and 0 otherwise.
@@ -19467,24 +19915,26 @@
1946719915
}
1946819916
}else
1946919917
1947019918
if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
1947119919
char *zTable = 0; /* Insert data into this table */
19472
- char *zSchema = "main"; /* within this schema */
19920
+ char *zSchema = 0; /* within this schema (may default to "main") */
1947319921
char *zFile = 0; /* Name of file to extra content from */
1947419922
sqlite3_stmt *pStmt = NULL; /* A statement */
1947519923
int nCol; /* Number of columns in the table */
1947619924
int nByte; /* Number of bytes in an SQL string */
1947719925
int i, j; /* Loop counters */
1947819926
int needCommit; /* True to COMMIT or ROLLBACK at end */
1947919927
int nSep; /* Number of bytes in p->colSeparator[] */
1948019928
char *zSql; /* An SQL statement */
19929
+ char *zFullTabName; /* Table name with schema if applicable */
1948119930
ImportCtx sCtx; /* Reader context */
1948219931
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
1948319932
int eVerbose = 0; /* Larger for more console output */
1948419933
int nSkip = 0; /* Initial lines to skip */
1948519934
int useOutputMode = 1; /* Use output mode to determine separators */
19935
+ char *zCreate = 0; /* CREATE TABLE statement text */
1948619936
1948719937
failIfSafeMode(p, "cannot run .import in safe mode");
1948819938
memset(&sCtx, 0, sizeof(sCtx));
1948919939
sCtx.z = sqlite3_malloc64(120);
1949019940
if( sCtx.z==0 ){
@@ -19603,11 +20053,10 @@
1960320053
utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
1960420054
rc = 1;
1960520055
import_cleanup(&sCtx);
1960620056
goto meta_command_exit;
1960720057
}
19608
- /* Below, resources must be freed before exit. */
1960920058
if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
1961020059
char zSep[2];
1961120060
zSep[1] = 0;
1961220061
zSep[0] = sCtx.cColSep;
1961320062
utf8_printf(p->out, "Column separator ");
@@ -19615,71 +20064,83 @@
1961520064
utf8_printf(p->out, ", row separator ");
1961620065
zSep[0] = sCtx.cRowSep;
1961720066
output_c_string(p->out, zSep);
1961820067
utf8_printf(p->out, "\n");
1961920068
}
20069
+ /* Below, resources must be freed before exit. */
1962020070
while( (nSkip--)>0 ){
1962120071
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
1962220072
}
19623
- zSql = sqlite3_mprintf("SELECT * FROM \"%w\".\"%w\"", zSchema, zTable);
19624
- if( zSql==0 ){
20073
+ if( zSchema!=0 ){
20074
+ zFullTabName = sqlite3_mprintf("\"%w\".\"%w\"", zSchema, zTable);
20075
+ }else{
20076
+ zFullTabName = sqlite3_mprintf("\"%w\"", zTable);
20077
+ }
20078
+ zSql = sqlite3_mprintf("SELECT * FROM %s", zFullTabName);
20079
+ if( zSql==0 || zFullTabName==0 ){
1962520080
import_cleanup(&sCtx);
1962620081
shell_out_of_memory();
1962720082
}
1962820083
nByte = strlen30(zSql);
1962920084
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
1963020085
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
1963120086
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
19632
- char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
19633
- zSchema, zTable);
19634
- char cSep = '(';
20087
+ sqlite3 *dbCols = 0;
20088
+ char *zRenames = 0;
20089
+ char *zColDefs;
20090
+ zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName);
1963520091
while( xRead(&sCtx) ){
19636
- zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
19637
- cSep = ',';
20092
+ zAutoColumn(sCtx.z, &dbCols, 0);
1963820093
if( sCtx.cTerm!=sCtx.cColSep ) break;
1963920094
}
19640
- if( cSep=='(' ){
19641
- sqlite3_free(zCreate);
19642
- import_cleanup(&sCtx);
20095
+ zColDefs = zAutoColumn(0, &dbCols, &zRenames);
20096
+ if( zRenames!=0 ){
20097
+ utf8_printf((stdin_is_interactive && p->in==stdin)? p->out : stderr,
20098
+ "Columns renamed during .import %s due to duplicates:\n"
20099
+ "%s\n", sCtx.zFile, zRenames);
20100
+ sqlite3_free(zRenames);
20101
+ }
20102
+ assert(dbCols==0);
20103
+ if( zColDefs==0 ){
1964320104
utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
20105
+ import_fail:
20106
+ sqlite3_free(zCreate);
20107
+ sqlite3_free(zSql);
20108
+ sqlite3_free(zFullTabName);
20109
+ import_cleanup(&sCtx);
1964420110
rc = 1;
1964520111
goto meta_command_exit;
1964620112
}
19647
- zCreate = sqlite3_mprintf("%z\n)", zCreate);
20113
+ zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
1964820114
if( eVerbose>=1 ){
1964920115
utf8_printf(p->out, "%s\n", zCreate);
1965020116
}
1965120117
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
1965220118
if( rc ){
1965320119
utf8_printf(stderr, "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
19654
- sqlite3_free(zCreate);
19655
- import_cleanup(&sCtx);
19656
- rc = 1;
19657
- goto meta_command_exit;
20120
+ goto import_fail;
1965820121
}
1965920122
sqlite3_free(zCreate);
20123
+ zCreate = 0;
1966020124
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
1966120125
}
19662
- sqlite3_free(zSql);
1966320126
if( rc ){
1966420127
if (pStmt) sqlite3_finalize(pStmt);
1966520128
utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
19666
- import_cleanup(&sCtx);
19667
- rc = 1;
19668
- goto meta_command_exit;
20129
+ goto import_fail;
1966920130
}
20131
+ sqlite3_free(zSql);
1967020132
nCol = sqlite3_column_count(pStmt);
1967120133
sqlite3_finalize(pStmt);
1967220134
pStmt = 0;
1967320135
if( nCol==0 ) return 0; /* no columns, no error */
1967420136
zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
1967520137
if( zSql==0 ){
1967620138
import_cleanup(&sCtx);
1967720139
shell_out_of_memory();
1967820140
}
19679
- sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?",
19680
- zSchema, zTable);
20141
+ sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zFullTabName);
1968120142
j = strlen30(zSql);
1968220143
for(i=1; i<nCol; i++){
1968320144
zSql[j++] = ',';
1968420145
zSql[j++] = '?';
1968520146
}
@@ -19687,18 +20148,17 @@
1968720148
zSql[j] = 0;
1968820149
if( eVerbose>=2 ){
1968920150
utf8_printf(p->out, "Insert using: %s\n", zSql);
1969020151
}
1969120152
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19692
- sqlite3_free(zSql);
1969320153
if( rc ){
1969420154
utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
1969520155
if (pStmt) sqlite3_finalize(pStmt);
19696
- import_cleanup(&sCtx);
19697
- rc = 1;
19698
- goto meta_command_exit;
20156
+ goto import_fail;
1969920157
}
20158
+ sqlite3_free(zSql);
20159
+ sqlite3_free(zFullTabName);
1970020160
needCommit = sqlite3_get_autocommit(p->db);
1970120161
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1970220162
do{
1970320163
int startLine = sCtx.nLine;
1970420164
for(i=0; i<nCol; i++){
@@ -19976,68 +20436,127 @@
1997620436
p->pLog = output_file_open(zFile, 0);
1997720437
}
1997820438
}else
1997920439
1998020440
if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
19981
- const char *zMode = nArg>=2 ? azArg[1] : "";
19982
- int n2 = strlen30(zMode);
19983
- int c2 = zMode[0];
19984
- if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
20441
+ const char *zMode = 0;
20442
+ const char *zTabname = 0;
20443
+ int i, n2;
20444
+ ColModeOpts cmOpts = ColModeOpts_default;
20445
+ for(i=1; i<nArg; i++){
20446
+ const char *z = azArg[i];
20447
+ if( optionMatch(z,"wrap") && i+1<nArg ){
20448
+ cmOpts.iWrap = integerValue(azArg[++i]);
20449
+ }else if( optionMatch(z,"ww") ){
20450
+ cmOpts.bWordWrap = 1;
20451
+ }else if( optionMatch(z,"wordwrap") && i+1<nArg ){
20452
+ cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]);
20453
+ }else if( optionMatch(z,"quote") ){
20454
+ cmOpts.bQuote = 1;
20455
+ }else if( optionMatch(z,"noquote") ){
20456
+ cmOpts.bQuote = 0;
20457
+ }else if( zMode==0 ){
20458
+ zMode = z;
20459
+ /* Apply defaults for qbox pseudo-mods. If that
20460
+ * overwrites already-set values, user was informed of this.
20461
+ */
20462
+ if( strcmp(z, "qbox")==0 ){
20463
+ ColModeOpts cmo = ColModeOpts_default_qbox;
20464
+ zMode = "box";
20465
+ cmOpts = cmo;
20466
+ }
20467
+ }else if( zTabname==0 ){
20468
+ zTabname = z;
20469
+ }else if( z[0]=='-' ){
20470
+ utf8_printf(stderr, "unknown option: %s\n", z);
20471
+ utf8_printf(stderr, "options:\n"
20472
+ " --noquote\n"
20473
+ " --quote\n"
20474
+ " --wordwrap on/off\n"
20475
+ " --wrap N\n"
20476
+ " --ww\n");
20477
+ rc = 1;
20478
+ goto meta_command_exit;
20479
+ }else{
20480
+ utf8_printf(stderr, "extra argument: \"%s\"\n", z);
20481
+ rc = 1;
20482
+ goto meta_command_exit;
20483
+ }
20484
+ }
20485
+ if( zMode==0 ){
20486
+ if( p->mode==MODE_Column
20487
+ || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
20488
+ ){
20489
+ raw_printf
20490
+ (p->out,
20491
+ "current output mode: %s --wrap %d --wordwrap %s --%squote\n",
20492
+ modeDescr[p->mode], p->cmOpts.iWrap,
20493
+ p->cmOpts.bWordWrap ? "on" : "off",
20494
+ p->cmOpts.bQuote ? "" : "no");
20495
+ }else{
20496
+ raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
20497
+ }
20498
+ zMode = modeDescr[p->mode];
20499
+ }
20500
+ n2 = strlen30(zMode);
20501
+ if( strncmp(zMode,"lines",n2)==0 ){
1998520502
p->mode = MODE_Line;
1998620503
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19987
- }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
20504
+ }else if( strncmp(zMode,"columns",n2)==0 ){
1998820505
p->mode = MODE_Column;
1998920506
if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
1999020507
p->showHeader = 1;
1999120508
}
1999220509
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19993
- }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
20510
+ p->cmOpts = cmOpts;
20511
+ }else if( strncmp(zMode,"list",n2)==0 ){
1999420512
p->mode = MODE_List;
1999520513
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
1999620514
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19997
- }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
20515
+ }else if( strncmp(zMode,"html",n2)==0 ){
1999820516
p->mode = MODE_Html;
19999
- }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
20517
+ }else if( strncmp(zMode,"tcl",n2)==0 ){
2000020518
p->mode = MODE_Tcl;
2000120519
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
2000220520
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20003
- }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
20521
+ }else if( strncmp(zMode,"csv",n2)==0 ){
2000420522
p->mode = MODE_Csv;
2000520523
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
2000620524
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
20007
- }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
20525
+ }else if( strncmp(zMode,"tabs",n2)==0 ){
2000820526
p->mode = MODE_List;
2000920527
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
20010
- }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
20528
+ }else if( strncmp(zMode,"insert",n2)==0 ){
2001120529
p->mode = MODE_Insert;
20012
- set_table_name(p, nArg>=3 ? azArg[2] : "table");
20013
- }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
20530
+ set_table_name(p, zTabname ? zTabname : "table");
20531
+ }else if( strncmp(zMode,"quote",n2)==0 ){
2001420532
p->mode = MODE_Quote;
2001520533
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
2001620534
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20017
- }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
20535
+ }else if( strncmp(zMode,"ascii",n2)==0 ){
2001820536
p->mode = MODE_Ascii;
2001920537
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
2002020538
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
20021
- }else if( c2=='m' && strncmp(azArg[1],"markdown",n2)==0 ){
20539
+ }else if( strncmp(zMode,"markdown",n2)==0 ){
2002220540
p->mode = MODE_Markdown;
20023
- }else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
20541
+ p->cmOpts = cmOpts;
20542
+ }else if( strncmp(zMode,"table",n2)==0 ){
2002420543
p->mode = MODE_Table;
20025
- }else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
20544
+ p->cmOpts = cmOpts;
20545
+ }else if( strncmp(zMode,"box",n2)==0 ){
2002620546
p->mode = MODE_Box;
20027
- }else if( c2=='c' && strncmp(azArg[1],"count",n2)==0 ){
20547
+ p->cmOpts = cmOpts;
20548
+ }else if( strncmp(zMode,"count",n2)==0 ){
2002820549
p->mode = MODE_Count;
20029
- }else if( c2=='o' && strncmp(azArg[1],"off",n2)==0 ){
20550
+ }else if( strncmp(zMode,"off",n2)==0 ){
2003020551
p->mode = MODE_Off;
20031
- }else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
20552
+ }else if( strncmp(zMode,"json",n2)==0 ){
2003220553
p->mode = MODE_Json;
20033
- }else if( nArg==1 ){
20034
- raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
2003520554
}else{
2003620555
raw_printf(stderr, "Error: mode should be one of: "
2003720556
"ascii box column csv html insert json line list markdown "
20038
- "quote table tabs tcl\n");
20557
+ "qbox quote table tabs tcl\n");
2003920558
rc = 1;
2004020559
}
2004120560
p->cMode = p->mode;
2004220561
}else
2004320562
@@ -20158,13 +20677,14 @@
2015820677
){
2015920678
char *zFile = 0;
2016020679
int bTxtMode = 0;
2016120680
int i;
2016220681
int eMode = 0;
20163
- int bBOM = 0;
20164
- int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
20682
+ int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
20683
+ unsigned char zBOM[4]; /* Byte-order mark to using if --bom is present */
2016520684
20685
+ zBOM[0] = 0;
2016620686
failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
2016720687
if( c=='e' ){
2016820688
eMode = 'x';
2016920689
bOnce = 2;
2017020690
}else if( strncmp(azArg[0],"once",n)==0 ){
@@ -20173,11 +20693,14 @@
2017320693
for(i=1; i<nArg; i++){
2017420694
char *z = azArg[i];
2017520695
if( z[0]=='-' ){
2017620696
if( z[1]=='-' ) z++;
2017720697
if( strcmp(z,"-bom")==0 ){
20178
- bBOM = 1;
20698
+ zBOM[0] = 0xef;
20699
+ zBOM[1] = 0xbb;
20700
+ zBOM[2] = 0xbf;
20701
+ zBOM[3] = 0;
2017920702
}else if( c!='e' && strcmp(z,"-x")==0 ){
2018020703
eMode = 'x'; /* spreadsheet */
2018120704
}else if( c!='e' && strcmp(z,"-e")==0 ){
2018220705
eMode = 'e'; /* text editor */
2018320706
}else{
@@ -20242,11 +20765,11 @@
2024220765
if( p->out==0 ){
2024320766
utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
2024420767
p->out = stdout;
2024520768
rc = 1;
2024620769
}else{
20247
- if( bBOM ) fprintf(p->out,"\357\273\277");
20770
+ if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out);
2024820771
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
2024920772
}
2025020773
#endif
2025120774
}else{
2025220775
p->out = output_file_open(zFile, bTxtMode);
@@ -20255,11 +20778,11 @@
2025520778
utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
2025620779
}
2025720780
p->out = stdout;
2025820781
rc = 1;
2025920782
} else {
20260
- if( bBOM ) fprintf(p->out,"\357\273\277");
20783
+ if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out);
2026120784
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
2026220785
}
2026320786
}
2026420787
sqlite3_free(zFile);
2026520788
}else
@@ -21181,11 +21704,21 @@
2118121704
azBool[ShellHasFlag(p, SHFLG_Echo)]);
2118221705
utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
2118321706
utf8_printf(p->out, "%12.12s: %s\n","explain",
2118421707
p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
2118521708
utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
21186
- utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
21709
+ if( p->mode==MODE_Column
21710
+ || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
21711
+ ){
21712
+ utf8_printf
21713
+ (p->out, "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode",
21714
+ modeDescr[p->mode], p->cmOpts.iWrap,
21715
+ p->cmOpts.bWordWrap ? "on" : "off",
21716
+ p->cmOpts.bQuote ? "" : "no");
21717
+ }else{
21718
+ utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
21719
+ }
2118721720
utf8_printf(p->out, "%12.12s: ", "nullvalue");
2118821721
output_c_string(p->out, p->nullValue);
2118921722
raw_printf(p->out, "\n");
2119021723
utf8_printf(p->out,"%12.12s: %s\n","output",
2119121724
strlen30(p->outfile) ? p->outfile : "stdout");
@@ -21979,23 +22512,34 @@
2197922512
BEGIN_TIMER;
2198022513
rc = shell_exec(p, zSql, &zErrMsg);
2198122514
END_TIMER;
2198222515
if( rc || zErrMsg ){
2198322516
char zPrefix[100];
22517
+ const char *zErrorTail;
22518
+ const char *zErrorType;
22519
+ if( zErrMsg==0 ){
22520
+ zErrorType = "Error";
22521
+ zErrorTail = sqlite3_errmsg(p->db);
22522
+ }else if( strncmp(zErrMsg, "in prepare, ",12)==0 ){
22523
+ zErrorType = "Parse error";
22524
+ zErrorTail = &zErrMsg[12];
22525
+ }else if( strncmp(zErrMsg, "stepping, ", 10)==0 ){
22526
+ zErrorType = "Runtime error";
22527
+ zErrorTail = &zErrMsg[10];
22528
+ }else{
22529
+ zErrorType = "Error";
22530
+ zErrorTail = zErrMsg;
22531
+ }
2198422532
if( in!=0 || !stdin_is_interactive ){
2198522533
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
21986
- "Error: near line %d:", startline);
21987
- }else{
21988
- sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
21989
- }
21990
- if( zErrMsg!=0 ){
21991
- utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
21992
- sqlite3_free(zErrMsg);
21993
- zErrMsg = 0;
21994
- }else{
21995
- utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
21996
- }
22534
+ "%s near line %d:", zErrorType, startline);
22535
+ }else{
22536
+ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType);
22537
+ }
22538
+ utf8_printf(stderr, "%s %s\n", zPrefix, zErrorTail);
22539
+ sqlite3_free(zErrMsg);
22540
+ zErrMsg = 0;
2199722541
return 1;
2199822542
}else if( ShellHasFlag(p, SHFLG_CountChanges) ){
2199922543
char zLineBuf[2000];
2200022544
sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
2200122545
"changes: %lld total_changes: %lld",
@@ -22108,11 +22652,12 @@
2210822652
if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
2210922653
nSql = 0;
2211022654
qss = QSS_Start;
2211122655
}
2211222656
}
22113
- if( nSql && QSS_PLAINDARK(qss) ){
22657
+ if( nSql ){
22658
+ /* This may be incomplete. Let the SQL parser deal with that. */
2211422659
errCnt += runOneSqlLine(p, zSql, p->in, startline);
2211522660
}
2211622661
free(zSql);
2211722662
free(zLine);
2211822663
--p->inputNesting;
2211922664
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -39,14 +39,14 @@
39 ** Optionally #include a user-defined header, whereby compilation options
40 ** may be set prior to where they take effect, but after platform setup.
41 ** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include
42 ** file. Note that this macro has a like effect on sqlite3.c compilation.
43 */
 
 
44 #ifdef SQLITE_CUSTOM_INCLUDE
45 # define INC_STRINGIFY_(f) #f
46 # define INC_STRINGIFY(f) INC_STRINGIFY_(f)
47 # include INC_STRINGIFY(SQLITE_CUSTOM_INCLUDE)
48 #endif
49
50 /*
51 ** Determine if we are dealing with WinRT, which provides only a subset of
52 ** the full Win32 API.
@@ -1401,11 +1401,11 @@
1401 ** sha3_query(Y,SIZE)
1402 **
1403 ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
1404 ** X is NULL.
1405 **
1406 ** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
1407 ** and returns a hash of their results.
1408 **
1409 ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
1410 ** is used. If SIZE is included it must be one of the integers 224, 256,
1411 ** 384, or 512, to determine SHA3 hash variant that is computed.
@@ -5449,11 +5449,11 @@
5449 unsigned int i;
5450 int rc = SQLITE_OK;
5451 SQLITE_EXTENSION_INIT2(pApi);
5452 (void)pzErrMsg; /* Unused parameter */
5453 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
5454 rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
5455 SQLITE_UTF8|SQLITE_INNOCUOUS,
5456 (void*)&aFunc[i].iAux,
5457 aFunc[i].xFunc, 0, 0);
5458 }
5459 return rc;
@@ -7962,13 +7962,18 @@
7962 zFile = pTab->zFile;
7963 }else if( idxNum==0 ){
7964 zipfileCursorErr(pCsr, "zipfile() function requires an argument");
7965 return SQLITE_ERROR;
7966 }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
 
7967 const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
7968 int nBlob = sqlite3_value_bytes(argv[0]);
7969 assert( pTab->pFirstEntry==0 );
 
 
 
 
7970 rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
7971 pCsr->pFreeEntry = pTab->pFirstEntry;
7972 pTab->pFirstEntry = pTab->pLastEntry = 0;
7973 if( rc!=SQLITE_OK ) return rc;
7974 bInMemory = 1;
@@ -8870,10 +8875,14 @@
8870 0, /* xSync */
8871 zipfileCommit, /* xCommit */
8872 zipfileRollback, /* xRollback */
8873 zipfileFindFunction, /* xFindMethod */
8874 0, /* xRename */
 
 
 
 
8875 };
8876
8877 int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
8878 if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
8879 if( rc==SQLITE_OK ){
@@ -12143,10 +12152,19 @@
12143 EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
12144 EQPGraphRow *pLast; /* Last element of the pRow list */
12145 char zPrefix[100]; /* Graph prefix */
12146 };
12147
 
 
 
 
 
 
 
 
 
12148 /*
12149 ** State information about the database connection is contained in an
12150 ** instance of the following structure.
12151 */
12152 typedef struct ShellState ShellState;
@@ -12161,10 +12179,11 @@
12161 u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
12162 u8 nEqpLevel; /* Depth of the EQP output graph */
12163 u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
12164 u8 bSafeMode; /* True to prohibit unsafe operations */
12165 u8 bSafeModePersist; /* The long-term value of bSafeMode */
 
12166 unsigned statsOn; /* True to display memory stats before each finalize */
12167 unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */
12168 int inputNesting; /* Track nesting level of .read and other redirects */
12169 int outCount; /* Revert to stdout when reaching zero */
12170 int cnt; /* Number of records displayed so far */
@@ -13378,11 +13397,16 @@
13378 if( ur==0x7ff0000000000000LL ){
13379 raw_printf(p->out, "1e999");
13380 }else if( ur==0xfff0000000000000LL ){
13381 raw_printf(p->out, "-1e999");
13382 }else{
13383 sqlite3_snprintf(50,z,"%!.20g", r);
 
 
 
 
 
13384 raw_printf(p->out, "%s", z);
13385 }
13386 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
13387 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
13388 int nBlob = sqlite3_column_bytes(p->pStmt, i);
@@ -13704,21 +13728,28 @@
13704 /*
13705 ** Allocate space and save off string indicating current error.
13706 */
13707 static char *save_err_msg(
13708 sqlite3 *db, /* Database to query */
13709 const char *zWhen, /* Qualifier (format) wrapper */
13710 int rc, /* Error code returned from API */
13711 const char *zSql /* SQL string, or NULL */
13712 ){
13713 char *zErr;
13714 char *zContext;
13715 if( zWhen==0 ) zWhen = "%s (%d)%s";
 
 
 
 
13716 zContext = shell_error_context(zSql, db);
13717 zErr = sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc, zContext);
 
 
 
 
13718 shell_check_oom(zErr);
13719 sqlite3_free(zContext);
13720 return zErr;
13721 }
13722
13723 #ifdef __linux__
13724 /*
@@ -14241,11 +14272,138 @@
14241 utf8_printf(p->out, "%s", zSep3);
14242 }
14243 fputs("\n", p->out);
14244 }
14245
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14247
14248 /*
14249 ** Run a prepared statement and output the result in one of the
14250 ** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
14251 ** or MODE_Box.
@@ -14261,39 +14419,41 @@
14261 ){
14262 sqlite3_int64 nRow = 0;
14263 int nColumn = 0;
14264 char **azData = 0;
14265 sqlite3_int64 nAlloc = 0;
 
 
14266 const char *z;
 
14267 int rc;
14268 sqlite3_int64 i, nData;
14269 int j, nTotal, w, n;
14270 const char *colSep = 0;
14271 const char *rowSep = 0;
 
 
 
 
14272
14273 rc = sqlite3_step(pStmt);
14274 if( rc!=SQLITE_ROW ) return;
14275 nColumn = sqlite3_column_count(pStmt);
14276 nAlloc = nColumn*4;
14277 if( nAlloc<=0 ) nAlloc = 1;
14278 azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
14279 shell_check_oom(azData);
14280 for(i=0; i<nColumn; i++){
14281 azData[i] = strdup(sqlite3_column_name(pStmt,i));
14282 }
14283 do{
14284 if( (nRow+2)*nColumn >= nAlloc ){
14285 nAlloc *= 2;
14286 azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
14287 shell_check_oom(azData);
14288 }
14289 nRow++;
14290 for(i=0; i<nColumn; i++){
14291 z = (const char*)sqlite3_column_text(pStmt,i);
14292 azData[nRow*nColumn + i] = z ? strdup(z) : 0;
14293 }
14294 }while( sqlite3_step(pStmt)==SQLITE_ROW );
14295 if( nColumn>p->nWidth ){
14296 p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int));
14297 shell_check_oom(p->colWidth);
14298 for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
14299 p->nWidth = nColumn;
@@ -14303,10 +14463,56 @@
14303 for(i=0; i<nColumn; i++){
14304 w = p->colWidth[i];
14305 if( w<0 ) w = -w;
14306 p->actualWidth[i] = w;
14307 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14308 nTotal = nColumn*(nRow+1);
14309 for(i=0; i<nTotal; i++){
14310 z = azData[i];
14311 if( z==0 ) z = p->nullValue;
14312 n = strlenChar(z);
@@ -14385,10 +14591,19 @@
14385 w = p->actualWidth[j];
14386 if( p->colWidth[j]<0 ) w = -w;
14387 utf8_width_print(p->out, w, z);
14388 if( j==nColumn-1 ){
14389 utf8_printf(p->out, "%s", rowSep);
 
 
 
 
 
 
 
 
 
14390 j = -1;
14391 if( seenInterrupt ) goto columnar_end;
14392 }else{
14393 utf8_printf(p->out, "%s", colSep);
14394 }
@@ -14403,10 +14618,16 @@
14403 utf8_printf(p->out, "Interrupt\n");
14404 }
14405 nData = (nRow+1)*nColumn;
14406 for(i=0; i<nData; i++) free(azData[i]);
14407 sqlite3_free(azData);
 
 
 
 
 
 
14408 }
14409
14410 /*
14411 ** Run a prepared statement
14412 */
@@ -14655,11 +14876,11 @@
14655 while( zSql[0] && (SQLITE_OK == rc) ){
14656 static const char *zStmtSql;
14657 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
14658 if( SQLITE_OK != rc ){
14659 if( pzErrMsg ){
14660 *pzErrMsg = save_err_msg(db, "in prepare, %s (%d)%s", rc, zSql);
14661 }
14662 }else{
14663 if( !pStmt ){
14664 /* this happens for a comment or white-space */
14665 zSql = zLeftover;
@@ -14771,11 +14992,11 @@
14771 if( rc!=SQLITE_NOMEM ) rc = rc2;
14772 if( rc==SQLITE_OK ){
14773 zSql = zLeftover;
14774 while( IsSpace(zSql[0]) ) zSql++;
14775 }else if( pzErrMsg ){
14776 *pzErrMsg = save_err_msg(db, "stepping, %s (%d)", rc, 0);
14777 }
14778
14779 /* clear saved stmt handle */
14780 if( pArg ){
14781 pArg->pStmt = NULL;
@@ -15110,10 +15331,11 @@
15110 #endif
15111 #ifndef SQLITE_OMIT_AUTHORIZATION
15112 ".auth ON|OFF Show authorizer callbacks",
15113 #endif
15114 ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
 
15115 " --append Use the appendvfs",
15116 " --async Write to FILE without journal and fsync()",
15117 ".bail on|off Stop after hitting an error. Default OFF",
15118 ".binary on|off Turn binary output on or off. Default OFF",
15119 ".cd DIRECTORY Change the working directory to DIRECTORY",
@@ -15180,27 +15402,35 @@
15180 " fkey-indexes Find missing foreign key indexes",
15181 #ifndef SQLITE_OMIT_LOAD_EXTENSION
15182 ".load FILE ?ENTRY? Load an extension library",
15183 #endif
15184 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
15185 ".mode MODE ?TABLE? Set output mode",
15186 " MODE is one of:",
15187 " ascii Columns/rows delimited by 0x1F and 0x1E",
15188 " box Tables using unicode box-drawing characters",
15189 " csv Comma-separated values",
15190 " column Output in columns. (See .width)",
15191 " html HTML <table> code",
15192 " insert SQL insert statements for TABLE",
15193 " json Results in a JSON array",
15194 " line One value per line",
15195 " list Values delimited by \"|\"",
15196 " markdown Markdown table format",
15197 " quote Escape answers as for SQL",
15198 " table ASCII-art table",
15199 " tabs Tab-separated values",
15200 " tcl TCL list elements",
15201 ".nonce STRING Disable safe mode for one command if the nonce matches",
 
 
 
 
 
 
 
 
15202 ".nullvalue STRING Use STRING in place of NULL values",
15203 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
15204 " If FILE begins with '|' then open as a pipe",
15205 " --bom Put a UTF8 byte-order mark at the beginning",
15206 " -e Send output to the system text editor",
@@ -15249,11 +15479,11 @@
15249 " --lost-and-found TABLE Alternative name for the lost-and-found table",
15250 " --no-rowids Do not attempt to recover rowid values",
15251 " that are not also INTEGER PRIMARY KEYs",
15252 #endif
15253 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
15254 ".save FILE Write in-memory database into FILE",
15255 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
15256 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
15257 " Options:",
15258 " --indent Try to pretty-print the schema",
15259 " --nosys Omit objects whose names start with \"sqlite_\"",
@@ -15853,12 +16083,14 @@
15853 sqlite3_series_init(p->db, 0, 0);
15854 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
15855 sqlite3_dbdata_init(p->db, 0, 0);
15856 #endif
15857 #ifdef SQLITE_HAVE_ZLIB
15858 sqlite3_zipfile_init(p->db, 0, 0);
15859 sqlite3_sqlar_init(p->db, 0, 0);
 
 
15860 #endif
15861 sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
15862 shellAddSchemaName, 0, 0);
15863 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
15864 shellModuleSchema, 0, 0);
@@ -16613,14 +16845,14 @@
16613 }
16614
16615 /*
16616 ** Run an SQL command and return the single integer result.
16617 */
16618 static int db_int(ShellState *p, const char *zSql){
16619 sqlite3_stmt *pStmt;
16620 int res = 0;
16621 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
16622 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
16623 res = sqlite3_column_int(pStmt,0);
16624 }
16625 sqlite3_finalize(pStmt);
16626 return res;
@@ -16721,11 +16953,11 @@
16721 }else{
16722 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
16723 }
16724 for(i=0; i<ArraySize(aQuery); i++){
16725 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
16726 int val = db_int(p, zSql);
16727 sqlite3_free(zSql);
16728 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
16729 }
16730 sqlite3_free(zSchemaTab);
16731 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
@@ -18084,10 +18316,11 @@
18084 *pRc = SQLITE_NOMEM;
18085 }
18086 }
18087 return z;
18088 }
 
18089
18090 /*
18091 ** When running the ".recover" command, each output table, and the special
18092 ** orphaned row table if it is required, is represented by an instance
18093 ** of the following struct.
@@ -18681,10 +18914,225 @@
18681 sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
18682 return rc;
18683 }
18684 #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
18685
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18686 /*
18687 ** If an input line begins with "." then invoke this routine to
18688 ** process that line.
18689 **
18690 ** Return 1 on error, 2 to exit, and 0 otherwise.
@@ -19467,24 +19915,26 @@
19467 }
19468 }else
19469
19470 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
19471 char *zTable = 0; /* Insert data into this table */
19472 char *zSchema = "main"; /* within this schema */
19473 char *zFile = 0; /* Name of file to extra content from */
19474 sqlite3_stmt *pStmt = NULL; /* A statement */
19475 int nCol; /* Number of columns in the table */
19476 int nByte; /* Number of bytes in an SQL string */
19477 int i, j; /* Loop counters */
19478 int needCommit; /* True to COMMIT or ROLLBACK at end */
19479 int nSep; /* Number of bytes in p->colSeparator[] */
19480 char *zSql; /* An SQL statement */
 
19481 ImportCtx sCtx; /* Reader context */
19482 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
19483 int eVerbose = 0; /* Larger for more console output */
19484 int nSkip = 0; /* Initial lines to skip */
19485 int useOutputMode = 1; /* Use output mode to determine separators */
 
19486
19487 failIfSafeMode(p, "cannot run .import in safe mode");
19488 memset(&sCtx, 0, sizeof(sCtx));
19489 sCtx.z = sqlite3_malloc64(120);
19490 if( sCtx.z==0 ){
@@ -19603,11 +20053,10 @@
19603 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
19604 rc = 1;
19605 import_cleanup(&sCtx);
19606 goto meta_command_exit;
19607 }
19608 /* Below, resources must be freed before exit. */
19609 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
19610 char zSep[2];
19611 zSep[1] = 0;
19612 zSep[0] = sCtx.cColSep;
19613 utf8_printf(p->out, "Column separator ");
@@ -19615,71 +20064,83 @@
19615 utf8_printf(p->out, ", row separator ");
19616 zSep[0] = sCtx.cRowSep;
19617 output_c_string(p->out, zSep);
19618 utf8_printf(p->out, "\n");
19619 }
 
19620 while( (nSkip--)>0 ){
19621 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
19622 }
19623 zSql = sqlite3_mprintf("SELECT * FROM \"%w\".\"%w\"", zSchema, zTable);
19624 if( zSql==0 ){
 
 
 
 
 
19625 import_cleanup(&sCtx);
19626 shell_out_of_memory();
19627 }
19628 nByte = strlen30(zSql);
19629 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19630 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
19631 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
19632 char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
19633 zSchema, zTable);
19634 char cSep = '(';
 
19635 while( xRead(&sCtx) ){
19636 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
19637 cSep = ',';
19638 if( sCtx.cTerm!=sCtx.cColSep ) break;
19639 }
19640 if( cSep=='(' ){
19641 sqlite3_free(zCreate);
19642 import_cleanup(&sCtx);
 
 
 
 
 
 
19643 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
 
 
 
 
 
19644 rc = 1;
19645 goto meta_command_exit;
19646 }
19647 zCreate = sqlite3_mprintf("%z\n)", zCreate);
19648 if( eVerbose>=1 ){
19649 utf8_printf(p->out, "%s\n", zCreate);
19650 }
19651 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
19652 if( rc ){
19653 utf8_printf(stderr, "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
19654 sqlite3_free(zCreate);
19655 import_cleanup(&sCtx);
19656 rc = 1;
19657 goto meta_command_exit;
19658 }
19659 sqlite3_free(zCreate);
 
19660 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19661 }
19662 sqlite3_free(zSql);
19663 if( rc ){
19664 if (pStmt) sqlite3_finalize(pStmt);
19665 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
19666 import_cleanup(&sCtx);
19667 rc = 1;
19668 goto meta_command_exit;
19669 }
 
19670 nCol = sqlite3_column_count(pStmt);
19671 sqlite3_finalize(pStmt);
19672 pStmt = 0;
19673 if( nCol==0 ) return 0; /* no columns, no error */
19674 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
19675 if( zSql==0 ){
19676 import_cleanup(&sCtx);
19677 shell_out_of_memory();
19678 }
19679 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?",
19680 zSchema, zTable);
19681 j = strlen30(zSql);
19682 for(i=1; i<nCol; i++){
19683 zSql[j++] = ',';
19684 zSql[j++] = '?';
19685 }
@@ -19687,18 +20148,17 @@
19687 zSql[j] = 0;
19688 if( eVerbose>=2 ){
19689 utf8_printf(p->out, "Insert using: %s\n", zSql);
19690 }
19691 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
19692 sqlite3_free(zSql);
19693 if( rc ){
19694 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
19695 if (pStmt) sqlite3_finalize(pStmt);
19696 import_cleanup(&sCtx);
19697 rc = 1;
19698 goto meta_command_exit;
19699 }
 
 
19700 needCommit = sqlite3_get_autocommit(p->db);
19701 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
19702 do{
19703 int startLine = sCtx.nLine;
19704 for(i=0; i<nCol; i++){
@@ -19976,68 +20436,127 @@
19976 p->pLog = output_file_open(zFile, 0);
19977 }
19978 }else
19979
19980 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
19981 const char *zMode = nArg>=2 ? azArg[1] : "";
19982 int n2 = strlen30(zMode);
19983 int c2 = zMode[0];
19984 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19985 p->mode = MODE_Line;
19986 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19987 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
19988 p->mode = MODE_Column;
19989 if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
19990 p->showHeader = 1;
19991 }
19992 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19993 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
 
19994 p->mode = MODE_List;
19995 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
19996 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
19997 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
19998 p->mode = MODE_Html;
19999 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
20000 p->mode = MODE_Tcl;
20001 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
20002 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20003 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
20004 p->mode = MODE_Csv;
20005 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
20006 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
20007 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
20008 p->mode = MODE_List;
20009 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
20010 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
20011 p->mode = MODE_Insert;
20012 set_table_name(p, nArg>=3 ? azArg[2] : "table");
20013 }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
20014 p->mode = MODE_Quote;
20015 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
20016 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20017 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
20018 p->mode = MODE_Ascii;
20019 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
20020 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
20021 }else if( c2=='m' && strncmp(azArg[1],"markdown",n2)==0 ){
20022 p->mode = MODE_Markdown;
20023 }else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
 
20024 p->mode = MODE_Table;
20025 }else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
 
20026 p->mode = MODE_Box;
20027 }else if( c2=='c' && strncmp(azArg[1],"count",n2)==0 ){
 
20028 p->mode = MODE_Count;
20029 }else if( c2=='o' && strncmp(azArg[1],"off",n2)==0 ){
20030 p->mode = MODE_Off;
20031 }else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
20032 p->mode = MODE_Json;
20033 }else if( nArg==1 ){
20034 raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
20035 }else{
20036 raw_printf(stderr, "Error: mode should be one of: "
20037 "ascii box column csv html insert json line list markdown "
20038 "quote table tabs tcl\n");
20039 rc = 1;
20040 }
20041 p->cMode = p->mode;
20042 }else
20043
@@ -20158,13 +20677,14 @@
20158 ){
20159 char *zFile = 0;
20160 int bTxtMode = 0;
20161 int i;
20162 int eMode = 0;
20163 int bBOM = 0;
20164 int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
20165
 
20166 failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
20167 if( c=='e' ){
20168 eMode = 'x';
20169 bOnce = 2;
20170 }else if( strncmp(azArg[0],"once",n)==0 ){
@@ -20173,11 +20693,14 @@
20173 for(i=1; i<nArg; i++){
20174 char *z = azArg[i];
20175 if( z[0]=='-' ){
20176 if( z[1]=='-' ) z++;
20177 if( strcmp(z,"-bom")==0 ){
20178 bBOM = 1;
 
 
 
20179 }else if( c!='e' && strcmp(z,"-x")==0 ){
20180 eMode = 'x'; /* spreadsheet */
20181 }else if( c!='e' && strcmp(z,"-e")==0 ){
20182 eMode = 'e'; /* text editor */
20183 }else{
@@ -20242,11 +20765,11 @@
20242 if( p->out==0 ){
20243 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
20244 p->out = stdout;
20245 rc = 1;
20246 }else{
20247 if( bBOM ) fprintf(p->out,"\357\273\277");
20248 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
20249 }
20250 #endif
20251 }else{
20252 p->out = output_file_open(zFile, bTxtMode);
@@ -20255,11 +20778,11 @@
20255 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
20256 }
20257 p->out = stdout;
20258 rc = 1;
20259 } else {
20260 if( bBOM ) fprintf(p->out,"\357\273\277");
20261 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
20262 }
20263 }
20264 sqlite3_free(zFile);
20265 }else
@@ -21181,11 +21704,21 @@
21181 azBool[ShellHasFlag(p, SHFLG_Echo)]);
21182 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
21183 utf8_printf(p->out, "%12.12s: %s\n","explain",
21184 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
21185 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
21186 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
 
 
 
 
 
 
 
 
 
 
21187 utf8_printf(p->out, "%12.12s: ", "nullvalue");
21188 output_c_string(p->out, p->nullValue);
21189 raw_printf(p->out, "\n");
21190 utf8_printf(p->out,"%12.12s: %s\n","output",
21191 strlen30(p->outfile) ? p->outfile : "stdout");
@@ -21979,23 +22512,34 @@
21979 BEGIN_TIMER;
21980 rc = shell_exec(p, zSql, &zErrMsg);
21981 END_TIMER;
21982 if( rc || zErrMsg ){
21983 char zPrefix[100];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21984 if( in!=0 || !stdin_is_interactive ){
21985 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
21986 "Error: near line %d:", startline);
21987 }else{
21988 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
21989 }
21990 if( zErrMsg!=0 ){
21991 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
21992 sqlite3_free(zErrMsg);
21993 zErrMsg = 0;
21994 }else{
21995 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
21996 }
21997 return 1;
21998 }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
21999 char zLineBuf[2000];
22000 sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
22001 "changes: %lld total_changes: %lld",
@@ -22108,11 +22652,12 @@
22108 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
22109 nSql = 0;
22110 qss = QSS_Start;
22111 }
22112 }
22113 if( nSql && QSS_PLAINDARK(qss) ){
 
22114 errCnt += runOneSqlLine(p, zSql, p->in, startline);
22115 }
22116 free(zSql);
22117 free(zLine);
22118 --p->inputNesting;
22119
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -39,14 +39,14 @@
39 ** Optionally #include a user-defined header, whereby compilation options
40 ** may be set prior to where they take effect, but after platform setup.
41 ** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include
42 ** file. Note that this macro has a like effect on sqlite3.c compilation.
43 */
44 # define SHELL_STRINGIFY_(f) #f
45 # define SHELL_STRINGIFY(f) SHELL_STRINGIFY_(f)
46 #ifdef SQLITE_CUSTOM_INCLUDE
47 # include SHELL_STRINGIFY(SQLITE_CUSTOM_INCLUDE)
 
 
48 #endif
49
50 /*
51 ** Determine if we are dealing with WinRT, which provides only a subset of
52 ** the full Win32 API.
@@ -1401,11 +1401,11 @@
1401 ** sha3_query(Y,SIZE)
1402 **
1403 ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
1404 ** X is NULL.
1405 **
1406 ** The sha3_query(Y) function evaluates all queries in the SQL statements of Y
1407 ** and returns a hash of their results.
1408 **
1409 ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm
1410 ** is used. If SIZE is included it must be one of the integers 224, 256,
1411 ** 384, or 512, to determine SHA3 hash variant that is computed.
@@ -5449,11 +5449,11 @@
5449 unsigned int i;
5450 int rc = SQLITE_OK;
5451 SQLITE_EXTENSION_INIT2(pApi);
5452 (void)pzErrMsg; /* Unused parameter */
5453 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
5454 rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
5455 SQLITE_UTF8|SQLITE_INNOCUOUS,
5456 (void*)&aFunc[i].iAux,
5457 aFunc[i].xFunc, 0, 0);
5458 }
5459 return rc;
@@ -7962,13 +7962,18 @@
7962 zFile = pTab->zFile;
7963 }else if( idxNum==0 ){
7964 zipfileCursorErr(pCsr, "zipfile() function requires an argument");
7965 return SQLITE_ERROR;
7966 }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
7967 static const u8 aEmptyBlob = 0;
7968 const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
7969 int nBlob = sqlite3_value_bytes(argv[0]);
7970 assert( pTab->pFirstEntry==0 );
7971 if( aBlob==0 ){
7972 aBlob = &aEmptyBlob;
7973 nBlob = 0;
7974 }
7975 rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
7976 pCsr->pFreeEntry = pTab->pFirstEntry;
7977 pTab->pFirstEntry = pTab->pLastEntry = 0;
7978 if( rc!=SQLITE_OK ) return rc;
7979 bInMemory = 1;
@@ -8870,10 +8875,14 @@
8875 0, /* xSync */
8876 zipfileCommit, /* xCommit */
8877 zipfileRollback, /* xRollback */
8878 zipfileFindFunction, /* xFindMethod */
8879 0, /* xRename */
8880 0, /* xSavepoint */
8881 0, /* xRelease */
8882 0, /* xRollback */
8883 0 /* xShadowName */
8884 };
8885
8886 int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
8887 if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
8888 if( rc==SQLITE_OK ){
@@ -12143,10 +12152,19 @@
12152 EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
12153 EQPGraphRow *pLast; /* Last element of the pRow list */
12154 char zPrefix[100]; /* Graph prefix */
12155 };
12156
12157 /* Parameters affecting columnar mode result display (defaulting together) */
12158 typedef struct ColModeOpts {
12159 int iWrap; /* In columnar modes, wrap lines reaching this limit */
12160 u8 bQuote; /* Quote results for .mode box and table */
12161 u8 bWordWrap; /* In columnar modes, wrap at word boundaries */
12162 } ColModeOpts;
12163 #define ColModeOpts_default { 60, 0, 0 }
12164 #define ColModeOpts_default_qbox { 60, 1, 0 }
12165
12166 /*
12167 ** State information about the database connection is contained in an
12168 ** instance of the following structure.
12169 */
12170 typedef struct ShellState ShellState;
@@ -12161,10 +12179,11 @@
12179 u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
12180 u8 nEqpLevel; /* Depth of the EQP output graph */
12181 u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
12182 u8 bSafeMode; /* True to prohibit unsafe operations */
12183 u8 bSafeModePersist; /* The long-term value of bSafeMode */
12184 ColModeOpts cmOpts; /* Option values affecting columnar mode output */
12185 unsigned statsOn; /* True to display memory stats before each finalize */
12186 unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */
12187 int inputNesting; /* Track nesting level of .read and other redirects */
12188 int outCount; /* Revert to stdout when reaching zero */
12189 int cnt; /* Number of records displayed so far */
@@ -13378,11 +13397,16 @@
13397 if( ur==0x7ff0000000000000LL ){
13398 raw_printf(p->out, "1e999");
13399 }else if( ur==0xfff0000000000000LL ){
13400 raw_printf(p->out, "-1e999");
13401 }else{
13402 sqlite3_int64 ir = (sqlite3_int64)r;
13403 if( r==(double)ir ){
13404 sqlite3_snprintf(50,z,"%lld.0", ir);
13405 }else{
13406 sqlite3_snprintf(50,z,"%!.20g", r);
13407 }
13408 raw_printf(p->out, "%s", z);
13409 }
13410 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
13411 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
13412 int nBlob = sqlite3_column_bytes(p->pStmt, i);
@@ -13704,21 +13728,28 @@
13728 /*
13729 ** Allocate space and save off string indicating current error.
13730 */
13731 static char *save_err_msg(
13732 sqlite3 *db, /* Database to query */
13733 const char *zPhase, /* When the error occcurs */
13734 int rc, /* Error code returned from API */
13735 const char *zSql /* SQL string, or NULL */
13736 ){
13737 char *zErr;
13738 char *zContext;
13739 sqlite3_str *pStr = sqlite3_str_new(0);
13740 sqlite3_str_appendf(pStr, "%s, %s", zPhase, sqlite3_errmsg(db));
13741 if( rc>1 ){
13742 sqlite3_str_appendf(pStr, " (%d)", rc);
13743 }
13744 zContext = shell_error_context(zSql, db);
13745 if( zContext ){
13746 sqlite3_str_appendall(pStr, zContext);
13747 sqlite3_free(zContext);
13748 }
13749 zErr = sqlite3_str_finish(pStr);
13750 shell_check_oom(zErr);
 
13751 return zErr;
13752 }
13753
13754 #ifdef __linux__
13755 /*
@@ -14241,11 +14272,138 @@
14272 utf8_printf(p->out, "%s", zSep3);
14273 }
14274 fputs("\n", p->out);
14275 }
14276
14277 /*
14278 ** z[] is a line of text that is to be displayed the .mode box or table or
14279 ** similar tabular formats. z[] might contain control characters such
14280 ** as \n, \t, \f, or \r.
14281 **
14282 ** Compute characters to display on the first line of z[]. Stop at the
14283 ** first \r, \n, or \f. Expand \t into spaces. Return a copy (obtained
14284 ** from malloc()) of that first line, which caller should free sometime.
14285 ** Write anything to display on the next line into *pzTail. If this is
14286 ** the last line, write a NULL into *pzTail. (*pzTail is not allocated.)
14287 */
14288 static char *translateForDisplayAndDup(
14289 const unsigned char *z, /* Input text to be transformed */
14290 const unsigned char **pzTail, /* OUT: Tail of the input for next line */
14291 int mxWidth, /* Max width. 0 means no limit */
14292 u8 bWordWrap /* If true, avoid breaking mid-word */
14293 ){
14294 int i; /* Input bytes consumed */
14295 int j; /* Output bytes generated */
14296 int k; /* Input bytes to be displayed */
14297 int n; /* Output column number */
14298 unsigned char *zOut; /* Output text */
14299
14300 if( z==0 ){
14301 *pzTail = 0;
14302 return 0;
14303 }
14304 if( mxWidth<0 ) mxWidth = -mxWidth;
14305 if( mxWidth==0 ) mxWidth = 1000000;
14306 i = j = n = 0;
14307 while( n<mxWidth ){
14308 if( z[i]>=' ' ){
14309 n++;
14310 do{ i++; j++; }while( (z[i]&0xc0)==0x80 );
14311 continue;
14312 }
14313 if( z[i]=='\t' ){
14314 do{
14315 n++;
14316 j++;
14317 }while( (n&7)!=0 && n<mxWidth );
14318 i++;
14319 continue;
14320 }
14321 break;
14322 }
14323 if( n>=mxWidth && bWordWrap ){
14324 /* Perhaps try to back up to a better place to break the line */
14325 for(k=i; k>i/2; k--){
14326 if( isspace(z[k-1]) ) break;
14327 }
14328 if( k<=i/2 ){
14329 for(k=i; k>i/2; k--){
14330 if( isalnum(z[k-1])!=isalnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
14331 }
14332 }
14333 if( k<=i/2 ){
14334 k = i;
14335 }else{
14336 i = k;
14337 while( z[i]==' ' ) i++;
14338 }
14339 }else{
14340 k = i;
14341 }
14342 if( n>=mxWidth && z[i]>=' ' ){
14343 *pzTail = &z[i];
14344 }else if( z[i]=='\r' && z[i+1]=='\n' ){
14345 *pzTail = z[i+2] ? &z[i+2] : 0;
14346 }else if( z[i]==0 || z[i+1]==0 ){
14347 *pzTail = 0;
14348 }else{
14349 *pzTail = &z[i+1];
14350 }
14351 zOut = malloc( j+1 );
14352 shell_check_oom(zOut);
14353 i = j = n = 0;
14354 while( i<k ){
14355 if( z[i]>=' ' ){
14356 n++;
14357 do{ zOut[j++] = z[i++]; }while( (z[i]&0xc0)==0x80 );
14358 continue;
14359 }
14360 if( z[i]=='\t' ){
14361 do{
14362 n++;
14363 zOut[j++] = ' ';
14364 }while( (n&7)!=0 && n<mxWidth );
14365 i++;
14366 continue;
14367 }
14368 break;
14369 }
14370 zOut[j] = 0;
14371 return (char*)zOut;
14372 }
14373
14374 /* Extract the value of the i-th current column for pStmt as an SQL literal
14375 ** value. Memory is obtained from sqlite3_malloc64() and must be freed by
14376 ** the caller.
14377 */
14378 static char *quoted_column(sqlite3_stmt *pStmt, int i){
14379 switch( sqlite3_column_type(pStmt, i) ){
14380 case SQLITE_NULL: {
14381 return sqlite3_mprintf("NULL");
14382 }
14383 case SQLITE_INTEGER:
14384 case SQLITE_FLOAT: {
14385 return sqlite3_mprintf("%s",sqlite3_column_text(pStmt,i));
14386 }
14387 case SQLITE_TEXT: {
14388 return sqlite3_mprintf("%Q",sqlite3_column_text(pStmt,i));
14389 }
14390 case SQLITE_BLOB: {
14391 int j;
14392 sqlite3_str *pStr = sqlite3_str_new(0);
14393 const unsigned char *a = sqlite3_column_blob(pStmt,i);
14394 int n = sqlite3_column_bytes(pStmt,i);
14395 sqlite3_str_append(pStr, "x'", 2);
14396 for(j=0; j<n; j++){
14397 sqlite3_str_appendf(pStr, "%02x", a[j]);
14398 }
14399 sqlite3_str_append(pStr, "'", 1);
14400 return sqlite3_str_finish(pStr);
14401 }
14402 }
14403 return 0; /* Not reached */
14404 }
14405
14406 /*
14407 ** Run a prepared statement and output the result in one of the
14408 ** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
14409 ** or MODE_Box.
@@ -14261,39 +14419,41 @@
14419 ){
14420 sqlite3_int64 nRow = 0;
14421 int nColumn = 0;
14422 char **azData = 0;
14423 sqlite3_int64 nAlloc = 0;
14424 char *abRowDiv = 0;
14425 const unsigned char *uz;
14426 const char *z;
14427 char **azQuoted = 0;
14428 int rc;
14429 sqlite3_int64 i, nData;
14430 int j, nTotal, w, n;
14431 const char *colSep = 0;
14432 const char *rowSep = 0;
14433 const unsigned char **azNextLine = 0;
14434 int bNextLine = 0;
14435 int bMultiLineRowExists = 0;
14436 int bw = p->cmOpts.bWordWrap;
14437
14438 rc = sqlite3_step(pStmt);
14439 if( rc!=SQLITE_ROW ) return;
14440 nColumn = sqlite3_column_count(pStmt);
14441 nAlloc = nColumn*4;
14442 if( nAlloc<=0 ) nAlloc = 1;
14443 azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
14444 shell_check_oom(azData);
14445 azNextLine = sqlite3_malloc64( nColumn*sizeof(char*) );
14446 shell_check_oom((void*)azNextLine);
14447 memset((void*)azNextLine, 0, nColumn*sizeof(char*) );
14448 if( p->cmOpts.bQuote ){
14449 azQuoted = sqlite3_malloc64( nColumn*sizeof(char*) );
14450 shell_check_oom(azQuoted);
14451 memset(azQuoted, 0, nColumn*sizeof(char*) );
14452 }
14453 abRowDiv = sqlite3_malloc64( nAlloc/nColumn );
14454 shell_check_oom(abRowDiv);
 
 
 
 
 
14455 if( nColumn>p->nWidth ){
14456 p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int));
14457 shell_check_oom(p->colWidth);
14458 for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
14459 p->nWidth = nColumn;
@@ -14303,10 +14463,56 @@
14463 for(i=0; i<nColumn; i++){
14464 w = p->colWidth[i];
14465 if( w<0 ) w = -w;
14466 p->actualWidth[i] = w;
14467 }
14468 for(i=0; i<nColumn; i++){
14469 const unsigned char *zNotUsed;
14470 int wx = p->colWidth[i];
14471 if( wx==0 ){
14472 wx = p->cmOpts.iWrap;
14473 }
14474 if( wx<0 ) wx = -wx;
14475 uz = (const unsigned char*)sqlite3_column_name(pStmt,i);
14476 azData[i] = translateForDisplayAndDup(uz, &zNotUsed, wx, bw);
14477 }
14478 do{
14479 int useNextLine = bNextLine;
14480 bNextLine = 0;
14481 if( (nRow+2)*nColumn >= nAlloc ){
14482 nAlloc *= 2;
14483 azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
14484 shell_check_oom(azData);
14485 abRowDiv = sqlite3_realloc64(abRowDiv, nAlloc/nColumn);
14486 shell_check_oom(abRowDiv);
14487 }
14488 abRowDiv[nRow] = 1;
14489 nRow++;
14490 for(i=0; i<nColumn; i++){
14491 int wx = p->colWidth[i];
14492 if( wx==0 ){
14493 wx = p->cmOpts.iWrap;
14494 }
14495 if( wx<0 ) wx = -wx;
14496 if( useNextLine ){
14497 uz = azNextLine[i];
14498 }else if( p->cmOpts.bQuote ){
14499 sqlite3_free(azQuoted[i]);
14500 azQuoted[i] = quoted_column(pStmt,i);
14501 uz = (const unsigned char*)azQuoted[i];
14502 }else{
14503 uz = (const unsigned char*)sqlite3_column_text(pStmt,i);
14504 }
14505 azData[nRow*nColumn + i]
14506 = translateForDisplayAndDup(uz, &azNextLine[i], wx, bw);
14507 if( azNextLine[i] ){
14508 bNextLine = 1;
14509 abRowDiv[nRow-1] = 0;
14510 bMultiLineRowExists = 1;
14511 }
14512 }
14513 }while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW );
14514 nTotal = nColumn*(nRow+1);
14515 for(i=0; i<nTotal; i++){
14516 z = azData[i];
14517 if( z==0 ) z = p->nullValue;
14518 n = strlenChar(z);
@@ -14385,10 +14591,19 @@
14591 w = p->actualWidth[j];
14592 if( p->colWidth[j]<0 ) w = -w;
14593 utf8_width_print(p->out, w, z);
14594 if( j==nColumn-1 ){
14595 utf8_printf(p->out, "%s", rowSep);
14596 if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1<nTotal ){
14597 if( p->cMode==MODE_Table ){
14598 print_row_separator(p, nColumn, "+");
14599 }else if( p->cMode==MODE_Box ){
14600 print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
14601 }else if( p->cMode==MODE_Column ){
14602 raw_printf(p->out, "\n");
14603 }
14604 }
14605 j = -1;
14606 if( seenInterrupt ) goto columnar_end;
14607 }else{
14608 utf8_printf(p->out, "%s", colSep);
14609 }
@@ -14403,10 +14618,16 @@
14618 utf8_printf(p->out, "Interrupt\n");
14619 }
14620 nData = (nRow+1)*nColumn;
14621 for(i=0; i<nData; i++) free(azData[i]);
14622 sqlite3_free(azData);
14623 sqlite3_free((void*)azNextLine);
14624 sqlite3_free(abRowDiv);
14625 if( azQuoted ){
14626 for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]);
14627 sqlite3_free(azQuoted);
14628 }
14629 }
14630
14631 /*
14632 ** Run a prepared statement
14633 */
@@ -14655,11 +14876,11 @@
14876 while( zSql[0] && (SQLITE_OK == rc) ){
14877 static const char *zStmtSql;
14878 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
14879 if( SQLITE_OK != rc ){
14880 if( pzErrMsg ){
14881 *pzErrMsg = save_err_msg(db, "in prepare", rc, zSql);
14882 }
14883 }else{
14884 if( !pStmt ){
14885 /* this happens for a comment or white-space */
14886 zSql = zLeftover;
@@ -14771,11 +14992,11 @@
14992 if( rc!=SQLITE_NOMEM ) rc = rc2;
14993 if( rc==SQLITE_OK ){
14994 zSql = zLeftover;
14995 while( IsSpace(zSql[0]) ) zSql++;
14996 }else if( pzErrMsg ){
14997 *pzErrMsg = save_err_msg(db, "stepping", rc, 0);
14998 }
14999
15000 /* clear saved stmt handle */
15001 if( pArg ){
15002 pArg->pStmt = NULL;
@@ -15110,10 +15331,11 @@
15331 #endif
15332 #ifndef SQLITE_OMIT_AUTHORIZATION
15333 ".auth ON|OFF Show authorizer callbacks",
15334 #endif
15335 ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
15336 " Options:",
15337 " --append Use the appendvfs",
15338 " --async Write to FILE without journal and fsync()",
15339 ".bail on|off Stop after hitting an error. Default OFF",
15340 ".binary on|off Turn binary output on or off. Default OFF",
15341 ".cd DIRECTORY Change the working directory to DIRECTORY",
@@ -15180,27 +15402,35 @@
15402 " fkey-indexes Find missing foreign key indexes",
15403 #ifndef SQLITE_OMIT_LOAD_EXTENSION
15404 ".load FILE ?ENTRY? Load an extension library",
15405 #endif
15406 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
15407 ".mode MODE ?OPTIONS? Set output mode",
15408 " MODE is one of:",
15409 " ascii Columns/rows delimited by 0x1F and 0x1E",
15410 " box Tables using unicode box-drawing characters",
15411 " csv Comma-separated values",
15412 " column Output in columns. (See .width)",
15413 " html HTML <table> code",
15414 " insert SQL insert statements for TABLE",
15415 " json Results in a JSON array",
15416 " line One value per line",
15417 " list Values delimited by \"|\"",
15418 " markdown Markdown table format",
15419 " qbox Shorthand for \"box --width 60 --quote\"",
15420 " quote Escape answers as for SQL",
15421 " table ASCII-art table",
15422 " tabs Tab-separated values",
15423 " tcl TCL list elements",
15424 " OPTIONS: (for columnar modes or insert mode):",
15425 " --wrap N Wrap output lines to no longer than N characters",
15426 " --wordwrap B Wrap or not at word boundaries per B (on/off)",
15427 " --ww Shorthand for \"--wordwrap 1\"",
15428 " --quote Quote output text as SQL literals",
15429 " --noquote Do not quote output text",
15430 " TABLE The name of SQL table used for \"insert\" mode",
15431 ".nonce STRING Suspend safe mode for one command if nonce matches",
15432 ".nullvalue STRING Use STRING in place of NULL values",
15433 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
15434 " If FILE begins with '|' then open as a pipe",
15435 " --bom Put a UTF8 byte-order mark at the beginning",
15436 " -e Send output to the system text editor",
@@ -15249,11 +15479,11 @@
15479 " --lost-and-found TABLE Alternative name for the lost-and-found table",
15480 " --no-rowids Do not attempt to recover rowid values",
15481 " that are not also INTEGER PRIMARY KEYs",
15482 #endif
15483 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
15484 ".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)",
15485 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
15486 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
15487 " Options:",
15488 " --indent Try to pretty-print the schema",
15489 " --nosys Omit objects whose names start with \"sqlite_\"",
@@ -15853,12 +16083,14 @@
16083 sqlite3_series_init(p->db, 0, 0);
16084 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
16085 sqlite3_dbdata_init(p->db, 0, 0);
16086 #endif
16087 #ifdef SQLITE_HAVE_ZLIB
16088 if( !p->bSafeModePersist ){
16089 sqlite3_zipfile_init(p->db, 0, 0);
16090 sqlite3_sqlar_init(p->db, 0, 0);
16091 }
16092 #endif
16093 sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
16094 shellAddSchemaName, 0, 0);
16095 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
16096 shellModuleSchema, 0, 0);
@@ -16613,14 +16845,14 @@
16845 }
16846
16847 /*
16848 ** Run an SQL command and return the single integer result.
16849 */
16850 static int db_int(sqlite3 *db, const char *zSql){
16851 sqlite3_stmt *pStmt;
16852 int res = 0;
16853 sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
16854 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
16855 res = sqlite3_column_int(pStmt,0);
16856 }
16857 sqlite3_finalize(pStmt);
16858 return res;
@@ -16721,11 +16953,11 @@
16953 }else{
16954 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
16955 }
16956 for(i=0; i<ArraySize(aQuery); i++){
16957 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
16958 int val = db_int(p->db, zSql);
16959 sqlite3_free(zSql);
16960 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
16961 }
16962 sqlite3_free(zSchemaTab);
16963 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
@@ -18084,10 +18316,11 @@
18316 *pRc = SQLITE_NOMEM;
18317 }
18318 }
18319 return z;
18320 }
18321
18322
18323 /*
18324 ** When running the ".recover" command, each output table, and the special
18325 ** orphaned row table if it is required, is represented by an instance
18326 ** of the following struct.
@@ -18681,10 +18914,225 @@
18914 sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
18915 return rc;
18916 }
18917 #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
18918
18919
18920 /*
18921 * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it.
18922 * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE,
18923 * close db and set it to 0, and return the columns spec, to later
18924 * be sqlite3_free()'ed by the caller.
18925 * The return is 0 when either:
18926 * (a) The db was not initialized and zCol==0 (There are no columns.)
18927 * (b) zCol!=0 (Column was added, db initialized as needed.)
18928 * The 3rd argument, pRenamed, references an out parameter. If the
18929 * pointer is non-zero, its referent will be set to a summary of renames
18930 * done if renaming was necessary, or set to 0 if none was done. The out
18931 * string (if any) must be sqlite3_free()'ed by the caller.
18932 */
18933 #ifdef SHELL_DEBUG
18934 #define rc_err_oom_die(rc) \
18935 if( rc==SQLITE_NOMEM ) shell_check_oom(0); \
18936 else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \
18937 fprintf(stderr,"E:%d\n",rc), assert(0)
18938 #else
18939 static void rc_err_oom_die(int rc){
18940 if( rc==SQLITE_NOMEM ) shell_check_oom(0);
18941 assert(rc==SQLITE_OK||rc==SQLITE_DONE);
18942 }
18943 #endif
18944
18945 #ifdef SHELL_COLFIX_DB /* If this is set, the DB can be in a file. */
18946 static char zCOL_DB[] = SHELL_STRINGIFY(SHELL_COLFIX_DB);
18947 #else /* Otherwise, memory is faster/better for the transient DB. */
18948 static const char *zCOL_DB = ":memory:";
18949 #endif
18950
18951 /* Define character (as C string) to separate generated column ordinal
18952 * from protected part of incoming column names. This defaults to "_"
18953 * so that incoming column identifiers that did not need not be quoted
18954 * remain usable without being quoted. It must be one character.
18955 */
18956 #ifndef SHELL_AUTOCOLUMN_SEP
18957 # define AUTOCOLUMN_SEP "_"
18958 #else
18959 # define AUTOCOLUMN_SEP SHELL_STRINGIFY(SHELL_AUTOCOLUMN_SEP)
18960 #endif
18961
18962 static char *zAutoColumn(const char *zColNew, sqlite3 **pDb, char **pzRenamed){
18963 /* Queries and D{D,M}L used here */
18964 static const char * const zTabMake = "\
18965 CREATE TABLE ColNames(\
18966 cpos INTEGER PRIMARY KEY,\
18967 name TEXT, nlen INT, chop INT, reps INT, suff TEXT);\
18968 CREATE VIEW RepeatedNames AS \
18969 SELECT DISTINCT t.name FROM ColNames t \
18970 WHERE t.name COLLATE NOCASE IN (\
18971 SELECT o.name FROM ColNames o WHERE o.cpos<>t.cpos\
18972 );\
18973 ";
18974 static const char * const zTabFill = "\
18975 INSERT INTO ColNames(name,nlen,chop,reps,suff)\
18976 VALUES(iif(length(?1)>0,?1,'?'),max(length(?1),1),0,0,'')\
18977 ";
18978 static const char * const zHasDupes = "\
18979 SELECT count(DISTINCT (substring(name,1,nlen-chop)||suff) COLLATE NOCASE)\
18980 <count(name) FROM ColNames\
18981 ";
18982 #ifdef SHELL_COLUMN_RENAME_CLEAN
18983 static const char * const zDedoctor = "\
18984 UPDATE ColNames SET chop=iif(\
18985 (substring(name,nlen,1) BETWEEN '0' AND '9')\
18986 AND (rtrim(name,'0123456790') glob '*"AUTOCOLUMN_SEP"'),\
18987 nlen-length(rtrim(name, '"AUTOCOLUMN_SEP"0123456789')),\
18988 0\
18989 )\
18990 ";
18991 #endif
18992 static const char * const zSetReps = "\
18993 UPDATE ColNames AS t SET reps=\
18994 (SELECT count(*) FROM ColNames d \
18995 WHERE substring(t.name,1,t.nlen-t.chop)=substring(d.name,1,d.nlen-d.chop)\
18996 COLLATE NOCASE\
18997 )\
18998 ";
18999 #ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19000 static const char * const zColDigits = "\
19001 SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
19002 ";
19003 #endif
19004 static const char * const zRenameRank =
19005 #ifdef SHELL_COLUMN_RENAME_CLEAN
19006 "UPDATE ColNames AS t SET suff="
19007 "iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')"
19008 #else /* ...RENAME_MINIMAL_ONE_PASS */
19009 "WITH Lzn(nlz) AS (" /* Find minimum extraneous leading 0's for uniqueness */
19010 " SELECT 0 AS nlz"
19011 " UNION"
19012 " SELECT nlz+1 AS nlz FROM Lzn"
19013 " WHERE EXISTS("
19014 " SELECT 1"
19015 " FROM ColNames t, ColNames o"
19016 " WHERE"
19017 " iif(t.name IN (SELECT * FROM RepeatedNames),"
19018 " printf('%s"AUTOCOLUMN_SEP"%s',"
19019 " t.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,t.cpos),2)),"
19020 " t.name"
19021 " )"
19022 " ="
19023 " iif(o.name IN (SELECT * FROM RepeatedNames),"
19024 " printf('%s"AUTOCOLUMN_SEP"%s',"
19025 " o.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,o.cpos),2)),"
19026 " o.name"
19027 " )"
19028 " COLLATE NOCASE"
19029 " AND o.cpos<>t.cpos"
19030 " GROUP BY t.cpos"
19031 " )"
19032 ") UPDATE Colnames AS t SET"
19033 " chop = 0," /* No chopping, never touch incoming names. */
19034 " suff = iif(name IN (SELECT * FROM RepeatedNames),"
19035 " printf('"AUTOCOLUMN_SEP"%s', substring("
19036 " printf('%.*c%0.*d',(SELECT max(nlz) FROM Lzn)+1,'0',1,t.cpos),2)),"
19037 " ''"
19038 " )"
19039 #endif
19040 ;
19041 static const char * const zCollectVar = "\
19042 SELECT\
19043 '('||x'0a'\
19044 || group_concat(\
19045 cname||' TEXT',\
19046 ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
19047 ||')' AS ColsSpec \
19048 FROM (\
19049 SELECT cpos, printf('\"%w\"',printf('%.*s%s', nlen-chop,name,suff)) AS cname \
19050 FROM ColNames ORDER BY cpos\
19051 )";
19052 static const char * const zRenamesDone =
19053 "SELECT group_concat("
19054 " printf('\"%w\" to \"%w\"',name,printf('%.*s%s', nlen-chop, name, suff)),"
19055 " ','||x'0a')"
19056 "FROM ColNames WHERE suff<>'' OR chop!=0"
19057 ;
19058 int rc;
19059 sqlite3_stmt *pStmt = 0;
19060 assert(pDb!=0);
19061 if( zColNew ){
19062 /* Add initial or additional column. Init db if necessary. */
19063 if( *pDb==0 ){
19064 if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0;
19065 #ifdef SHELL_COLFIX_DB
19066 if(*zCOL_DB!=':')
19067 sqlite3_exec(*pDb,"drop table if exists ColNames;"
19068 "drop view if exists RepeatedNames;",0,0,0);
19069 #endif
19070 rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0);
19071 rc_err_oom_die(rc);
19072 }
19073 assert(*pDb!=0);
19074 rc = sqlite3_prepare_v2(*pDb, zTabFill, -1, &pStmt, 0);
19075 rc_err_oom_die(rc);
19076 rc = sqlite3_bind_text(pStmt, 1, zColNew, -1, 0);
19077 rc_err_oom_die(rc);
19078 rc = sqlite3_step(pStmt);
19079 rc_err_oom_die(rc);
19080 sqlite3_finalize(pStmt);
19081 return 0;
19082 }else if( *pDb==0 ){
19083 return 0;
19084 }else{
19085 /* Formulate the columns spec, close the DB, zero *pDb. */
19086 char *zColsSpec = 0;
19087 int hasDupes = db_int(*pDb, zHasDupes);
19088 #ifdef SQLITE_ENABLE_MATH_FUNCTIONS
19089 int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
19090 #else
19091 # define nDigits 2
19092 #endif
19093 if( hasDupes ){
19094 #ifdef SHELL_COLUMN_RENAME_CLEAN
19095 rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
19096 rc_err_oom_die(rc);
19097 #endif
19098 rc = sqlite3_exec(*pDb, zSetReps, 0, 0, 0);
19099 rc_err_oom_die(rc);
19100 rc = sqlite3_prepare_v2(*pDb, zRenameRank, -1, &pStmt, 0);
19101 rc_err_oom_die(rc);
19102 sqlite3_bind_int(pStmt, 1, nDigits);
19103 rc = sqlite3_step(pStmt);
19104 sqlite3_finalize(pStmt);
19105 assert(rc==SQLITE_DONE);
19106 }
19107 assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */
19108 rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0);
19109 rc_err_oom_die(rc);
19110 rc = sqlite3_step(pStmt);
19111 if( rc==SQLITE_ROW ){
19112 zColsSpec = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
19113 }else{
19114 zColsSpec = 0;
19115 }
19116 if( pzRenamed!=0 ){
19117 if( !hasDupes ) *pzRenamed = 0;
19118 else{
19119 sqlite3_finalize(pStmt);
19120 if( SQLITE_OK==sqlite3_prepare_v2(*pDb, zRenamesDone, -1, &pStmt, 0)
19121 && SQLITE_ROW==sqlite3_step(pStmt) ){
19122 *pzRenamed = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
19123 }else
19124 *pzRenamed = 0;
19125 }
19126 }
19127 sqlite3_finalize(pStmt);
19128 sqlite3_close(*pDb);
19129 *pDb = 0;
19130 return zColsSpec;
19131 }
19132 }
19133
19134 /*
19135 ** If an input line begins with "." then invoke this routine to
19136 ** process that line.
19137 **
19138 ** Return 1 on error, 2 to exit, and 0 otherwise.
@@ -19467,24 +19915,26 @@
19915 }
19916 }else
19917
19918 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
19919 char *zTable = 0; /* Insert data into this table */
19920 char *zSchema = 0; /* within this schema (may default to "main") */
19921 char *zFile = 0; /* Name of file to extra content from */
19922 sqlite3_stmt *pStmt = NULL; /* A statement */
19923 int nCol; /* Number of columns in the table */
19924 int nByte; /* Number of bytes in an SQL string */
19925 int i, j; /* Loop counters */
19926 int needCommit; /* True to COMMIT or ROLLBACK at end */
19927 int nSep; /* Number of bytes in p->colSeparator[] */
19928 char *zSql; /* An SQL statement */
19929 char *zFullTabName; /* Table name with schema if applicable */
19930 ImportCtx sCtx; /* Reader context */
19931 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
19932 int eVerbose = 0; /* Larger for more console output */
19933 int nSkip = 0; /* Initial lines to skip */
19934 int useOutputMode = 1; /* Use output mode to determine separators */
19935 char *zCreate = 0; /* CREATE TABLE statement text */
19936
19937 failIfSafeMode(p, "cannot run .import in safe mode");
19938 memset(&sCtx, 0, sizeof(sCtx));
19939 sCtx.z = sqlite3_malloc64(120);
19940 if( sCtx.z==0 ){
@@ -19603,11 +20053,10 @@
20053 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
20054 rc = 1;
20055 import_cleanup(&sCtx);
20056 goto meta_command_exit;
20057 }
 
20058 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
20059 char zSep[2];
20060 zSep[1] = 0;
20061 zSep[0] = sCtx.cColSep;
20062 utf8_printf(p->out, "Column separator ");
@@ -19615,71 +20064,83 @@
20064 utf8_printf(p->out, ", row separator ");
20065 zSep[0] = sCtx.cRowSep;
20066 output_c_string(p->out, zSep);
20067 utf8_printf(p->out, "\n");
20068 }
20069 /* Below, resources must be freed before exit. */
20070 while( (nSkip--)>0 ){
20071 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
20072 }
20073 if( zSchema!=0 ){
20074 zFullTabName = sqlite3_mprintf("\"%w\".\"%w\"", zSchema, zTable);
20075 }else{
20076 zFullTabName = sqlite3_mprintf("\"%w\"", zTable);
20077 }
20078 zSql = sqlite3_mprintf("SELECT * FROM %s", zFullTabName);
20079 if( zSql==0 || zFullTabName==0 ){
20080 import_cleanup(&sCtx);
20081 shell_out_of_memory();
20082 }
20083 nByte = strlen30(zSql);
20084 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
20085 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
20086 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
20087 sqlite3 *dbCols = 0;
20088 char *zRenames = 0;
20089 char *zColDefs;
20090 zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName);
20091 while( xRead(&sCtx) ){
20092 zAutoColumn(sCtx.z, &dbCols, 0);
 
20093 if( sCtx.cTerm!=sCtx.cColSep ) break;
20094 }
20095 zColDefs = zAutoColumn(0, &dbCols, &zRenames);
20096 if( zRenames!=0 ){
20097 utf8_printf((stdin_is_interactive && p->in==stdin)? p->out : stderr,
20098 "Columns renamed during .import %s due to duplicates:\n"
20099 "%s\n", sCtx.zFile, zRenames);
20100 sqlite3_free(zRenames);
20101 }
20102 assert(dbCols==0);
20103 if( zColDefs==0 ){
20104 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
20105 import_fail:
20106 sqlite3_free(zCreate);
20107 sqlite3_free(zSql);
20108 sqlite3_free(zFullTabName);
20109 import_cleanup(&sCtx);
20110 rc = 1;
20111 goto meta_command_exit;
20112 }
20113 zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
20114 if( eVerbose>=1 ){
20115 utf8_printf(p->out, "%s\n", zCreate);
20116 }
20117 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
20118 if( rc ){
20119 utf8_printf(stderr, "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
20120 goto import_fail;
 
 
 
20121 }
20122 sqlite3_free(zCreate);
20123 zCreate = 0;
20124 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
20125 }
 
20126 if( rc ){
20127 if (pStmt) sqlite3_finalize(pStmt);
20128 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
20129 goto import_fail;
 
 
20130 }
20131 sqlite3_free(zSql);
20132 nCol = sqlite3_column_count(pStmt);
20133 sqlite3_finalize(pStmt);
20134 pStmt = 0;
20135 if( nCol==0 ) return 0; /* no columns, no error */
20136 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
20137 if( zSql==0 ){
20138 import_cleanup(&sCtx);
20139 shell_out_of_memory();
20140 }
20141 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zFullTabName);
 
20142 j = strlen30(zSql);
20143 for(i=1; i<nCol; i++){
20144 zSql[j++] = ',';
20145 zSql[j++] = '?';
20146 }
@@ -19687,18 +20148,17 @@
20148 zSql[j] = 0;
20149 if( eVerbose>=2 ){
20150 utf8_printf(p->out, "Insert using: %s\n", zSql);
20151 }
20152 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
 
20153 if( rc ){
20154 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
20155 if (pStmt) sqlite3_finalize(pStmt);
20156 goto import_fail;
 
 
20157 }
20158 sqlite3_free(zSql);
20159 sqlite3_free(zFullTabName);
20160 needCommit = sqlite3_get_autocommit(p->db);
20161 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
20162 do{
20163 int startLine = sCtx.nLine;
20164 for(i=0; i<nCol; i++){
@@ -19976,68 +20436,127 @@
20436 p->pLog = output_file_open(zFile, 0);
20437 }
20438 }else
20439
20440 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
20441 const char *zMode = 0;
20442 const char *zTabname = 0;
20443 int i, n2;
20444 ColModeOpts cmOpts = ColModeOpts_default;
20445 for(i=1; i<nArg; i++){
20446 const char *z = azArg[i];
20447 if( optionMatch(z,"wrap") && i+1<nArg ){
20448 cmOpts.iWrap = integerValue(azArg[++i]);
20449 }else if( optionMatch(z,"ww") ){
20450 cmOpts.bWordWrap = 1;
20451 }else if( optionMatch(z,"wordwrap") && i+1<nArg ){
20452 cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]);
20453 }else if( optionMatch(z,"quote") ){
20454 cmOpts.bQuote = 1;
20455 }else if( optionMatch(z,"noquote") ){
20456 cmOpts.bQuote = 0;
20457 }else if( zMode==0 ){
20458 zMode = z;
20459 /* Apply defaults for qbox pseudo-mods. If that
20460 * overwrites already-set values, user was informed of this.
20461 */
20462 if( strcmp(z, "qbox")==0 ){
20463 ColModeOpts cmo = ColModeOpts_default_qbox;
20464 zMode = "box";
20465 cmOpts = cmo;
20466 }
20467 }else if( zTabname==0 ){
20468 zTabname = z;
20469 }else if( z[0]=='-' ){
20470 utf8_printf(stderr, "unknown option: %s\n", z);
20471 utf8_printf(stderr, "options:\n"
20472 " --noquote\n"
20473 " --quote\n"
20474 " --wordwrap on/off\n"
20475 " --wrap N\n"
20476 " --ww\n");
20477 rc = 1;
20478 goto meta_command_exit;
20479 }else{
20480 utf8_printf(stderr, "extra argument: \"%s\"\n", z);
20481 rc = 1;
20482 goto meta_command_exit;
20483 }
20484 }
20485 if( zMode==0 ){
20486 if( p->mode==MODE_Column
20487 || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
20488 ){
20489 raw_printf
20490 (p->out,
20491 "current output mode: %s --wrap %d --wordwrap %s --%squote\n",
20492 modeDescr[p->mode], p->cmOpts.iWrap,
20493 p->cmOpts.bWordWrap ? "on" : "off",
20494 p->cmOpts.bQuote ? "" : "no");
20495 }else{
20496 raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
20497 }
20498 zMode = modeDescr[p->mode];
20499 }
20500 n2 = strlen30(zMode);
20501 if( strncmp(zMode,"lines",n2)==0 ){
20502 p->mode = MODE_Line;
20503 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20504 }else if( strncmp(zMode,"columns",n2)==0 ){
20505 p->mode = MODE_Column;
20506 if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
20507 p->showHeader = 1;
20508 }
20509 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20510 p->cmOpts = cmOpts;
20511 }else if( strncmp(zMode,"list",n2)==0 ){
20512 p->mode = MODE_List;
20513 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
20514 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20515 }else if( strncmp(zMode,"html",n2)==0 ){
20516 p->mode = MODE_Html;
20517 }else if( strncmp(zMode,"tcl",n2)==0 ){
20518 p->mode = MODE_Tcl;
20519 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
20520 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20521 }else if( strncmp(zMode,"csv",n2)==0 ){
20522 p->mode = MODE_Csv;
20523 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
20524 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
20525 }else if( strncmp(zMode,"tabs",n2)==0 ){
20526 p->mode = MODE_List;
20527 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
20528 }else if( strncmp(zMode,"insert",n2)==0 ){
20529 p->mode = MODE_Insert;
20530 set_table_name(p, zTabname ? zTabname : "table");
20531 }else if( strncmp(zMode,"quote",n2)==0 ){
20532 p->mode = MODE_Quote;
20533 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
20534 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
20535 }else if( strncmp(zMode,"ascii",n2)==0 ){
20536 p->mode = MODE_Ascii;
20537 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
20538 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
20539 }else if( strncmp(zMode,"markdown",n2)==0 ){
20540 p->mode = MODE_Markdown;
20541 p->cmOpts = cmOpts;
20542 }else if( strncmp(zMode,"table",n2)==0 ){
20543 p->mode = MODE_Table;
20544 p->cmOpts = cmOpts;
20545 }else if( strncmp(zMode,"box",n2)==0 ){
20546 p->mode = MODE_Box;
20547 p->cmOpts = cmOpts;
20548 }else if( strncmp(zMode,"count",n2)==0 ){
20549 p->mode = MODE_Count;
20550 }else if( strncmp(zMode,"off",n2)==0 ){
20551 p->mode = MODE_Off;
20552 }else if( strncmp(zMode,"json",n2)==0 ){
20553 p->mode = MODE_Json;
 
 
20554 }else{
20555 raw_printf(stderr, "Error: mode should be one of: "
20556 "ascii box column csv html insert json line list markdown "
20557 "qbox quote table tabs tcl\n");
20558 rc = 1;
20559 }
20560 p->cMode = p->mode;
20561 }else
20562
@@ -20158,13 +20677,14 @@
20677 ){
20678 char *zFile = 0;
20679 int bTxtMode = 0;
20680 int i;
20681 int eMode = 0;
20682 int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
20683 unsigned char zBOM[4]; /* Byte-order mark to using if --bom is present */
20684
20685 zBOM[0] = 0;
20686 failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
20687 if( c=='e' ){
20688 eMode = 'x';
20689 bOnce = 2;
20690 }else if( strncmp(azArg[0],"once",n)==0 ){
@@ -20173,11 +20693,14 @@
20693 for(i=1; i<nArg; i++){
20694 char *z = azArg[i];
20695 if( z[0]=='-' ){
20696 if( z[1]=='-' ) z++;
20697 if( strcmp(z,"-bom")==0 ){
20698 zBOM[0] = 0xef;
20699 zBOM[1] = 0xbb;
20700 zBOM[2] = 0xbf;
20701 zBOM[3] = 0;
20702 }else if( c!='e' && strcmp(z,"-x")==0 ){
20703 eMode = 'x'; /* spreadsheet */
20704 }else if( c!='e' && strcmp(z,"-e")==0 ){
20705 eMode = 'e'; /* text editor */
20706 }else{
@@ -20242,11 +20765,11 @@
20765 if( p->out==0 ){
20766 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
20767 p->out = stdout;
20768 rc = 1;
20769 }else{
20770 if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out);
20771 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
20772 }
20773 #endif
20774 }else{
20775 p->out = output_file_open(zFile, bTxtMode);
@@ -20255,11 +20778,11 @@
20778 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
20779 }
20780 p->out = stdout;
20781 rc = 1;
20782 } else {
20783 if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out);
20784 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
20785 }
20786 }
20787 sqlite3_free(zFile);
20788 }else
@@ -21181,11 +21704,21 @@
21704 azBool[ShellHasFlag(p, SHFLG_Echo)]);
21705 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
21706 utf8_printf(p->out, "%12.12s: %s\n","explain",
21707 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
21708 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
21709 if( p->mode==MODE_Column
21710 || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
21711 ){
21712 utf8_printf
21713 (p->out, "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode",
21714 modeDescr[p->mode], p->cmOpts.iWrap,
21715 p->cmOpts.bWordWrap ? "on" : "off",
21716 p->cmOpts.bQuote ? "" : "no");
21717 }else{
21718 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
21719 }
21720 utf8_printf(p->out, "%12.12s: ", "nullvalue");
21721 output_c_string(p->out, p->nullValue);
21722 raw_printf(p->out, "\n");
21723 utf8_printf(p->out,"%12.12s: %s\n","output",
21724 strlen30(p->outfile) ? p->outfile : "stdout");
@@ -21979,23 +22512,34 @@
22512 BEGIN_TIMER;
22513 rc = shell_exec(p, zSql, &zErrMsg);
22514 END_TIMER;
22515 if( rc || zErrMsg ){
22516 char zPrefix[100];
22517 const char *zErrorTail;
22518 const char *zErrorType;
22519 if( zErrMsg==0 ){
22520 zErrorType = "Error";
22521 zErrorTail = sqlite3_errmsg(p->db);
22522 }else if( strncmp(zErrMsg, "in prepare, ",12)==0 ){
22523 zErrorType = "Parse error";
22524 zErrorTail = &zErrMsg[12];
22525 }else if( strncmp(zErrMsg, "stepping, ", 10)==0 ){
22526 zErrorType = "Runtime error";
22527 zErrorTail = &zErrMsg[10];
22528 }else{
22529 zErrorType = "Error";
22530 zErrorTail = zErrMsg;
22531 }
22532 if( in!=0 || !stdin_is_interactive ){
22533 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
22534 "%s near line %d:", zErrorType, startline);
22535 }else{
22536 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType);
22537 }
22538 utf8_printf(stderr, "%s %s\n", zPrefix, zErrorTail);
22539 sqlite3_free(zErrMsg);
22540 zErrMsg = 0;
 
 
 
 
22541 return 1;
22542 }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
22543 char zLineBuf[2000];
22544 sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
22545 "changes: %lld total_changes: %lld",
@@ -22108,11 +22652,12 @@
22652 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
22653 nSql = 0;
22654 qss = QSS_Start;
22655 }
22656 }
22657 if( nSql ){
22658 /* This may be incomplete. Let the SQL parser deal with that. */
22659 errCnt += runOneSqlLine(p, zSql, p->in, startline);
22660 }
22661 free(zSql);
22662 free(zLine);
22663 --p->inputNesting;
22664
+2271 -1115
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
11
/******************************************************************************
22
** This file is an amalgamation of many separate C source files from SQLite
3
-** version 3.38.0. By combining all the individual C code files into this
3
+** version 3.39.0. By combining all the individual C code files into this
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -450,13 +450,13 @@
450450
**
451451
** See also: [sqlite3_libversion()],
452452
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453453
** [sqlite_version()] and [sqlite_source_id()].
454454
*/
455
-#define SQLITE_VERSION "3.38.0"
456
-#define SQLITE_VERSION_NUMBER 3038000
457
-#define SQLITE_SOURCE_ID "2022-01-25 00:03:25 a8db69411b0d1275909adeb21027784ada17af24efe3a59ae0ae2a897659ff17"
455
+#define SQLITE_VERSION "3.39.0"
456
+#define SQLITE_VERSION_NUMBER 3039000
457
+#define SQLITE_SOURCE_ID "2022-04-01 17:23:17 a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c"
458458
459459
/*
460460
** CAPI3REF: Run-Time Library Version Numbers
461461
** KEYWORDS: sqlite3_version sqlite3_sourceid
462462
**
@@ -870,11 +870,11 @@
870870
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
871871
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
872872
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
873873
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
874874
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
875
-#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
875
+#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
876876
877877
/*
878878
** CAPI3REF: Flags For File Open Operations
879879
**
880880
** These bit values are intended for use in the
@@ -4154,11 +4154,11 @@
41544154
**
41554155
** ^If the most recent error references a specific token in the input
41564156
** SQL, the sqlite3_error_offset() interface returns the byte offset
41574157
** of the start of that token. ^The byte offset returned by
41584158
** sqlite3_error_offset() assumes that the input SQL is UTF8.
4159
-** ^If the most error does not reference a specific token in the input
4159
+** ^If the most recent error does not reference a specific token in the input
41604160
** SQL, then the sqlite3_error_offset() function returns -1.
41614161
**
41624162
** When the serialized [threading mode] is in use, it might be the
41634163
** case that a second error occurs on a separate thread in between
41644164
** the time of the first error and the call to these interfaces.
@@ -4588,10 +4588,14 @@
45884588
** ^For example, an UPDATE statement might have a WHERE clause that
45894589
** makes it a no-op, but the sqlite3_stmt_readonly() result would still
45904590
** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
45914591
** read-only no-op if the table already exists, but
45924592
** sqlite3_stmt_readonly() still returns false for such a statement.
4593
+**
4594
+** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN]
4595
+** statement, then sqlite3_stmt_readonly(X) returns the same value as
4596
+** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted.
45934597
*/
45944598
SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
45954599
45964600
/*
45974601
** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4656,10 +4660,12 @@
46564660
** still make the distinction between protected and unprotected
46574661
** sqlite3_value objects even when not strictly required.
46584662
**
46594663
** ^The sqlite3_value objects that are passed as parameters into the
46604664
** implementation of [application-defined SQL functions] are protected.
4665
+** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
4666
+** are protected.
46614667
** ^The sqlite3_value object returned by
46624668
** [sqlite3_column_value()] is unprotected.
46634669
** Unprotected sqlite3_value objects may only be used as arguments
46644670
** to [sqlite3_result_value()], [sqlite3_bind_value()], and
46654671
** [sqlite3_value_dup()].
@@ -5276,10 +5282,14 @@
52765282
** bytes in the string, not the number of characters.
52775283
**
52785284
** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
52795285
** even empty strings, are always zero-terminated. ^The return
52805286
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
5287
+**
5288
+** ^Strings returned by sqlite3_column_text16() always have the endianness
5289
+** which is native to the platform, regardless of the text encoding set
5290
+** for the database.
52815291
**
52825292
** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
52835293
** [unprotected sqlite3_value] object. In a multithreaded environment,
52845294
** an unprotected sqlite3_value object may only be used safely with
52855295
** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -5290,11 +5300,11 @@
52905300
** Hence, the sqlite3_column_value() interface
52915301
** is normally only useful within the implementation of
52925302
** [application-defined SQL functions] or [virtual tables], not within
52935303
** top-level application code.
52945304
**
5295
-** The these routines may attempt to convert the datatype of the result.
5305
+** These routines may attempt to convert the datatype of the result.
52965306
** ^For example, if the internal representation is FLOAT and a text result
52975307
** is requested, [sqlite3_snprintf()] is used internally to perform the
52985308
** conversion automatically. ^(The following table details the conversions
52995309
** that are applied:
53005310
**
@@ -5315,11 +5325,11 @@
53155325
** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
53165326
** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
53175327
** <tr><td> TEXT <td> BLOB <td> No change
53185328
** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
53195329
** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5320
-** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
5330
+** <tr><td> BLOB <td> TEXT <td> [CAST] to TEXT, ensure zero terminator
53215331
** </table>
53225332
** </blockquote>)^
53235333
**
53245334
** Note that when type conversions occur, pointers returned by prior
53255335
** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5887,11 +5897,12 @@
58875897
**
58885898
** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
58895899
** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
58905900
** is a [protected sqlite3_value] object even if the input is not.
58915901
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5892
-** memory allocation fails.
5902
+** memory allocation fails. ^If V is a [pointer value], then the result
5903
+** of sqlite3_value_dup(V) is a NULL value.
58935904
**
58945905
** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
58955906
** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
58965907
** then sqlite3_value_free(V) is a harmless no-op.
58975908
*/
@@ -7435,28 +7446,60 @@
74357446
/*
74367447
** CAPI3REF: Virtual Table Constraint Operator Codes
74377448
**
74387449
** These macros define the allowed values for the
74397450
** [sqlite3_index_info].aConstraint[].op field. Each value represents
7440
-** an operator that is part of a constraint term in the wHERE clause of
7451
+** an operator that is part of a constraint term in the WHERE clause of
74417452
** a query that uses a [virtual table].
7453
+**
7454
+** ^The left-hand operand of the operator is given by the corresponding
7455
+** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand
7456
+** operand is the rowid.
7457
+** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
7458
+** operators have no left-hand operand, and so for those operators the
7459
+** corresponding aConstraint[].iColumn is meaningless and should not be
7460
+** used.
7461
+**
7462
+** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through
7463
+** value 255 are reserved to represent functions that are overloaded
7464
+** by the [xFindFunction|xFindFunction method] of the virtual table
7465
+** implementation.
7466
+**
7467
+** The right-hand operands for each constraint might be accessible using
7468
+** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand
7469
+** operand is only available if it appears as a single constant literal
7470
+** in the input SQL. If the right-hand operand is another column or an
7471
+** expression (even a constant expression) or a parameter, then the
7472
+** sqlite3_vtab_rhs_value() probably will not be able to extract it.
7473
+** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and
7474
+** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand
7475
+** and hence calls to sqlite3_vtab_rhs_value() for those operators will
7476
+** always return SQLITE_NOTFOUND.
7477
+**
7478
+** The collating sequence to be used for comparison can be found using
7479
+** the [sqlite3_vtab_collation()] interface. For most real-world virtual
7480
+** tables, the collating sequence of constraints does not matter (for example
7481
+** because the constraints are numeric) and so the sqlite3_vtab_collation()
7482
+** interface is no commonly needed.
74427483
*/
7443
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
7444
-#define SQLITE_INDEX_CONSTRAINT_GT 4
7445
-#define SQLITE_INDEX_CONSTRAINT_LE 8
7446
-#define SQLITE_INDEX_CONSTRAINT_LT 16
7447
-#define SQLITE_INDEX_CONSTRAINT_GE 32
7448
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
7449
-#define SQLITE_INDEX_CONSTRAINT_LIKE 65
7450
-#define SQLITE_INDEX_CONSTRAINT_GLOB 66
7451
-#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7452
-#define SQLITE_INDEX_CONSTRAINT_NE 68
7453
-#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7454
-#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7455
-#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7456
-#define SQLITE_INDEX_CONSTRAINT_IS 72
7457
-#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
7484
+#define SQLITE_INDEX_CONSTRAINT_EQ 2
7485
+#define SQLITE_INDEX_CONSTRAINT_GT 4
7486
+#define SQLITE_INDEX_CONSTRAINT_LE 8
7487
+#define SQLITE_INDEX_CONSTRAINT_LT 16
7488
+#define SQLITE_INDEX_CONSTRAINT_GE 32
7489
+#define SQLITE_INDEX_CONSTRAINT_MATCH 64
7490
+#define SQLITE_INDEX_CONSTRAINT_LIKE 65
7491
+#define SQLITE_INDEX_CONSTRAINT_GLOB 66
7492
+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7493
+#define SQLITE_INDEX_CONSTRAINT_NE 68
7494
+#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7495
+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7496
+#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7497
+#define SQLITE_INDEX_CONSTRAINT_IS 72
7498
+#define SQLITE_INDEX_CONSTRAINT_LIMIT 73
7499
+#define SQLITE_INDEX_CONSTRAINT_OFFSET 74
7500
+#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
74587501
74597502
/*
74607503
** CAPI3REF: Register A Virtual Table Implementation
74617504
** METHOD: sqlite3
74627505
**
@@ -7481,11 +7524,11 @@
74817524
** ^The sqlite3_create_module()
74827525
** interface is equivalent to sqlite3_create_module_v2() with a NULL
74837526
** destructor.
74847527
**
74857528
** ^If the third parameter (the pointer to the sqlite3_module object) is
7486
-** NULL then no new module is create and any existing modules with the
7529
+** NULL then no new module is created and any existing modules with the
74877530
** same name are dropped.
74887531
**
74897532
** See also: [sqlite3_drop_modules()]
74907533
*/
74917534
SQLITE_API int sqlite3_create_module(
@@ -9812,28 +9855,29 @@
98129855
98139856
/*
98149857
** CAPI3REF: Determine if a virtual table query is DISTINCT
98159858
** METHOD: sqlite3_index_info
98169859
**
9817
-** This API may only be used from within an xBestIndex() callback. The
9818
-** results of calling it from outside of an xBestIndex() callback are
9819
-** undefined and probably harmful.
9860
+** This API may only be used from within an [xBestIndex|xBestIndex method]
9861
+** of a [virtual table] implementation. The result of calling this
9862
+** interface from outside of xBestIndex() is undefined and probably harmful.
98209863
**
9821
-** ^The sqlite3_vtab_distinct() returns an integer that is either 0, 1, or
9822
-** 2. The integer returned by sqlite3_vtab_distinct() gives the virtual table
9823
-** additional information about how the query planner wants the output to be
9824
-** ordered. As long as the virtual table can meet the ordering requirements
9825
-** of the query planner, it may set the "orderByConsumed" flag.
9864
+** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and
9865
+** 3. The integer returned by sqlite3_vtab_distinct()
9866
+** gives the virtual table additional information about how the query
9867
+** planner wants the output to be ordered. As long as the virtual table
9868
+** can meet the ordering requirements of the query planner, it may set
9869
+** the "orderByConsumed" flag.
98269870
**
98279871
** <ol><li value="0"><p>
98289872
** ^If the sqlite3_vtab_distinct() interface returns 0, that means
98299873
** that the query planner needs the virtual table to return all rows in the
98309874
** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
98319875
** [sqlite3_index_info] object. This is the default expectation. If the
98329876
** virtual table outputs all rows in sorted order, then it is always safe for
98339877
** the xBestIndex method to set the "orderByConsumed" flag, regardless of
9834
-** what the return value from sqlite3_vtab_distinct().
9878
+** the return value from sqlite3_vtab_distinct().
98359879
** <li value="1"><p>
98369880
** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
98379881
** that the query planner does not need the rows to be returned in sorted order
98389882
** as long as all rows with the same values in all columns identified by the
98399883
** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
@@ -9842,16 +9886,23 @@
98429886
** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
98439887
** that the query planner does not need the rows returned in any particular
98449888
** order, as long as rows with the same values in all "aOrderBy" columns
98459889
** are adjacent.)^ ^(Furthermore, only a single row for each particular
98469890
** combination of values in the columns identified by the "aOrderBy" field
9847
-** needs to be returned.)^ ^It is ok always for two or more rows with the same
9891
+** needs to be returned.)^ ^It is always ok for two or more rows with the same
98489892
** values in all "aOrderBy" columns to be returned, as long as all such rows
98499893
** are adjacent. ^The virtual table may, if it chooses, omit extra rows
98509894
** that have the same value for all columns identified by "aOrderBy".
98519895
** ^However omitting the extra rows is optional.
98529896
** This mode is used for a DISTINCT query.
9897
+** <li value="3"><p>
9898
+** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
9899
+** that the query planner needs only distinct rows but it does need the
9900
+** rows to be sorted.)^ ^The virtual table implementation is free to omit
9901
+** rows that are identical in all aOrderBy columns, if it wants to, but
9902
+** it is not required to omit any rows. This mode is used for queries
9903
+** that have both DISTINCT and ORDER BY clauses.
98539904
** </ol>
98549905
**
98559906
** ^For the purposes of comparing virtual table output values to see if the
98569907
** values are same value for sorting purposes, two NULL values are considered
98579908
** to be the same. In other words, the comparison operator is "IS"
@@ -9873,35 +9924,171 @@
98739924
** valid to do so, on the other hand, might cause SQLite to return incorrect
98749925
** results.
98759926
*/
98769927
SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
98779928
9929
+/*
9930
+** CAPI3REF: Identify and handle IN constraints in xBestIndex
9931
+**
9932
+** This interface may only be used from within an
9933
+** [xBestIndex|xBestIndex() method] of a [virtual table] implementation.
9934
+** The result of invoking this interface from any other context is
9935
+** undefined and probably harmful.
9936
+**
9937
+** ^(A constraint on a virtual table of the form
9938
+** "[IN operator|column IN (...)]" is
9939
+** communicated to the xBestIndex method as a
9940
+** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
9941
+** this constraint, it must set the corresponding
9942
+** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
9943
+** the usual mode of handling IN operators, SQLite generates [bytecode]
9944
+** that invokes the [xFilter|xFilter() method] once for each value
9945
+** on the right-hand side of the IN operator.)^ Thus the virtual table
9946
+** only sees a single value from the right-hand side of the IN operator
9947
+** at a time.
9948
+**
9949
+** In some cases, however, it would be advantageous for the virtual
9950
+** table to see all values on the right-hand of the IN operator all at
9951
+** once. The sqlite3_vtab_in() interfaces facilitates this in two ways:
9952
+**
9953
+** <ol>
9954
+** <li><p>
9955
+** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero)
9956
+** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint
9957
+** is an [IN operator] that can be processed all at once. ^In other words,
9958
+** sqlite3_vtab_in() with -1 in the third argument is a mechanism
9959
+** by which the virtual table can ask SQLite if all-at-once processing
9960
+** of the IN operator is even possible.
9961
+**
9962
+** <li><p>
9963
+** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates
9964
+** to SQLite that the virtual table does or does not want to process
9965
+** the IN operator all-at-once, respectively. ^Thus when the third
9966
+** parameter (F) is non-negative, this interface is the mechanism by
9967
+** which the virtual table tells SQLite how it wants to process the
9968
+** IN operator.
9969
+** </ol>
9970
+**
9971
+** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times
9972
+** within the same xBestIndex method call. ^For any given P,N pair,
9973
+** the return value from sqlite3_vtab_in(P,N,F) will always be the same
9974
+** within the same xBestIndex call. ^If the interface returns true
9975
+** (non-zero), that means that the constraint is an IN operator
9976
+** that can be processed all-at-once. ^If the constraint is not an IN
9977
+** operator or cannot be processed all-at-once, then the interface returns
9978
+** false.
9979
+**
9980
+** ^(All-at-once processing of the IN operator is selected if both of the
9981
+** following conditions are met:
9982
+**
9983
+** <ol>
9984
+** <li><p> The P->aConstraintUsage[N].argvIndex value is set to a positive
9985
+** integer. This is how the virtual table tells SQLite that it wants to
9986
+** use the N-th constraint.
9987
+**
9988
+** <li><p> The last call to sqlite3_vtab_in(P,N,F) for which F was
9989
+** non-negative had F>=1.
9990
+** </ol>)^
9991
+**
9992
+** ^If either or both of the conditions above are false, then SQLite uses
9993
+** the traditional one-at-a-time processing strategy for the IN constraint.
9994
+** ^If both conditions are true, then the argvIndex-th parameter to the
9995
+** xFilter method will be an [sqlite3_value] that appears to be NULL,
9996
+** but which can be passed to [sqlite3_vtab_in_first()] and
9997
+** [sqlite3_vtab_in_next()] to find all values on the right-hand side
9998
+** of the IN constraint.
9999
+*/
10000
+SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
10001
+
10002
+/*
10003
+** CAPI3REF: Find all elements on the right-hand side of an IN constraint.
10004
+**
10005
+** These interfaces are only useful from within the
10006
+** [xFilter|xFilter() method] of a [virtual table] implementation.
10007
+** The result of invoking these interfaces from any other context
10008
+** is undefined and probably harmful.
10009
+**
10010
+** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
10011
+** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
10012
+** xFilter method which invokes these routines, and specifically
10013
+** a parameter that was previously selected for all-at-once IN constraint
10014
+** processing use the [sqlite3_vtab_in()] interface in the
10015
+** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
10016
+** an xFilter argument that was selected for all-at-once IN constraint
10017
+** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
10018
+** exhibit some other undefined or harmful behavior.
10019
+**
10020
+** ^(Use these routines to access all values on the right-hand side
10021
+** of the IN constraint using code like the following:
10022
+**
10023
+** <blockquote><pre>
10024
+** &nbsp; for(rc=sqlite3_vtab_in_first(pList, &pVal);
10025
+** &nbsp; rc==SQLITE_OK && pVal
10026
+** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
10027
+** &nbsp; ){
10028
+** &nbsp; // do something with pVal
10029
+** &nbsp; }
10030
+** &nbsp; if( rc!=SQLITE_OK ){
10031
+** &nbsp; // an error has occurred
10032
+** &nbsp; }
10033
+** </pre></blockquote>)^
10034
+**
10035
+** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
10036
+** routines return SQLITE_OK and set *P to point to the first or next value
10037
+** on the RHS of the IN constraint. ^If there are no more values on the
10038
+** right hand side of the IN constraint, then *P is set to NULL and these
10039
+** routines return [SQLITE_DONE]. ^The return value might be
10040
+** some other value, such as SQLITE_NOMEM, in the event of a malfunction.
10041
+**
10042
+** The *ppOut values returned by these routines are only valid until the
10043
+** next call to either of these routines or until the end of the xFilter
10044
+** method from which these routines were called. If the virtual table
10045
+** implementation needs to retain the *ppOut values for longer, it must make
10046
+** copies. The *ppOut values are [protected sqlite3_value|protected].
10047
+*/
10048
+SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
10049
+SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
10050
+
987810051
/*
987910052
** CAPI3REF: Constraint values in xBestIndex()
988010053
** METHOD: sqlite3_index_info
988110054
**
9882
-** This API may only be used from within an xBestIndex() callback. The
9883
-** results of calling it from outside of an xBestIndex() callback are
9884
-** undefined and probably harmful.
10055
+** This API may only be used from within the [xBestIndex|xBestIndex method]
10056
+** of a [virtual table] implementation. The result of calling this interface
10057
+** from outside of an xBestIndex method are undefined and probably harmful.
988510058
**
988610059
** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
988710060
** the [xBestIndex] method of a [virtual table] implementation, with P being
988810061
** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
988910062
** J being a 0-based index into P->aConstraint[], then this routine
9890
-** attempts to set *V to be the value on the right-hand side of
9891
-** that constraint if the right-hand side is a known constant. ^If the
9892
-** right-hand side of the constraint is not known, then *V is set to a NULL
9893
-** pointer. ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
10063
+** attempts to set *V to the value of the right-hand operand of
10064
+** that constraint if the right-hand operand is known. ^If the
10065
+** right-hand operand is not known, then *V is set to a NULL pointer.
10066
+** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
989410067
** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
989510068
** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
989610069
** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
989710070
** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
989810071
** something goes wrong.
989910072
**
9900
-** ^The sqlite3_value object returned in *V remains valid for the duration of
9901
-** the xBestIndex method code. ^When xBestIndex returns, the sqlite3_value
9902
-** object returned by sqlite3_vtab_rhs_value() is automatically deallocated.
10073
+** The sqlite3_vtab_rhs_value() interface is usually only successful if
10074
+** the right-hand operand of a constraint is a literal value in the original
10075
+** SQL statement. If the right-hand operand is an expression or a reference
10076
+** to some other column or a [host parameter], then sqlite3_vtab_rhs_value()
10077
+** will probably return [SQLITE_NOTFOUND].
10078
+**
10079
+** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and
10080
+** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such
10081
+** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^
10082
+**
10083
+** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value
10084
+** and remains valid for the duration of the xBestIndex method call.
10085
+** ^When xBestIndex returns, the sqlite3_value object returned by
10086
+** sqlite3_vtab_rhs_value() is automatically deallocated.
10087
+**
10088
+** The "_rhs_" in the name of this routine is an abbreviation for
10089
+** "Right-Hand Side".
990310090
*/
990410091
SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
990510092
990610093
/*
990710094
** CAPI3REF: Conflict resolution modes
@@ -14340,11 +14527,11 @@
1434014527
** one parameter that destructors normally want. So we have to introduce
1434114528
** this magic value that the code knows to handle differently. Any
1434214529
** pointer will work here as long as it is distinct from SQLITE_STATIC
1434314530
** and SQLITE_TRANSIENT.
1434414531
*/
14345
-#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomFault)
14532
+#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomClear)
1434614533
1434714534
/*
1434814535
** When SQLITE_OMIT_WSD is defined, it means that the target platform does
1434914536
** not support Writable Static Data (WSD) such as global and static variables.
1435014537
** All variables must either be on the stack or dynamically allocated from
@@ -14468,14 +14655,15 @@
1446814655
#define BMS ((int)(sizeof(Bitmask)*8))
1446914656
1447014657
/*
1447114658
** A bit in a Bitmask
1447214659
*/
14473
-#define MASKBIT(n) (((Bitmask)1)<<(n))
14474
-#define MASKBIT64(n) (((u64)1)<<(n))
14475
-#define MASKBIT32(n) (((unsigned int)1)<<(n))
14476
-#define ALLBITS ((Bitmask)-1)
14660
+#define MASKBIT(n) (((Bitmask)1)<<(n))
14661
+#define MASKBIT64(n) (((u64)1)<<(n))
14662
+#define MASKBIT32(n) (((unsigned int)1)<<(n))
14663
+#define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0)
14664
+#define ALLBITS ((Bitmask)-1)
1447714665
1447814666
/* A VList object records a mapping between parameters/variables/wildcards
1447914667
** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
1448014668
** variable number associated with that parameter. See the format description
1448114669
** on the sqlite3VListAdd() routine for more information. A VList is really
@@ -14533,18 +14721,19 @@
1453314721
** Handle type for pages.
1453414722
*/
1453514723
typedef struct PgHdr DbPage;
1453614724
1453714725
/*
14538
-** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
14726
+** Page number PAGER_SJ_PGNO is never used in an SQLite database (it is
1453914727
** reserved for working around a windows/posix incompatibility). It is
1454014728
** used in the journal to signify that the remainder of the journal file
1454114729
** is devoted to storing a super-journal name - there are no more pages to
1454214730
** roll back. See comments for function writeSuperJournal() in pager.c
1454314731
** for details.
1454414732
*/
14545
-#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
14733
+#define PAGER_SJ_PGNO_COMPUTED(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
14734
+#define PAGER_SJ_PGNO(x) ((x)->lckPgno)
1454614735
1454714736
/*
1454814737
** Allowed values for the flags parameter to sqlite3PagerOpen().
1454914738
**
1455014739
** NOTE: These values must match the corresponding BTREE_ values in btree.h.
@@ -15217,11 +15406,10 @@
1521715406
SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
1521815407
Table *pTab; /* Used when p4type is P4_TABLE */
1521915408
#ifdef SQLITE_ENABLE_CURSOR_HINTS
1522015409
Expr *pExpr; /* Used when p4type is P4_EXPR */
1522115410
#endif
15222
- int (*xAdvance)(BtCursor *, int);
1522315411
} p4;
1522415412
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
1522515413
char *zComment; /* Comment to improve readability */
1522615414
#endif
1522715415
#ifdef VDBE_PROFILE
@@ -15268,25 +15456,23 @@
1526815456
#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
1526915457
#define P4_STATIC (-1) /* Pointer to a static string */
1527015458
#define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */
1527115459
#define P4_INT32 (-3) /* P4 is a 32-bit signed integer */
1527215460
#define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */
15273
-#define P4_ADVANCE (-5) /* P4 is a pointer to BtreeNext() or BtreePrev() */
15274
-#define P4_TABLE (-6) /* P4 is a pointer to a Table structure */
15461
+#define P4_TABLE (-5) /* P4 is a pointer to a Table structure */
1527515462
/* Above do not own any resources. Must free those below */
15276
-#define P4_FREE_IF_LE (-7)
15277
-#define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */
15278
-#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */
15279
-#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */
15280
-#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */
15281
-#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */
15282
-#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */
15283
-#define P4_REAL (-13) /* P4 is a 64-bit floating point value */
15284
-#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */
15285
-#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
15286
-#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
15287
-#define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */
15463
+#define P4_FREE_IF_LE (-6)
15464
+#define P4_DYNAMIC (-6) /* Pointer to memory from sqliteMalloc() */
15465
+#define P4_FUNCDEF (-7) /* P4 is a pointer to a FuncDef structure */
15466
+#define P4_KEYINFO (-8) /* P4 is a pointer to a KeyInfo structure */
15467
+#define P4_EXPR (-9) /* P4 is a pointer to an Expr tree */
15468
+#define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */
15469
+#define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */
15470
+#define P4_REAL (-12) /* P4 is a 64-bit floating point value */
15471
+#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
15472
+#define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */
15473
+#define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */
1528815474
1528915475
/* Error message codes for OP_Halt */
1529015476
#define P5_ConstraintNotNull 1
1529115477
#define P5_ConstraintUnique 2
1529215478
#define P5_ConstraintCheck 3
@@ -15327,46 +15513,46 @@
1532715513
/* Automatically generated. Do not edit */
1532815514
/* See the tool/mkopcodeh.tcl script for details */
1532915515
#define OP_Savepoint 0
1533015516
#define OP_AutoCommit 1
1533115517
#define OP_Transaction 2
15332
-#define OP_SorterNext 3 /* jump */
15333
-#define OP_Prev 4 /* jump */
15334
-#define OP_Next 5 /* jump */
15335
-#define OP_Checkpoint 6
15336
-#define OP_JournalMode 7
15337
-#define OP_Vacuum 8
15338
-#define OP_VFilter 9 /* jump, synopsis: iplan=r[P3] zplan='P4' */
15339
-#define OP_VUpdate 10 /* synopsis: data=r[P3@P2] */
15340
-#define OP_Goto 11 /* jump */
15341
-#define OP_Gosub 12 /* jump */
15342
-#define OP_InitCoroutine 13 /* jump */
15343
-#define OP_Yield 14 /* jump */
15344
-#define OP_MustBeInt 15 /* jump */
15345
-#define OP_Jump 16 /* jump */
15346
-#define OP_Once 17 /* jump */
15347
-#define OP_If 18 /* jump */
15518
+#define OP_Checkpoint 3
15519
+#define OP_JournalMode 4
15520
+#define OP_Vacuum 5
15521
+#define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */
15522
+#define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */
15523
+#define OP_Goto 8 /* jump */
15524
+#define OP_Gosub 9 /* jump */
15525
+#define OP_InitCoroutine 10 /* jump */
15526
+#define OP_Yield 11 /* jump */
15527
+#define OP_MustBeInt 12 /* jump */
15528
+#define OP_Jump 13 /* jump */
15529
+#define OP_Once 14 /* jump */
15530
+#define OP_If 15 /* jump */
15531
+#define OP_IfNot 16 /* jump */
15532
+#define OP_IsNullOrType 17 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */
15533
+#define OP_IfNullRow 18 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
1534815534
#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
15349
-#define OP_IfNot 20 /* jump */
15350
-#define OP_IsNullOrType 21 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */
15351
-#define OP_IfNullRow 22 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
15352
-#define OP_SeekLT 23 /* jump, synopsis: key=r[P3@P4] */
15353
-#define OP_SeekLE 24 /* jump, synopsis: key=r[P3@P4] */
15354
-#define OP_SeekGE 25 /* jump, synopsis: key=r[P3@P4] */
15355
-#define OP_SeekGT 26 /* jump, synopsis: key=r[P3@P4] */
15356
-#define OP_IfNotOpen 27 /* jump, synopsis: if( !csr[P1] ) goto P2 */
15357
-#define OP_IfNoHope 28 /* jump, synopsis: key=r[P3@P4] */
15358
-#define OP_NoConflict 29 /* jump, synopsis: key=r[P3@P4] */
15359
-#define OP_NotFound 30 /* jump, synopsis: key=r[P3@P4] */
15360
-#define OP_Found 31 /* jump, synopsis: key=r[P3@P4] */
15361
-#define OP_SeekRowid 32 /* jump, synopsis: intkey=r[P3] */
15362
-#define OP_NotExists 33 /* jump, synopsis: intkey=r[P3] */
15363
-#define OP_Last 34 /* jump */
15364
-#define OP_IfSmaller 35 /* jump */
15365
-#define OP_SorterSort 36 /* jump */
15366
-#define OP_Sort 37 /* jump */
15367
-#define OP_Rewind 38 /* jump */
15535
+#define OP_SeekLT 20 /* jump, synopsis: key=r[P3@P4] */
15536
+#define OP_SeekLE 21 /* jump, synopsis: key=r[P3@P4] */
15537
+#define OP_SeekGE 22 /* jump, synopsis: key=r[P3@P4] */
15538
+#define OP_SeekGT 23 /* jump, synopsis: key=r[P3@P4] */
15539
+#define OP_IfNotOpen 24 /* jump, synopsis: if( !csr[P1] ) goto P2 */
15540
+#define OP_IfNoHope 25 /* jump, synopsis: key=r[P3@P4] */
15541
+#define OP_NoConflict 26 /* jump, synopsis: key=r[P3@P4] */
15542
+#define OP_NotFound 27 /* jump, synopsis: key=r[P3@P4] */
15543
+#define OP_Found 28 /* jump, synopsis: key=r[P3@P4] */
15544
+#define OP_SeekRowid 29 /* jump, synopsis: intkey=r[P3] */
15545
+#define OP_NotExists 30 /* jump, synopsis: intkey=r[P3] */
15546
+#define OP_Last 31 /* jump */
15547
+#define OP_IfSmaller 32 /* jump */
15548
+#define OP_SorterSort 33 /* jump */
15549
+#define OP_Sort 34 /* jump */
15550
+#define OP_Rewind 35 /* jump */
15551
+#define OP_SorterNext 36 /* jump */
15552
+#define OP_Prev 37 /* jump */
15553
+#define OP_Next 38 /* jump */
1536815554
#define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */
1536915555
#define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */
1537015556
#define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */
1537115557
#define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */
1537215558
#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
@@ -15395,41 +15581,41 @@
1539515581
#define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
1539615582
#define OP_Return 67
1539715583
#define OP_EndCoroutine 68
1539815584
#define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
1539915585
#define OP_Halt 70
15400
-#define OP_Integer 71 /* synopsis: r[P2]=P1 */
15401
-#define OP_Int64 72 /* synopsis: r[P2]=P4 */
15402
-#define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */
15403
-#define OP_Null 74 /* synopsis: r[P2..P3]=NULL */
15404
-#define OP_SoftNull 75 /* synopsis: r[P1]=NULL */
15405
-#define OP_Blob 76 /* synopsis: r[P2]=P4 (len=P1) */
15406
-#define OP_Variable 77 /* synopsis: r[P2]=parameter(P1,P4) */
15407
-#define OP_Move 78 /* synopsis: r[P2@P3]=r[P1@P3] */
15408
-#define OP_Copy 79 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15409
-#define OP_SCopy 80 /* synopsis: r[P2]=r[P1] */
15410
-#define OP_IntCopy 81 /* synopsis: r[P2]=r[P1] */
15411
-#define OP_FkCheck 82
15412
-#define OP_ResultRow 83 /* synopsis: output=r[P1@P2] */
15413
-#define OP_CollSeq 84
15414
-#define OP_AddImm 85 /* synopsis: r[P1]=r[P1]+P2 */
15415
-#define OP_RealAffinity 86
15416
-#define OP_Cast 87 /* synopsis: affinity(r[P1]) */
15417
-#define OP_Permutation 88
15418
-#define OP_Compare 89 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15419
-#define OP_IsTrue 90 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15420
-#define OP_ZeroOrNull 91 /* synopsis: r[P2] = 0 OR NULL */
15421
-#define OP_Offset 92 /* synopsis: r[P3] = sqlite_offset(P1) */
15422
-#define OP_Column 93 /* synopsis: r[P3]=PX */
15423
-#define OP_TypeCheck 94 /* synopsis: typecheck(r[P1@P2]) */
15424
-#define OP_Affinity 95 /* synopsis: affinity(r[P1@P2]) */
15425
-#define OP_MakeRecord 96 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15426
-#define OP_Count 97 /* synopsis: r[P2]=count() */
15427
-#define OP_ReadCookie 98
15428
-#define OP_SetCookie 99
15429
-#define OP_ReopenIdx 100 /* synopsis: root=P2 iDb=P3 */
15430
-#define OP_OpenRead 101 /* synopsis: root=P2 iDb=P3 */
15586
+#define OP_BeginSubrtn 71 /* synopsis: r[P2]=P1 */
15587
+#define OP_Integer 72 /* synopsis: r[P2]=P1 */
15588
+#define OP_Int64 73 /* synopsis: r[P2]=P4 */
15589
+#define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */
15590
+#define OP_Null 75 /* synopsis: r[P2..P3]=NULL */
15591
+#define OP_SoftNull 76 /* synopsis: r[P1]=NULL */
15592
+#define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */
15593
+#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */
15594
+#define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */
15595
+#define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15596
+#define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */
15597
+#define OP_IntCopy 82 /* synopsis: r[P2]=r[P1] */
15598
+#define OP_FkCheck 83
15599
+#define OP_ResultRow 84 /* synopsis: output=r[P1@P2] */
15600
+#define OP_CollSeq 85
15601
+#define OP_AddImm 86 /* synopsis: r[P1]=r[P1]+P2 */
15602
+#define OP_RealAffinity 87
15603
+#define OP_Cast 88 /* synopsis: affinity(r[P1]) */
15604
+#define OP_Permutation 89
15605
+#define OP_Compare 90 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15606
+#define OP_IsTrue 91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15607
+#define OP_ZeroOrNull 92 /* synopsis: r[P2] = 0 OR NULL */
15608
+#define OP_Offset 93 /* synopsis: r[P3] = sqlite_offset(P1) */
15609
+#define OP_Column 94 /* synopsis: r[P3]=PX */
15610
+#define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */
15611
+#define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */
15612
+#define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15613
+#define OP_Count 98 /* synopsis: r[P2]=count() */
15614
+#define OP_ReadCookie 99
15615
+#define OP_SetCookie 100
15616
+#define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */
1543115617
#define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
1543215618
#define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
1543315619
#define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
1543415620
#define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
1543515621
#define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
@@ -15436,82 +15622,84 @@
1543615622
#define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
1543715623
#define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
1543815624
#define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
1543915625
#define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
1544015626
#define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
15441
-#define OP_OpenWrite 112 /* synopsis: root=P2 iDb=P3 */
15442
-#define OP_OpenDup 113
15627
+#define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */
15628
+#define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */
1544315629
#define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
15444
-#define OP_OpenAutoindex 115 /* synopsis: nColumn=P2 */
15445
-#define OP_OpenEphemeral 116 /* synopsis: nColumn=P2 */
15630
+#define OP_OpenDup 115
15631
+#define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */
1544615632
#define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */
15447
-#define OP_SorterOpen 118
15448
-#define OP_SequenceTest 119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15449
-#define OP_OpenPseudo 120 /* synopsis: P3 columns in r[P2] */
15450
-#define OP_Close 121
15451
-#define OP_ColumnsUsed 122
15452
-#define OP_SeekScan 123 /* synopsis: Scan-ahead up to P1 rows */
15453
-#define OP_SeekHit 124 /* synopsis: set P2<=seekHit<=P3 */
15454
-#define OP_Sequence 125 /* synopsis: r[P2]=cursor[P1].ctr++ */
15455
-#define OP_NewRowid 126 /* synopsis: r[P2]=rowid */
15456
-#define OP_Insert 127 /* synopsis: intkey=r[P3] data=r[P2] */
15457
-#define OP_RowCell 128
15458
-#define OP_Delete 129
15459
-#define OP_ResetCount 130
15460
-#define OP_SorterCompare 131 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15461
-#define OP_SorterData 132 /* synopsis: r[P2]=data */
15462
-#define OP_RowData 133 /* synopsis: r[P2]=data */
15463
-#define OP_Rowid 134 /* synopsis: r[P2]=rowid */
15464
-#define OP_NullRow 135
15465
-#define OP_SeekEnd 136
15466
-#define OP_IdxInsert 137 /* synopsis: key=r[P2] */
15467
-#define OP_SorterInsert 138 /* synopsis: key=r[P2] */
15468
-#define OP_IdxDelete 139 /* synopsis: key=r[P2@P3] */
15469
-#define OP_DeferredSeek 140 /* synopsis: Move P3 to P1.rowid if needed */
15470
-#define OP_IdxRowid 141 /* synopsis: r[P2]=rowid */
15471
-#define OP_FinishSeek 142
15472
-#define OP_Destroy 143
15473
-#define OP_Clear 144
15474
-#define OP_ResetSorter 145
15475
-#define OP_CreateBtree 146 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15476
-#define OP_SqlExec 147
15477
-#define OP_ParseSchema 148
15478
-#define OP_LoadAnalysis 149
15479
-#define OP_DropTable 150
15480
-#define OP_DropIndex 151
15481
-#define OP_DropTrigger 152
15633
+#define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */
15634
+#define OP_SorterOpen 119
15635
+#define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15636
+#define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */
15637
+#define OP_Close 122
15638
+#define OP_ColumnsUsed 123
15639
+#define OP_SeekScan 124 /* synopsis: Scan-ahead up to P1 rows */
15640
+#define OP_SeekHit 125 /* synopsis: set P2<=seekHit<=P3 */
15641
+#define OP_Sequence 126 /* synopsis: r[P2]=cursor[P1].ctr++ */
15642
+#define OP_NewRowid 127 /* synopsis: r[P2]=rowid */
15643
+#define OP_Insert 128 /* synopsis: intkey=r[P3] data=r[P2] */
15644
+#define OP_RowCell 129
15645
+#define OP_Delete 130
15646
+#define OP_ResetCount 131
15647
+#define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15648
+#define OP_SorterData 133 /* synopsis: r[P2]=data */
15649
+#define OP_RowData 134 /* synopsis: r[P2]=data */
15650
+#define OP_Rowid 135 /* synopsis: r[P2]=rowid */
15651
+#define OP_NullRow 136
15652
+#define OP_SeekEnd 137
15653
+#define OP_IdxInsert 138 /* synopsis: key=r[P2] */
15654
+#define OP_SorterInsert 139 /* synopsis: key=r[P2] */
15655
+#define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */
15656
+#define OP_DeferredSeek 141 /* synopsis: Move P3 to P1.rowid if needed */
15657
+#define OP_IdxRowid 142 /* synopsis: r[P2]=rowid */
15658
+#define OP_FinishSeek 143
15659
+#define OP_Destroy 144
15660
+#define OP_Clear 145
15661
+#define OP_ResetSorter 146
15662
+#define OP_CreateBtree 147 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15663
+#define OP_SqlExec 148
15664
+#define OP_ParseSchema 149
15665
+#define OP_LoadAnalysis 150
15666
+#define OP_DropTable 151
15667
+#define OP_DropIndex 152
1548215668
#define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
15483
-#define OP_IntegrityCk 154
15484
-#define OP_RowSetAdd 155 /* synopsis: rowset(P1)=r[P2] */
15485
-#define OP_Param 156
15486
-#define OP_FkCounter 157 /* synopsis: fkctr[P1]+=P2 */
15487
-#define OP_MemMax 158 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15488
-#define OP_OffsetLimit 159 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15489
-#define OP_AggInverse 160 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15490
-#define OP_AggStep 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15491
-#define OP_AggStep1 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15492
-#define OP_AggValue 163 /* synopsis: r[P3]=value N=P2 */
15493
-#define OP_AggFinal 164 /* synopsis: accum=r[P1] N=P2 */
15494
-#define OP_Expire 165
15495
-#define OP_CursorLock 166
15496
-#define OP_CursorUnlock 167
15497
-#define OP_TableLock 168 /* synopsis: iDb=P1 root=P2 write=P3 */
15498
-#define OP_VBegin 169
15499
-#define OP_VCreate 170
15500
-#define OP_VDestroy 171
15501
-#define OP_VOpen 172
15502
-#define OP_VColumn 173 /* synopsis: r[P3]=vcolumn(P2) */
15503
-#define OP_VRename 174
15504
-#define OP_Pagecount 175
15505
-#define OP_MaxPgcnt 176
15506
-#define OP_FilterAdd 177 /* synopsis: filter(P1) += key(P3@P4) */
15507
-#define OP_Trace 178
15508
-#define OP_CursorHint 179
15509
-#define OP_ReleaseReg 180 /* synopsis: release r[P1@P2] mask P3 */
15510
-#define OP_Noop 181
15511
-#define OP_Explain 182
15512
-#define OP_Abortable 183
15669
+#define OP_DropTrigger 154
15670
+#define OP_IntegrityCk 155
15671
+#define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */
15672
+#define OP_Param 157
15673
+#define OP_FkCounter 158 /* synopsis: fkctr[P1]+=P2 */
15674
+#define OP_MemMax 159 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15675
+#define OP_OffsetLimit 160 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15676
+#define OP_AggInverse 161 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15677
+#define OP_AggStep 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15678
+#define OP_AggStep1 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15679
+#define OP_AggValue 164 /* synopsis: r[P3]=value N=P2 */
15680
+#define OP_AggFinal 165 /* synopsis: accum=r[P1] N=P2 */
15681
+#define OP_Expire 166
15682
+#define OP_CursorLock 167
15683
+#define OP_CursorUnlock 168
15684
+#define OP_TableLock 169 /* synopsis: iDb=P1 root=P2 write=P3 */
15685
+#define OP_VBegin 170
15686
+#define OP_VCreate 171
15687
+#define OP_VDestroy 172
15688
+#define OP_VOpen 173
15689
+#define OP_VInitIn 174 /* synopsis: r[P2]=ValueList(P1,P3) */
15690
+#define OP_VColumn 175 /* synopsis: r[P3]=vcolumn(P2) */
15691
+#define OP_VRename 176
15692
+#define OP_Pagecount 177
15693
+#define OP_MaxPgcnt 178
15694
+#define OP_FilterAdd 179 /* synopsis: filter(P1) += key(P3@P4) */
15695
+#define OP_Trace 180
15696
+#define OP_CursorHint 181
15697
+#define OP_ReleaseReg 182 /* synopsis: release r[P1@P2] mask P3 */
15698
+#define OP_Noop 183
15699
+#define OP_Explain 184
15700
+#define OP_Abortable 185
1551315701
1551415702
/* Properties such as "out2" or "jump" that are specified in
1551515703
** comments following the "case" for each opcode in the vdbe.c
1551615704
** are encoded into bitvectors as follows:
1551715705
*/
@@ -15520,34 +15708,34 @@
1552015708
#define OPFLG_IN2 0x04 /* in2: P2 is an input */
1552115709
#define OPFLG_IN3 0x08 /* in3: P3 is an input */
1552215710
#define OPFLG_OUT2 0x10 /* out2: P2 is an output */
1552315711
#define OPFLG_OUT3 0x20 /* out3: P3 is an output */
1552415712
#define OPFLG_INITIALIZER {\
15525
-/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\
15526
-/* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\
15527
-/* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x03, 0x01, 0x09,\
15528
-/* 24 */ 0x09, 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09,\
15529
-/* 32 */ 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
15713
+/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\
15714
+/* 8 */ 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03,\
15715
+/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x09, 0x09, 0x09, 0x09,\
15716
+/* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\
15717
+/* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
1553015718
/* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
1553115719
/* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
1553215720
/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15533
-/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
15534
-/* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\
15535
-/* 80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\
15536
-/* 88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\
15537
-/* 96 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\
15721
+/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x00,\
15722
+/* 72 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
15723
+/* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\
15724
+/* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\
15725
+/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\
1553815726
/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
1553915727
/* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\
15540
-/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
15541
-/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15542
-/* 136 */ 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10,\
15543
-/* 144 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15544
-/* 152 */ 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a,\
15545
-/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15546
-/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
15547
-/* 176 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15548
-}
15728
+/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
15729
+/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
15730
+/* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\
15731
+/* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
15732
+/* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
15733
+/* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15734
+/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15735
+/* 176 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15736
+/* 184 */ 0x00, 0x00,}
1554915737
1555015738
/* The resolve3P2Values() routine is able to run faster if it knows
1555115739
** the value of the largest JUMP opcode. The smaller the maximum
1555215740
** JUMP opcode the better, so the mkopcodeh.tcl script that
1555315741
** generated this include file strives to group all JUMP opcodes
@@ -17601,10 +17789,15 @@
1760117789
** b-tree.
1760217790
*/
1760317791
struct UnpackedRecord {
1760417792
KeyInfo *pKeyInfo; /* Collation and sort-order information */
1760517793
Mem *aMem; /* Values */
17794
+ union {
17795
+ char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */
17796
+ i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */
17797
+ } u;
17798
+ int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */
1760617799
u16 nField; /* Number of entries in apMem[] */
1760717800
i8 default_rc; /* Comparison result if keys are equal */
1760817801
u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
1760917802
i8 r1; /* Value to return if (lhs < rhs) */
1761017803
i8 r2; /* Value to return if (lhs > rhs) */
@@ -17908,11 +18101,14 @@
1790818101
** TK_SELECT: 1st register of result vector */
1790918102
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
1791018103
** TK_VARIABLE: variable number (always >= 1).
1791118104
** TK_SELECT_COLUMN: column of the result vector */
1791218105
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
17913
- int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
18106
+ union {
18107
+ int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
18108
+ int iOfst; /* else: start of token from start of statement */
18109
+ } w;
1791418110
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
1791518111
union {
1791618112
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
1791718113
** for a column of an index on an expression */
1791818114
Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */
@@ -19017,10 +19213,11 @@
1901719213
#endif
1901819214
#ifndef SQLITE_UNTESTABLE
1901919215
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
1902019216
#endif
1902119217
int bLocaltimeFault; /* True to fail localtime() calls */
19218
+ int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
1902219219
int iOnceResetThreshold; /* When to reset OP_Once counters */
1902319220
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
1902419221
unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
1902519222
/* vvvv--- must be last ---vvv */
1902619223
#ifdef SQLITE_DEBUG
@@ -19221,11 +19418,11 @@
1922119418
Expr *pStart; /* Expression for "<expr> PRECEDING" */
1922219419
Expr *pEnd; /* Expression for "<expr> FOLLOWING" */
1922319420
Window **ppThis; /* Pointer to this object in Select.pWin list */
1922419421
Window *pNextWin; /* Next window function belonging to this SELECT */
1922519422
Expr *pFilter; /* The FILTER expression */
19226
- FuncDef *pFunc; /* The function */
19423
+ FuncDef *pWFunc; /* The function */
1922719424
int iEphCsr; /* Partition buffer or Peer buffer */
1922819425
int regAccum; /* Accumulator */
1922919426
int regResult; /* Interim result */
1923019427
int csrApp; /* Function cursor (used by min/max) */
1923119428
int regApp; /* Function register (also used by min/max) */
@@ -19662,11 +19859,12 @@
1966219859
#endif
1966319860
SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*);
1966419861
SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
1966519862
SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
1966619863
Upsert*);
19667
-SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
19864
+SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,
19865
+ ExprList*,Select*,u16,int);
1966819866
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
1966919867
SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
1967019868
SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
1967119869
SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
1967219870
SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
@@ -20075,10 +20273,11 @@
2007520273
SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
2007620274
SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
2007720275
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
2007820276
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
2007920277
SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*);
20278
+SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3*,const Expr*);
2008020279
2008120280
SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
2008220281
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
2008320282
2008420283
#ifndef SQLITE_OMIT_SUBQUERY
@@ -20179,11 +20378,16 @@
2017920378
SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
2018020379
SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
2018120380
SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*);
2018220381
SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
2018320382
SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
20383
+
2018420384
SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
20385
+#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
20386
+ && !defined(SQLITE_OMIT_VIRTUALTABLE)
20387
+SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info*);
20388
+#endif
2018520389
SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
2018620390
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
2018720391
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
2018820392
SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*);
2018920393
SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse*);
@@ -21695,13 +21899,17 @@
2169521899
#endif
2169621900
#ifndef SQLITE_UNTESTABLE
2169721901
0, /* xTestCallback */
2169821902
#endif
2169921903
0, /* bLocaltimeFault */
21904
+ 0, /* xAltLocaltime */
2170021905
0x7ffffffe, /* iOnceResetThreshold */
2170121906
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
2170221907
0, /* iPrngSeed */
21908
+#ifdef SQLITE_DEBUG
21909
+ {0,0,0,0,0,0} /* aTune */
21910
+#endif
2170321911
};
2170421912
2170521913
/*
2170621914
** Hash table for global functions - functions common to all
2170721915
** database connections. After initialization, this table is
@@ -22041,20 +22249,20 @@
2204122249
i64 i; /* Integer value used when MEM_Int is set in flags */
2204222250
int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
2204322251
const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
2204422252
FuncDef *pDef; /* Used only when flags==MEM_Agg */
2204522253
} u;
22254
+ char *z; /* String or BLOB value */
22255
+ int n; /* Number of characters in string value, excluding '\0' */
2204622256
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
2204722257
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
2204822258
u8 eSubtype; /* Subtype for this value */
22049
- int n; /* Number of characters in string value, excluding '\0' */
22050
- char *z; /* String or BLOB value */
2205122259
/* ShallowCopy only needs to copy the information above */
22052
- char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
22260
+ sqlite3 *db; /* The associated database connection */
2205322261
int szMalloc; /* Size of the zMalloc allocation */
2205422262
u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
22055
- sqlite3 *db; /* The associated database connection */
22263
+ char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
2205622264
void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
2205722265
#ifdef SQLITE_DEBUG
2205822266
Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
2205922267
u16 mScopyFlags; /* flags value immediately after the shallow copy */
2206022268
#endif
@@ -22062,15 +22270,47 @@
2206222270
2206322271
/*
2206422272
** Size of struct Mem not including the Mem.zMalloc member or anything that
2206522273
** follows.
2206622274
*/
22067
-#define MEMCELLSIZE offsetof(Mem,zMalloc)
22275
+#define MEMCELLSIZE offsetof(Mem,db)
2206822276
22069
-/* One or more of the following flags are set to indicate the validOK
22277
+/* One or more of the following flags are set to indicate the
2207022278
** representations of the value stored in the Mem struct.
2207122279
**
22280
+** * MEM_Null An SQL NULL value
22281
+**
22282
+** * MEM_Null|MEM_Zero An SQL NULL with the virtual table
22283
+** UPDATE no-change flag set
22284
+**
22285
+** * MEM_Null|MEM_Term| An SQL NULL, but also contains a
22286
+** MEM_Subtype pointer accessible using
22287
+** sqlite3_value_pointer().
22288
+**
22289
+** * MEM_Null|MEM_Cleared Special SQL NULL that compares non-equal
22290
+** to other NULLs even using the IS operator.
22291
+**
22292
+** * MEM_Str A string, stored in Mem.z with
22293
+** length Mem.n. Zero-terminated if
22294
+** MEM_Term is set. This flag is
22295
+** incompatible with MEM_Blob and
22296
+** MEM_Null, but can appear with MEM_Int,
22297
+** MEM_Real, and MEM_IntReal.
22298
+**
22299
+** * MEM_Blob A blob, stored in Mem.z length Mem.n.
22300
+** Incompatible with MEM_Str, MEM_Null,
22301
+** MEM_Int, MEM_Real, and MEM_IntReal.
22302
+**
22303
+** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus
22304
+** MEM.u.i extra 0x00 bytes at the end.
22305
+**
22306
+** * MEM_Int Integer stored in Mem.u.i.
22307
+**
22308
+** * MEM_Real Real stored in Mem.u.r.
22309
+**
22310
+** * MEM_IntReal Real stored as an integer in Mem.u.i.
22311
+**
2207222312
** If the MEM_Null flag is set, then the value is an SQL NULL value.
2207322313
** For a pointer type created using sqlite3_bind_pointer() or
2207422314
** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
2207522315
**
2207622316
** If the MEM_Str flag is set then Mem.z points at a string representation.
@@ -22077,39 +22317,36 @@
2207722317
** Usually this is encoded in the same unicode encoding as the main
2207822318
** database (see below for exceptions). If the MEM_Term flag is also
2207922319
** set, then the string is nul terminated. The MEM_Int and MEM_Real
2208022320
** flags may coexist with the MEM_Str flag.
2208122321
*/
22322
+#define MEM_Undefined 0x0000 /* Value is undefined */
2208222323
#define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
2208322324
#define MEM_Str 0x0002 /* Value is a string */
2208422325
#define MEM_Int 0x0004 /* Value is an integer */
2208522326
#define MEM_Real 0x0008 /* Value is a real number */
2208622327
#define MEM_Blob 0x0010 /* Value is a BLOB */
2208722328
#define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
2208822329
#define MEM_AffMask 0x003f /* Mask of affinity bits */
22330
+
22331
+/* Extra bits that modify the meanings of the core datatypes above
22332
+*/
2208922333
#define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
22090
-#define MEM_Undefined 0x0080 /* Value is undefined */
22334
+ /* 0x0080 // Available */
2209122335
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
22092
-#define MEM_TypeMask 0xc1bf /* Mask of type bits */
22093
-
22094
-
22095
-/* Whenever Mem contains a valid string or blob representation, one of
22096
-** the following flags must be set to determine the memory management
22097
-** policy for Mem.z. The MEM_Term flag tells us whether or not the
22098
-** string is \000 or \u0000 terminated
22099
-*/
2210022336
#define MEM_Term 0x0200 /* String in Mem.z is zero terminated */
22101
-#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
22102
-#define MEM_Static 0x0800 /* Mem.z points to a static string */
22103
-#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
22104
-#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
22105
-#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */
22106
-#define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */
22107
-#ifdef SQLITE_OMIT_INCRBLOB
22108
- #undef MEM_Zero
22109
- #define MEM_Zero 0x0000
22110
-#endif
22337
+#define MEM_Zero 0x0400 /* Mem.i contains count of 0s appended to blob */
22338
+#define MEM_Subtype 0x0800 /* Mem.eSubtype is valid */
22339
+#define MEM_TypeMask 0x0dbf /* Mask of type bits */
22340
+
22341
+/* Bits that determine the storage for Mem.z for a string or blob or
22342
+** aggregate accumulator.
22343
+*/
22344
+#define MEM_Dyn 0x1000 /* Need to call Mem.xDel() on Mem.z */
22345
+#define MEM_Static 0x2000 /* Mem.z points to a static string */
22346
+#define MEM_Ephem 0x4000 /* Mem.z points to an ephemeral string */
22347
+#define MEM_Agg 0x8000 /* Mem.z points to an agg function context */
2211122348
2211222349
/* Return TRUE if Mem X contains dynamically allocated content - anything
2211322350
** that needs to be deallocated to avoid a leak.
2211422351
*/
2211522352
#define VdbeMemDynamic(X) \
@@ -22127,15 +22364,19 @@
2212722364
#define MemNullNochng(X) \
2212822365
(((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \
2212922366
&& (X)->n==0 && (X)->u.nZero==0)
2213022367
2213122368
/*
22132
-** Return true if a memory cell is not marked as invalid. This macro
22369
+** Return true if a memory cell has been initialized and is valid.
2213322370
** is for use inside assert() statements only.
22371
+**
22372
+** A Memory cell is initialized if at least one of the
22373
+** MEM_Null, MEM_Str, MEM_Int, MEM_Real, MEM_Blob, or MEM_IntReal bits
22374
+** is set. It is "undefined" if all those bits are zero.
2213422375
*/
2213522376
#ifdef SQLITE_DEBUG
22136
-#define memIsValid(M) ((M)->flags & MEM_Undefined)==0
22377
+#define memIsValid(M) ((M)->flags & MEM_AffMask)!=0
2213722378
#endif
2213822379
2213922380
/*
2214022381
** Each auxiliary data pointer stored by a user defined function
2214122382
** implementation calling sqlite3_set_auxdata() is stored in an instance
@@ -22169,10 +22410,11 @@
2216922410
FuncDef *pFunc; /* Pointer to function information */
2217022411
Mem *pMem; /* Memory cell used to store aggregate context */
2217122412
Vdbe *pVdbe; /* The VM that owns this context */
2217222413
int iOp; /* Instruction number of OP_Function */
2217322414
int isError; /* Error code returned by the function. */
22415
+ u8 enc; /* Encoding to use for results */
2217422416
u8 skipFlag; /* Skip accumulator loading if true */
2217522417
u8 argc; /* Number of arguments */
2217622418
sqlite3_value *argv[1]; /* Argument set */
2217722419
};
2217822420
@@ -22217,11 +22459,10 @@
2221722459
struct Vdbe {
2221822460
sqlite3 *db; /* The database connection that owns this statement */
2221922461
Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
2222022462
Parse *pParse; /* Parsing context used to create this Vdbe */
2222122463
ynVar nVar; /* Number of entries in aVar[] */
22222
- u32 iVdbeMagic; /* Magic number defining state of the SQL statement */
2222322464
int nMem; /* Number of memory locations currently allocated */
2222422465
int nCursor; /* Number of slots in apCsr[] */
2222522466
u32 cacheCtr; /* VdbeCursor row cache generation counter */
2222622467
int pc; /* The program counter */
2222722468
int rc; /* Value to return */
@@ -22256,10 +22497,11 @@
2225622497
u16 nResColumn; /* Number of columns in one row of the result set */
2225722498
u8 errorAction; /* Recovery action to do in case of an error */
2225822499
u8 minWriteFileFormat; /* Minimum file format for writable database files */
2225922500
u8 prepFlags; /* SQLITE_PREPARE_* flags */
2226022501
u8 doingRerun; /* True if rerunning after an auto-reprepare */
22502
+ u8 eVdbeState; /* On of the VDBE_*_STATE values */
2226122503
bft expired:2; /* 1: recompile VM immediately 2: when convenient */
2226222504
bft explain:2; /* True if EXPLAIN present on SQL command */
2226322505
bft changeCntOn:1; /* True to update the change-counter */
2226422506
bft runOnlyOnce:1; /* Automatically expire on reset */
2226522507
bft usesStmtJournal:1; /* True if uses a statement journal */
@@ -22286,17 +22528,16 @@
2228622528
ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */
2228722529
#endif
2228822530
};
2228922531
2229022532
/*
22291
-** The following are allowed values for Vdbe.magic
22533
+** The following are allowed values for Vdbe.eVdbeState
2229222534
*/
22293
-#define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */
22294
-#define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */
22295
-#define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */
22296
-#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */
22297
-#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */
22535
+#define VDBE_INIT_STATE 0 /* Prepared statement under construction */
22536
+#define VDBE_READY_STATE 1 /* Ready to run but not yet started */
22537
+#define VDBE_RUN_STATE 2 /* Run in progress */
22538
+#define VDBE_HALT_STATE 3 /* Finished. Need reset() or finalize() */
2229822539
2229922540
/*
2230022541
** Structure used to store the context required by the
2230122542
** sqlite3_preupdate_*() API functions.
2230222543
*/
@@ -22315,18 +22556,36 @@
2231522556
Mem *aNew; /* Array of new.* values */
2231622557
Table *pTab; /* Schema object being upated */
2231722558
Index *pPk; /* PK index if pTab is WITHOUT ROWID */
2231822559
};
2231922560
22561
+/*
22562
+** An instance of this object is used to pass an vector of values into
22563
+** OP_VFilter, the xFilter method of a virtual table. The vector is the
22564
+** set of values on the right-hand side of an IN constraint.
22565
+**
22566
+** The value as passed into xFilter is an sqlite3_value with a "pointer"
22567
+** type, such as is generated by sqlite3_result_pointer() and read by
22568
+** sqlite3_value_pointer. Such values have MEM_Term|MEM_Subtype|MEM_Null
22569
+** and a subtype of 'p'. The sqlite3_vtab_in_first() and _next() interfaces
22570
+** know how to use this object to step through all the values in the
22571
+** right operand of the IN constraint.
22572
+*/
22573
+typedef struct ValueList ValueList;
22574
+struct ValueList {
22575
+ BtCursor *pCsr; /* An ephemeral table holding all values */
22576
+ sqlite3_value *pOut; /* Register to hold each decoded output value */
22577
+};
22578
+
2232022579
/*
2232122580
** Function prototypes
2232222581
*/
2232322582
SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
2232422583
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
2232522584
void sqliteVdbePopStack(Vdbe*,int);
22585
+SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p);
2232622586
SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
22327
-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, u32*);
2232822587
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
2232922588
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
2233022589
SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
2233122590
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
2233222591
SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
@@ -22384,10 +22643,11 @@
2238422643
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
2238522644
SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8);
2238622645
SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
2238722646
SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
2238822647
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
22648
+SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem*p);
2238922649
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
2239022650
#ifndef SQLITE_OMIT_WINDOWFUNC
2239122651
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
2239222652
#endif
2239322653
#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
@@ -23351,12 +23611,14 @@
2335123611
** The following routine implements the rough equivalent of localtime_r()
2335223612
** using whatever operating-system specific localtime facility that
2335323613
** is available. This routine returns 0 on success and
2335423614
** non-zero on any kind of error.
2335523615
**
23356
-** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
23357
-** routine will always fail.
23616
+** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this
23617
+** routine will always fail. If bLocaltimeFault is nonzero and
23618
+** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is
23619
+** invoked in place of the OS-defined localtime() function.
2335823620
**
2335923621
** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
2336023622
** library function localtime_r() is used to assist in the calculation of
2336123623
** local time.
2336223624
*/
@@ -23368,20 +23630,34 @@
2336823630
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
2336923631
#endif
2337023632
sqlite3_mutex_enter(mutex);
2337123633
pX = localtime(t);
2337223634
#ifndef SQLITE_UNTESTABLE
23373
- if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
23635
+ if( sqlite3GlobalConfig.bLocaltimeFault ){
23636
+ if( sqlite3GlobalConfig.xAltLocaltime!=0
23637
+ && 0==sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm)
23638
+ ){
23639
+ pX = pTm;
23640
+ }else{
23641
+ pX = 0;
23642
+ }
23643
+ }
2337423644
#endif
2337523645
if( pX ) *pTm = *pX;
2337623646
#if SQLITE_THREADSAFE>0
2337723647
sqlite3_mutex_leave(mutex);
2337823648
#endif
2337923649
rc = pX==0;
2338023650
#else
2338123651
#ifndef SQLITE_UNTESTABLE
23382
- if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
23652
+ if( sqlite3GlobalConfig.bLocaltimeFault ){
23653
+ if( sqlite3GlobalConfig.xAltLocaltime!=0 ){
23654
+ return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm);
23655
+ }else{
23656
+ return 1;
23657
+ }
23658
+ }
2338323659
#endif
2338423660
#if HAVE_LOCALTIME_R
2338523661
rc = localtime_r(t, pTm)==0;
2338623662
#else
2338723663
rc = localtime_s(pTm, t);
@@ -23392,71 +23668,60 @@
2339223668
#endif /* SQLITE_OMIT_LOCALTIME */
2339323669
2339423670
2339523671
#ifndef SQLITE_OMIT_LOCALTIME
2339623672
/*
23397
-** Compute the difference (in milliseconds) between localtime and UTC
23398
-** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
23399
-** return this value and set *pRc to SQLITE_OK.
23400
-**
23401
-** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
23402
-** is undefined in this case.
23673
+** Assuming the input DateTime is UTC, move it to its localtime equivalent.
2340323674
*/
23404
-static sqlite3_int64 localtimeOffset(
23405
- DateTime *p, /* Date at which to calculate offset */
23406
- sqlite3_context *pCtx, /* Write error here if one occurs */
23407
- int *pRc /* OUT: Error code. SQLITE_OK or ERROR */
23675
+static int toLocaltime(
23676
+ DateTime *p, /* Date at which to calculate offset */
23677
+ sqlite3_context *pCtx /* Write error here if one occurs */
2340823678
){
23409
- DateTime x, y;
2341023679
time_t t;
2341123680
struct tm sLocal;
23681
+ int iYearDiff;
2341223682
2341323683
/* Initialize the contents of sLocal to avoid a compiler warning. */
2341423684
memset(&sLocal, 0, sizeof(sLocal));
2341523685
23416
- x = *p;
23417
- computeYMD_HMS(&x);
23418
- if( x.Y<1971 || x.Y>=2038 ){
23686
+ computeJD(p);
23687
+ if( p->iJD<2108667600*(i64)100000 /* 1970-01-01 */
23688
+ || p->iJD>2130141456*(i64)100000 /* 2038-01-18 */
23689
+ ){
2341923690
/* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
2342023691
** works for years between 1970 and 2037. For dates outside this range,
2342123692
** SQLite attempts to map the year into an equivalent year within this
2342223693
** range, do the calculation, then map the year back.
2342323694
*/
23424
- x.Y = 2000;
23425
- x.M = 1;
23426
- x.D = 1;
23427
- x.h = 0;
23428
- x.m = 0;
23429
- x.s = 0.0;
23430
- } else {
23431
- int s = (int)(x.s + 0.5);
23432
- x.s = s;
23433
- }
23434
- x.tz = 0;
23435
- x.validJD = 0;
23436
- computeJD(&x);
23437
- t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
23695
+ DateTime x = *p;
23696
+ computeYMD_HMS(&x);
23697
+ iYearDiff = (2000 + x.Y%4) - x.Y;
23698
+ x.Y += iYearDiff;
23699
+ x.validJD = 0;
23700
+ computeJD(&x);
23701
+ t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
23702
+ }else{
23703
+ iYearDiff = 0;
23704
+ t = (time_t)(p->iJD/1000 - 21086676*(i64)10000);
23705
+ }
2343823706
if( osLocaltime(&t, &sLocal) ){
2343923707
sqlite3_result_error(pCtx, "local time unavailable", -1);
23440
- *pRc = SQLITE_ERROR;
23441
- return 0;
23442
- }
23443
- y.Y = sLocal.tm_year + 1900;
23444
- y.M = sLocal.tm_mon + 1;
23445
- y.D = sLocal.tm_mday;
23446
- y.h = sLocal.tm_hour;
23447
- y.m = sLocal.tm_min;
23448
- y.s = sLocal.tm_sec;
23449
- y.validYMD = 1;
23450
- y.validHMS = 1;
23451
- y.validJD = 0;
23452
- y.rawS = 0;
23453
- y.validTZ = 0;
23454
- y.isError = 0;
23455
- computeJD(&y);
23456
- *pRc = SQLITE_OK;
23457
- return y.iJD - x.iJD;
23708
+ return SQLITE_ERROR;
23709
+ }
23710
+ p->Y = sLocal.tm_year + 1900 - iYearDiff;
23711
+ p->M = sLocal.tm_mon + 1;
23712
+ p->D = sLocal.tm_mday;
23713
+ p->h = sLocal.tm_hour;
23714
+ p->m = sLocal.tm_min;
23715
+ p->s = sLocal.tm_sec + (p->iJD%1000)*0.001;
23716
+ p->validYMD = 1;
23717
+ p->validHMS = 1;
23718
+ p->validJD = 0;
23719
+ p->rawS = 0;
23720
+ p->validTZ = 0;
23721
+ p->isError = 0;
23722
+ return SQLITE_OK;
2345823723
}
2345923724
#endif /* SQLITE_OMIT_LOCALTIME */
2346023725
2346123726
/*
2346223727
** The following table defines various date transformations of the form
@@ -23524,11 +23789,13 @@
2352423789
if( sqlite3_stricmp(z, "auto")==0 ){
2352523790
if( idx>1 ) return 1; /* IMP: R-33611-57934 */
2352623791
if( !p->rawS || p->validJD ){
2352723792
rc = 0;
2352823793
p->rawS = 0;
23529
- }else if( p->s>=-210866760000 && p->s<=253402300799 ){
23794
+ }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */
23795
+ && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */
23796
+ ){
2353023797
r = p->s*1000.0 + 210866760000000.0;
2353123798
clearYMD_HMS_TZ(p);
2353223799
p->iJD = (sqlite3_int64)(r + 0.5);
2353323800
p->validJD = 1;
2353423801
p->rawS = 0;
@@ -23545,11 +23812,11 @@
2354523812
** is not the first modifier, or if the prior argument is not a numeric
2354623813
** value in the allowed range of julian day numbers understood by
2354723814
** SQLite (0..5373484.5) then the result will be NULL.
2354823815
*/
2354923816
if( sqlite3_stricmp(z, "julianday")==0 ){
23550
- if( idx>1 ) return 1;
23817
+ if( idx>1 ) return 1; /* IMP: R-31176-64601 */
2355123818
if( p->validJD && p->rawS ){
2355223819
rc = 0;
2355323820
p->rawS = 0;
2355423821
}
2355523822
}
@@ -23561,13 +23828,11 @@
2356123828
**
2356223829
** Assuming the current time value is UTC (a.k.a. GMT), shift it to
2356323830
** show local time.
2356423831
*/
2356523832
if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
23566
- computeJD(p);
23567
- p->iJD += localtimeOffset(p, pCtx, &rc);
23568
- clearYMD_HMS_TZ(p);
23833
+ rc = toLocaltime(p, pCtx);
2356923834
}
2357023835
break;
2357123836
}
2357223837
#endif
2357323838
case 'u': {
@@ -23576,10 +23841,11 @@
2357623841
**
2357723842
** Treat the current value of p->s as the number of
2357823843
** seconds since 1970. Convert to a real julian day number.
2357923844
*/
2358023845
if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
23846
+ if( idx>1 ) return 1; /* IMP: R-49255-55373 */
2358123847
r = p->s*1000.0 + 210866760000000.0;
2358223848
if( r>=0.0 && r<464269060800000.0 ){
2358323849
clearYMD_HMS_TZ(p);
2358423850
p->iJD = (sqlite3_int64)(r + 0.5);
2358523851
p->validJD = 1;
@@ -23588,22 +23854,35 @@
2358823854
}
2358923855
}
2359023856
#ifndef SQLITE_OMIT_LOCALTIME
2359123857
else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
2359223858
if( p->tzSet==0 ){
23593
- sqlite3_int64 c1;
23859
+ i64 iOrigJD; /* Original localtime */
23860
+ i64 iGuess; /* Guess at the corresponding utc time */
23861
+ int cnt = 0; /* Safety to prevent infinite loop */
23862
+ int iErr; /* Guess is off by this much */
23863
+
2359423864
computeJD(p);
23595
- c1 = localtimeOffset(p, pCtx, &rc);
23596
- if( rc==SQLITE_OK ){
23597
- p->iJD -= c1;
23598
- clearYMD_HMS_TZ(p);
23599
- p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
23600
- }
23865
+ iGuess = iOrigJD = p->iJD;
23866
+ iErr = 0;
23867
+ do{
23868
+ DateTime new;
23869
+ memset(&new, 0, sizeof(new));
23870
+ iGuess -= iErr;
23871
+ new.iJD = iGuess;
23872
+ new.validJD = 1;
23873
+ rc = toLocaltime(&new, pCtx);
23874
+ if( rc ) return rc;
23875
+ computeJD(&new);
23876
+ iErr = new.iJD - iOrigJD;
23877
+ }while( iErr && cnt++<3 );
23878
+ memset(p, 0, sizeof(*p));
23879
+ p->iJD = iGuess;
23880
+ p->validJD = 1;
2360123881
p->tzSet = 1;
23602
- }else{
23603
- rc = SQLITE_OK;
2360423882
}
23883
+ rc = SQLITE_OK;
2360523884
}
2360623885
#endif
2360723886
break;
2360823887
}
2360923888
case 'w': {
@@ -23849,15 +24128,42 @@
2384924128
int argc,
2385024129
sqlite3_value **argv
2385124130
){
2385224131
DateTime x;
2385324132
if( isDate(context, argc, argv, &x)==0 ){
23854
- char zBuf[100];
24133
+ int Y, s;
24134
+ char zBuf[24];
2385524135
computeYMD_HMS(&x);
23856
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
23857
- x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
23858
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
24136
+ Y = x.Y;
24137
+ if( Y<0 ) Y = -Y;
24138
+ zBuf[1] = '0' + (Y/1000)%10;
24139
+ zBuf[2] = '0' + (Y/100)%10;
24140
+ zBuf[3] = '0' + (Y/10)%10;
24141
+ zBuf[4] = '0' + (Y)%10;
24142
+ zBuf[5] = '-';
24143
+ zBuf[6] = '0' + (x.M/10)%10;
24144
+ zBuf[7] = '0' + (x.M)%10;
24145
+ zBuf[8] = '-';
24146
+ zBuf[9] = '0' + (x.D/10)%10;
24147
+ zBuf[10] = '0' + (x.D)%10;
24148
+ zBuf[11] = ' ';
24149
+ zBuf[12] = '0' + (x.h/10)%10;
24150
+ zBuf[13] = '0' + (x.h)%10;
24151
+ zBuf[14] = ':';
24152
+ zBuf[15] = '0' + (x.m/10)%10;
24153
+ zBuf[16] = '0' + (x.m)%10;
24154
+ zBuf[17] = ':';
24155
+ s = (int)x.s;
24156
+ zBuf[18] = '0' + (s/10)%10;
24157
+ zBuf[19] = '0' + (s)%10;
24158
+ zBuf[20] = 0;
24159
+ if( x.Y<0 ){
24160
+ zBuf[0] = '-';
24161
+ sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT);
24162
+ }else{
24163
+ sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT);
24164
+ }
2385924165
}
2386024166
}
2386124167
2386224168
/*
2386324169
** time( TIMESTRING, MOD, MOD, ...)
@@ -23869,14 +24175,24 @@
2386924175
int argc,
2387024176
sqlite3_value **argv
2387124177
){
2387224178
DateTime x;
2387324179
if( isDate(context, argc, argv, &x)==0 ){
23874
- char zBuf[100];
24180
+ int s;
24181
+ char zBuf[16];
2387524182
computeHMS(&x);
23876
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
23877
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
24183
+ zBuf[0] = '0' + (x.h/10)%10;
24184
+ zBuf[1] = '0' + (x.h)%10;
24185
+ zBuf[2] = ':';
24186
+ zBuf[3] = '0' + (x.m/10)%10;
24187
+ zBuf[4] = '0' + (x.m)%10;
24188
+ zBuf[5] = ':';
24189
+ s = (int)x.s;
24190
+ zBuf[6] = '0' + (s/10)%10;
24191
+ zBuf[7] = '0' + (s)%10;
24192
+ zBuf[8] = 0;
24193
+ sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT);
2387824194
}
2387924195
}
2388024196
2388124197
/*
2388224198
** date( TIMESTRING, MOD, MOD, ...)
@@ -23888,14 +24204,32 @@
2388824204
int argc,
2388924205
sqlite3_value **argv
2389024206
){
2389124207
DateTime x;
2389224208
if( isDate(context, argc, argv, &x)==0 ){
23893
- char zBuf[100];
24209
+ int Y;
24210
+ char zBuf[16];
2389424211
computeYMD(&x);
23895
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
23896
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
24212
+ Y = x.Y;
24213
+ if( Y<0 ) Y = -Y;
24214
+ zBuf[1] = '0' + (Y/1000)%10;
24215
+ zBuf[2] = '0' + (Y/100)%10;
24216
+ zBuf[3] = '0' + (Y/10)%10;
24217
+ zBuf[4] = '0' + (Y)%10;
24218
+ zBuf[5] = '-';
24219
+ zBuf[6] = '0' + (x.M/10)%10;
24220
+ zBuf[7] = '0' + (x.M)%10;
24221
+ zBuf[8] = '-';
24222
+ zBuf[9] = '0' + (x.D/10)%10;
24223
+ zBuf[10] = '0' + (x.D)%10;
24224
+ zBuf[11] = 0;
24225
+ if( x.Y<0 ){
24226
+ zBuf[0] = '-';
24227
+ sqlite3_result_text(context, zBuf, 11, SQLITE_TRANSIENT);
24228
+ }else{
24229
+ sqlite3_result_text(context, &zBuf[1], 10, SQLITE_TRANSIENT);
24230
+ }
2389724231
}
2389824232
}
2389924233
2390024234
/*
2390124235
** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
@@ -26668,12 +27002,17 @@
2666827002
** 32-bit signed integer. Hence the largest allocation is 0x40000000
2666927003
** or 1073741824 bytes.
2667027004
*/
2667127005
static int memsys5Roundup(int n){
2667227006
int iFullSz;
26673
- if( n > 0x40000000 ) return 0;
26674
- for(iFullSz=mem5.szAtom; iFullSz<n; iFullSz *= 2);
27007
+ if( n<=mem5.szAtom*2 ){
27008
+ if( n<=mem5.szAtom ) return mem5.szAtom;
27009
+ return mem5.szAtom*2;
27010
+ }
27011
+ if( n>0x40000000 ) return 0;
27012
+ for(iFullSz=mem5.szAtom*8; iFullSz<n; iFullSz *= 4);
27013
+ if( (iFullSz/2)>=n ) return iFullSz/2;
2667527014
return iFullSz;
2667627015
}
2667727016
2667827017
/*
2667927018
** Return the ceiling of the logarithm base 2 of iValue.
@@ -29988,17 +30327,26 @@
2998830327
bufpt[j] = 0;
2998930328
length = j;
2999030329
goto adjust_width_for_utf8;
2999130330
}
2999230331
case etTOKEN: {
29993
- Token *pToken;
2999430332
if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
29995
- pToken = va_arg(ap, Token*);
29996
- assert( bArgList==0 );
29997
- if( pToken && pToken->n ){
29998
- sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
29999
- sqlite3RecordErrorByteOffset(pAccum->db, pToken->z);
30333
+ if( flag_alternateform ){
30334
+ /* %#T means an Expr pointer that uses Expr.u.zToken */
30335
+ Expr *pExpr = va_arg(ap,Expr*);
30336
+ if( ALWAYS(pExpr) && ALWAYS(!ExprHasProperty(pExpr,EP_IntValue)) ){
30337
+ sqlite3_str_appendall(pAccum, (const char*)pExpr->u.zToken);
30338
+ sqlite3RecordErrorOffsetOfExpr(pAccum->db, pExpr);
30339
+ }
30340
+ }else{
30341
+ /* %T means a Token pointer */
30342
+ Token *pToken = va_arg(ap, Token*);
30343
+ assert( bArgList==0 );
30344
+ if( pToken && pToken->n ){
30345
+ sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
30346
+ sqlite3RecordErrorByteOffset(pAccum->db, pToken->z);
30347
+ }
3000030348
}
3000130349
length = width = 0;
3000230350
break;
3000330351
}
3000430352
case etSRCITEM: {
@@ -30072,10 +30420,22 @@
3007230420
zEnd = &zText[strlen(zText)];
3007330421
if( SQLITE_WITHIN(z,zText,zEnd) ){
3007430422
db->errByteOffset = (int)(z-zText);
3007530423
}
3007630424
}
30425
+
30426
+/*
30427
+** If pExpr has a byte offset for the start of a token, record that as
30428
+** as the error offset.
30429
+*/
30430
+SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){
30431
+ while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){
30432
+ pExpr = pExpr->pLeft;
30433
+ }
30434
+ if( pExpr==0 ) return;
30435
+ db->errByteOffset = pExpr->w.iOfst;
30436
+}
3007730437
3007830438
/*
3007930439
** Enlarge the memory allocation on a StrAccum object so that it is
3008030440
** able to accept at least N more bytes of text.
3008130441
**
@@ -30535,11 +30895,11 @@
3053530895
memset(p, 0, sizeof(*p));
3053630896
}else{
3053730897
p->iLevel++;
3053830898
}
3053930899
assert( moreToFollow==0 || moreToFollow==1 );
30540
- if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
30900
+ if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
3054130901
return p;
3054230902
}
3054330903
3054430904
/*
3054530905
** Finished with one layer of the tree
@@ -30559,11 +30919,11 @@
3055930919
int i;
3056030920
StrAccum acc;
3056130921
char zBuf[500];
3056230922
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
3056330923
if( p ){
30564
- for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
30924
+ for(i=0; i<p->iLevel && i<(int)sizeof(p->bLine)-1; i++){
3056530925
sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4);
3056630926
}
3056730927
sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
3056830928
}
3056930929
if( zFormat!=0 ){
@@ -30889,11 +31249,11 @@
3088931249
** Generate a human-readable explanation for a Window Function object
3089031250
*/
3089131251
SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
3089231252
pView = sqlite3TreeViewPush(pView, more);
3089331253
sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
30894
- pWin->pFunc->zName, pWin->pFunc->nArg);
31254
+ pWin->pWFunc->zName, pWin->pWFunc->nArg);
3089531255
sqlite3TreeViewWindow(pView, pWin, 0);
3089631256
sqlite3TreeViewPop(pView);
3089731257
}
3089831258
#endif /* SQLITE_OMIT_WINDOWFUNC */
3089931259
@@ -30914,11 +31274,11 @@
3091431274
StrAccum x;
3091531275
sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
3091631276
sqlite3_str_appendf(&x, " fg.af=%x.%c",
3091731277
pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
3091831278
if( ExprHasProperty(pExpr, EP_FromJoin) ){
30919
- sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable);
31279
+ sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable);
3092031280
}
3092131281
if( ExprHasProperty(pExpr, EP_FromDDL) ){
3092231282
sqlite3_str_appendf(&x, " DDL");
3092331283
}
3092431284
if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -34282,46 +34642,46 @@
3428234642
SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
3428334643
static const char *const azName[] = {
3428434644
/* 0 */ "Savepoint" OpHelp(""),
3428534645
/* 1 */ "AutoCommit" OpHelp(""),
3428634646
/* 2 */ "Transaction" OpHelp(""),
34287
- /* 3 */ "SorterNext" OpHelp(""),
34288
- /* 4 */ "Prev" OpHelp(""),
34289
- /* 5 */ "Next" OpHelp(""),
34290
- /* 6 */ "Checkpoint" OpHelp(""),
34291
- /* 7 */ "JournalMode" OpHelp(""),
34292
- /* 8 */ "Vacuum" OpHelp(""),
34293
- /* 9 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
34294
- /* 10 */ "VUpdate" OpHelp("data=r[P3@P2]"),
34295
- /* 11 */ "Goto" OpHelp(""),
34296
- /* 12 */ "Gosub" OpHelp(""),
34297
- /* 13 */ "InitCoroutine" OpHelp(""),
34298
- /* 14 */ "Yield" OpHelp(""),
34299
- /* 15 */ "MustBeInt" OpHelp(""),
34300
- /* 16 */ "Jump" OpHelp(""),
34301
- /* 17 */ "Once" OpHelp(""),
34302
- /* 18 */ "If" OpHelp(""),
34647
+ /* 3 */ "Checkpoint" OpHelp(""),
34648
+ /* 4 */ "JournalMode" OpHelp(""),
34649
+ /* 5 */ "Vacuum" OpHelp(""),
34650
+ /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
34651
+ /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"),
34652
+ /* 8 */ "Goto" OpHelp(""),
34653
+ /* 9 */ "Gosub" OpHelp(""),
34654
+ /* 10 */ "InitCoroutine" OpHelp(""),
34655
+ /* 11 */ "Yield" OpHelp(""),
34656
+ /* 12 */ "MustBeInt" OpHelp(""),
34657
+ /* 13 */ "Jump" OpHelp(""),
34658
+ /* 14 */ "Once" OpHelp(""),
34659
+ /* 15 */ "If" OpHelp(""),
34660
+ /* 16 */ "IfNot" OpHelp(""),
34661
+ /* 17 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
34662
+ /* 18 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
3430334663
/* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
34304
- /* 20 */ "IfNot" OpHelp(""),
34305
- /* 21 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
34306
- /* 22 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
34307
- /* 23 */ "SeekLT" OpHelp("key=r[P3@P4]"),
34308
- /* 24 */ "SeekLE" OpHelp("key=r[P3@P4]"),
34309
- /* 25 */ "SeekGE" OpHelp("key=r[P3@P4]"),
34310
- /* 26 */ "SeekGT" OpHelp("key=r[P3@P4]"),
34311
- /* 27 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"),
34312
- /* 28 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
34313
- /* 29 */ "NoConflict" OpHelp("key=r[P3@P4]"),
34314
- /* 30 */ "NotFound" OpHelp("key=r[P3@P4]"),
34315
- /* 31 */ "Found" OpHelp("key=r[P3@P4]"),
34316
- /* 32 */ "SeekRowid" OpHelp("intkey=r[P3]"),
34317
- /* 33 */ "NotExists" OpHelp("intkey=r[P3]"),
34318
- /* 34 */ "Last" OpHelp(""),
34319
- /* 35 */ "IfSmaller" OpHelp(""),
34320
- /* 36 */ "SorterSort" OpHelp(""),
34321
- /* 37 */ "Sort" OpHelp(""),
34322
- /* 38 */ "Rewind" OpHelp(""),
34664
+ /* 20 */ "SeekLT" OpHelp("key=r[P3@P4]"),
34665
+ /* 21 */ "SeekLE" OpHelp("key=r[P3@P4]"),
34666
+ /* 22 */ "SeekGE" OpHelp("key=r[P3@P4]"),
34667
+ /* 23 */ "SeekGT" OpHelp("key=r[P3@P4]"),
34668
+ /* 24 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"),
34669
+ /* 25 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
34670
+ /* 26 */ "NoConflict" OpHelp("key=r[P3@P4]"),
34671
+ /* 27 */ "NotFound" OpHelp("key=r[P3@P4]"),
34672
+ /* 28 */ "Found" OpHelp("key=r[P3@P4]"),
34673
+ /* 29 */ "SeekRowid" OpHelp("intkey=r[P3]"),
34674
+ /* 30 */ "NotExists" OpHelp("intkey=r[P3]"),
34675
+ /* 31 */ "Last" OpHelp(""),
34676
+ /* 32 */ "IfSmaller" OpHelp(""),
34677
+ /* 33 */ "SorterSort" OpHelp(""),
34678
+ /* 34 */ "Sort" OpHelp(""),
34679
+ /* 35 */ "Rewind" OpHelp(""),
34680
+ /* 36 */ "SorterNext" OpHelp(""),
34681
+ /* 37 */ "Prev" OpHelp(""),
34682
+ /* 38 */ "Next" OpHelp(""),
3432334683
/* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"),
3432434684
/* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"),
3432534685
/* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"),
3432634686
/* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"),
3432734687
/* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
@@ -34350,41 +34710,41 @@
3435034710
/* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
3435134711
/* 67 */ "Return" OpHelp(""),
3435234712
/* 68 */ "EndCoroutine" OpHelp(""),
3435334713
/* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
3435434714
/* 70 */ "Halt" OpHelp(""),
34355
- /* 71 */ "Integer" OpHelp("r[P2]=P1"),
34356
- /* 72 */ "Int64" OpHelp("r[P2]=P4"),
34357
- /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34358
- /* 74 */ "Null" OpHelp("r[P2..P3]=NULL"),
34359
- /* 75 */ "SoftNull" OpHelp("r[P1]=NULL"),
34360
- /* 76 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34361
- /* 77 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34362
- /* 78 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
34363
- /* 79 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
34364
- /* 80 */ "SCopy" OpHelp("r[P2]=r[P1]"),
34365
- /* 81 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
34366
- /* 82 */ "FkCheck" OpHelp(""),
34367
- /* 83 */ "ResultRow" OpHelp("output=r[P1@P2]"),
34368
- /* 84 */ "CollSeq" OpHelp(""),
34369
- /* 85 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
34370
- /* 86 */ "RealAffinity" OpHelp(""),
34371
- /* 87 */ "Cast" OpHelp("affinity(r[P1])"),
34372
- /* 88 */ "Permutation" OpHelp(""),
34373
- /* 89 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34374
- /* 90 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34375
- /* 91 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34376
- /* 92 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34377
- /* 93 */ "Column" OpHelp("r[P3]=PX"),
34378
- /* 94 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34379
- /* 95 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34380
- /* 96 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34381
- /* 97 */ "Count" OpHelp("r[P2]=count()"),
34382
- /* 98 */ "ReadCookie" OpHelp(""),
34383
- /* 99 */ "SetCookie" OpHelp(""),
34384
- /* 100 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
34385
- /* 101 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
34715
+ /* 71 */ "BeginSubrtn" OpHelp("r[P2]=P1"),
34716
+ /* 72 */ "Integer" OpHelp("r[P2]=P1"),
34717
+ /* 73 */ "Int64" OpHelp("r[P2]=P4"),
34718
+ /* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34719
+ /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"),
34720
+ /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"),
34721
+ /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34722
+ /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34723
+ /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
34724
+ /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
34725
+ /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"),
34726
+ /* 82 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
34727
+ /* 83 */ "FkCheck" OpHelp(""),
34728
+ /* 84 */ "ResultRow" OpHelp("output=r[P1@P2]"),
34729
+ /* 85 */ "CollSeq" OpHelp(""),
34730
+ /* 86 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
34731
+ /* 87 */ "RealAffinity" OpHelp(""),
34732
+ /* 88 */ "Cast" OpHelp("affinity(r[P1])"),
34733
+ /* 89 */ "Permutation" OpHelp(""),
34734
+ /* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34735
+ /* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34736
+ /* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34737
+ /* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34738
+ /* 94 */ "Column" OpHelp("r[P3]=PX"),
34739
+ /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34740
+ /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34741
+ /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34742
+ /* 98 */ "Count" OpHelp("r[P2]=count()"),
34743
+ /* 99 */ "ReadCookie" OpHelp(""),
34744
+ /* 100 */ "SetCookie" OpHelp(""),
34745
+ /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
3438634746
/* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
3438734747
/* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
3438834748
/* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
3438934749
/* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
3439034750
/* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
@@ -34391,82 +34751,84 @@
3439134751
/* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
3439234752
/* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
3439334753
/* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
3439434754
/* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
3439534755
/* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
34396
- /* 112 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
34397
- /* 113 */ "OpenDup" OpHelp(""),
34756
+ /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
34757
+ /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
3439834758
/* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
34399
- /* 115 */ "OpenAutoindex" OpHelp("nColumn=P2"),
34400
- /* 116 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34759
+ /* 115 */ "OpenDup" OpHelp(""),
34760
+ /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"),
3440134761
/* 117 */ "String8" OpHelp("r[P2]='P4'"),
34402
- /* 118 */ "SorterOpen" OpHelp(""),
34403
- /* 119 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34404
- /* 120 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34405
- /* 121 */ "Close" OpHelp(""),
34406
- /* 122 */ "ColumnsUsed" OpHelp(""),
34407
- /* 123 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34408
- /* 124 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34409
- /* 125 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34410
- /* 126 */ "NewRowid" OpHelp("r[P2]=rowid"),
34411
- /* 127 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34412
- /* 128 */ "RowCell" OpHelp(""),
34413
- /* 129 */ "Delete" OpHelp(""),
34414
- /* 130 */ "ResetCount" OpHelp(""),
34415
- /* 131 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34416
- /* 132 */ "SorterData" OpHelp("r[P2]=data"),
34417
- /* 133 */ "RowData" OpHelp("r[P2]=data"),
34418
- /* 134 */ "Rowid" OpHelp("r[P2]=rowid"),
34419
- /* 135 */ "NullRow" OpHelp(""),
34420
- /* 136 */ "SeekEnd" OpHelp(""),
34421
- /* 137 */ "IdxInsert" OpHelp("key=r[P2]"),
34422
- /* 138 */ "SorterInsert" OpHelp("key=r[P2]"),
34423
- /* 139 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34424
- /* 140 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34425
- /* 141 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34426
- /* 142 */ "FinishSeek" OpHelp(""),
34427
- /* 143 */ "Destroy" OpHelp(""),
34428
- /* 144 */ "Clear" OpHelp(""),
34429
- /* 145 */ "ResetSorter" OpHelp(""),
34430
- /* 146 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34431
- /* 147 */ "SqlExec" OpHelp(""),
34432
- /* 148 */ "ParseSchema" OpHelp(""),
34433
- /* 149 */ "LoadAnalysis" OpHelp(""),
34434
- /* 150 */ "DropTable" OpHelp(""),
34435
- /* 151 */ "DropIndex" OpHelp(""),
34436
- /* 152 */ "DropTrigger" OpHelp(""),
34762
+ /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34763
+ /* 119 */ "SorterOpen" OpHelp(""),
34764
+ /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34765
+ /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34766
+ /* 122 */ "Close" OpHelp(""),
34767
+ /* 123 */ "ColumnsUsed" OpHelp(""),
34768
+ /* 124 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34769
+ /* 125 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34770
+ /* 126 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34771
+ /* 127 */ "NewRowid" OpHelp("r[P2]=rowid"),
34772
+ /* 128 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34773
+ /* 129 */ "RowCell" OpHelp(""),
34774
+ /* 130 */ "Delete" OpHelp(""),
34775
+ /* 131 */ "ResetCount" OpHelp(""),
34776
+ /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34777
+ /* 133 */ "SorterData" OpHelp("r[P2]=data"),
34778
+ /* 134 */ "RowData" OpHelp("r[P2]=data"),
34779
+ /* 135 */ "Rowid" OpHelp("r[P2]=rowid"),
34780
+ /* 136 */ "NullRow" OpHelp(""),
34781
+ /* 137 */ "SeekEnd" OpHelp(""),
34782
+ /* 138 */ "IdxInsert" OpHelp("key=r[P2]"),
34783
+ /* 139 */ "SorterInsert" OpHelp("key=r[P2]"),
34784
+ /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34785
+ /* 141 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34786
+ /* 142 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34787
+ /* 143 */ "FinishSeek" OpHelp(""),
34788
+ /* 144 */ "Destroy" OpHelp(""),
34789
+ /* 145 */ "Clear" OpHelp(""),
34790
+ /* 146 */ "ResetSorter" OpHelp(""),
34791
+ /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34792
+ /* 148 */ "SqlExec" OpHelp(""),
34793
+ /* 149 */ "ParseSchema" OpHelp(""),
34794
+ /* 150 */ "LoadAnalysis" OpHelp(""),
34795
+ /* 151 */ "DropTable" OpHelp(""),
34796
+ /* 152 */ "DropIndex" OpHelp(""),
3443734797
/* 153 */ "Real" OpHelp("r[P2]=P4"),
34438
- /* 154 */ "IntegrityCk" OpHelp(""),
34439
- /* 155 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34440
- /* 156 */ "Param" OpHelp(""),
34441
- /* 157 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34442
- /* 158 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34443
- /* 159 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34444
- /* 160 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34445
- /* 161 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34446
- /* 162 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34447
- /* 163 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34448
- /* 164 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34449
- /* 165 */ "Expire" OpHelp(""),
34450
- /* 166 */ "CursorLock" OpHelp(""),
34451
- /* 167 */ "CursorUnlock" OpHelp(""),
34452
- /* 168 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34453
- /* 169 */ "VBegin" OpHelp(""),
34454
- /* 170 */ "VCreate" OpHelp(""),
34455
- /* 171 */ "VDestroy" OpHelp(""),
34456
- /* 172 */ "VOpen" OpHelp(""),
34457
- /* 173 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34458
- /* 174 */ "VRename" OpHelp(""),
34459
- /* 175 */ "Pagecount" OpHelp(""),
34460
- /* 176 */ "MaxPgcnt" OpHelp(""),
34461
- /* 177 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
34462
- /* 178 */ "Trace" OpHelp(""),
34463
- /* 179 */ "CursorHint" OpHelp(""),
34464
- /* 180 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34465
- /* 181 */ "Noop" OpHelp(""),
34466
- /* 182 */ "Explain" OpHelp(""),
34467
- /* 183 */ "Abortable" OpHelp(""),
34798
+ /* 154 */ "DropTrigger" OpHelp(""),
34799
+ /* 155 */ "IntegrityCk" OpHelp(""),
34800
+ /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34801
+ /* 157 */ "Param" OpHelp(""),
34802
+ /* 158 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34803
+ /* 159 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34804
+ /* 160 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34805
+ /* 161 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34806
+ /* 162 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34807
+ /* 163 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34808
+ /* 164 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34809
+ /* 165 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34810
+ /* 166 */ "Expire" OpHelp(""),
34811
+ /* 167 */ "CursorLock" OpHelp(""),
34812
+ /* 168 */ "CursorUnlock" OpHelp(""),
34813
+ /* 169 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34814
+ /* 170 */ "VBegin" OpHelp(""),
34815
+ /* 171 */ "VCreate" OpHelp(""),
34816
+ /* 172 */ "VDestroy" OpHelp(""),
34817
+ /* 173 */ "VOpen" OpHelp(""),
34818
+ /* 174 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"),
34819
+ /* 175 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34820
+ /* 176 */ "VRename" OpHelp(""),
34821
+ /* 177 */ "Pagecount" OpHelp(""),
34822
+ /* 178 */ "MaxPgcnt" OpHelp(""),
34823
+ /* 179 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
34824
+ /* 180 */ "Trace" OpHelp(""),
34825
+ /* 181 */ "CursorHint" OpHelp(""),
34826
+ /* 182 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34827
+ /* 183 */ "Noop" OpHelp(""),
34828
+ /* 184 */ "Explain" OpHelp(""),
34829
+ /* 185 */ "Abortable" OpHelp(""),
3446834830
};
3446934831
return azName[i];
3447034832
}
3447134833
#endif
3447234834
@@ -39382,15 +39744,21 @@
3938239744
int ofst, /* First lock to acquire or release */
3938339745
int n, /* Number of locks to acquire or release */
3938439746
int flags /* What to do with the lock */
3938539747
){
3938639748
unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
39387
- unixShm *p = pDbFd->pShm; /* The shared memory being locked */
39388
- unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */
39749
+ unixShm *p; /* The shared memory being locked */
39750
+ unixShmNode *pShmNode; /* The underlying file iNode */
3938939751
int rc = SQLITE_OK; /* Result code */
3939039752
u16 mask; /* Mask of locks to take or release */
39391
- int *aLock = pShmNode->aLock;
39753
+ int *aLock;
39754
+
39755
+ p = pDbFd->pShm;
39756
+ if( p==0 ) return SQLITE_IOERR_SHMLOCK;
39757
+ pShmNode = p->pShmNode;
39758
+ if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
39759
+ aLock = pShmNode->aLock;
3939239760
3939339761
assert( pShmNode==pDbFd->pInode->pShmNode );
3939439762
assert( pShmNode->pInode==pDbFd->pInode );
3939539763
assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
3939639764
assert( n>=1 );
@@ -40483,24 +40851,27 @@
4048340851
** "<path to db>-journalNN"
4048440852
** "<path to db>-walNN"
4048540853
**
4048640854
** where NN is a decimal number. The NN naming schemes are
4048740855
** used by the test_multiplex.c module.
40856
+ **
40857
+ ** In normal operation, the journal file name will always contain
40858
+ ** a '-' character. However in 8+3 filename mode, or if a corrupt
40859
+ ** rollback journal specifies a super-journal with a goofy name, then
40860
+ ** the '-' might be missing or the '-' might be the first character in
40861
+ ** the filename. In that case, just return SQLITE_OK with *pMode==0.
4048840862
*/
4048940863
nDb = sqlite3Strlen30(zPath) - 1;
40490
- while( zPath[nDb]!='-' ){
40491
- /* In normal operation, the journal file name will always contain
40492
- ** a '-' character. However in 8+3 filename mode, or if a corrupt
40493
- ** rollback journal specifies a super-journal with a goofy name, then
40494
- ** the '-' might be missing. */
40495
- if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
40864
+ while( nDb>0 && zPath[nDb]!='.' ){
40865
+ if( zPath[nDb]=='-' ){
40866
+ memcpy(zDb, zPath, nDb);
40867
+ zDb[nDb] = '\0';
40868
+ rc = getFileMode(zDb, pMode, pUid, pGid);
40869
+ break;
40870
+ }
4049640871
nDb--;
4049740872
}
40498
- memcpy(zDb, zPath, nDb);
40499
- zDb[nDb] = '\0';
40500
-
40501
- rc = getFileMode(zDb, pMode, pUid, pGid);
4050240873
}else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
4050340874
*pMode = 0600;
4050440875
}else if( flags & SQLITE_OPEN_URI ){
4050540876
/* If this is a main database file and the file was opened using a URI
4050640877
** filename, check for the "modeof" parameter. If present, interpret
@@ -46674,14 +47045,18 @@
4667447045
int flags /* What to do with the lock */
4667547046
){
4667647047
winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */
4667747048
winShm *p = pDbFd->pShm; /* The shared memory being locked */
4667847049
winShm *pX; /* For looping over all siblings */
46679
- winShmNode *pShmNode = p->pShmNode;
47050
+ winShmNode *pShmNode;
4668047051
int rc = SQLITE_OK; /* Result code */
4668147052
u16 mask; /* Mask of locks to take or release */
4668247053
47054
+ if( p==0 ) return SQLITE_IOERR_SHMLOCK;
47055
+ pShmNode = p->pShmNode;
47056
+ if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
47057
+
4668347058
assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
4668447059
assert( n>=1 );
4668547060
assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
4668647061
|| flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
4668747062
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
@@ -53576,10 +53951,11 @@
5357653951
u16 nExtra; /* Add this many bytes to each in-memory page */
5357753952
i16 nReserve; /* Number of unused bytes at end of each page */
5357853953
u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
5357953954
u32 sectorSize; /* Assumed sector size during rollback */
5358053955
Pgno mxPgno; /* Maximum allowed size of the database */
53956
+ Pgno lckPgno; /* Page number for the locking page */
5358153957
i64 pageSize; /* Number of bytes in a page */
5358253958
i64 journalSizeLimit; /* Size limit for persistent journal files */
5358353959
char *zFilename; /* Name of the database file */
5358453960
char *zJournal; /* Name of the journal file */
5358553961
int (*xBusyHandler)(void*); /* Function to call when busy */
@@ -54562,11 +54938,11 @@
5456254938
** pPager at the current location. The super-journal name must be the last
5456354939
** thing written to a journal file. If the pager is in full-sync mode, the
5456454940
** journal file descriptor is advanced to the next sector boundary before
5456554941
** anything is written. The format is:
5456654942
**
54567
-** + 4 bytes: PAGER_MJ_PGNO.
54943
+** + 4 bytes: PAGER_SJ_PGNO.
5456854944
** + N bytes: super-journal filename in utf-8.
5456954945
** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator).
5457054946
** + 4 bytes: super-journal name checksum.
5457154947
** + 8 bytes: aJournalMagic[].
5457254948
**
@@ -54610,11 +54986,11 @@
5461054986
iHdrOff = pPager->journalOff;
5461154987
5461254988
/* Write the super-journal data to the end of the journal file. If
5461354989
** an error occurs, return the error code to the caller.
5461454990
*/
54615
- if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
54991
+ if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_SJ_PGNO(pPager))))
5461654992
|| (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4)))
5461754993
|| (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper)))
5461854994
|| (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum)))
5461954995
|| (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8,
5462054996
iHdrOff+4+nSuper+8)))
@@ -55120,11 +55496,11 @@
5512055496
** to the database file, then the IO error code is returned. If data
5512155497
** is successfully read from the (sub-)journal file but appears to be
5512255498
** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
5512355499
** two circumstances:
5512455500
**
55125
-** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
55501
+** * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or
5512655502
** * If the record is being rolled back from the main journal file
5512755503
** and the checksum field does not match the record content.
5512855504
**
5512955505
** Neither of these two scenarios are possible during a savepoint rollback.
5513055506
**
@@ -55180,11 +55556,11 @@
5518055556
/* Sanity checking on the page. This is more important that I originally
5518155557
** thought. If a power failure occurs while the journal is being written,
5518255558
** it could cause invalid data to be written into the journal. We need to
5518355559
** detect this invalid data (with high probability) and ignore it.
5518455560
*/
55185
- if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
55561
+ if( pgno==0 || pgno==PAGER_SJ_PGNO(pPager) ){
5518655562
assert( !isSavepnt );
5518755563
return SQLITE_DONE;
5518855564
}
5518955565
if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
5519055566
return SQLITE_OK;
@@ -55739,10 +56115,13 @@
5573956115
rc = pager_truncate(pPager, mxPg);
5574056116
if( rc!=SQLITE_OK ){
5574156117
goto end_playback;
5574256118
}
5574356119
pPager->dbSize = mxPg;
56120
+ if( pPager->mxPgno<mxPg ){
56121
+ pPager->mxPgno = mxPg;
56122
+ }
5574456123
}
5574556124
5574656125
/* Copy original pages out of the journal and back into the
5574756126
** database file and/or page cache.
5574856127
*/
@@ -56635,10 +57014,11 @@
5663557014
if( rc==SQLITE_OK ){
5663657015
sqlite3PageFree(pPager->pTmpSpace);
5663757016
pPager->pTmpSpace = pNew;
5663857017
pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
5663957018
pPager->pageSize = pageSize;
57019
+ pPager->lckPgno = (Pgno)(PENDING_BYTE/pageSize) + 1;
5664057020
}else{
5664157021
sqlite3PageFree(pNew);
5664257022
}
5664357023
}
5664457024
@@ -56840,11 +57220,11 @@
5684057220
** Once this function has been called, the transaction must either be
5684157221
** rolled back or committed. It is not safe to call this function and
5684257222
** then continue writing to the database.
5684357223
*/
5684457224
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
56845
- assert( pPager->dbSize>=nPage );
57225
+ assert( pPager->dbSize>=nPage || CORRUPT_DB );
5684657226
assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
5684757227
pPager->dbSize = nPage;
5684857228
5684957229
/* At one point the code here called assertTruncateConstraint() to
5685057230
** ensure that all pages being truncated away by this operation are,
@@ -58404,11 +58784,11 @@
5840458784
5840558785
noContent = (flags & PAGER_GET_NOCONTENT)!=0;
5840658786
if( pPg->pPager && !noContent ){
5840758787
/* In this case the pcache already contains an initialized copy of
5840858788
** the page. Return without further ado. */
58409
- assert( pgno!=PAGER_MJ_PGNO(pPager) );
58789
+ assert( pgno!=PAGER_SJ_PGNO(pPager) );
5841058790
pPager->aStat[PAGER_STAT_HIT]++;
5841158791
return SQLITE_OK;
5841258792
5841358793
}else{
5841458794
/* The pager cache has created a new page. Its content needs to
@@ -58415,11 +58795,11 @@
5841558795
** be initialized. But first some error checks:
5841658796
**
5841758797
** (*) obsolete. Was: maximum page number is 2^31
5841858798
** (2) Never try to fetch the locking page
5841958799
*/
58420
- if( pgno==PAGER_MJ_PGNO(pPager) ){
58800
+ if( pgno==PAGER_SJ_PGNO(pPager) ){
5842158801
rc = SQLITE_CORRUPT_BKPT;
5842258802
goto pager_acquire_err;
5842358803
}
5842458804
5842558805
pPg->pPager = pPager;
@@ -58814,11 +59194,11 @@
5881459194
i64 iOff = pPager->journalOff;
5881559195
5881659196
/* We should never write to the journal file the page that
5881759197
** contains the database locks. The following assert verifies
5881859198
** that we do not. */
58819
- assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
59199
+ assert( pPg->pgno!=PAGER_SJ_PGNO(pPager) );
5882059200
5882159201
assert( pPager->journalHdr<=pPager->journalOff );
5882259202
pData2 = pPg->pData;
5882359203
cksum = pager_cksum(pPager, (u8*)pData2);
5882459204
@@ -58993,11 +59373,11 @@
5899359373
5899459374
for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
5899559375
Pgno pg = pg1+ii;
5899659376
PgHdr *pPage;
5899759377
if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
58998
- if( pg!=PAGER_MJ_PGNO(pPager) ){
59378
+ if( pg!=PAGER_SJ_PGNO(pPager) ){
5899959379
rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
5900059380
if( rc==SQLITE_OK ){
5900159381
rc = pager_write(pPage);
5900259382
if( pPage->flags&PGHDR_NEED_SYNC ){
5900359383
needSync = 1;
@@ -59471,11 +59851,11 @@
5947159851
** image was extended as part of the current transaction and then the
5947259852
** last page in the db image moved to the free-list. In this case the
5947359853
** last page is never written out to disk, leaving the database file
5947459854
** undersized. Fix this now if it is the case. */
5947559855
if( pPager->dbSize>pPager->dbFileSize ){
59476
- Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
59856
+ Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_SJ_PGNO(pPager));
5947759857
assert( pPager->eState==PAGER_WRITER_DBMOD );
5947859858
rc = pager_truncate(pPager, nNew);
5947959859
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
5948059860
}
5948159861
@@ -60320,10 +60700,22 @@
6032060700
int eMode, /* Type of checkpoint */
6032160701
int *pnLog, /* OUT: Final number of frames in log */
6032260702
int *pnCkpt /* OUT: Final number of checkpointed frames */
6032360703
){
6032460704
int rc = SQLITE_OK;
60705
+ if( pPager->pWal==0 && pPager->journalMode==PAGER_JOURNALMODE_WAL ){
60706
+ /* This only happens when a database file is zero bytes in size opened and
60707
+ ** then "PRAGMA journal_mode=WAL" is run and then sqlite3_wal_checkpoint()
60708
+ ** is invoked without any intervening transactions. We need to start
60709
+ ** a transaction to initialize pWal. The PRAGMA table_list statement is
60710
+ ** used for this since it starts transactions on every database file,
60711
+ ** including all ATTACHed databases. This seems expensive for a single
60712
+ ** sqlite3_wal_checkpoint() call, but it happens very rarely.
60713
+ ** https://sqlite.org/forum/forumpost/fd0f19d229156939
60714
+ */
60715
+ sqlite3_exec(db, "PRAGMA table_list",0,0,0);
60716
+ }
6032560717
if( pPager->pWal ){
6032660718
rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
6032760719
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
6032860720
pPager->pBusyHandlerArg,
6032960721
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
@@ -65086,11 +65478,13 @@
6508665478
u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th
6508765479
** non-overflow cell */
6508865480
u8 *apOvfl[4]; /* Pointers to the body of overflow cells */
6508965481
BtShared *pBt; /* Pointer to BtShared that this page is part of */
6509065482
u8 *aData; /* Pointer to disk image of the page data */
65091
- u8 *aDataEnd; /* One byte past the end of usable data */
65483
+ u8 *aDataEnd; /* One byte past the end of the entire page - not just
65484
+ ** the usable space, the entire page. Used to prevent
65485
+ ** corruption-induced buffer overflow. */
6509265486
u8 *aCellIdx; /* The cell index area */
6509365487
u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */
6509465488
DbPage *pDbPage; /* Pager page handle */
6509565489
u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
6509665490
void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
@@ -65391,11 +65785,11 @@
6539165785
#define CURSOR_FAULT 4
6539265786
6539365787
/*
6539465788
** The database page the PENDING_BYTE occupies. This page is never used.
6539565789
*/
65396
-# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
65790
+#define PENDING_BYTE_PAGE(pBt) ((Pgno)((PENDING_BYTE/((pBt)->pageSize))+1))
6539765791
6539865792
/*
6539965793
** These macros define the location of the pointer-map entry for a
6540065794
** database page. The first argument to each is the number of usable
6540165795
** bytes on each page of the database (often 1024). The second is the
@@ -66032,11 +66426,11 @@
6603266426
if( isIndex ){
6603366427
HashElem *p;
6603466428
int bSeen = 0;
6603566429
for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
6603666430
Index *pIdx = (Index *)sqliteHashData(p);
66037
- if( pIdx->tnum==(int)iRoot ){
66431
+ if( pIdx->tnum==iRoot ){
6603866432
if( bSeen ){
6603966433
/* Two or more indexes share the same root page. There must
6604066434
** be imposter tables. So just return true. The assert is not
6604166435
** useful in that case. */
6604266436
return 1;
@@ -66625,11 +67019,11 @@
6662567019
}
6662667020
6662767021
/*
6662867022
** In this version of BtreeMoveto, pKey is a packed index record
6662967023
** such as is generated by the OP_MakeRecord opcode. Unpack the
66630
-** record and then call BtreeMovetoUnpacked() to do the work.
67024
+** record and then call sqlite3BtreeIndexMoveto() to do the work.
6663167025
*/
6663267026
static int btreeMoveto(
6663367027
BtCursor *pCur, /* Cursor open on the btree to be searched */
6663467028
const void *pKey, /* Packed key if the btree is an index */
6663567029
i64 nKey, /* Integer key for tables. Size of pKey for indices */
@@ -67145,10 +67539,11 @@
6714567539
** data area of the btree-page. The return number includes the cell
6714667540
** data header and the local payload, but not any overflow page or
6714767541
** the space used by the cell pointer.
6714867542
**
6714967543
** cellSizePtrNoPayload() => table internal nodes
67544
+** cellSizePtrTableLeaf() => table leaf nodes
6715067545
** cellSizePtr() => all index nodes & table leaf nodes
6715167546
*/
6715267547
static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
6715367548
u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
6715467549
u8 *pEnd; /* End mark for a varint */
@@ -67170,17 +67565,10 @@
6717067565
do{
6717167566
nSize = (nSize<<7) | (*++pIter & 0x7f);
6717267567
}while( *(pIter)>=0x80 && pIter<pEnd );
6717367568
}
6717467569
pIter++;
67175
- if( pPage->intKey ){
67176
- /* pIter now points at the 64-bit integer key value, a variable length
67177
- ** integer. The following block moves pIter to point at the first byte
67178
- ** past the end of the key value. */
67179
- pEnd = &pIter[9];
67180
- while( (*pIter++)&0x80 && pIter<pEnd );
67181
- }
6718267570
testcase( nSize==pPage->maxLocal );
6718367571
testcase( nSize==(u32)pPage->maxLocal+1 );
6718467572
if( nSize<=pPage->maxLocal ){
6718567573
nSize += (u32)(pIter - pCell);
6718667574
if( nSize<4 ) nSize = 4;
@@ -67216,10 +67604,62 @@
6721667604
pEnd = pIter + 9;
6721767605
while( (*pIter++)&0x80 && pIter<pEnd );
6721867606
assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB );
6721967607
return (u16)(pIter - pCell);
6722067608
}
67609
+static u16 cellSizePtrTableLeaf(MemPage *pPage, u8 *pCell){
67610
+ u8 *pIter = pCell; /* For looping over bytes of pCell */
67611
+ u8 *pEnd; /* End mark for a varint */
67612
+ u32 nSize; /* Size value to return */
67613
+
67614
+#ifdef SQLITE_DEBUG
67615
+ /* The value returned by this function should always be the same as
67616
+ ** the (CellInfo.nSize) value found by doing a full parse of the
67617
+ ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
67618
+ ** this function verifies that this invariant is not violated. */
67619
+ CellInfo debuginfo;
67620
+ pPage->xParseCell(pPage, pCell, &debuginfo);
67621
+#endif
67622
+
67623
+ nSize = *pIter;
67624
+ if( nSize>=0x80 ){
67625
+ pEnd = &pIter[8];
67626
+ nSize &= 0x7f;
67627
+ do{
67628
+ nSize = (nSize<<7) | (*++pIter & 0x7f);
67629
+ }while( *(pIter)>=0x80 && pIter<pEnd );
67630
+ }
67631
+ pIter++;
67632
+ /* pIter now points at the 64-bit integer key value, a variable length
67633
+ ** integer. The following block moves pIter to point at the first byte
67634
+ ** past the end of the key value. */
67635
+ if( (*pIter++)&0x80
67636
+ && (*pIter++)&0x80
67637
+ && (*pIter++)&0x80
67638
+ && (*pIter++)&0x80
67639
+ && (*pIter++)&0x80
67640
+ && (*pIter++)&0x80
67641
+ && (*pIter++)&0x80
67642
+ && (*pIter++)&0x80 ){ pIter++; }
67643
+ testcase( nSize==pPage->maxLocal );
67644
+ testcase( nSize==(u32)pPage->maxLocal+1 );
67645
+ if( nSize<=pPage->maxLocal ){
67646
+ nSize += (u32)(pIter - pCell);
67647
+ if( nSize<4 ) nSize = 4;
67648
+ }else{
67649
+ int minLocal = pPage->minLocal;
67650
+ nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
67651
+ testcase( nSize==pPage->maxLocal );
67652
+ testcase( nSize==(u32)pPage->maxLocal+1 );
67653
+ if( nSize>pPage->maxLocal ){
67654
+ nSize = minLocal;
67655
+ }
67656
+ nSize += 4 + (u16)(pIter - pCell);
67657
+ }
67658
+ assert( nSize==debuginfo.nSize || CORRUPT_DB );
67659
+ return (u16)nSize;
67660
+}
6722167661
6722267662
6722367663
#ifdef SQLITE_DEBUG
6722467664
/* This variation on cellSizePtr() is used inside of assert() statements
6722567665
** only. */
@@ -67229,11 +67669,11 @@
6722967669
#endif
6723067670
6723167671
#ifndef SQLITE_OMIT_AUTOVACUUM
6723267672
/*
6723367673
** The cell pCell is currently part of page pSrc but will ultimately be part
67234
-** of pPage. (pSrc and pPager are often the same.) If pCell contains a
67674
+** of pPage. (pSrc and pPage are often the same.) If pCell contains a
6723567675
** pointer to an overflow page, insert an entry into the pointer-map for
6723667676
** the overflow page that will be valid after pCell has been moved to pPage.
6723767677
*/
6723867678
static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
6723967679
CellInfo info;
@@ -67404,21 +67844,23 @@
6740467844
*/
6740567845
static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
6740667846
const int hdr = pPg->hdrOffset; /* Offset to page header */
6740767847
u8 * const aData = pPg->aData; /* Page data */
6740867848
int iAddr = hdr + 1; /* Address of ptr to pc */
67409
- int pc = get2byte(&aData[iAddr]); /* Address of a free slot */
67849
+ u8 *pTmp = &aData[iAddr]; /* Temporary ptr into aData[] */
67850
+ int pc = get2byte(pTmp); /* Address of a free slot */
6741067851
int x; /* Excess size of the slot */
6741167852
int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */
6741267853
int size; /* Size of the free slot */
6741367854
6741467855
assert( pc>0 );
6741567856
while( pc<=maxPC ){
6741667857
/* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
6741767858
** freeblock form a big-endian integer which is the size of the freeblock
6741867859
** in bytes, including the 4-byte header. */
67419
- size = get2byte(&aData[pc+2]);
67860
+ pTmp = &aData[pc+2];
67861
+ size = get2byte(pTmp);
6742067862
if( (x = size - nByte)>=0 ){
6742167863
testcase( x==4 );
6742267864
testcase( x==3 );
6742367865
if( x<4 ){
6742467866
/* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
@@ -67439,11 +67881,12 @@
6743967881
put2byte(&aData[pc+2], x);
6744067882
}
6744167883
return &aData[pc + x];
6744267884
}
6744367885
iAddr = pc;
67444
- pc = get2byte(&aData[pc]);
67886
+ pTmp = &aData[pc];
67887
+ pc = get2byte(pTmp);
6744567888
if( pc<=iAddr+size ){
6744667889
if( pc ){
6744767890
/* The next slot in the chain is not past the end of the current slot */
6744867891
*pRc = SQLITE_CORRUPT_PAGE(pPg);
6744967892
}
@@ -67473,10 +67916,11 @@
6747367916
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
6747467917
const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
6747567918
u8 * const data = pPage->aData; /* Local cache of pPage->aData */
6747667919
int top; /* First byte of cell content area */
6747767920
int rc = SQLITE_OK; /* Integer return code */
67921
+ u8 *pTmp; /* Temp ptr into data[] */
6747867922
int gap; /* First byte of gap between cell pointers and cell content */
6747967923
6748067924
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
6748167925
assert( pPage->pBt );
6748267926
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
@@ -67491,11 +67935,12 @@
6749167935
/* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
6749267936
** and the reserved space is zero (the usual value for reserved space)
6749367937
** then the cell content offset of an empty page wants to be 65536.
6749467938
** However, that integer is too large to be stored in a 2-byte unsigned
6749567939
** integer, so a value of 0 is used in its place. */
67496
- top = get2byte(&data[hdr+5]);
67940
+ pTmp = &data[hdr+5];
67941
+ top = get2byte(pTmp);
6749767942
assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
6749867943
if( gap>top ){
6749967944
if( top==0 && pPage->pBt->usableSize==65536 ){
6750067945
top = 65536;
6750167946
}else{
@@ -67573,10 +68018,11 @@
6757368018
u8 nFrag = 0; /* Reduction in fragmentation */
6757468019
u16 iOrigSize = iSize; /* Original value of iSize */
6757568020
u16 x; /* Offset to cell content area */
6757668021
u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
6757768022
unsigned char *data = pPage->aData; /* Page content */
68023
+ u8 *pTmp; /* Temporary ptr into data[] */
6757868024
6757968025
assert( pPage->pBt!=0 );
6758068026
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
6758168027
assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
6758268028
assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
@@ -67600,11 +68046,11 @@
6760068046
iPtr = iFreeBlk;
6760168047
}
6760268048
if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
6760368049
return SQLITE_CORRUPT_PAGE(pPage);
6760468050
}
67605
- assert( iFreeBlk>iPtr || iFreeBlk==0 );
68051
+ assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB );
6760668052
6760768053
/* At this point:
6760868054
** iFreeBlk: First freeblock after iStart, or zero if none
6760968055
** iPtr: The address of a pointer to iFreeBlk
6761068056
**
@@ -67635,11 +68081,12 @@
6763568081
}
6763668082
}
6763768083
if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
6763868084
data[hdr+7] -= nFrag;
6763968085
}
67640
- x = get2byte(&data[hdr+5]);
68086
+ pTmp = &data[hdr+5];
68087
+ x = get2byte(pTmp);
6764168088
if( iStart<=x ){
6764268089
/* The new freeblock is at the beginning of the cell content area,
6764368090
** so just extend the cell content area rather than create another
6764468091
** freelist entry */
6764568092
if( iStart<x ) return SQLITE_CORRUPT_PAGE(pPage);
@@ -67679,11 +68126,10 @@
6767968126
assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
6768068127
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
6768168128
pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 );
6768268129
flagByte &= ~PTF_LEAF;
6768368130
pPage->childPtrSize = 4-4*pPage->leaf;
67684
- pPage->xCellSize = cellSizePtr;
6768568131
pBt = pPage->pBt;
6768668132
if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
6768768133
/* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
6768868134
** interior table b-tree page. */
6768968135
assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
@@ -67691,10 +68137,11 @@
6769168137
** leaf table b-tree page. */
6769268138
assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
6769368139
pPage->intKey = 1;
6769468140
if( pPage->leaf ){
6769568141
pPage->intKeyLeaf = 1;
68142
+ pPage->xCellSize = cellSizePtrTableLeaf;
6769668143
pPage->xParseCell = btreeParseCellPtr;
6769768144
}else{
6769868145
pPage->intKeyLeaf = 0;
6769968146
pPage->xCellSize = cellSizePtrNoPayload;
6770068147
pPage->xParseCell = btreeParseCellPtrNoPayload;
@@ -67708,16 +68155,21 @@
6770868155
/* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
6770968156
** leaf index b-tree page. */
6771068157
assert( (PTF_ZERODATA|PTF_LEAF)==10 );
6771168158
pPage->intKey = 0;
6771268159
pPage->intKeyLeaf = 0;
68160
+ pPage->xCellSize = cellSizePtr;
6771368161
pPage->xParseCell = btreeParseCellPtrIndex;
6771468162
pPage->maxLocal = pBt->maxLocal;
6771568163
pPage->minLocal = pBt->minLocal;
6771668164
}else{
6771768165
/* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
6771868166
** an error. */
68167
+ pPage->intKey = 0;
68168
+ pPage->intKeyLeaf = 0;
68169
+ pPage->xCellSize = cellSizePtr;
68170
+ pPage->xParseCell = btreeParseCellPtrIndex;
6771968171
return SQLITE_CORRUPT_PAGE(pPage);
6772068172
}
6772168173
pPage->max1bytePayload = pBt->max1bytePayload;
6772268174
return SQLITE_OK;
6772368175
}
@@ -67871,11 +68323,11 @@
6787168323
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
6787268324
pPage->maskPage = (u16)(pBt->pageSize - 1);
6787368325
pPage->nOverflow = 0;
6787468326
pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize;
6787568327
pPage->aCellIdx = data + pPage->childPtrSize + 8;
67876
- pPage->aDataEnd = pPage->aData + pBt->usableSize;
68328
+ pPage->aDataEnd = pPage->aData + pBt->pageSize;
6787768329
pPage->aDataOfst = pPage->aData + pPage->childPtrSize;
6787868330
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
6787968331
** number of cells on the page. */
6788068332
pPage->nCell = get2byte(&data[3]);
6788168333
if( pPage->nCell>MX_CELL(pBt) ){
@@ -67906,11 +68358,11 @@
6790668358
unsigned char *data = pPage->aData;
6790768359
BtShared *pBt = pPage->pBt;
6790868360
u8 hdr = pPage->hdrOffset;
6790968361
u16 first;
6791068362
67911
- assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
68363
+ assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB );
6791268364
assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
6791368365
assert( sqlite3PagerGetData(pPage->pDbPage) == data );
6791468366
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
6791568367
assert( sqlite3_mutex_held(pBt->mutex) );
6791668368
if( pBt->btsFlags & BTS_FAST_SECURE ){
@@ -67922,11 +68374,11 @@
6792268374
data[hdr+7] = 0;
6792368375
put2byte(&data[hdr+5], pBt->usableSize);
6792468376
pPage->nFree = (u16)(pBt->usableSize - first);
6792568377
decodeFlags(pPage, flags);
6792668378
pPage->cellOffset = first;
67927
- pPage->aDataEnd = &data[pBt->usableSize];
68379
+ pPage->aDataEnd = &data[pBt->pageSize];
6792868380
pPage->aCellIdx = &data[first];
6792968381
pPage->aDataOfst = &data[pPage->childPtrSize];
6793068382
pPage->nOverflow = 0;
6793168383
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
6793268384
pPage->maskPage = (u16)(pBt->pageSize - 1);
@@ -68048,11 +68500,11 @@
6804868500
rc = btreeInitPage(*ppPage);
6804968501
if( rc!=SQLITE_OK ){
6805068502
goto getAndInitPage_error2;
6805168503
}
6805268504
}
68053
- assert( (*ppPage)->pgno==pgno );
68505
+ assert( (*ppPage)->pgno==pgno || CORRUPT_DB );
6805468506
assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
6805568507
6805668508
/* If obtaining a child page for a cursor, we must verify that the page is
6805768509
** compatible with the root page. */
6805868510
if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
@@ -68067,11 +68519,13 @@
6806768519
if( pCur ){
6806868520
pCur->iPage--;
6806968521
pCur->pPage = pCur->apPage[pCur->iPage];
6807068522
}
6807168523
testcase( pgno==0 );
68072
- assert( pgno!=0 || rc==SQLITE_CORRUPT );
68524
+ assert( pgno!=0 || rc==SQLITE_CORRUPT
68525
+ || rc==SQLITE_IOERR_NOMEM
68526
+ || rc==SQLITE_NOMEM );
6807368527
return rc;
6807468528
}
6807568529
6807668530
/*
6807768531
** Release a MemPage. This should be called once for each prior
@@ -71135,11 +71589,11 @@
7113571589
}
7113671590
pCur->iPage = 0;
7113771591
pCur->curIntKey = pCur->pPage->intKey;
7113871592
}
7113971593
pRoot = pCur->pPage;
71140
- assert( pRoot->pgno==pCur->pgnoRoot );
71594
+ assert( pRoot->pgno==pCur->pgnoRoot || CORRUPT_DB );
7114171595
7114271596
/* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
7114371597
** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
7114471598
** NULL, the caller expects a table b-tree. If this is not the case,
7114571599
** return an SQLITE_CORRUPT error.
@@ -71455,10 +71909,73 @@
7145571909
moveto_table_finish:
7145671910
pCur->info.nSize = 0;
7145771911
assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
7145871912
return rc;
7145971913
}
71914
+
71915
+/*
71916
+** Compare the "idx"-th cell on the page the cursor pCur is currently
71917
+** pointing to to pIdxKey using xRecordCompare. Return negative or
71918
+** zero if the cell is less than or equal pIdxKey. Return positive
71919
+** if unknown.
71920
+**
71921
+** Return value negative: Cell at pCur[idx] less than pIdxKey
71922
+**
71923
+** Return value is zero: Cell at pCur[idx] equals pIdxKey
71924
+**
71925
+** Return value positive: Nothing is known about the relationship
71926
+** of the cell at pCur[idx] and pIdxKey.
71927
+**
71928
+** This routine is part of an optimization. It is always safe to return
71929
+** a positive value as that will cause the optimization to be skipped.
71930
+*/
71931
+static int indexCellCompare(
71932
+ BtCursor *pCur,
71933
+ int idx,
71934
+ UnpackedRecord *pIdxKey,
71935
+ RecordCompare xRecordCompare
71936
+){
71937
+ MemPage *pPage = pCur->pPage;
71938
+ int c;
71939
+ int nCell; /* Size of the pCell cell in bytes */
71940
+ u8 *pCell = findCellPastPtr(pPage, idx);
71941
+
71942
+ nCell = pCell[0];
71943
+ if( nCell<=pPage->max1bytePayload ){
71944
+ /* This branch runs if the record-size field of the cell is a
71945
+ ** single byte varint and the record fits entirely on the main
71946
+ ** b-tree page. */
71947
+ testcase( pCell+nCell+1==pPage->aDataEnd );
71948
+ c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
71949
+ }else if( !(pCell[1] & 0x80)
71950
+ && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
71951
+ ){
71952
+ /* The record-size field is a 2 byte varint and the record
71953
+ ** fits entirely on the main b-tree page. */
71954
+ testcase( pCell+nCell+2==pPage->aDataEnd );
71955
+ c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
71956
+ }else{
71957
+ /* If the record extends into overflow pages, do not attempt
71958
+ ** the optimization. */
71959
+ c = 99;
71960
+ }
71961
+ return c;
71962
+}
71963
+
71964
+/*
71965
+** Return true (non-zero) if pCur is current pointing to the last
71966
+** page of a table.
71967
+*/
71968
+static int cursorOnLastPage(BtCursor *pCur){
71969
+ int i;
71970
+ assert( pCur->eState==CURSOR_VALID );
71971
+ for(i=0; i<pCur->iPage; i++){
71972
+ MemPage *pPage = pCur->apPage[i];
71973
+ if( pCur->aiIdx[i]<pPage->nCell ) return 0;
71974
+ }
71975
+ return 1;
71976
+}
7146071977
7146171978
/* Move the cursor so that it points to an entry in an index table
7146271979
** near the key pIdxKey. Return a success code.
7146371980
**
7146471981
** If an exact match is not found, then the cursor is always
@@ -71506,25 +72023,61 @@
7150672023
assert( pIdxKey->default_rc==1
7150772024
|| pIdxKey->default_rc==0
7150872025
|| pIdxKey->default_rc==-1
7150972026
);
7151072027
72028
+
72029
+ /* Check to see if we can skip a lot of work. Two cases:
72030
+ **
72031
+ ** (1) If the cursor is already pointing to the very last cell
72032
+ ** in the table and the pIdxKey search key is greater than or
72033
+ ** equal to that last cell, then no movement is required.
72034
+ **
72035
+ ** (2) If the cursor is on the last page of the table and the first
72036
+ ** cell on that last page is less than or equal to the pIdxKey
72037
+ ** search key, then we can start the search on the current page
72038
+ ** without needing to go back to root.
72039
+ */
72040
+ if( pCur->eState==CURSOR_VALID
72041
+ && pCur->pPage->leaf
72042
+ && cursorOnLastPage(pCur)
72043
+ ){
72044
+ int c;
72045
+ if( pCur->ix==pCur->pPage->nCell-1
72046
+ && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0
72047
+ && pIdxKey->errCode==SQLITE_OK
72048
+ ){
72049
+ *pRes = c;
72050
+ return SQLITE_OK; /* Cursor already pointing at the correct spot */
72051
+ }
72052
+ if( pCur->iPage>0
72053
+ && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
72054
+ && pIdxKey->errCode==SQLITE_OK
72055
+ ){
72056
+ pCur->curFlags &= ~BTCF_ValidOvfl;
72057
+ goto bypass_moveto_root; /* Start search on the current page */
72058
+ }
72059
+ pIdxKey->errCode = SQLITE_OK;
72060
+ }
72061
+
7151172062
rc = moveToRoot(pCur);
7151272063
if( rc ){
7151372064
if( rc==SQLITE_EMPTY ){
7151472065
assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
7151572066
*pRes = -1;
7151672067
return SQLITE_OK;
7151772068
}
7151872069
return rc;
7151972070
}
72071
+
72072
+bypass_moveto_root:
7152072073
assert( pCur->pPage );
7152172074
assert( pCur->pPage->isInit );
7152272075
assert( pCur->eState==CURSOR_VALID );
7152372076
assert( pCur->pPage->nCell > 0 );
71524
- assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey );
71525
- assert( pCur->curIntKey || pIdxKey );
72077
+ assert( pCur->curIntKey==0 );
72078
+ assert( pIdxKey!=0 );
7152672079
for(;;){
7152772080
int lwr, upr, idx, c;
7152872081
Pgno chldPg;
7152972082
MemPage *pPage = pCur->pPage;
7153072083
u8 *pCell; /* Pointer to current cell in pPage */
@@ -71534,11 +72087,11 @@
7153472087
** not run. If this is not the root-page, then the moveToChild() routine
7153572088
** would have already detected db corruption. Similarly, pPage must
7153672089
** be the right kind (index or table) of b-tree page. Otherwise
7153772090
** a moveToChild() or moveToRoot() call would have detected corruption. */
7153872091
assert( pPage->nCell>0 );
71539
- assert( pPage->intKey==(pIdxKey==0) );
72092
+ assert( pPage->intKey==0 );
7154072093
lwr = 0;
7154172094
upr = pPage->nCell-1;
7154272095
idx = upr>>1; /* idx = (lwr+upr)/2; */
7154372096
for(;;){
7154472097
int nCell; /* Size of the pCell cell in bytes */
@@ -72229,11 +72782,11 @@
7222972782
7223072783
assert( sqlite3_mutex_held(pBt->mutex) );
7223172784
assert( CORRUPT_DB || iPage>1 );
7223272785
assert( !pMemPage || pMemPage->pgno==iPage );
7223372786
72234
- if( NEVER(iPage<2) || iPage>pBt->nPage ){
72787
+ if( iPage<2 || iPage>pBt->nPage ){
7223572788
return SQLITE_CORRUPT_BKPT;
7223672789
}
7223772790
if( pMemPage ){
7223872791
pPage = pMemPage;
7223972792
sqlite3PagerRef(pPage->pDbPage);
@@ -72664,10 +73217,16 @@
7266473217
data = pPage->aData;
7266573218
ptr = &pPage->aCellIdx[2*idx];
7266673219
assert( pPage->pBt->usableSize > (u32)(ptr-data) );
7266773220
pc = get2byte(ptr);
7266873221
hdr = pPage->hdrOffset;
73222
+#if 0 /* Not required. Omit for efficiency */
73223
+ if( pc<hdr+pPage->nCell*2 ){
73224
+ *pRC = SQLITE_CORRUPT_BKPT;
73225
+ return;
73226
+ }
73227
+#endif
7266973228
testcase( pc==(u32)get2byte(&data[hdr+5]) );
7267073229
testcase( pc+sz==pPage->pBt->usableSize );
7267173230
if( pc+sz > pPage->pBt->usableSize ){
7267273231
*pRC = SQLITE_CORRUPT_BKPT;
7267373232
return;
@@ -74395,11 +74954,10 @@
7439574954
** balance_deeper()
7439674955
** balance_nonroot()
7439774956
*/
7439874957
static int balance(BtCursor *pCur){
7439974958
int rc = SQLITE_OK;
74400
- const int nMin = pCur->pBt->usableSize * 2 / 3;
7440174959
u8 aBalanceQuickSpace[13];
7440274960
u8 *pFree = 0;
7440374961
7440474962
VVA_ONLY( int balance_quick_called = 0 );
7440574963
VVA_ONLY( int balance_deeper_called = 0 );
@@ -74407,11 +74965,15 @@
7440774965
do {
7440874966
int iPage;
7440974967
MemPage *pPage = pCur->pPage;
7441074968
7441174969
if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
74412
- if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
74970
+ if( pPage->nOverflow==0 && pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){
74971
+ /* No rebalance required as long as:
74972
+ ** (1) There are no overflow cells
74973
+ ** (2) The amount of free space on the page is less than 2/3rds of
74974
+ ** the total usable space on the page. */
7441374975
break;
7441474976
}else if( (iPage = pCur->iPage)==0 ){
7441574977
if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){
7441674978
/* The root page of the b-tree is overfull. In this case call the
7441774979
** balance_deeper() function to create a new child for the root-page
@@ -74627,11 +75189,11 @@
7462775189
** For an index btree (used for indexes and WITHOUT ROWID tables), the
7462875190
** key is an arbitrary byte sequence stored in pX.pKey,nKey. The
7462975191
** pX.pData,nData,nZero fields must be zero.
7463075192
**
7463175193
** If the seekResult parameter is non-zero, then a successful call to
74632
-** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already
75194
+** sqlite3BtreeIndexMoveto() to seek cursor pCur to (pKey,nKey) has already
7463375195
** been performed. In other words, if seekResult!=0 then the cursor
7463475196
** is currently pointing to a cell that will be adjacent to the cell
7463575197
** to be inserted. If seekResult<0 then pCur points to a cell that is
7463675198
** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell
7463775199
** that is larger than (pKey,nKey).
@@ -74645,11 +75207,11 @@
7464575207
*/
7464675208
SQLITE_PRIVATE int sqlite3BtreeInsert(
7464775209
BtCursor *pCur, /* Insert data into the table of this cursor */
7464875210
const BtreePayload *pX, /* Content of the row to be inserted */
7464975211
int flags, /* True if this is likely an append */
74650
- int seekResult /* Result of prior MovetoUnpacked() call */
75212
+ int seekResult /* Result of prior IndexMoveto() call */
7465175213
){
7465275214
int rc;
7465375215
int loc = seekResult; /* -1: before desired location +1: after */
7465475216
int szNew = 0;
7465575217
int idx;
@@ -74660,28 +75222,10 @@
7466075222
unsigned char *newCell = 0;
7466175223
7466275224
assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
7466375225
assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 );
7466475226
74665
- if( pCur->eState==CURSOR_FAULT ){
74666
- assert( pCur->skipNext!=SQLITE_OK );
74667
- return pCur->skipNext;
74668
- }
74669
-
74670
- assert( cursorOwnsBtShared(pCur) );
74671
- assert( (pCur->curFlags & BTCF_WriteFlag)!=0
74672
- && pBt->inTransaction==TRANS_WRITE
74673
- && (pBt->btsFlags & BTS_READ_ONLY)==0 );
74674
- assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
74675
-
74676
- /* Assert that the caller has been consistent. If this cursor was opened
74677
- ** expecting an index b-tree, then the caller should be inserting blob
74678
- ** keys with no associated data. If the cursor was opened expecting an
74679
- ** intkey table, the caller should be inserting integer keys with a
74680
- ** blob of associated data. */
74681
- assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
74682
-
7468375227
/* Save the positions of any other cursors open on this table.
7468475228
**
7468575229
** In some cases, the call to btreeMoveto() below is a no-op. For
7468675230
** example, when inserting data into a table with auto-generated integer
7468775231
** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
@@ -74702,10 +75246,33 @@
7470275246
** set the flag, load the schema, and then unset the flag. */
7470375247
return SQLITE_CORRUPT_BKPT;
7470475248
}
7470575249
}
7470675250
75251
+ /* Ensure that the cursor is not in the CURSOR_FAULT state and that it
75252
+ ** points to a valid cell.
75253
+ */
75254
+ if( pCur->eState>=CURSOR_REQUIRESEEK ){
75255
+ testcase( pCur->eState==CURSOR_REQUIRESEEK );
75256
+ testcase( pCur->eState==CURSOR_FAULT );
75257
+ rc = moveToRoot(pCur);
75258
+ if( rc && rc!=SQLITE_EMPTY ) return rc;
75259
+ }
75260
+
75261
+ assert( cursorOwnsBtShared(pCur) );
75262
+ assert( (pCur->curFlags & BTCF_WriteFlag)!=0
75263
+ && pBt->inTransaction==TRANS_WRITE
75264
+ && (pBt->btsFlags & BTS_READ_ONLY)==0 );
75265
+ assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
75266
+
75267
+ /* Assert that the caller has been consistent. If this cursor was opened
75268
+ ** expecting an index b-tree, then the caller should be inserting blob
75269
+ ** keys with no associated data. If the cursor was opened expecting an
75270
+ ** intkey table, the caller should be inserting integer keys with a
75271
+ ** blob of associated data. */
75272
+ assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
75273
+
7470775274
if( pCur->pKeyInfo==0 ){
7470875275
assert( pX->pKey==0 );
7470975276
/* If this is an insert into a table b-tree, invalidate any incrblob
7471075277
** cursors open on the row being replaced */
7471175278
if( p->hasIncrblobCur ){
@@ -74790,18 +75357,18 @@
7479075357
return btreeOverwriteCell(pCur, &x2);
7479175358
}
7479275359
}
7479375360
}
7479475361
assert( pCur->eState==CURSOR_VALID
74795
- || (pCur->eState==CURSOR_INVALID && loc)
74796
- || CORRUPT_DB );
75362
+ || (pCur->eState==CURSOR_INVALID && loc) );
7479775363
7479875364
pPage = pCur->pPage;
7479975365
assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
7480075366
assert( pPage->leaf || !pPage->intKey );
7480175367
if( pPage->nFree<0 ){
7480275368
if( NEVER(pCur->eState>CURSOR_INVALID) ){
75369
+ /* ^^^^^--- due to the moveToRoot() call above */
7480375370
rc = SQLITE_CORRUPT_BKPT;
7480475371
}else{
7480575372
rc = btreeComputeFreeSpace(pPage);
7480675373
}
7480775374
if( rc ) return rc;
@@ -75078,16 +75645,20 @@
7507875645
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
7507975646
assert( pCur->curFlags & BTCF_WriteFlag );
7508075647
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
7508175648
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
7508275649
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
75083
- if( pCur->eState==CURSOR_REQUIRESEEK ){
75084
- rc = btreeRestoreCursorPosition(pCur);
75085
- assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
75086
- if( rc || pCur->eState!=CURSOR_VALID ) return rc;
75650
+ if( pCur->eState!=CURSOR_VALID ){
75651
+ if( pCur->eState>=CURSOR_REQUIRESEEK ){
75652
+ rc = btreeRestoreCursorPosition(pCur);
75653
+ assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
75654
+ if( rc || pCur->eState!=CURSOR_VALID ) return rc;
75655
+ }else{
75656
+ return SQLITE_CORRUPT_BKPT;
75657
+ }
7508775658
}
75088
- assert( CORRUPT_DB || pCur->eState==CURSOR_VALID );
75659
+ assert( pCur->eState==CURSOR_VALID );
7508975660
7509075661
iCellDepth = pCur->iPage;
7509175662
iCellIdx = pCur->ix;
7509275663
pPage = pCur->pPage;
7509375664
if( pPage->nCell<=iCellIdx ){
@@ -75115,11 +75686,12 @@
7511575686
** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT.
7511675687
*/
7511775688
bPreserve = (flags & BTREE_SAVEPOSITION)!=0;
7511875689
if( bPreserve ){
7511975690
if( !pPage->leaf
75120
- || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
75691
+ || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2) >
75692
+ (int)(pBt->usableSize*2/3)
7512175693
|| pPage->nCell==1 /* See dbfuzz001.test for a test case */
7512275694
){
7512375695
/* A b-tree rebalance will be required after deleting this entry.
7512475696
** Save the cursor key. */
7512575697
rc = saveCursorKey(pCur);
@@ -75211,11 +75783,19 @@
7521175783
** on the leaf node first. If the balance proceeds far enough up the
7521275784
** tree that we can be sure that any problem in the internal node has
7521375785
** been corrected, so be it. Otherwise, after balancing the leaf node,
7521475786
** walk the cursor up the tree to the internal node and balance it as
7521575787
** well. */
75216
- rc = balance(pCur);
75788
+ assert( pCur->pPage->nOverflow==0 );
75789
+ assert( pCur->pPage->nFree>=0 );
75790
+ if( pCur->pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){
75791
+ /* Optimization: If the free space is less than 2/3rds of the page,
75792
+ ** then balance() will always be a no-op. No need to invoke it. */
75793
+ rc = SQLITE_OK;
75794
+ }else{
75795
+ rc = balance(pCur);
75796
+ }
7521775797
if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
7521875798
releasePageNotNull(pCur->pPage);
7521975799
pCur->iPage--;
7522075800
while( pCur->iPage>iCellDepth ){
7522175801
releasePage(pCur->apPage[pCur->iPage--]);
@@ -75434,11 +76014,11 @@
7543476014
return SQLITE_CORRUPT_BKPT;
7543576015
}
7543676016
rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
7543776017
if( rc ) return rc;
7543876018
if( (pBt->openFlags & BTREE_SINGLE)==0
75439
- && sqlite3PagerPageRefcount(pPage->pDbPage)!=1
76019
+ && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1))
7544076020
){
7544176021
rc = SQLITE_CORRUPT_BKPT;
7544276022
goto cleardatabasepage_out;
7544376023
}
7544476024
hdr = pPage->hdrOffset;
@@ -76814,11 +77394,11 @@
7681477394
int i = sqlite3FindDbName(pDb, zDb);
7681577395
7681677396
if( i==1 ){
7681777397
Parse sParse;
7681877398
int rc = 0;
76819
- sqlite3ParseObjectInit(&sParse,pErrorDb);
77399
+ sqlite3ParseObjectInit(&sParse,pDb);
7682077400
if( sqlite3OpenTempDatabase(&sParse) ){
7682177401
sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
7682277402
rc = SQLITE_ERROR;
7682377403
}
7682477404
sqlite3DbFree(pErrorDb, sParse.zErrMsg);
@@ -77706,11 +78286,15 @@
7770678286
#endif
7770778287
assert( pMem!=0 );
7770878288
assert( !sqlite3VdbeMemIsRowSet(pMem) );
7770978289
assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
7771078290
|| desiredEnc==SQLITE_UTF16BE );
77711
- if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
78291
+ if( !(pMem->flags&MEM_Str) ){
78292
+ pMem->enc = desiredEnc;
78293
+ return SQLITE_OK;
78294
+ }
78295
+ if( pMem->enc==desiredEnc ){
7771278296
return SQLITE_OK;
7771378297
}
7771478298
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7771578299
#ifdef SQLITE_OMIT_UTF16
7771678300
return SQLITE_ERROR;
@@ -77965,10 +78549,11 @@
7796578549
t.flags = MEM_Null;
7796678550
t.db = pMem->db;
7796778551
ctx.pOut = &t;
7796878552
ctx.pMem = pMem;
7796978553
ctx.pFunc = pFunc;
78554
+ ctx.enc = ENC(t.db);
7797078555
pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
7797178556
assert( (pMem->flags & MEM_Dyn)==0 );
7797278557
if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
7797378558
memcpy(pMem, &t, sizeof(t));
7797478559
return ctx.isError;
@@ -77992,10 +78577,11 @@
7799278577
memset(&ctx, 0, sizeof(ctx));
7799378578
sqlite3VdbeMemSetNull(pOut);
7799478579
ctx.pOut = pOut;
7799578580
ctx.pMem = pAccum;
7799678581
ctx.pFunc = pFunc;
78582
+ ctx.enc = ENC(pAccum->db);
7799778583
pFunc->xValue(&ctx);
7799878584
return ctx.isError;
7799978585
}
7800078586
#endif /* SQLITE_OMIT_WINDOWFUNC */
7800178587
@@ -78056,10 +78642,18 @@
7805678642
assert( sqlite3VdbeCheckMemInvariants(p) );
7805778643
if( VdbeMemDynamic(p) || p->szMalloc ){
7805878644
vdbeMemClear(p);
7805978645
}
7806078646
}
78647
+
78648
+/* Like sqlite3VdbeMemRelease() but faster for cases where we
78649
+** know in advance that the Mem is not MEM_Dyn or MEM_Agg.
78650
+*/
78651
+SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){
78652
+ assert( !VdbeMemDynamic(p) );
78653
+ if( p->szMalloc ) vdbeMemClear(p);
78654
+}
7806178655
7806278656
/*
7806378657
** Convert a 64-bit IEEE double into a 64-bit signed integer.
7806478658
** If the double is out of range of a 64-bit signed integer then
7806578659
** return the closest available 64-bit signed integer.
@@ -78418,10 +79012,11 @@
7841879012
void *pPtr,
7841979013
const char *zPType,
7842079014
void (*xDestructor)(void*)
7842179015
){
7842279016
assert( pMem->flags==MEM_Null );
79017
+ vdbeMemClear(pMem);
7842379018
pMem->u.zPType = zPType ? zPType : "";
7842479019
pMem->z = pPtr;
7842579020
pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
7842679021
pMem->eSubtype = 'p';
7842779022
pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
@@ -78600,10 +79195,17 @@
7860079195
** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH
7860179196
** size limit) then no memory allocation occurs. If the string can be
7860279197
** stored without allocating memory, then it is. If a memory allocation
7860379198
** is required to store the string, then value of pMem is unchanged. In
7860479199
** either case, SQLITE_TOOBIG is returned.
79200
+**
79201
+** The "enc" parameter is the text encoding for the string, or zero
79202
+** to store a blob.
79203
+**
79204
+** If n is negative, then the string consists of all bytes up to but
79205
+** excluding the first zero character. The n parameter must be
79206
+** non-negative for blobs.
7860579207
*/
7860679208
SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
7860779209
Mem *pMem, /* Memory cell to set to string value */
7860879210
const char *z, /* String pointer */
7860979211
i64 n, /* Bytes in string, or negative */
@@ -78610,15 +79212,16 @@
7861079212
u8 enc, /* Encoding of z. 0 for BLOBs */
7861179213
void (*xDel)(void*) /* Destructor function */
7861279214
){
7861379215
i64 nByte = n; /* New value for pMem->n */
7861479216
int iLimit; /* Maximum allowed string or blob size */
78615
- u16 flags = 0; /* New value for pMem->flags */
79217
+ u16 flags; /* New value for pMem->flags */
7861679218
7861779219
assert( pMem!=0 );
7861879220
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7861979221
assert( !sqlite3VdbeMemIsRowSet(pMem) );
79222
+ assert( enc!=0 || n>=0 );
7862079223
7862179224
/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
7862279225
if( !z ){
7862379226
sqlite3VdbeMemSetNull(pMem);
7862479227
return SQLITE_OK;
@@ -78627,19 +79230,34 @@
7862779230
if( pMem->db ){
7862879231
iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH];
7862979232
}else{
7863079233
iLimit = SQLITE_MAX_LENGTH;
7863179234
}
78632
- flags = (enc==0?MEM_Blob:MEM_Str);
7863379235
if( nByte<0 ){
7863479236
assert( enc!=0 );
7863579237
if( enc==SQLITE_UTF8 ){
7863679238
nByte = strlen(z);
7863779239
}else{
7863879240
for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
7863979241
}
78640
- flags |= MEM_Term;
79242
+ flags= MEM_Str|MEM_Term;
79243
+ }else if( enc==0 ){
79244
+ flags = MEM_Blob;
79245
+ enc = SQLITE_UTF8;
79246
+ }else{
79247
+ flags = MEM_Str;
79248
+ }
79249
+ if( nByte>iLimit ){
79250
+ if( xDel && xDel!=SQLITE_TRANSIENT ){
79251
+ if( xDel==SQLITE_DYNAMIC ){
79252
+ sqlite3DbFree(pMem->db, (void*)z);
79253
+ }else{
79254
+ xDel((void*)z);
79255
+ }
79256
+ }
79257
+ sqlite3VdbeMemSetNull(pMem);
79258
+ return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
7864179259
}
7864279260
7864379261
/* The following block sets the new values of Mem.z and Mem.xDel. It
7864479262
** also sets a flag in local variable "flags" to indicate the memory
7864579263
** management (one of MEM_Dyn or MEM_Static).
@@ -78647,13 +79265,10 @@
7864779265
if( xDel==SQLITE_TRANSIENT ){
7864879266
i64 nAlloc = nByte;
7864979267
if( flags&MEM_Term ){
7865079268
nAlloc += (enc==SQLITE_UTF8?1:2);
7865179269
}
78652
- if( nByte>iLimit ){
78653
- return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
78654
- }
7865579270
testcase( nAlloc==0 );
7865679271
testcase( nAlloc==31 );
7865779272
testcase( nAlloc==32 );
7865879273
if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
7865979274
return SQLITE_NOMEM_BKPT;
@@ -78671,30 +79286,18 @@
7867179286
}
7867279287
}
7867379288
7867479289
pMem->n = (int)(nByte & 0x7fffffff);
7867579290
pMem->flags = flags;
78676
- if( enc ){
78677
- pMem->enc = enc;
78678
-#ifdef SQLITE_ENABLE_SESSION
78679
- }else if( pMem->db==0 ){
78680
- pMem->enc = SQLITE_UTF8;
78681
-#endif
78682
- }else{
78683
- assert( pMem->db!=0 );
78684
- pMem->enc = ENC(pMem->db);
78685
- }
79291
+ pMem->enc = enc;
7868679292
7868779293
#ifndef SQLITE_OMIT_UTF16
7868879294
if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
7868979295
return SQLITE_NOMEM_BKPT;
7869079296
}
7869179297
#endif
7869279298
78693
- if( nByte>iLimit ){
78694
- return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
78695
- }
7869679299
7869779300
return SQLITE_OK;
7869879301
}
7869979302
7870079303
/*
@@ -78972,10 +79575,11 @@
7897279575
7897379576
assert( pCtx->pParse->rc==SQLITE_OK );
7897479577
memset(&ctx, 0, sizeof(ctx));
7897579578
ctx.pOut = pVal;
7897679579
ctx.pFunc = pFunc;
79580
+ ctx.enc = ENC(db);
7897779581
pFunc->xSFunc(&ctx, nVal, apVal);
7897879582
if( ctx.isError ){
7897979583
rc = ctx.isError;
7898079584
sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
7898179585
}else{
@@ -79032,15 +79636,11 @@
7903279636
const char *zNeg = "";
7903379637
int rc = SQLITE_OK;
7903479638
7903579639
assert( pExpr!=0 );
7903679640
while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
79037
-#if defined(SQLITE_ENABLE_STAT4)
7903879641
if( op==TK_REGISTER ) op = pExpr->op2;
79039
-#else
79040
- if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
79041
-#endif
7904279642
7904379643
/* Compressed expressions only appear when parsing the DEFAULT clause
7904479644
** on a table column definition, and hence only when pCtx==0. This
7904579645
** check ensures that an EP_TokenOnly expression is never passed down
7904679646
** into valueFromFunction(). */
@@ -79151,11 +79751,11 @@
7915179751
*ppVal = pVal;
7915279752
return rc;
7915379753
7915479754
no_mem:
7915579755
#ifdef SQLITE_ENABLE_STAT4
79156
- if( pCtx==0 || pCtx->pParse->nErr==0 )
79756
+ if( pCtx==0 || NEVER(pCtx->pParse->nErr==0) )
7915779757
#endif
7915879758
sqlite3OomFault(db);
7915979759
sqlite3DbFree(db, zVal);
7916079760
assert( *ppVal==0 );
7916179761
#ifdef SQLITE_ENABLE_STAT4
@@ -79486,11 +80086,11 @@
7948680086
db->pVdbe->pPrev = p;
7948780087
}
7948880088
p->pNext = db->pVdbe;
7948980089
p->pPrev = 0;
7949080090
db->pVdbe = p;
79491
- p->iVdbeMagic = VDBE_MAGIC_INIT;
80091
+ assert( p->eVdbeState==VDBE_INIT_STATE );
7949280092
p->pParse = pParse;
7949380093
pParse->pVdbe = p;
7949480094
assert( pParse->aLabel==0 );
7949580095
assert( pParse->nLabel==0 );
7949680096
assert( p->nOpAlloc==0 );
@@ -79631,11 +80231,11 @@
7963180231
if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
7963280232
sqlite3OomFault(p->db);
7963380233
return SQLITE_NOMEM;
7963480234
}
7963580235
79636
- assert( nOp<=(1024/sizeof(Op)) );
80236
+ assert( nOp<=(int)(1024/sizeof(Op)) );
7963780237
assert( nNew>=(v->nOpAlloc+nOp) );
7963880238
pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
7963980239
if( pNew ){
7964080240
p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
7964180241
v->nOpAlloc = p->szOpAlloc/sizeof(Op);
@@ -79687,11 +80287,11 @@
7968780287
SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
7968880288
int i;
7968980289
VdbeOp *pOp;
7969080290
7969180291
i = p->nOp;
79692
- assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
80292
+ assert( p->eVdbeState==VDBE_INIT_STATE );
7969380293
assert( op>=0 && op<0xff );
7969480294
if( p->nOpAlloc<=i ){
7969580295
return growOp3(p, op, p1, p2, p3);
7969680296
}
7969780297
assert( p->aOp!=0 );
@@ -80019,11 +80619,11 @@
8001980619
}
8002080620
}
8002180621
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
8002280622
Parse *p = v->pParse;
8002380623
int j = ADDR(x);
80024
- assert( v->iVdbeMagic==VDBE_MAGIC_INIT );
80624
+ assert( v->eVdbeState==VDBE_INIT_STATE );
8002580625
assert( j<-p->nLabel );
8002680626
assert( j>=0 );
8002780627
#ifdef SQLITE_DEBUG
8002880628
if( p->db->flags & SQLITE_VdbeAddopTrace ){
8002980629
printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
@@ -80150,10 +80750,12 @@
8015080750
int hasCreateTable = 0;
8015180751
int hasCreateIndex = 0;
8015280752
int hasInitCoroutine = 0;
8015380753
Op *pOp;
8015480754
VdbeOpIter sIter;
80755
+
80756
+ if( v==0 ) return 0;
8015580757
memset(&sIter, 0, sizeof(sIter));
8015680758
sIter.v = v;
8015780759
8015880760
while( (pOp = opIterNext(&sIter))!=0 ){
8015980761
int opcode = pOp->opcode;
@@ -80233,11 +80835,11 @@
8023380835
** and store that value in *pMaxFuncArgs.
8023480836
**
8023580837
** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
8023680838
** indicate what the prepared statement actually does.
8023780839
**
80238
-** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
80840
+** (4) (discontinued)
8023980841
**
8024080842
** (5) Reclaim the memory allocated for storing labels.
8024180843
**
8024280844
** This routine will only function correctly if the mkopcodeh.tcl generator
8024380845
** script numbers the opcodes correctly. Changes to this routine must be
@@ -80279,29 +80881,10 @@
8027980881
case OP_JournalMode: {
8028080882
p->readOnly = 0;
8028180883
p->bIsReader = 1;
8028280884
break;
8028380885
}
80284
- case OP_Next:
80285
- case OP_SorterNext: {
80286
- pOp->p4.xAdvance = sqlite3BtreeNext;
80287
- pOp->p4type = P4_ADVANCE;
80288
- /* The code generator never codes any of these opcodes as a jump
80289
- ** to a label. They are always coded as a jump backwards to a
80290
- ** known address */
80291
- assert( pOp->p2>=0 );
80292
- break;
80293
- }
80294
- case OP_Prev: {
80295
- pOp->p4.xAdvance = sqlite3BtreePrevious;
80296
- pOp->p4type = P4_ADVANCE;
80297
- /* The code generator never codes any of these opcodes as a jump
80298
- ** to a label. They are always coded as a jump backwards to a
80299
- ** known address */
80300
- assert( pOp->p2>=0 );
80301
- break;
80302
- }
8030380886
#ifndef SQLITE_OMIT_VIRTUALTABLE
8030480887
case OP_VUpdate: {
8030580888
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
8030680889
break;
8030780890
}
@@ -80333,22 +80916,24 @@
8033380916
assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0);
8033480917
}
8033580918
if( pOp==p->aOp ) break;
8033680919
pOp--;
8033780920
}
80338
- sqlite3DbFree(p->db, pParse->aLabel);
80339
- pParse->aLabel = 0;
80921
+ if( aLabel ){
80922
+ sqlite3DbFreeNN(p->db, pParse->aLabel);
80923
+ pParse->aLabel = 0;
80924
+ }
8034080925
pParse->nLabel = 0;
8034180926
*pMaxFuncArgs = nMaxArgs;
8034280927
assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
8034380928
}
8034480929
8034580930
/*
8034680931
** Return the address of the next instruction to be inserted.
8034780932
*/
8034880933
SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){
80349
- assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
80934
+ assert( p->eVdbeState==VDBE_INIT_STATE );
8035080935
return p->nOp;
8035180936
}
8035280937
8035380938
/*
8035480939
** Verify that at least N opcode slots are available in p without
@@ -80429,11 +81014,11 @@
8042981014
int iLineno /* Source-file line number of first opcode */
8043081015
){
8043181016
int i;
8043281017
VdbeOp *pOut, *pFirst;
8043381018
assert( nOp>0 );
80434
- assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
81019
+ assert( p->eVdbeState==VDBE_INIT_STATE );
8043581020
if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
8043681021
return 0;
8043781022
}
8043881023
pFirst = pOut = &p->aOp[p->nOp];
8043981024
for(i=0; i<nOp; i++, aOp++, pOut++){
@@ -80581,11 +81166,10 @@
8058181166
break;
8058281167
}
8058381168
case P4_REAL:
8058481169
case P4_INT64:
8058581170
case P4_DYNAMIC:
80586
- case P4_DYNBLOB:
8058781171
case P4_INTARRAY: {
8058881172
sqlite3DbFree(db, p4);
8058981173
break;
8059081174
}
8059181175
case P4_KEYINFO: {
@@ -80621,17 +81205,20 @@
8062181205
** Free the space allocated for aOp and any p4 values allocated for the
8062281206
** opcodes contained within. If aOp is not NULL it is assumed to contain
8062381207
** nOp entries.
8062481208
*/
8062581209
static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
81210
+ assert( nOp>=0 );
8062681211
if( aOp ){
80627
- Op *pOp;
80628
- for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){
81212
+ Op *pOp = &aOp[nOp-1];
81213
+ while(1){ /* Exit via break */
8062981214
if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p);
8063081215
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
8063181216
sqlite3DbFree(db, pOp->zComment);
8063281217
#endif
81218
+ if( pOp==aOp ) break;
81219
+ pOp--;
8063381220
}
8063481221
sqlite3DbFreeNN(db, aOp);
8063581222
}
8063681223
}
8063781224
@@ -80753,11 +81340,11 @@
8075381340
SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
8075481341
Op *pOp;
8075581342
sqlite3 *db;
8075681343
assert( p!=0 );
8075781344
db = p->db;
80758
- assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
81345
+ assert( p->eVdbeState==VDBE_INIT_STATE );
8075981346
assert( p->aOp!=0 || db->mallocFailed );
8076081347
if( db->mallocFailed ){
8076181348
if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
8076281349
return;
8076381350
}
@@ -80881,11 +81468,11 @@
8088181468
*/
8088281469
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
8088381470
/* C89 specifies that the constant "dummy" will be initialized to all
8088481471
** zeros, which is correct. MSVC generates a warning, nevertheless. */
8088581472
static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */
80886
- assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
81473
+ assert( p->eVdbeState==VDBE_INIT_STATE );
8088781474
if( addr<0 ){
8088881475
addr = p->nOp - 1;
8088981476
}
8089081477
assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
8089181478
if( p->db->mallocFailed ){
@@ -81178,14 +81765,10 @@
8117881765
}
8117981766
case P4_SUBPROGRAM: {
8118081767
zP4 = "program";
8118181768
break;
8118281769
}
81183
- case P4_DYNBLOB:
81184
- case P4_ADVANCE: {
81185
- break;
81186
- }
8118781770
case P4_TABLE: {
8118881771
zP4 = pOp->p4.pTab->zName;
8118981772
break;
8119081773
}
8119181774
default: {
@@ -81313,25 +81896,44 @@
8131381896
}
8131481897
#endif
8131581898
8131681899
/*
8131781900
** Initialize an array of N Mem element.
81901
+**
81902
+** This is a high-runner, so only those fields that really do need to
81903
+** be initialized are set. The Mem structure is organized so that
81904
+** the fields that get initialized are nearby and hopefully on the same
81905
+** cache line.
81906
+**
81907
+** Mem.flags = flags
81908
+** Mem.db = db
81909
+** Mem.szMalloc = 0
81910
+**
81911
+** All other fields of Mem can safely remain uninitialized for now. They
81912
+** will be initialized before use.
8131881913
*/
8131981914
static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
81320
- while( (N--)>0 ){
81321
- p->db = db;
81322
- p->flags = flags;
81323
- p->szMalloc = 0;
81915
+ if( N>0 ){
81916
+ do{
81917
+ p->flags = flags;
81918
+ p->db = db;
81919
+ p->szMalloc = 0;
8132481920
#ifdef SQLITE_DEBUG
81325
- p->pScopyFrom = 0;
81921
+ p->pScopyFrom = 0;
8132681922
#endif
81327
- p++;
81923
+ p++;
81924
+ }while( (--N)>0 );
8132881925
}
8132981926
}
8133081927
8133181928
/*
81332
-** Release an array of N Mem elements
81929
+** Release auxiliary memory held in an array of N Mem elements.
81930
+**
81931
+** After this routine returns, all Mem elements in the array will still
81932
+** be valid. Those Mem elements that were not holding auxiliary resources
81933
+** will be unchanged. Mem elements which had something freed will be
81934
+** set to MEM_Undefined.
8133381935
*/
8133481936
static void releaseMemArray(Mem *p, int N){
8133581937
if( p && N ){
8133681938
Mem *pEnd = &p[N];
8133781939
sqlite3 *db = p->db;
@@ -81360,16 +81962,21 @@
8136081962
testcase( p->flags & MEM_Agg );
8136181963
testcase( p->flags & MEM_Dyn );
8136281964
if( p->flags&(MEM_Agg|MEM_Dyn) ){
8136381965
testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel );
8136481966
sqlite3VdbeMemRelease(p);
81967
+ p->flags = MEM_Undefined;
8136581968
}else if( p->szMalloc ){
8136681969
sqlite3DbFreeNN(db, p->zMalloc);
8136781970
p->szMalloc = 0;
81971
+ p->flags = MEM_Undefined;
8136881972
}
81369
-
81370
- p->flags = MEM_Undefined;
81973
+#ifdef SQLITE_DEBUG
81974
+ else{
81975
+ p->flags = MEM_Undefined;
81976
+ }
81977
+#endif
8137181978
}while( (++p)<pEnd );
8137281979
}
8137381980
}
8137481981
8137581982
#ifdef SQLITE_DEBUG
@@ -81563,11 +82170,11 @@
8156382170
int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
8156482171
Op *aOp; /* Array of opcodes */
8156582172
Op *pOp; /* Current opcode */
8156682173
8156782174
assert( p->explain );
81568
- assert( p->iVdbeMagic==VDBE_MAGIC_RUN );
82175
+ assert( p->eVdbeState==VDBE_RUN_STATE );
8156982176
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
8157082177
8157182178
/* Even though this opcode does not use dynamic strings for
8157282179
** the result, result columns may become dynamic if the user calls
8157382180
** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
@@ -81743,18 +82350,19 @@
8174382350
SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
8174482351
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
8174582352
int i;
8174682353
#endif
8174782354
assert( p!=0 );
81748
- assert( p->iVdbeMagic==VDBE_MAGIC_INIT || p->iVdbeMagic==VDBE_MAGIC_RESET );
82355
+ assert( p->eVdbeState==VDBE_INIT_STATE
82356
+ || p->eVdbeState==VDBE_READY_STATE
82357
+ || p->eVdbeState==VDBE_HALT_STATE );
8174982358
8175082359
/* There should be at least one opcode.
8175182360
*/
8175282361
assert( p->nOp>0 );
8175382362
81754
- /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
81755
- p->iVdbeMagic = VDBE_MAGIC_RUN;
82363
+ p->eVdbeState = VDBE_READY_STATE;
8175682364
8175782365
#ifdef SQLITE_DEBUG
8175882366
for(i=0; i<p->nMem; i++){
8175982367
assert( p->aMem[i].db==p->db );
8176082368
}
@@ -81806,11 +82414,11 @@
8180682414
struct ReusableSpace x; /* Reusable bulk memory */
8180782415
8180882416
assert( p!=0 );
8180982417
assert( p->nOp>0 );
8181082418
assert( pParse!=0 );
81811
- assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
82419
+ assert( p->eVdbeState==VDBE_INIT_STATE );
8181282420
assert( pParse==p->pParse );
8181382421
p->pVList = pParse->pVList;
8181482422
pParse->pVList = 0;
8181582423
db = p->db;
8181682424
assert( db->mallocFailed==0 );
@@ -81947,18 +82555,16 @@
8194782555
8194882556
/*
8194982557
** Close all cursors in the current frame.
8195082558
*/
8195182559
static void closeCursorsInFrame(Vdbe *p){
81952
- if( p->apCsr ){
81953
- int i;
81954
- for(i=0; i<p->nCursor; i++){
81955
- VdbeCursor *pC = p->apCsr[i];
81956
- if( pC ){
81957
- sqlite3VdbeFreeCursor(p, pC);
81958
- p->apCsr[i] = 0;
81959
- }
82560
+ int i;
82561
+ for(i=0; i<p->nCursor; i++){
82562
+ VdbeCursor *pC = p->apCsr[i];
82563
+ if( pC ){
82564
+ sqlite3VdbeFreeCursor(p, pC);
82565
+ p->apCsr[i] = 0;
8196082566
}
8196182567
}
8196282568
}
8196382569
8196482570
/*
@@ -82003,13 +82609,11 @@
8200382609
p->pFrame = 0;
8200482610
p->nFrame = 0;
8200582611
}
8200682612
assert( p->nFrame==0 );
8200782613
closeCursorsInFrame(p);
82008
- if( p->aMem ){
82009
- releaseMemArray(p->aMem, p->nMem);
82010
- }
82614
+ releaseMemArray(p->aMem, p->nMem);
8201182615
while( p->pDelFrame ){
8201282616
VdbeFrame *pDel = p->pDelFrame;
8201382617
p->pDelFrame = pDel->pParent;
8201482618
sqlite3VdbeFrameDelete(pDel);
8201582619
}
@@ -82445,11 +83049,12 @@
8244583049
|| (!deferred && p->nFkConstraint>0)
8244683050
){
8244783051
p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
8244883052
p->errorAction = OE_Abort;
8244983053
sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
82450
- return SQLITE_ERROR;
83054
+ if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR;
83055
+ return SQLITE_CONSTRAINT_FOREIGNKEY;
8245183056
}
8245283057
return SQLITE_OK;
8245383058
}
8245483059
#endif
8245583060
@@ -82484,11 +83089,11 @@
8248483089
** Then the internal cache might have been left in an inconsistent
8248583090
** state. We need to rollback the statement transaction, if there is
8248683091
** one, or the complete transaction if there is no statement transaction.
8248783092
*/
8248883093
82489
- if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
83094
+ if( p->eVdbeState!=VDBE_RUN_STATE ){
8249083095
return SQLITE_OK;
8249183096
}
8249283097
if( db->mallocFailed ){
8249383098
p->rc = SQLITE_NOMEM_BKPT;
8249483099
}
@@ -82495,11 +83100,11 @@
8249583100
closeAllCursors(p);
8249683101
checkActiveVdbeCnt(db);
8249783102
8249883103
/* No commit or rollback needed if the program never started or if the
8249983104
** SQL statement does not read or write a database file. */
82500
- if( p->pc>=0 && p->bIsReader ){
83105
+ if( p->bIsReader ){
8250183106
int mrc; /* Primary error code from p->rc */
8250283107
int eStatementOp = 0;
8250383108
int isSpecialError; /* Set to true if a 'special' error */
8250483109
8250583110
/* Lock all btrees used by the statement */
@@ -82643,19 +83248,17 @@
8264383248
/* Release the locks */
8264483249
sqlite3VdbeLeave(p);
8264583250
}
8264683251
8264783252
/* We have successfully halted and closed the VM. Record this fact. */
82648
- if( p->pc>=0 ){
82649
- db->nVdbeActive--;
82650
- if( !p->readOnly ) db->nVdbeWrite--;
82651
- if( p->bIsReader ) db->nVdbeRead--;
82652
- assert( db->nVdbeActive>=db->nVdbeRead );
82653
- assert( db->nVdbeRead>=db->nVdbeWrite );
82654
- assert( db->nVdbeWrite>=0 );
82655
- }
82656
- p->iVdbeMagic = VDBE_MAGIC_HALT;
83253
+ db->nVdbeActive--;
83254
+ if( !p->readOnly ) db->nVdbeWrite--;
83255
+ if( p->bIsReader ) db->nVdbeRead--;
83256
+ assert( db->nVdbeActive>=db->nVdbeRead );
83257
+ assert( db->nVdbeRead>=db->nVdbeWrite );
83258
+ assert( db->nVdbeWrite>=0 );
83259
+ p->eVdbeState = VDBE_HALT_STATE;
8265783260
checkActiveVdbeCnt(db);
8265883261
if( db->mallocFailed ){
8265983262
p->rc = SQLITE_NOMEM_BKPT;
8266083263
}
8266183264
@@ -82700,10 +83303,11 @@
8270083303
db->bBenignMalloc--;
8270183304
}else if( db->pErr ){
8270283305
sqlite3ValueSetNull(db->pErr);
8270383306
}
8270483307
db->errCode = rc;
83308
+ db->errByteOffset = -1;
8270583309
return rc;
8270683310
}
8270783311
8270883312
#ifdef SQLITE_ENABLE_SQLLOG
8270983313
/*
@@ -82732,12 +83336,12 @@
8273283336
**
8273383337
** After this routine is run, the VDBE should be ready to be executed
8273483338
** again.
8273583339
**
8273683340
** To look at it another way, this routine resets the state of the
82737
-** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
82738
-** VDBE_MAGIC_INIT.
83341
+** virtual machine from VDBE_RUN_STATE or VDBE_HALT_STATE back to
83342
+** VDBE_READY_STATE.
8273983343
*/
8274083344
SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
8274183345
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
8274283346
int i;
8274383347
#endif
@@ -82762,16 +83366,10 @@
8276283366
sqlite3VdbeTransferError(p);
8276383367
}else{
8276483368
db->errCode = p->rc;
8276583369
}
8276683370
if( p->runOnlyOnce ) p->expired = 1;
82767
- }else if( p->rc && p->expired ){
82768
- /* The expired flag was set on the VDBE before the first call
82769
- ** to sqlite3_step(). For consistency (since sqlite3_step() was
82770
- ** called), set the database error in this case as well.
82771
- */
82772
- sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
8277383371
}
8277483372
8277583373
/* Reset register contents and reclaim error message memory.
8277683374
*/
8277783375
#ifdef SQLITE_DEBUG
@@ -82824,21 +83422,23 @@
8282483422
}
8282583423
fclose(out);
8282683424
}
8282783425
}
8282883426
#endif
82829
- p->iVdbeMagic = VDBE_MAGIC_RESET;
8283083427
return p->rc & db->errMask;
8283183428
}
8283283429
8283383430
/*
8283483431
** Clean up and delete a VDBE after execution. Return an integer which is
8283583432
** the result code. Write any error message text into *pzErrMsg.
8283683433
*/
8283783434
SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
8283883435
int rc = SQLITE_OK;
82839
- if( p->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){
83436
+ assert( VDBE_RUN_STATE>VDBE_READY_STATE );
83437
+ assert( VDBE_HALT_STATE>VDBE_READY_STATE );
83438
+ assert( VDBE_INIT_STATE<VDBE_READY_STATE );
83439
+ if( p->eVdbeState>=VDBE_READY_STATE ){
8284083440
rc = sqlite3VdbeReset(p);
8284183441
assert( (rc & p->db->errMask)==rc );
8284283442
}
8284383443
sqlite3VdbeDelete(p);
8284483444
return rc;
@@ -82889,23 +83489,25 @@
8288983489
** the database connection and frees the object itself.
8289083490
*/
8289183491
SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
8289283492
SubProgram *pSub, *pNext;
8289383493
assert( p->db==0 || p->db==db );
82894
- releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
83494
+ if( p->aColName ){
83495
+ releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
83496
+ sqlite3DbFreeNN(db, p->aColName);
83497
+ }
8289583498
for(pSub=p->pProgram; pSub; pSub=pNext){
8289683499
pNext = pSub->pNext;
8289783500
vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
8289883501
sqlite3DbFree(db, pSub);
8289983502
}
82900
- if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){
83503
+ if( p->eVdbeState!=VDBE_INIT_STATE ){
8290183504
releaseMemArray(p->aVar, p->nVar);
82902
- sqlite3DbFree(db, p->pVList);
82903
- sqlite3DbFree(db, p->pFree);
83505
+ if( p->pVList ) sqlite3DbFreeNN(db, p->pVList);
83506
+ if( p->pFree ) sqlite3DbFreeNN(db, p->pFree);
8290483507
}
8290583508
vdbeFreeOpArray(db, p->aOp, p->nOp);
82906
- sqlite3DbFree(db, p->aColName);
8290783509
sqlite3DbFree(db, p->zSql);
8290883510
#ifdef SQLITE_ENABLE_NORMALIZE
8290983511
sqlite3DbFree(db, p->zNormSql);
8291083512
{
8291183513
DblquoteStr *pThis, *pNext;
@@ -82943,12 +83545,10 @@
8294383545
db->pVdbe = p->pNext;
8294483546
}
8294583547
if( p->pNext ){
8294683548
p->pNext->pPrev = p->pPrev;
8294783549
}
82948
- p->iVdbeMagic = VDBE_MAGIC_DEAD;
82949
- p->db = 0;
8295083550
sqlite3DbFreeNN(db, p);
8295183551
}
8295283552
8295383553
/*
8295483554
** The cursor "p" has a pending seek operation that has not yet been
@@ -82979,11 +83579,11 @@
8297983579
** pointed to was deleted out from under it. Or maybe the btree was
8298083580
** rebalanced. Whatever the cause, try to restore "p" to the place it
8298183581
** is supposed to be pointing. If the row was deleted out from under the
8298283582
** cursor, set the cursor to point to a NULL row.
8298383583
*/
82984
-static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
83584
+SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){
8298583585
int isDifferentRow, rc;
8298683586
assert( p->eCurType==CURTYPE_BTREE );
8298783587
assert( p->uc.pCursor!=0 );
8298883588
assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) );
8298983589
rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow);
@@ -82997,43 +83597,11 @@
8299783597
** if need be. Return any I/O error from the restore operation.
8299883598
*/
8299983599
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
8300083600
assert( p->eCurType==CURTYPE_BTREE );
8300183601
if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
83002
- return handleMovedCursor(p);
83003
- }
83004
- return SQLITE_OK;
83005
-}
83006
-
83007
-/*
83008
-** Make sure the cursor p is ready to read or write the row to which it
83009
-** was last positioned. Return an error code if an OOM fault or I/O error
83010
-** prevents us from positioning the cursor to its correct position.
83011
-**
83012
-** If a MoveTo operation is pending on the given cursor, then do that
83013
-** MoveTo now. If no move is pending, check to see if the row has been
83014
-** deleted out from under the cursor and if it has, mark the row as
83015
-** a NULL row.
83016
-**
83017
-** If the cursor is already pointing to the correct row and that row has
83018
-** not been deleted out from under the cursor, then this routine is a no-op.
83019
-*/
83020
-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){
83021
- VdbeCursor *p = *pp;
83022
- assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
83023
- if( p->deferredMoveto ){
83024
- u32 iMap;
83025
- assert( !p->isEphemeral );
83026
- if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){
83027
- *pp = p->pAltCursor;
83028
- *piCol = iMap - 1;
83029
- return SQLITE_OK;
83030
- }
83031
- return sqlite3VdbeFinishMoveto(p);
83032
- }
83033
- if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
83034
- return handleMovedCursor(p);
83602
+ return sqlite3VdbeHandleMovedCursor(p);
8303583603
}
8303683604
return SQLITE_OK;
8303783605
}
8303883606
8303983607
/*
@@ -83691,12 +84259,12 @@
8369184259
if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
8369284260
rc = 0;
8369384261
}else{
8369484262
rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2);
8369584263
}
83696
- sqlite3VdbeMemRelease(&c1);
83697
- sqlite3VdbeMemRelease(&c2);
84264
+ sqlite3VdbeMemReleaseMalloc(&c1);
84265
+ sqlite3VdbeMemReleaseMalloc(&c2);
8369884266
return rc;
8369984267
}
8370084268
}
8370184269
8370284270
/*
@@ -84216,11 +84784,12 @@
8421684784
8421784785
default:
8421884786
return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
8421984787
}
8422084788
84221
- v = pPKey2->aMem[0].u.i;
84789
+ assert( pPKey2->u.i == pPKey2->aMem[0].u.i );
84790
+ v = pPKey2->u.i;
8422284791
if( v>lhs ){
8422384792
res = pPKey2->r1;
8422484793
}else if( v<lhs ){
8422584794
res = pPKey2->r2;
8422684795
}else if( pPKey2->nField>1 ){
@@ -84251,16 +84820,22 @@
8425184820
const u8 *aKey1 = (const u8*)pKey1;
8425284821
int serial_type;
8425384822
int res;
8425484823
8425584824
assert( pPKey2->aMem[0].flags & MEM_Str );
84825
+ assert( pPKey2->aMem[0].n == pPKey2->n );
84826
+ assert( pPKey2->aMem[0].z == pPKey2->u.z );
8425684827
vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
84257
- serial_type = (u8)(aKey1[1]);
84258
- if( serial_type >= 0x80 ){
84259
- sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
84260
- }
84828
+ serial_type = (signed char)(aKey1[1]);
84829
+
84830
+vrcs_restart:
8426184831
if( serial_type<12 ){
84832
+ if( serial_type<0 ){
84833
+ sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
84834
+ if( serial_type>=12 ) goto vrcs_restart;
84835
+ assert( CORRUPT_DB );
84836
+ }
8426284837
res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
8426384838
}else if( !(serial_type & 0x01) ){
8426484839
res = pPKey2->r2; /* (pKey1/nKey1) is a blob */
8426584840
}else{
8426684841
int nCmp;
@@ -84270,19 +84845,19 @@
8427084845
nStr = (serial_type-12) / 2;
8427184846
if( (szHdr + nStr) > nKey1 ){
8427284847
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
8427384848
return 0; /* Corruption */
8427484849
}
84275
- nCmp = MIN( pPKey2->aMem[0].n, nStr );
84276
- res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
84850
+ nCmp = MIN( pPKey2->n, nStr );
84851
+ res = memcmp(&aKey1[szHdr], pPKey2->u.z, nCmp);
8427784852
8427884853
if( res>0 ){
8427984854
res = pPKey2->r2;
8428084855
}else if( res<0 ){
8428184856
res = pPKey2->r1;
8428284857
}else{
84283
- res = nStr - pPKey2->aMem[0].n;
84858
+ res = nStr - pPKey2->n;
8428484859
if( res==0 ){
8428584860
if( pPKey2->nField>1 ){
8428684861
res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
8428784862
}else{
8428884863
res = pPKey2->default_rc;
@@ -84333,19 +84908,22 @@
8433384908
}else{
8433484909
p->r1 = -1;
8433584910
p->r2 = 1;
8433684911
}
8433784912
if( (flags & MEM_Int) ){
84913
+ p->u.i = p->aMem[0].u.i;
8433884914
return vdbeRecordCompareInt;
8433984915
}
8434084916
testcase( flags & MEM_Real );
8434184917
testcase( flags & MEM_Null );
8434284918
testcase( flags & MEM_Blob );
8434384919
if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
8434484920
&& p->pKeyInfo->aColl[0]==0
8434584921
){
8434684922
assert( flags & MEM_Str );
84923
+ p->u.z = p->aMem[0].z;
84924
+ p->n = p->aMem[0].n;
8434784925
return vdbeRecordCompareString;
8434884926
}
8434984927
}
8435084928
8435184929
return sqlite3VdbeRecordCompare;
@@ -84414,18 +84992,18 @@
8441484992
}
8441584993
8441684994
/* Fetch the integer off the end of the index record */
8441784995
sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
8441884996
*rowid = v.u.i;
84419
- sqlite3VdbeMemRelease(&m);
84997
+ sqlite3VdbeMemReleaseMalloc(&m);
8442084998
return SQLITE_OK;
8442184999
8442285000
/* Jump here if database corruption is detected after m has been
8442385001
** allocated. Free the m object and return SQLITE_CORRUPT. */
8442485002
idx_rowid_corruption:
8442585003
testcase( m.szMalloc!=0 );
84426
- sqlite3VdbeMemRelease(&m);
85004
+ sqlite3VdbeMemReleaseMalloc(&m);
8442785005
return SQLITE_CORRUPT_BKPT;
8442885006
}
8442985007
8443085008
/*
8443185009
** Compare the key of the index entry that cursor pC is pointing to against
@@ -84463,11 +85041,11 @@
8446385041
rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
8446485042
if( rc ){
8446585043
return rc;
8446685044
}
8446785045
*res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
84468
- sqlite3VdbeMemRelease(&m);
85046
+ sqlite3VdbeMemReleaseMalloc(&m);
8446985047
return SQLITE_OK;
8447085048
}
8447185049
8447285050
/*
8447385051
** This routine sets the value to be returned by subsequent calls to
@@ -84630,11 +85208,11 @@
8463085208
static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
8463185209
if( p ){
8463285210
int i;
8463385211
for(i=0; i<nField; i++){
8463485212
Mem *pMem = &p->aMem[i];
84635
- if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
85213
+ if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem);
8463685214
}
8463785215
sqlite3DbFreeNN(db, p);
8463885216
}
8463985217
}
8464085218
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -85057,10 +85635,13 @@
8505785635
pNew->flags |= MEM_Ephem;
8505885636
if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
8505985637
sqlite3ValueFree(pNew);
8506085638
pNew = 0;
8506185639
}
85640
+ }else if( pNew->flags & MEM_Null ){
85641
+ /* Do not duplicate pointer values */
85642
+ pNew->flags &= ~(MEM_Term|MEM_Subtype);
8506285643
}
8506385644
return pNew;
8506485645
}
8506585646
8506685647
/* Destroy an sqlite3_value object previously obtained from
@@ -85087,20 +85668,26 @@
8508785668
const char *z, /* String pointer */
8508885669
int n, /* Bytes in string, or negative */
8508985670
u8 enc, /* Encoding of z. 0 for BLOBs */
8509085671
void (*xDel)(void*) /* Destructor function */
8509185672
){
85092
- int rc = sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel);
85673
+ Mem *pOut = pCtx->pOut;
85674
+ int rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel);
8509385675
if( rc ){
8509485676
if( rc==SQLITE_TOOBIG ){
8509585677
sqlite3_result_error_toobig(pCtx);
8509685678
}else{
8509785679
/* The only errors possible from sqlite3VdbeMemSetStr are
8509885680
** SQLITE_TOOBIG and SQLITE_NOMEM */
8509985681
assert( rc==SQLITE_NOMEM );
8510085682
sqlite3_result_error_nomem(pCtx);
8510185683
}
85684
+ return;
85685
+ }
85686
+ sqlite3VdbeChangeEncoding(pOut, pCtx->enc);
85687
+ if( sqlite3VdbeMemTooBig(pOut) ){
85688
+ sqlite3_result_error_toobig(pCtx);
8510285689
}
8510385690
}
8510485691
static int invokeValueDestructor(
8510585692
const void *p, /* Value to destroy */
8510685693
void (*xDel)(void*), /* The destructor */
@@ -85240,21 +85827,26 @@
8524085827
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
8524185828
setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
8524285829
}
8524385830
#endif /* SQLITE_OMIT_UTF16 */
8524485831
SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
85832
+ Mem *pOut = pCtx->pOut;
8524585833
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
85246
- sqlite3VdbeMemCopy(pCtx->pOut, pValue);
85834
+ sqlite3VdbeMemCopy(pOut, pValue);
85835
+ sqlite3VdbeChangeEncoding(pOut, pCtx->enc);
85836
+ if( sqlite3VdbeMemTooBig(pOut) ){
85837
+ sqlite3_result_error_toobig(pCtx);
85838
+ }
8524785839
}
8524885840
SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
85249
- assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
85250
- sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
85841
+ sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0);
8525185842
}
8525285843
SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
8525385844
Mem *pOut = pCtx->pOut;
8525485845
assert( sqlite3_mutex_held(pOut->db->mutex) );
8525585846
if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
85847
+ sqlite3_result_error_toobig(pCtx);
8525685848
return SQLITE_TOOBIG;
8525785849
}
8525885850
#ifndef SQLITE_OMIT_INCRBLOB
8525985851
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
8526085852
return SQLITE_OK;
@@ -85266,12 +85858,12 @@
8526685858
pCtx->isError = errCode ? errCode : -1;
8526785859
#ifdef SQLITE_DEBUG
8526885860
if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
8526985861
#endif
8527085862
if( pCtx->pOut->flags & MEM_Null ){
85271
- sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1,
85272
- SQLITE_UTF8, SQLITE_STATIC);
85863
+ setResultStrOrError(pCtx, sqlite3ErrStr(errCode), -1, SQLITE_UTF8,
85864
+ SQLITE_STATIC);
8527385865
}
8527485866
}
8527585867
8527685868
/* Force an SQLITE_TOOBIG error. */
8527785869
SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
@@ -85340,85 +85932,94 @@
8534085932
*/
8534185933
static int sqlite3Step(Vdbe *p){
8534285934
sqlite3 *db;
8534385935
int rc;
8534485936
85345
- assert(p);
85346
- if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
85347
- /* We used to require that sqlite3_reset() be called before retrying
85348
- ** sqlite3_step() after any error or after SQLITE_DONE. But beginning
85349
- ** with version 3.7.0, we changed this so that sqlite3_reset() would
85350
- ** be called automatically instead of throwing the SQLITE_MISUSE error.
85351
- ** This "automatic-reset" change is not technically an incompatibility,
85352
- ** since any application that receives an SQLITE_MISUSE is broken by
85353
- ** definition.
85354
- **
85355
- ** Nevertheless, some published applications that were originally written
85356
- ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
85357
- ** returns, and those were broken by the automatic-reset change. As a
85358
- ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
85359
- ** legacy behavior of returning SQLITE_MISUSE for cases where the
85360
- ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
85361
- ** or SQLITE_BUSY error.
85362
- */
85363
-#ifdef SQLITE_OMIT_AUTORESET
85364
- if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
85365
- sqlite3_reset((sqlite3_stmt*)p);
85366
- }else{
85367
- return SQLITE_MISUSE_BKPT;
85368
- }
85369
-#else
85370
- sqlite3_reset((sqlite3_stmt*)p);
85371
-#endif
85372
- }
85373
-
8537485937
/* Check that malloc() has not failed. If it has, return early. */
8537585938
db = p->db;
8537685939
if( db->mallocFailed ){
8537785940
p->rc = SQLITE_NOMEM;
8537885941
return SQLITE_NOMEM_BKPT;
8537985942
}
8538085943
85381
- if( p->pc<0 && p->expired ){
85382
- p->rc = SQLITE_SCHEMA;
85383
- rc = SQLITE_ERROR;
85384
- if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){
85385
- /* If this statement was prepared using saved SQL and an
85386
- ** error has occurred, then return the error code in p->rc to the
85387
- ** caller. Set the error code in the database handle to the same value.
85388
- */
85389
- rc = sqlite3VdbeTransferError(p);
85390
- }
85391
- goto end_of_step;
85392
- }
85393
- if( p->pc<0 ){
85394
- /* If there are no other statements currently running, then
85395
- ** reset the interrupt flag. This prevents a call to sqlite3_interrupt
85396
- ** from interrupting a statement that has not yet started.
85397
- */
85398
- if( db->nVdbeActive==0 ){
85399
- AtomicStore(&db->u1.isInterrupted, 0);
85400
- }
85401
-
85402
- assert( db->nVdbeWrite>0 || db->autoCommit==0
85403
- || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
85404
- );
85944
+ assert(p);
85945
+ if( p->eVdbeState!=VDBE_RUN_STATE ){
85946
+ restart_step:
85947
+ if( p->eVdbeState==VDBE_READY_STATE ){
85948
+ if( p->expired ){
85949
+ p->rc = SQLITE_SCHEMA;
85950
+ rc = SQLITE_ERROR;
85951
+ if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){
85952
+ /* If this statement was prepared using saved SQL and an
85953
+ ** error has occurred, then return the error code in p->rc to the
85954
+ ** caller. Set the error code in the database handle to the same
85955
+ ** value.
85956
+ */
85957
+ rc = sqlite3VdbeTransferError(p);
85958
+ }
85959
+ goto end_of_step;
85960
+ }
85961
+
85962
+ /* If there are no other statements currently running, then
85963
+ ** reset the interrupt flag. This prevents a call to sqlite3_interrupt
85964
+ ** from interrupting a statement that has not yet started.
85965
+ */
85966
+ if( db->nVdbeActive==0 ){
85967
+ AtomicStore(&db->u1.isInterrupted, 0);
85968
+ }
85969
+
85970
+ assert( db->nVdbeWrite>0 || db->autoCommit==0
85971
+ || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
85972
+ );
8540585973
8540685974
#ifndef SQLITE_OMIT_TRACE
85407
- if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
85408
- && !db->init.busy && p->zSql ){
85409
- sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
85410
- }else{
85411
- assert( p->startTime==0 );
85412
- }
85975
+ if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
85976
+ && !db->init.busy && p->zSql ){
85977
+ sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
85978
+ }else{
85979
+ assert( p->startTime==0 );
85980
+ }
8541385981
#endif
8541485982
85415
- db->nVdbeActive++;
85416
- if( p->readOnly==0 ) db->nVdbeWrite++;
85417
- if( p->bIsReader ) db->nVdbeRead++;
85418
- p->pc = 0;
85983
+ db->nVdbeActive++;
85984
+ if( p->readOnly==0 ) db->nVdbeWrite++;
85985
+ if( p->bIsReader ) db->nVdbeRead++;
85986
+ p->pc = 0;
85987
+ p->eVdbeState = VDBE_RUN_STATE;
85988
+ }else
85989
+
85990
+ if( ALWAYS(p->eVdbeState==VDBE_HALT_STATE) ){
85991
+ /* We used to require that sqlite3_reset() be called before retrying
85992
+ ** sqlite3_step() after any error or after SQLITE_DONE. But beginning
85993
+ ** with version 3.7.0, we changed this so that sqlite3_reset() would
85994
+ ** be called automatically instead of throwing the SQLITE_MISUSE error.
85995
+ ** This "automatic-reset" change is not technically an incompatibility,
85996
+ ** since any application that receives an SQLITE_MISUSE is broken by
85997
+ ** definition.
85998
+ **
85999
+ ** Nevertheless, some published applications that were originally written
86000
+ ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
86001
+ ** returns, and those were broken by the automatic-reset change. As a
86002
+ ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
86003
+ ** legacy behavior of returning SQLITE_MISUSE for cases where the
86004
+ ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
86005
+ ** or SQLITE_BUSY error.
86006
+ */
86007
+#ifdef SQLITE_OMIT_AUTORESET
86008
+ if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
86009
+ sqlite3_reset((sqlite3_stmt*)p);
86010
+ }else{
86011
+ return SQLITE_MISUSE_BKPT;
86012
+ }
86013
+#else
86014
+ sqlite3_reset((sqlite3_stmt*)p);
86015
+#endif
86016
+ assert( p->eVdbeState==VDBE_READY_STATE );
86017
+ goto restart_step;
86018
+ }
8541986019
}
86020
+
8542086021
#ifdef SQLITE_DEBUG
8542186022
p->rcApp = SQLITE_OK;
8542286023
#endif
8542386024
#ifndef SQLITE_OMIT_EXPLAIN
8542486025
if( p->explain ){
@@ -85429,11 +86030,16 @@
8542986030
db->nVdbeExec++;
8543086031
rc = sqlite3VdbeExec(p);
8543186032
db->nVdbeExec--;
8543286033
}
8543386034
85434
- if( rc!=SQLITE_ROW ){
86035
+ if( rc==SQLITE_ROW ){
86036
+ assert( p->rc==SQLITE_OK );
86037
+ assert( db->mallocFailed==0 );
86038
+ db->errCode = SQLITE_ROW;
86039
+ return SQLITE_ROW;
86040
+ }else{
8543586041
#ifndef SQLITE_OMIT_TRACE
8543686042
/* If the statement completed successfully, invoke the profile callback */
8543786043
checkProfileCallback(db, p);
8543886044
#endif
8543986045
@@ -85557,10 +86163,74 @@
8555786163
*/
8555886164
SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
8555986165
assert( p );
8556086166
return sqlite3_value_nochange(p->pOut);
8556186167
}
86168
+
86169
+/*
86170
+** Implementation of sqlite3_vtab_in_first() (if bNext==0) and
86171
+** sqlite3_vtab_in_next() (if bNext!=0).
86172
+*/
86173
+static int valueFromValueList(
86174
+ sqlite3_value *pVal, /* Pointer to the ValueList object */
86175
+ sqlite3_value **ppOut, /* Store the next value from the list here */
86176
+ int bNext /* 1 for _next(). 0 for _first() */
86177
+){
86178
+ int rc;
86179
+ ValueList *pRhs;
86180
+
86181
+ *ppOut = 0;
86182
+ if( pVal==0 ) return SQLITE_MISUSE;
86183
+ pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList");
86184
+ if( pRhs==0 ) return SQLITE_MISUSE;
86185
+ if( bNext ){
86186
+ rc = sqlite3BtreeNext(pRhs->pCsr, 0);
86187
+ }else{
86188
+ int dummy = 0;
86189
+ rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy);
86190
+ assert( rc==SQLITE_OK || sqlite3BtreeEof(pRhs->pCsr) );
86191
+ if( sqlite3BtreeEof(pRhs->pCsr) ) rc = SQLITE_DONE;
86192
+ }
86193
+ if( rc==SQLITE_OK ){
86194
+ u32 sz; /* Size of current row in bytes */
86195
+ Mem sMem; /* Raw content of current row */
86196
+ memset(&sMem, 0, sizeof(sMem));
86197
+ sz = sqlite3BtreePayloadSize(pRhs->pCsr);
86198
+ rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem);
86199
+ if( rc==SQLITE_OK ){
86200
+ u8 *zBuf = (u8*)sMem.z;
86201
+ u32 iSerial;
86202
+ sqlite3_value *pOut = pRhs->pOut;
86203
+ int iOff = 1 + getVarint32(&zBuf[1], iSerial);
86204
+ sqlite3VdbeSerialGet(&zBuf[iOff], iSerial, pOut);
86205
+ pOut->enc = ENC(pOut->db);
86206
+ if( (pOut->flags & MEM_Ephem)!=0 && sqlite3VdbeMemMakeWriteable(pOut) ){
86207
+ rc = SQLITE_NOMEM;
86208
+ }else{
86209
+ *ppOut = pOut;
86210
+ }
86211
+ }
86212
+ sqlite3VdbeMemRelease(&sMem);
86213
+ }
86214
+ return rc;
86215
+}
86216
+
86217
+/*
86218
+** Set the iterator value pVal to point to the first value in the set.
86219
+** Set (*ppOut) to point to this value before returning.
86220
+*/
86221
+SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut){
86222
+ return valueFromValueList(pVal, ppOut, 0);
86223
+}
86224
+
86225
+/*
86226
+** Set the iterator value pVal to point to the next value in the set.
86227
+** Set (*ppOut) to point to this value before returning.
86228
+*/
86229
+SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut){
86230
+ return valueFromValueList(pVal, ppOut, 1);
86231
+}
8556286232
8556386233
/*
8556486234
** Return the current time for a statement. If the current time
8556586235
** is requested more than once within the same run of a single prepared
8556686236
** statement, the exact same time is returned for each invocation regardless
@@ -85752,19 +86422,19 @@
8575286422
#if defined(SQLITE_DEBUG) && defined(__GNUC__)
8575386423
__attribute__((aligned(8)))
8575486424
#endif
8575586425
= {
8575686426
/* .u = */ {0},
86427
+ /* .z = */ (char*)0,
86428
+ /* .n = */ (int)0,
8575786429
/* .flags = */ (u16)MEM_Null,
8575886430
/* .enc = */ (u8)0,
8575986431
/* .eSubtype = */ (u8)0,
85760
- /* .n = */ (int)0,
85761
- /* .z = */ (char*)0,
85762
- /* .zMalloc = */ (char*)0,
86432
+ /* .db = */ (sqlite3*)0,
8576386433
/* .szMalloc = */ (int)0,
8576486434
/* .uTemp = */ (u32)0,
85765
- /* .db = */ (sqlite3*)0,
86435
+ /* .zMalloc = */ (char*)0,
8576686436
/* .xDel = */ (void(*)(void*))0,
8576786437
#ifdef SQLITE_DEBUG
8576886438
/* .pScopyFrom = */ (Mem*)0,
8576986439
/* .mScopyFlags= */ 0,
8577086440
#endif
@@ -86057,11 +86727,11 @@
8605786727
Mem *pVar;
8605886728
if( vdbeSafetyNotNull(p) ){
8605986729
return SQLITE_MISUSE_BKPT;
8606086730
}
8606186731
sqlite3_mutex_enter(p->db->mutex);
86062
- if( p->iVdbeMagic!=VDBE_MAGIC_RUN || p->pc>=0 ){
86732
+ if( p->eVdbeState!=VDBE_READY_STATE ){
8606386733
sqlite3Error(p->db, SQLITE_MISUSE);
8606486734
sqlite3_mutex_leave(p->db->mutex);
8606586735
sqlite3_log(SQLITE_MISUSE,
8606686736
"bind on a busy prepared statement: [%s]", p->zSql);
8606786737
return SQLITE_MISUSE_BKPT;
@@ -86242,11 +86912,14 @@
8624286912
case SQLITE_INTEGER: {
8624386913
rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
8624486914
break;
8624586915
}
8624686916
case SQLITE_FLOAT: {
86247
- rc = sqlite3_bind_double(pStmt, i, pValue->u.r);
86917
+ assert( pValue->flags & (MEM_Real|MEM_IntReal) );
86918
+ rc = sqlite3_bind_double(pStmt, i,
86919
+ (pValue->flags & MEM_Real) ? pValue->u.r : (double)pValue->u.i
86920
+ );
8624886921
break;
8624986922
}
8625086923
case SQLITE_BLOB: {
8625186924
if( pValue->flags & MEM_Zero ){
8625286925
rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero);
@@ -86407,11 +87080,11 @@
8640787080
/*
8640887081
** Return true if the prepared statement is in need of being reset.
8640987082
*/
8641087083
SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
8641187084
Vdbe *v = (Vdbe*)pStmt;
86412
- return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0;
87085
+ return v!=0 && v->eVdbeState==VDBE_RUN_STATE;
8641387086
}
8641487087
8641587088
/*
8641687089
** Return a pointer to the next prepared statement after pStmt associated
8641787090
** with database connection pDb. If pStmt is NULL, return the first
@@ -87721,11 +88394,11 @@
8772188394
#ifdef VDBE_PROFILE
8772288395
u64 start; /* CPU clock count at start of opcode */
8772388396
#endif
8772488397
/*** INSERT STACK UNION HERE ***/
8772588398
87726
- assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
88399
+ assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */
8772788400
sqlite3VdbeEnter(p);
8772888401
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
8772988402
if( db->xProgress ){
8773088403
u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
8773188404
assert( 0 < db->nProgressOps );
@@ -87972,14 +88645,18 @@
8797288645
jump_to_p2:
8797388646
pOp = &aOp[pOp->p2 - 1];
8797488647
break;
8797588648
}
8797688649
87977
-/* Opcode: Return P1 * * * *
88650
+/* Opcode: Return P1 * P3 * *
8797888651
**
8797988652
** Jump to the next instruction after the address in register P1. After
8798088653
** the jump, register P1 becomes undefined.
88654
+**
88655
+** P3 is not used by the byte-code engine. However, the code generator
88656
+** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is
88657
+** one.
8798188658
*/
8798288659
case OP_Return: { /* in1 */
8798388660
pIn1 = &aMem[pOp->p1];
8798488661
assert( pIn1->flags==MEM_Int );
8798588662
pOp = &aOp[pIn1->u.i];
@@ -88163,15 +88840,26 @@
8816388840
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
8816488841
}
8816588842
goto vdbe_return;
8816688843
}
8816788844
88845
+/* Opcode: BeginSubrtn P1 P2 * * *
88846
+** Synopsis: r[P2]=P1
88847
+**
88848
+** Mark the beginning of a subroutine by loading the integer value P1
88849
+** into register r[P2]. The P2 register is used to store the return
88850
+** address of the subroutine call.
88851
+**
88852
+** This opcode is identical to OP_Integer. It has a different name
88853
+** only to make the byte code easier to read and verify.
88854
+*/
8816888855
/* Opcode: Integer P1 P2 * * *
8816988856
** Synopsis: r[P2]=P1
8817088857
**
8817188858
** The 32-bit integer value P1 is written into register P2.
8817288859
*/
88860
+case OP_BeginSubrtn:
8817388861
case OP_Integer: { /* out2 */
8817488862
pOut = out2Prerelease(p, pOp);
8817588863
pOut->u.i = pOp->p1;
8817688864
break;
8817788865
}
@@ -89608,14 +90296,22 @@
8960890296
case OP_Offset: { /* out3 */
8960990297
VdbeCursor *pC; /* The VDBE cursor */
8961090298
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
8961190299
pC = p->apCsr[pOp->p1];
8961290300
pOut = &p->aMem[pOp->p3];
89613
- if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){
90301
+ if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){
8961490302
sqlite3VdbeMemSetNull(pOut);
8961590303
}else{
89616
- sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
90304
+ if( pC->deferredMoveto ){
90305
+ rc = sqlite3VdbeFinishMoveto(pC);
90306
+ if( rc ) goto abort_due_to_error;
90307
+ }
90308
+ if( sqlite3BtreeEof(pC->uc.pCursor) ){
90309
+ sqlite3VdbeMemSetNull(pOut);
90310
+ }else{
90311
+ sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
90312
+ }
8961790313
}
8961890314
break;
8961990315
}
8962090316
#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
8962190317
@@ -89640,11 +90336,11 @@
8964090336
** skipped for length() and all content loading can be skipped for typeof().
8964190337
*/
8964290338
case OP_Column: {
8964390339
u32 p2; /* column number to retrieve */
8964490340
VdbeCursor *pC; /* The VDBE cursor */
89645
- BtCursor *pCrsr; /* The BTree cursor */
90341
+ BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */
8964690342
u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
8964790343
int len; /* The length of the serialized data for the column */
8964890344
int i; /* Loop counter */
8964990345
Mem *pDest; /* Where to write the extracted value */
8965090346
Mem sMem; /* For storing the record being decoded */
@@ -89654,23 +90350,15 @@
8965490350
u64 offset64; /* 64-bit offset */
8965590351
u32 t; /* A type code from the record header */
8965690352
Mem *pReg; /* PseudoTable input register */
8965790353
8965890354
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
90355
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
8965990356
pC = p->apCsr[pOp->p1];
89660
- assert( pC!=0 );
8966190357
p2 = (u32)pOp->p2;
8966290358
89663
- /* If the cursor cache is stale (meaning it is not currently point at
89664
- ** the correct row) then bring it up-to-date by doing the necessary
89665
- ** B-Tree seek. */
89666
- rc = sqlite3VdbeCursorMoveto(&pC, &p2);
89667
- if( rc ) goto abort_due_to_error;
89668
-
89669
- assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
89670
- pDest = &aMem[pOp->p3];
89671
- memAboutToChange(p, pDest);
90359
+op_column_restart:
8967290360
assert( pC!=0 );
8967390361
assert( p2<(u32)pC->nField );
8967490362
aOffset = pC->aOffset;
8967590363
assert( aOffset==pC->aType+pC->nField );
8967690364
assert( pC->eCurType!=CURTYPE_VTAB );
@@ -89687,30 +90375,43 @@
8968790375
assert( pReg->flags & MEM_Blob );
8968890376
assert( memIsValid(pReg) );
8968990377
pC->payloadSize = pC->szRow = pReg->n;
8969090378
pC->aRow = (u8*)pReg->z;
8969190379
}else{
90380
+ pDest = &aMem[pOp->p3];
90381
+ memAboutToChange(p, pDest);
8969290382
sqlite3VdbeMemSetNull(pDest);
8969390383
goto op_column_out;
8969490384
}
8969590385
}else{
8969690386
pCrsr = pC->uc.pCursor;
90387
+ if( pC->deferredMoveto ){
90388
+ u32 iMap;
90389
+ assert( !pC->isEphemeral );
90390
+ if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){
90391
+ pC = pC->pAltCursor;
90392
+ p2 = iMap - 1;
90393
+ goto op_column_restart;
90394
+ }
90395
+ rc = sqlite3VdbeFinishMoveto(pC);
90396
+ if( rc ) goto abort_due_to_error;
90397
+ }else if( sqlite3BtreeCursorHasMoved(pCrsr) ){
90398
+ rc = sqlite3VdbeHandleMovedCursor(pC);
90399
+ if( rc ) goto abort_due_to_error;
90400
+ goto op_column_restart;
90401
+ }
8969790402
assert( pC->eCurType==CURTYPE_BTREE );
8969890403
assert( pCrsr );
8969990404
assert( sqlite3BtreeCursorIsValid(pCrsr) );
8970090405
pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
8970190406
pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
8970290407
assert( pC->szRow<=pC->payloadSize );
8970390408
assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
89704
- if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
89705
- goto too_big;
89706
- }
8970790409
}
8970890410
pC->cacheStatus = p->cacheCtr;
8970990411
pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
8971090412
pC->nHdrParsed = 0;
89711
-
8971290413
8971390414
if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
8971490415
/* pC->aRow does not have to hold the entire row, but it does at least
8971590416
** need to cover the header of the record. If pC->aRow does not contain
8971690417
** the complete header, then set it to zero, forcing the header to be
@@ -89747,10 +90448,14 @@
8974790448
zData = pC->aRow;
8974890449
assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
8974990450
testcase( aOffset[0]==0 );
8975090451
goto op_column_read_header;
8975190452
}
90453
+ }else if( sqlite3BtreeCursorHasMoved(pC->uc.pCursor) ){
90454
+ rc = sqlite3VdbeHandleMovedCursor(pC);
90455
+ if( rc ) goto abort_due_to_error;
90456
+ goto op_column_restart;
8975290457
}
8975390458
8975490459
/* Make sure at least the first p2+1 entries of the header have been
8975590460
** parsed and valid information is in aOffset[] and pC->aType[].
8975690461
*/
@@ -89815,10 +90520,12 @@
8981590520
/* If after trying to extract new entries from the header, nHdrParsed is
8981690521
** still not up to p2, that means that the record has fewer than p2
8981790522
** columns. So the result will be either the default value or a NULL.
8981890523
*/
8981990524
if( pC->nHdrParsed<=p2 ){
90525
+ pDest = &aMem[pOp->p3];
90526
+ memAboutToChange(p, pDest);
8982090527
if( pOp->p4type==P4_MEM ){
8982190528
sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
8982290529
}else{
8982390530
sqlite3VdbeMemSetNull(pDest);
8982490531
}
@@ -89832,10 +90539,12 @@
8983290539
** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
8983390540
** all valid.
8983490541
*/
8983590542
assert( p2<pC->nHdrParsed );
8983690543
assert( rc==SQLITE_OK );
90544
+ pDest = &aMem[pOp->p3];
90545
+ memAboutToChange(p, pDest);
8983790546
assert( sqlite3VdbeCheckMemInvariants(pDest) );
8983890547
if( VdbeMemDynamic(pDest) ){
8983990548
sqlite3VdbeMemSetNull(pDest);
8984090549
}
8984190550
assert( t==pC->aType[p2] );
@@ -89852,10 +90561,11 @@
8985290561
*/
8985390562
static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term };
8985490563
pDest->n = len = (t-12)/2;
8985590564
pDest->enc = encoding;
8985690565
if( pDest->szMalloc < len+2 ){
90566
+ if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
8985790567
pDest->flags = MEM_Null;
8985890568
if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem;
8985990569
}else{
8986090570
pDest->z = pDest->zMalloc;
8986190571
}
@@ -89884,10 +90594,11 @@
8988490594
** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
8988590595
** and it begins with a bunch of zeros.
8988690596
*/
8988790597
sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
8988890598
}else{
90599
+ if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
8988990600
rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
8989090601
if( rc!=SQLITE_OK ) goto abort_due_to_error;
8989190602
sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
8989290603
pDest->flags &= ~MEM_Ephem;
8989390604
}
@@ -90096,11 +90807,10 @@
9009690807
u32 serial_type; /* Type field */
9009790808
Mem *pData0; /* First field to be combined into the record */
9009890809
Mem *pLast; /* Last field of the record */
9009990810
int nField; /* Number of fields in the record */
9010090811
char *zAffinity; /* The affinity string for the record */
90101
- int file_format; /* File format to use for encoding */
9010290812
u32 len; /* Length of a field */
9010390813
u8 *zHdr; /* Where to write next byte of the header */
9010490814
u8 *zPayload; /* Where to write next byte of the payload */
9010590815
9010690816
/* Assuming the record contains N fields, the record format looks
@@ -90125,11 +90835,10 @@
9012590835
zAffinity = pOp->p4.z;
9012690836
assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 );
9012790837
pData0 = &aMem[nField];
9012890838
nField = pOp->p2;
9012990839
pLast = &pData0[nField-1];
90130
- file_format = p->minWriteFileFormat;
9013190840
9013290841
/* Identify the output register */
9013390842
assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
9013490843
pOut = &aMem[pOp->p3];
9013590844
memAboutToChange(p, pOut);
@@ -90224,14 +90933,14 @@
9022490933
}
9022590934
nHdr++;
9022690935
testcase( uu==127 ); testcase( uu==128 );
9022790936
testcase( uu==32767 ); testcase( uu==32768 );
9022890937
testcase( uu==8388607 ); testcase( uu==8388608 );
90229
- testcase( uu==2147483647 ); testcase( uu==2147483648 );
90938
+ testcase( uu==2147483647 ); testcase( uu==2147483648LL );
9023090939
testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL );
9023190940
if( uu<=127 ){
90232
- if( (i&1)==i && file_format>=4 ){
90941
+ if( (i&1)==i && p->minWriteFileFormat>=4 ){
9023390942
pRec->uTemp = 8+(u32)uu;
9023490943
}else{
9023590944
nData++;
9023690945
pRec->uTemp = 1;
9023790946
}
@@ -92690,10 +93399,14 @@
9269093399
/* Opcode: NullRow P1 * * * *
9269193400
**
9269293401
** Move the cursor P1 to a null row. Any OP_Column operations
9269393402
** that occur while the cursor is on the null row will always
9269493403
** write a NULL.
93404
+**
93405
+** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo)
93406
+** just reset the cache for that cursor. This causes the row of
93407
+** content held by the pseudo-cursor to be reparsed.
9269593408
*/
9269693409
case OP_NullRow: {
9269793410
VdbeCursor *pC;
9269893411
9269993412
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
@@ -92869,11 +93582,11 @@
9286993582
VdbeBranchTaken(res!=0,2);
9287093583
if( res ) goto jump_to_p2;
9287193584
break;
9287293585
}
9287393586
92874
-/* Opcode: Next P1 P2 P3 P4 P5
93587
+/* Opcode: Next P1 P2 P3 * P5
9287593588
**
9287693589
** Advance cursor P1 so that it points to the next key/data pair in its
9287793590
** table or index. If there are no more key/value pairs then fall through
9287893591
** to the following instruction. But if the cursor advance was successful,
9287993592
** jump immediately to P2.
@@ -92888,19 +93601,16 @@
9288893601
** The P3 value is a hint to the btree implementation. If P3==1, that
9288993602
** means P1 is an SQL index and that this instruction could have been
9289093603
** omitted if that index had been unique. P3 is usually 0. P3 is
9289193604
** always either 0 or 1.
9289293605
**
92893
-** P4 is always of type P4_ADVANCE. The function pointer points to
92894
-** sqlite3BtreeNext().
92895
-**
9289693606
** If P5 is positive and the jump is taken, then event counter
9289793607
** number P5-1 in the prepared statement is incremented.
9289893608
**
9289993609
** See also: Prev
9290093610
*/
92901
-/* Opcode: Prev P1 P2 P3 P4 P5
93611
+/* Opcode: Prev P1 P2 P3 * P5
9290293612
**
9290393613
** Back up cursor P1 so that it points to the previous key/data pair in its
9290493614
** table or index. If there is no previous key/value pairs then fall through
9290593615
** to the following instruction. But if the cursor backup was successful,
9290693616
** jump immediately to P2.
@@ -92916,13 +93626,10 @@
9291693626
** The P3 value is a hint to the btree implementation. If P3==1, that
9291793627
** means P1 is an SQL index and that this instruction could have been
9291893628
** omitted if that index had been unique. P3 is usually 0. P3 is
9291993629
** always either 0 or 1.
9292093630
**
92921
-** P4 is always of type P4_ADVANCE. The function pointer points to
92922
-** sqlite3BtreePrevious().
92923
-**
9292493631
** If P5 is positive and the jump is taken, then event counter
9292593632
** number P5-1 in the prepared statement is incremented.
9292693633
*/
9292793634
/* Opcode: SorterNext P1 P2 * * P5
9292893635
**
@@ -92936,34 +93643,37 @@
9293693643
9293793644
pC = p->apCsr[pOp->p1];
9293893645
assert( isSorter(pC) );
9293993646
rc = sqlite3VdbeSorterNext(db, pC);
9294093647
goto next_tail;
93648
+
9294193649
case OP_Prev: /* jump */
93650
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93651
+ assert( pOp->p5<ArraySize(p->aCounter) );
93652
+ pC = p->apCsr[pOp->p1];
93653
+ assert( pC!=0 );
93654
+ assert( pC->deferredMoveto==0 );
93655
+ assert( pC->eCurType==CURTYPE_BTREE );
93656
+ assert( pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
93657
+ || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope
93658
+ || pC->seekOp==OP_NullRow);
93659
+ rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3);
93660
+ goto next_tail;
93661
+
9294293662
case OP_Next: /* jump */
9294393663
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
9294493664
assert( pOp->p5<ArraySize(p->aCounter) );
9294593665
pC = p->apCsr[pOp->p1];
9294693666
assert( pC!=0 );
9294793667
assert( pC->deferredMoveto==0 );
9294893668
assert( pC->eCurType==CURTYPE_BTREE );
92949
- assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
92950
- assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
92951
-
92952
- /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
92953
- ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
92954
- assert( pOp->opcode!=OP_Next
92955
- || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
93669
+ assert( pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
9295693670
|| pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
9295793671
|| pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid
9295893672
|| pC->seekOp==OP_IfNoHope);
92959
- assert( pOp->opcode!=OP_Prev
92960
- || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
92961
- || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope
92962
- || pC->seekOp==OP_NullRow);
93673
+ rc = sqlite3BtreeNext(pC->uc.pCursor, pOp->p3);
9296393674
92964
- rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
9296593675
next_tail:
9296693676
pC->cacheStatus = CACHE_STALE;
9296793677
VdbeBranchTaken(rc==SQLITE_OK,2);
9296893678
if( rc==SQLITE_OK ){
9296993679
pC->nullRow = 0;
@@ -93177,10 +93887,11 @@
9317793887
assert( pTabCur->uc.pCursor!=0 );
9317893888
assert( pTabCur->isTable );
9317993889
pTabCur->nullRow = 0;
9318093890
pTabCur->movetoTarget = rowid;
9318193891
pTabCur->deferredMoveto = 1;
93892
+ pTabCur->cacheStatus = CACHE_STALE;
9318293893
assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
9318393894
assert( !pTabCur->isEphemeral );
9318493895
pTabCur->ub.aAltMap = pOp->p4.ai;
9318593896
assert( !pC->isEphemeral );
9318693897
pTabCur->pAltCursor = pC;
@@ -93311,11 +94022,11 @@
9331194022
}
9331294023
sqlite3VdbeMemInit(&m, db, 0);
9331394024
rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
9331494025
if( rc ) goto abort_due_to_error;
9331594026
res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0);
93316
- sqlite3VdbeMemRelease(&m);
94027
+ sqlite3VdbeMemReleaseMalloc(&m);
9331794028
}
9331894029
/* End of inlined sqlite3VdbeIdxKeyCompare() */
9331994030
9332094031
assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
9332194032
if( (pOp->opcode&1)==(OP_IdxLT&1) ){
@@ -94192,10 +94903,11 @@
9419294903
pCtx->pFunc = pOp->p4.pFunc;
9419394904
pCtx->iOp = (int)(pOp - aOp);
9419494905
pCtx->pVdbe = p;
9419594906
pCtx->skipFlag = 0;
9419694907
pCtx->isError = 0;
94908
+ pCtx->enc = encoding;
9419794909
pCtx->argc = n;
9419894910
pOp->p4type = P4_FUNCCTX;
9419994911
pOp->p4.pCtx = pCtx;
9420094912
9420194913
/* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */
@@ -94321,13 +95033,10 @@
9432195033
sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
9432295034
goto abort_due_to_error;
9432395035
}
9432495036
sqlite3VdbeChangeEncoding(pMem, encoding);
9432595037
UPDATE_MAX_BLOBSIZE(pMem);
94326
- if( sqlite3VdbeMemTooBig(pMem) ){
94327
- goto too_big;
94328
- }
9432995038
break;
9433095039
}
9433195040
9433295041
#ifndef SQLITE_OMIT_WAL
9433395042
/* Opcode: Checkpoint P1 P2 P3 * *
@@ -94714,10 +95423,38 @@
9471495423
goto no_mem;
9471595424
}
9471695425
break;
9471795426
}
9471895427
#endif /* SQLITE_OMIT_VIRTUALTABLE */
95428
+
95429
+#ifndef SQLITE_OMIT_VIRTUALTABLE
95430
+/* Opcode: VInitIn P1 P2 P3 * *
95431
+** Synopsis: r[P2]=ValueList(P1,P3)
95432
+**
95433
+** Set register P2 to be a pointer to a ValueList object for cursor P1
95434
+** with cache register P3 and output register P3+1. This ValueList object
95435
+** can be used as the first argument to sqlite3_vtab_in_first() and
95436
+** sqlite3_vtab_in_next() to extract all of the values stored in the P1
95437
+** cursor. Register P3 is used to hold the values returned by
95438
+** sqlite3_vtab_in_first() and sqlite3_vtab_in_next().
95439
+*/
95440
+case OP_VInitIn: { /* out2 */
95441
+ VdbeCursor *pC; /* The cursor containing the RHS values */
95442
+ ValueList *pRhs; /* New ValueList object to put in reg[P2] */
95443
+
95444
+ pC = p->apCsr[pOp->p1];
95445
+ pRhs = sqlite3_malloc64( sizeof(*pRhs) );
95446
+ if( pRhs==0 ) goto no_mem;
95447
+ pRhs->pCsr = pC->uc.pCursor;
95448
+ pRhs->pOut = &aMem[pOp->p3];
95449
+ pOut = out2Prerelease(p, pOp);
95450
+ pOut->flags = MEM_Null;
95451
+ sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free);
95452
+ break;
95453
+}
95454
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
95455
+
9471995456
9472095457
#ifndef SQLITE_OMIT_VIRTUALTABLE
9472195458
/* Opcode: VFilter P1 P2 P3 P4 *
9472295459
** Synopsis: iplan=r[P3] zplan='P4'
9472395460
**
@@ -94816,10 +95553,11 @@
9481695553
pVtab = pCur->uc.pVCur->pVtab;
9481795554
pModule = pVtab->pModule;
9481895555
assert( pModule->xColumn );
9481995556
memset(&sContext, 0, sizeof(sContext));
9482095557
sContext.pOut = pDest;
95558
+ sContext.enc = encoding;
9482195559
assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
9482295560
if( pOp->p5 & OPFLAG_NOCHNG ){
9482395561
sqlite3VdbeMemSetNull(pDest);
9482495562
pDest->flags = MEM_Null|MEM_Zero;
9482595563
pDest->u.nZero = 0;
@@ -94834,13 +95572,10 @@
9483495572
}
9483595573
sqlite3VdbeChangeEncoding(pDest, encoding);
9483695574
REGISTER_TRACE(pOp->p3, pDest);
9483795575
UPDATE_MAX_BLOBSIZE(pDest);
9483895576
94839
- if( sqlite3VdbeMemTooBig(pDest) ){
94840
- goto too_big;
94841
- }
9484295577
if( rc ) goto abort_due_to_error;
9484395578
break;
9484495579
}
9484595580
#endif /* SQLITE_OMIT_VIRTUALTABLE */
9484695581
@@ -95103,10 +95838,11 @@
9510395838
** reinitializes the relavant parts of the sqlite3_context object */
9510495839
pOut = &aMem[pOp->p3];
9510595840
if( pCtx->pOut != pOut ){
9510695841
pCtx->pVdbe = p;
9510795842
pCtx->pOut = pOut;
95843
+ pCtx->enc = encoding;
9510895844
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
9510995845
}
9511095846
assert( pCtx->pVdbe==p );
9511195847
9511295848
memAboutToChange(p, pOut);
@@ -95129,15 +95865,14 @@
9512995865
sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
9513095866
pCtx->isError = 0;
9513195867
if( rc ) goto abort_due_to_error;
9513295868
}
9513395869
95134
- /* Copy the result of the function into register P3 */
95135
- if( pOut->flags & (MEM_Str|MEM_Blob) ){
95136
- sqlite3VdbeChangeEncoding(pOut, encoding);
95137
- if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
95138
- }
95870
+ assert( (pOut->flags&MEM_Str)==0
95871
+ || pOut->enc==encoding
95872
+ || db->mallocFailed );
95873
+ assert( !sqlite3VdbeMemTooBig(pOut) );
9513995874
9514095875
REGISTER_TRACE(pOp->p3, pOut);
9514195876
UPDATE_MAX_BLOBSIZE(pOut);
9514295877
break;
9514395878
}
@@ -99442,10 +100177,13 @@
99442100177
}
99443100178
return rc;
99444100179
}
99445100180
99446100181
100182
+/* Forward reference */
100183
+static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size);
100184
+
99447100185
/*
99448100186
** Write data to the file.
99449100187
*/
99450100188
static int memjrnlWrite(
99451100189
sqlite3_file *pJfd, /* The journal file into which to write */
@@ -99472,26 +100210,24 @@
99472100210
/* An in-memory journal file should only ever be appended to. Random
99473100211
** access writes are not required. The only exception to this is when
99474100212
** the in-memory journal is being used by a connection using the
99475100213
** atomic-write optimization. In this case the first 28 bytes of the
99476100214
** journal file may be written as part of committing the transaction. */
99477
- assert( iOfst==p->endpoint.iOffset || iOfst==0 );
99478
-#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
99479
- || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
100215
+ assert( iOfst<=p->endpoint.iOffset );
100216
+ if( iOfst>0 && iOfst!=p->endpoint.iOffset ){
100217
+ memjrnlTruncate(pJfd, iOfst);
100218
+ }
99480100219
if( iOfst==0 && p->pFirst ){
99481100220
assert( p->nChunkSize>iAmt );
99482100221
memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
99483
- }else
99484
-#else
99485
- assert( iOfst>0 || p->pFirst==0 );
99486
-#endif
99487
- {
100222
+ }else{
99488100223
while( nWrite>0 ){
99489100224
FileChunk *pChunk = p->endpoint.pChunk;
99490100225
int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
99491100226
int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
99492100227
100228
+ assert( pChunk!=0 || iChunkOffset==0 );
99493100229
if( iChunkOffset==0 ){
99494100230
/* New chunk is required to extend the file. */
99495100231
FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
99496100232
if( !pNew ){
99497100233
return SQLITE_IOERR_NOMEM_BKPT;
@@ -99502,14 +100238,15 @@
99502100238
pChunk->pNext = pNew;
99503100239
}else{
99504100240
assert( !p->pFirst );
99505100241
p->pFirst = pNew;
99506100242
}
99507
- p->endpoint.pChunk = pNew;
100243
+ pChunk = p->endpoint.pChunk = pNew;
99508100244
}
99509100245
99510
- memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
100246
+ assert( pChunk!=0 );
100247
+ memcpy((u8*)pChunk->zChunk + iChunkOffset, zWrite, iSpace);
99511100248
zWrite += iSpace;
99512100249
nWrite -= iSpace;
99513100250
p->endpoint.iOffset += iSpace;
99514100251
}
99515100252
}
@@ -100583,10 +101320,11 @@
100583101320
}else if( zTab ){
100584101321
sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
100585101322
}else{
100586101323
sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
100587101324
}
101325
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
100588101326
pParse->checkSchema = 1;
100589101327
pTopNC->nNcErr++;
100590101328
}
100591101329
100592101330
/* If a column from a table in pSrcList is referenced, then record
@@ -100691,11 +101429,12 @@
100691101429
*/
100692101430
static void notValidImpl(
100693101431
Parse *pParse, /* Leave error message here */
100694101432
NameContext *pNC, /* The name context */
100695101433
const char *zMsg, /* Type of error */
100696
- Expr *pExpr /* Invalidate this expression on error */
101434
+ Expr *pExpr, /* Invalidate this expression on error */
101435
+ Expr *pError /* Associate error with this expression */
100697101436
){
100698101437
const char *zIn = "partial index WHERE clauses";
100699101438
if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
100700101439
#ifndef SQLITE_OMIT_CHECK
100701101440
else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
@@ -100703,14 +101442,15 @@
100703101442
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
100704101443
else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns";
100705101444
#endif
100706101445
sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
100707101446
if( pExpr ) pExpr->op = TK_NULL;
101447
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pError);
100708101448
}
100709
-#define sqlite3ResolveNotValid(P,N,M,X,E) \
101449
+#define sqlite3ResolveNotValid(P,N,M,X,E,R) \
100710101450
assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \
100711
- if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E);
101451
+ if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E,R);
100712101452
100713101453
/*
100714101454
** Expression p should encode a floating point value between 1.0 and 0.0.
100715101455
** Return 1024 times this value. Or return -1 if p is not a floating point
100716101456
** value between 1.0 and 0.0.
@@ -100841,11 +101581,11 @@
100841101581
}else{
100842101582
Expr *pLeft = pExpr->pLeft;
100843101583
testcase( pNC->ncFlags & NC_IdxExpr );
100844101584
testcase( pNC->ncFlags & NC_GenCol );
100845101585
sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator",
100846
- NC_IdxExpr|NC_GenCol, 0);
101586
+ NC_IdxExpr|NC_GenCol, 0, pExpr);
100847101587
pRight = pExpr->pRight;
100848101588
if( pRight->op==TK_ID ){
100849101589
zDb = 0;
100850101590
}else{
100851101591
assert( pRight->op==TK_DOT );
@@ -100872,21 +101612,19 @@
100872101612
ExprList *pList = pExpr->x.pList; /* The argument list */
100873101613
int n = pList ? pList->nExpr : 0; /* Number of arguments */
100874101614
int no_such_func = 0; /* True if no such function exists */
100875101615
int wrong_num_args = 0; /* True if wrong number of arguments */
100876101616
int is_agg = 0; /* True if is an aggregate function */
100877
- int nId; /* Number of characters in function name */
100878101617
const char *zId; /* The function name. */
100879101618
FuncDef *pDef; /* Information about the function */
100880101619
u8 enc = ENC(pParse->db); /* The database encoding */
100881101620
int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
100882101621
#ifndef SQLITE_OMIT_WINDOWFUNC
100883101622
Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
100884101623
#endif
100885101624
assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
100886101625
zId = pExpr->u.zToken;
100887
- nId = sqlite3Strlen30(zId);
100888101626
pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
100889101627
if( pDef==0 ){
100890101628
pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
100891101629
if( pDef==0 ){
100892101630
no_such_func = 1;
@@ -100899,12 +101637,12 @@
100899101637
ExprSetProperty(pExpr, EP_Unlikely);
100900101638
if( n==2 ){
100901101639
pExpr->iTable = exprProbability(pList->a[1].pExpr);
100902101640
if( pExpr->iTable<0 ){
100903101641
sqlite3ErrorMsg(pParse,
100904
- "second argument to likelihood() must be a "
100905
- "constant between 0.0 and 1.0");
101642
+ "second argument to %#T() must be a "
101643
+ "constant between 0.0 and 1.0", pExpr);
100906101644
pNC->nNcErr++;
100907101645
}
100908101646
}else{
100909101647
/* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
100910101648
** equivalent to likelihood(X, 0.0625).
@@ -100921,12 +101659,12 @@
100921101659
#ifndef SQLITE_OMIT_AUTHORIZATION
100922101660
{
100923101661
int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
100924101662
if( auth!=SQLITE_OK ){
100925101663
if( auth==SQLITE_DENY ){
100926
- sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
100927
- pDef->zName);
101664
+ sqlite3ErrorMsg(pParse, "not authorized to use function: %#T",
101665
+ pExpr);
100928101666
pNC->nNcErr++;
100929101667
}
100930101668
pExpr->op = TK_NULL;
100931101669
return WRC_Prune;
100932101670
}
@@ -100945,11 +101683,11 @@
100945101683
** sqlite_version() that might change over time cannot be used
100946101684
** in an index or generated column. Curiously, they can be used
100947101685
** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
100948101686
** all this. */
100949101687
sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
100950
- NC_IdxExpr|NC_PartIdx|NC_GenCol, 0);
101688
+ NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr);
100951101689
}else{
100952101690
assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
100953101691
pExpr->op2 = pNC->ncFlags & NC_SelfRef;
100954101692
if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
100955101693
}
@@ -100958,11 +101696,11 @@
100958101696
&& (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
100959101697
){
100960101698
/* Internal-use-only functions are disallowed unless the
100961101699
** SQL is being compiled using sqlite3NestedParse() or
100962101700
** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
100963
- ** used to activate internal functionsn for testing purposes */
101701
+ ** used to activate internal functions for testing purposes */
100964101702
no_such_func = 1;
100965101703
pDef = 0;
100966101704
}else
100967101705
if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
100968101706
&& !IN_RENAME_OBJECT
@@ -100977,11 +101715,11 @@
100977101715
|| (pDef->xValue==0 && pDef->xInverse==0)
100978101716
|| (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
100979101717
);
100980101718
if( pDef && pDef->xValue==0 && pWin ){
100981101719
sqlite3ErrorMsg(pParse,
100982
- "%.*s() may not be used as a window function", nId, zId
101720
+ "%#T() may not be used as a window function", pExpr
100983101721
);
100984101722
pNC->nNcErr++;
100985101723
}else if(
100986101724
(is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
100987101725
|| (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin)
@@ -100991,38 +101729,38 @@
100991101729
if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){
100992101730
zType = "window";
100993101731
}else{
100994101732
zType = "aggregate";
100995101733
}
100996
- sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
101734
+ sqlite3ErrorMsg(pParse, "misuse of %s function %#T()",zType,pExpr);
100997101735
pNC->nNcErr++;
100998101736
is_agg = 0;
100999101737
}
101000101738
#else
101001101739
if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
101002
- sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId);
101740
+ sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr);
101003101741
pNC->nNcErr++;
101004101742
is_agg = 0;
101005101743
}
101006101744
#endif
101007101745
else if( no_such_func && pParse->db->init.busy==0
101008101746
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
101009101747
&& pParse->explain==0
101010101748
#endif
101011101749
){
101012
- sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
101750
+ sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr);
101013101751
pNC->nNcErr++;
101014101752
}else if( wrong_num_args ){
101015
- sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
101016
- nId, zId);
101753
+ sqlite3ErrorMsg(pParse,"wrong number of arguments to function %#T()",
101754
+ pExpr);
101017101755
pNC->nNcErr++;
101018101756
}
101019101757
#ifndef SQLITE_OMIT_WINDOWFUNC
101020101758
else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
101021101759
sqlite3ErrorMsg(pParse,
101022
- "FILTER may not be used with non-aggregate %.*s()",
101023
- nId, zId
101760
+ "FILTER may not be used with non-aggregate %#T()",
101761
+ pExpr
101024101762
);
101025101763
pNC->nNcErr++;
101026101764
}
101027101765
#endif
101028101766
if( is_agg ){
@@ -101103,11 +101841,11 @@
101103101841
testcase( pNC->ncFlags & NC_IsCheck );
101104101842
testcase( pNC->ncFlags & NC_PartIdx );
101105101843
testcase( pNC->ncFlags & NC_IdxExpr );
101106101844
testcase( pNC->ncFlags & NC_GenCol );
101107101845
if( pNC->ncFlags & NC_SelfRef ){
101108
- notValidImpl(pParse, pNC, "subqueries", pExpr);
101846
+ notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr);
101109101847
}else{
101110101848
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
101111101849
}
101112101850
assert( pNC->nRef>=nRef );
101113101851
if( nRef!=pNC->nRef ){
@@ -101121,11 +101859,11 @@
101121101859
testcase( pNC->ncFlags & NC_IsCheck );
101122101860
testcase( pNC->ncFlags & NC_PartIdx );
101123101861
testcase( pNC->ncFlags & NC_IdxExpr );
101124101862
testcase( pNC->ncFlags & NC_GenCol );
101125101863
sqlite3ResolveNotValid(pParse, pNC, "parameters",
101126
- NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr);
101864
+ NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr, pExpr);
101127101865
break;
101128101866
}
101129101867
case TK_IS:
101130101868
case TK_ISNOT: {
101131101869
Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
@@ -101173,10 +101911,11 @@
101173101911
testcase( pExpr->op==TK_GE );
101174101912
testcase( pExpr->op==TK_IS );
101175101913
testcase( pExpr->op==TK_ISNOT );
101176101914
testcase( pExpr->op==TK_BETWEEN );
101177101915
sqlite3ErrorMsg(pParse, "row value misused");
101916
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
101178101917
}
101179101918
break;
101180101919
}
101181101920
}
101182101921
assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
@@ -101286,15 +102025,17 @@
101286102025
*/
101287102026
static void resolveOutOfRangeError(
101288102027
Parse *pParse, /* The error context into which to write the error */
101289102028
const char *zType, /* "ORDER" or "GROUP" */
101290102029
int i, /* The index (1-based) of the term out of range */
101291
- int mx /* Largest permissible value of i */
102030
+ int mx, /* Largest permissible value of i */
102031
+ Expr *pError /* Associate the error with the expression */
101292102032
){
101293102033
sqlite3ErrorMsg(pParse,
101294102034
"%r %s BY term out of range - should be "
101295102035
"between 1 and %d", i, zType, mx);
102036
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pError);
101296102037
}
101297102038
101298102039
/*
101299102040
** Analyze the ORDER BY clause in a compound SELECT statement. Modify
101300102041
** each term of the ORDER BY clause is a constant integer between 1
@@ -101346,11 +102087,11 @@
101346102087
if( pItem->done ) continue;
101347102088
pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
101348102089
if( NEVER(pE==0) ) continue;
101349102090
if( sqlite3ExprIsInteger(pE, &iCol) ){
101350102091
if( iCol<=0 || iCol>pEList->nExpr ){
101351
- resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
102092
+ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE);
101352102093
return 1;
101353102094
}
101354102095
}else{
101355102096
iCol = resolveAsName(pParse, pEList, pE);
101356102097
if( iCol==0 ){
@@ -101442,11 +102183,11 @@
101442102183
pEList = pSelect->pEList;
101443102184
assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
101444102185
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
101445102186
if( pItem->u.x.iOrderByCol ){
101446102187
if( pItem->u.x.iOrderByCol>pEList->nExpr ){
101447
- resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
102188
+ resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr, 0);
101448102189
return 1;
101449102190
}
101450102191
resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0);
101451102192
}
101452102193
}
@@ -101534,11 +102275,11 @@
101534102275
if( sqlite3ExprIsInteger(pE2, &iCol) ){
101535102276
/* The ORDER BY term is an integer constant. Again, set the column
101536102277
** number so that sqlite3ResolveOrderGroupBy() will convert the
101537102278
** order-by term to a copy of the result-set expression */
101538102279
if( iCol<1 || iCol>0xffff ){
101539
- resolveOutOfRangeError(pParse, zType, i+1, nResult);
102280
+ resolveOutOfRangeError(pParse, zType, i+1, nResult, pE2);
101540102281
return 1;
101541102282
}
101542102283
pItem->u.x.iOrderByCol = (u16)iCol;
101543102284
continue;
101544102285
}
@@ -102787,13 +103528,12 @@
102787103528
**
102788103529
** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
102789103530
** if appropriate.
102790103531
*/
102791103532
static void exprSetHeight(Expr *p){
102792
- int nHeight = 0;
102793
- heightOfExpr(p->pLeft, &nHeight);
102794
- heightOfExpr(p->pRight, &nHeight);
103533
+ int nHeight = p->pLeft ? p->pLeft->nHeight : 0;
103534
+ if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight;
102795103535
if( ExprUseXSelect(p) ){
102796103536
heightOfSelect(p->x.pSelect, &nHeight);
102797103537
}else if( p->x.pList ){
102798103538
heightOfExprList(p->x.pList, &nHeight);
102799103539
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
@@ -103088,10 +103828,11 @@
103088103828
pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
103089103829
if( pNew==0 ){
103090103830
sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
103091103831
return 0;
103092103832
}
103833
+ pNew->w.iOfst = (int)(pToken->z - pParse->zTail);
103093103834
if( pList
103094103835
&& pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
103095103836
&& !pParse->nested
103096103837
){
103097103838
sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
@@ -103131,11 +103872,11 @@
103131103872
** (2) not tagged with SQLITE_INNOCUOUS (which means it
103132103873
** is tagged with SQLITE_FUNC_UNSAFE) and
103133103874
** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
103134103875
** that the schema is possibly tainted).
103135103876
*/
103136
- sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName);
103877
+ sqlite3ErrorMsg(pParse, "unsafe use of %#T()", pExpr);
103137103878
}
103138103879
}
103139103880
}
103140103881
103141103882
/*
@@ -103187,10 +103928,11 @@
103187103928
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
103188103929
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
103189103930
if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103190103931
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
103191103932
db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
103933
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
103192103934
return;
103193103935
}
103194103936
x = (ynVar)i;
103195103937
if( x>pParse->nVar ){
103196103938
pParse->nVar = (int)x;
@@ -103214,10 +103956,11 @@
103214103956
}
103215103957
}
103216103958
pExpr->iColumn = x;
103217103959
if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103218103960
sqlite3ErrorMsg(pParse, "too many SQL variables");
103961
+ sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
103219103962
}
103220103963
}
103221103964
103222103965
/*
103223103966
** Recursively delete an expression tree.
@@ -105056,12 +105799,11 @@
105056105799
assert( !ExprUseYWin(pExpr) );
105057105800
ExprSetProperty(pExpr, EP_Subrtn);
105058105801
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
105059105802
pExpr->y.sub.regReturn = ++pParse->nMem;
105060105803
pExpr->y.sub.iAddr =
105061
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
105062
- VdbeComment((v, "return address"));
105804
+ sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
105063105805
105064105806
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
105065105807
}
105066105808
105067105809
/* Check to see if this is a vector IN operator */
@@ -105159,10 +105901,11 @@
105159105901
** disable the test that was generated above that makes sure
105160105902
** this code only executes once. Because for a non-constant
105161105903
** expression we need to rerun this code each time.
105162105904
*/
105163105905
if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
105906
+ sqlite3VdbeChangeToNoop(v, addrOnce-1);
105164105907
sqlite3VdbeChangeToNoop(v, addrOnce);
105165105908
ExprClearProperty(pExpr, EP_Subrtn);
105166105909
addrOnce = 0;
105167105910
}
105168105911
@@ -105179,11 +105922,14 @@
105179105922
}
105180105923
if( addrOnce ){
105181105924
sqlite3VdbeJumpHere(v, addrOnce);
105182105925
/* Subroutine return */
105183105926
assert( ExprUseYSub(pExpr) );
105184
- sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
105927
+ assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
105928
+ || pParse->nErr );
105929
+ sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
105930
+ pExpr->y.sub.iAddr-1);
105185105931
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105186105932
sqlite3ClearTempRegCache(pParse);
105187105933
}
105188105934
}
105189105935
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -105234,13 +105980,11 @@
105234105980
assert( !ExprUseYWin(pExpr) );
105235105981
assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
105236105982
ExprSetProperty(pExpr, EP_Subrtn);
105237105983
pExpr->y.sub.regReturn = ++pParse->nMem;
105238105984
pExpr->y.sub.iAddr =
105239
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
105240
- VdbeComment((v, "return address"));
105241
-
105985
+ sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
105242105986
105243105987
/* The evaluation of the EXISTS/SELECT must be repeated every time it
105244105988
** is encountered if any of the following is true:
105245105989
**
105246105990
** * The right-hand side is a correlated subquery
@@ -105309,11 +106053,14 @@
105309106053
sqlite3VdbeJumpHere(v, addrOnce);
105310106054
}
105311106055
105312106056
/* Subroutine return */
105313106057
assert( ExprUseYSub(pExpr) );
105314
- sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
106058
+ assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
106059
+ || pParse->nErr );
106060
+ sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
106061
+ pExpr->y.sub.iAddr-1);
105315106062
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105316106063
sqlite3ClearTempRegCache(pParse);
105317106064
return rReg;
105318106065
}
105319106066
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -105515,11 +106262,10 @@
105515106262
if( destIfNull==destIfFalse ){
105516106263
destStep2 = destIfFalse;
105517106264
}else{
105518106265
destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
105519106266
}
105520
-// if( pParse->nErr ) goto sqlite3ExprCodeIN_finished;
105521106267
for(i=0; i<nVector; i++){
105522106268
Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
105523106269
if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error;
105524106270
if( sqlite3ExprCanBeNull(p) ){
105525106271
sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
@@ -105656,15 +106402,16 @@
105656106402
const char *z = pExpr->u.zToken;
105657106403
assert( z!=0 );
105658106404
c = sqlite3DecOrHexToI64(z, &value);
105659106405
if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
105660106406
#ifdef SQLITE_OMIT_FLOATING_POINT
105661
- sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
106407
+ sqlite3ErrorMsg(pParse, "oversized integer: %s%#T", negFlag?"-":"",pExpr);
105662106408
#else
105663106409
#ifndef SQLITE_OMIT_HEX_INTEGER
105664106410
if( sqlite3_strnicmp(z,"0x",2)==0 ){
105665
- sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z);
106411
+ sqlite3ErrorMsg(pParse, "hex literal too big: %s%#T",
106412
+ negFlag?"-":"",pExpr);
105666106413
}else
105667106414
#endif
105668106415
{
105669106416
codeReal(v, z, negFlag, iMem);
105670106417
}
@@ -106336,11 +107083,11 @@
106336107083
if( pInfo==0
106337107084
|| NEVER(pExpr->iAgg<0)
106338107085
|| NEVER(pExpr->iAgg>=pInfo->nFunc)
106339107086
){
106340107087
assert( !ExprHasProperty(pExpr, EP_IntValue) );
106341
- sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
107088
+ sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr);
106342107089
}else{
106343107090
return pInfo->aFunc[pExpr->iAgg].iMem;
106344107091
}
106345107092
break;
106346107093
}
@@ -106377,11 +107124,11 @@
106377107124
if( pDef==0 && pParse->explain ){
106378107125
pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
106379107126
}
106380107127
#endif
106381107128
if( pDef==0 || pDef->xFinalize!=0 ){
106382
- sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
107129
+ sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr);
106383107130
break;
106384107131
}
106385107132
if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
106386107133
assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
106387107134
assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
@@ -109000,11 +109747,11 @@
109000109747
if( !zOld ) goto exit_rename_column;
109001109748
for(iCol=0; iCol<pTab->nCol; iCol++){
109002109749
if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break;
109003109750
}
109004109751
if( iCol==pTab->nCol ){
109005
- sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
109752
+ sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld);
109006109753
goto exit_rename_column;
109007109754
}
109008109755
109009109756
/* Ensure the schema contains no double-quoted strings */
109010109757
renameTestSchema(pParse, zDb, iSchema==1, "", 0);
@@ -109430,16 +110177,16 @@
109430110177
){
109431110178
const char *zT = (const char*)sqlite3_value_text(pType);
109432110179
const char *zN = (const char*)sqlite3_value_text(pObject);
109433110180
char *zErr;
109434110181
109435
- zErr = sqlite3_mprintf("error in %s %s%s%s: %s",
110182
+ zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s",
109436110183
zT, zN, (zWhen[0] ? " " : ""), zWhen,
109437110184
pParse->zErrMsg
109438110185
);
109439110186
sqlite3_result_error(pCtx, zErr, -1);
109440
- sqlite3_free(zErr);
110187
+ sqlite3DbFree(pParse->db, zErr);
109441110188
}
109442110189
109443110190
/*
109444110191
** For each name in the the expression-list pEList (i.e. each
109445110192
** pEList->a[i].zName) that matches the string in zOld, extract the
@@ -109500,23 +110247,25 @@
109500110247
const char *zSql, /* SQL to parse */
109501110248
int bTemp /* True if SQL is from temp schema */
109502110249
){
109503110250
int rc;
109504110251
109505
- db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
109506
-
109507
- /* Parse the SQL statement passed as the first argument. If no error
109508
- ** occurs and the parse does not result in a new table, index or
109509
- ** trigger object, the database must be corrupt. */
109510110252
sqlite3ParseObjectInit(p, db);
110253
+ if( zSql==0 ){
110254
+ return SQLITE_NOMEM;
110255
+ }
110256
+ if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){
110257
+ return SQLITE_CORRUPT_BKPT;
110258
+ }
110259
+ db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
109511110260
p->eParseMode = PARSE_MODE_RENAME;
109512110261
p->db = db;
109513110262
p->nQueryLoop = 1;
109514
- rc = zSql ? sqlite3RunParser(p, zSql) : SQLITE_NOMEM;
110263
+ rc = sqlite3RunParser(p, zSql);
109515110264
if( db->mallocFailed ) rc = SQLITE_NOMEM;
109516110265
if( rc==SQLITE_OK
109517
- && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0
110266
+ && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0)
109518110267
){
109519110268
rc = SQLITE_CORRUPT_BKPT;
109520110269
}
109521110270
109522110271
#ifdef SQLITE_DEBUG
@@ -109796,11 +110545,11 @@
109796110545
}
109797110546
109798110547
/*
109799110548
** SQL function:
109800110549
**
109801
-** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld)
110550
+** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP)
109802110551
**
109803110552
** 0. zSql: SQL statement to rewrite
109804110553
** 1. type: Type of object ("table", "view" etc.)
109805110554
** 2. object: Name of object
109806110555
** 3. Database: Database name (e.g. "main")
@@ -109814,11 +110563,12 @@
109814110563
** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
109815110564
** into zNew. The name should be quoted if bQuote is true.
109816110565
**
109817110566
** This function is used internally by the ALTER TABLE RENAME COLUMN command.
109818110567
** It is only accessible to SQL created using sqlite3NestedParse(). It is
109819
-** not reachable from ordinary SQL passed into sqlite3_prepare().
110568
+** not reachable from ordinary SQL passed into sqlite3_prepare() unless the
110569
+** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled.
109820110570
*/
109821110571
static void renameColumnFunc(
109822110572
sqlite3_context *context,
109823110573
int NotUsed,
109824110574
sqlite3_value **argv
@@ -109963,11 +110713,13 @@
109963110713
assert( rc==SQLITE_OK );
109964110714
rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);
109965110715
109966110716
renameColumnFunc_done:
109967110717
if( rc!=SQLITE_OK ){
109968
- if( sParse.zErrMsg ){
110718
+ if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){
110719
+ sqlite3_result_value(context, argv[0]);
110720
+ }else if( sParse.zErrMsg ){
109969110721
renameColumnParseError(context, "", argv[1], argv[2], &sParse);
109970110722
}else{
109971110723
sqlite3_result_error_code(context, rc);
109972110724
}
109973110725
}
@@ -110162,11 +110914,13 @@
110162110914
110163110915
if( rc==SQLITE_OK ){
110164110916
rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
110165110917
}
110166110918
if( rc!=SQLITE_OK ){
110167
- if( sParse.zErrMsg ){
110919
+ if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){
110920
+ sqlite3_result_value(context, argv[3]);
110921
+ }else if( sParse.zErrMsg ){
110168110922
renameColumnParseError(context, "", argv[1], argv[2], &sParse);
110169110923
}else{
110170110924
sqlite3_result_error_code(context, rc);
110171110925
}
110172110926
}
@@ -110187,14 +110941,14 @@
110187110941
renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr);
110188110942
}
110189110943
return WRC_Continue;
110190110944
}
110191110945
110192
-/*
110193
-** The implementation of an SQL scalar function that rewrites DDL statements
110194
-** so that any string literals that use double-quotes are modified so that
110195
-** they use single quotes.
110946
+/* SQL function: sqlite_rename_quotefix(DB,SQL)
110947
+**
110948
+** Rewrite the DDL statement "SQL" so that any string literals that use
110949
+** double-quotes use single quotes instead.
110196110950
**
110197110951
** Two arguments must be passed:
110198110952
**
110199110953
** 0: Database name ("main", "temp" etc.).
110200110954
** 1: SQL statement to edit.
@@ -110209,10 +110963,14 @@
110209110963
** );
110210110964
**
110211110965
** returns the string:
110212110966
**
110213110967
** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1
110968
+**
110969
+** If there is a error in the input SQL, then raise an error, except
110970
+** if PRAGMA writable_schema=ON, then just return the input string
110971
+** unmodified following an error.
110214110972
*/
110215110973
static void renameQuotefixFunc(
110216110974
sqlite3_context *context,
110217110975
int NotUsed,
110218110976
sqlite3_value **argv
@@ -110283,11 +111041,15 @@
110283111041
rc = renameEditSql(context, &sCtx, zInput, 0, 0);
110284111042
}
110285111043
renameTokenFree(db, sCtx.pList);
110286111044
}
110287111045
if( rc!=SQLITE_OK ){
110288
- sqlite3_result_error_code(context, rc);
111046
+ if( sqlite3WritableSchema(db) && rc==SQLITE_ERROR ){
111047
+ sqlite3_result_value(context, argv[1]);
111048
+ }else{
111049
+ sqlite3_result_error_code(context, rc);
111050
+ }
110289111051
}
110290111052
renameParseCleanup(&sParse);
110291111053
}
110292111054
110293111055
#ifndef SQLITE_OMIT_AUTHORIZATION
@@ -110295,11 +111057,12 @@
110295111057
#endif
110296111058
110297111059
sqlite3BtreeLeaveAll(db);
110298111060
}
110299111061
110300
-/*
111062
+/* Function: sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS)
111063
+**
110301111064
** An SQL user function that checks that there are no parse or symbol
110302111065
** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
110303111066
** After an ALTER TABLE .. RENAME operation is performed and the schema
110304111067
** reloaded, this function is called on each SQL statement in the schema
110305111068
** to ensure that it is still usable.
@@ -110310,15 +111073,17 @@
110310111073
** 3: Object name.
110311111074
** 4: True if object is from temp schema.
110312111075
** 5: "when" part of error message.
110313111076
** 6: True to disable the DQS quirk when parsing SQL.
110314111077
**
110315
-** Unless it finds an error, this function normally returns NULL. However, it
110316
-** returns integer value 1 if:
111078
+** The return value is computed as follows:
110317111079
**
110318
-** * the SQL argument creates a trigger, and
110319
-** * the table that the trigger is attached to is in database zDb.
111080
+** A. If an error is seen and not in PRAGMA writable_schema=ON mode,
111081
+** then raise the error.
111082
+** B. Else if a trigger is created and the the table that the trigger is
111083
+** attached to is in database zDb, then return 1.
111084
+** C. Otherwise return NULL.
110320111085
*/
110321111086
static void renameTableTest(
110322111087
sqlite3_context *context,
110323111088
int NotUsed,
110324111089
sqlite3_value **argv
@@ -110359,16 +111124,20 @@
110359111124
rc = renameResolveTrigger(&sParse);
110360111125
}
110361111126
if( rc==SQLITE_OK ){
110362111127
int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
110363111128
int i2 = sqlite3FindDbName(db, zDb);
110364
- if( i1==i2 ) sqlite3_result_int(context, 1);
111129
+ if( i1==i2 ){
111130
+ /* Handle output case B */
111131
+ sqlite3_result_int(context, 1);
111132
+ }
110365111133
}
110366111134
}
110367111135
}
110368111136
110369
- if( rc!=SQLITE_OK && zWhen ){
111137
+ if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){
111138
+ /* Output case A */
110370111139
renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse);
110371111140
}
110372111141
renameParseCleanup(&sParse);
110373111142
}
110374111143
@@ -110480,11 +111249,11 @@
110480111249
assert( db->mallocFailed );
110481111250
goto exit_drop_column;
110482111251
}
110483111252
iCol = sqlite3ColumnIndex(pTab, zCol);
110484111253
if( iCol<0 ){
110485
- sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zCol);
111254
+ sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName);
110486111255
goto exit_drop_column;
110487111256
}
110488111257
110489111258
/* Do not allow the user to drop a PRIMARY KEY column or a column
110490111259
** constrained by a UNIQUE constraint. */
@@ -111633,11 +112402,11 @@
111633112402
if( pStat1==0 ) return;
111634112403
pStat1->zName = (char*)&pStat1[1];
111635112404
memcpy(pStat1->zName, "sqlite_stat1", 13);
111636112405
pStat1->nCol = 3;
111637112406
pStat1->iPKey = -1;
111638
- sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
112407
+ sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNAMIC);
111639112408
}
111640112409
#endif
111641112410
111642112411
/* Establish a read-lock on the table at the shared-cache level.
111643112412
** Open a read-only cursor on the table. Also allocate a cursor number
@@ -113629,11 +114398,13 @@
113629114398
&& (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr)
113630114399
){
113631114400
int iDb, i;
113632114401
assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
113633114402
sqlite3VdbeJumpHere(v, 0);
113634
- for(iDb=0; iDb<db->nDb; iDb++){
114403
+ assert( db->nDb>0 );
114404
+ iDb = 0;
114405
+ do{
113635114406
Schema *pSchema;
113636114407
if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
113637114408
sqlite3VdbeUsesBtree(v, iDb);
113638114409
pSchema = db->aDb[iDb].pSchema;
113639114410
sqlite3VdbeAddOp4Int(v,
@@ -113644,11 +114415,11 @@
113644114415
pSchema->iGeneration /* P4 */
113645114416
);
113646114417
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
113647114418
VdbeComment((v,
113648114419
"usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
113649
- }
114420
+ }while( ++iDb<db->nDb );
113650114421
#ifndef SQLITE_OMIT_VIRTUALTABLE
113651114422
for(i=0; i<pParse->nVtabLock; i++){
113652114423
char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
113653114424
sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
113654114425
}
@@ -113748,10 +114519,12 @@
113748114519
pParse->nested++;
113749114520
memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
113750114521
memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
113751114522
db->mDbFlags |= DBFLAG_PreferBuiltin;
113752114523
sqlite3RunParser(pParse, zSql);
114524
+ sqlite3DbFree(db, pParse->zErrMsg);
114525
+ pParse->zErrMsg = 0;
113753114526
db->mDbFlags = savedDbFlags;
113754114527
sqlite3DbFree(db, zSql);
113755114528
memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
113756114529
pParse->nested--;
113757114530
}
@@ -114708,11 +115481,12 @@
114708115481
goto begin_table_error;
114709115482
}
114710115483
pTable = sqlite3FindTable(db, zName, zDb);
114711115484
if( pTable ){
114712115485
if( !noErr ){
114713
- sqlite3ErrorMsg(pParse, "table %T already exists", pName);
115486
+ sqlite3ErrorMsg(pParse, "%s %T already exists",
115487
+ (IsView(pTable)? "view" : "table"), pName);
114714115488
}else{
114715115489
assert( !db->init.busy || CORRUPT_DB );
114716115490
sqlite3CodeVerifySchema(pParse, iDb);
114717115491
sqlite3ForceNotReadOnly(pParse);
114718115492
}
@@ -116238,10 +117012,15 @@
116238117012
int regRec; /* A record to be insert into the new table */
116239117013
int regRowid; /* Rowid of the next row to insert */
116240117014
int addrInsLoop; /* Top of the loop for inserting rows */
116241117015
Table *pSelTab; /* A table that describes the SELECT results */
116242117016
117017
+ if( IN_SPECIAL_PARSE ){
117018
+ pParse->rc = SQLITE_ERROR;
117019
+ pParse->nErr++;
117020
+ return;
117021
+ }
116243117022
regYield = ++pParse->nMem;
116244117023
regRec = ++pParse->nMem;
116245117024
regRowid = ++pParse->nMem;
116246117025
assert(pParse->nTab==1);
116247117026
sqlite3MayAbort(pParse);
@@ -120069,11 +120848,11 @@
120069120848
**
120070120849
** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
120071120850
** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
120072120851
** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
120073120852
*/
120074
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
120853
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1);
120075120854
if( pWInfo==0 ) goto delete_from_cleanup;
120076120855
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
120077120856
assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
120078120857
assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
120079120858
if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
@@ -120682,10 +121461,11 @@
120682121461
static void subtypeFunc(
120683121462
sqlite3_context *context,
120684121463
int argc,
120685121464
sqlite3_value **argv
120686121465
){
121466
+ UNUSED_PARAMETER(argc);
120687121467
sqlite3_result_int(context, sqlite3_value_subtype(argv[0]));
120688121468
}
120689121469
120690121470
/*
120691121471
** Implementation of the length() function
@@ -121695,12 +122475,13 @@
121695122475
UNUSED_PARAMETER(argc);
121696122476
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
121697122477
sqlite3QuoteValue(&str,argv[0]);
121698122478
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar,
121699122479
SQLITE_DYNAMIC);
121700
- if( str.accError==SQLITE_NOMEM ){
121701
- sqlite3_result_error_nomem(context);
122480
+ if( str.accError!=SQLITE_OK ){
122481
+ sqlite3_result_null(context);
122482
+ sqlite3_result_error_code(context, str.accError);
121702122483
}
121703122484
}
121704122485
121705122486
/*
121706122487
** The unicode() function. Return the integer unicode code-point value
@@ -122815,12 +123596,12 @@
122815123596
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
122816123597
INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122817123598
INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122818123599
INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122819123600
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
122820
- FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET|
122821
- SQLITE_FUNC_TYPEOF),
123601
+ {1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF,
123602
+ 0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} },
122822123603
#endif
122823123604
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
122824123605
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
122825123606
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
122826123607
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
@@ -123612,11 +124393,11 @@
123612124393
123613124394
/* Create VDBE to loop through the entries in pSrc that match the WHERE
123614124395
** clause. For each row found, increment either the deferred or immediate
123615124396
** foreign key constraint counter. */
123616124397
if( pParse->nErr==0 ){
123617
- pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
124398
+ pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0, 0);
123618124399
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
123619124400
if( pWInfo ){
123620124401
sqlite3WhereEnd(pWInfo);
123621124402
}
123622124403
}
@@ -124620,11 +125401,11 @@
124620125401
sqlite3OomFault(db);
124621125402
return;
124622125403
}
124623125404
124624125405
for(i=j=0; i<pTab->nCol; i++){
124625
- assert( pTab->aCol[i].affinity!=0 );
125406
+ assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 );
124626125407
if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
124627125408
zColAff[j++] = pTab->aCol[i].affinity;
124628125409
}
124629125410
}
124630125411
do{
@@ -125234,11 +126015,15 @@
125234126015
** Then special optimizations can be applied that make the transfer
125235126016
** very fast and which reduce fragmentation of indices.
125236126017
**
125237126018
** This is the 2nd template.
125238126019
*/
125239
- if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
126020
+ if( pColumn==0
126021
+ && pSelect!=0
126022
+ && pTrigger==0
126023
+ && xferOptimization(pParse, pTab, pSelect, onError, iDb)
126024
+ ){
125240126025
assert( !pTrigger );
125241126026
assert( pList==0 );
125242126027
goto insert_end;
125243126028
}
125244126029
#endif /* SQLITE_OMIT_XFER_OPT */
@@ -126717,11 +127502,11 @@
126717127502
}
126718127503
}
126719127504
if( isUpdate ){
126720127505
/* If currently processing the PRIMARY KEY of a WITHOUT ROWID
126721127506
** table, only conflict if the new PRIMARY KEY values are actually
126722
- ** different from the old.
127507
+ ** different from the old. See TH3 withoutrowid04.test.
126723127508
**
126724127509
** For a UNIQUE index, only conflict if the PRIMARY KEY values
126725127510
** of the matched index row are different from the original PRIMARY
126726127511
** KEY values of this row before the update. */
126727127512
int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
@@ -127205,22 +127990,17 @@
127205127990
Vdbe *v; /* The VDBE we are building */
127206127991
int regAutoinc; /* Memory register used by AUTOINC */
127207127992
int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
127208127993
int regData, regRowid; /* Registers holding data and rowid */
127209127994
127210
- if( pSelect==0 ){
127211
- return 0; /* Must be of the form INSERT INTO ... SELECT ... */
127212
- }
127995
+ assert( pSelect!=0 );
127213127996
if( pParse->pWith || pSelect->pWith ){
127214127997
/* Do not attempt to process this query if there are an WITH clauses
127215127998
** attached to it. Proceeding may generate a false "no such table: xxx"
127216127999
** error if pSelect reads from a CTE named "xxx". */
127217128000
return 0;
127218128001
}
127219
- if( sqlite3TriggerList(pParse, pDest) ){
127220
- return 0; /* tab1 must not have triggers */
127221
- }
127222128002
#ifndef SQLITE_OMIT_VIRTUALTABLE
127223128003
if( IsVirtual(pDest) ){
127224128004
return 0; /* tab1 must not be a virtual table */
127225128005
}
127226128006
#endif
@@ -128083,10 +128863,18 @@
128083128863
void*, void(*)(void*));
128084128864
/* Version 3.38.0 and later */
128085128865
int (*error_offset)(sqlite3*);
128086128866
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
128087128867
int (*vtab_distinct)(sqlite3_index_info*);
128868
+ int (*vtab_in)(sqlite3_index_info*,int,int);
128869
+ int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
128870
+ int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
128871
+ /* Version 3.39.0 and later */
128872
+ int (*deserialize)(sqlite3*,const char*,unsigned char*,
128873
+ sqlite3_int64,sqlite3_int64,unsigned);
128874
+ unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
128875
+ unsigned int);
128088128876
};
128089128877
128090128878
/*
128091128879
** This is the function signature used for all extension entry points. It
128092128880
** is also defined in the file "loadext.c".
@@ -128398,10 +129186,17 @@
128398129186
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
128399129187
/* Version 3.38.0 and later */
128400129188
#define sqlite3_error_offset sqlite3_api->error_offset
128401129189
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
128402129190
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
129191
+#define sqlite3_vtab_in sqlite3_api->vtab_in
129192
+#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
129193
+#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
129194
+#ifndef SQLITE_OMIT_DESERIALIZE
129195
+#define sqlite3_deserialize sqlite3_api->deserialize
129196
+#define sqlite3_serialize sqlite3_api->serialize
129197
+#endif
128403129198
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
128404129199
128405129200
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
128406129201
/* This case when the file really is being compiled as a loadable
128407129202
** extension */
@@ -128891,10 +129686,21 @@
128891129686
sqlite3_autovacuum_pages,
128892129687
/* Version 3.38.0 and later */
128893129688
sqlite3_error_offset,
128894129689
sqlite3_vtab_rhs_value,
128895129690
sqlite3_vtab_distinct,
129691
+ sqlite3_vtab_in,
129692
+ sqlite3_vtab_in_first,
129693
+ sqlite3_vtab_in_next,
129694
+ /* Version 3.39.0 and later */
129695
+#ifndef SQLITE_OMIT_DESERIALIZE
129696
+ sqlite3_deserialize,
129697
+ sqlite3_serialize
129698
+#else
129699
+ 0,
129700
+ 0
129701
+#endif
128896129702
};
128897129703
128898129704
/* True if x is the directory separator character
128899129705
*/
128900129706
#if SQLITE_OS_WIN
@@ -129561,11 +130367,11 @@
129561130367
/* iArg: */ BTREE_DATA_VERSION },
129562130368
#endif
129563130369
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
129564130370
{/* zName: */ "database_list",
129565130371
/* ePragTyp: */ PragTyp_DATABASE_LIST,
129566
- /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
130372
+ /* ePragFlg: */ PragFlg_Result0,
129567130373
/* ColNames: */ 47, 3,
129568130374
/* iArg: */ 0 },
129569130375
#endif
129570130376
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
129571130377
{/* zName: */ "default_cache_size",
@@ -130249,19 +131055,20 @@
130249131055
Vdbe *v, /* The prepared statement being created */
130250131056
FuncDef *p, /* A particular function definition */
130251131057
int isBuiltin, /* True if this is a built-in function */
130252131058
int showInternFuncs /* True if showing internal functions */
130253131059
){
131060
+ u32 mask =
131061
+ SQLITE_DETERMINISTIC |
131062
+ SQLITE_DIRECTONLY |
131063
+ SQLITE_SUBTYPE |
131064
+ SQLITE_INNOCUOUS |
131065
+ SQLITE_FUNC_INTERNAL
131066
+ ;
131067
+ if( showInternFuncs ) mask = 0xffffffff;
130254131068
for(; p; p=p->pNext){
130255131069
const char *zType;
130256
- static const u32 mask =
130257
- SQLITE_DETERMINISTIC |
130258
- SQLITE_DIRECTONLY |
130259
- SQLITE_SUBTYPE |
130260
- SQLITE_INNOCUOUS |
130261
- SQLITE_FUNC_INTERNAL
130262
- ;
130263131070
static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" };
130264131071
130265131072
assert( SQLITE_FUNC_ENCMASK==0x3 );
130266131073
assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 );
130267131074
assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 );
@@ -130749,11 +131556,11 @@
130749131556
**
130750131557
** Do N steps of incremental vacuuming on a database.
130751131558
*/
130752131559
#ifndef SQLITE_OMIT_AUTOVACUUM
130753131560
case PragTyp_INCREMENTAL_VACUUM: {
130754
- int iLimit, addr;
131561
+ int iLimit = 0, addr;
130755131562
if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){
130756131563
iLimit = 0x7fffffff;
130757131564
}
130758131565
sqlite3BeginWriteOperation(pParse, 0, iDb);
130759131566
sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
@@ -133053,11 +133860,11 @@
133053133860
if( db->mallocFailed ){
133054133861
rc = SQLITE_NOMEM_BKPT;
133055133862
sqlite3ResetAllSchemasOfConnection(db);
133056133863
pDb = &db->aDb[iDb];
133057133864
}else
133058
- if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
133865
+ if( rc==SQLITE_OK || ((db->flags&SQLITE_NoSchemaError) && rc!=SQLITE_NOMEM)){
133059133866
/* Hack: If the SQLITE_NoSchemaError flag is set, then consider
133060133867
** the schema loaded, even if errors (other than OOM) occurred. In
133061133868
** this situation the current sqlite3_prepare() operation will fail,
133062133869
** but the following one will attempt to compile the supplied statement
133063133870
** against whatever subset of the schema was loaded before the error
@@ -133324,10 +134131,11 @@
133324134131
memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
133325134132
assert( db->pParse!=pParse );
133326134133
pParse->pOuterParse = db->pParse;
133327134134
db->pParse = pParse;
133328134135
pParse->db = db;
134136
+ if( db->mallocFailed ) sqlite3ErrorMsg(pParse, "out of memory");
133329134137
}
133330134138
133331134139
/*
133332134140
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
133333134141
*/
@@ -133350,11 +134158,11 @@
133350134158
sParse.pOuterParse = db->pParse;
133351134159
db->pParse = &sParse;
133352134160
sParse.db = db;
133353134161
sParse.pReprepare = pReprepare;
133354134162
assert( ppStmt && *ppStmt==0 );
133355
- /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
134163
+ if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory");
133356134164
assert( sqlite3_mutex_held(db->mutex) );
133357134165
133358134166
/* For a long-term use prepared statement avoid the use of
133359134167
** lookaside memory.
133360134168
*/
@@ -133741,11 +134549,11 @@
133741134549
** how to process the DISTINCT keyword, to simplify passing that information
133742134550
** into the selectInnerLoop() routine.
133743134551
*/
133744134552
typedef struct DistinctCtx DistinctCtx;
133745134553
struct DistinctCtx {
133746
- u8 isTnct; /* True if the DISTINCT keyword is present */
134554
+ u8 isTnct; /* 0: Not distinct. 1: DISTICT 2: DISTINCT and ORDER BY */
133747134555
u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */
133748134556
int tabTnct; /* Ephemeral table used for DISTINCT processing */
133749134557
int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */
133750134558
};
133751134559
@@ -134074,29 +134882,29 @@
134074134882
** sqlite3PExpr(). */
134075134883
if( pEq && isOuterJoin ){
134076134884
ExprSetProperty(pEq, EP_FromJoin);
134077134885
assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
134078134886
ExprSetVVAProperty(pEq, EP_NoReduce);
134079
- pEq->iRightJoinTable = pE2->iTable;
134887
+ pEq->w.iRightJoinTable = pE2->iTable;
134080134888
}
134081134889
*ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
134082134890
}
134083134891
134084134892
/*
134085134893
** Set the EP_FromJoin property on all terms of the given expression.
134086
-** And set the Expr.iRightJoinTable to iTable for every term in the
134894
+** And set the Expr.w.iRightJoinTable to iTable for every term in the
134087134895
** expression.
134088134896
**
134089134897
** The EP_FromJoin property is used on terms of an expression to tell
134090134898
** the LEFT OUTER JOIN processing logic that this term is part of the
134091134899
** join restriction specified in the ON or USING clause and not a part
134092134900
** of the more general WHERE clause. These terms are moved over to the
134093134901
** WHERE clause during join processing but we need to remember that they
134094134902
** originated in the ON or USING clause.
134095134903
**
134096
-** The Expr.iRightJoinTable tells the WHERE clause processing that the
134097
-** expression depends on table iRightJoinTable even if that table is not
134904
+** The Expr.w.iRightJoinTable tells the WHERE clause processing that the
134905
+** expression depends on table w.iRightJoinTable even if that table is not
134098134906
** explicitly mentioned in the expression. That information is needed
134099134907
** for cases like this:
134100134908
**
134101134909
** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
134102134910
**
@@ -134110,11 +134918,11 @@
134110134918
SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){
134111134919
while( p ){
134112134920
ExprSetProperty(p, EP_FromJoin);
134113134921
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
134114134922
ExprSetVVAProperty(p, EP_NoReduce);
134115
- p->iRightJoinTable = iTable;
134923
+ p->w.iRightJoinTable = iTable;
134116134924
if( p->op==TK_FUNCTION ){
134117134925
assert( ExprUseXList(p) );
134118134926
if( p->x.pList ){
134119134927
int i;
134120134928
for(i=0; i<p->x.pList->nExpr; i++){
@@ -134126,19 +134934,19 @@
134126134934
p = p->pRight;
134127134935
}
134128134936
}
134129134937
134130134938
/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
134131
-** term that is marked with EP_FromJoin and iRightJoinTable==iTable into
134939
+** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into
134132134940
** an ordinary term that omits the EP_FromJoin mark.
134133134941
**
134134134942
** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
134135134943
*/
134136134944
static void unsetJoinExpr(Expr *p, int iTable){
134137134945
while( p ){
134138134946
if( ExprHasProperty(p, EP_FromJoin)
134139
- && (iTable<0 || p->iRightJoinTable==iTable) ){
134947
+ && (iTable<0 || p->w.iRightJoinTable==iTable) ){
134140134948
ExprClearProperty(p, EP_FromJoin);
134141134949
}
134142134950
if( p->op==TK_COLUMN && p->iTable==iTable ){
134143134951
ExprClearProperty(p, EP_CanBeNull);
134144134952
}
@@ -136343,11 +137151,11 @@
136343137151
** (3) There is no ORDER BY clause
136344137152
**
136345137153
** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
136346137154
** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
136347137155
** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
136348
-** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
137156
+** Since the limit is exactly 1, we only need to evaluate the left-most VALUES.
136349137157
*/
136350137158
static int multiSelectValues(
136351137159
Parse *pParse, /* Parsing context */
136352137160
Select *p, /* The right-most of SELECTs to be coded */
136353137161
SelectDest *pDest /* What to do with query results */
@@ -137368,13 +138176,13 @@
137368138176
SubstContext *pSubst, /* Description of the substitution */
137369138177
Expr *pExpr /* Expr in which substitution occurs */
137370138178
){
137371138179
if( pExpr==0 ) return 0;
137372138180
if( ExprHasProperty(pExpr, EP_FromJoin)
137373
- && pExpr->iRightJoinTable==pSubst->iTable
138181
+ && pExpr->w.iRightJoinTable==pSubst->iTable
137374138182
){
137375
- pExpr->iRightJoinTable = pSubst->iNewTable;
138183
+ pExpr->w.iRightJoinTable = pSubst->iNewTable;
137376138184
}
137377138185
if( pExpr->op==TK_COLUMN
137378138186
&& pExpr->iTable==pSubst->iTable
137379138187
&& !ExprHasProperty(pExpr, EP_FixedCol)
137380138188
){
@@ -137409,11 +138217,11 @@
137409138217
}
137410138218
if( pSubst->isLeftJoin ){
137411138219
ExprSetProperty(pNew, EP_CanBeNull);
137412138220
}
137413138221
if( ExprHasProperty(pExpr,EP_FromJoin) ){
137414
- sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable);
138222
+ sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable);
137415138223
}
137416138224
sqlite3ExprDelete(db, pExpr);
137417138225
pExpr = pNew;
137418138226
137419138227
/* Ensure that the expression now has an implicit collation sequence,
@@ -137574,11 +138382,11 @@
137574138382
int op = pExpr->op;
137575138383
if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
137576138384
renumberCursorDoMapping(pWalker, &pExpr->iTable);
137577138385
}
137578138386
if( ExprHasProperty(pExpr, EP_FromJoin) ){
137579
- renumberCursorDoMapping(pWalker, &pExpr->iRightJoinTable);
138387
+ renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable);
137580138388
}
137581138389
return WRC_Continue;
137582138390
}
137583138391
137584138392
/*
@@ -138584,15 +139392,17 @@
138584139392
iCursor, isLeftJoin);
138585139393
pWhere = pWhere->pLeft;
138586139394
}
138587139395
if( isLeftJoin
138588139396
&& (ExprHasProperty(pWhere,EP_FromJoin)==0
138589
- || pWhere->iRightJoinTable!=iCursor)
139397
+ || pWhere->w.iRightJoinTable!=iCursor)
138590139398
){
138591139399
return 0; /* restriction (4) */
138592139400
}
138593
- if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
139401
+ if( ExprHasProperty(pWhere,EP_FromJoin)
139402
+ && pWhere->w.iRightJoinTable!=iCursor
139403
+ ){
138594139404
return 0; /* restriction (5) */
138595139405
}
138596139406
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
138597139407
nChng++;
138598139408
pSubq->selFlags |= SF_PushDown;
@@ -140539,10 +141349,11 @@
140539141349
p->selFlags |= SF_Aggregate;
140540141350
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
140541141351
** the sDistinct.isTnct is still set. Hence, isTnct represents the
140542141352
** original setting of the SF_Distinct flag, not the current setting */
140543141353
assert( sDistinct.isTnct );
141354
+ sDistinct.isTnct = 2;
140544141355
140545141356
#if SELECTTRACE_ENABLED
140546141357
if( sqlite3SelectTrace & 0x400 ){
140547141358
SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
140548141359
sqlite3TreeViewSelect(0, p, 0);
@@ -140618,11 +141429,11 @@
140618141429
140619141430
140620141431
/* Begin the database scan. */
140621141432
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
140622141433
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
140623
- p->pEList, wctrlFlags, p->nSelectRow);
141434
+ p->pEList, p, wctrlFlags, p->nSelectRow);
140624141435
if( pWInfo==0 ) goto select_end;
140625141436
if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
140626141437
p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
140627141438
}
140628141439
if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
@@ -140882,11 +141693,12 @@
140882141693
** in the right order to begin with.
140883141694
*/
140884141695
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
140885141696
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
140886141697
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct,
140887
- WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
141698
+ 0, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY)
141699
+ | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
140888141700
);
140889141701
if( pWInfo==0 ){
140890141702
sqlite3ExprListDelete(db, pDistinct);
140891141703
goto select_end;
140892141704
}
@@ -141064,11 +141876,11 @@
141064141876
resetAccumulator(pParse, pAggInfo);
141065141877
sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
141066141878
VdbeComment((v, "indicate accumulator empty"));
141067141879
sqlite3VdbeAddOp1(v, OP_Return, regReset);
141068141880
141069
- if( eDist!=WHERE_DISTINCT_NOOP ){
141881
+ if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){
141070141882
struct AggInfo_func *pF = &pAggInfo->aFunc[0];
141071141883
fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
141072141884
}
141073141885
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
141074141886
else {
@@ -141180,11 +141992,11 @@
141180141992
assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
141181141993
assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
141182141994
141183141995
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
141184141996
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
141185
- pDistinct, minMaxFlag|distFlag, 0);
141997
+ pDistinct, 0, minMaxFlag|distFlag, 0);
141186141998
if( pWInfo==0 ){
141187141999
goto select_end;
141188142000
}
141189142001
SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
141190142002
eDist = sqlite3WhereIsDistinct(pWInfo);
@@ -141538,15 +142350,14 @@
141538142350
&& 0==sqlite3StrICmp(pTrig->table, pTab->zName)
141539142351
&& pTrig->pTabSchema!=pTmpSchema
141540142352
){
141541142353
pTrig->pNext = pList;
141542142354
pList = pTrig;
141543
- }else if( pTrig->op==TK_RETURNING
142355
+ }else if( pTrig->op==TK_RETURNING ){
141544142356
#ifndef SQLITE_OMIT_VIRTUALTABLE
141545
- && pParse->db->pVtabCtx==0
142357
+ assert( pParse->db->pVtabCtx==0 );
141546142358
#endif
141547
- ){
141548142359
assert( pParse->bReturning );
141549142360
assert( &(pParse->u1.pReturning->retTrig) == pTrig );
141550142361
pTrig->table = pTab->zName;
141551142362
pTrig->pTabSchema = pTab->pSchema;
141552142363
pTrig->pNext = pList;
@@ -141917,10 +142728,11 @@
141917142728
const char *zEnd /* End of SQL text */
141918142729
){
141919142730
sqlite3 *db = pParse->db;
141920142731
TriggerStep *pTriggerStep;
141921142732
142733
+ if( pParse->nErr ) return 0;
141922142734
pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
141923142735
if( pTriggerStep ){
141924142736
char *z = (char*)&pTriggerStep[1];
141925142737
memcpy(z, pName->z, pName->n);
141926142738
sqlite3Dequote(z);
@@ -142707,10 +143519,11 @@
142707143519
);
142708143520
142709143521
/* If an existing TriggerPrg could not be located, create a new one. */
142710143522
if( !pPrg ){
142711143523
pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
143524
+ pParse->db->errByteOffset = -1;
142712143525
}
142713143526
142714143527
return pPrg;
142715143528
}
142716143529
@@ -143623,11 +144436,11 @@
143623144436
** or index, causing a single-pass approach to malfunction. */
143624144437
flags = WHERE_ONEPASS_DESIRED;
143625144438
if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
143626144439
flags |= WHERE_ONEPASS_MULTIROW;
143627144440
}
143628
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags,iIdxCur);
144441
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
143629144442
if( pWInfo==0 ) goto update_cleanup;
143630144443
143631144444
/* A one-pass strategy that might update more than one row may not
143632144445
** be used if any column of the index used for the scan is being
143633144446
** updated. Otherwise, if there is an index on "b", statements like
@@ -144145,11 +144958,13 @@
144145144958
}else{
144146144959
regRec = ++pParse->nMem;
144147144960
regRowid = ++pParse->nMem;
144148144961
144149144962
/* Start scanning the virtual table */
144150
- pWInfo = sqlite3WhereBegin(pParse, pSrc,pWhere,0,0,WHERE_ONEPASS_DESIRED,0);
144963
+ pWInfo = sqlite3WhereBegin(
144964
+ pParse, pSrc, pWhere, 0, 0, 0, WHERE_ONEPASS_DESIRED, 0
144965
+ );
144151144966
if( pWInfo==0 ) return;
144152144967
144153144968
/* Populate the argument registers. */
144154144969
for(i=0; i<pTab->nCol; i++){
144155144970
assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 );
@@ -145792,10 +146607,11 @@
145792146607
pTab = pCtx->pTab;
145793146608
assert( IsVirtual(pTab) );
145794146609
145795146610
sqlite3ParseObjectInit(&sParse, db);
145796146611
sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
146612
+ sParse.disableTriggers = 1;
145797146613
/* We should never be able to reach this point while loading the
145798146614
** schema. Nevertheless, defend against that (turn off db->init.busy)
145799146615
** in case a bug arises. */
145800146616
assert( db->init.busy==0 );
145801146617
initBusy = db->init.busy;
@@ -146456,14 +147272,16 @@
146456147272
u16 nDistinctCol; /* Index columns used to sort for DISTINCT */
146457147273
Index *pIndex; /* Index used, or NULL */
146458147274
} btree;
146459147275
struct { /* Information for virtual tables */
146460147276
int idxNum; /* Index number */
146461
- u8 needFree; /* True if sqlite3_free(idxStr) is needed */
147277
+ u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
147278
+ u32 bOmitOffset : 1; /* True to let virtual table handle offset */
146462147279
i8 isOrdered; /* True if satisfies ORDER BY */
146463147280
u16 omitMask; /* Terms that may be omitted */
146464147281
char *idxStr; /* Index identifier string */
147282
+ u32 mHandleIn; /* Terms to handle as IN(...) instead of == */
146465147283
} vtab;
146466147284
} u;
146467147285
u32 wsFlags; /* WHERE_* flags describing the plan */
146468147286
u16 nLTerm; /* Number of entries in aLTerm[] */
146469147287
u16 nSkip; /* Number of NULL aLTerm[] entries */
@@ -146616,10 +147434,11 @@
146616147434
#ifdef SQLITE_ENABLE_STAT4
146617147435
# define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */
146618147436
#else
146619147437
# define TERM_HIGHTRUTH 0 /* Only used with STAT4 */
146620147438
#endif
147439
+#define TERM_SLICE 0x8000 /* One slice of a row-value/vector comparison */
146621147440
146622147441
/*
146623147442
** An instance of the WhereScan object is used as an iterator for locating
146624147443
** terms in the WHERE clause that are useful to the query planner.
146625147444
*/
@@ -146786,10 +147605,13 @@
146786147605
Parse *pParse; /* Parsing and code generating context */
146787147606
SrcList *pTabList; /* List of tables in the join */
146788147607
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
146789147608
ExprList *pResultSet; /* Result set of the query */
146790147609
Expr *pWhere; /* The complete WHERE clause */
147610
+#ifndef SQLITE_OMIT_VIRTUALTABLE
147611
+ Select *pLimit; /* Used to access LIMIT expr/registers for vtabs */
147612
+#endif
146791147613
int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
146792147614
int iContinue; /* Jump here to continue with next record */
146793147615
int iBreak; /* Jump here to break out of the loop */
146794147616
int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
146795147617
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
@@ -146871,10 +147693,11 @@
146871147693
146872147694
/* whereexpr.c: */
146873147695
SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
146874147696
SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
146875147697
SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
147698
+SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause*, Select*);
146876147699
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
146877147700
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
146878147701
SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
146879147702
SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
146880147703
SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
@@ -146941,10 +147764,11 @@
146941147764
#define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
146942147765
#define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
146943147766
#define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
146944147767
#define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
146945147768
#define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
147769
+#define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */
146946147770
146947147771
#endif /* !defined(SQLITE_WHEREINT_H) */
146948147772
146949147773
/************** End of whereInt.h ********************************************/
146950147774
/************** Continuing where we left off in wherecode.c ******************/
@@ -147719,10 +148543,11 @@
147719148543
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
147720148544
VdbeCoverageIf(v, bRev==0);
147721148545
VdbeCoverageIf(v, bRev!=0);
147722148546
VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
147723148547
j = sqlite3VdbeAddOp0(v, OP_Goto);
148548
+ assert( pLevel->addrSkip==0 );
147724148549
pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
147725148550
iIdxCur, 0, regBase, nSkip);
147726148551
VdbeCoverageIf(v, bRev==0);
147727148552
VdbeCoverageIf(v, bRev!=0);
147728148553
sqlite3VdbeJumpHere(v, j);
@@ -147989,11 +148814,11 @@
147989148814
** are also excluded. See codeCursorHintIsOrFunction() for details.
147990148815
*/
147991148816
if( pTabItem->fg.jointype & JT_LEFT ){
147992148817
Expr *pExpr = pTerm->pExpr;
147993148818
if( !ExprHasProperty(pExpr, EP_FromJoin)
147994
- || pExpr->iRightJoinTable!=pTabItem->iCursor
148819
+ || pExpr->w.iRightJoinTable!=pTabItem->iCursor
147995148820
){
147996148821
sWalker.eCode = 0;
147997148822
sWalker.xExprCallback = codeCursorHintIsOrFunction;
147998148823
sqlite3WalkExpr(&sWalker, pTerm->pExpr);
147999148824
if( sWalker.eCode ) continue;
@@ -148044,18 +148869,26 @@
148044148869
** rowid stored in register iRowid.
148045148870
**
148046148871
** Normally, this is just:
148047148872
**
148048148873
** OP_DeferredSeek $iCur $iRowid
148874
+**
148875
+** Which causes a seek on $iCur to the row with rowid $iRowid.
148049148876
**
148050148877
** However, if the scan currently being coded is a branch of an OR-loop and
148051
-** the statement currently being coded is a SELECT, then P3 of OP_DeferredSeek
148052
-** is set to iIdxCur and P4 is set to point to an array of integers
148053
-** containing one entry for each column of the table cursor iCur is open
148054
-** on. For each table column, if the column is the i'th column of the
148055
-** index, then the corresponding array entry is set to (i+1). If the column
148056
-** does not appear in the index at all, the array entry is set to 0.
148878
+** the statement currently being coded is a SELECT, then additional information
148879
+** is added that might allow OP_Column to omit the seek and instead do its
148880
+** lookup on the index, thus avoiding an expensive seek operation. To
148881
+** enable this optimization, the P3 of OP_DeferredSeek is set to iIdxCur
148882
+** and P4 is set to an array of integers containing one entry for each column
148883
+** in the table. For each table column, if the column is the i'th
148884
+** column of the index, then the corresponding array entry is set to (i+1).
148885
+** If the column does not appear in the index at all, the array entry is set
148886
+** to 0. The OP_Column opcode can check this array to see if the column it
148887
+** wants is in the index and if it is, it will substitute the index cursor
148888
+** and column number and continue with those new values, rather than seeking
148889
+** the table cursor.
148057148890
*/
148058148891
static void codeDeferredSeek(
148059148892
WhereInfo *pWInfo, /* Where clause context */
148060148893
Index *pIdx, /* Index scan is using */
148061148894
int iCur, /* Cursor for IPK b-tree */
@@ -148316,10 +149149,11 @@
148316149149
){
148317149150
while( ++iLevel < pWInfo->nLevel ){
148318149151
WhereLevel *pLevel = &pWInfo->a[iLevel];
148319149152
WhereLoop *pLoop = pLevel->pWLoop;
148320149153
if( pLevel->regFilter==0 ) continue;
149154
+ if( pLevel->pWLoop->nSkip ) continue;
148321149155
/* ,--- Because sqlite3ConstructBloomFilter() has will not have set
148322149156
** vvvvv--' pLevel->regFilter if this were true. */
148323149157
if( NEVER(pLoop->prereq & notReady) ) continue;
148324149158
if( pLoop->wsFlags & WHERE_IPK ){
148325149159
WhereTerm *pTerm = pLoop->aLTerm[0];
@@ -148450,24 +149284,39 @@
148450149284
** to access the data.
148451149285
*/
148452149286
int iReg; /* P3 Value for OP_VFilter */
148453149287
int addrNotFound;
148454149288
int nConstraint = pLoop->nLTerm;
148455
- int iIn; /* Counter for IN constraints */
148456149289
148457149290
iReg = sqlite3GetTempRange(pParse, nConstraint+2);
148458149291
addrNotFound = pLevel->addrBrk;
148459149292
for(j=0; j<nConstraint; j++){
148460149293
int iTarget = iReg+j+2;
148461149294
pTerm = pLoop->aLTerm[j];
148462149295
if( NEVER(pTerm==0) ) continue;
148463149296
if( pTerm->eOperator & WO_IN ){
148464
- codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
148465
- addrNotFound = pLevel->addrNxt;
149297
+ if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){
149298
+ int iTab = pParse->nTab++;
149299
+ int iCache = ++pParse->nMem;
149300
+ sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab);
149301
+ sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache);
149302
+ }else{
149303
+ codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
149304
+ addrNotFound = pLevel->addrNxt;
149305
+ }
148466149306
}else{
148467149307
Expr *pRight = pTerm->pExpr->pRight;
148468149308
codeExprOrVector(pParse, pRight, iTarget, 1);
149309
+ if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET
149310
+ && pLoop->u.vtab.bOmitOffset
149311
+ ){
149312
+ assert( pTerm->eOperator==WO_AUX );
149313
+ assert( pWInfo->pLimit!=0 );
149314
+ assert( pWInfo->pLimit->iOffset>0 );
149315
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset);
149316
+ VdbeComment((v,"Zero OFFSET counter"));
149317
+ }
148469149318
}
148470149319
}
148471149320
sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
148472149321
sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
148473149322
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
@@ -148480,61 +149329,71 @@
148480149329
if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
148481149330
pLevel->p1 = iCur;
148482149331
pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
148483149332
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148484149333
assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
148485
- if( pLoop->wsFlags & WHERE_IN_ABLE ){
148486
- iIn = pLevel->u.in.nIn;
148487
- }else{
148488
- iIn = 0;
148489
- }
148490
- for(j=nConstraint-1; j>=0; j--){
149334
+
149335
+ for(j=0; j<nConstraint; j++){
148491149336
pTerm = pLoop->aLTerm[j];
148492
- if( (pTerm->eOperator & WO_IN)!=0 ) iIn--;
148493149337
if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
148494149338
disableTerm(pLevel, pTerm);
148495
- }else if( (pTerm->eOperator & WO_IN)!=0
148496
- && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1
149339
+ continue;
149340
+ }
149341
+ if( (pTerm->eOperator & WO_IN)!=0
149342
+ && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0
149343
+ && !db->mallocFailed
148497149344
){
148498149345
Expr *pCompare; /* The comparison operator */
148499149346
Expr *pRight; /* RHS of the comparison */
148500149347
VdbeOp *pOp; /* Opcode to access the value of the IN constraint */
149348
+ int iIn; /* IN loop corresponding to the j-th constraint */
148501149349
148502149350
/* Reload the constraint value into reg[iReg+j+2]. The same value
148503149351
** was loaded into the same register prior to the OP_VFilter, but
148504149352
** the xFilter implementation might have changed the datatype or
148505
- ** encoding of the value in the register, so it *must* be reloaded. */
148506
- assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
148507
- if( !db->mallocFailed ){
148508
- assert( iIn>=0 && iIn<pLevel->u.in.nIn );
149353
+ ** encoding of the value in the register, so it *must* be reloaded.
149354
+ */
149355
+ for(iIn=0; ALWAYS(iIn<pLevel->u.in.nIn); iIn++){
148509149356
pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop);
148510
- assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
148511
- assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
148512
- assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
148513
- testcase( pOp->opcode==OP_Rowid );
148514
- sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
149357
+ if( (pOp->opcode==OP_Column && pOp->p3==iReg+j+2)
149358
+ || (pOp->opcode==OP_Rowid && pOp->p2==iReg+j+2)
149359
+ ){
149360
+ testcase( pOp->opcode==OP_Rowid );
149361
+ sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
149362
+ break;
149363
+ }
148515149364
}
148516149365
148517149366
/* Generate code that will continue to the next row if
148518
- ** the IN constraint is not satisfied */
149367
+ ** the IN constraint is not satisfied
149368
+ */
148519149369
pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
148520
- assert( pCompare!=0 || db->mallocFailed );
148521
- if( pCompare ){
148522
- pCompare->pLeft = pTerm->pExpr->pLeft;
149370
+ if( !db->mallocFailed ){
149371
+ int iFld = pTerm->u.x.iField;
149372
+ Expr *pLeft = pTerm->pExpr->pLeft;
149373
+ assert( pLeft!=0 );
149374
+ if( iFld>0 ){
149375
+ assert( pLeft->op==TK_VECTOR );
149376
+ assert( ExprUseXList(pLeft) );
149377
+ assert( iFld<=pLeft->x.pList->nExpr );
149378
+ pCompare->pLeft = pLeft->x.pList->a[iFld-1].pExpr;
149379
+ }else{
149380
+ pCompare->pLeft = pLeft;
149381
+ }
148523149382
pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
148524149383
if( pRight ){
148525149384
pRight->iTable = iReg+j+2;
148526149385
sqlite3ExprIfFalse(
148527149386
pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL
148528149387
);
148529149388
}
148530149389
pCompare->pLeft = 0;
148531
- sqlite3ExprDelete(db, pCompare);
148532149390
}
149391
+ sqlite3ExprDelete(db, pCompare);
148533149392
}
148534149393
}
148535
- assert( iIn==0 || db->mallocFailed );
149394
+
148536149395
/* These registers need to be preserved in case there is an IN operator
148537149396
** loop. So we could deallocate the registers here (and potentially
148538149397
** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
148539149398
** simpler and safer to simply not reuse the registers.
148540149399
**
@@ -149222,11 +150081,11 @@
149222150081
regRowid = ++pParse->nMem;
149223150082
}
149224150083
iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
149225150084
149226150085
/* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
149227
- ** Then for every term xN, evaluate as the subexpression: xN AND z
150086
+ ** Then for every term xN, evaluate as the subexpression: xN AND y
149228150087
** That way, terms in y that are factored into the disjunction will
149229150088
** be picked up by the recursive calls to sqlite3WhereBegin() below.
149230150089
**
149231150090
** Actually, each subexpression is converted to "xN AND w" where w is
149232150091
** the "interesting" terms of z - terms that did not originate in the
@@ -149234,21 +150093,38 @@
149234150093
** indices.
149235150094
**
149236150095
** This optimization also only applies if the (x1 OR x2 OR ...) term
149237150096
** is not contained in the ON clause of a LEFT JOIN.
149238150097
** See ticket http://www.sqlite.org/src/info/f2369304e4
150098
+ **
150099
+ ** 2022-02-04: Do not push down slices of a row-value comparison.
150100
+ ** In other words, "w" or "y" may not be a slice of a vector. Otherwise,
150101
+ ** the initialization of the right-hand operand of the vector comparison
150102
+ ** might not occur, or might occur only in an OR branch that is not
150103
+ ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1.
150104
+ **
150105
+ ** 2022-03-03: Do not push down expressions that involve subqueries.
150106
+ ** The subquery might get coded as a subroutine. Any table-references
150107
+ ** in the subquery might be resolved to index-references for the index on
150108
+ ** the OR branch in which the subroutine is coded. But if the subroutine
150109
+ ** is invoked from a different OR branch that uses a different index, such
150110
+ ** index-references will not work. tag-20220303a
150111
+ ** https://sqlite.org/forum/forumpost/36937b197273d403
149239150112
*/
149240150113
if( pWC->nTerm>1 ){
149241150114
int iTerm;
149242150115
for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
149243150116
Expr *pExpr = pWC->a[iTerm].pExpr;
149244150117
if( &pWC->a[iTerm] == pTerm ) continue;
149245150118
testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
149246150119
testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
149247
- if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
150120
+ testcase( pWC->a[iTerm].wtFlags & TERM_SLICE );
150121
+ if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){
150122
+ continue;
150123
+ }
149248150124
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
149249
- testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
150125
+ if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */
149250150126
pExpr = sqlite3ExprDup(db, pExpr, 0);
149251150127
pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
149252150128
}
149253150129
if( pAndExpr ){
149254150130
/* The extra 0x10000 bit on the opcode is masked off and does not
@@ -149285,11 +150161,11 @@
149285150161
pOrExpr = pAndExpr;
149286150162
}
149287150163
/* Loop through table entries that match term pOrTerm. */
149288150164
ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
149289150165
WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
149290
- pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
150166
+ pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0,
149291150167
WHERE_OR_SUBCLAUSE, iCovCur);
149292150168
assert( pSubWInfo || pParse->nErr );
149293150169
if( pSubWInfo ){
149294150170
WhereLoop *pSubLoop;
149295150171
int addrExplain = sqlite3WhereExplainOneScan(
@@ -150025,11 +150901,11 @@
150025150901
void *pNotUsed;
150026150902
pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
150027150903
assert( pVtab!=0 );
150028150904
assert( pVtab->pModule!=0 );
150029150905
assert( !ExprHasProperty(pExpr, EP_IntValue) );
150030
- pMod = (sqlite3_module *)pVtab->pModule;
150906
+ pMod = (sqlite3_module *)pVtab->pModule;
150031150907
if( pMod->xFindFunction!=0 ){
150032150908
i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
150033150909
if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
150034150910
*peOp2 = i;
150035150911
*ppRight = pList->a[1].pExpr;
@@ -150069,11 +150945,11 @@
150069150945
** a join, then transfer the appropriate markings over to derived.
150070150946
*/
150071150947
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
150072150948
if( pDerived ){
150073150949
pDerived->flags |= pBase->flags & EP_FromJoin;
150074
- pDerived->iRightJoinTable = pBase->iRightJoinTable;
150950
+ pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable;
150075150951
}
150076150952
}
150077150953
150078150954
/*
150079150955
** Mark term iChild as being a child of term iParent
@@ -150714,11 +151590,11 @@
150714151590
abort();
150715151591
}
150716151592
#endif
150717151593
150718151594
if( ExprHasProperty(pExpr, EP_FromJoin) ){
150719
- Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
151595
+ Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable);
150720151596
prereqAll |= x;
150721151597
extraRight = x-1; /* ON clause terms may not be used with an index
150722151598
** on left table of a LEFT JOIN. Ticket #3015 */
150723151599
if( (prereqAll>>1)>=x ){
150724151600
sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
@@ -150982,11 +151858,14 @@
150982151858
** new terms for each component comparison - "a = ?" and "b = ?". The
150983151859
** new terms completely replace the original vector comparison, which is
150984151860
** no longer used.
150985151861
**
150986151862
** This is only required if at least one side of the comparison operation
150987
- ** is not a sub-select. */
151863
+ ** is not a sub-select.
151864
+ **
151865
+ ** tag-20220128a
151866
+ */
150988151867
if( (pExpr->op==TK_EQ || pExpr->op==TK_IS)
150989151868
&& (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
150990151869
&& sqlite3ExprVectorSize(pExpr->pRight)==nLeft
150991151870
&& ( (pExpr->pLeft->flags & EP_xIsSelect)==0
150992151871
|| (pExpr->pRight->flags & EP_xIsSelect)==0)
@@ -150999,11 +151878,11 @@
150999151878
Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, nLeft);
151000151879
Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, nLeft);
151001151880
151002151881
pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
151003151882
transferJoinMarkings(pNew, pExpr);
151004
- idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
151883
+ idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE);
151005151884
exprAnalyze(pSrc, pWC, idxNew);
151006151885
}
151007151886
pTerm = &pWC->a[idxTerm];
151008151887
pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
151009151888
pTerm->eOperator = 0;
@@ -151029,11 +151908,11 @@
151029151908
&& pWC->op==TK_AND
151030151909
){
151031151910
int i;
151032151911
for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
151033151912
int idxNew;
151034
- idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
151913
+ idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE);
151035151914
pWC->a[idxNew].u.x.iField = i+1;
151036151915
exprAnalyze(pSrc, pWC, idxNew);
151037151916
markTermAsChild(pWC, idxNew, idxTerm);
151038151917
}
151039151918
}
@@ -151062,11 +151941,11 @@
151062151941
Expr *pNewExpr;
151063151942
pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
151064151943
0, sqlite3ExprDup(db, pRight, 0));
151065151944
if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
151066151945
ExprSetProperty(pNewExpr, EP_FromJoin);
151067
- pNewExpr->iRightJoinTable = pExpr->iRightJoinTable;
151946
+ pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable;
151068151947
}
151069151948
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
151070151949
testcase( idxNew==0 );
151071151950
pNewTerm = &pWC->a[idxNew];
151072151951
pNewTerm->prereqRight = prereqExpr;
@@ -151124,10 +152003,117 @@
151124152003
}else{
151125152004
sqlite3WhereSplit(pWC, pE2->pLeft, op);
151126152005
sqlite3WhereSplit(pWC, pE2->pRight, op);
151127152006
}
151128152007
}
152008
+
152009
+/*
152010
+** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or
152011
+** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the
152012
+** where-clause passed as the first argument. The value for the term
152013
+** is found in register iReg.
152014
+**
152015
+** In the common case where the value is a simple integer
152016
+** (example: "LIMIT 5 OFFSET 10") then the expression codes as a
152017
+** TK_INTEGER so that it will be available to sqlite3_vtab_rhs_value().
152018
+** If not, then it codes as a TK_REGISTER expression.
152019
+*/
152020
+static void whereAddLimitExpr(
152021
+ WhereClause *pWC, /* Add the constraint to this WHERE clause */
152022
+ int iReg, /* Register that will hold value of the limit/offset */
152023
+ Expr *pExpr, /* Expression that defines the limit/offset */
152024
+ int iCsr, /* Cursor to which the constraint applies */
152025
+ int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */
152026
+){
152027
+ Parse *pParse = pWC->pWInfo->pParse;
152028
+ sqlite3 *db = pParse->db;
152029
+ Expr *pNew;
152030
+ int iVal = 0;
152031
+
152032
+ if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){
152033
+ Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0);
152034
+ if( pVal==0 ) return;
152035
+ ExprSetProperty(pVal, EP_IntValue);
152036
+ pVal->u.iValue = iVal;
152037
+ pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
152038
+ }else{
152039
+ Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0);
152040
+ if( pVal==0 ) return;
152041
+ pVal->iTable = iReg;
152042
+ pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
152043
+ }
152044
+ if( pNew ){
152045
+ WhereTerm *pTerm;
152046
+ int idx;
152047
+ idx = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_VIRTUAL);
152048
+ pTerm = &pWC->a[idx];
152049
+ pTerm->leftCursor = iCsr;
152050
+ pTerm->eOperator = WO_AUX;
152051
+ pTerm->eMatchOp = eMatchOp;
152052
+ }
152053
+}
152054
+
152055
+/*
152056
+** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the
152057
+** SELECT statement passed as the second argument. These terms are only
152058
+** added if:
152059
+**
152060
+** 1. The SELECT statement has a LIMIT clause, and
152061
+** 2. The SELECT statement is not an aggregate or DISTINCT query, and
152062
+** 3. The SELECT statement has exactly one object in its from clause, and
152063
+** that object is a virtual table, and
152064
+** 4. There are no terms in the WHERE clause that will not be passed
152065
+** to the virtual table xBestIndex method.
152066
+** 5. The ORDER BY clause, if any, will be made available to the xBestIndex
152067
+** method.
152068
+**
152069
+** LIMIT and OFFSET terms are ignored by most of the planner code. They
152070
+** exist only so that they may be passed to the xBestIndex method of the
152071
+** single virtual table in the FROM clause of the SELECT.
152072
+*/
152073
+SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
152074
+ assert( p==0 || (p->pGroupBy==0 && (p->selFlags & SF_Aggregate)==0) );
152075
+ if( (p && p->pLimit) /* 1 */
152076
+ && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */
152077
+ && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */
152078
+ ){
152079
+ ExprList *pOrderBy = p->pOrderBy;
152080
+ int iCsr = p->pSrc->a[0].iCursor;
152081
+ int ii;
152082
+
152083
+ /* Check condition (4). Return early if it is not met. */
152084
+ for(ii=0; ii<pWC->nTerm; ii++){
152085
+ if( pWC->a[ii].wtFlags & TERM_CODED ){
152086
+ /* This term is a vector operation that has been decomposed into
152087
+ ** other, subsequent terms. It can be ignored. See tag-20220128a */
152088
+ assert( pWC->a[ii].wtFlags & TERM_VIRTUAL );
152089
+ assert( pWC->a[ii].eOperator==0 );
152090
+ continue;
152091
+ }
152092
+ if( pWC->a[ii].leftCursor!=iCsr ) return;
152093
+ }
152094
+
152095
+ /* Check condition (5). Return early if it is not met. */
152096
+ if( pOrderBy ){
152097
+ for(ii=0; ii<pOrderBy->nExpr; ii++){
152098
+ Expr *pExpr = pOrderBy->a[ii].pExpr;
152099
+ if( pExpr->op!=TK_COLUMN ) return;
152100
+ if( pExpr->iTable!=iCsr ) return;
152101
+ if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return;
152102
+ }
152103
+ }
152104
+
152105
+ /* All conditions are met. Add the terms to the where-clause object. */
152106
+ assert( p->pLimit->op==TK_LIMIT );
152107
+ whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft,
152108
+ iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT);
152109
+ if( p->iOffset>0 ){
152110
+ whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight,
152111
+ iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET);
152112
+ }
152113
+ }
152114
+}
151129152115
151130152116
/*
151131152117
** Initialize a preallocated WhereClause structure.
151132152118
*/
151133152119
SQLITE_PRIVATE void sqlite3WhereClauseInit(
@@ -151160,10 +152146,11 @@
151160152146
for(i=pWC->nBase; i<pWC->nTerm; i++){
151161152147
assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 );
151162152148
}
151163152149
#endif
151164152150
while(1){
152151
+ assert( a->eMatchOp==0 || a->eOperator==WO_AUX );
151165152152
if( a->wtFlags & TERM_DYNAMIC ){
151166152153
sqlite3ExprDelete(db, a->pExpr);
151167152154
}
151168152155
if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){
151169152156
if( a->wtFlags & TERM_ORINFO ){
@@ -151317,10 +152304,11 @@
151317152304
if( pColRef==0 ) return;
151318152305
pColRef->iTable = pItem->iCursor;
151319152306
pColRef->iColumn = k++;
151320152307
assert( ExprUseYTab(pColRef) );
151321152308
pColRef->y.pTab = pTab;
152309
+ pItem->colUsed |= sqlite3ExprColUsed(pColRef);
151322152310
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
151323152311
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
151324152312
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
151325152313
if( pItem->fg.jointype & JT_LEFT ){
151326152314
sqlite3SetJoinExpr(pTerm, pItem->iCursor);
@@ -151364,10 +152352,12 @@
151364152352
typedef struct HiddenIndexInfo HiddenIndexInfo;
151365152353
struct HiddenIndexInfo {
151366152354
WhereClause *pWC; /* The Where clause being analyzed */
151367152355
Parse *pParse; /* The parsing context */
151368152356
int eDistinct; /* Value to return from sqlite3_vtab_distinct() */
152357
+ u32 mIn; /* Mask of terms that are <col> IN (...) */
152358
+ u32 mHandleIn; /* Terms that vtab will handle as <col> IN (...) */
151369152359
sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST
151370152360
** because extra space is allocated to hold up
151371152361
** to nTerm such values */
151372152362
};
151373152363
@@ -152407,11 +153397,14 @@
152407153397
VdbeCoverage(v);
152408153398
sqlite3VdbeJumpHere(v, addrTop);
152409153399
pLoop->wsFlags &= ~WHERE_BLOOMFILTER;
152410153400
if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
152411153401
while( ++iLevel < pWInfo->nLevel ){
153402
+ const SrcItem *pTabItem;
152412153403
pLevel = &pWInfo->a[iLevel];
153404
+ pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
153405
+ if( pTabItem->fg.jointype & JT_LEFT ) continue;
152413153406
pLoop = pLevel->pWLoop;
152414153407
if( NEVER(pLoop==0) ) continue;
152415153408
if( pLoop->prereq & notReady ) continue;
152416153409
if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN))
152417153410
==WHERE_BLOOMFILTER
@@ -152474,10 +153467,11 @@
152474153467
testcase( pTerm->eOperator & WO_ISNULL );
152475153468
testcase( pTerm->eOperator & WO_IS );
152476153469
testcase( pTerm->eOperator & WO_ALL );
152477153470
if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
152478153471
if( pTerm->wtFlags & TERM_VNULL ) continue;
153472
+
152479153473
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
152480153474
assert( pTerm->u.x.leftColumn>=XN_ROWID );
152481153475
assert( pTerm->u.x.leftColumn<pTab->nCol );
152482153476
152483153477
/* tag-20191211-002: WHERE-clause constraints are not useful to the
@@ -152535,14 +153529,16 @@
152535153529
}
152536153530
152537153531
/* No matches cause a break out of the loop */
152538153532
break;
152539153533
}
152540
- if( i==n){
153534
+ if( i==n ){
152541153535
nOrderBy = n;
152542
- if( (pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY)) ){
152543
- eDistinct = 1 + ((pWInfo->wctrlFlags & WHERE_DISTINCTBY)!=0);
153536
+ if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){
153537
+ eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0);
153538
+ }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){
153539
+ eDistinct = 1;
152544153540
}
152545153541
}
152546153542
}
152547153543
152548153544
/* Allocate the sqlite3_index_info structure
@@ -152563,17 +153559,23 @@
152563153559
pIdxInfo->aOrderBy = pIdxOrderBy;
152564153560
pIdxInfo->aConstraintUsage = pUsage;
152565153561
pHidden->pWC = pWC;
152566153562
pHidden->pParse = pParse;
152567153563
pHidden->eDistinct = eDistinct;
153564
+ pHidden->mIn = 0;
152568153565
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
152569153566
u16 op;
152570153567
if( (pTerm->wtFlags & TERM_OK)==0 ) continue;
152571153568
pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
152572153569
pIdxCons[j].iTermOffset = i;
152573153570
op = pTerm->eOperator & WO_ALL;
152574
- if( op==WO_IN ) op = WO_EQ;
153571
+ if( op==WO_IN ){
153572
+ if( (pTerm->wtFlags & TERM_SLICE)==0 ){
153573
+ pHidden->mIn |= SMASKBIT32(j);
153574
+ }
153575
+ op = WO_EQ;
153576
+ }
152575153577
if( op==WO_AUX ){
152576153578
pIdxCons[j].op = pTerm->eMatchOp;
152577153579
}else if( op & (WO_ISNULL|WO_IS) ){
152578153580
if( op==WO_ISNULL ){
152579153581
pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
@@ -152659,11 +153661,13 @@
152659153661
static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
152660153662
sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
152661153663
int rc;
152662153664
152663153665
whereTraceIndexInfoInputs(p);
153666
+ pParse->db->nSchemaLock++;
152664153667
rc = pVtab->pModule->xBestIndex(pVtab, p);
153668
+ pParse->db->nSchemaLock--;
152665153669
whereTraceIndexInfoOutputs(p);
152666153670
152667153671
if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
152668153672
if( rc==SQLITE_NOMEM ){
152669153673
sqlite3OomFault(pParse->db);
@@ -153911,12 +154915,21 @@
153911154915
if( j<0 ){
153912154916
if( pLoop->maskSelf==pTerm->prereqAll ){
153913154917
/* If there are extra terms in the WHERE clause not used by an index
153914154918
** that depend only on the table being scanned, and that will tend to
153915154919
** cause many rows to be omitted, then mark that table as
153916
- ** "self-culling". */
153917
- pLoop->wsFlags |= WHERE_SELFCULL;
154920
+ ** "self-culling".
154921
+ **
154922
+ ** 2022-03-24: Self-culling only applies if either the extra terms
154923
+ ** are straight comparison operators that are non-true with NULL
154924
+ ** operand, or if the loop is not a LEFT JOIN.
154925
+ */
154926
+ if( (pTerm->eOperator & 0x3f)!=0
154927
+ || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0
154928
+ ){
154929
+ pLoop->wsFlags |= WHERE_SELFCULL;
154930
+ }
153918154931
}
153919154932
if( pTerm->truthProb<=0 ){
153920154933
/* If a truth probability is specified using the likelihood() hints,
153921154934
** then use the probability provided by the application. */
153922154935
pLoop->nOut += pTerm->truthProb;
@@ -154488,11 +155501,11 @@
154488155501
}
154489155502
if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
154490155503
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
154491155504
Expr *pExpr;
154492155505
pExpr = pTerm->pExpr;
154493
- if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
155506
+ if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab)
154494155507
&& (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
154495155508
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
154496155509
&& (pTerm->wtFlags & TERM_VNULL)==0
154497155510
){
154498155511
return 1;
@@ -154789,10 +155802,19 @@
154789155802
}
154790155803
return rc;
154791155804
}
154792155805
154793155806
#ifndef SQLITE_OMIT_VIRTUALTABLE
155807
+
155808
+/*
155809
+** Return true if pTerm is a virtual table LIMIT or OFFSET term.
155810
+*/
155811
+static int isLimitTerm(WhereTerm *pTerm){
155812
+ assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 );
155813
+ return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT
155814
+ && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET;
155815
+}
154794155816
154795155817
/*
154796155818
** Argument pIdxInfo is already populated with all constraints that may
154797155819
** be used by the virtual table identified by pBuilder->pNew->iTab. This
154798155820
** function marks a subset of those constraints usable, invokes the
@@ -154817,13 +155839,15 @@
154817155839
Bitmask mPrereq, /* Mask of tables that must be used. */
154818155840
Bitmask mUsable, /* Mask of usable tables */
154819155841
u16 mExclude, /* Exclude terms using these operators */
154820155842
sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
154821155843
u16 mNoOmit, /* Do not omit these constraints */
154822
- int *pbIn /* OUT: True if plan uses an IN(...) op */
155844
+ int *pbIn, /* OUT: True if plan uses an IN(...) op */
155845
+ int *pbRetryLimit /* OUT: Retry without LIMIT/OFFSET */
154823155846
){
154824155847
WhereClause *pWC = pBuilder->pWC;
155848
+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
154825155849
struct sqlite3_index_constraint *pIdxCons;
154826155850
struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
154827155851
int i;
154828155852
int mxTerm;
154829155853
int rc = SQLITE_OK;
@@ -154842,10 +155866,11 @@
154842155866
for(i=0; i<nConstraint; i++, pIdxCons++){
154843155867
WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset];
154844155868
pIdxCons->usable = 0;
154845155869
if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight
154846155870
&& (pTerm->eOperator & mExclude)==0
155871
+ && (pbRetryLimit || !isLimitTerm(pTerm))
154847155872
){
154848155873
pIdxCons->usable = 1;
154849155874
}
154850155875
}
154851155876
@@ -154857,10 +155882,11 @@
154857155882
pIdxInfo->orderByConsumed = 0;
154858155883
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
154859155884
pIdxInfo->estimatedRows = 25;
154860155885
pIdxInfo->idxFlags = 0;
154861155886
pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
155887
+ pHidden->mHandleIn = 0;
154862155888
154863155889
/* Invoke the virtual table xBestIndex() method */
154864155890
rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
154865155891
if( rc ){
154866155892
if( rc==SQLITE_CONSTRAINT ){
@@ -154874,12 +155900,12 @@
154874155900
return rc;
154875155901
}
154876155902
154877155903
mxTerm = -1;
154878155904
assert( pNew->nLSlot>=nConstraint );
154879
- for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
154880
- pNew->u.vtab.omitMask = 0;
155905
+ memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint );
155906
+ memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab));
154881155907
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
154882155908
for(i=0; i<nConstraint; i++, pIdxCons++){
154883155909
int iTerm;
154884155910
if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
154885155911
WhereTerm *pTerm;
@@ -154909,21 +155935,41 @@
154909155935
testcase( i!=iTerm );
154910155936
pNew->u.vtab.omitMask |= 1<<iTerm;
154911155937
}else{
154912155938
testcase( i!=iTerm );
154913155939
}
155940
+ if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET ){
155941
+ pNew->u.vtab.bOmitOffset = 1;
155942
+ }
154914155943
}
154915
- if( (pTerm->eOperator & WO_IN)!=0 ){
155944
+ if( SMASKBIT32(i) & pHidden->mHandleIn ){
155945
+ pNew->u.vtab.mHandleIn |= MASKBIT32(iTerm);
155946
+ }else if( (pTerm->eOperator & WO_IN)!=0 ){
154916155947
/* A virtual table that is constrained by an IN clause may not
154917155948
** consume the ORDER BY clause because (1) the order of IN terms
154918155949
** is not necessarily related to the order of output terms and
154919155950
** (2) Multiple outputs from a single IN value will not merge
154920155951
** together. */
154921155952
pIdxInfo->orderByConsumed = 0;
154922155953
pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
154923155954
*pbIn = 1; assert( (mExclude & WO_IN)==0 );
154924155955
}
155956
+
155957
+ if( isLimitTerm(pTerm) && *pbIn ){
155958
+ /* If there is an IN(...) term handled as an == (separate call to
155959
+ ** xFilter for each value on the RHS of the IN) and a LIMIT or
155960
+ ** OFFSET term handled as well, the plan is unusable. Set output
155961
+ ** variable *pbRetryLimit to true to tell the caller to retry with
155962
+ ** LIMIT and OFFSET disabled. */
155963
+ if( pIdxInfo->needToFreeIdxStr ){
155964
+ sqlite3_free(pIdxInfo->idxStr);
155965
+ pIdxInfo->idxStr = 0;
155966
+ pIdxInfo->needToFreeIdxStr = 0;
155967
+ }
155968
+ *pbRetryLimit = 1;
155969
+ return SQLITE_OK;
155970
+ }
154925155971
}
154926155972
}
154927155973
154928155974
pNew->nLTerm = mxTerm+1;
154929155975
for(i=0; i<=mxTerm; i++){
@@ -154992,10 +156038,29 @@
154992156038
}
154993156039
zRet = (pC ? pC->zName : sqlite3StrBINARY);
154994156040
}
154995156041
return zRet;
154996156042
}
156043
+
156044
+/*
156045
+** Return true if constraint iCons is really an IN(...) constraint, or
156046
+** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0)
156047
+** or clear (if bHandle==0) the flag to handle it using an iterator.
156048
+*/
156049
+SQLITE_API int sqlite3_vtab_in(sqlite3_index_info *pIdxInfo, int iCons, int bHandle){
156050
+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156051
+ u32 m = SMASKBIT32(iCons);
156052
+ if( m & pHidden->mIn ){
156053
+ if( bHandle==0 ){
156054
+ pHidden->mHandleIn &= ~m;
156055
+ }else if( bHandle>0 ){
156056
+ pHidden->mHandleIn |= m;
156057
+ }
156058
+ return 1;
156059
+ }
156060
+ return 0;
156061
+}
154997156062
154998156063
/*
154999156064
** This interface is callable from within the xBestIndex callback only.
155000156065
**
155001156066
** If possible, set (*ppVal) to point to an object containing the value
@@ -155029,21 +156094,34 @@
155029156094
}
155030156095
155031156096
return rc;
155032156097
}
155033156098
155034
-
155035156099
/*
155036156100
** Return true if ORDER BY clause may be handled as DISTINCT.
155037156101
*/
155038156102
SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){
155039156103
HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
155040
- assert( pHidden->eDistinct==0
155041
- || pHidden->eDistinct==1
155042
- || pHidden->eDistinct==2 );
156104
+ assert( pHidden->eDistinct>=0 && pHidden->eDistinct<=3 );
155043156105
return pHidden->eDistinct;
155044156106
}
156107
+
156108
+#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
156109
+ && !defined(SQLITE_OMIT_VIRTUALTABLE)
156110
+/*
156111
+** Cause the prepared statement that is associated with a call to
156112
+** xBestIndex to open write transactions on all attached schemas.
156113
+** This is used by the (built-in) sqlite_dbpage virtual table.
156114
+*/
156115
+SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){
156116
+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156117
+ Parse *pParse = pHidden->pParse;
156118
+ int nDb = pParse->db->nDb;
156119
+ int i;
156120
+ for(i=0; i<nDb; i++) sqlite3BeginWriteOperation(pParse, 0, i);
156121
+}
156122
+#endif
155045156123
155046156124
/*
155047156125
** Add all WhereLoop objects for a table of the join identified by
155048156126
** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
155049156127
**
@@ -155082,10 +156160,11 @@
155082156160
int nConstraint; /* Number of constraints in p */
155083156161
int bIn; /* True if plan uses IN(...) operator */
155084156162
WhereLoop *pNew;
155085156163
Bitmask mBest; /* Tables used by best possible plan */
155086156164
u16 mNoOmit;
156165
+ int bRetry = 0; /* True to retry with LIMIT/OFFSET disabled */
155087156166
155088156167
assert( (mPrereq & mUnusable)==0 );
155089156168
pWInfo = pBuilder->pWInfo;
155090156169
pParse = pWInfo->pParse;
155091156170
pWC = pBuilder->pWC;
@@ -155105,11 +156184,19 @@
155105156184
}
155106156185
155107156186
/* First call xBestIndex() with all constraints usable. */
155108156187
WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
155109156188
WHERETRACE(0x40, (" VirtualOne: all usable\n"));
155110
- rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
156189
+ rc = whereLoopAddVirtualOne(
156190
+ pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry
156191
+ );
156192
+ if( bRetry ){
156193
+ assert( rc==SQLITE_OK );
156194
+ rc = whereLoopAddVirtualOne(
156195
+ pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, 0
156196
+ );
156197
+ }
155111156198
155112156199
/* If the call to xBestIndex() with all terms enabled produced a plan
155113156200
** that does not require any source tables (IOW: a plan with mBest==0)
155114156201
** and does not use an IN(...) operator, then there is no point in making
155115156202
** any further calls to xBestIndex() since they will all return the same
@@ -155123,11 +156210,11 @@
155123156210
/* If the plan produced by the earlier call uses an IN(...) term, call
155124156211
** xBestIndex again, this time with IN(...) terms disabled. */
155125156212
if( bIn ){
155126156213
WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
155127156214
rc = whereLoopAddVirtualOne(
155128
- pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
156215
+ pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0);
155129156216
assert( bIn==0 );
155130156217
mBestNoIn = pNew->prereq & ~mPrereq;
155131156218
if( mBestNoIn==0 ){
155132156219
seenZero = 1;
155133156220
seenZeroNoIN = 1;
@@ -155150,11 +156237,11 @@
155150156237
if( mNext==ALLBITS ) break;
155151156238
if( mNext==mBest || mNext==mBestNoIn ) continue;
155152156239
WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
155153156240
(sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
155154156241
rc = whereLoopAddVirtualOne(
155155
- pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
156242
+ pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn, 0);
155156156243
if( pNew->prereq==mPrereq ){
155157156244
seenZero = 1;
155158156245
if( bIn==0 ) seenZeroNoIN = 1;
155159156246
}
155160156247
}
@@ -155163,21 +156250,21 @@
155163156250
** that requires no source tables at all (i.e. one guaranteed to be
155164156251
** usable), make a call here with all source tables disabled */
155165156252
if( rc==SQLITE_OK && seenZero==0 ){
155166156253
WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
155167156254
rc = whereLoopAddVirtualOne(
155168
- pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
156255
+ pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0);
155169156256
if( bIn==0 ) seenZeroNoIN = 1;
155170156257
}
155171156258
155172156259
/* If the calls to xBestIndex() have so far failed to find a plan
155173156260
** that requires no source tables at all and does not use an IN(...)
155174156261
** operator, make a final call to obtain one here. */
155175156262
if( rc==SQLITE_OK && seenZeroNoIN==0 ){
155176156263
WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
155177156264
rc = whereLoopAddVirtualOne(
155178
- pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
156265
+ pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0);
155179156266
}
155180156267
}
155181156268
155182156269
if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
155183156270
freeIndexInfo(pParse->db, p);
@@ -155471,11 +156558,13 @@
155471156558
if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue;
155472156559
}else{
155473156560
pLoop = pLast;
155474156561
}
155475156562
if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
155476
- if( pLoop->u.vtab.isOrdered && (wctrlFlags & WHERE_DISTINCTBY)==0 ){
156563
+ if( pLoop->u.vtab.isOrdered
156564
+ && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY)
156565
+ ){
155477156566
obSat = obDone;
155478156567
}
155479156568
break;
155480156569
}else if( wctrlFlags & WHERE_DISTINCTBY ){
155481156570
pLoop->u.btree.nDistinctCol = 0;
@@ -155738,11 +156827,11 @@
155738156827
**
155739156828
** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1
155740156829
** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0
155741156830
*/
155742156831
SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){
155743
- assert( pWInfo->wctrlFlags & WHERE_GROUPBY );
156832
+ assert( pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY) );
155744156833
assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP );
155745156834
return pWInfo->sorted;
155746156835
}
155747156836
155748156837
#ifdef WHERETRACE_ENABLED
@@ -156139,16 +157228,16 @@
156139157228
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
156140157229
}
156141157230
}
156142157231
pWInfo->bOrderedInnerLoop = 0;
156143157232
if( pWInfo->pOrderBy ){
157233
+ pWInfo->nOBSat = pFrom->isOrdered;
156144157234
if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
156145157235
if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
156146157236
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
156147157237
}
156148157238
}else{
156149
- pWInfo->nOBSat = pFrom->isOrdered;
156150157239
pWInfo->revMask = pFrom->revLoop;
156151157240
if( pWInfo->nOBSat<=0 ){
156152157241
pWInfo->nOBSat = 0;
156153157242
if( nLoop>0 ){
156154157243
u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
@@ -156407,11 +157496,11 @@
156407157496
if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
156408157497
pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
156409157498
for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
156410157499
if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
156411157500
if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
156412
- || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
157501
+ || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor
156413157502
){
156414157503
break;
156415157504
}
156416157505
}
156417157506
}
@@ -156579,10 +157668,11 @@
156579157668
Parse *pParse, /* The parser context */
156580157669
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
156581157670
Expr *pWhere, /* The WHERE clause */
156582157671
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
156583157672
ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
157673
+ Select *pLimit, /* Use this LIMIT/OFFSET clause, if any */
156584157674
u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
156585157675
int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
156586157676
** If WHERE_USE_LIMIT, then the limit amount */
156587157677
){
156588157678
int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
@@ -156655,10 +157745,13 @@
156655157745
pWInfo->nLevel = nTabList;
156656157746
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
156657157747
pWInfo->wctrlFlags = wctrlFlags;
156658157748
pWInfo->iLimit = iAuxArg;
156659157749
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
157750
+#ifndef SQLITE_OMIT_VIRTUALTABLE
157751
+ pWInfo->pLimit = pLimit;
157752
+#endif
156660157753
memset(&pWInfo->nOBSat, 0,
156661157754
offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
156662157755
memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
156663157756
assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
156664157757
pMaskSet = &pWInfo->sMaskSet;
@@ -156723,10 +157816,11 @@
156723157816
#endif
156724157817
}
156725157818
156726157819
/* Analyze all of the subexpressions. */
156727157820
sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
157821
+ sqlite3WhereAddLimit(&pWInfo->sWC, pLimit);
156728157822
if( db->mallocFailed ) goto whereBeginError;
156729157823
156730157824
/* Special case: WHERE terms that do not refer to any tables in the join
156731157825
** (constant expressions). Evaluate each such term, and jump over all the
156732157826
** generated code if the result is not true.
@@ -156969,10 +158063,11 @@
156969158063
testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
156970158064
testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
156971158065
if( pWInfo->eOnePass==ONEPASS_OFF
156972158066
&& pTab->nCol<BMS
156973158067
&& (pTab->tabFlags & (TF_HasGenerated|TF_WithoutRowid))==0
158068
+ && (pLoop->wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))==0
156974158069
){
156975158070
/* If we know that only a prefix of the record will be used,
156976158071
** it is advantageous to reduce the "column count" field in
156977158072
** the P4 operand of the OP_OpenRead/Write opcode. */
156978158073
Bitmask b = pTabItem->colUsed;
@@ -157129,10 +158224,30 @@
157129158224
if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
157130158225
sqlite3VdbePrintOp(0, pc, pOp);
157131158226
}
157132158227
#endif
157133158228
158229
+#ifdef SQLITE_DEBUG
158230
+/*
158231
+** Return true if cursor iCur is opened by instruction k of the
158232
+** bytecode. Used inside of assert() only.
158233
+*/
158234
+static int cursorIsOpen(Vdbe *v, int iCur, int k){
158235
+ while( k>=0 ){
158236
+ VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
158237
+ if( pOp->p1!=iCur ) continue;
158238
+ if( pOp->opcode==OP_Close ) return 0;
158239
+ if( pOp->opcode==OP_OpenRead ) return 1;
158240
+ if( pOp->opcode==OP_OpenWrite ) return 1;
158241
+ if( pOp->opcode==OP_OpenDup ) return 1;
158242
+ if( pOp->opcode==OP_OpenAutoindex ) return 1;
158243
+ if( pOp->opcode==OP_OpenEphemeral ) return 1;
158244
+ }
158245
+ return 0;
158246
+}
158247
+#endif /* SQLITE_DEBUG */
158248
+
157134158249
/*
157135158250
** Generate the end of the WHERE loop. See comments on
157136158251
** sqlite3WhereBegin() for additional information.
157137158252
*/
157138158253
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
@@ -157381,10 +158496,15 @@
157381158496
|| pOp->opcode==OP_Offset
157382158497
#endif
157383158498
){
157384158499
int x = pOp->p2;
157385158500
assert( pIdx->pTable==pTab );
158501
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158502
+ if( pOp->opcode==OP_Offset ){
158503
+ /* Do not need to translate the column number */
158504
+ }else
158505
+#endif
157386158506
if( !HasRowid(pTab) ){
157387158507
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
157388158508
x = pPk->aiColumn[x];
157389158509
assert( x>=0 );
157390158510
}else{
@@ -157394,13 +158514,26 @@
157394158514
x = sqlite3TableColumnToIndex(pIdx, x);
157395158515
if( x>=0 ){
157396158516
pOp->p2 = x;
157397158517
pOp->p1 = pLevel->iIdxCur;
157398158518
OpcodeRewriteTrace(db, k, pOp);
158519
+ }else{
158520
+ /* Unable to translate the table reference into an index
158521
+ ** reference. Verify that this is harmless - that the
158522
+ ** table being referenced really is open.
158523
+ */
158524
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158525
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158526
+ || cursorIsOpen(v,pOp->p1,k)
158527
+ || pOp->opcode==OP_Offset
158528
+ );
158529
+#else
158530
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158531
+ || cursorIsOpen(v,pOp->p1,k)
158532
+ );
158533
+#endif
157399158534
}
157400
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0
157401
- || pWInfo->eOnePass );
157402158535
}else if( pOp->opcode==OP_Rowid ){
157403158536
pOp->p1 = pLevel->iIdxCur;
157404158537
pOp->opcode = OP_IdxRowid;
157405158538
OpcodeRewriteTrace(db, k, pOp);
157406158539
}else if( pOp->opcode==OP_IfNullRow ){
@@ -158151,11 +159284,11 @@
158151159284
break;
158152159285
}
158153159286
}
158154159287
}
158155159288
}
158156
- pWin->pFunc = pFunc;
159289
+ pWin->pWFunc = pFunc;
158157159290
}
158158159291
158159159292
/*
158160159293
** Context object passed through sqlite3WalkExprList() to
158161159294
** selectWindowRewriteExprCb() by selectWindowRewriteEList().
@@ -158384,11 +159517,15 @@
158384159517
** are invoked in the correct order as described under "SELECT REWRITING"
158385159518
** at the top of this file.
158386159519
*/
158387159520
SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
158388159521
int rc = SQLITE_OK;
158389
- if( p->pWin && p->pPrior==0 && ALWAYS((p->selFlags & SF_WinRewrite)==0) ){
159522
+ if( p->pWin
159523
+ && p->pPrior==0
159524
+ && ALWAYS((p->selFlags & SF_WinRewrite)==0)
159525
+ && ALWAYS(!IN_RENAME_OBJECT)
159526
+ ){
158390159527
Vdbe *v = sqlite3GetVdbe(pParse);
158391159528
sqlite3 *db = pParse->db;
158392159529
Select *pSub = 0; /* The subquery */
158393159530
SrcList *pSrc = p->pSrc;
158394159531
Expr *pWhere = p->pWhere;
@@ -158459,12 +159596,13 @@
158459159596
** window function - one for the accumulator, another for interim
158460159597
** results. */
158461159598
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158462159599
ExprList *pArgs;
158463159600
assert( ExprUseXList(pWin->pOwner) );
159601
+ assert( pWin->pWFunc!=0 );
158464159602
pArgs = pWin->pOwner->x.pList;
158465
- if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
159603
+ if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
158466159604
selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
158467159605
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
158468159606
pWin->bExprArgs = 1;
158469159607
}else{
158470159608
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
@@ -158842,11 +159980,11 @@
158842159980
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
158843159981
return;
158844159982
}
158845159983
158846159984
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158847
- FuncDef *p = pWin->pFunc;
159985
+ FuncDef *p = pWin->pWFunc;
158848159986
if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
158849159987
/* The inline versions of min() and max() require a single ephemeral
158850159988
** table and 3 registers. The registers are used as follows:
158851159989
**
158852159990
** regApp+0: slot to copy min()/max() argument to for MakeRecord
@@ -158859,11 +159997,11 @@
158859159997
pList = pWin->pOwner->x.pList;
158860159998
pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
158861159999
pWin->csrApp = pParse->nTab++;
158862160000
pWin->regApp = pParse->nMem+1;
158863160001
pParse->nMem += 3;
158864
- if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
160002
+ if( pKeyInfo && pWin->pWFunc->zName[1]=='i' ){
158865160003
assert( pKeyInfo->aSortFlags[0]==0 );
158866160004
pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
158867160005
}
158868160006
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
158869160007
sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
@@ -159082,11 +160220,11 @@
159082160220
){
159083160221
Parse *pParse = p->pParse;
159084160222
Vdbe *v = sqlite3GetVdbe(pParse);
159085160223
Window *pWin;
159086160224
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159087
- FuncDef *pFunc = pWin->pFunc;
160225
+ FuncDef *pFunc = pWin->pWFunc;
159088160226
int regArg;
159089160227
int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
159090160228
int i;
159091160229
159092160230
assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
@@ -159196,11 +160334,11 @@
159196160334
Vdbe *v = sqlite3GetVdbe(pParse);
159197160335
Window *pWin;
159198160336
159199160337
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159200160338
if( pMWin->regStartRowid==0
159201
- && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
160339
+ && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX)
159202160340
&& (pWin->eStart!=TK_UNBOUNDED)
159203160341
){
159204160342
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
159205160343
sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
159206160344
VdbeCoverage(v);
@@ -159210,16 +160348,16 @@
159210160348
assert( pMWin->regStartRowid==0 );
159211160349
}else{
159212160350
int nArg = windowArgCount(pWin);
159213160351
if( bFin ){
159214160352
sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
159215
- sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
160353
+ sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
159216160354
sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
159217160355
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
159218160356
}else{
159219160357
sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
159220
- sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
160358
+ sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
159221160359
}
159222160360
}
159223160361
}
159224160362
}
159225160363
@@ -159344,11 +160482,11 @@
159344160482
}else{
159345160483
Parse *pParse = p->pParse;
159346160484
Window *pWin;
159347160485
159348160486
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159349
- FuncDef *pFunc = pWin->pFunc;
160487
+ FuncDef *pFunc = pWin->pWFunc;
159350160488
assert( ExprUseXList(pWin->pOwner) );
159351160489
if( pFunc->zName==nth_valueName
159352160490
|| pFunc->zName==first_valueName
159353160491
){
159354160492
int csr = pWin->csrApp;
@@ -159416,11 +160554,11 @@
159416160554
Vdbe *v = sqlite3GetVdbe(pParse);
159417160555
int regArg;
159418160556
int nArg = 0;
159419160557
Window *pWin;
159420160558
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159421
- FuncDef *pFunc = pWin->pFunc;
160559
+ FuncDef *pFunc = pWin->pWFunc;
159422160560
assert( pWin->regAccum );
159423160561
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
159424160562
nArg = MAX(nArg, windowArgCount(pWin));
159425160563
if( pMWin->regStartRowid==0 ){
159426160564
if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
@@ -159446,11 +160584,11 @@
159446160584
*/
159447160585
static int windowCacheFrame(Window *pMWin){
159448160586
Window *pWin;
159449160587
if( pMWin->regStartRowid ) return 1;
159450160588
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159451
- FuncDef *pFunc = pWin->pFunc;
160589
+ FuncDef *pFunc = pWin->pWFunc;
159452160590
if( (pFunc->zName==nth_valueName)
159453160591
|| (pFunc->zName==first_valueName)
159454160592
|| (pFunc->zName==leadName)
159455160593
|| (pFunc->zName==lagName)
159456160594
){
@@ -159804,11 +160942,11 @@
159804160942
pNew = sqlite3DbMallocZero(db, sizeof(Window));
159805160943
if( pNew ){
159806160944
pNew->zName = sqlite3DbStrDup(db, p->zName);
159807160945
pNew->zBase = sqlite3DbStrDup(db, p->zBase);
159808160946
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
159809
- pNew->pFunc = p->pFunc;
160947
+ pNew->pWFunc = p->pWFunc;
159810160948
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
159811160949
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
159812160950
pNew->eFrmType = p->eFrmType;
159813160951
pNew->eEnd = p->eEnd;
159814160952
pNew->eStart = p->eStart;
@@ -160681,14 +161819,11 @@
160681161819
}
160682161820
return pSelect;
160683161821
}
160684161822
160685161823
160686
- /* Construct a new Expr object from a single identifier. Use the
160687
- ** new Expr to populate pOut. Set the span of pOut to be the identifier
160688
- ** that created the expression.
160689
- */
161824
+ /* Construct a new Expr object from a single token */
160690161825
static Expr *tokenExpr(Parse *pParse, int op, Token t){
160691161826
Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
160692161827
if( p ){
160693161828
/* memset(p, 0, sizeof(Expr)); */
160694161829
p->op = (u8)op;
@@ -160704,10 +161839,11 @@
160704161839
p->iTable = 0;
160705161840
p->iColumn = 0;
160706161841
p->u.zToken = (char*)&p[1];
160707161842
memcpy(p->u.zToken, t.z, t.n);
160708161843
p->u.zToken[t.n] = 0;
161844
+ p->w.iOfst = (int)(t.z - pParse->zTail);
160709161845
if( sqlite3Isquote(p->u.zToken[0]) ){
160710161846
sqlite3DequoteExpr(p);
160711161847
}
160712161848
#if SQLITE_MAX_EXPR_DEPTH>0
160713161849
p->nHeight = 1;
@@ -164515,11 +165651,11 @@
164515165651
}
164516165652
break;
164517165653
case 102: /* selcollist ::= sclp scanpt nm DOT STAR */
164518165654
{
164519165655
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
164520
- Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
165656
+ Expr *pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0);
164521165657
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
164522165658
yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
164523165659
}
164524165660
break;
164525165661
case 103: /* as ::= AS nm */
@@ -164800,29 +165936,24 @@
164800165936
case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179);
164801165937
{yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
164802165938
break;
164803165939
case 180: /* expr ::= nm DOT nm */
164804165940
{
164805
- Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
164806
- Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
164807
- if( IN_RENAME_OBJECT ){
164808
- sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
164809
- sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
164810
- }
165941
+ Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
165942
+ Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
164811165943
yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
164812165944
}
164813165945
yymsp[-2].minor.yy528 = yylhsminor.yy528;
164814165946
break;
164815165947
case 181: /* expr ::= nm DOT nm DOT nm */
164816165948
{
164817
- Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
164818
- Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
164819
- Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
165949
+ Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0);
165950
+ Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
165951
+ Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
164820165952
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
164821165953
if( IN_RENAME_OBJECT ){
164822
- sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
164823
- sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
165954
+ sqlite3RenameTokenRemap(pParse, 0, temp1);
164824165955
}
164825165956
yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
164826165957
}
164827165958
yymsp[-4].minor.yy528 = yylhsminor.yy528;
164828165959
break;
@@ -164831,10 +165962,11 @@
164831165962
{yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
164832165963
break;
164833165964
case 184: /* term ::= INTEGER */
164834165965
{
164835165966
yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
165967
+ if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
164836165968
}
164837165969
yymsp[0].minor.yy528 = yylhsminor.yy528;
164838165970
break;
164839165971
case 185: /* expr ::= VARIABLE */
164840165972
{
@@ -167075,11 +168207,14 @@
167075168207
}else if( tokenType==TK_FILTER ){
167076168208
assert( n==6 );
167077168209
tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
167078168210
#endif /* SQLITE_OMIT_WINDOWFUNC */
167079168211
}else{
167080
- sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
168212
+ Token x;
168213
+ x.z = zSql;
168214
+ x.n = n;
168215
+ sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
167081168216
break;
167082168217
}
167083168218
}
167084168219
pParse->sLastToken.z = zSql;
167085168220
pParse->sLastToken.n = n;
@@ -167125,11 +168260,11 @@
167125168260
sqlite3DeleteTable(db, pParse->pNewTable);
167126168261
}
167127168262
if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){
167128168263
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
167129168264
}
167130
- sqlite3DbFree(db, pParse->pVList);
168265
+ if( pParse->pVList ) sqlite3DbFreeNN(db, pParse->pVList);
167131168266
db->pParse = pParentParse;
167132168267
assert( nErr==0 || pParse->rc!=SQLITE_OK );
167133168268
return nErr;
167134168269
}
167135168270
@@ -171686,16 +172821,20 @@
171686172821
** is called immediately after installing the new callback and the return
171687172822
** value from sqlite3FaultSim(0) becomes the return from
171688172823
** sqlite3_test_control().
171689172824
*/
171690172825
case SQLITE_TESTCTRL_FAULT_INSTALL: {
171691
- /* MSVC is picky about pulling func ptrs from va lists.
171692
- ** http://support.microsoft.com/kb/47961
172826
+ /* A bug in MSVC prevents it from understanding pointers to functions
172827
+ ** types in the second argument to va_arg(). Work around the problem
172828
+ ** using a typedef.
172829
+ ** http://support.microsoft.com/kb/47961 <-- dead hyperlink
172830
+ ** Search at http://web.archive.org/ to find the 2015-03-16 archive
172831
+ ** of the link above to see the original text.
171693172832
** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
171694172833
*/
171695
- typedef int(*TESTCALLBACKFUNC_t)(int);
171696
- sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
172834
+ typedef int(*sqlite3FaultFuncType)(int);
172835
+ sqlite3GlobalConfig.xTestCallback = va_arg(ap, sqlite3FaultFuncType);
171697172836
rc = sqlite3FaultSim(0);
171698172837
break;
171699172838
}
171700172839
171701172840
/*
@@ -171818,17 +172957,31 @@
171818172957
sqlite3 *db = va_arg(ap, sqlite3*);
171819172958
db->dbOptFlags = va_arg(ap, u32);
171820172959
break;
171821172960
}
171822172961
171823
- /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
172962
+ /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
172963
+ **
172964
+ ** If parameter onoff is 1, subsequent calls to localtime() fail.
172965
+ ** If 2, then invoke xAlt() instead of localtime(). If 0, normal
172966
+ ** processing.
172967
+ **
172968
+ ** xAlt arguments are void pointers, but they really want to be:
172969
+ **
172970
+ ** int xAlt(const time_t*, struct tm*);
171824172971
**
171825
- ** If parameter onoff is non-zero, subsequent calls to localtime()
171826
- ** and its variants fail. If onoff is zero, undo this setting.
172972
+ ** xAlt should write results in to struct tm object of its 2nd argument
172973
+ ** and return zero on success, or return non-zero on failure.
171827172974
*/
171828172975
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
171829172976
sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
172977
+ if( sqlite3GlobalConfig.bLocaltimeFault==2 ){
172978
+ typedef int(*sqlite3LocaltimeType)(const void*,void*);
172979
+ sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType);
172980
+ }else{
172981
+ sqlite3GlobalConfig.xAltLocaltime = 0;
172982
+ }
171830172983
break;
171831172984
}
171832172985
171833172986
/* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*);
171834172987
**
@@ -172026,14 +173179,16 @@
172026173179
** Test access for the LogEst conversion routines.
172027173180
*/
172028173181
case SQLITE_TESTCTRL_LOGEST: {
172029173182
double rIn = va_arg(ap, double);
172030173183
LogEst rLogEst = sqlite3LogEstFromDouble(rIn);
172031
- u64 iInt = sqlite3LogEstToInt(rLogEst);
172032
- va_arg(ap, int*)[0] = rLogEst;
172033
- va_arg(ap, u64*)[0] = iInt;
172034
- va_arg(ap, int*)[0] = sqlite3LogEst(iInt);
173184
+ int *pI1 = va_arg(ap,int*);
173185
+ u64 *pU64 = va_arg(ap,u64*);
173186
+ int *pI2 = va_arg(ap,int*);
173187
+ *pI1 = rLogEst;
173188
+ *pU64 = sqlite3LogEstToInt(rLogEst);
173189
+ *pI2 = sqlite3LogEst(*pU64);
172035173190
break;
172036173191
}
172037173192
172038173193
172039173194
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
@@ -193960,11 +195115,11 @@
193960195115
u32 iRoot;
193961195116
JsonNode *pTarget;
193962195117
if( pPatch->eType!=JSON_OBJECT ){
193963195118
return pPatch;
193964195119
}
193965
- assert( iTarget>=0 && iTarget<pParse->nNode );
195120
+ assert( iTarget<pParse->nNode );
193966195121
pTarget = &pParse->aNode[iTarget];
193967195122
assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
193968195123
if( pTarget->eType!=JSON_OBJECT ){
193969195124
jsonRemoveAllNulls(pPatch);
193970195125
return pPatch;
@@ -195001,11 +196156,11 @@
195001196156
sqlite3_module *pModule;
195002196157
} aMod[] = {
195003196158
{ "json_each", &jsonEachModule },
195004196159
{ "json_tree", &jsonTreeModule },
195005196160
};
195006
- int i;
196161
+ unsigned int i;
195007196162
for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
195008196163
rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
195009196164
}
195010196165
return rc;
195011196166
}
@@ -209255,10 +210410,11 @@
209255210410
&& pIdxInfo->aOrderBy[0].iColumn<=0
209256210411
&& pIdxInfo->aOrderBy[0].desc==0
209257210412
){
209258210413
pIdxInfo->orderByConsumed = 1;
209259210414
}
210415
+ sqlite3VtabWriteAll(pIdxInfo);
209260210416
return SQLITE_OK;
209261210417
}
209262210418
209263210419
/*
209264210420
** Open a new dbpagevfs cursor.
@@ -209432,11 +210588,11 @@
209432210588
if( iDb<0 ){
209433210589
zErr = "no such schema";
209434210590
goto update_fail;
209435210591
}
209436210592
pBt = pTab->db->aDb[iDb].pBt;
209437
- if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){
210593
+ if( pgno<1 || pBt==0 || pgno>sqlite3BtreeLastPage(pBt) ){
209438210594
zErr = "bad page number";
209439210595
goto update_fail;
209440210596
}
209441210597
szPage = sqlite3BtreeGetPageSize(pBt);
209442210598
if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
@@ -231609,11 +232765,11 @@
231609232765
int rc;
231610232766
231611232767
rc = sqlite3_step(pSorter->pStmt);
231612232768
if( rc==SQLITE_DONE ){
231613232769
rc = SQLITE_OK;
231614
- CsrFlagSet(pCsr, FTS5CSR_EOF);
232770
+ CsrFlagSet(pCsr, FTS5CSR_EOF|FTS5CSR_REQUIRE_CONTENT);
231615232771
}else if( rc==SQLITE_ROW ){
231616232772
const u8 *a;
231617232773
const u8 *aBlob;
231618232774
int nBlob;
231619232775
int i;
@@ -233598,11 +234754,11 @@
233598234754
int nArg, /* Number of args */
233599234755
sqlite3_value **apUnused /* Function arguments */
233600234756
){
233601234757
assert( nArg==0 );
233602234758
UNUSED_PARAM2(nArg, apUnused);
233603
- sqlite3_result_text(pCtx, "fts5: 2022-01-25 00:03:25 a8db69411b0d1275909adeb21027784ada17af24efe3a59ae0ae2a897659ff17", -1, SQLITE_TRANSIENT);
234759
+ sqlite3_result_text(pCtx, "fts5: 2022-03-31 11:12:56 f2d9262e4427ab37ba26c004fc7a4790c86c1856d695a6b4ec3e72732ea54c09", -1, SQLITE_TRANSIENT);
233604234760
}
233605234761
233606234762
/*
233607234763
** Return true if zName is the extension on one of the shadow tables used
233608234764
** by this module.
233609234765
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.38.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -450,13 +450,13 @@
450 **
451 ** See also: [sqlite3_libversion()],
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.38.0"
456 #define SQLITE_VERSION_NUMBER 3038000
457 #define SQLITE_SOURCE_ID "2022-01-25 00:03:25 a8db69411b0d1275909adeb21027784ada17af24efe3a59ae0ae2a897659ff17"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -870,11 +870,11 @@
870 #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
871 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
872 #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
873 #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
874 #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
875 #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
876
877 /*
878 ** CAPI3REF: Flags For File Open Operations
879 **
880 ** These bit values are intended for use in the
@@ -4154,11 +4154,11 @@
4154 **
4155 ** ^If the most recent error references a specific token in the input
4156 ** SQL, the sqlite3_error_offset() interface returns the byte offset
4157 ** of the start of that token. ^The byte offset returned by
4158 ** sqlite3_error_offset() assumes that the input SQL is UTF8.
4159 ** ^If the most error does not reference a specific token in the input
4160 ** SQL, then the sqlite3_error_offset() function returns -1.
4161 **
4162 ** When the serialized [threading mode] is in use, it might be the
4163 ** case that a second error occurs on a separate thread in between
4164 ** the time of the first error and the call to these interfaces.
@@ -4588,10 +4588,14 @@
4588 ** ^For example, an UPDATE statement might have a WHERE clause that
4589 ** makes it a no-op, but the sqlite3_stmt_readonly() result would still
4590 ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
4591 ** read-only no-op if the table already exists, but
4592 ** sqlite3_stmt_readonly() still returns false for such a statement.
 
 
 
 
4593 */
4594 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
4595
4596 /*
4597 ** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4656,10 +4660,12 @@
4656 ** still make the distinction between protected and unprotected
4657 ** sqlite3_value objects even when not strictly required.
4658 **
4659 ** ^The sqlite3_value objects that are passed as parameters into the
4660 ** implementation of [application-defined SQL functions] are protected.
 
 
4661 ** ^The sqlite3_value object returned by
4662 ** [sqlite3_column_value()] is unprotected.
4663 ** Unprotected sqlite3_value objects may only be used as arguments
4664 ** to [sqlite3_result_value()], [sqlite3_bind_value()], and
4665 ** [sqlite3_value_dup()].
@@ -5276,10 +5282,14 @@
5276 ** bytes in the string, not the number of characters.
5277 **
5278 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
5279 ** even empty strings, are always zero-terminated. ^The return
5280 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
 
 
 
 
5281 **
5282 ** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
5283 ** [unprotected sqlite3_value] object. In a multithreaded environment,
5284 ** an unprotected sqlite3_value object may only be used safely with
5285 ** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -5290,11 +5300,11 @@
5290 ** Hence, the sqlite3_column_value() interface
5291 ** is normally only useful within the implementation of
5292 ** [application-defined SQL functions] or [virtual tables], not within
5293 ** top-level application code.
5294 **
5295 ** The these routines may attempt to convert the datatype of the result.
5296 ** ^For example, if the internal representation is FLOAT and a text result
5297 ** is requested, [sqlite3_snprintf()] is used internally to perform the
5298 ** conversion automatically. ^(The following table details the conversions
5299 ** that are applied:
5300 **
@@ -5315,11 +5325,11 @@
5315 ** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
5316 ** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
5317 ** <tr><td> TEXT <td> BLOB <td> No change
5318 ** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
5319 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5320 ** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
5321 ** </table>
5322 ** </blockquote>)^
5323 **
5324 ** Note that when type conversions occur, pointers returned by prior
5325 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5887,11 +5897,12 @@
5887 **
5888 ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
5889 ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
5890 ** is a [protected sqlite3_value] object even if the input is not.
5891 ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5892 ** memory allocation fails.
 
5893 **
5894 ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
5895 ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
5896 ** then sqlite3_value_free(V) is a harmless no-op.
5897 */
@@ -7435,28 +7446,60 @@
7435 /*
7436 ** CAPI3REF: Virtual Table Constraint Operator Codes
7437 **
7438 ** These macros define the allowed values for the
7439 ** [sqlite3_index_info].aConstraint[].op field. Each value represents
7440 ** an operator that is part of a constraint term in the wHERE clause of
7441 ** a query that uses a [virtual table].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7442 */
7443 #define SQLITE_INDEX_CONSTRAINT_EQ 2
7444 #define SQLITE_INDEX_CONSTRAINT_GT 4
7445 #define SQLITE_INDEX_CONSTRAINT_LE 8
7446 #define SQLITE_INDEX_CONSTRAINT_LT 16
7447 #define SQLITE_INDEX_CONSTRAINT_GE 32
7448 #define SQLITE_INDEX_CONSTRAINT_MATCH 64
7449 #define SQLITE_INDEX_CONSTRAINT_LIKE 65
7450 #define SQLITE_INDEX_CONSTRAINT_GLOB 66
7451 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7452 #define SQLITE_INDEX_CONSTRAINT_NE 68
7453 #define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7454 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7455 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7456 #define SQLITE_INDEX_CONSTRAINT_IS 72
7457 #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
 
 
7458
7459 /*
7460 ** CAPI3REF: Register A Virtual Table Implementation
7461 ** METHOD: sqlite3
7462 **
@@ -7481,11 +7524,11 @@
7481 ** ^The sqlite3_create_module()
7482 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
7483 ** destructor.
7484 **
7485 ** ^If the third parameter (the pointer to the sqlite3_module object) is
7486 ** NULL then no new module is create and any existing modules with the
7487 ** same name are dropped.
7488 **
7489 ** See also: [sqlite3_drop_modules()]
7490 */
7491 SQLITE_API int sqlite3_create_module(
@@ -9812,28 +9855,29 @@
9812
9813 /*
9814 ** CAPI3REF: Determine if a virtual table query is DISTINCT
9815 ** METHOD: sqlite3_index_info
9816 **
9817 ** This API may only be used from within an xBestIndex() callback. The
9818 ** results of calling it from outside of an xBestIndex() callback are
9819 ** undefined and probably harmful.
9820 **
9821 ** ^The sqlite3_vtab_distinct() returns an integer that is either 0, 1, or
9822 ** 2. The integer returned by sqlite3_vtab_distinct() gives the virtual table
9823 ** additional information about how the query planner wants the output to be
9824 ** ordered. As long as the virtual table can meet the ordering requirements
9825 ** of the query planner, it may set the "orderByConsumed" flag.
 
9826 **
9827 ** <ol><li value="0"><p>
9828 ** ^If the sqlite3_vtab_distinct() interface returns 0, that means
9829 ** that the query planner needs the virtual table to return all rows in the
9830 ** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
9831 ** [sqlite3_index_info] object. This is the default expectation. If the
9832 ** virtual table outputs all rows in sorted order, then it is always safe for
9833 ** the xBestIndex method to set the "orderByConsumed" flag, regardless of
9834 ** what the return value from sqlite3_vtab_distinct().
9835 ** <li value="1"><p>
9836 ** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
9837 ** that the query planner does not need the rows to be returned in sorted order
9838 ** as long as all rows with the same values in all columns identified by the
9839 ** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
@@ -9842,16 +9886,23 @@
9842 ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
9843 ** that the query planner does not need the rows returned in any particular
9844 ** order, as long as rows with the same values in all "aOrderBy" columns
9845 ** are adjacent.)^ ^(Furthermore, only a single row for each particular
9846 ** combination of values in the columns identified by the "aOrderBy" field
9847 ** needs to be returned.)^ ^It is ok always for two or more rows with the same
9848 ** values in all "aOrderBy" columns to be returned, as long as all such rows
9849 ** are adjacent. ^The virtual table may, if it chooses, omit extra rows
9850 ** that have the same value for all columns identified by "aOrderBy".
9851 ** ^However omitting the extra rows is optional.
9852 ** This mode is used for a DISTINCT query.
 
 
 
 
 
 
 
9853 ** </ol>
9854 **
9855 ** ^For the purposes of comparing virtual table output values to see if the
9856 ** values are same value for sorting purposes, two NULL values are considered
9857 ** to be the same. In other words, the comparison operator is "IS"
@@ -9873,35 +9924,171 @@
9873 ** valid to do so, on the other hand, might cause SQLite to return incorrect
9874 ** results.
9875 */
9876 SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
9877
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9878 /*
9879 ** CAPI3REF: Constraint values in xBestIndex()
9880 ** METHOD: sqlite3_index_info
9881 **
9882 ** This API may only be used from within an xBestIndex() callback. The
9883 ** results of calling it from outside of an xBestIndex() callback are
9884 ** undefined and probably harmful.
9885 **
9886 ** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
9887 ** the [xBestIndex] method of a [virtual table] implementation, with P being
9888 ** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
9889 ** J being a 0-based index into P->aConstraint[], then this routine
9890 ** attempts to set *V to be the value on the right-hand side of
9891 ** that constraint if the right-hand side is a known constant. ^If the
9892 ** right-hand side of the constraint is not known, then *V is set to a NULL
9893 ** pointer. ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
9894 ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
9895 ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
9896 ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
9897 ** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
9898 ** something goes wrong.
9899 **
9900 ** ^The sqlite3_value object returned in *V remains valid for the duration of
9901 ** the xBestIndex method code. ^When xBestIndex returns, the sqlite3_value
9902 ** object returned by sqlite3_vtab_rhs_value() is automatically deallocated.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9903 */
9904 SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
9905
9906 /*
9907 ** CAPI3REF: Conflict resolution modes
@@ -14340,11 +14527,11 @@
14340 ** one parameter that destructors normally want. So we have to introduce
14341 ** this magic value that the code knows to handle differently. Any
14342 ** pointer will work here as long as it is distinct from SQLITE_STATIC
14343 ** and SQLITE_TRANSIENT.
14344 */
14345 #define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomFault)
14346
14347 /*
14348 ** When SQLITE_OMIT_WSD is defined, it means that the target platform does
14349 ** not support Writable Static Data (WSD) such as global and static variables.
14350 ** All variables must either be on the stack or dynamically allocated from
@@ -14468,14 +14655,15 @@
14468 #define BMS ((int)(sizeof(Bitmask)*8))
14469
14470 /*
14471 ** A bit in a Bitmask
14472 */
14473 #define MASKBIT(n) (((Bitmask)1)<<(n))
14474 #define MASKBIT64(n) (((u64)1)<<(n))
14475 #define MASKBIT32(n) (((unsigned int)1)<<(n))
14476 #define ALLBITS ((Bitmask)-1)
 
14477
14478 /* A VList object records a mapping between parameters/variables/wildcards
14479 ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
14480 ** variable number associated with that parameter. See the format description
14481 ** on the sqlite3VListAdd() routine for more information. A VList is really
@@ -14533,18 +14721,19 @@
14533 ** Handle type for pages.
14534 */
14535 typedef struct PgHdr DbPage;
14536
14537 /*
14538 ** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
14539 ** reserved for working around a windows/posix incompatibility). It is
14540 ** used in the journal to signify that the remainder of the journal file
14541 ** is devoted to storing a super-journal name - there are no more pages to
14542 ** roll back. See comments for function writeSuperJournal() in pager.c
14543 ** for details.
14544 */
14545 #define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
 
14546
14547 /*
14548 ** Allowed values for the flags parameter to sqlite3PagerOpen().
14549 **
14550 ** NOTE: These values must match the corresponding BTREE_ values in btree.h.
@@ -15217,11 +15406,10 @@
15217 SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
15218 Table *pTab; /* Used when p4type is P4_TABLE */
15219 #ifdef SQLITE_ENABLE_CURSOR_HINTS
15220 Expr *pExpr; /* Used when p4type is P4_EXPR */
15221 #endif
15222 int (*xAdvance)(BtCursor *, int);
15223 } p4;
15224 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
15225 char *zComment; /* Comment to improve readability */
15226 #endif
15227 #ifdef VDBE_PROFILE
@@ -15268,25 +15456,23 @@
15268 #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
15269 #define P4_STATIC (-1) /* Pointer to a static string */
15270 #define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */
15271 #define P4_INT32 (-3) /* P4 is a 32-bit signed integer */
15272 #define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */
15273 #define P4_ADVANCE (-5) /* P4 is a pointer to BtreeNext() or BtreePrev() */
15274 #define P4_TABLE (-6) /* P4 is a pointer to a Table structure */
15275 /* Above do not own any resources. Must free those below */
15276 #define P4_FREE_IF_LE (-7)
15277 #define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */
15278 #define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */
15279 #define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */
15280 #define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */
15281 #define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */
15282 #define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */
15283 #define P4_REAL (-13) /* P4 is a 64-bit floating point value */
15284 #define P4_INT64 (-14) /* P4 is a 64-bit signed integer */
15285 #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
15286 #define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
15287 #define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */
15288
15289 /* Error message codes for OP_Halt */
15290 #define P5_ConstraintNotNull 1
15291 #define P5_ConstraintUnique 2
15292 #define P5_ConstraintCheck 3
@@ -15327,46 +15513,46 @@
15327 /* Automatically generated. Do not edit */
15328 /* See the tool/mkopcodeh.tcl script for details */
15329 #define OP_Savepoint 0
15330 #define OP_AutoCommit 1
15331 #define OP_Transaction 2
15332 #define OP_SorterNext 3 /* jump */
15333 #define OP_Prev 4 /* jump */
15334 #define OP_Next 5 /* jump */
15335 #define OP_Checkpoint 6
15336 #define OP_JournalMode 7
15337 #define OP_Vacuum 8
15338 #define OP_VFilter 9 /* jump, synopsis: iplan=r[P3] zplan='P4' */
15339 #define OP_VUpdate 10 /* synopsis: data=r[P3@P2] */
15340 #define OP_Goto 11 /* jump */
15341 #define OP_Gosub 12 /* jump */
15342 #define OP_InitCoroutine 13 /* jump */
15343 #define OP_Yield 14 /* jump */
15344 #define OP_MustBeInt 15 /* jump */
15345 #define OP_Jump 16 /* jump */
15346 #define OP_Once 17 /* jump */
15347 #define OP_If 18 /* jump */
15348 #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
15349 #define OP_IfNot 20 /* jump */
15350 #define OP_IsNullOrType 21 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */
15351 #define OP_IfNullRow 22 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
15352 #define OP_SeekLT 23 /* jump, synopsis: key=r[P3@P4] */
15353 #define OP_SeekLE 24 /* jump, synopsis: key=r[P3@P4] */
15354 #define OP_SeekGE 25 /* jump, synopsis: key=r[P3@P4] */
15355 #define OP_SeekGT 26 /* jump, synopsis: key=r[P3@P4] */
15356 #define OP_IfNotOpen 27 /* jump, synopsis: if( !csr[P1] ) goto P2 */
15357 #define OP_IfNoHope 28 /* jump, synopsis: key=r[P3@P4] */
15358 #define OP_NoConflict 29 /* jump, synopsis: key=r[P3@P4] */
15359 #define OP_NotFound 30 /* jump, synopsis: key=r[P3@P4] */
15360 #define OP_Found 31 /* jump, synopsis: key=r[P3@P4] */
15361 #define OP_SeekRowid 32 /* jump, synopsis: intkey=r[P3] */
15362 #define OP_NotExists 33 /* jump, synopsis: intkey=r[P3] */
15363 #define OP_Last 34 /* jump */
15364 #define OP_IfSmaller 35 /* jump */
15365 #define OP_SorterSort 36 /* jump */
15366 #define OP_Sort 37 /* jump */
15367 #define OP_Rewind 38 /* jump */
15368 #define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */
15369 #define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */
15370 #define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */
15371 #define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */
15372 #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
@@ -15395,41 +15581,41 @@
15395 #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
15396 #define OP_Return 67
15397 #define OP_EndCoroutine 68
15398 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
15399 #define OP_Halt 70
15400 #define OP_Integer 71 /* synopsis: r[P2]=P1 */
15401 #define OP_Int64 72 /* synopsis: r[P2]=P4 */
15402 #define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */
15403 #define OP_Null 74 /* synopsis: r[P2..P3]=NULL */
15404 #define OP_SoftNull 75 /* synopsis: r[P1]=NULL */
15405 #define OP_Blob 76 /* synopsis: r[P2]=P4 (len=P1) */
15406 #define OP_Variable 77 /* synopsis: r[P2]=parameter(P1,P4) */
15407 #define OP_Move 78 /* synopsis: r[P2@P3]=r[P1@P3] */
15408 #define OP_Copy 79 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15409 #define OP_SCopy 80 /* synopsis: r[P2]=r[P1] */
15410 #define OP_IntCopy 81 /* synopsis: r[P2]=r[P1] */
15411 #define OP_FkCheck 82
15412 #define OP_ResultRow 83 /* synopsis: output=r[P1@P2] */
15413 #define OP_CollSeq 84
15414 #define OP_AddImm 85 /* synopsis: r[P1]=r[P1]+P2 */
15415 #define OP_RealAffinity 86
15416 #define OP_Cast 87 /* synopsis: affinity(r[P1]) */
15417 #define OP_Permutation 88
15418 #define OP_Compare 89 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15419 #define OP_IsTrue 90 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15420 #define OP_ZeroOrNull 91 /* synopsis: r[P2] = 0 OR NULL */
15421 #define OP_Offset 92 /* synopsis: r[P3] = sqlite_offset(P1) */
15422 #define OP_Column 93 /* synopsis: r[P3]=PX */
15423 #define OP_TypeCheck 94 /* synopsis: typecheck(r[P1@P2]) */
15424 #define OP_Affinity 95 /* synopsis: affinity(r[P1@P2]) */
15425 #define OP_MakeRecord 96 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15426 #define OP_Count 97 /* synopsis: r[P2]=count() */
15427 #define OP_ReadCookie 98
15428 #define OP_SetCookie 99
15429 #define OP_ReopenIdx 100 /* synopsis: root=P2 iDb=P3 */
15430 #define OP_OpenRead 101 /* synopsis: root=P2 iDb=P3 */
15431 #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
15432 #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
15433 #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
15434 #define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
15435 #define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
@@ -15436,82 +15622,84 @@
15436 #define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
15437 #define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
15438 #define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
15439 #define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
15440 #define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
15441 #define OP_OpenWrite 112 /* synopsis: root=P2 iDb=P3 */
15442 #define OP_OpenDup 113
15443 #define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
15444 #define OP_OpenAutoindex 115 /* synopsis: nColumn=P2 */
15445 #define OP_OpenEphemeral 116 /* synopsis: nColumn=P2 */
15446 #define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */
15447 #define OP_SorterOpen 118
15448 #define OP_SequenceTest 119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15449 #define OP_OpenPseudo 120 /* synopsis: P3 columns in r[P2] */
15450 #define OP_Close 121
15451 #define OP_ColumnsUsed 122
15452 #define OP_SeekScan 123 /* synopsis: Scan-ahead up to P1 rows */
15453 #define OP_SeekHit 124 /* synopsis: set P2<=seekHit<=P3 */
15454 #define OP_Sequence 125 /* synopsis: r[P2]=cursor[P1].ctr++ */
15455 #define OP_NewRowid 126 /* synopsis: r[P2]=rowid */
15456 #define OP_Insert 127 /* synopsis: intkey=r[P3] data=r[P2] */
15457 #define OP_RowCell 128
15458 #define OP_Delete 129
15459 #define OP_ResetCount 130
15460 #define OP_SorterCompare 131 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15461 #define OP_SorterData 132 /* synopsis: r[P2]=data */
15462 #define OP_RowData 133 /* synopsis: r[P2]=data */
15463 #define OP_Rowid 134 /* synopsis: r[P2]=rowid */
15464 #define OP_NullRow 135
15465 #define OP_SeekEnd 136
15466 #define OP_IdxInsert 137 /* synopsis: key=r[P2] */
15467 #define OP_SorterInsert 138 /* synopsis: key=r[P2] */
15468 #define OP_IdxDelete 139 /* synopsis: key=r[P2@P3] */
15469 #define OP_DeferredSeek 140 /* synopsis: Move P3 to P1.rowid if needed */
15470 #define OP_IdxRowid 141 /* synopsis: r[P2]=rowid */
15471 #define OP_FinishSeek 142
15472 #define OP_Destroy 143
15473 #define OP_Clear 144
15474 #define OP_ResetSorter 145
15475 #define OP_CreateBtree 146 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15476 #define OP_SqlExec 147
15477 #define OP_ParseSchema 148
15478 #define OP_LoadAnalysis 149
15479 #define OP_DropTable 150
15480 #define OP_DropIndex 151
15481 #define OP_DropTrigger 152
15482 #define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
15483 #define OP_IntegrityCk 154
15484 #define OP_RowSetAdd 155 /* synopsis: rowset(P1)=r[P2] */
15485 #define OP_Param 156
15486 #define OP_FkCounter 157 /* synopsis: fkctr[P1]+=P2 */
15487 #define OP_MemMax 158 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15488 #define OP_OffsetLimit 159 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15489 #define OP_AggInverse 160 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15490 #define OP_AggStep 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15491 #define OP_AggStep1 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15492 #define OP_AggValue 163 /* synopsis: r[P3]=value N=P2 */
15493 #define OP_AggFinal 164 /* synopsis: accum=r[P1] N=P2 */
15494 #define OP_Expire 165
15495 #define OP_CursorLock 166
15496 #define OP_CursorUnlock 167
15497 #define OP_TableLock 168 /* synopsis: iDb=P1 root=P2 write=P3 */
15498 #define OP_VBegin 169
15499 #define OP_VCreate 170
15500 #define OP_VDestroy 171
15501 #define OP_VOpen 172
15502 #define OP_VColumn 173 /* synopsis: r[P3]=vcolumn(P2) */
15503 #define OP_VRename 174
15504 #define OP_Pagecount 175
15505 #define OP_MaxPgcnt 176
15506 #define OP_FilterAdd 177 /* synopsis: filter(P1) += key(P3@P4) */
15507 #define OP_Trace 178
15508 #define OP_CursorHint 179
15509 #define OP_ReleaseReg 180 /* synopsis: release r[P1@P2] mask P3 */
15510 #define OP_Noop 181
15511 #define OP_Explain 182
15512 #define OP_Abortable 183
 
 
15513
15514 /* Properties such as "out2" or "jump" that are specified in
15515 ** comments following the "case" for each opcode in the vdbe.c
15516 ** are encoded into bitvectors as follows:
15517 */
@@ -15520,34 +15708,34 @@
15520 #define OPFLG_IN2 0x04 /* in2: P2 is an input */
15521 #define OPFLG_IN3 0x08 /* in3: P3 is an input */
15522 #define OPFLG_OUT2 0x10 /* out2: P2 is an output */
15523 #define OPFLG_OUT3 0x20 /* out3: P3 is an output */
15524 #define OPFLG_INITIALIZER {\
15525 /* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\
15526 /* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\
15527 /* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x03, 0x01, 0x09,\
15528 /* 24 */ 0x09, 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09,\
15529 /* 32 */ 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
15530 /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
15531 /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
15532 /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15533 /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
15534 /* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\
15535 /* 80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\
15536 /* 88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\
15537 /* 96 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\
15538 /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
15539 /* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\
15540 /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
15541 /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15542 /* 136 */ 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10,\
15543 /* 144 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15544 /* 152 */ 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a,\
15545 /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15546 /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
15547 /* 176 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15548 }
15549
15550 /* The resolve3P2Values() routine is able to run faster if it knows
15551 ** the value of the largest JUMP opcode. The smaller the maximum
15552 ** JUMP opcode the better, so the mkopcodeh.tcl script that
15553 ** generated this include file strives to group all JUMP opcodes
@@ -17601,10 +17789,15 @@
17601 ** b-tree.
17602 */
17603 struct UnpackedRecord {
17604 KeyInfo *pKeyInfo; /* Collation and sort-order information */
17605 Mem *aMem; /* Values */
 
 
 
 
 
17606 u16 nField; /* Number of entries in apMem[] */
17607 i8 default_rc; /* Comparison result if keys are equal */
17608 u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
17609 i8 r1; /* Value to return if (lhs < rhs) */
17610 i8 r2; /* Value to return if (lhs > rhs) */
@@ -17908,11 +18101,14 @@
17908 ** TK_SELECT: 1st register of result vector */
17909 ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
17910 ** TK_VARIABLE: variable number (always >= 1).
17911 ** TK_SELECT_COLUMN: column of the result vector */
17912 i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
17913 int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
 
 
 
17914 AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
17915 union {
17916 Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
17917 ** for a column of an index on an expression */
17918 Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */
@@ -19017,10 +19213,11 @@
19017 #endif
19018 #ifndef SQLITE_UNTESTABLE
19019 int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
19020 #endif
19021 int bLocaltimeFault; /* True to fail localtime() calls */
 
19022 int iOnceResetThreshold; /* When to reset OP_Once counters */
19023 u32 szSorterRef; /* Min size in bytes to use sorter-refs */
19024 unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
19025 /* vvvv--- must be last ---vvv */
19026 #ifdef SQLITE_DEBUG
@@ -19221,11 +19418,11 @@
19221 Expr *pStart; /* Expression for "<expr> PRECEDING" */
19222 Expr *pEnd; /* Expression for "<expr> FOLLOWING" */
19223 Window **ppThis; /* Pointer to this object in Select.pWin list */
19224 Window *pNextWin; /* Next window function belonging to this SELECT */
19225 Expr *pFilter; /* The FILTER expression */
19226 FuncDef *pFunc; /* The function */
19227 int iEphCsr; /* Partition buffer or Peer buffer */
19228 int regAccum; /* Accumulator */
19229 int regResult; /* Interim result */
19230 int csrApp; /* Function cursor (used by min/max) */
19231 int regApp; /* Function register (also used by min/max) */
@@ -19662,11 +19859,12 @@
19662 #endif
19663 SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*);
19664 SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
19665 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
19666 Upsert*);
19667 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
 
19668 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
19669 SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
19670 SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
19671 SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
19672 SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
@@ -20075,10 +20273,11 @@
20075 SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
20076 SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
20077 SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
20078 SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
20079 SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*);
 
20080
20081 SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
20082 SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
20083
20084 #ifndef SQLITE_OMIT_SUBQUERY
@@ -20179,11 +20378,16 @@
20179 SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
20180 SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
20181 SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*);
20182 SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
20183 SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
 
20184 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
 
 
 
 
20185 SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
20186 SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
20187 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
20188 SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*);
20189 SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse*);
@@ -21695,13 +21899,17 @@
21695 #endif
21696 #ifndef SQLITE_UNTESTABLE
21697 0, /* xTestCallback */
21698 #endif
21699 0, /* bLocaltimeFault */
 
21700 0x7ffffffe, /* iOnceResetThreshold */
21701 SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
21702 0, /* iPrngSeed */
 
 
 
21703 };
21704
21705 /*
21706 ** Hash table for global functions - functions common to all
21707 ** database connections. After initialization, this table is
@@ -22041,20 +22249,20 @@
22041 i64 i; /* Integer value used when MEM_Int is set in flags */
22042 int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
22043 const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
22044 FuncDef *pDef; /* Used only when flags==MEM_Agg */
22045 } u;
 
 
22046 u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
22047 u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
22048 u8 eSubtype; /* Subtype for this value */
22049 int n; /* Number of characters in string value, excluding '\0' */
22050 char *z; /* String or BLOB value */
22051 /* ShallowCopy only needs to copy the information above */
22052 char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
22053 int szMalloc; /* Size of the zMalloc allocation */
22054 u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
22055 sqlite3 *db; /* The associated database connection */
22056 void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
22057 #ifdef SQLITE_DEBUG
22058 Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
22059 u16 mScopyFlags; /* flags value immediately after the shallow copy */
22060 #endif
@@ -22062,15 +22270,47 @@
22062
22063 /*
22064 ** Size of struct Mem not including the Mem.zMalloc member or anything that
22065 ** follows.
22066 */
22067 #define MEMCELLSIZE offsetof(Mem,zMalloc)
22068
22069 /* One or more of the following flags are set to indicate the validOK
22070 ** representations of the value stored in the Mem struct.
22071 **
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22072 ** If the MEM_Null flag is set, then the value is an SQL NULL value.
22073 ** For a pointer type created using sqlite3_bind_pointer() or
22074 ** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
22075 **
22076 ** If the MEM_Str flag is set then Mem.z points at a string representation.
@@ -22077,39 +22317,36 @@
22077 ** Usually this is encoded in the same unicode encoding as the main
22078 ** database (see below for exceptions). If the MEM_Term flag is also
22079 ** set, then the string is nul terminated. The MEM_Int and MEM_Real
22080 ** flags may coexist with the MEM_Str flag.
22081 */
 
22082 #define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
22083 #define MEM_Str 0x0002 /* Value is a string */
22084 #define MEM_Int 0x0004 /* Value is an integer */
22085 #define MEM_Real 0x0008 /* Value is a real number */
22086 #define MEM_Blob 0x0010 /* Value is a BLOB */
22087 #define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
22088 #define MEM_AffMask 0x003f /* Mask of affinity bits */
 
 
 
22089 #define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
22090 #define MEM_Undefined 0x0080 /* Value is undefined */
22091 #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
22092 #define MEM_TypeMask 0xc1bf /* Mask of type bits */
22093
22094
22095 /* Whenever Mem contains a valid string or blob representation, one of
22096 ** the following flags must be set to determine the memory management
22097 ** policy for Mem.z. The MEM_Term flag tells us whether or not the
22098 ** string is \000 or \u0000 terminated
22099 */
22100 #define MEM_Term 0x0200 /* String in Mem.z is zero terminated */
22101 #define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
22102 #define MEM_Static 0x0800 /* Mem.z points to a static string */
22103 #define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
22104 #define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
22105 #define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */
22106 #define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */
22107 #ifdef SQLITE_OMIT_INCRBLOB
22108 #undef MEM_Zero
22109 #define MEM_Zero 0x0000
22110 #endif
 
22111
22112 /* Return TRUE if Mem X contains dynamically allocated content - anything
22113 ** that needs to be deallocated to avoid a leak.
22114 */
22115 #define VdbeMemDynamic(X) \
@@ -22127,15 +22364,19 @@
22127 #define MemNullNochng(X) \
22128 (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \
22129 && (X)->n==0 && (X)->u.nZero==0)
22130
22131 /*
22132 ** Return true if a memory cell is not marked as invalid. This macro
22133 ** is for use inside assert() statements only.
 
 
 
 
22134 */
22135 #ifdef SQLITE_DEBUG
22136 #define memIsValid(M) ((M)->flags & MEM_Undefined)==0
22137 #endif
22138
22139 /*
22140 ** Each auxiliary data pointer stored by a user defined function
22141 ** implementation calling sqlite3_set_auxdata() is stored in an instance
@@ -22169,10 +22410,11 @@
22169 FuncDef *pFunc; /* Pointer to function information */
22170 Mem *pMem; /* Memory cell used to store aggregate context */
22171 Vdbe *pVdbe; /* The VM that owns this context */
22172 int iOp; /* Instruction number of OP_Function */
22173 int isError; /* Error code returned by the function. */
 
22174 u8 skipFlag; /* Skip accumulator loading if true */
22175 u8 argc; /* Number of arguments */
22176 sqlite3_value *argv[1]; /* Argument set */
22177 };
22178
@@ -22217,11 +22459,10 @@
22217 struct Vdbe {
22218 sqlite3 *db; /* The database connection that owns this statement */
22219 Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
22220 Parse *pParse; /* Parsing context used to create this Vdbe */
22221 ynVar nVar; /* Number of entries in aVar[] */
22222 u32 iVdbeMagic; /* Magic number defining state of the SQL statement */
22223 int nMem; /* Number of memory locations currently allocated */
22224 int nCursor; /* Number of slots in apCsr[] */
22225 u32 cacheCtr; /* VdbeCursor row cache generation counter */
22226 int pc; /* The program counter */
22227 int rc; /* Value to return */
@@ -22256,10 +22497,11 @@
22256 u16 nResColumn; /* Number of columns in one row of the result set */
22257 u8 errorAction; /* Recovery action to do in case of an error */
22258 u8 minWriteFileFormat; /* Minimum file format for writable database files */
22259 u8 prepFlags; /* SQLITE_PREPARE_* flags */
22260 u8 doingRerun; /* True if rerunning after an auto-reprepare */
 
22261 bft expired:2; /* 1: recompile VM immediately 2: when convenient */
22262 bft explain:2; /* True if EXPLAIN present on SQL command */
22263 bft changeCntOn:1; /* True to update the change-counter */
22264 bft runOnlyOnce:1; /* Automatically expire on reset */
22265 bft usesStmtJournal:1; /* True if uses a statement journal */
@@ -22286,17 +22528,16 @@
22286 ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */
22287 #endif
22288 };
22289
22290 /*
22291 ** The following are allowed values for Vdbe.magic
22292 */
22293 #define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */
22294 #define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */
22295 #define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */
22296 #define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */
22297 #define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */
22298
22299 /*
22300 ** Structure used to store the context required by the
22301 ** sqlite3_preupdate_*() API functions.
22302 */
@@ -22315,18 +22556,36 @@
22315 Mem *aNew; /* Array of new.* values */
22316 Table *pTab; /* Schema object being upated */
22317 Index *pPk; /* PK index if pTab is WITHOUT ROWID */
22318 };
22319
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22320 /*
22321 ** Function prototypes
22322 */
22323 SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
22324 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
22325 void sqliteVdbePopStack(Vdbe*,int);
 
22326 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
22327 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, u32*);
22328 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
22329 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
22330 SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
22331 SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
22332 SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
@@ -22384,10 +22643,11 @@
22384 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
22385 SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8);
22386 SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
22387 SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
22388 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
 
22389 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
22390 #ifndef SQLITE_OMIT_WINDOWFUNC
22391 SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
22392 #endif
22393 #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
@@ -23351,12 +23611,14 @@
23351 ** The following routine implements the rough equivalent of localtime_r()
23352 ** using whatever operating-system specific localtime facility that
23353 ** is available. This routine returns 0 on success and
23354 ** non-zero on any kind of error.
23355 **
23356 ** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
23357 ** routine will always fail.
 
 
23358 **
23359 ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
23360 ** library function localtime_r() is used to assist in the calculation of
23361 ** local time.
23362 */
@@ -23368,20 +23630,34 @@
23368 sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
23369 #endif
23370 sqlite3_mutex_enter(mutex);
23371 pX = localtime(t);
23372 #ifndef SQLITE_UNTESTABLE
23373 if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
 
 
 
 
 
 
 
 
23374 #endif
23375 if( pX ) *pTm = *pX;
23376 #if SQLITE_THREADSAFE>0
23377 sqlite3_mutex_leave(mutex);
23378 #endif
23379 rc = pX==0;
23380 #else
23381 #ifndef SQLITE_UNTESTABLE
23382 if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
 
 
 
 
 
 
23383 #endif
23384 #if HAVE_LOCALTIME_R
23385 rc = localtime_r(t, pTm)==0;
23386 #else
23387 rc = localtime_s(pTm, t);
@@ -23392,71 +23668,60 @@
23392 #endif /* SQLITE_OMIT_LOCALTIME */
23393
23394
23395 #ifndef SQLITE_OMIT_LOCALTIME
23396 /*
23397 ** Compute the difference (in milliseconds) between localtime and UTC
23398 ** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
23399 ** return this value and set *pRc to SQLITE_OK.
23400 **
23401 ** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
23402 ** is undefined in this case.
23403 */
23404 static sqlite3_int64 localtimeOffset(
23405 DateTime *p, /* Date at which to calculate offset */
23406 sqlite3_context *pCtx, /* Write error here if one occurs */
23407 int *pRc /* OUT: Error code. SQLITE_OK or ERROR */
23408 ){
23409 DateTime x, y;
23410 time_t t;
23411 struct tm sLocal;
 
23412
23413 /* Initialize the contents of sLocal to avoid a compiler warning. */
23414 memset(&sLocal, 0, sizeof(sLocal));
23415
23416 x = *p;
23417 computeYMD_HMS(&x);
23418 if( x.Y<1971 || x.Y>=2038 ){
 
23419 /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
23420 ** works for years between 1970 and 2037. For dates outside this range,
23421 ** SQLite attempts to map the year into an equivalent year within this
23422 ** range, do the calculation, then map the year back.
23423 */
23424 x.Y = 2000;
23425 x.M = 1;
23426 x.D = 1;
23427 x.h = 0;
23428 x.m = 0;
23429 x.s = 0.0;
23430 } else {
23431 int s = (int)(x.s + 0.5);
23432 x.s = s;
23433 }
23434 x.tz = 0;
23435 x.validJD = 0;
23436 computeJD(&x);
23437 t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
23438 if( osLocaltime(&t, &sLocal) ){
23439 sqlite3_result_error(pCtx, "local time unavailable", -1);
23440 *pRc = SQLITE_ERROR;
23441 return 0;
23442 }
23443 y.Y = sLocal.tm_year + 1900;
23444 y.M = sLocal.tm_mon + 1;
23445 y.D = sLocal.tm_mday;
23446 y.h = sLocal.tm_hour;
23447 y.m = sLocal.tm_min;
23448 y.s = sLocal.tm_sec;
23449 y.validYMD = 1;
23450 y.validHMS = 1;
23451 y.validJD = 0;
23452 y.rawS = 0;
23453 y.validTZ = 0;
23454 y.isError = 0;
23455 computeJD(&y);
23456 *pRc = SQLITE_OK;
23457 return y.iJD - x.iJD;
23458 }
23459 #endif /* SQLITE_OMIT_LOCALTIME */
23460
23461 /*
23462 ** The following table defines various date transformations of the form
@@ -23524,11 +23789,13 @@
23524 if( sqlite3_stricmp(z, "auto")==0 ){
23525 if( idx>1 ) return 1; /* IMP: R-33611-57934 */
23526 if( !p->rawS || p->validJD ){
23527 rc = 0;
23528 p->rawS = 0;
23529 }else if( p->s>=-210866760000 && p->s<=253402300799 ){
 
 
23530 r = p->s*1000.0 + 210866760000000.0;
23531 clearYMD_HMS_TZ(p);
23532 p->iJD = (sqlite3_int64)(r + 0.5);
23533 p->validJD = 1;
23534 p->rawS = 0;
@@ -23545,11 +23812,11 @@
23545 ** is not the first modifier, or if the prior argument is not a numeric
23546 ** value in the allowed range of julian day numbers understood by
23547 ** SQLite (0..5373484.5) then the result will be NULL.
23548 */
23549 if( sqlite3_stricmp(z, "julianday")==0 ){
23550 if( idx>1 ) return 1;
23551 if( p->validJD && p->rawS ){
23552 rc = 0;
23553 p->rawS = 0;
23554 }
23555 }
@@ -23561,13 +23828,11 @@
23561 **
23562 ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
23563 ** show local time.
23564 */
23565 if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
23566 computeJD(p);
23567 p->iJD += localtimeOffset(p, pCtx, &rc);
23568 clearYMD_HMS_TZ(p);
23569 }
23570 break;
23571 }
23572 #endif
23573 case 'u': {
@@ -23576,10 +23841,11 @@
23576 **
23577 ** Treat the current value of p->s as the number of
23578 ** seconds since 1970. Convert to a real julian day number.
23579 */
23580 if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
 
23581 r = p->s*1000.0 + 210866760000000.0;
23582 if( r>=0.0 && r<464269060800000.0 ){
23583 clearYMD_HMS_TZ(p);
23584 p->iJD = (sqlite3_int64)(r + 0.5);
23585 p->validJD = 1;
@@ -23588,22 +23854,35 @@
23588 }
23589 }
23590 #ifndef SQLITE_OMIT_LOCALTIME
23591 else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
23592 if( p->tzSet==0 ){
23593 sqlite3_int64 c1;
 
 
 
 
23594 computeJD(p);
23595 c1 = localtimeOffset(p, pCtx, &rc);
23596 if( rc==SQLITE_OK ){
23597 p->iJD -= c1;
23598 clearYMD_HMS_TZ(p);
23599 p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
23600 }
 
 
 
 
 
 
 
 
 
 
23601 p->tzSet = 1;
23602 }else{
23603 rc = SQLITE_OK;
23604 }
 
23605 }
23606 #endif
23607 break;
23608 }
23609 case 'w': {
@@ -23849,15 +24128,42 @@
23849 int argc,
23850 sqlite3_value **argv
23851 ){
23852 DateTime x;
23853 if( isDate(context, argc, argv, &x)==0 ){
23854 char zBuf[100];
 
23855 computeYMD_HMS(&x);
23856 sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
23857 x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
23858 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23859 }
23860 }
23861
23862 /*
23863 ** time( TIMESTRING, MOD, MOD, ...)
@@ -23869,14 +24175,24 @@
23869 int argc,
23870 sqlite3_value **argv
23871 ){
23872 DateTime x;
23873 if( isDate(context, argc, argv, &x)==0 ){
23874 char zBuf[100];
 
23875 computeHMS(&x);
23876 sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
23877 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
 
 
 
 
 
 
 
 
 
23878 }
23879 }
23880
23881 /*
23882 ** date( TIMESTRING, MOD, MOD, ...)
@@ -23888,14 +24204,32 @@
23888 int argc,
23889 sqlite3_value **argv
23890 ){
23891 DateTime x;
23892 if( isDate(context, argc, argv, &x)==0 ){
23893 char zBuf[100];
 
23894 computeYMD(&x);
23895 sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
23896 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23897 }
23898 }
23899
23900 /*
23901 ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
@@ -26668,12 +27002,17 @@
26668 ** 32-bit signed integer. Hence the largest allocation is 0x40000000
26669 ** or 1073741824 bytes.
26670 */
26671 static int memsys5Roundup(int n){
26672 int iFullSz;
26673 if( n > 0x40000000 ) return 0;
26674 for(iFullSz=mem5.szAtom; iFullSz<n; iFullSz *= 2);
 
 
 
 
 
26675 return iFullSz;
26676 }
26677
26678 /*
26679 ** Return the ceiling of the logarithm base 2 of iValue.
@@ -29988,17 +30327,26 @@
29988 bufpt[j] = 0;
29989 length = j;
29990 goto adjust_width_for_utf8;
29991 }
29992 case etTOKEN: {
29993 Token *pToken;
29994 if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
29995 pToken = va_arg(ap, Token*);
29996 assert( bArgList==0 );
29997 if( pToken && pToken->n ){
29998 sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
29999 sqlite3RecordErrorByteOffset(pAccum->db, pToken->z);
 
 
 
 
 
 
 
 
 
 
30000 }
30001 length = width = 0;
30002 break;
30003 }
30004 case etSRCITEM: {
@@ -30072,10 +30420,22 @@
30072 zEnd = &zText[strlen(zText)];
30073 if( SQLITE_WITHIN(z,zText,zEnd) ){
30074 db->errByteOffset = (int)(z-zText);
30075 }
30076 }
 
 
 
 
 
 
 
 
 
 
 
 
30077
30078 /*
30079 ** Enlarge the memory allocation on a StrAccum object so that it is
30080 ** able to accept at least N more bytes of text.
30081 **
@@ -30535,11 +30895,11 @@
30535 memset(p, 0, sizeof(*p));
30536 }else{
30537 p->iLevel++;
30538 }
30539 assert( moreToFollow==0 || moreToFollow==1 );
30540 if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
30541 return p;
30542 }
30543
30544 /*
30545 ** Finished with one layer of the tree
@@ -30559,11 +30919,11 @@
30559 int i;
30560 StrAccum acc;
30561 char zBuf[500];
30562 sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
30563 if( p ){
30564 for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
30565 sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4);
30566 }
30567 sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
30568 }
30569 if( zFormat!=0 ){
@@ -30889,11 +31249,11 @@
30889 ** Generate a human-readable explanation for a Window Function object
30890 */
30891 SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
30892 pView = sqlite3TreeViewPush(pView, more);
30893 sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
30894 pWin->pFunc->zName, pWin->pFunc->nArg);
30895 sqlite3TreeViewWindow(pView, pWin, 0);
30896 sqlite3TreeViewPop(pView);
30897 }
30898 #endif /* SQLITE_OMIT_WINDOWFUNC */
30899
@@ -30914,11 +31274,11 @@
30914 StrAccum x;
30915 sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
30916 sqlite3_str_appendf(&x, " fg.af=%x.%c",
30917 pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
30918 if( ExprHasProperty(pExpr, EP_FromJoin) ){
30919 sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable);
30920 }
30921 if( ExprHasProperty(pExpr, EP_FromDDL) ){
30922 sqlite3_str_appendf(&x, " DDL");
30923 }
30924 if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -34282,46 +34642,46 @@
34282 SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
34283 static const char *const azName[] = {
34284 /* 0 */ "Savepoint" OpHelp(""),
34285 /* 1 */ "AutoCommit" OpHelp(""),
34286 /* 2 */ "Transaction" OpHelp(""),
34287 /* 3 */ "SorterNext" OpHelp(""),
34288 /* 4 */ "Prev" OpHelp(""),
34289 /* 5 */ "Next" OpHelp(""),
34290 /* 6 */ "Checkpoint" OpHelp(""),
34291 /* 7 */ "JournalMode" OpHelp(""),
34292 /* 8 */ "Vacuum" OpHelp(""),
34293 /* 9 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
34294 /* 10 */ "VUpdate" OpHelp("data=r[P3@P2]"),
34295 /* 11 */ "Goto" OpHelp(""),
34296 /* 12 */ "Gosub" OpHelp(""),
34297 /* 13 */ "InitCoroutine" OpHelp(""),
34298 /* 14 */ "Yield" OpHelp(""),
34299 /* 15 */ "MustBeInt" OpHelp(""),
34300 /* 16 */ "Jump" OpHelp(""),
34301 /* 17 */ "Once" OpHelp(""),
34302 /* 18 */ "If" OpHelp(""),
34303 /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
34304 /* 20 */ "IfNot" OpHelp(""),
34305 /* 21 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
34306 /* 22 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
34307 /* 23 */ "SeekLT" OpHelp("key=r[P3@P4]"),
34308 /* 24 */ "SeekLE" OpHelp("key=r[P3@P4]"),
34309 /* 25 */ "SeekGE" OpHelp("key=r[P3@P4]"),
34310 /* 26 */ "SeekGT" OpHelp("key=r[P3@P4]"),
34311 /* 27 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"),
34312 /* 28 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
34313 /* 29 */ "NoConflict" OpHelp("key=r[P3@P4]"),
34314 /* 30 */ "NotFound" OpHelp("key=r[P3@P4]"),
34315 /* 31 */ "Found" OpHelp("key=r[P3@P4]"),
34316 /* 32 */ "SeekRowid" OpHelp("intkey=r[P3]"),
34317 /* 33 */ "NotExists" OpHelp("intkey=r[P3]"),
34318 /* 34 */ "Last" OpHelp(""),
34319 /* 35 */ "IfSmaller" OpHelp(""),
34320 /* 36 */ "SorterSort" OpHelp(""),
34321 /* 37 */ "Sort" OpHelp(""),
34322 /* 38 */ "Rewind" OpHelp(""),
34323 /* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"),
34324 /* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"),
34325 /* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"),
34326 /* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"),
34327 /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
@@ -34350,41 +34710,41 @@
34350 /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
34351 /* 67 */ "Return" OpHelp(""),
34352 /* 68 */ "EndCoroutine" OpHelp(""),
34353 /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
34354 /* 70 */ "Halt" OpHelp(""),
34355 /* 71 */ "Integer" OpHelp("r[P2]=P1"),
34356 /* 72 */ "Int64" OpHelp("r[P2]=P4"),
34357 /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34358 /* 74 */ "Null" OpHelp("r[P2..P3]=NULL"),
34359 /* 75 */ "SoftNull" OpHelp("r[P1]=NULL"),
34360 /* 76 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34361 /* 77 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34362 /* 78 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
34363 /* 79 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
34364 /* 80 */ "SCopy" OpHelp("r[P2]=r[P1]"),
34365 /* 81 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
34366 /* 82 */ "FkCheck" OpHelp(""),
34367 /* 83 */ "ResultRow" OpHelp("output=r[P1@P2]"),
34368 /* 84 */ "CollSeq" OpHelp(""),
34369 /* 85 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
34370 /* 86 */ "RealAffinity" OpHelp(""),
34371 /* 87 */ "Cast" OpHelp("affinity(r[P1])"),
34372 /* 88 */ "Permutation" OpHelp(""),
34373 /* 89 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34374 /* 90 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34375 /* 91 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34376 /* 92 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34377 /* 93 */ "Column" OpHelp("r[P3]=PX"),
34378 /* 94 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34379 /* 95 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34380 /* 96 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34381 /* 97 */ "Count" OpHelp("r[P2]=count()"),
34382 /* 98 */ "ReadCookie" OpHelp(""),
34383 /* 99 */ "SetCookie" OpHelp(""),
34384 /* 100 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
34385 /* 101 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
34386 /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
34387 /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
34388 /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
34389 /* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
34390 /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
@@ -34391,82 +34751,84 @@
34391 /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
34392 /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
34393 /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
34394 /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
34395 /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
34396 /* 112 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
34397 /* 113 */ "OpenDup" OpHelp(""),
34398 /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
34399 /* 115 */ "OpenAutoindex" OpHelp("nColumn=P2"),
34400 /* 116 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34401 /* 117 */ "String8" OpHelp("r[P2]='P4'"),
34402 /* 118 */ "SorterOpen" OpHelp(""),
34403 /* 119 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34404 /* 120 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34405 /* 121 */ "Close" OpHelp(""),
34406 /* 122 */ "ColumnsUsed" OpHelp(""),
34407 /* 123 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34408 /* 124 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34409 /* 125 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34410 /* 126 */ "NewRowid" OpHelp("r[P2]=rowid"),
34411 /* 127 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34412 /* 128 */ "RowCell" OpHelp(""),
34413 /* 129 */ "Delete" OpHelp(""),
34414 /* 130 */ "ResetCount" OpHelp(""),
34415 /* 131 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34416 /* 132 */ "SorterData" OpHelp("r[P2]=data"),
34417 /* 133 */ "RowData" OpHelp("r[P2]=data"),
34418 /* 134 */ "Rowid" OpHelp("r[P2]=rowid"),
34419 /* 135 */ "NullRow" OpHelp(""),
34420 /* 136 */ "SeekEnd" OpHelp(""),
34421 /* 137 */ "IdxInsert" OpHelp("key=r[P2]"),
34422 /* 138 */ "SorterInsert" OpHelp("key=r[P2]"),
34423 /* 139 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34424 /* 140 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34425 /* 141 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34426 /* 142 */ "FinishSeek" OpHelp(""),
34427 /* 143 */ "Destroy" OpHelp(""),
34428 /* 144 */ "Clear" OpHelp(""),
34429 /* 145 */ "ResetSorter" OpHelp(""),
34430 /* 146 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34431 /* 147 */ "SqlExec" OpHelp(""),
34432 /* 148 */ "ParseSchema" OpHelp(""),
34433 /* 149 */ "LoadAnalysis" OpHelp(""),
34434 /* 150 */ "DropTable" OpHelp(""),
34435 /* 151 */ "DropIndex" OpHelp(""),
34436 /* 152 */ "DropTrigger" OpHelp(""),
34437 /* 153 */ "Real" OpHelp("r[P2]=P4"),
34438 /* 154 */ "IntegrityCk" OpHelp(""),
34439 /* 155 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34440 /* 156 */ "Param" OpHelp(""),
34441 /* 157 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34442 /* 158 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34443 /* 159 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34444 /* 160 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34445 /* 161 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34446 /* 162 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34447 /* 163 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34448 /* 164 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34449 /* 165 */ "Expire" OpHelp(""),
34450 /* 166 */ "CursorLock" OpHelp(""),
34451 /* 167 */ "CursorUnlock" OpHelp(""),
34452 /* 168 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34453 /* 169 */ "VBegin" OpHelp(""),
34454 /* 170 */ "VCreate" OpHelp(""),
34455 /* 171 */ "VDestroy" OpHelp(""),
34456 /* 172 */ "VOpen" OpHelp(""),
34457 /* 173 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34458 /* 174 */ "VRename" OpHelp(""),
34459 /* 175 */ "Pagecount" OpHelp(""),
34460 /* 176 */ "MaxPgcnt" OpHelp(""),
34461 /* 177 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
34462 /* 178 */ "Trace" OpHelp(""),
34463 /* 179 */ "CursorHint" OpHelp(""),
34464 /* 180 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34465 /* 181 */ "Noop" OpHelp(""),
34466 /* 182 */ "Explain" OpHelp(""),
34467 /* 183 */ "Abortable" OpHelp(""),
 
 
34468 };
34469 return azName[i];
34470 }
34471 #endif
34472
@@ -39382,15 +39744,21 @@
39382 int ofst, /* First lock to acquire or release */
39383 int n, /* Number of locks to acquire or release */
39384 int flags /* What to do with the lock */
39385 ){
39386 unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
39387 unixShm *p = pDbFd->pShm; /* The shared memory being locked */
39388 unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */
39389 int rc = SQLITE_OK; /* Result code */
39390 u16 mask; /* Mask of locks to take or release */
39391 int *aLock = pShmNode->aLock;
 
 
 
 
 
 
39392
39393 assert( pShmNode==pDbFd->pInode->pShmNode );
39394 assert( pShmNode->pInode==pDbFd->pInode );
39395 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
39396 assert( n>=1 );
@@ -40483,24 +40851,27 @@
40483 ** "<path to db>-journalNN"
40484 ** "<path to db>-walNN"
40485 **
40486 ** where NN is a decimal number. The NN naming schemes are
40487 ** used by the test_multiplex.c module.
 
 
 
 
 
 
40488 */
40489 nDb = sqlite3Strlen30(zPath) - 1;
40490 while( zPath[nDb]!='-' ){
40491 /* In normal operation, the journal file name will always contain
40492 ** a '-' character. However in 8+3 filename mode, or if a corrupt
40493 ** rollback journal specifies a super-journal with a goofy name, then
40494 ** the '-' might be missing. */
40495 if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
 
40496 nDb--;
40497 }
40498 memcpy(zDb, zPath, nDb);
40499 zDb[nDb] = '\0';
40500
40501 rc = getFileMode(zDb, pMode, pUid, pGid);
40502 }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
40503 *pMode = 0600;
40504 }else if( flags & SQLITE_OPEN_URI ){
40505 /* If this is a main database file and the file was opened using a URI
40506 ** filename, check for the "modeof" parameter. If present, interpret
@@ -46674,14 +47045,18 @@
46674 int flags /* What to do with the lock */
46675 ){
46676 winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */
46677 winShm *p = pDbFd->pShm; /* The shared memory being locked */
46678 winShm *pX; /* For looping over all siblings */
46679 winShmNode *pShmNode = p->pShmNode;
46680 int rc = SQLITE_OK; /* Result code */
46681 u16 mask; /* Mask of locks to take or release */
46682
 
 
 
 
46683 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
46684 assert( n>=1 );
46685 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
46686 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
46687 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
@@ -53576,10 +53951,11 @@
53576 u16 nExtra; /* Add this many bytes to each in-memory page */
53577 i16 nReserve; /* Number of unused bytes at end of each page */
53578 u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
53579 u32 sectorSize; /* Assumed sector size during rollback */
53580 Pgno mxPgno; /* Maximum allowed size of the database */
 
53581 i64 pageSize; /* Number of bytes in a page */
53582 i64 journalSizeLimit; /* Size limit for persistent journal files */
53583 char *zFilename; /* Name of the database file */
53584 char *zJournal; /* Name of the journal file */
53585 int (*xBusyHandler)(void*); /* Function to call when busy */
@@ -54562,11 +54938,11 @@
54562 ** pPager at the current location. The super-journal name must be the last
54563 ** thing written to a journal file. If the pager is in full-sync mode, the
54564 ** journal file descriptor is advanced to the next sector boundary before
54565 ** anything is written. The format is:
54566 **
54567 ** + 4 bytes: PAGER_MJ_PGNO.
54568 ** + N bytes: super-journal filename in utf-8.
54569 ** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator).
54570 ** + 4 bytes: super-journal name checksum.
54571 ** + 8 bytes: aJournalMagic[].
54572 **
@@ -54610,11 +54986,11 @@
54610 iHdrOff = pPager->journalOff;
54611
54612 /* Write the super-journal data to the end of the journal file. If
54613 ** an error occurs, return the error code to the caller.
54614 */
54615 if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
54616 || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4)))
54617 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper)))
54618 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum)))
54619 || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8,
54620 iHdrOff+4+nSuper+8)))
@@ -55120,11 +55496,11 @@
55120 ** to the database file, then the IO error code is returned. If data
55121 ** is successfully read from the (sub-)journal file but appears to be
55122 ** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
55123 ** two circumstances:
55124 **
55125 ** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
55126 ** * If the record is being rolled back from the main journal file
55127 ** and the checksum field does not match the record content.
55128 **
55129 ** Neither of these two scenarios are possible during a savepoint rollback.
55130 **
@@ -55180,11 +55556,11 @@
55180 /* Sanity checking on the page. This is more important that I originally
55181 ** thought. If a power failure occurs while the journal is being written,
55182 ** it could cause invalid data to be written into the journal. We need to
55183 ** detect this invalid data (with high probability) and ignore it.
55184 */
55185 if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
55186 assert( !isSavepnt );
55187 return SQLITE_DONE;
55188 }
55189 if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
55190 return SQLITE_OK;
@@ -55739,10 +56115,13 @@
55739 rc = pager_truncate(pPager, mxPg);
55740 if( rc!=SQLITE_OK ){
55741 goto end_playback;
55742 }
55743 pPager->dbSize = mxPg;
 
 
 
55744 }
55745
55746 /* Copy original pages out of the journal and back into the
55747 ** database file and/or page cache.
55748 */
@@ -56635,10 +57014,11 @@
56635 if( rc==SQLITE_OK ){
56636 sqlite3PageFree(pPager->pTmpSpace);
56637 pPager->pTmpSpace = pNew;
56638 pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
56639 pPager->pageSize = pageSize;
 
56640 }else{
56641 sqlite3PageFree(pNew);
56642 }
56643 }
56644
@@ -56840,11 +57220,11 @@
56840 ** Once this function has been called, the transaction must either be
56841 ** rolled back or committed. It is not safe to call this function and
56842 ** then continue writing to the database.
56843 */
56844 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
56845 assert( pPager->dbSize>=nPage );
56846 assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
56847 pPager->dbSize = nPage;
56848
56849 /* At one point the code here called assertTruncateConstraint() to
56850 ** ensure that all pages being truncated away by this operation are,
@@ -58404,11 +58784,11 @@
58404
58405 noContent = (flags & PAGER_GET_NOCONTENT)!=0;
58406 if( pPg->pPager && !noContent ){
58407 /* In this case the pcache already contains an initialized copy of
58408 ** the page. Return without further ado. */
58409 assert( pgno!=PAGER_MJ_PGNO(pPager) );
58410 pPager->aStat[PAGER_STAT_HIT]++;
58411 return SQLITE_OK;
58412
58413 }else{
58414 /* The pager cache has created a new page. Its content needs to
@@ -58415,11 +58795,11 @@
58415 ** be initialized. But first some error checks:
58416 **
58417 ** (*) obsolete. Was: maximum page number is 2^31
58418 ** (2) Never try to fetch the locking page
58419 */
58420 if( pgno==PAGER_MJ_PGNO(pPager) ){
58421 rc = SQLITE_CORRUPT_BKPT;
58422 goto pager_acquire_err;
58423 }
58424
58425 pPg->pPager = pPager;
@@ -58814,11 +59194,11 @@
58814 i64 iOff = pPager->journalOff;
58815
58816 /* We should never write to the journal file the page that
58817 ** contains the database locks. The following assert verifies
58818 ** that we do not. */
58819 assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
58820
58821 assert( pPager->journalHdr<=pPager->journalOff );
58822 pData2 = pPg->pData;
58823 cksum = pager_cksum(pPager, (u8*)pData2);
58824
@@ -58993,11 +59373,11 @@
58993
58994 for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
58995 Pgno pg = pg1+ii;
58996 PgHdr *pPage;
58997 if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
58998 if( pg!=PAGER_MJ_PGNO(pPager) ){
58999 rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
59000 if( rc==SQLITE_OK ){
59001 rc = pager_write(pPage);
59002 if( pPage->flags&PGHDR_NEED_SYNC ){
59003 needSync = 1;
@@ -59471,11 +59851,11 @@
59471 ** image was extended as part of the current transaction and then the
59472 ** last page in the db image moved to the free-list. In this case the
59473 ** last page is never written out to disk, leaving the database file
59474 ** undersized. Fix this now if it is the case. */
59475 if( pPager->dbSize>pPager->dbFileSize ){
59476 Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
59477 assert( pPager->eState==PAGER_WRITER_DBMOD );
59478 rc = pager_truncate(pPager, nNew);
59479 if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
59480 }
59481
@@ -60320,10 +60700,22 @@
60320 int eMode, /* Type of checkpoint */
60321 int *pnLog, /* OUT: Final number of frames in log */
60322 int *pnCkpt /* OUT: Final number of checkpointed frames */
60323 ){
60324 int rc = SQLITE_OK;
 
 
 
 
 
 
 
 
 
 
 
 
60325 if( pPager->pWal ){
60326 rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
60327 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
60328 pPager->pBusyHandlerArg,
60329 pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
@@ -65086,11 +65478,13 @@
65086 u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th
65087 ** non-overflow cell */
65088 u8 *apOvfl[4]; /* Pointers to the body of overflow cells */
65089 BtShared *pBt; /* Pointer to BtShared that this page is part of */
65090 u8 *aData; /* Pointer to disk image of the page data */
65091 u8 *aDataEnd; /* One byte past the end of usable data */
 
 
65092 u8 *aCellIdx; /* The cell index area */
65093 u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */
65094 DbPage *pDbPage; /* Pager page handle */
65095 u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
65096 void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
@@ -65391,11 +65785,11 @@
65391 #define CURSOR_FAULT 4
65392
65393 /*
65394 ** The database page the PENDING_BYTE occupies. This page is never used.
65395 */
65396 # define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
65397
65398 /*
65399 ** These macros define the location of the pointer-map entry for a
65400 ** database page. The first argument to each is the number of usable
65401 ** bytes on each page of the database (often 1024). The second is the
@@ -66032,11 +66426,11 @@
66032 if( isIndex ){
66033 HashElem *p;
66034 int bSeen = 0;
66035 for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
66036 Index *pIdx = (Index *)sqliteHashData(p);
66037 if( pIdx->tnum==(int)iRoot ){
66038 if( bSeen ){
66039 /* Two or more indexes share the same root page. There must
66040 ** be imposter tables. So just return true. The assert is not
66041 ** useful in that case. */
66042 return 1;
@@ -66625,11 +67019,11 @@
66625 }
66626
66627 /*
66628 ** In this version of BtreeMoveto, pKey is a packed index record
66629 ** such as is generated by the OP_MakeRecord opcode. Unpack the
66630 ** record and then call BtreeMovetoUnpacked() to do the work.
66631 */
66632 static int btreeMoveto(
66633 BtCursor *pCur, /* Cursor open on the btree to be searched */
66634 const void *pKey, /* Packed key if the btree is an index */
66635 i64 nKey, /* Integer key for tables. Size of pKey for indices */
@@ -67145,10 +67539,11 @@
67145 ** data area of the btree-page. The return number includes the cell
67146 ** data header and the local payload, but not any overflow page or
67147 ** the space used by the cell pointer.
67148 **
67149 ** cellSizePtrNoPayload() => table internal nodes
 
67150 ** cellSizePtr() => all index nodes & table leaf nodes
67151 */
67152 static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
67153 u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
67154 u8 *pEnd; /* End mark for a varint */
@@ -67170,17 +67565,10 @@
67170 do{
67171 nSize = (nSize<<7) | (*++pIter & 0x7f);
67172 }while( *(pIter)>=0x80 && pIter<pEnd );
67173 }
67174 pIter++;
67175 if( pPage->intKey ){
67176 /* pIter now points at the 64-bit integer key value, a variable length
67177 ** integer. The following block moves pIter to point at the first byte
67178 ** past the end of the key value. */
67179 pEnd = &pIter[9];
67180 while( (*pIter++)&0x80 && pIter<pEnd );
67181 }
67182 testcase( nSize==pPage->maxLocal );
67183 testcase( nSize==(u32)pPage->maxLocal+1 );
67184 if( nSize<=pPage->maxLocal ){
67185 nSize += (u32)(pIter - pCell);
67186 if( nSize<4 ) nSize = 4;
@@ -67216,10 +67604,62 @@
67216 pEnd = pIter + 9;
67217 while( (*pIter++)&0x80 && pIter<pEnd );
67218 assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB );
67219 return (u16)(pIter - pCell);
67220 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67221
67222
67223 #ifdef SQLITE_DEBUG
67224 /* This variation on cellSizePtr() is used inside of assert() statements
67225 ** only. */
@@ -67229,11 +67669,11 @@
67229 #endif
67230
67231 #ifndef SQLITE_OMIT_AUTOVACUUM
67232 /*
67233 ** The cell pCell is currently part of page pSrc but will ultimately be part
67234 ** of pPage. (pSrc and pPager are often the same.) If pCell contains a
67235 ** pointer to an overflow page, insert an entry into the pointer-map for
67236 ** the overflow page that will be valid after pCell has been moved to pPage.
67237 */
67238 static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
67239 CellInfo info;
@@ -67404,21 +67844,23 @@
67404 */
67405 static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
67406 const int hdr = pPg->hdrOffset; /* Offset to page header */
67407 u8 * const aData = pPg->aData; /* Page data */
67408 int iAddr = hdr + 1; /* Address of ptr to pc */
67409 int pc = get2byte(&aData[iAddr]); /* Address of a free slot */
 
67410 int x; /* Excess size of the slot */
67411 int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */
67412 int size; /* Size of the free slot */
67413
67414 assert( pc>0 );
67415 while( pc<=maxPC ){
67416 /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
67417 ** freeblock form a big-endian integer which is the size of the freeblock
67418 ** in bytes, including the 4-byte header. */
67419 size = get2byte(&aData[pc+2]);
 
67420 if( (x = size - nByte)>=0 ){
67421 testcase( x==4 );
67422 testcase( x==3 );
67423 if( x<4 ){
67424 /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
@@ -67439,11 +67881,12 @@
67439 put2byte(&aData[pc+2], x);
67440 }
67441 return &aData[pc + x];
67442 }
67443 iAddr = pc;
67444 pc = get2byte(&aData[pc]);
 
67445 if( pc<=iAddr+size ){
67446 if( pc ){
67447 /* The next slot in the chain is not past the end of the current slot */
67448 *pRc = SQLITE_CORRUPT_PAGE(pPg);
67449 }
@@ -67473,10 +67916,11 @@
67473 static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
67474 const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
67475 u8 * const data = pPage->aData; /* Local cache of pPage->aData */
67476 int top; /* First byte of cell content area */
67477 int rc = SQLITE_OK; /* Integer return code */
 
67478 int gap; /* First byte of gap between cell pointers and cell content */
67479
67480 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
67481 assert( pPage->pBt );
67482 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
@@ -67491,11 +67935,12 @@
67491 /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
67492 ** and the reserved space is zero (the usual value for reserved space)
67493 ** then the cell content offset of an empty page wants to be 65536.
67494 ** However, that integer is too large to be stored in a 2-byte unsigned
67495 ** integer, so a value of 0 is used in its place. */
67496 top = get2byte(&data[hdr+5]);
 
67497 assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
67498 if( gap>top ){
67499 if( top==0 && pPage->pBt->usableSize==65536 ){
67500 top = 65536;
67501 }else{
@@ -67573,10 +68018,11 @@
67573 u8 nFrag = 0; /* Reduction in fragmentation */
67574 u16 iOrigSize = iSize; /* Original value of iSize */
67575 u16 x; /* Offset to cell content area */
67576 u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
67577 unsigned char *data = pPage->aData; /* Page content */
 
67578
67579 assert( pPage->pBt!=0 );
67580 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
67581 assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
67582 assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
@@ -67600,11 +68046,11 @@
67600 iPtr = iFreeBlk;
67601 }
67602 if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
67603 return SQLITE_CORRUPT_PAGE(pPage);
67604 }
67605 assert( iFreeBlk>iPtr || iFreeBlk==0 );
67606
67607 /* At this point:
67608 ** iFreeBlk: First freeblock after iStart, or zero if none
67609 ** iPtr: The address of a pointer to iFreeBlk
67610 **
@@ -67635,11 +68081,12 @@
67635 }
67636 }
67637 if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
67638 data[hdr+7] -= nFrag;
67639 }
67640 x = get2byte(&data[hdr+5]);
 
67641 if( iStart<=x ){
67642 /* The new freeblock is at the beginning of the cell content area,
67643 ** so just extend the cell content area rather than create another
67644 ** freelist entry */
67645 if( iStart<x ) return SQLITE_CORRUPT_PAGE(pPage);
@@ -67679,11 +68126,10 @@
67679 assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
67680 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
67681 pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 );
67682 flagByte &= ~PTF_LEAF;
67683 pPage->childPtrSize = 4-4*pPage->leaf;
67684 pPage->xCellSize = cellSizePtr;
67685 pBt = pPage->pBt;
67686 if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
67687 /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
67688 ** interior table b-tree page. */
67689 assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
@@ -67691,10 +68137,11 @@
67691 ** leaf table b-tree page. */
67692 assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
67693 pPage->intKey = 1;
67694 if( pPage->leaf ){
67695 pPage->intKeyLeaf = 1;
 
67696 pPage->xParseCell = btreeParseCellPtr;
67697 }else{
67698 pPage->intKeyLeaf = 0;
67699 pPage->xCellSize = cellSizePtrNoPayload;
67700 pPage->xParseCell = btreeParseCellPtrNoPayload;
@@ -67708,16 +68155,21 @@
67708 /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
67709 ** leaf index b-tree page. */
67710 assert( (PTF_ZERODATA|PTF_LEAF)==10 );
67711 pPage->intKey = 0;
67712 pPage->intKeyLeaf = 0;
 
67713 pPage->xParseCell = btreeParseCellPtrIndex;
67714 pPage->maxLocal = pBt->maxLocal;
67715 pPage->minLocal = pBt->minLocal;
67716 }else{
67717 /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
67718 ** an error. */
 
 
 
 
67719 return SQLITE_CORRUPT_PAGE(pPage);
67720 }
67721 pPage->max1bytePayload = pBt->max1bytePayload;
67722 return SQLITE_OK;
67723 }
@@ -67871,11 +68323,11 @@
67871 assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
67872 pPage->maskPage = (u16)(pBt->pageSize - 1);
67873 pPage->nOverflow = 0;
67874 pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize;
67875 pPage->aCellIdx = data + pPage->childPtrSize + 8;
67876 pPage->aDataEnd = pPage->aData + pBt->usableSize;
67877 pPage->aDataOfst = pPage->aData + pPage->childPtrSize;
67878 /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
67879 ** number of cells on the page. */
67880 pPage->nCell = get2byte(&data[3]);
67881 if( pPage->nCell>MX_CELL(pBt) ){
@@ -67906,11 +68358,11 @@
67906 unsigned char *data = pPage->aData;
67907 BtShared *pBt = pPage->pBt;
67908 u8 hdr = pPage->hdrOffset;
67909 u16 first;
67910
67911 assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
67912 assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
67913 assert( sqlite3PagerGetData(pPage->pDbPage) == data );
67914 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
67915 assert( sqlite3_mutex_held(pBt->mutex) );
67916 if( pBt->btsFlags & BTS_FAST_SECURE ){
@@ -67922,11 +68374,11 @@
67922 data[hdr+7] = 0;
67923 put2byte(&data[hdr+5], pBt->usableSize);
67924 pPage->nFree = (u16)(pBt->usableSize - first);
67925 decodeFlags(pPage, flags);
67926 pPage->cellOffset = first;
67927 pPage->aDataEnd = &data[pBt->usableSize];
67928 pPage->aCellIdx = &data[first];
67929 pPage->aDataOfst = &data[pPage->childPtrSize];
67930 pPage->nOverflow = 0;
67931 assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
67932 pPage->maskPage = (u16)(pBt->pageSize - 1);
@@ -68048,11 +68500,11 @@
68048 rc = btreeInitPage(*ppPage);
68049 if( rc!=SQLITE_OK ){
68050 goto getAndInitPage_error2;
68051 }
68052 }
68053 assert( (*ppPage)->pgno==pgno );
68054 assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
68055
68056 /* If obtaining a child page for a cursor, we must verify that the page is
68057 ** compatible with the root page. */
68058 if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
@@ -68067,11 +68519,13 @@
68067 if( pCur ){
68068 pCur->iPage--;
68069 pCur->pPage = pCur->apPage[pCur->iPage];
68070 }
68071 testcase( pgno==0 );
68072 assert( pgno!=0 || rc==SQLITE_CORRUPT );
 
 
68073 return rc;
68074 }
68075
68076 /*
68077 ** Release a MemPage. This should be called once for each prior
@@ -71135,11 +71589,11 @@
71135 }
71136 pCur->iPage = 0;
71137 pCur->curIntKey = pCur->pPage->intKey;
71138 }
71139 pRoot = pCur->pPage;
71140 assert( pRoot->pgno==pCur->pgnoRoot );
71141
71142 /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
71143 ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
71144 ** NULL, the caller expects a table b-tree. If this is not the case,
71145 ** return an SQLITE_CORRUPT error.
@@ -71455,10 +71909,73 @@
71455 moveto_table_finish:
71456 pCur->info.nSize = 0;
71457 assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
71458 return rc;
71459 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71460
71461 /* Move the cursor so that it points to an entry in an index table
71462 ** near the key pIdxKey. Return a success code.
71463 **
71464 ** If an exact match is not found, then the cursor is always
@@ -71506,25 +72023,61 @@
71506 assert( pIdxKey->default_rc==1
71507 || pIdxKey->default_rc==0
71508 || pIdxKey->default_rc==-1
71509 );
71510
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71511 rc = moveToRoot(pCur);
71512 if( rc ){
71513 if( rc==SQLITE_EMPTY ){
71514 assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
71515 *pRes = -1;
71516 return SQLITE_OK;
71517 }
71518 return rc;
71519 }
 
 
71520 assert( pCur->pPage );
71521 assert( pCur->pPage->isInit );
71522 assert( pCur->eState==CURSOR_VALID );
71523 assert( pCur->pPage->nCell > 0 );
71524 assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey );
71525 assert( pCur->curIntKey || pIdxKey );
71526 for(;;){
71527 int lwr, upr, idx, c;
71528 Pgno chldPg;
71529 MemPage *pPage = pCur->pPage;
71530 u8 *pCell; /* Pointer to current cell in pPage */
@@ -71534,11 +72087,11 @@
71534 ** not run. If this is not the root-page, then the moveToChild() routine
71535 ** would have already detected db corruption. Similarly, pPage must
71536 ** be the right kind (index or table) of b-tree page. Otherwise
71537 ** a moveToChild() or moveToRoot() call would have detected corruption. */
71538 assert( pPage->nCell>0 );
71539 assert( pPage->intKey==(pIdxKey==0) );
71540 lwr = 0;
71541 upr = pPage->nCell-1;
71542 idx = upr>>1; /* idx = (lwr+upr)/2; */
71543 for(;;){
71544 int nCell; /* Size of the pCell cell in bytes */
@@ -72229,11 +72782,11 @@
72229
72230 assert( sqlite3_mutex_held(pBt->mutex) );
72231 assert( CORRUPT_DB || iPage>1 );
72232 assert( !pMemPage || pMemPage->pgno==iPage );
72233
72234 if( NEVER(iPage<2) || iPage>pBt->nPage ){
72235 return SQLITE_CORRUPT_BKPT;
72236 }
72237 if( pMemPage ){
72238 pPage = pMemPage;
72239 sqlite3PagerRef(pPage->pDbPage);
@@ -72664,10 +73217,16 @@
72664 data = pPage->aData;
72665 ptr = &pPage->aCellIdx[2*idx];
72666 assert( pPage->pBt->usableSize > (u32)(ptr-data) );
72667 pc = get2byte(ptr);
72668 hdr = pPage->hdrOffset;
 
 
 
 
 
 
72669 testcase( pc==(u32)get2byte(&data[hdr+5]) );
72670 testcase( pc+sz==pPage->pBt->usableSize );
72671 if( pc+sz > pPage->pBt->usableSize ){
72672 *pRC = SQLITE_CORRUPT_BKPT;
72673 return;
@@ -74395,11 +74954,10 @@
74395 ** balance_deeper()
74396 ** balance_nonroot()
74397 */
74398 static int balance(BtCursor *pCur){
74399 int rc = SQLITE_OK;
74400 const int nMin = pCur->pBt->usableSize * 2 / 3;
74401 u8 aBalanceQuickSpace[13];
74402 u8 *pFree = 0;
74403
74404 VVA_ONLY( int balance_quick_called = 0 );
74405 VVA_ONLY( int balance_deeper_called = 0 );
@@ -74407,11 +74965,15 @@
74407 do {
74408 int iPage;
74409 MemPage *pPage = pCur->pPage;
74410
74411 if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
74412 if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
 
 
 
 
74413 break;
74414 }else if( (iPage = pCur->iPage)==0 ){
74415 if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){
74416 /* The root page of the b-tree is overfull. In this case call the
74417 ** balance_deeper() function to create a new child for the root-page
@@ -74627,11 +75189,11 @@
74627 ** For an index btree (used for indexes and WITHOUT ROWID tables), the
74628 ** key is an arbitrary byte sequence stored in pX.pKey,nKey. The
74629 ** pX.pData,nData,nZero fields must be zero.
74630 **
74631 ** If the seekResult parameter is non-zero, then a successful call to
74632 ** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already
74633 ** been performed. In other words, if seekResult!=0 then the cursor
74634 ** is currently pointing to a cell that will be adjacent to the cell
74635 ** to be inserted. If seekResult<0 then pCur points to a cell that is
74636 ** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell
74637 ** that is larger than (pKey,nKey).
@@ -74645,11 +75207,11 @@
74645 */
74646 SQLITE_PRIVATE int sqlite3BtreeInsert(
74647 BtCursor *pCur, /* Insert data into the table of this cursor */
74648 const BtreePayload *pX, /* Content of the row to be inserted */
74649 int flags, /* True if this is likely an append */
74650 int seekResult /* Result of prior MovetoUnpacked() call */
74651 ){
74652 int rc;
74653 int loc = seekResult; /* -1: before desired location +1: after */
74654 int szNew = 0;
74655 int idx;
@@ -74660,28 +75222,10 @@
74660 unsigned char *newCell = 0;
74661
74662 assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
74663 assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 );
74664
74665 if( pCur->eState==CURSOR_FAULT ){
74666 assert( pCur->skipNext!=SQLITE_OK );
74667 return pCur->skipNext;
74668 }
74669
74670 assert( cursorOwnsBtShared(pCur) );
74671 assert( (pCur->curFlags & BTCF_WriteFlag)!=0
74672 && pBt->inTransaction==TRANS_WRITE
74673 && (pBt->btsFlags & BTS_READ_ONLY)==0 );
74674 assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
74675
74676 /* Assert that the caller has been consistent. If this cursor was opened
74677 ** expecting an index b-tree, then the caller should be inserting blob
74678 ** keys with no associated data. If the cursor was opened expecting an
74679 ** intkey table, the caller should be inserting integer keys with a
74680 ** blob of associated data. */
74681 assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
74682
74683 /* Save the positions of any other cursors open on this table.
74684 **
74685 ** In some cases, the call to btreeMoveto() below is a no-op. For
74686 ** example, when inserting data into a table with auto-generated integer
74687 ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
@@ -74702,10 +75246,33 @@
74702 ** set the flag, load the schema, and then unset the flag. */
74703 return SQLITE_CORRUPT_BKPT;
74704 }
74705 }
74706
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74707 if( pCur->pKeyInfo==0 ){
74708 assert( pX->pKey==0 );
74709 /* If this is an insert into a table b-tree, invalidate any incrblob
74710 ** cursors open on the row being replaced */
74711 if( p->hasIncrblobCur ){
@@ -74790,18 +75357,18 @@
74790 return btreeOverwriteCell(pCur, &x2);
74791 }
74792 }
74793 }
74794 assert( pCur->eState==CURSOR_VALID
74795 || (pCur->eState==CURSOR_INVALID && loc)
74796 || CORRUPT_DB );
74797
74798 pPage = pCur->pPage;
74799 assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
74800 assert( pPage->leaf || !pPage->intKey );
74801 if( pPage->nFree<0 ){
74802 if( NEVER(pCur->eState>CURSOR_INVALID) ){
 
74803 rc = SQLITE_CORRUPT_BKPT;
74804 }else{
74805 rc = btreeComputeFreeSpace(pPage);
74806 }
74807 if( rc ) return rc;
@@ -75078,16 +75645,20 @@
75078 assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
75079 assert( pCur->curFlags & BTCF_WriteFlag );
75080 assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
75081 assert( !hasReadConflicts(p, pCur->pgnoRoot) );
75082 assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
75083 if( pCur->eState==CURSOR_REQUIRESEEK ){
75084 rc = btreeRestoreCursorPosition(pCur);
75085 assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
75086 if( rc || pCur->eState!=CURSOR_VALID ) return rc;
 
 
 
 
75087 }
75088 assert( CORRUPT_DB || pCur->eState==CURSOR_VALID );
75089
75090 iCellDepth = pCur->iPage;
75091 iCellIdx = pCur->ix;
75092 pPage = pCur->pPage;
75093 if( pPage->nCell<=iCellIdx ){
@@ -75115,11 +75686,12 @@
75115 ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT.
75116 */
75117 bPreserve = (flags & BTREE_SAVEPOSITION)!=0;
75118 if( bPreserve ){
75119 if( !pPage->leaf
75120 || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
 
75121 || pPage->nCell==1 /* See dbfuzz001.test for a test case */
75122 ){
75123 /* A b-tree rebalance will be required after deleting this entry.
75124 ** Save the cursor key. */
75125 rc = saveCursorKey(pCur);
@@ -75211,11 +75783,19 @@
75211 ** on the leaf node first. If the balance proceeds far enough up the
75212 ** tree that we can be sure that any problem in the internal node has
75213 ** been corrected, so be it. Otherwise, after balancing the leaf node,
75214 ** walk the cursor up the tree to the internal node and balance it as
75215 ** well. */
75216 rc = balance(pCur);
 
 
 
 
 
 
 
 
75217 if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
75218 releasePageNotNull(pCur->pPage);
75219 pCur->iPage--;
75220 while( pCur->iPage>iCellDepth ){
75221 releasePage(pCur->apPage[pCur->iPage--]);
@@ -75434,11 +76014,11 @@
75434 return SQLITE_CORRUPT_BKPT;
75435 }
75436 rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
75437 if( rc ) return rc;
75438 if( (pBt->openFlags & BTREE_SINGLE)==0
75439 && sqlite3PagerPageRefcount(pPage->pDbPage)!=1
75440 ){
75441 rc = SQLITE_CORRUPT_BKPT;
75442 goto cleardatabasepage_out;
75443 }
75444 hdr = pPage->hdrOffset;
@@ -76814,11 +77394,11 @@
76814 int i = sqlite3FindDbName(pDb, zDb);
76815
76816 if( i==1 ){
76817 Parse sParse;
76818 int rc = 0;
76819 sqlite3ParseObjectInit(&sParse,pErrorDb);
76820 if( sqlite3OpenTempDatabase(&sParse) ){
76821 sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
76822 rc = SQLITE_ERROR;
76823 }
76824 sqlite3DbFree(pErrorDb, sParse.zErrMsg);
@@ -77706,11 +78286,15 @@
77706 #endif
77707 assert( pMem!=0 );
77708 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77709 assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
77710 || desiredEnc==SQLITE_UTF16BE );
77711 if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
 
 
 
 
77712 return SQLITE_OK;
77713 }
77714 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77715 #ifdef SQLITE_OMIT_UTF16
77716 return SQLITE_ERROR;
@@ -77965,10 +78549,11 @@
77965 t.flags = MEM_Null;
77966 t.db = pMem->db;
77967 ctx.pOut = &t;
77968 ctx.pMem = pMem;
77969 ctx.pFunc = pFunc;
 
77970 pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
77971 assert( (pMem->flags & MEM_Dyn)==0 );
77972 if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
77973 memcpy(pMem, &t, sizeof(t));
77974 return ctx.isError;
@@ -77992,10 +78577,11 @@
77992 memset(&ctx, 0, sizeof(ctx));
77993 sqlite3VdbeMemSetNull(pOut);
77994 ctx.pOut = pOut;
77995 ctx.pMem = pAccum;
77996 ctx.pFunc = pFunc;
 
77997 pFunc->xValue(&ctx);
77998 return ctx.isError;
77999 }
78000 #endif /* SQLITE_OMIT_WINDOWFUNC */
78001
@@ -78056,10 +78642,18 @@
78056 assert( sqlite3VdbeCheckMemInvariants(p) );
78057 if( VdbeMemDynamic(p) || p->szMalloc ){
78058 vdbeMemClear(p);
78059 }
78060 }
 
 
 
 
 
 
 
 
78061
78062 /*
78063 ** Convert a 64-bit IEEE double into a 64-bit signed integer.
78064 ** If the double is out of range of a 64-bit signed integer then
78065 ** return the closest available 64-bit signed integer.
@@ -78418,10 +79012,11 @@
78418 void *pPtr,
78419 const char *zPType,
78420 void (*xDestructor)(void*)
78421 ){
78422 assert( pMem->flags==MEM_Null );
 
78423 pMem->u.zPType = zPType ? zPType : "";
78424 pMem->z = pPtr;
78425 pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
78426 pMem->eSubtype = 'p';
78427 pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
@@ -78600,10 +79195,17 @@
78600 ** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH
78601 ** size limit) then no memory allocation occurs. If the string can be
78602 ** stored without allocating memory, then it is. If a memory allocation
78603 ** is required to store the string, then value of pMem is unchanged. In
78604 ** either case, SQLITE_TOOBIG is returned.
 
 
 
 
 
 
 
78605 */
78606 SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
78607 Mem *pMem, /* Memory cell to set to string value */
78608 const char *z, /* String pointer */
78609 i64 n, /* Bytes in string, or negative */
@@ -78610,15 +79212,16 @@
78610 u8 enc, /* Encoding of z. 0 for BLOBs */
78611 void (*xDel)(void*) /* Destructor function */
78612 ){
78613 i64 nByte = n; /* New value for pMem->n */
78614 int iLimit; /* Maximum allowed string or blob size */
78615 u16 flags = 0; /* New value for pMem->flags */
78616
78617 assert( pMem!=0 );
78618 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
78619 assert( !sqlite3VdbeMemIsRowSet(pMem) );
 
78620
78621 /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
78622 if( !z ){
78623 sqlite3VdbeMemSetNull(pMem);
78624 return SQLITE_OK;
@@ -78627,19 +79230,34 @@
78627 if( pMem->db ){
78628 iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH];
78629 }else{
78630 iLimit = SQLITE_MAX_LENGTH;
78631 }
78632 flags = (enc==0?MEM_Blob:MEM_Str);
78633 if( nByte<0 ){
78634 assert( enc!=0 );
78635 if( enc==SQLITE_UTF8 ){
78636 nByte = strlen(z);
78637 }else{
78638 for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
78639 }
78640 flags |= MEM_Term;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78641 }
78642
78643 /* The following block sets the new values of Mem.z and Mem.xDel. It
78644 ** also sets a flag in local variable "flags" to indicate the memory
78645 ** management (one of MEM_Dyn or MEM_Static).
@@ -78647,13 +79265,10 @@
78647 if( xDel==SQLITE_TRANSIENT ){
78648 i64 nAlloc = nByte;
78649 if( flags&MEM_Term ){
78650 nAlloc += (enc==SQLITE_UTF8?1:2);
78651 }
78652 if( nByte>iLimit ){
78653 return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
78654 }
78655 testcase( nAlloc==0 );
78656 testcase( nAlloc==31 );
78657 testcase( nAlloc==32 );
78658 if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
78659 return SQLITE_NOMEM_BKPT;
@@ -78671,30 +79286,18 @@
78671 }
78672 }
78673
78674 pMem->n = (int)(nByte & 0x7fffffff);
78675 pMem->flags = flags;
78676 if( enc ){
78677 pMem->enc = enc;
78678 #ifdef SQLITE_ENABLE_SESSION
78679 }else if( pMem->db==0 ){
78680 pMem->enc = SQLITE_UTF8;
78681 #endif
78682 }else{
78683 assert( pMem->db!=0 );
78684 pMem->enc = ENC(pMem->db);
78685 }
78686
78687 #ifndef SQLITE_OMIT_UTF16
78688 if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
78689 return SQLITE_NOMEM_BKPT;
78690 }
78691 #endif
78692
78693 if( nByte>iLimit ){
78694 return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
78695 }
78696
78697 return SQLITE_OK;
78698 }
78699
78700 /*
@@ -78972,10 +79575,11 @@
78972
78973 assert( pCtx->pParse->rc==SQLITE_OK );
78974 memset(&ctx, 0, sizeof(ctx));
78975 ctx.pOut = pVal;
78976 ctx.pFunc = pFunc;
 
78977 pFunc->xSFunc(&ctx, nVal, apVal);
78978 if( ctx.isError ){
78979 rc = ctx.isError;
78980 sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
78981 }else{
@@ -79032,15 +79636,11 @@
79032 const char *zNeg = "";
79033 int rc = SQLITE_OK;
79034
79035 assert( pExpr!=0 );
79036 while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
79037 #if defined(SQLITE_ENABLE_STAT4)
79038 if( op==TK_REGISTER ) op = pExpr->op2;
79039 #else
79040 if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
79041 #endif
79042
79043 /* Compressed expressions only appear when parsing the DEFAULT clause
79044 ** on a table column definition, and hence only when pCtx==0. This
79045 ** check ensures that an EP_TokenOnly expression is never passed down
79046 ** into valueFromFunction(). */
@@ -79151,11 +79751,11 @@
79151 *ppVal = pVal;
79152 return rc;
79153
79154 no_mem:
79155 #ifdef SQLITE_ENABLE_STAT4
79156 if( pCtx==0 || pCtx->pParse->nErr==0 )
79157 #endif
79158 sqlite3OomFault(db);
79159 sqlite3DbFree(db, zVal);
79160 assert( *ppVal==0 );
79161 #ifdef SQLITE_ENABLE_STAT4
@@ -79486,11 +80086,11 @@
79486 db->pVdbe->pPrev = p;
79487 }
79488 p->pNext = db->pVdbe;
79489 p->pPrev = 0;
79490 db->pVdbe = p;
79491 p->iVdbeMagic = VDBE_MAGIC_INIT;
79492 p->pParse = pParse;
79493 pParse->pVdbe = p;
79494 assert( pParse->aLabel==0 );
79495 assert( pParse->nLabel==0 );
79496 assert( p->nOpAlloc==0 );
@@ -79631,11 +80231,11 @@
79631 if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
79632 sqlite3OomFault(p->db);
79633 return SQLITE_NOMEM;
79634 }
79635
79636 assert( nOp<=(1024/sizeof(Op)) );
79637 assert( nNew>=(v->nOpAlloc+nOp) );
79638 pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
79639 if( pNew ){
79640 p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
79641 v->nOpAlloc = p->szOpAlloc/sizeof(Op);
@@ -79687,11 +80287,11 @@
79687 SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
79688 int i;
79689 VdbeOp *pOp;
79690
79691 i = p->nOp;
79692 assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
79693 assert( op>=0 && op<0xff );
79694 if( p->nOpAlloc<=i ){
79695 return growOp3(p, op, p1, p2, p3);
79696 }
79697 assert( p->aOp!=0 );
@@ -80019,11 +80619,11 @@
80019 }
80020 }
80021 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
80022 Parse *p = v->pParse;
80023 int j = ADDR(x);
80024 assert( v->iVdbeMagic==VDBE_MAGIC_INIT );
80025 assert( j<-p->nLabel );
80026 assert( j>=0 );
80027 #ifdef SQLITE_DEBUG
80028 if( p->db->flags & SQLITE_VdbeAddopTrace ){
80029 printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
@@ -80150,10 +80750,12 @@
80150 int hasCreateTable = 0;
80151 int hasCreateIndex = 0;
80152 int hasInitCoroutine = 0;
80153 Op *pOp;
80154 VdbeOpIter sIter;
 
 
80155 memset(&sIter, 0, sizeof(sIter));
80156 sIter.v = v;
80157
80158 while( (pOp = opIterNext(&sIter))!=0 ){
80159 int opcode = pOp->opcode;
@@ -80233,11 +80835,11 @@
80233 ** and store that value in *pMaxFuncArgs.
80234 **
80235 ** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
80236 ** indicate what the prepared statement actually does.
80237 **
80238 ** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
80239 **
80240 ** (5) Reclaim the memory allocated for storing labels.
80241 **
80242 ** This routine will only function correctly if the mkopcodeh.tcl generator
80243 ** script numbers the opcodes correctly. Changes to this routine must be
@@ -80279,29 +80881,10 @@
80279 case OP_JournalMode: {
80280 p->readOnly = 0;
80281 p->bIsReader = 1;
80282 break;
80283 }
80284 case OP_Next:
80285 case OP_SorterNext: {
80286 pOp->p4.xAdvance = sqlite3BtreeNext;
80287 pOp->p4type = P4_ADVANCE;
80288 /* The code generator never codes any of these opcodes as a jump
80289 ** to a label. They are always coded as a jump backwards to a
80290 ** known address */
80291 assert( pOp->p2>=0 );
80292 break;
80293 }
80294 case OP_Prev: {
80295 pOp->p4.xAdvance = sqlite3BtreePrevious;
80296 pOp->p4type = P4_ADVANCE;
80297 /* The code generator never codes any of these opcodes as a jump
80298 ** to a label. They are always coded as a jump backwards to a
80299 ** known address */
80300 assert( pOp->p2>=0 );
80301 break;
80302 }
80303 #ifndef SQLITE_OMIT_VIRTUALTABLE
80304 case OP_VUpdate: {
80305 if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
80306 break;
80307 }
@@ -80333,22 +80916,24 @@
80333 assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0);
80334 }
80335 if( pOp==p->aOp ) break;
80336 pOp--;
80337 }
80338 sqlite3DbFree(p->db, pParse->aLabel);
80339 pParse->aLabel = 0;
 
 
80340 pParse->nLabel = 0;
80341 *pMaxFuncArgs = nMaxArgs;
80342 assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
80343 }
80344
80345 /*
80346 ** Return the address of the next instruction to be inserted.
80347 */
80348 SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){
80349 assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
80350 return p->nOp;
80351 }
80352
80353 /*
80354 ** Verify that at least N opcode slots are available in p without
@@ -80429,11 +81014,11 @@
80429 int iLineno /* Source-file line number of first opcode */
80430 ){
80431 int i;
80432 VdbeOp *pOut, *pFirst;
80433 assert( nOp>0 );
80434 assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
80435 if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
80436 return 0;
80437 }
80438 pFirst = pOut = &p->aOp[p->nOp];
80439 for(i=0; i<nOp; i++, aOp++, pOut++){
@@ -80581,11 +81166,10 @@
80581 break;
80582 }
80583 case P4_REAL:
80584 case P4_INT64:
80585 case P4_DYNAMIC:
80586 case P4_DYNBLOB:
80587 case P4_INTARRAY: {
80588 sqlite3DbFree(db, p4);
80589 break;
80590 }
80591 case P4_KEYINFO: {
@@ -80621,17 +81205,20 @@
80621 ** Free the space allocated for aOp and any p4 values allocated for the
80622 ** opcodes contained within. If aOp is not NULL it is assumed to contain
80623 ** nOp entries.
80624 */
80625 static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
 
80626 if( aOp ){
80627 Op *pOp;
80628 for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){
80629 if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p);
80630 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
80631 sqlite3DbFree(db, pOp->zComment);
80632 #endif
 
 
80633 }
80634 sqlite3DbFreeNN(db, aOp);
80635 }
80636 }
80637
@@ -80753,11 +81340,11 @@
80753 SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
80754 Op *pOp;
80755 sqlite3 *db;
80756 assert( p!=0 );
80757 db = p->db;
80758 assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
80759 assert( p->aOp!=0 || db->mallocFailed );
80760 if( db->mallocFailed ){
80761 if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
80762 return;
80763 }
@@ -80881,11 +81468,11 @@
80881 */
80882 SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
80883 /* C89 specifies that the constant "dummy" will be initialized to all
80884 ** zeros, which is correct. MSVC generates a warning, nevertheless. */
80885 static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */
80886 assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
80887 if( addr<0 ){
80888 addr = p->nOp - 1;
80889 }
80890 assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
80891 if( p->db->mallocFailed ){
@@ -81178,14 +81765,10 @@
81178 }
81179 case P4_SUBPROGRAM: {
81180 zP4 = "program";
81181 break;
81182 }
81183 case P4_DYNBLOB:
81184 case P4_ADVANCE: {
81185 break;
81186 }
81187 case P4_TABLE: {
81188 zP4 = pOp->p4.pTab->zName;
81189 break;
81190 }
81191 default: {
@@ -81313,25 +81896,44 @@
81313 }
81314 #endif
81315
81316 /*
81317 ** Initialize an array of N Mem element.
 
 
 
 
 
 
 
 
 
 
 
 
81318 */
81319 static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
81320 while( (N--)>0 ){
81321 p->db = db;
81322 p->flags = flags;
81323 p->szMalloc = 0;
 
81324 #ifdef SQLITE_DEBUG
81325 p->pScopyFrom = 0;
81326 #endif
81327 p++;
 
81328 }
81329 }
81330
81331 /*
81332 ** Release an array of N Mem elements
 
 
 
 
 
81333 */
81334 static void releaseMemArray(Mem *p, int N){
81335 if( p && N ){
81336 Mem *pEnd = &p[N];
81337 sqlite3 *db = p->db;
@@ -81360,16 +81962,21 @@
81360 testcase( p->flags & MEM_Agg );
81361 testcase( p->flags & MEM_Dyn );
81362 if( p->flags&(MEM_Agg|MEM_Dyn) ){
81363 testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel );
81364 sqlite3VdbeMemRelease(p);
 
81365 }else if( p->szMalloc ){
81366 sqlite3DbFreeNN(db, p->zMalloc);
81367 p->szMalloc = 0;
 
81368 }
81369
81370 p->flags = MEM_Undefined;
 
 
 
81371 }while( (++p)<pEnd );
81372 }
81373 }
81374
81375 #ifdef SQLITE_DEBUG
@@ -81563,11 +82170,11 @@
81563 int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
81564 Op *aOp; /* Array of opcodes */
81565 Op *pOp; /* Current opcode */
81566
81567 assert( p->explain );
81568 assert( p->iVdbeMagic==VDBE_MAGIC_RUN );
81569 assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
81570
81571 /* Even though this opcode does not use dynamic strings for
81572 ** the result, result columns may become dynamic if the user calls
81573 ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
@@ -81743,18 +82350,19 @@
81743 SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
81744 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
81745 int i;
81746 #endif
81747 assert( p!=0 );
81748 assert( p->iVdbeMagic==VDBE_MAGIC_INIT || p->iVdbeMagic==VDBE_MAGIC_RESET );
 
 
81749
81750 /* There should be at least one opcode.
81751 */
81752 assert( p->nOp>0 );
81753
81754 /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
81755 p->iVdbeMagic = VDBE_MAGIC_RUN;
81756
81757 #ifdef SQLITE_DEBUG
81758 for(i=0; i<p->nMem; i++){
81759 assert( p->aMem[i].db==p->db );
81760 }
@@ -81806,11 +82414,11 @@
81806 struct ReusableSpace x; /* Reusable bulk memory */
81807
81808 assert( p!=0 );
81809 assert( p->nOp>0 );
81810 assert( pParse!=0 );
81811 assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
81812 assert( pParse==p->pParse );
81813 p->pVList = pParse->pVList;
81814 pParse->pVList = 0;
81815 db = p->db;
81816 assert( db->mallocFailed==0 );
@@ -81947,18 +82555,16 @@
81947
81948 /*
81949 ** Close all cursors in the current frame.
81950 */
81951 static void closeCursorsInFrame(Vdbe *p){
81952 if( p->apCsr ){
81953 int i;
81954 for(i=0; i<p->nCursor; i++){
81955 VdbeCursor *pC = p->apCsr[i];
81956 if( pC ){
81957 sqlite3VdbeFreeCursor(p, pC);
81958 p->apCsr[i] = 0;
81959 }
81960 }
81961 }
81962 }
81963
81964 /*
@@ -82003,13 +82609,11 @@
82003 p->pFrame = 0;
82004 p->nFrame = 0;
82005 }
82006 assert( p->nFrame==0 );
82007 closeCursorsInFrame(p);
82008 if( p->aMem ){
82009 releaseMemArray(p->aMem, p->nMem);
82010 }
82011 while( p->pDelFrame ){
82012 VdbeFrame *pDel = p->pDelFrame;
82013 p->pDelFrame = pDel->pParent;
82014 sqlite3VdbeFrameDelete(pDel);
82015 }
@@ -82445,11 +83049,12 @@
82445 || (!deferred && p->nFkConstraint>0)
82446 ){
82447 p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
82448 p->errorAction = OE_Abort;
82449 sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
82450 return SQLITE_ERROR;
 
82451 }
82452 return SQLITE_OK;
82453 }
82454 #endif
82455
@@ -82484,11 +83089,11 @@
82484 ** Then the internal cache might have been left in an inconsistent
82485 ** state. We need to rollback the statement transaction, if there is
82486 ** one, or the complete transaction if there is no statement transaction.
82487 */
82488
82489 if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
82490 return SQLITE_OK;
82491 }
82492 if( db->mallocFailed ){
82493 p->rc = SQLITE_NOMEM_BKPT;
82494 }
@@ -82495,11 +83100,11 @@
82495 closeAllCursors(p);
82496 checkActiveVdbeCnt(db);
82497
82498 /* No commit or rollback needed if the program never started or if the
82499 ** SQL statement does not read or write a database file. */
82500 if( p->pc>=0 && p->bIsReader ){
82501 int mrc; /* Primary error code from p->rc */
82502 int eStatementOp = 0;
82503 int isSpecialError; /* Set to true if a 'special' error */
82504
82505 /* Lock all btrees used by the statement */
@@ -82643,19 +83248,17 @@
82643 /* Release the locks */
82644 sqlite3VdbeLeave(p);
82645 }
82646
82647 /* We have successfully halted and closed the VM. Record this fact. */
82648 if( p->pc>=0 ){
82649 db->nVdbeActive--;
82650 if( !p->readOnly ) db->nVdbeWrite--;
82651 if( p->bIsReader ) db->nVdbeRead--;
82652 assert( db->nVdbeActive>=db->nVdbeRead );
82653 assert( db->nVdbeRead>=db->nVdbeWrite );
82654 assert( db->nVdbeWrite>=0 );
82655 }
82656 p->iVdbeMagic = VDBE_MAGIC_HALT;
82657 checkActiveVdbeCnt(db);
82658 if( db->mallocFailed ){
82659 p->rc = SQLITE_NOMEM_BKPT;
82660 }
82661
@@ -82700,10 +83303,11 @@
82700 db->bBenignMalloc--;
82701 }else if( db->pErr ){
82702 sqlite3ValueSetNull(db->pErr);
82703 }
82704 db->errCode = rc;
 
82705 return rc;
82706 }
82707
82708 #ifdef SQLITE_ENABLE_SQLLOG
82709 /*
@@ -82732,12 +83336,12 @@
82732 **
82733 ** After this routine is run, the VDBE should be ready to be executed
82734 ** again.
82735 **
82736 ** To look at it another way, this routine resets the state of the
82737 ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
82738 ** VDBE_MAGIC_INIT.
82739 */
82740 SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
82741 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
82742 int i;
82743 #endif
@@ -82762,16 +83366,10 @@
82762 sqlite3VdbeTransferError(p);
82763 }else{
82764 db->errCode = p->rc;
82765 }
82766 if( p->runOnlyOnce ) p->expired = 1;
82767 }else if( p->rc && p->expired ){
82768 /* The expired flag was set on the VDBE before the first call
82769 ** to sqlite3_step(). For consistency (since sqlite3_step() was
82770 ** called), set the database error in this case as well.
82771 */
82772 sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
82773 }
82774
82775 /* Reset register contents and reclaim error message memory.
82776 */
82777 #ifdef SQLITE_DEBUG
@@ -82824,21 +83422,23 @@
82824 }
82825 fclose(out);
82826 }
82827 }
82828 #endif
82829 p->iVdbeMagic = VDBE_MAGIC_RESET;
82830 return p->rc & db->errMask;
82831 }
82832
82833 /*
82834 ** Clean up and delete a VDBE after execution. Return an integer which is
82835 ** the result code. Write any error message text into *pzErrMsg.
82836 */
82837 SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
82838 int rc = SQLITE_OK;
82839 if( p->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){
 
 
 
82840 rc = sqlite3VdbeReset(p);
82841 assert( (rc & p->db->errMask)==rc );
82842 }
82843 sqlite3VdbeDelete(p);
82844 return rc;
@@ -82889,23 +83489,25 @@
82889 ** the database connection and frees the object itself.
82890 */
82891 SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
82892 SubProgram *pSub, *pNext;
82893 assert( p->db==0 || p->db==db );
82894 releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
 
 
 
82895 for(pSub=p->pProgram; pSub; pSub=pNext){
82896 pNext = pSub->pNext;
82897 vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
82898 sqlite3DbFree(db, pSub);
82899 }
82900 if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){
82901 releaseMemArray(p->aVar, p->nVar);
82902 sqlite3DbFree(db, p->pVList);
82903 sqlite3DbFree(db, p->pFree);
82904 }
82905 vdbeFreeOpArray(db, p->aOp, p->nOp);
82906 sqlite3DbFree(db, p->aColName);
82907 sqlite3DbFree(db, p->zSql);
82908 #ifdef SQLITE_ENABLE_NORMALIZE
82909 sqlite3DbFree(db, p->zNormSql);
82910 {
82911 DblquoteStr *pThis, *pNext;
@@ -82943,12 +83545,10 @@
82943 db->pVdbe = p->pNext;
82944 }
82945 if( p->pNext ){
82946 p->pNext->pPrev = p->pPrev;
82947 }
82948 p->iVdbeMagic = VDBE_MAGIC_DEAD;
82949 p->db = 0;
82950 sqlite3DbFreeNN(db, p);
82951 }
82952
82953 /*
82954 ** The cursor "p" has a pending seek operation that has not yet been
@@ -82979,11 +83579,11 @@
82979 ** pointed to was deleted out from under it. Or maybe the btree was
82980 ** rebalanced. Whatever the cause, try to restore "p" to the place it
82981 ** is supposed to be pointing. If the row was deleted out from under the
82982 ** cursor, set the cursor to point to a NULL row.
82983 */
82984 static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
82985 int isDifferentRow, rc;
82986 assert( p->eCurType==CURTYPE_BTREE );
82987 assert( p->uc.pCursor!=0 );
82988 assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) );
82989 rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow);
@@ -82997,43 +83597,11 @@
82997 ** if need be. Return any I/O error from the restore operation.
82998 */
82999 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
83000 assert( p->eCurType==CURTYPE_BTREE );
83001 if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
83002 return handleMovedCursor(p);
83003 }
83004 return SQLITE_OK;
83005 }
83006
83007 /*
83008 ** Make sure the cursor p is ready to read or write the row to which it
83009 ** was last positioned. Return an error code if an OOM fault or I/O error
83010 ** prevents us from positioning the cursor to its correct position.
83011 **
83012 ** If a MoveTo operation is pending on the given cursor, then do that
83013 ** MoveTo now. If no move is pending, check to see if the row has been
83014 ** deleted out from under the cursor and if it has, mark the row as
83015 ** a NULL row.
83016 **
83017 ** If the cursor is already pointing to the correct row and that row has
83018 ** not been deleted out from under the cursor, then this routine is a no-op.
83019 */
83020 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){
83021 VdbeCursor *p = *pp;
83022 assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
83023 if( p->deferredMoveto ){
83024 u32 iMap;
83025 assert( !p->isEphemeral );
83026 if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){
83027 *pp = p->pAltCursor;
83028 *piCol = iMap - 1;
83029 return SQLITE_OK;
83030 }
83031 return sqlite3VdbeFinishMoveto(p);
83032 }
83033 if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
83034 return handleMovedCursor(p);
83035 }
83036 return SQLITE_OK;
83037 }
83038
83039 /*
@@ -83691,12 +84259,12 @@
83691 if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
83692 rc = 0;
83693 }else{
83694 rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2);
83695 }
83696 sqlite3VdbeMemRelease(&c1);
83697 sqlite3VdbeMemRelease(&c2);
83698 return rc;
83699 }
83700 }
83701
83702 /*
@@ -84216,11 +84784,12 @@
84216
84217 default:
84218 return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
84219 }
84220
84221 v = pPKey2->aMem[0].u.i;
 
84222 if( v>lhs ){
84223 res = pPKey2->r1;
84224 }else if( v<lhs ){
84225 res = pPKey2->r2;
84226 }else if( pPKey2->nField>1 ){
@@ -84251,16 +84820,22 @@
84251 const u8 *aKey1 = (const u8*)pKey1;
84252 int serial_type;
84253 int res;
84254
84255 assert( pPKey2->aMem[0].flags & MEM_Str );
 
 
84256 vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
84257 serial_type = (u8)(aKey1[1]);
84258 if( serial_type >= 0x80 ){
84259 sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
84260 }
84261 if( serial_type<12 ){
 
 
 
 
 
84262 res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
84263 }else if( !(serial_type & 0x01) ){
84264 res = pPKey2->r2; /* (pKey1/nKey1) is a blob */
84265 }else{
84266 int nCmp;
@@ -84270,19 +84845,19 @@
84270 nStr = (serial_type-12) / 2;
84271 if( (szHdr + nStr) > nKey1 ){
84272 pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
84273 return 0; /* Corruption */
84274 }
84275 nCmp = MIN( pPKey2->aMem[0].n, nStr );
84276 res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
84277
84278 if( res>0 ){
84279 res = pPKey2->r2;
84280 }else if( res<0 ){
84281 res = pPKey2->r1;
84282 }else{
84283 res = nStr - pPKey2->aMem[0].n;
84284 if( res==0 ){
84285 if( pPKey2->nField>1 ){
84286 res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
84287 }else{
84288 res = pPKey2->default_rc;
@@ -84333,19 +84908,22 @@
84333 }else{
84334 p->r1 = -1;
84335 p->r2 = 1;
84336 }
84337 if( (flags & MEM_Int) ){
 
84338 return vdbeRecordCompareInt;
84339 }
84340 testcase( flags & MEM_Real );
84341 testcase( flags & MEM_Null );
84342 testcase( flags & MEM_Blob );
84343 if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
84344 && p->pKeyInfo->aColl[0]==0
84345 ){
84346 assert( flags & MEM_Str );
 
 
84347 return vdbeRecordCompareString;
84348 }
84349 }
84350
84351 return sqlite3VdbeRecordCompare;
@@ -84414,18 +84992,18 @@
84414 }
84415
84416 /* Fetch the integer off the end of the index record */
84417 sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
84418 *rowid = v.u.i;
84419 sqlite3VdbeMemRelease(&m);
84420 return SQLITE_OK;
84421
84422 /* Jump here if database corruption is detected after m has been
84423 ** allocated. Free the m object and return SQLITE_CORRUPT. */
84424 idx_rowid_corruption:
84425 testcase( m.szMalloc!=0 );
84426 sqlite3VdbeMemRelease(&m);
84427 return SQLITE_CORRUPT_BKPT;
84428 }
84429
84430 /*
84431 ** Compare the key of the index entry that cursor pC is pointing to against
@@ -84463,11 +85041,11 @@
84463 rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
84464 if( rc ){
84465 return rc;
84466 }
84467 *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
84468 sqlite3VdbeMemRelease(&m);
84469 return SQLITE_OK;
84470 }
84471
84472 /*
84473 ** This routine sets the value to be returned by subsequent calls to
@@ -84630,11 +85208,11 @@
84630 static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
84631 if( p ){
84632 int i;
84633 for(i=0; i<nField; i++){
84634 Mem *pMem = &p->aMem[i];
84635 if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
84636 }
84637 sqlite3DbFreeNN(db, p);
84638 }
84639 }
84640 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -85057,10 +85635,13 @@
85057 pNew->flags |= MEM_Ephem;
85058 if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
85059 sqlite3ValueFree(pNew);
85060 pNew = 0;
85061 }
 
 
 
85062 }
85063 return pNew;
85064 }
85065
85066 /* Destroy an sqlite3_value object previously obtained from
@@ -85087,20 +85668,26 @@
85087 const char *z, /* String pointer */
85088 int n, /* Bytes in string, or negative */
85089 u8 enc, /* Encoding of z. 0 for BLOBs */
85090 void (*xDel)(void*) /* Destructor function */
85091 ){
85092 int rc = sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel);
 
85093 if( rc ){
85094 if( rc==SQLITE_TOOBIG ){
85095 sqlite3_result_error_toobig(pCtx);
85096 }else{
85097 /* The only errors possible from sqlite3VdbeMemSetStr are
85098 ** SQLITE_TOOBIG and SQLITE_NOMEM */
85099 assert( rc==SQLITE_NOMEM );
85100 sqlite3_result_error_nomem(pCtx);
85101 }
 
 
 
 
 
85102 }
85103 }
85104 static int invokeValueDestructor(
85105 const void *p, /* Value to destroy */
85106 void (*xDel)(void*), /* The destructor */
@@ -85240,21 +85827,26 @@
85240 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
85241 setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
85242 }
85243 #endif /* SQLITE_OMIT_UTF16 */
85244 SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
 
85245 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
85246 sqlite3VdbeMemCopy(pCtx->pOut, pValue);
 
 
 
 
85247 }
85248 SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
85249 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
85250 sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
85251 }
85252 SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
85253 Mem *pOut = pCtx->pOut;
85254 assert( sqlite3_mutex_held(pOut->db->mutex) );
85255 if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
 
85256 return SQLITE_TOOBIG;
85257 }
85258 #ifndef SQLITE_OMIT_INCRBLOB
85259 sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
85260 return SQLITE_OK;
@@ -85266,12 +85858,12 @@
85266 pCtx->isError = errCode ? errCode : -1;
85267 #ifdef SQLITE_DEBUG
85268 if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
85269 #endif
85270 if( pCtx->pOut->flags & MEM_Null ){
85271 sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1,
85272 SQLITE_UTF8, SQLITE_STATIC);
85273 }
85274 }
85275
85276 /* Force an SQLITE_TOOBIG error. */
85277 SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
@@ -85340,85 +85932,94 @@
85340 */
85341 static int sqlite3Step(Vdbe *p){
85342 sqlite3 *db;
85343 int rc;
85344
85345 assert(p);
85346 if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
85347 /* We used to require that sqlite3_reset() be called before retrying
85348 ** sqlite3_step() after any error or after SQLITE_DONE. But beginning
85349 ** with version 3.7.0, we changed this so that sqlite3_reset() would
85350 ** be called automatically instead of throwing the SQLITE_MISUSE error.
85351 ** This "automatic-reset" change is not technically an incompatibility,
85352 ** since any application that receives an SQLITE_MISUSE is broken by
85353 ** definition.
85354 **
85355 ** Nevertheless, some published applications that were originally written
85356 ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
85357 ** returns, and those were broken by the automatic-reset change. As a
85358 ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
85359 ** legacy behavior of returning SQLITE_MISUSE for cases where the
85360 ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
85361 ** or SQLITE_BUSY error.
85362 */
85363 #ifdef SQLITE_OMIT_AUTORESET
85364 if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
85365 sqlite3_reset((sqlite3_stmt*)p);
85366 }else{
85367 return SQLITE_MISUSE_BKPT;
85368 }
85369 #else
85370 sqlite3_reset((sqlite3_stmt*)p);
85371 #endif
85372 }
85373
85374 /* Check that malloc() has not failed. If it has, return early. */
85375 db = p->db;
85376 if( db->mallocFailed ){
85377 p->rc = SQLITE_NOMEM;
85378 return SQLITE_NOMEM_BKPT;
85379 }
85380
85381 if( p->pc<0 && p->expired ){
85382 p->rc = SQLITE_SCHEMA;
85383 rc = SQLITE_ERROR;
85384 if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){
85385 /* If this statement was prepared using saved SQL and an
85386 ** error has occurred, then return the error code in p->rc to the
85387 ** caller. Set the error code in the database handle to the same value.
85388 */
85389 rc = sqlite3VdbeTransferError(p);
85390 }
85391 goto end_of_step;
85392 }
85393 if( p->pc<0 ){
85394 /* If there are no other statements currently running, then
85395 ** reset the interrupt flag. This prevents a call to sqlite3_interrupt
85396 ** from interrupting a statement that has not yet started.
85397 */
85398 if( db->nVdbeActive==0 ){
85399 AtomicStore(&db->u1.isInterrupted, 0);
85400 }
85401
85402 assert( db->nVdbeWrite>0 || db->autoCommit==0
85403 || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
85404 );
 
 
 
 
 
85405
85406 #ifndef SQLITE_OMIT_TRACE
85407 if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
85408 && !db->init.busy && p->zSql ){
85409 sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
85410 }else{
85411 assert( p->startTime==0 );
85412 }
85413 #endif
85414
85415 db->nVdbeActive++;
85416 if( p->readOnly==0 ) db->nVdbeWrite++;
85417 if( p->bIsReader ) db->nVdbeRead++;
85418 p->pc = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85419 }
 
85420 #ifdef SQLITE_DEBUG
85421 p->rcApp = SQLITE_OK;
85422 #endif
85423 #ifndef SQLITE_OMIT_EXPLAIN
85424 if( p->explain ){
@@ -85429,11 +86030,16 @@
85429 db->nVdbeExec++;
85430 rc = sqlite3VdbeExec(p);
85431 db->nVdbeExec--;
85432 }
85433
85434 if( rc!=SQLITE_ROW ){
 
 
 
 
 
85435 #ifndef SQLITE_OMIT_TRACE
85436 /* If the statement completed successfully, invoke the profile callback */
85437 checkProfileCallback(db, p);
85438 #endif
85439
@@ -85557,10 +86163,74 @@
85557 */
85558 SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
85559 assert( p );
85560 return sqlite3_value_nochange(p->pOut);
85561 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85562
85563 /*
85564 ** Return the current time for a statement. If the current time
85565 ** is requested more than once within the same run of a single prepared
85566 ** statement, the exact same time is returned for each invocation regardless
@@ -85752,19 +86422,19 @@
85752 #if defined(SQLITE_DEBUG) && defined(__GNUC__)
85753 __attribute__((aligned(8)))
85754 #endif
85755 = {
85756 /* .u = */ {0},
 
 
85757 /* .flags = */ (u16)MEM_Null,
85758 /* .enc = */ (u8)0,
85759 /* .eSubtype = */ (u8)0,
85760 /* .n = */ (int)0,
85761 /* .z = */ (char*)0,
85762 /* .zMalloc = */ (char*)0,
85763 /* .szMalloc = */ (int)0,
85764 /* .uTemp = */ (u32)0,
85765 /* .db = */ (sqlite3*)0,
85766 /* .xDel = */ (void(*)(void*))0,
85767 #ifdef SQLITE_DEBUG
85768 /* .pScopyFrom = */ (Mem*)0,
85769 /* .mScopyFlags= */ 0,
85770 #endif
@@ -86057,11 +86727,11 @@
86057 Mem *pVar;
86058 if( vdbeSafetyNotNull(p) ){
86059 return SQLITE_MISUSE_BKPT;
86060 }
86061 sqlite3_mutex_enter(p->db->mutex);
86062 if( p->iVdbeMagic!=VDBE_MAGIC_RUN || p->pc>=0 ){
86063 sqlite3Error(p->db, SQLITE_MISUSE);
86064 sqlite3_mutex_leave(p->db->mutex);
86065 sqlite3_log(SQLITE_MISUSE,
86066 "bind on a busy prepared statement: [%s]", p->zSql);
86067 return SQLITE_MISUSE_BKPT;
@@ -86242,11 +86912,14 @@
86242 case SQLITE_INTEGER: {
86243 rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
86244 break;
86245 }
86246 case SQLITE_FLOAT: {
86247 rc = sqlite3_bind_double(pStmt, i, pValue->u.r);
 
 
 
86248 break;
86249 }
86250 case SQLITE_BLOB: {
86251 if( pValue->flags & MEM_Zero ){
86252 rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero);
@@ -86407,11 +87080,11 @@
86407 /*
86408 ** Return true if the prepared statement is in need of being reset.
86409 */
86410 SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
86411 Vdbe *v = (Vdbe*)pStmt;
86412 return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0;
86413 }
86414
86415 /*
86416 ** Return a pointer to the next prepared statement after pStmt associated
86417 ** with database connection pDb. If pStmt is NULL, return the first
@@ -87721,11 +88394,11 @@
87721 #ifdef VDBE_PROFILE
87722 u64 start; /* CPU clock count at start of opcode */
87723 #endif
87724 /*** INSERT STACK UNION HERE ***/
87725
87726 assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
87727 sqlite3VdbeEnter(p);
87728 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
87729 if( db->xProgress ){
87730 u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
87731 assert( 0 < db->nProgressOps );
@@ -87972,14 +88645,18 @@
87972 jump_to_p2:
87973 pOp = &aOp[pOp->p2 - 1];
87974 break;
87975 }
87976
87977 /* Opcode: Return P1 * * * *
87978 **
87979 ** Jump to the next instruction after the address in register P1. After
87980 ** the jump, register P1 becomes undefined.
 
 
 
 
87981 */
87982 case OP_Return: { /* in1 */
87983 pIn1 = &aMem[pOp->p1];
87984 assert( pIn1->flags==MEM_Int );
87985 pOp = &aOp[pIn1->u.i];
@@ -88163,15 +88840,26 @@
88163 rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
88164 }
88165 goto vdbe_return;
88166 }
88167
 
 
 
 
 
 
 
 
 
 
88168 /* Opcode: Integer P1 P2 * * *
88169 ** Synopsis: r[P2]=P1
88170 **
88171 ** The 32-bit integer value P1 is written into register P2.
88172 */
 
88173 case OP_Integer: { /* out2 */
88174 pOut = out2Prerelease(p, pOp);
88175 pOut->u.i = pOp->p1;
88176 break;
88177 }
@@ -89608,14 +90296,22 @@
89608 case OP_Offset: { /* out3 */
89609 VdbeCursor *pC; /* The VDBE cursor */
89610 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
89611 pC = p->apCsr[pOp->p1];
89612 pOut = &p->aMem[pOp->p3];
89613 if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){
89614 sqlite3VdbeMemSetNull(pOut);
89615 }else{
89616 sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
 
 
 
 
 
 
 
 
89617 }
89618 break;
89619 }
89620 #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
89621
@@ -89640,11 +90336,11 @@
89640 ** skipped for length() and all content loading can be skipped for typeof().
89641 */
89642 case OP_Column: {
89643 u32 p2; /* column number to retrieve */
89644 VdbeCursor *pC; /* The VDBE cursor */
89645 BtCursor *pCrsr; /* The BTree cursor */
89646 u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
89647 int len; /* The length of the serialized data for the column */
89648 int i; /* Loop counter */
89649 Mem *pDest; /* Where to write the extracted value */
89650 Mem sMem; /* For storing the record being decoded */
@@ -89654,23 +90350,15 @@
89654 u64 offset64; /* 64-bit offset */
89655 u32 t; /* A type code from the record header */
89656 Mem *pReg; /* PseudoTable input register */
89657
89658 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
 
89659 pC = p->apCsr[pOp->p1];
89660 assert( pC!=0 );
89661 p2 = (u32)pOp->p2;
89662
89663 /* If the cursor cache is stale (meaning it is not currently point at
89664 ** the correct row) then bring it up-to-date by doing the necessary
89665 ** B-Tree seek. */
89666 rc = sqlite3VdbeCursorMoveto(&pC, &p2);
89667 if( rc ) goto abort_due_to_error;
89668
89669 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
89670 pDest = &aMem[pOp->p3];
89671 memAboutToChange(p, pDest);
89672 assert( pC!=0 );
89673 assert( p2<(u32)pC->nField );
89674 aOffset = pC->aOffset;
89675 assert( aOffset==pC->aType+pC->nField );
89676 assert( pC->eCurType!=CURTYPE_VTAB );
@@ -89687,30 +90375,43 @@
89687 assert( pReg->flags & MEM_Blob );
89688 assert( memIsValid(pReg) );
89689 pC->payloadSize = pC->szRow = pReg->n;
89690 pC->aRow = (u8*)pReg->z;
89691 }else{
 
 
89692 sqlite3VdbeMemSetNull(pDest);
89693 goto op_column_out;
89694 }
89695 }else{
89696 pCrsr = pC->uc.pCursor;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89697 assert( pC->eCurType==CURTYPE_BTREE );
89698 assert( pCrsr );
89699 assert( sqlite3BtreeCursorIsValid(pCrsr) );
89700 pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
89701 pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
89702 assert( pC->szRow<=pC->payloadSize );
89703 assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
89704 if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
89705 goto too_big;
89706 }
89707 }
89708 pC->cacheStatus = p->cacheCtr;
89709 pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
89710 pC->nHdrParsed = 0;
89711
89712
89713 if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
89714 /* pC->aRow does not have to hold the entire row, but it does at least
89715 ** need to cover the header of the record. If pC->aRow does not contain
89716 ** the complete header, then set it to zero, forcing the header to be
@@ -89747,10 +90448,14 @@
89747 zData = pC->aRow;
89748 assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
89749 testcase( aOffset[0]==0 );
89750 goto op_column_read_header;
89751 }
 
 
 
 
89752 }
89753
89754 /* Make sure at least the first p2+1 entries of the header have been
89755 ** parsed and valid information is in aOffset[] and pC->aType[].
89756 */
@@ -89815,10 +90520,12 @@
89815 /* If after trying to extract new entries from the header, nHdrParsed is
89816 ** still not up to p2, that means that the record has fewer than p2
89817 ** columns. So the result will be either the default value or a NULL.
89818 */
89819 if( pC->nHdrParsed<=p2 ){
 
 
89820 if( pOp->p4type==P4_MEM ){
89821 sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
89822 }else{
89823 sqlite3VdbeMemSetNull(pDest);
89824 }
@@ -89832,10 +90539,12 @@
89832 ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
89833 ** all valid.
89834 */
89835 assert( p2<pC->nHdrParsed );
89836 assert( rc==SQLITE_OK );
 
 
89837 assert( sqlite3VdbeCheckMemInvariants(pDest) );
89838 if( VdbeMemDynamic(pDest) ){
89839 sqlite3VdbeMemSetNull(pDest);
89840 }
89841 assert( t==pC->aType[p2] );
@@ -89852,10 +90561,11 @@
89852 */
89853 static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term };
89854 pDest->n = len = (t-12)/2;
89855 pDest->enc = encoding;
89856 if( pDest->szMalloc < len+2 ){
 
89857 pDest->flags = MEM_Null;
89858 if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem;
89859 }else{
89860 pDest->z = pDest->zMalloc;
89861 }
@@ -89884,10 +90594,11 @@
89884 ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
89885 ** and it begins with a bunch of zeros.
89886 */
89887 sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
89888 }else{
 
89889 rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
89890 if( rc!=SQLITE_OK ) goto abort_due_to_error;
89891 sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
89892 pDest->flags &= ~MEM_Ephem;
89893 }
@@ -90096,11 +90807,10 @@
90096 u32 serial_type; /* Type field */
90097 Mem *pData0; /* First field to be combined into the record */
90098 Mem *pLast; /* Last field of the record */
90099 int nField; /* Number of fields in the record */
90100 char *zAffinity; /* The affinity string for the record */
90101 int file_format; /* File format to use for encoding */
90102 u32 len; /* Length of a field */
90103 u8 *zHdr; /* Where to write next byte of the header */
90104 u8 *zPayload; /* Where to write next byte of the payload */
90105
90106 /* Assuming the record contains N fields, the record format looks
@@ -90125,11 +90835,10 @@
90125 zAffinity = pOp->p4.z;
90126 assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 );
90127 pData0 = &aMem[nField];
90128 nField = pOp->p2;
90129 pLast = &pData0[nField-1];
90130 file_format = p->minWriteFileFormat;
90131
90132 /* Identify the output register */
90133 assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
90134 pOut = &aMem[pOp->p3];
90135 memAboutToChange(p, pOut);
@@ -90224,14 +90933,14 @@
90224 }
90225 nHdr++;
90226 testcase( uu==127 ); testcase( uu==128 );
90227 testcase( uu==32767 ); testcase( uu==32768 );
90228 testcase( uu==8388607 ); testcase( uu==8388608 );
90229 testcase( uu==2147483647 ); testcase( uu==2147483648 );
90230 testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL );
90231 if( uu<=127 ){
90232 if( (i&1)==i && file_format>=4 ){
90233 pRec->uTemp = 8+(u32)uu;
90234 }else{
90235 nData++;
90236 pRec->uTemp = 1;
90237 }
@@ -92690,10 +93399,14 @@
92690 /* Opcode: NullRow P1 * * * *
92691 **
92692 ** Move the cursor P1 to a null row. Any OP_Column operations
92693 ** that occur while the cursor is on the null row will always
92694 ** write a NULL.
 
 
 
 
92695 */
92696 case OP_NullRow: {
92697 VdbeCursor *pC;
92698
92699 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
@@ -92869,11 +93582,11 @@
92869 VdbeBranchTaken(res!=0,2);
92870 if( res ) goto jump_to_p2;
92871 break;
92872 }
92873
92874 /* Opcode: Next P1 P2 P3 P4 P5
92875 **
92876 ** Advance cursor P1 so that it points to the next key/data pair in its
92877 ** table or index. If there are no more key/value pairs then fall through
92878 ** to the following instruction. But if the cursor advance was successful,
92879 ** jump immediately to P2.
@@ -92888,19 +93601,16 @@
92888 ** The P3 value is a hint to the btree implementation. If P3==1, that
92889 ** means P1 is an SQL index and that this instruction could have been
92890 ** omitted if that index had been unique. P3 is usually 0. P3 is
92891 ** always either 0 or 1.
92892 **
92893 ** P4 is always of type P4_ADVANCE. The function pointer points to
92894 ** sqlite3BtreeNext().
92895 **
92896 ** If P5 is positive and the jump is taken, then event counter
92897 ** number P5-1 in the prepared statement is incremented.
92898 **
92899 ** See also: Prev
92900 */
92901 /* Opcode: Prev P1 P2 P3 P4 P5
92902 **
92903 ** Back up cursor P1 so that it points to the previous key/data pair in its
92904 ** table or index. If there is no previous key/value pairs then fall through
92905 ** to the following instruction. But if the cursor backup was successful,
92906 ** jump immediately to P2.
@@ -92916,13 +93626,10 @@
92916 ** The P3 value is a hint to the btree implementation. If P3==1, that
92917 ** means P1 is an SQL index and that this instruction could have been
92918 ** omitted if that index had been unique. P3 is usually 0. P3 is
92919 ** always either 0 or 1.
92920 **
92921 ** P4 is always of type P4_ADVANCE. The function pointer points to
92922 ** sqlite3BtreePrevious().
92923 **
92924 ** If P5 is positive and the jump is taken, then event counter
92925 ** number P5-1 in the prepared statement is incremented.
92926 */
92927 /* Opcode: SorterNext P1 P2 * * P5
92928 **
@@ -92936,34 +93643,37 @@
92936
92937 pC = p->apCsr[pOp->p1];
92938 assert( isSorter(pC) );
92939 rc = sqlite3VdbeSorterNext(db, pC);
92940 goto next_tail;
 
92941 case OP_Prev: /* jump */
 
 
 
 
 
 
 
 
 
 
 
 
92942 case OP_Next: /* jump */
92943 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
92944 assert( pOp->p5<ArraySize(p->aCounter) );
92945 pC = p->apCsr[pOp->p1];
92946 assert( pC!=0 );
92947 assert( pC->deferredMoveto==0 );
92948 assert( pC->eCurType==CURTYPE_BTREE );
92949 assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
92950 assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
92951
92952 /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
92953 ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
92954 assert( pOp->opcode!=OP_Next
92955 || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
92956 || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
92957 || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid
92958 || pC->seekOp==OP_IfNoHope);
92959 assert( pOp->opcode!=OP_Prev
92960 || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
92961 || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope
92962 || pC->seekOp==OP_NullRow);
92963
92964 rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
92965 next_tail:
92966 pC->cacheStatus = CACHE_STALE;
92967 VdbeBranchTaken(rc==SQLITE_OK,2);
92968 if( rc==SQLITE_OK ){
92969 pC->nullRow = 0;
@@ -93177,10 +93887,11 @@
93177 assert( pTabCur->uc.pCursor!=0 );
93178 assert( pTabCur->isTable );
93179 pTabCur->nullRow = 0;
93180 pTabCur->movetoTarget = rowid;
93181 pTabCur->deferredMoveto = 1;
 
93182 assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
93183 assert( !pTabCur->isEphemeral );
93184 pTabCur->ub.aAltMap = pOp->p4.ai;
93185 assert( !pC->isEphemeral );
93186 pTabCur->pAltCursor = pC;
@@ -93311,11 +94022,11 @@
93311 }
93312 sqlite3VdbeMemInit(&m, db, 0);
93313 rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
93314 if( rc ) goto abort_due_to_error;
93315 res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0);
93316 sqlite3VdbeMemRelease(&m);
93317 }
93318 /* End of inlined sqlite3VdbeIdxKeyCompare() */
93319
93320 assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
93321 if( (pOp->opcode&1)==(OP_IdxLT&1) ){
@@ -94192,10 +94903,11 @@
94192 pCtx->pFunc = pOp->p4.pFunc;
94193 pCtx->iOp = (int)(pOp - aOp);
94194 pCtx->pVdbe = p;
94195 pCtx->skipFlag = 0;
94196 pCtx->isError = 0;
 
94197 pCtx->argc = n;
94198 pOp->p4type = P4_FUNCCTX;
94199 pOp->p4.pCtx = pCtx;
94200
94201 /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */
@@ -94321,13 +95033,10 @@
94321 sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
94322 goto abort_due_to_error;
94323 }
94324 sqlite3VdbeChangeEncoding(pMem, encoding);
94325 UPDATE_MAX_BLOBSIZE(pMem);
94326 if( sqlite3VdbeMemTooBig(pMem) ){
94327 goto too_big;
94328 }
94329 break;
94330 }
94331
94332 #ifndef SQLITE_OMIT_WAL
94333 /* Opcode: Checkpoint P1 P2 P3 * *
@@ -94714,10 +95423,38 @@
94714 goto no_mem;
94715 }
94716 break;
94717 }
94718 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94719
94720 #ifndef SQLITE_OMIT_VIRTUALTABLE
94721 /* Opcode: VFilter P1 P2 P3 P4 *
94722 ** Synopsis: iplan=r[P3] zplan='P4'
94723 **
@@ -94816,10 +95553,11 @@
94816 pVtab = pCur->uc.pVCur->pVtab;
94817 pModule = pVtab->pModule;
94818 assert( pModule->xColumn );
94819 memset(&sContext, 0, sizeof(sContext));
94820 sContext.pOut = pDest;
 
94821 assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
94822 if( pOp->p5 & OPFLAG_NOCHNG ){
94823 sqlite3VdbeMemSetNull(pDest);
94824 pDest->flags = MEM_Null|MEM_Zero;
94825 pDest->u.nZero = 0;
@@ -94834,13 +95572,10 @@
94834 }
94835 sqlite3VdbeChangeEncoding(pDest, encoding);
94836 REGISTER_TRACE(pOp->p3, pDest);
94837 UPDATE_MAX_BLOBSIZE(pDest);
94838
94839 if( sqlite3VdbeMemTooBig(pDest) ){
94840 goto too_big;
94841 }
94842 if( rc ) goto abort_due_to_error;
94843 break;
94844 }
94845 #endif /* SQLITE_OMIT_VIRTUALTABLE */
94846
@@ -95103,10 +95838,11 @@
95103 ** reinitializes the relavant parts of the sqlite3_context object */
95104 pOut = &aMem[pOp->p3];
95105 if( pCtx->pOut != pOut ){
95106 pCtx->pVdbe = p;
95107 pCtx->pOut = pOut;
 
95108 for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
95109 }
95110 assert( pCtx->pVdbe==p );
95111
95112 memAboutToChange(p, pOut);
@@ -95129,15 +95865,14 @@
95129 sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
95130 pCtx->isError = 0;
95131 if( rc ) goto abort_due_to_error;
95132 }
95133
95134 /* Copy the result of the function into register P3 */
95135 if( pOut->flags & (MEM_Str|MEM_Blob) ){
95136 sqlite3VdbeChangeEncoding(pOut, encoding);
95137 if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
95138 }
95139
95140 REGISTER_TRACE(pOp->p3, pOut);
95141 UPDATE_MAX_BLOBSIZE(pOut);
95142 break;
95143 }
@@ -99442,10 +100177,13 @@
99442 }
99443 return rc;
99444 }
99445
99446
 
 
 
99447 /*
99448 ** Write data to the file.
99449 */
99450 static int memjrnlWrite(
99451 sqlite3_file *pJfd, /* The journal file into which to write */
@@ -99472,26 +100210,24 @@
99472 /* An in-memory journal file should only ever be appended to. Random
99473 ** access writes are not required. The only exception to this is when
99474 ** the in-memory journal is being used by a connection using the
99475 ** atomic-write optimization. In this case the first 28 bytes of the
99476 ** journal file may be written as part of committing the transaction. */
99477 assert( iOfst==p->endpoint.iOffset || iOfst==0 );
99478 #if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
99479 || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
 
99480 if( iOfst==0 && p->pFirst ){
99481 assert( p->nChunkSize>iAmt );
99482 memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
99483 }else
99484 #else
99485 assert( iOfst>0 || p->pFirst==0 );
99486 #endif
99487 {
99488 while( nWrite>0 ){
99489 FileChunk *pChunk = p->endpoint.pChunk;
99490 int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
99491 int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
99492
 
99493 if( iChunkOffset==0 ){
99494 /* New chunk is required to extend the file. */
99495 FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
99496 if( !pNew ){
99497 return SQLITE_IOERR_NOMEM_BKPT;
@@ -99502,14 +100238,15 @@
99502 pChunk->pNext = pNew;
99503 }else{
99504 assert( !p->pFirst );
99505 p->pFirst = pNew;
99506 }
99507 p->endpoint.pChunk = pNew;
99508 }
99509
99510 memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace);
 
99511 zWrite += iSpace;
99512 nWrite -= iSpace;
99513 p->endpoint.iOffset += iSpace;
99514 }
99515 }
@@ -100583,10 +101320,11 @@
100583 }else if( zTab ){
100584 sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
100585 }else{
100586 sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
100587 }
 
100588 pParse->checkSchema = 1;
100589 pTopNC->nNcErr++;
100590 }
100591
100592 /* If a column from a table in pSrcList is referenced, then record
@@ -100691,11 +101429,12 @@
100691 */
100692 static void notValidImpl(
100693 Parse *pParse, /* Leave error message here */
100694 NameContext *pNC, /* The name context */
100695 const char *zMsg, /* Type of error */
100696 Expr *pExpr /* Invalidate this expression on error */
 
100697 ){
100698 const char *zIn = "partial index WHERE clauses";
100699 if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
100700 #ifndef SQLITE_OMIT_CHECK
100701 else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
@@ -100703,14 +101442,15 @@
100703 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
100704 else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns";
100705 #endif
100706 sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
100707 if( pExpr ) pExpr->op = TK_NULL;
 
100708 }
100709 #define sqlite3ResolveNotValid(P,N,M,X,E) \
100710 assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \
100711 if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E);
100712
100713 /*
100714 ** Expression p should encode a floating point value between 1.0 and 0.0.
100715 ** Return 1024 times this value. Or return -1 if p is not a floating point
100716 ** value between 1.0 and 0.0.
@@ -100841,11 +101581,11 @@
100841 }else{
100842 Expr *pLeft = pExpr->pLeft;
100843 testcase( pNC->ncFlags & NC_IdxExpr );
100844 testcase( pNC->ncFlags & NC_GenCol );
100845 sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator",
100846 NC_IdxExpr|NC_GenCol, 0);
100847 pRight = pExpr->pRight;
100848 if( pRight->op==TK_ID ){
100849 zDb = 0;
100850 }else{
100851 assert( pRight->op==TK_DOT );
@@ -100872,21 +101612,19 @@
100872 ExprList *pList = pExpr->x.pList; /* The argument list */
100873 int n = pList ? pList->nExpr : 0; /* Number of arguments */
100874 int no_such_func = 0; /* True if no such function exists */
100875 int wrong_num_args = 0; /* True if wrong number of arguments */
100876 int is_agg = 0; /* True if is an aggregate function */
100877 int nId; /* Number of characters in function name */
100878 const char *zId; /* The function name. */
100879 FuncDef *pDef; /* Information about the function */
100880 u8 enc = ENC(pParse->db); /* The database encoding */
100881 int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
100882 #ifndef SQLITE_OMIT_WINDOWFUNC
100883 Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
100884 #endif
100885 assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
100886 zId = pExpr->u.zToken;
100887 nId = sqlite3Strlen30(zId);
100888 pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
100889 if( pDef==0 ){
100890 pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
100891 if( pDef==0 ){
100892 no_such_func = 1;
@@ -100899,12 +101637,12 @@
100899 ExprSetProperty(pExpr, EP_Unlikely);
100900 if( n==2 ){
100901 pExpr->iTable = exprProbability(pList->a[1].pExpr);
100902 if( pExpr->iTable<0 ){
100903 sqlite3ErrorMsg(pParse,
100904 "second argument to likelihood() must be a "
100905 "constant between 0.0 and 1.0");
100906 pNC->nNcErr++;
100907 }
100908 }else{
100909 /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
100910 ** equivalent to likelihood(X, 0.0625).
@@ -100921,12 +101659,12 @@
100921 #ifndef SQLITE_OMIT_AUTHORIZATION
100922 {
100923 int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
100924 if( auth!=SQLITE_OK ){
100925 if( auth==SQLITE_DENY ){
100926 sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
100927 pDef->zName);
100928 pNC->nNcErr++;
100929 }
100930 pExpr->op = TK_NULL;
100931 return WRC_Prune;
100932 }
@@ -100945,11 +101683,11 @@
100945 ** sqlite_version() that might change over time cannot be used
100946 ** in an index or generated column. Curiously, they can be used
100947 ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
100948 ** all this. */
100949 sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
100950 NC_IdxExpr|NC_PartIdx|NC_GenCol, 0);
100951 }else{
100952 assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
100953 pExpr->op2 = pNC->ncFlags & NC_SelfRef;
100954 if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
100955 }
@@ -100958,11 +101696,11 @@
100958 && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
100959 ){
100960 /* Internal-use-only functions are disallowed unless the
100961 ** SQL is being compiled using sqlite3NestedParse() or
100962 ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
100963 ** used to activate internal functionsn for testing purposes */
100964 no_such_func = 1;
100965 pDef = 0;
100966 }else
100967 if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
100968 && !IN_RENAME_OBJECT
@@ -100977,11 +101715,11 @@
100977 || (pDef->xValue==0 && pDef->xInverse==0)
100978 || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
100979 );
100980 if( pDef && pDef->xValue==0 && pWin ){
100981 sqlite3ErrorMsg(pParse,
100982 "%.*s() may not be used as a window function", nId, zId
100983 );
100984 pNC->nNcErr++;
100985 }else if(
100986 (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
100987 || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin)
@@ -100991,38 +101729,38 @@
100991 if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){
100992 zType = "window";
100993 }else{
100994 zType = "aggregate";
100995 }
100996 sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
100997 pNC->nNcErr++;
100998 is_agg = 0;
100999 }
101000 #else
101001 if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
101002 sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId);
101003 pNC->nNcErr++;
101004 is_agg = 0;
101005 }
101006 #endif
101007 else if( no_such_func && pParse->db->init.busy==0
101008 #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
101009 && pParse->explain==0
101010 #endif
101011 ){
101012 sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
101013 pNC->nNcErr++;
101014 }else if( wrong_num_args ){
101015 sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
101016 nId, zId);
101017 pNC->nNcErr++;
101018 }
101019 #ifndef SQLITE_OMIT_WINDOWFUNC
101020 else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
101021 sqlite3ErrorMsg(pParse,
101022 "FILTER may not be used with non-aggregate %.*s()",
101023 nId, zId
101024 );
101025 pNC->nNcErr++;
101026 }
101027 #endif
101028 if( is_agg ){
@@ -101103,11 +101841,11 @@
101103 testcase( pNC->ncFlags & NC_IsCheck );
101104 testcase( pNC->ncFlags & NC_PartIdx );
101105 testcase( pNC->ncFlags & NC_IdxExpr );
101106 testcase( pNC->ncFlags & NC_GenCol );
101107 if( pNC->ncFlags & NC_SelfRef ){
101108 notValidImpl(pParse, pNC, "subqueries", pExpr);
101109 }else{
101110 sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
101111 }
101112 assert( pNC->nRef>=nRef );
101113 if( nRef!=pNC->nRef ){
@@ -101121,11 +101859,11 @@
101121 testcase( pNC->ncFlags & NC_IsCheck );
101122 testcase( pNC->ncFlags & NC_PartIdx );
101123 testcase( pNC->ncFlags & NC_IdxExpr );
101124 testcase( pNC->ncFlags & NC_GenCol );
101125 sqlite3ResolveNotValid(pParse, pNC, "parameters",
101126 NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr);
101127 break;
101128 }
101129 case TK_IS:
101130 case TK_ISNOT: {
101131 Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
@@ -101173,10 +101911,11 @@
101173 testcase( pExpr->op==TK_GE );
101174 testcase( pExpr->op==TK_IS );
101175 testcase( pExpr->op==TK_ISNOT );
101176 testcase( pExpr->op==TK_BETWEEN );
101177 sqlite3ErrorMsg(pParse, "row value misused");
 
101178 }
101179 break;
101180 }
101181 }
101182 assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
@@ -101286,15 +102025,17 @@
101286 */
101287 static void resolveOutOfRangeError(
101288 Parse *pParse, /* The error context into which to write the error */
101289 const char *zType, /* "ORDER" or "GROUP" */
101290 int i, /* The index (1-based) of the term out of range */
101291 int mx /* Largest permissible value of i */
 
101292 ){
101293 sqlite3ErrorMsg(pParse,
101294 "%r %s BY term out of range - should be "
101295 "between 1 and %d", i, zType, mx);
 
101296 }
101297
101298 /*
101299 ** Analyze the ORDER BY clause in a compound SELECT statement. Modify
101300 ** each term of the ORDER BY clause is a constant integer between 1
@@ -101346,11 +102087,11 @@
101346 if( pItem->done ) continue;
101347 pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
101348 if( NEVER(pE==0) ) continue;
101349 if( sqlite3ExprIsInteger(pE, &iCol) ){
101350 if( iCol<=0 || iCol>pEList->nExpr ){
101351 resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
101352 return 1;
101353 }
101354 }else{
101355 iCol = resolveAsName(pParse, pEList, pE);
101356 if( iCol==0 ){
@@ -101442,11 +102183,11 @@
101442 pEList = pSelect->pEList;
101443 assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
101444 for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
101445 if( pItem->u.x.iOrderByCol ){
101446 if( pItem->u.x.iOrderByCol>pEList->nExpr ){
101447 resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
101448 return 1;
101449 }
101450 resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0);
101451 }
101452 }
@@ -101534,11 +102275,11 @@
101534 if( sqlite3ExprIsInteger(pE2, &iCol) ){
101535 /* The ORDER BY term is an integer constant. Again, set the column
101536 ** number so that sqlite3ResolveOrderGroupBy() will convert the
101537 ** order-by term to a copy of the result-set expression */
101538 if( iCol<1 || iCol>0xffff ){
101539 resolveOutOfRangeError(pParse, zType, i+1, nResult);
101540 return 1;
101541 }
101542 pItem->u.x.iOrderByCol = (u16)iCol;
101543 continue;
101544 }
@@ -102787,13 +103528,12 @@
102787 **
102788 ** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
102789 ** if appropriate.
102790 */
102791 static void exprSetHeight(Expr *p){
102792 int nHeight = 0;
102793 heightOfExpr(p->pLeft, &nHeight);
102794 heightOfExpr(p->pRight, &nHeight);
102795 if( ExprUseXSelect(p) ){
102796 heightOfSelect(p->x.pSelect, &nHeight);
102797 }else if( p->x.pList ){
102798 heightOfExprList(p->x.pList, &nHeight);
102799 p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
@@ -103088,10 +103828,11 @@
103088 pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
103089 if( pNew==0 ){
103090 sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
103091 return 0;
103092 }
 
103093 if( pList
103094 && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
103095 && !pParse->nested
103096 ){
103097 sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
@@ -103131,11 +103872,11 @@
103131 ** (2) not tagged with SQLITE_INNOCUOUS (which means it
103132 ** is tagged with SQLITE_FUNC_UNSAFE) and
103133 ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
103134 ** that the schema is possibly tainted).
103135 */
103136 sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName);
103137 }
103138 }
103139 }
103140
103141 /*
@@ -103187,10 +103928,11 @@
103187 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
103188 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
103189 if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103190 sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
103191 db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
 
103192 return;
103193 }
103194 x = (ynVar)i;
103195 if( x>pParse->nVar ){
103196 pParse->nVar = (int)x;
@@ -103214,10 +103956,11 @@
103214 }
103215 }
103216 pExpr->iColumn = x;
103217 if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103218 sqlite3ErrorMsg(pParse, "too many SQL variables");
 
103219 }
103220 }
103221
103222 /*
103223 ** Recursively delete an expression tree.
@@ -105056,12 +105799,11 @@
105056 assert( !ExprUseYWin(pExpr) );
105057 ExprSetProperty(pExpr, EP_Subrtn);
105058 assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
105059 pExpr->y.sub.regReturn = ++pParse->nMem;
105060 pExpr->y.sub.iAddr =
105061 sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
105062 VdbeComment((v, "return address"));
105063
105064 addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
105065 }
105066
105067 /* Check to see if this is a vector IN operator */
@@ -105159,10 +105901,11 @@
105159 ** disable the test that was generated above that makes sure
105160 ** this code only executes once. Because for a non-constant
105161 ** expression we need to rerun this code each time.
105162 */
105163 if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
 
105164 sqlite3VdbeChangeToNoop(v, addrOnce);
105165 ExprClearProperty(pExpr, EP_Subrtn);
105166 addrOnce = 0;
105167 }
105168
@@ -105179,11 +105922,14 @@
105179 }
105180 if( addrOnce ){
105181 sqlite3VdbeJumpHere(v, addrOnce);
105182 /* Subroutine return */
105183 assert( ExprUseYSub(pExpr) );
105184 sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
 
 
 
105185 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105186 sqlite3ClearTempRegCache(pParse);
105187 }
105188 }
105189 #endif /* SQLITE_OMIT_SUBQUERY */
@@ -105234,13 +105980,11 @@
105234 assert( !ExprUseYWin(pExpr) );
105235 assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
105236 ExprSetProperty(pExpr, EP_Subrtn);
105237 pExpr->y.sub.regReturn = ++pParse->nMem;
105238 pExpr->y.sub.iAddr =
105239 sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
105240 VdbeComment((v, "return address"));
105241
105242
105243 /* The evaluation of the EXISTS/SELECT must be repeated every time it
105244 ** is encountered if any of the following is true:
105245 **
105246 ** * The right-hand side is a correlated subquery
@@ -105309,11 +106053,14 @@
105309 sqlite3VdbeJumpHere(v, addrOnce);
105310 }
105311
105312 /* Subroutine return */
105313 assert( ExprUseYSub(pExpr) );
105314 sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
 
 
 
105315 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105316 sqlite3ClearTempRegCache(pParse);
105317 return rReg;
105318 }
105319 #endif /* SQLITE_OMIT_SUBQUERY */
@@ -105515,11 +106262,10 @@
105515 if( destIfNull==destIfFalse ){
105516 destStep2 = destIfFalse;
105517 }else{
105518 destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
105519 }
105520 // if( pParse->nErr ) goto sqlite3ExprCodeIN_finished;
105521 for(i=0; i<nVector; i++){
105522 Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
105523 if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error;
105524 if( sqlite3ExprCanBeNull(p) ){
105525 sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
@@ -105656,15 +106402,16 @@
105656 const char *z = pExpr->u.zToken;
105657 assert( z!=0 );
105658 c = sqlite3DecOrHexToI64(z, &value);
105659 if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
105660 #ifdef SQLITE_OMIT_FLOATING_POINT
105661 sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
105662 #else
105663 #ifndef SQLITE_OMIT_HEX_INTEGER
105664 if( sqlite3_strnicmp(z,"0x",2)==0 ){
105665 sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z);
 
105666 }else
105667 #endif
105668 {
105669 codeReal(v, z, negFlag, iMem);
105670 }
@@ -106336,11 +107083,11 @@
106336 if( pInfo==0
106337 || NEVER(pExpr->iAgg<0)
106338 || NEVER(pExpr->iAgg>=pInfo->nFunc)
106339 ){
106340 assert( !ExprHasProperty(pExpr, EP_IntValue) );
106341 sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
106342 }else{
106343 return pInfo->aFunc[pExpr->iAgg].iMem;
106344 }
106345 break;
106346 }
@@ -106377,11 +107124,11 @@
106377 if( pDef==0 && pParse->explain ){
106378 pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
106379 }
106380 #endif
106381 if( pDef==0 || pDef->xFinalize!=0 ){
106382 sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
106383 break;
106384 }
106385 if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
106386 assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
106387 assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
@@ -109000,11 +109747,11 @@
109000 if( !zOld ) goto exit_rename_column;
109001 for(iCol=0; iCol<pTab->nCol; iCol++){
109002 if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break;
109003 }
109004 if( iCol==pTab->nCol ){
109005 sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
109006 goto exit_rename_column;
109007 }
109008
109009 /* Ensure the schema contains no double-quoted strings */
109010 renameTestSchema(pParse, zDb, iSchema==1, "", 0);
@@ -109430,16 +110177,16 @@
109430 ){
109431 const char *zT = (const char*)sqlite3_value_text(pType);
109432 const char *zN = (const char*)sqlite3_value_text(pObject);
109433 char *zErr;
109434
109435 zErr = sqlite3_mprintf("error in %s %s%s%s: %s",
109436 zT, zN, (zWhen[0] ? " " : ""), zWhen,
109437 pParse->zErrMsg
109438 );
109439 sqlite3_result_error(pCtx, zErr, -1);
109440 sqlite3_free(zErr);
109441 }
109442
109443 /*
109444 ** For each name in the the expression-list pEList (i.e. each
109445 ** pEList->a[i].zName) that matches the string in zOld, extract the
@@ -109500,23 +110247,25 @@
109500 const char *zSql, /* SQL to parse */
109501 int bTemp /* True if SQL is from temp schema */
109502 ){
109503 int rc;
109504
109505 db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
109506
109507 /* Parse the SQL statement passed as the first argument. If no error
109508 ** occurs and the parse does not result in a new table, index or
109509 ** trigger object, the database must be corrupt. */
109510 sqlite3ParseObjectInit(p, db);
 
 
 
 
 
 
 
109511 p->eParseMode = PARSE_MODE_RENAME;
109512 p->db = db;
109513 p->nQueryLoop = 1;
109514 rc = zSql ? sqlite3RunParser(p, zSql) : SQLITE_NOMEM;
109515 if( db->mallocFailed ) rc = SQLITE_NOMEM;
109516 if( rc==SQLITE_OK
109517 && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0
109518 ){
109519 rc = SQLITE_CORRUPT_BKPT;
109520 }
109521
109522 #ifdef SQLITE_DEBUG
@@ -109796,11 +110545,11 @@
109796 }
109797
109798 /*
109799 ** SQL function:
109800 **
109801 ** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld)
109802 **
109803 ** 0. zSql: SQL statement to rewrite
109804 ** 1. type: Type of object ("table", "view" etc.)
109805 ** 2. object: Name of object
109806 ** 3. Database: Database name (e.g. "main")
@@ -109814,11 +110563,12 @@
109814 ** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
109815 ** into zNew. The name should be quoted if bQuote is true.
109816 **
109817 ** This function is used internally by the ALTER TABLE RENAME COLUMN command.
109818 ** It is only accessible to SQL created using sqlite3NestedParse(). It is
109819 ** not reachable from ordinary SQL passed into sqlite3_prepare().
 
109820 */
109821 static void renameColumnFunc(
109822 sqlite3_context *context,
109823 int NotUsed,
109824 sqlite3_value **argv
@@ -109963,11 +110713,13 @@
109963 assert( rc==SQLITE_OK );
109964 rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);
109965
109966 renameColumnFunc_done:
109967 if( rc!=SQLITE_OK ){
109968 if( sParse.zErrMsg ){
 
 
109969 renameColumnParseError(context, "", argv[1], argv[2], &sParse);
109970 }else{
109971 sqlite3_result_error_code(context, rc);
109972 }
109973 }
@@ -110162,11 +110914,13 @@
110162
110163 if( rc==SQLITE_OK ){
110164 rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
110165 }
110166 if( rc!=SQLITE_OK ){
110167 if( sParse.zErrMsg ){
 
 
110168 renameColumnParseError(context, "", argv[1], argv[2], &sParse);
110169 }else{
110170 sqlite3_result_error_code(context, rc);
110171 }
110172 }
@@ -110187,14 +110941,14 @@
110187 renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr);
110188 }
110189 return WRC_Continue;
110190 }
110191
110192 /*
110193 ** The implementation of an SQL scalar function that rewrites DDL statements
110194 ** so that any string literals that use double-quotes are modified so that
110195 ** they use single quotes.
110196 **
110197 ** Two arguments must be passed:
110198 **
110199 ** 0: Database name ("main", "temp" etc.).
110200 ** 1: SQL statement to edit.
@@ -110209,10 +110963,14 @@
110209 ** );
110210 **
110211 ** returns the string:
110212 **
110213 ** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1
 
 
 
 
110214 */
110215 static void renameQuotefixFunc(
110216 sqlite3_context *context,
110217 int NotUsed,
110218 sqlite3_value **argv
@@ -110283,11 +111041,15 @@
110283 rc = renameEditSql(context, &sCtx, zInput, 0, 0);
110284 }
110285 renameTokenFree(db, sCtx.pList);
110286 }
110287 if( rc!=SQLITE_OK ){
110288 sqlite3_result_error_code(context, rc);
 
 
 
 
110289 }
110290 renameParseCleanup(&sParse);
110291 }
110292
110293 #ifndef SQLITE_OMIT_AUTHORIZATION
@@ -110295,11 +111057,12 @@
110295 #endif
110296
110297 sqlite3BtreeLeaveAll(db);
110298 }
110299
110300 /*
 
110301 ** An SQL user function that checks that there are no parse or symbol
110302 ** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
110303 ** After an ALTER TABLE .. RENAME operation is performed and the schema
110304 ** reloaded, this function is called on each SQL statement in the schema
110305 ** to ensure that it is still usable.
@@ -110310,15 +111073,17 @@
110310 ** 3: Object name.
110311 ** 4: True if object is from temp schema.
110312 ** 5: "when" part of error message.
110313 ** 6: True to disable the DQS quirk when parsing SQL.
110314 **
110315 ** Unless it finds an error, this function normally returns NULL. However, it
110316 ** returns integer value 1 if:
110317 **
110318 ** * the SQL argument creates a trigger, and
110319 ** * the table that the trigger is attached to is in database zDb.
 
 
 
110320 */
110321 static void renameTableTest(
110322 sqlite3_context *context,
110323 int NotUsed,
110324 sqlite3_value **argv
@@ -110359,16 +111124,20 @@
110359 rc = renameResolveTrigger(&sParse);
110360 }
110361 if( rc==SQLITE_OK ){
110362 int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
110363 int i2 = sqlite3FindDbName(db, zDb);
110364 if( i1==i2 ) sqlite3_result_int(context, 1);
 
 
 
110365 }
110366 }
110367 }
110368
110369 if( rc!=SQLITE_OK && zWhen ){
 
110370 renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse);
110371 }
110372 renameParseCleanup(&sParse);
110373 }
110374
@@ -110480,11 +111249,11 @@
110480 assert( db->mallocFailed );
110481 goto exit_drop_column;
110482 }
110483 iCol = sqlite3ColumnIndex(pTab, zCol);
110484 if( iCol<0 ){
110485 sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zCol);
110486 goto exit_drop_column;
110487 }
110488
110489 /* Do not allow the user to drop a PRIMARY KEY column or a column
110490 ** constrained by a UNIQUE constraint. */
@@ -111633,11 +112402,11 @@
111633 if( pStat1==0 ) return;
111634 pStat1->zName = (char*)&pStat1[1];
111635 memcpy(pStat1->zName, "sqlite_stat1", 13);
111636 pStat1->nCol = 3;
111637 pStat1->iPKey = -1;
111638 sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
111639 }
111640 #endif
111641
111642 /* Establish a read-lock on the table at the shared-cache level.
111643 ** Open a read-only cursor on the table. Also allocate a cursor number
@@ -113629,11 +114398,13 @@
113629 && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr)
113630 ){
113631 int iDb, i;
113632 assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
113633 sqlite3VdbeJumpHere(v, 0);
113634 for(iDb=0; iDb<db->nDb; iDb++){
 
 
113635 Schema *pSchema;
113636 if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
113637 sqlite3VdbeUsesBtree(v, iDb);
113638 pSchema = db->aDb[iDb].pSchema;
113639 sqlite3VdbeAddOp4Int(v,
@@ -113644,11 +114415,11 @@
113644 pSchema->iGeneration /* P4 */
113645 );
113646 if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
113647 VdbeComment((v,
113648 "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
113649 }
113650 #ifndef SQLITE_OMIT_VIRTUALTABLE
113651 for(i=0; i<pParse->nVtabLock; i++){
113652 char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
113653 sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
113654 }
@@ -113748,10 +114519,12 @@
113748 pParse->nested++;
113749 memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
113750 memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
113751 db->mDbFlags |= DBFLAG_PreferBuiltin;
113752 sqlite3RunParser(pParse, zSql);
 
 
113753 db->mDbFlags = savedDbFlags;
113754 sqlite3DbFree(db, zSql);
113755 memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
113756 pParse->nested--;
113757 }
@@ -114708,11 +115481,12 @@
114708 goto begin_table_error;
114709 }
114710 pTable = sqlite3FindTable(db, zName, zDb);
114711 if( pTable ){
114712 if( !noErr ){
114713 sqlite3ErrorMsg(pParse, "table %T already exists", pName);
 
114714 }else{
114715 assert( !db->init.busy || CORRUPT_DB );
114716 sqlite3CodeVerifySchema(pParse, iDb);
114717 sqlite3ForceNotReadOnly(pParse);
114718 }
@@ -116238,10 +117012,15 @@
116238 int regRec; /* A record to be insert into the new table */
116239 int regRowid; /* Rowid of the next row to insert */
116240 int addrInsLoop; /* Top of the loop for inserting rows */
116241 Table *pSelTab; /* A table that describes the SELECT results */
116242
 
 
 
 
 
116243 regYield = ++pParse->nMem;
116244 regRec = ++pParse->nMem;
116245 regRowid = ++pParse->nMem;
116246 assert(pParse->nTab==1);
116247 sqlite3MayAbort(pParse);
@@ -120069,11 +120848,11 @@
120069 **
120070 ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
120071 ** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
120072 ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
120073 */
120074 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
120075 if( pWInfo==0 ) goto delete_from_cleanup;
120076 eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
120077 assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
120078 assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
120079 if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
@@ -120682,10 +121461,11 @@
120682 static void subtypeFunc(
120683 sqlite3_context *context,
120684 int argc,
120685 sqlite3_value **argv
120686 ){
 
120687 sqlite3_result_int(context, sqlite3_value_subtype(argv[0]));
120688 }
120689
120690 /*
120691 ** Implementation of the length() function
@@ -121695,12 +122475,13 @@
121695 UNUSED_PARAMETER(argc);
121696 sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
121697 sqlite3QuoteValue(&str,argv[0]);
121698 sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar,
121699 SQLITE_DYNAMIC);
121700 if( str.accError==SQLITE_NOMEM ){
121701 sqlite3_result_error_nomem(context);
 
121702 }
121703 }
121704
121705 /*
121706 ** The unicode() function. Return the integer unicode code-point value
@@ -122815,12 +123596,12 @@
122815 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
122816 INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122817 INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122818 INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
122819 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
122820 FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET|
122821 SQLITE_FUNC_TYPEOF),
122822 #endif
122823 FUNCTION(ltrim, 1, 1, 0, trimFunc ),
122824 FUNCTION(ltrim, 2, 1, 0, trimFunc ),
122825 FUNCTION(rtrim, 1, 2, 0, trimFunc ),
122826 FUNCTION(rtrim, 2, 2, 0, trimFunc ),
@@ -123612,11 +124393,11 @@
123612
123613 /* Create VDBE to loop through the entries in pSrc that match the WHERE
123614 ** clause. For each row found, increment either the deferred or immediate
123615 ** foreign key constraint counter. */
123616 if( pParse->nErr==0 ){
123617 pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
123618 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
123619 if( pWInfo ){
123620 sqlite3WhereEnd(pWInfo);
123621 }
123622 }
@@ -124620,11 +125401,11 @@
124620 sqlite3OomFault(db);
124621 return;
124622 }
124623
124624 for(i=j=0; i<pTab->nCol; i++){
124625 assert( pTab->aCol[i].affinity!=0 );
124626 if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
124627 zColAff[j++] = pTab->aCol[i].affinity;
124628 }
124629 }
124630 do{
@@ -125234,11 +126015,15 @@
125234 ** Then special optimizations can be applied that make the transfer
125235 ** very fast and which reduce fragmentation of indices.
125236 **
125237 ** This is the 2nd template.
125238 */
125239 if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
 
 
 
 
125240 assert( !pTrigger );
125241 assert( pList==0 );
125242 goto insert_end;
125243 }
125244 #endif /* SQLITE_OMIT_XFER_OPT */
@@ -126717,11 +127502,11 @@
126717 }
126718 }
126719 if( isUpdate ){
126720 /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
126721 ** table, only conflict if the new PRIMARY KEY values are actually
126722 ** different from the old.
126723 **
126724 ** For a UNIQUE index, only conflict if the PRIMARY KEY values
126725 ** of the matched index row are different from the original PRIMARY
126726 ** KEY values of this row before the update. */
126727 int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
@@ -127205,22 +127990,17 @@
127205 Vdbe *v; /* The VDBE we are building */
127206 int regAutoinc; /* Memory register used by AUTOINC */
127207 int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
127208 int regData, regRowid; /* Registers holding data and rowid */
127209
127210 if( pSelect==0 ){
127211 return 0; /* Must be of the form INSERT INTO ... SELECT ... */
127212 }
127213 if( pParse->pWith || pSelect->pWith ){
127214 /* Do not attempt to process this query if there are an WITH clauses
127215 ** attached to it. Proceeding may generate a false "no such table: xxx"
127216 ** error if pSelect reads from a CTE named "xxx". */
127217 return 0;
127218 }
127219 if( sqlite3TriggerList(pParse, pDest) ){
127220 return 0; /* tab1 must not have triggers */
127221 }
127222 #ifndef SQLITE_OMIT_VIRTUALTABLE
127223 if( IsVirtual(pDest) ){
127224 return 0; /* tab1 must not be a virtual table */
127225 }
127226 #endif
@@ -128083,10 +128863,18 @@
128083 void*, void(*)(void*));
128084 /* Version 3.38.0 and later */
128085 int (*error_offset)(sqlite3*);
128086 int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
128087 int (*vtab_distinct)(sqlite3_index_info*);
 
 
 
 
 
 
 
 
128088 };
128089
128090 /*
128091 ** This is the function signature used for all extension entry points. It
128092 ** is also defined in the file "loadext.c".
@@ -128398,10 +129186,17 @@
128398 #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
128399 /* Version 3.38.0 and later */
128400 #define sqlite3_error_offset sqlite3_api->error_offset
128401 #define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
128402 #define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
 
 
 
 
 
 
 
128403 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
128404
128405 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
128406 /* This case when the file really is being compiled as a loadable
128407 ** extension */
@@ -128891,10 +129686,21 @@
128891 sqlite3_autovacuum_pages,
128892 /* Version 3.38.0 and later */
128893 sqlite3_error_offset,
128894 sqlite3_vtab_rhs_value,
128895 sqlite3_vtab_distinct,
 
 
 
 
 
 
 
 
 
 
 
128896 };
128897
128898 /* True if x is the directory separator character
128899 */
128900 #if SQLITE_OS_WIN
@@ -129561,11 +130367,11 @@
129561 /* iArg: */ BTREE_DATA_VERSION },
129562 #endif
129563 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
129564 {/* zName: */ "database_list",
129565 /* ePragTyp: */ PragTyp_DATABASE_LIST,
129566 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
129567 /* ColNames: */ 47, 3,
129568 /* iArg: */ 0 },
129569 #endif
129570 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
129571 {/* zName: */ "default_cache_size",
@@ -130249,19 +131055,20 @@
130249 Vdbe *v, /* The prepared statement being created */
130250 FuncDef *p, /* A particular function definition */
130251 int isBuiltin, /* True if this is a built-in function */
130252 int showInternFuncs /* True if showing internal functions */
130253 ){
 
 
 
 
 
 
 
 
130254 for(; p; p=p->pNext){
130255 const char *zType;
130256 static const u32 mask =
130257 SQLITE_DETERMINISTIC |
130258 SQLITE_DIRECTONLY |
130259 SQLITE_SUBTYPE |
130260 SQLITE_INNOCUOUS |
130261 SQLITE_FUNC_INTERNAL
130262 ;
130263 static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" };
130264
130265 assert( SQLITE_FUNC_ENCMASK==0x3 );
130266 assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 );
130267 assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 );
@@ -130749,11 +131556,11 @@
130749 **
130750 ** Do N steps of incremental vacuuming on a database.
130751 */
130752 #ifndef SQLITE_OMIT_AUTOVACUUM
130753 case PragTyp_INCREMENTAL_VACUUM: {
130754 int iLimit, addr;
130755 if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){
130756 iLimit = 0x7fffffff;
130757 }
130758 sqlite3BeginWriteOperation(pParse, 0, iDb);
130759 sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
@@ -133053,11 +133860,11 @@
133053 if( db->mallocFailed ){
133054 rc = SQLITE_NOMEM_BKPT;
133055 sqlite3ResetAllSchemasOfConnection(db);
133056 pDb = &db->aDb[iDb];
133057 }else
133058 if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
133059 /* Hack: If the SQLITE_NoSchemaError flag is set, then consider
133060 ** the schema loaded, even if errors (other than OOM) occurred. In
133061 ** this situation the current sqlite3_prepare() operation will fail,
133062 ** but the following one will attempt to compile the supplied statement
133063 ** against whatever subset of the schema was loaded before the error
@@ -133324,10 +134131,11 @@
133324 memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
133325 assert( db->pParse!=pParse );
133326 pParse->pOuterParse = db->pParse;
133327 db->pParse = pParse;
133328 pParse->db = db;
 
133329 }
133330
133331 /*
133332 ** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
133333 */
@@ -133350,11 +134158,11 @@
133350 sParse.pOuterParse = db->pParse;
133351 db->pParse = &sParse;
133352 sParse.db = db;
133353 sParse.pReprepare = pReprepare;
133354 assert( ppStmt && *ppStmt==0 );
133355 /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
133356 assert( sqlite3_mutex_held(db->mutex) );
133357
133358 /* For a long-term use prepared statement avoid the use of
133359 ** lookaside memory.
133360 */
@@ -133741,11 +134549,11 @@
133741 ** how to process the DISTINCT keyword, to simplify passing that information
133742 ** into the selectInnerLoop() routine.
133743 */
133744 typedef struct DistinctCtx DistinctCtx;
133745 struct DistinctCtx {
133746 u8 isTnct; /* True if the DISTINCT keyword is present */
133747 u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */
133748 int tabTnct; /* Ephemeral table used for DISTINCT processing */
133749 int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */
133750 };
133751
@@ -134074,29 +134882,29 @@
134074 ** sqlite3PExpr(). */
134075 if( pEq && isOuterJoin ){
134076 ExprSetProperty(pEq, EP_FromJoin);
134077 assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
134078 ExprSetVVAProperty(pEq, EP_NoReduce);
134079 pEq->iRightJoinTable = pE2->iTable;
134080 }
134081 *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
134082 }
134083
134084 /*
134085 ** Set the EP_FromJoin property on all terms of the given expression.
134086 ** And set the Expr.iRightJoinTable to iTable for every term in the
134087 ** expression.
134088 **
134089 ** The EP_FromJoin property is used on terms of an expression to tell
134090 ** the LEFT OUTER JOIN processing logic that this term is part of the
134091 ** join restriction specified in the ON or USING clause and not a part
134092 ** of the more general WHERE clause. These terms are moved over to the
134093 ** WHERE clause during join processing but we need to remember that they
134094 ** originated in the ON or USING clause.
134095 **
134096 ** The Expr.iRightJoinTable tells the WHERE clause processing that the
134097 ** expression depends on table iRightJoinTable even if that table is not
134098 ** explicitly mentioned in the expression. That information is needed
134099 ** for cases like this:
134100 **
134101 ** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
134102 **
@@ -134110,11 +134918,11 @@
134110 SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){
134111 while( p ){
134112 ExprSetProperty(p, EP_FromJoin);
134113 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
134114 ExprSetVVAProperty(p, EP_NoReduce);
134115 p->iRightJoinTable = iTable;
134116 if( p->op==TK_FUNCTION ){
134117 assert( ExprUseXList(p) );
134118 if( p->x.pList ){
134119 int i;
134120 for(i=0; i<p->x.pList->nExpr; i++){
@@ -134126,19 +134934,19 @@
134126 p = p->pRight;
134127 }
134128 }
134129
134130 /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
134131 ** term that is marked with EP_FromJoin and iRightJoinTable==iTable into
134132 ** an ordinary term that omits the EP_FromJoin mark.
134133 **
134134 ** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
134135 */
134136 static void unsetJoinExpr(Expr *p, int iTable){
134137 while( p ){
134138 if( ExprHasProperty(p, EP_FromJoin)
134139 && (iTable<0 || p->iRightJoinTable==iTable) ){
134140 ExprClearProperty(p, EP_FromJoin);
134141 }
134142 if( p->op==TK_COLUMN && p->iTable==iTable ){
134143 ExprClearProperty(p, EP_CanBeNull);
134144 }
@@ -136343,11 +137151,11 @@
136343 ** (3) There is no ORDER BY clause
136344 **
136345 ** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
136346 ** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
136347 ** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
136348 ** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
136349 */
136350 static int multiSelectValues(
136351 Parse *pParse, /* Parsing context */
136352 Select *p, /* The right-most of SELECTs to be coded */
136353 SelectDest *pDest /* What to do with query results */
@@ -137368,13 +138176,13 @@
137368 SubstContext *pSubst, /* Description of the substitution */
137369 Expr *pExpr /* Expr in which substitution occurs */
137370 ){
137371 if( pExpr==0 ) return 0;
137372 if( ExprHasProperty(pExpr, EP_FromJoin)
137373 && pExpr->iRightJoinTable==pSubst->iTable
137374 ){
137375 pExpr->iRightJoinTable = pSubst->iNewTable;
137376 }
137377 if( pExpr->op==TK_COLUMN
137378 && pExpr->iTable==pSubst->iTable
137379 && !ExprHasProperty(pExpr, EP_FixedCol)
137380 ){
@@ -137409,11 +138217,11 @@
137409 }
137410 if( pSubst->isLeftJoin ){
137411 ExprSetProperty(pNew, EP_CanBeNull);
137412 }
137413 if( ExprHasProperty(pExpr,EP_FromJoin) ){
137414 sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable);
137415 }
137416 sqlite3ExprDelete(db, pExpr);
137417 pExpr = pNew;
137418
137419 /* Ensure that the expression now has an implicit collation sequence,
@@ -137574,11 +138382,11 @@
137574 int op = pExpr->op;
137575 if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
137576 renumberCursorDoMapping(pWalker, &pExpr->iTable);
137577 }
137578 if( ExprHasProperty(pExpr, EP_FromJoin) ){
137579 renumberCursorDoMapping(pWalker, &pExpr->iRightJoinTable);
137580 }
137581 return WRC_Continue;
137582 }
137583
137584 /*
@@ -138584,15 +139392,17 @@
138584 iCursor, isLeftJoin);
138585 pWhere = pWhere->pLeft;
138586 }
138587 if( isLeftJoin
138588 && (ExprHasProperty(pWhere,EP_FromJoin)==0
138589 || pWhere->iRightJoinTable!=iCursor)
138590 ){
138591 return 0; /* restriction (4) */
138592 }
138593 if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
 
 
138594 return 0; /* restriction (5) */
138595 }
138596 if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
138597 nChng++;
138598 pSubq->selFlags |= SF_PushDown;
@@ -140539,10 +141349,11 @@
140539 p->selFlags |= SF_Aggregate;
140540 /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
140541 ** the sDistinct.isTnct is still set. Hence, isTnct represents the
140542 ** original setting of the SF_Distinct flag, not the current setting */
140543 assert( sDistinct.isTnct );
 
140544
140545 #if SELECTTRACE_ENABLED
140546 if( sqlite3SelectTrace & 0x400 ){
140547 SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
140548 sqlite3TreeViewSelect(0, p, 0);
@@ -140618,11 +141429,11 @@
140618
140619
140620 /* Begin the database scan. */
140621 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
140622 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
140623 p->pEList, wctrlFlags, p->nSelectRow);
140624 if( pWInfo==0 ) goto select_end;
140625 if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
140626 p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
140627 }
140628 if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
@@ -140882,11 +141693,12 @@
140882 ** in the right order to begin with.
140883 */
140884 sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
140885 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
140886 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct,
140887 WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
 
140888 );
140889 if( pWInfo==0 ){
140890 sqlite3ExprListDelete(db, pDistinct);
140891 goto select_end;
140892 }
@@ -141064,11 +141876,11 @@
141064 resetAccumulator(pParse, pAggInfo);
141065 sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
141066 VdbeComment((v, "indicate accumulator empty"));
141067 sqlite3VdbeAddOp1(v, OP_Return, regReset);
141068
141069 if( eDist!=WHERE_DISTINCT_NOOP ){
141070 struct AggInfo_func *pF = &pAggInfo->aFunc[0];
141071 fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
141072 }
141073 } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
141074 else {
@@ -141180,11 +141992,11 @@
141180 assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
141181 assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
141182
141183 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
141184 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
141185 pDistinct, minMaxFlag|distFlag, 0);
141186 if( pWInfo==0 ){
141187 goto select_end;
141188 }
141189 SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
141190 eDist = sqlite3WhereIsDistinct(pWInfo);
@@ -141538,15 +142350,14 @@
141538 && 0==sqlite3StrICmp(pTrig->table, pTab->zName)
141539 && pTrig->pTabSchema!=pTmpSchema
141540 ){
141541 pTrig->pNext = pList;
141542 pList = pTrig;
141543 }else if( pTrig->op==TK_RETURNING
141544 #ifndef SQLITE_OMIT_VIRTUALTABLE
141545 && pParse->db->pVtabCtx==0
141546 #endif
141547 ){
141548 assert( pParse->bReturning );
141549 assert( &(pParse->u1.pReturning->retTrig) == pTrig );
141550 pTrig->table = pTab->zName;
141551 pTrig->pTabSchema = pTab->pSchema;
141552 pTrig->pNext = pList;
@@ -141917,10 +142728,11 @@
141917 const char *zEnd /* End of SQL text */
141918 ){
141919 sqlite3 *db = pParse->db;
141920 TriggerStep *pTriggerStep;
141921
 
141922 pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
141923 if( pTriggerStep ){
141924 char *z = (char*)&pTriggerStep[1];
141925 memcpy(z, pName->z, pName->n);
141926 sqlite3Dequote(z);
@@ -142707,10 +143519,11 @@
142707 );
142708
142709 /* If an existing TriggerPrg could not be located, create a new one. */
142710 if( !pPrg ){
142711 pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
 
142712 }
142713
142714 return pPrg;
142715 }
142716
@@ -143623,11 +144436,11 @@
143623 ** or index, causing a single-pass approach to malfunction. */
143624 flags = WHERE_ONEPASS_DESIRED;
143625 if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
143626 flags |= WHERE_ONEPASS_MULTIROW;
143627 }
143628 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags,iIdxCur);
143629 if( pWInfo==0 ) goto update_cleanup;
143630
143631 /* A one-pass strategy that might update more than one row may not
143632 ** be used if any column of the index used for the scan is being
143633 ** updated. Otherwise, if there is an index on "b", statements like
@@ -144145,11 +144958,13 @@
144145 }else{
144146 regRec = ++pParse->nMem;
144147 regRowid = ++pParse->nMem;
144148
144149 /* Start scanning the virtual table */
144150 pWInfo = sqlite3WhereBegin(pParse, pSrc,pWhere,0,0,WHERE_ONEPASS_DESIRED,0);
 
 
144151 if( pWInfo==0 ) return;
144152
144153 /* Populate the argument registers. */
144154 for(i=0; i<pTab->nCol; i++){
144155 assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 );
@@ -145792,10 +146607,11 @@
145792 pTab = pCtx->pTab;
145793 assert( IsVirtual(pTab) );
145794
145795 sqlite3ParseObjectInit(&sParse, db);
145796 sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
 
145797 /* We should never be able to reach this point while loading the
145798 ** schema. Nevertheless, defend against that (turn off db->init.busy)
145799 ** in case a bug arises. */
145800 assert( db->init.busy==0 );
145801 initBusy = db->init.busy;
@@ -146456,14 +147272,16 @@
146456 u16 nDistinctCol; /* Index columns used to sort for DISTINCT */
146457 Index *pIndex; /* Index used, or NULL */
146458 } btree;
146459 struct { /* Information for virtual tables */
146460 int idxNum; /* Index number */
146461 u8 needFree; /* True if sqlite3_free(idxStr) is needed */
 
146462 i8 isOrdered; /* True if satisfies ORDER BY */
146463 u16 omitMask; /* Terms that may be omitted */
146464 char *idxStr; /* Index identifier string */
 
146465 } vtab;
146466 } u;
146467 u32 wsFlags; /* WHERE_* flags describing the plan */
146468 u16 nLTerm; /* Number of entries in aLTerm[] */
146469 u16 nSkip; /* Number of NULL aLTerm[] entries */
@@ -146616,10 +147434,11 @@
146616 #ifdef SQLITE_ENABLE_STAT4
146617 # define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */
146618 #else
146619 # define TERM_HIGHTRUTH 0 /* Only used with STAT4 */
146620 #endif
 
146621
146622 /*
146623 ** An instance of the WhereScan object is used as an iterator for locating
146624 ** terms in the WHERE clause that are useful to the query planner.
146625 */
@@ -146786,10 +147605,13 @@
146786 Parse *pParse; /* Parsing and code generating context */
146787 SrcList *pTabList; /* List of tables in the join */
146788 ExprList *pOrderBy; /* The ORDER BY clause or NULL */
146789 ExprList *pResultSet; /* Result set of the query */
146790 Expr *pWhere; /* The complete WHERE clause */
 
 
 
146791 int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
146792 int iContinue; /* Jump here to continue with next record */
146793 int iBreak; /* Jump here to break out of the loop */
146794 int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
146795 u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
@@ -146871,10 +147693,11 @@
146871
146872 /* whereexpr.c: */
146873 SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
146874 SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
146875 SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
 
146876 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
146877 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
146878 SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
146879 SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
146880 SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
@@ -146941,10 +147764,11 @@
146941 #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
146942 #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
146943 #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
146944 #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
146945 #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
 
146946
146947 #endif /* !defined(SQLITE_WHEREINT_H) */
146948
146949 /************** End of whereInt.h ********************************************/
146950 /************** Continuing where we left off in wherecode.c ******************/
@@ -147719,10 +148543,11 @@
147719 sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
147720 VdbeCoverageIf(v, bRev==0);
147721 VdbeCoverageIf(v, bRev!=0);
147722 VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
147723 j = sqlite3VdbeAddOp0(v, OP_Goto);
 
147724 pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
147725 iIdxCur, 0, regBase, nSkip);
147726 VdbeCoverageIf(v, bRev==0);
147727 VdbeCoverageIf(v, bRev!=0);
147728 sqlite3VdbeJumpHere(v, j);
@@ -147989,11 +148814,11 @@
147989 ** are also excluded. See codeCursorHintIsOrFunction() for details.
147990 */
147991 if( pTabItem->fg.jointype & JT_LEFT ){
147992 Expr *pExpr = pTerm->pExpr;
147993 if( !ExprHasProperty(pExpr, EP_FromJoin)
147994 || pExpr->iRightJoinTable!=pTabItem->iCursor
147995 ){
147996 sWalker.eCode = 0;
147997 sWalker.xExprCallback = codeCursorHintIsOrFunction;
147998 sqlite3WalkExpr(&sWalker, pTerm->pExpr);
147999 if( sWalker.eCode ) continue;
@@ -148044,18 +148869,26 @@
148044 ** rowid stored in register iRowid.
148045 **
148046 ** Normally, this is just:
148047 **
148048 ** OP_DeferredSeek $iCur $iRowid
 
 
148049 **
148050 ** However, if the scan currently being coded is a branch of an OR-loop and
148051 ** the statement currently being coded is a SELECT, then P3 of OP_DeferredSeek
148052 ** is set to iIdxCur and P4 is set to point to an array of integers
148053 ** containing one entry for each column of the table cursor iCur is open
148054 ** on. For each table column, if the column is the i'th column of the
148055 ** index, then the corresponding array entry is set to (i+1). If the column
148056 ** does not appear in the index at all, the array entry is set to 0.
 
 
 
 
 
 
148057 */
148058 static void codeDeferredSeek(
148059 WhereInfo *pWInfo, /* Where clause context */
148060 Index *pIdx, /* Index scan is using */
148061 int iCur, /* Cursor for IPK b-tree */
@@ -148316,10 +149149,11 @@
148316 ){
148317 while( ++iLevel < pWInfo->nLevel ){
148318 WhereLevel *pLevel = &pWInfo->a[iLevel];
148319 WhereLoop *pLoop = pLevel->pWLoop;
148320 if( pLevel->regFilter==0 ) continue;
 
148321 /* ,--- Because sqlite3ConstructBloomFilter() has will not have set
148322 ** vvvvv--' pLevel->regFilter if this were true. */
148323 if( NEVER(pLoop->prereq & notReady) ) continue;
148324 if( pLoop->wsFlags & WHERE_IPK ){
148325 WhereTerm *pTerm = pLoop->aLTerm[0];
@@ -148450,24 +149284,39 @@
148450 ** to access the data.
148451 */
148452 int iReg; /* P3 Value for OP_VFilter */
148453 int addrNotFound;
148454 int nConstraint = pLoop->nLTerm;
148455 int iIn; /* Counter for IN constraints */
148456
148457 iReg = sqlite3GetTempRange(pParse, nConstraint+2);
148458 addrNotFound = pLevel->addrBrk;
148459 for(j=0; j<nConstraint; j++){
148460 int iTarget = iReg+j+2;
148461 pTerm = pLoop->aLTerm[j];
148462 if( NEVER(pTerm==0) ) continue;
148463 if( pTerm->eOperator & WO_IN ){
148464 codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
148465 addrNotFound = pLevel->addrNxt;
 
 
 
 
 
 
 
148466 }else{
148467 Expr *pRight = pTerm->pExpr->pRight;
148468 codeExprOrVector(pParse, pRight, iTarget, 1);
 
 
 
 
 
 
 
 
 
148469 }
148470 }
148471 sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
148472 sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
148473 sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
@@ -148480,61 +149329,71 @@
148480 if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
148481 pLevel->p1 = iCur;
148482 pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
148483 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148484 assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
148485 if( pLoop->wsFlags & WHERE_IN_ABLE ){
148486 iIn = pLevel->u.in.nIn;
148487 }else{
148488 iIn = 0;
148489 }
148490 for(j=nConstraint-1; j>=0; j--){
148491 pTerm = pLoop->aLTerm[j];
148492 if( (pTerm->eOperator & WO_IN)!=0 ) iIn--;
148493 if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
148494 disableTerm(pLevel, pTerm);
148495 }else if( (pTerm->eOperator & WO_IN)!=0
148496 && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1
 
 
 
148497 ){
148498 Expr *pCompare; /* The comparison operator */
148499 Expr *pRight; /* RHS of the comparison */
148500 VdbeOp *pOp; /* Opcode to access the value of the IN constraint */
 
148501
148502 /* Reload the constraint value into reg[iReg+j+2]. The same value
148503 ** was loaded into the same register prior to the OP_VFilter, but
148504 ** the xFilter implementation might have changed the datatype or
148505 ** encoding of the value in the register, so it *must* be reloaded. */
148506 assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
148507 if( !db->mallocFailed ){
148508 assert( iIn>=0 && iIn<pLevel->u.in.nIn );
148509 pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop);
148510 assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
148511 assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
148512 assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
148513 testcase( pOp->opcode==OP_Rowid );
148514 sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
 
 
148515 }
148516
148517 /* Generate code that will continue to the next row if
148518 ** the IN constraint is not satisfied */
 
148519 pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
148520 assert( pCompare!=0 || db->mallocFailed );
148521 if( pCompare ){
148522 pCompare->pLeft = pTerm->pExpr->pLeft;
 
 
 
 
 
 
 
 
 
148523 pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
148524 if( pRight ){
148525 pRight->iTable = iReg+j+2;
148526 sqlite3ExprIfFalse(
148527 pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL
148528 );
148529 }
148530 pCompare->pLeft = 0;
148531 sqlite3ExprDelete(db, pCompare);
148532 }
 
148533 }
148534 }
148535 assert( iIn==0 || db->mallocFailed );
148536 /* These registers need to be preserved in case there is an IN operator
148537 ** loop. So we could deallocate the registers here (and potentially
148538 ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
148539 ** simpler and safer to simply not reuse the registers.
148540 **
@@ -149222,11 +150081,11 @@
149222 regRowid = ++pParse->nMem;
149223 }
149224 iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
149225
149226 /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
149227 ** Then for every term xN, evaluate as the subexpression: xN AND z
149228 ** That way, terms in y that are factored into the disjunction will
149229 ** be picked up by the recursive calls to sqlite3WhereBegin() below.
149230 **
149231 ** Actually, each subexpression is converted to "xN AND w" where w is
149232 ** the "interesting" terms of z - terms that did not originate in the
@@ -149234,21 +150093,38 @@
149234 ** indices.
149235 **
149236 ** This optimization also only applies if the (x1 OR x2 OR ...) term
149237 ** is not contained in the ON clause of a LEFT JOIN.
149238 ** See ticket http://www.sqlite.org/src/info/f2369304e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149239 */
149240 if( pWC->nTerm>1 ){
149241 int iTerm;
149242 for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
149243 Expr *pExpr = pWC->a[iTerm].pExpr;
149244 if( &pWC->a[iTerm] == pTerm ) continue;
149245 testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
149246 testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
149247 if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
 
 
 
149248 if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
149249 testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
149250 pExpr = sqlite3ExprDup(db, pExpr, 0);
149251 pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
149252 }
149253 if( pAndExpr ){
149254 /* The extra 0x10000 bit on the opcode is masked off and does not
@@ -149285,11 +150161,11 @@
149285 pOrExpr = pAndExpr;
149286 }
149287 /* Loop through table entries that match term pOrTerm. */
149288 ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
149289 WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
149290 pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
149291 WHERE_OR_SUBCLAUSE, iCovCur);
149292 assert( pSubWInfo || pParse->nErr );
149293 if( pSubWInfo ){
149294 WhereLoop *pSubLoop;
149295 int addrExplain = sqlite3WhereExplainOneScan(
@@ -150025,11 +150901,11 @@
150025 void *pNotUsed;
150026 pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
150027 assert( pVtab!=0 );
150028 assert( pVtab->pModule!=0 );
150029 assert( !ExprHasProperty(pExpr, EP_IntValue) );
150030 pMod = (sqlite3_module *)pVtab->pModule;
150031 if( pMod->xFindFunction!=0 ){
150032 i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
150033 if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
150034 *peOp2 = i;
150035 *ppRight = pList->a[1].pExpr;
@@ -150069,11 +150945,11 @@
150069 ** a join, then transfer the appropriate markings over to derived.
150070 */
150071 static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
150072 if( pDerived ){
150073 pDerived->flags |= pBase->flags & EP_FromJoin;
150074 pDerived->iRightJoinTable = pBase->iRightJoinTable;
150075 }
150076 }
150077
150078 /*
150079 ** Mark term iChild as being a child of term iParent
@@ -150714,11 +151590,11 @@
150714 abort();
150715 }
150716 #endif
150717
150718 if( ExprHasProperty(pExpr, EP_FromJoin) ){
150719 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
150720 prereqAll |= x;
150721 extraRight = x-1; /* ON clause terms may not be used with an index
150722 ** on left table of a LEFT JOIN. Ticket #3015 */
150723 if( (prereqAll>>1)>=x ){
150724 sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
@@ -150982,11 +151858,14 @@
150982 ** new terms for each component comparison - "a = ?" and "b = ?". The
150983 ** new terms completely replace the original vector comparison, which is
150984 ** no longer used.
150985 **
150986 ** This is only required if at least one side of the comparison operation
150987 ** is not a sub-select. */
 
 
 
150988 if( (pExpr->op==TK_EQ || pExpr->op==TK_IS)
150989 && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
150990 && sqlite3ExprVectorSize(pExpr->pRight)==nLeft
150991 && ( (pExpr->pLeft->flags & EP_xIsSelect)==0
150992 || (pExpr->pRight->flags & EP_xIsSelect)==0)
@@ -150999,11 +151878,11 @@
150999 Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, nLeft);
151000 Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, nLeft);
151001
151002 pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
151003 transferJoinMarkings(pNew, pExpr);
151004 idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
151005 exprAnalyze(pSrc, pWC, idxNew);
151006 }
151007 pTerm = &pWC->a[idxTerm];
151008 pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
151009 pTerm->eOperator = 0;
@@ -151029,11 +151908,11 @@
151029 && pWC->op==TK_AND
151030 ){
151031 int i;
151032 for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
151033 int idxNew;
151034 idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
151035 pWC->a[idxNew].u.x.iField = i+1;
151036 exprAnalyze(pSrc, pWC, idxNew);
151037 markTermAsChild(pWC, idxNew, idxTerm);
151038 }
151039 }
@@ -151062,11 +151941,11 @@
151062 Expr *pNewExpr;
151063 pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
151064 0, sqlite3ExprDup(db, pRight, 0));
151065 if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
151066 ExprSetProperty(pNewExpr, EP_FromJoin);
151067 pNewExpr->iRightJoinTable = pExpr->iRightJoinTable;
151068 }
151069 idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
151070 testcase( idxNew==0 );
151071 pNewTerm = &pWC->a[idxNew];
151072 pNewTerm->prereqRight = prereqExpr;
@@ -151124,10 +152003,117 @@
151124 }else{
151125 sqlite3WhereSplit(pWC, pE2->pLeft, op);
151126 sqlite3WhereSplit(pWC, pE2->pRight, op);
151127 }
151128 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151129
151130 /*
151131 ** Initialize a preallocated WhereClause structure.
151132 */
151133 SQLITE_PRIVATE void sqlite3WhereClauseInit(
@@ -151160,10 +152146,11 @@
151160 for(i=pWC->nBase; i<pWC->nTerm; i++){
151161 assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 );
151162 }
151163 #endif
151164 while(1){
 
151165 if( a->wtFlags & TERM_DYNAMIC ){
151166 sqlite3ExprDelete(db, a->pExpr);
151167 }
151168 if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){
151169 if( a->wtFlags & TERM_ORINFO ){
@@ -151317,10 +152304,11 @@
151317 if( pColRef==0 ) return;
151318 pColRef->iTable = pItem->iCursor;
151319 pColRef->iColumn = k++;
151320 assert( ExprUseYTab(pColRef) );
151321 pColRef->y.pTab = pTab;
 
151322 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
151323 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
151324 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
151325 if( pItem->fg.jointype & JT_LEFT ){
151326 sqlite3SetJoinExpr(pTerm, pItem->iCursor);
@@ -151364,10 +152352,12 @@
151364 typedef struct HiddenIndexInfo HiddenIndexInfo;
151365 struct HiddenIndexInfo {
151366 WhereClause *pWC; /* The Where clause being analyzed */
151367 Parse *pParse; /* The parsing context */
151368 int eDistinct; /* Value to return from sqlite3_vtab_distinct() */
 
 
151369 sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST
151370 ** because extra space is allocated to hold up
151371 ** to nTerm such values */
151372 };
151373
@@ -152407,11 +153397,14 @@
152407 VdbeCoverage(v);
152408 sqlite3VdbeJumpHere(v, addrTop);
152409 pLoop->wsFlags &= ~WHERE_BLOOMFILTER;
152410 if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
152411 while( ++iLevel < pWInfo->nLevel ){
 
152412 pLevel = &pWInfo->a[iLevel];
 
 
152413 pLoop = pLevel->pWLoop;
152414 if( NEVER(pLoop==0) ) continue;
152415 if( pLoop->prereq & notReady ) continue;
152416 if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN))
152417 ==WHERE_BLOOMFILTER
@@ -152474,10 +153467,11 @@
152474 testcase( pTerm->eOperator & WO_ISNULL );
152475 testcase( pTerm->eOperator & WO_IS );
152476 testcase( pTerm->eOperator & WO_ALL );
152477 if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
152478 if( pTerm->wtFlags & TERM_VNULL ) continue;
 
152479 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
152480 assert( pTerm->u.x.leftColumn>=XN_ROWID );
152481 assert( pTerm->u.x.leftColumn<pTab->nCol );
152482
152483 /* tag-20191211-002: WHERE-clause constraints are not useful to the
@@ -152535,14 +153529,16 @@
152535 }
152536
152537 /* No matches cause a break out of the loop */
152538 break;
152539 }
152540 if( i==n){
152541 nOrderBy = n;
152542 if( (pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY)) ){
152543 eDistinct = 1 + ((pWInfo->wctrlFlags & WHERE_DISTINCTBY)!=0);
 
 
152544 }
152545 }
152546 }
152547
152548 /* Allocate the sqlite3_index_info structure
@@ -152563,17 +153559,23 @@
152563 pIdxInfo->aOrderBy = pIdxOrderBy;
152564 pIdxInfo->aConstraintUsage = pUsage;
152565 pHidden->pWC = pWC;
152566 pHidden->pParse = pParse;
152567 pHidden->eDistinct = eDistinct;
 
152568 for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
152569 u16 op;
152570 if( (pTerm->wtFlags & TERM_OK)==0 ) continue;
152571 pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
152572 pIdxCons[j].iTermOffset = i;
152573 op = pTerm->eOperator & WO_ALL;
152574 if( op==WO_IN ) op = WO_EQ;
 
 
 
 
 
152575 if( op==WO_AUX ){
152576 pIdxCons[j].op = pTerm->eMatchOp;
152577 }else if( op & (WO_ISNULL|WO_IS) ){
152578 if( op==WO_ISNULL ){
152579 pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
@@ -152659,11 +153661,13 @@
152659 static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
152660 sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
152661 int rc;
152662
152663 whereTraceIndexInfoInputs(p);
 
152664 rc = pVtab->pModule->xBestIndex(pVtab, p);
 
152665 whereTraceIndexInfoOutputs(p);
152666
152667 if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
152668 if( rc==SQLITE_NOMEM ){
152669 sqlite3OomFault(pParse->db);
@@ -153911,12 +154915,21 @@
153911 if( j<0 ){
153912 if( pLoop->maskSelf==pTerm->prereqAll ){
153913 /* If there are extra terms in the WHERE clause not used by an index
153914 ** that depend only on the table being scanned, and that will tend to
153915 ** cause many rows to be omitted, then mark that table as
153916 ** "self-culling". */
153917 pLoop->wsFlags |= WHERE_SELFCULL;
 
 
 
 
 
 
 
 
 
153918 }
153919 if( pTerm->truthProb<=0 ){
153920 /* If a truth probability is specified using the likelihood() hints,
153921 ** then use the probability provided by the application. */
153922 pLoop->nOut += pTerm->truthProb;
@@ -154488,11 +155501,11 @@
154488 }
154489 if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
154490 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
154491 Expr *pExpr;
154492 pExpr = pTerm->pExpr;
154493 if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
154494 && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
154495 && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
154496 && (pTerm->wtFlags & TERM_VNULL)==0
154497 ){
154498 return 1;
@@ -154789,10 +155802,19 @@
154789 }
154790 return rc;
154791 }
154792
154793 #ifndef SQLITE_OMIT_VIRTUALTABLE
 
 
 
 
 
 
 
 
 
154794
154795 /*
154796 ** Argument pIdxInfo is already populated with all constraints that may
154797 ** be used by the virtual table identified by pBuilder->pNew->iTab. This
154798 ** function marks a subset of those constraints usable, invokes the
@@ -154817,13 +155839,15 @@
154817 Bitmask mPrereq, /* Mask of tables that must be used. */
154818 Bitmask mUsable, /* Mask of usable tables */
154819 u16 mExclude, /* Exclude terms using these operators */
154820 sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
154821 u16 mNoOmit, /* Do not omit these constraints */
154822 int *pbIn /* OUT: True if plan uses an IN(...) op */
 
154823 ){
154824 WhereClause *pWC = pBuilder->pWC;
 
154825 struct sqlite3_index_constraint *pIdxCons;
154826 struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
154827 int i;
154828 int mxTerm;
154829 int rc = SQLITE_OK;
@@ -154842,10 +155866,11 @@
154842 for(i=0; i<nConstraint; i++, pIdxCons++){
154843 WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset];
154844 pIdxCons->usable = 0;
154845 if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight
154846 && (pTerm->eOperator & mExclude)==0
 
154847 ){
154848 pIdxCons->usable = 1;
154849 }
154850 }
154851
@@ -154857,10 +155882,11 @@
154857 pIdxInfo->orderByConsumed = 0;
154858 pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
154859 pIdxInfo->estimatedRows = 25;
154860 pIdxInfo->idxFlags = 0;
154861 pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
 
154862
154863 /* Invoke the virtual table xBestIndex() method */
154864 rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
154865 if( rc ){
154866 if( rc==SQLITE_CONSTRAINT ){
@@ -154874,12 +155900,12 @@
154874 return rc;
154875 }
154876
154877 mxTerm = -1;
154878 assert( pNew->nLSlot>=nConstraint );
154879 for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
154880 pNew->u.vtab.omitMask = 0;
154881 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
154882 for(i=0; i<nConstraint; i++, pIdxCons++){
154883 int iTerm;
154884 if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
154885 WhereTerm *pTerm;
@@ -154909,21 +155935,41 @@
154909 testcase( i!=iTerm );
154910 pNew->u.vtab.omitMask |= 1<<iTerm;
154911 }else{
154912 testcase( i!=iTerm );
154913 }
 
 
 
154914 }
154915 if( (pTerm->eOperator & WO_IN)!=0 ){
 
 
154916 /* A virtual table that is constrained by an IN clause may not
154917 ** consume the ORDER BY clause because (1) the order of IN terms
154918 ** is not necessarily related to the order of output terms and
154919 ** (2) Multiple outputs from a single IN value will not merge
154920 ** together. */
154921 pIdxInfo->orderByConsumed = 0;
154922 pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
154923 *pbIn = 1; assert( (mExclude & WO_IN)==0 );
154924 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154925 }
154926 }
154927
154928 pNew->nLTerm = mxTerm+1;
154929 for(i=0; i<=mxTerm; i++){
@@ -154992,10 +156038,29 @@
154992 }
154993 zRet = (pC ? pC->zName : sqlite3StrBINARY);
154994 }
154995 return zRet;
154996 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154997
154998 /*
154999 ** This interface is callable from within the xBestIndex callback only.
155000 **
155001 ** If possible, set (*ppVal) to point to an object containing the value
@@ -155029,21 +156094,34 @@
155029 }
155030
155031 return rc;
155032 }
155033
155034
155035 /*
155036 ** Return true if ORDER BY clause may be handled as DISTINCT.
155037 */
155038 SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){
155039 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
155040 assert( pHidden->eDistinct==0
155041 || pHidden->eDistinct==1
155042 || pHidden->eDistinct==2 );
155043 return pHidden->eDistinct;
155044 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155045
155046 /*
155047 ** Add all WhereLoop objects for a table of the join identified by
155048 ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
155049 **
@@ -155082,10 +156160,11 @@
155082 int nConstraint; /* Number of constraints in p */
155083 int bIn; /* True if plan uses IN(...) operator */
155084 WhereLoop *pNew;
155085 Bitmask mBest; /* Tables used by best possible plan */
155086 u16 mNoOmit;
 
155087
155088 assert( (mPrereq & mUnusable)==0 );
155089 pWInfo = pBuilder->pWInfo;
155090 pParse = pWInfo->pParse;
155091 pWC = pBuilder->pWC;
@@ -155105,11 +156184,19 @@
155105 }
155106
155107 /* First call xBestIndex() with all constraints usable. */
155108 WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
155109 WHERETRACE(0x40, (" VirtualOne: all usable\n"));
155110 rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
 
 
 
 
 
 
 
 
155111
155112 /* If the call to xBestIndex() with all terms enabled produced a plan
155113 ** that does not require any source tables (IOW: a plan with mBest==0)
155114 ** and does not use an IN(...) operator, then there is no point in making
155115 ** any further calls to xBestIndex() since they will all return the same
@@ -155123,11 +156210,11 @@
155123 /* If the plan produced by the earlier call uses an IN(...) term, call
155124 ** xBestIndex again, this time with IN(...) terms disabled. */
155125 if( bIn ){
155126 WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
155127 rc = whereLoopAddVirtualOne(
155128 pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
155129 assert( bIn==0 );
155130 mBestNoIn = pNew->prereq & ~mPrereq;
155131 if( mBestNoIn==0 ){
155132 seenZero = 1;
155133 seenZeroNoIN = 1;
@@ -155150,11 +156237,11 @@
155150 if( mNext==ALLBITS ) break;
155151 if( mNext==mBest || mNext==mBestNoIn ) continue;
155152 WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
155153 (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
155154 rc = whereLoopAddVirtualOne(
155155 pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
155156 if( pNew->prereq==mPrereq ){
155157 seenZero = 1;
155158 if( bIn==0 ) seenZeroNoIN = 1;
155159 }
155160 }
@@ -155163,21 +156250,21 @@
155163 ** that requires no source tables at all (i.e. one guaranteed to be
155164 ** usable), make a call here with all source tables disabled */
155165 if( rc==SQLITE_OK && seenZero==0 ){
155166 WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
155167 rc = whereLoopAddVirtualOne(
155168 pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
155169 if( bIn==0 ) seenZeroNoIN = 1;
155170 }
155171
155172 /* If the calls to xBestIndex() have so far failed to find a plan
155173 ** that requires no source tables at all and does not use an IN(...)
155174 ** operator, make a final call to obtain one here. */
155175 if( rc==SQLITE_OK && seenZeroNoIN==0 ){
155176 WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
155177 rc = whereLoopAddVirtualOne(
155178 pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
155179 }
155180 }
155181
155182 if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
155183 freeIndexInfo(pParse->db, p);
@@ -155471,11 +156558,13 @@
155471 if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue;
155472 }else{
155473 pLoop = pLast;
155474 }
155475 if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
155476 if( pLoop->u.vtab.isOrdered && (wctrlFlags & WHERE_DISTINCTBY)==0 ){
 
 
155477 obSat = obDone;
155478 }
155479 break;
155480 }else if( wctrlFlags & WHERE_DISTINCTBY ){
155481 pLoop->u.btree.nDistinctCol = 0;
@@ -155738,11 +156827,11 @@
155738 **
155739 ** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1
155740 ** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0
155741 */
155742 SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){
155743 assert( pWInfo->wctrlFlags & WHERE_GROUPBY );
155744 assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP );
155745 return pWInfo->sorted;
155746 }
155747
155748 #ifdef WHERETRACE_ENABLED
@@ -156139,16 +157228,16 @@
156139 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
156140 }
156141 }
156142 pWInfo->bOrderedInnerLoop = 0;
156143 if( pWInfo->pOrderBy ){
 
156144 if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
156145 if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
156146 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
156147 }
156148 }else{
156149 pWInfo->nOBSat = pFrom->isOrdered;
156150 pWInfo->revMask = pFrom->revLoop;
156151 if( pWInfo->nOBSat<=0 ){
156152 pWInfo->nOBSat = 0;
156153 if( nLoop>0 ){
156154 u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
@@ -156407,11 +157496,11 @@
156407 if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
156408 pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
156409 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
156410 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
156411 if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
156412 || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
156413 ){
156414 break;
156415 }
156416 }
156417 }
@@ -156579,10 +157668,11 @@
156579 Parse *pParse, /* The parser context */
156580 SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
156581 Expr *pWhere, /* The WHERE clause */
156582 ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
156583 ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
 
156584 u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
156585 int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
156586 ** If WHERE_USE_LIMIT, then the limit amount */
156587 ){
156588 int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
@@ -156655,10 +157745,13 @@
156655 pWInfo->nLevel = nTabList;
156656 pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
156657 pWInfo->wctrlFlags = wctrlFlags;
156658 pWInfo->iLimit = iAuxArg;
156659 pWInfo->savedNQueryLoop = pParse->nQueryLoop;
 
 
 
156660 memset(&pWInfo->nOBSat, 0,
156661 offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
156662 memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
156663 assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
156664 pMaskSet = &pWInfo->sMaskSet;
@@ -156723,10 +157816,11 @@
156723 #endif
156724 }
156725
156726 /* Analyze all of the subexpressions. */
156727 sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
 
156728 if( db->mallocFailed ) goto whereBeginError;
156729
156730 /* Special case: WHERE terms that do not refer to any tables in the join
156731 ** (constant expressions). Evaluate each such term, and jump over all the
156732 ** generated code if the result is not true.
@@ -156969,10 +158063,11 @@
156969 testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
156970 testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
156971 if( pWInfo->eOnePass==ONEPASS_OFF
156972 && pTab->nCol<BMS
156973 && (pTab->tabFlags & (TF_HasGenerated|TF_WithoutRowid))==0
 
156974 ){
156975 /* If we know that only a prefix of the record will be used,
156976 ** it is advantageous to reduce the "column count" field in
156977 ** the P4 operand of the OP_OpenRead/Write opcode. */
156978 Bitmask b = pTabItem->colUsed;
@@ -157129,10 +158224,30 @@
157129 if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
157130 sqlite3VdbePrintOp(0, pc, pOp);
157131 }
157132 #endif
157133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157134 /*
157135 ** Generate the end of the WHERE loop. See comments on
157136 ** sqlite3WhereBegin() for additional information.
157137 */
157138 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
@@ -157381,10 +158496,15 @@
157381 || pOp->opcode==OP_Offset
157382 #endif
157383 ){
157384 int x = pOp->p2;
157385 assert( pIdx->pTable==pTab );
 
 
 
 
 
157386 if( !HasRowid(pTab) ){
157387 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
157388 x = pPk->aiColumn[x];
157389 assert( x>=0 );
157390 }else{
@@ -157394,13 +158514,26 @@
157394 x = sqlite3TableColumnToIndex(pIdx, x);
157395 if( x>=0 ){
157396 pOp->p2 = x;
157397 pOp->p1 = pLevel->iIdxCur;
157398 OpcodeRewriteTrace(db, k, pOp);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157399 }
157400 assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0
157401 || pWInfo->eOnePass );
157402 }else if( pOp->opcode==OP_Rowid ){
157403 pOp->p1 = pLevel->iIdxCur;
157404 pOp->opcode = OP_IdxRowid;
157405 OpcodeRewriteTrace(db, k, pOp);
157406 }else if( pOp->opcode==OP_IfNullRow ){
@@ -158151,11 +159284,11 @@
158151 break;
158152 }
158153 }
158154 }
158155 }
158156 pWin->pFunc = pFunc;
158157 }
158158
158159 /*
158160 ** Context object passed through sqlite3WalkExprList() to
158161 ** selectWindowRewriteExprCb() by selectWindowRewriteEList().
@@ -158384,11 +159517,15 @@
158384 ** are invoked in the correct order as described under "SELECT REWRITING"
158385 ** at the top of this file.
158386 */
158387 SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
158388 int rc = SQLITE_OK;
158389 if( p->pWin && p->pPrior==0 && ALWAYS((p->selFlags & SF_WinRewrite)==0) ){
 
 
 
 
158390 Vdbe *v = sqlite3GetVdbe(pParse);
158391 sqlite3 *db = pParse->db;
158392 Select *pSub = 0; /* The subquery */
158393 SrcList *pSrc = p->pSrc;
158394 Expr *pWhere = p->pWhere;
@@ -158459,12 +159596,13 @@
158459 ** window function - one for the accumulator, another for interim
158460 ** results. */
158461 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158462 ExprList *pArgs;
158463 assert( ExprUseXList(pWin->pOwner) );
 
158464 pArgs = pWin->pOwner->x.pList;
158465 if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
158466 selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
158467 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
158468 pWin->bExprArgs = 1;
158469 }else{
158470 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
@@ -158842,11 +159980,11 @@
158842 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
158843 return;
158844 }
158845
158846 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158847 FuncDef *p = pWin->pFunc;
158848 if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
158849 /* The inline versions of min() and max() require a single ephemeral
158850 ** table and 3 registers. The registers are used as follows:
158851 **
158852 ** regApp+0: slot to copy min()/max() argument to for MakeRecord
@@ -158859,11 +159997,11 @@
158859 pList = pWin->pOwner->x.pList;
158860 pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
158861 pWin->csrApp = pParse->nTab++;
158862 pWin->regApp = pParse->nMem+1;
158863 pParse->nMem += 3;
158864 if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
158865 assert( pKeyInfo->aSortFlags[0]==0 );
158866 pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
158867 }
158868 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
158869 sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
@@ -159082,11 +160220,11 @@
159082 ){
159083 Parse *pParse = p->pParse;
159084 Vdbe *v = sqlite3GetVdbe(pParse);
159085 Window *pWin;
159086 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159087 FuncDef *pFunc = pWin->pFunc;
159088 int regArg;
159089 int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
159090 int i;
159091
159092 assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
@@ -159196,11 +160334,11 @@
159196 Vdbe *v = sqlite3GetVdbe(pParse);
159197 Window *pWin;
159198
159199 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159200 if( pMWin->regStartRowid==0
159201 && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
159202 && (pWin->eStart!=TK_UNBOUNDED)
159203 ){
159204 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
159205 sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
159206 VdbeCoverage(v);
@@ -159210,16 +160348,16 @@
159210 assert( pMWin->regStartRowid==0 );
159211 }else{
159212 int nArg = windowArgCount(pWin);
159213 if( bFin ){
159214 sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
159215 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
159216 sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
159217 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
159218 }else{
159219 sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
159220 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
159221 }
159222 }
159223 }
159224 }
159225
@@ -159344,11 +160482,11 @@
159344 }else{
159345 Parse *pParse = p->pParse;
159346 Window *pWin;
159347
159348 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159349 FuncDef *pFunc = pWin->pFunc;
159350 assert( ExprUseXList(pWin->pOwner) );
159351 if( pFunc->zName==nth_valueName
159352 || pFunc->zName==first_valueName
159353 ){
159354 int csr = pWin->csrApp;
@@ -159416,11 +160554,11 @@
159416 Vdbe *v = sqlite3GetVdbe(pParse);
159417 int regArg;
159418 int nArg = 0;
159419 Window *pWin;
159420 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159421 FuncDef *pFunc = pWin->pFunc;
159422 assert( pWin->regAccum );
159423 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
159424 nArg = MAX(nArg, windowArgCount(pWin));
159425 if( pMWin->regStartRowid==0 ){
159426 if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
@@ -159446,11 +160584,11 @@
159446 */
159447 static int windowCacheFrame(Window *pMWin){
159448 Window *pWin;
159449 if( pMWin->regStartRowid ) return 1;
159450 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159451 FuncDef *pFunc = pWin->pFunc;
159452 if( (pFunc->zName==nth_valueName)
159453 || (pFunc->zName==first_valueName)
159454 || (pFunc->zName==leadName)
159455 || (pFunc->zName==lagName)
159456 ){
@@ -159804,11 +160942,11 @@
159804 pNew = sqlite3DbMallocZero(db, sizeof(Window));
159805 if( pNew ){
159806 pNew->zName = sqlite3DbStrDup(db, p->zName);
159807 pNew->zBase = sqlite3DbStrDup(db, p->zBase);
159808 pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
159809 pNew->pFunc = p->pFunc;
159810 pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
159811 pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
159812 pNew->eFrmType = p->eFrmType;
159813 pNew->eEnd = p->eEnd;
159814 pNew->eStart = p->eStart;
@@ -160681,14 +161819,11 @@
160681 }
160682 return pSelect;
160683 }
160684
160685
160686 /* Construct a new Expr object from a single identifier. Use the
160687 ** new Expr to populate pOut. Set the span of pOut to be the identifier
160688 ** that created the expression.
160689 */
160690 static Expr *tokenExpr(Parse *pParse, int op, Token t){
160691 Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
160692 if( p ){
160693 /* memset(p, 0, sizeof(Expr)); */
160694 p->op = (u8)op;
@@ -160704,10 +161839,11 @@
160704 p->iTable = 0;
160705 p->iColumn = 0;
160706 p->u.zToken = (char*)&p[1];
160707 memcpy(p->u.zToken, t.z, t.n);
160708 p->u.zToken[t.n] = 0;
 
160709 if( sqlite3Isquote(p->u.zToken[0]) ){
160710 sqlite3DequoteExpr(p);
160711 }
160712 #if SQLITE_MAX_EXPR_DEPTH>0
160713 p->nHeight = 1;
@@ -164515,11 +165651,11 @@
164515 }
164516 break;
164517 case 102: /* selcollist ::= sclp scanpt nm DOT STAR */
164518 {
164519 Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
164520 Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
164521 Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
164522 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
164523 }
164524 break;
164525 case 103: /* as ::= AS nm */
@@ -164800,29 +165936,24 @@
164800 case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179);
164801 {yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
164802 break;
164803 case 180: /* expr ::= nm DOT nm */
164804 {
164805 Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
164806 Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
164807 if( IN_RENAME_OBJECT ){
164808 sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
164809 sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
164810 }
164811 yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
164812 }
164813 yymsp[-2].minor.yy528 = yylhsminor.yy528;
164814 break;
164815 case 181: /* expr ::= nm DOT nm DOT nm */
164816 {
164817 Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
164818 Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
164819 Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
164820 Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
164821 if( IN_RENAME_OBJECT ){
164822 sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
164823 sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
164824 }
164825 yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
164826 }
164827 yymsp[-4].minor.yy528 = yylhsminor.yy528;
164828 break;
@@ -164831,10 +165962,11 @@
164831 {yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
164832 break;
164833 case 184: /* term ::= INTEGER */
164834 {
164835 yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
 
164836 }
164837 yymsp[0].minor.yy528 = yylhsminor.yy528;
164838 break;
164839 case 185: /* expr ::= VARIABLE */
164840 {
@@ -167075,11 +168207,14 @@
167075 }else if( tokenType==TK_FILTER ){
167076 assert( n==6 );
167077 tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
167078 #endif /* SQLITE_OMIT_WINDOWFUNC */
167079 }else{
167080 sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
 
 
 
167081 break;
167082 }
167083 }
167084 pParse->sLastToken.z = zSql;
167085 pParse->sLastToken.n = n;
@@ -167125,11 +168260,11 @@
167125 sqlite3DeleteTable(db, pParse->pNewTable);
167126 }
167127 if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){
167128 sqlite3DeleteTrigger(db, pParse->pNewTrigger);
167129 }
167130 sqlite3DbFree(db, pParse->pVList);
167131 db->pParse = pParentParse;
167132 assert( nErr==0 || pParse->rc!=SQLITE_OK );
167133 return nErr;
167134 }
167135
@@ -171686,16 +172821,20 @@
171686 ** is called immediately after installing the new callback and the return
171687 ** value from sqlite3FaultSim(0) becomes the return from
171688 ** sqlite3_test_control().
171689 */
171690 case SQLITE_TESTCTRL_FAULT_INSTALL: {
171691 /* MSVC is picky about pulling func ptrs from va lists.
171692 ** http://support.microsoft.com/kb/47961
 
 
 
 
171693 ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
171694 */
171695 typedef int(*TESTCALLBACKFUNC_t)(int);
171696 sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
171697 rc = sqlite3FaultSim(0);
171698 break;
171699 }
171700
171701 /*
@@ -171818,17 +172957,31 @@
171818 sqlite3 *db = va_arg(ap, sqlite3*);
171819 db->dbOptFlags = va_arg(ap, u32);
171820 break;
171821 }
171822
171823 /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
 
 
 
 
 
 
 
 
171824 **
171825 ** If parameter onoff is non-zero, subsequent calls to localtime()
171826 ** and its variants fail. If onoff is zero, undo this setting.
171827 */
171828 case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
171829 sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
 
 
 
 
 
 
171830 break;
171831 }
171832
171833 /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*);
171834 **
@@ -172026,14 +173179,16 @@
172026 ** Test access for the LogEst conversion routines.
172027 */
172028 case SQLITE_TESTCTRL_LOGEST: {
172029 double rIn = va_arg(ap, double);
172030 LogEst rLogEst = sqlite3LogEstFromDouble(rIn);
172031 u64 iInt = sqlite3LogEstToInt(rLogEst);
172032 va_arg(ap, int*)[0] = rLogEst;
172033 va_arg(ap, u64*)[0] = iInt;
172034 va_arg(ap, int*)[0] = sqlite3LogEst(iInt);
 
 
172035 break;
172036 }
172037
172038
172039 #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
@@ -193960,11 +195115,11 @@
193960 u32 iRoot;
193961 JsonNode *pTarget;
193962 if( pPatch->eType!=JSON_OBJECT ){
193963 return pPatch;
193964 }
193965 assert( iTarget>=0 && iTarget<pParse->nNode );
193966 pTarget = &pParse->aNode[iTarget];
193967 assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
193968 if( pTarget->eType!=JSON_OBJECT ){
193969 jsonRemoveAllNulls(pPatch);
193970 return pPatch;
@@ -195001,11 +196156,11 @@
195001 sqlite3_module *pModule;
195002 } aMod[] = {
195003 { "json_each", &jsonEachModule },
195004 { "json_tree", &jsonTreeModule },
195005 };
195006 int i;
195007 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
195008 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
195009 }
195010 return rc;
195011 }
@@ -209255,10 +210410,11 @@
209255 && pIdxInfo->aOrderBy[0].iColumn<=0
209256 && pIdxInfo->aOrderBy[0].desc==0
209257 ){
209258 pIdxInfo->orderByConsumed = 1;
209259 }
 
209260 return SQLITE_OK;
209261 }
209262
209263 /*
209264 ** Open a new dbpagevfs cursor.
@@ -209432,11 +210588,11 @@
209432 if( iDb<0 ){
209433 zErr = "no such schema";
209434 goto update_fail;
209435 }
209436 pBt = pTab->db->aDb[iDb].pBt;
209437 if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){
209438 zErr = "bad page number";
209439 goto update_fail;
209440 }
209441 szPage = sqlite3BtreeGetPageSize(pBt);
209442 if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
@@ -231609,11 +232765,11 @@
231609 int rc;
231610
231611 rc = sqlite3_step(pSorter->pStmt);
231612 if( rc==SQLITE_DONE ){
231613 rc = SQLITE_OK;
231614 CsrFlagSet(pCsr, FTS5CSR_EOF);
231615 }else if( rc==SQLITE_ROW ){
231616 const u8 *a;
231617 const u8 *aBlob;
231618 int nBlob;
231619 int i;
@@ -233598,11 +234754,11 @@
233598 int nArg, /* Number of args */
233599 sqlite3_value **apUnused /* Function arguments */
233600 ){
233601 assert( nArg==0 );
233602 UNUSED_PARAM2(nArg, apUnused);
233603 sqlite3_result_text(pCtx, "fts5: 2022-01-25 00:03:25 a8db69411b0d1275909adeb21027784ada17af24efe3a59ae0ae2a897659ff17", -1, SQLITE_TRANSIENT);
233604 }
233605
233606 /*
233607 ** Return true if zName is the extension on one of the shadow tables used
233608 ** by this module.
233609
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.39.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -450,13 +450,13 @@
450 **
451 ** See also: [sqlite3_libversion()],
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.39.0"
456 #define SQLITE_VERSION_NUMBER 3039000
457 #define SQLITE_SOURCE_ID "2022-04-01 17:23:17 a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -870,11 +870,11 @@
870 #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
871 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
872 #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
873 #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
874 #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
875 #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
876
877 /*
878 ** CAPI3REF: Flags For File Open Operations
879 **
880 ** These bit values are intended for use in the
@@ -4154,11 +4154,11 @@
4154 **
4155 ** ^If the most recent error references a specific token in the input
4156 ** SQL, the sqlite3_error_offset() interface returns the byte offset
4157 ** of the start of that token. ^The byte offset returned by
4158 ** sqlite3_error_offset() assumes that the input SQL is UTF8.
4159 ** ^If the most recent error does not reference a specific token in the input
4160 ** SQL, then the sqlite3_error_offset() function returns -1.
4161 **
4162 ** When the serialized [threading mode] is in use, it might be the
4163 ** case that a second error occurs on a separate thread in between
4164 ** the time of the first error and the call to these interfaces.
@@ -4588,10 +4588,14 @@
4588 ** ^For example, an UPDATE statement might have a WHERE clause that
4589 ** makes it a no-op, but the sqlite3_stmt_readonly() result would still
4590 ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
4591 ** read-only no-op if the table already exists, but
4592 ** sqlite3_stmt_readonly() still returns false for such a statement.
4593 **
4594 ** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN]
4595 ** statement, then sqlite3_stmt_readonly(X) returns the same value as
4596 ** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted.
4597 */
4598 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
4599
4600 /*
4601 ** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4656,10 +4660,12 @@
4660 ** still make the distinction between protected and unprotected
4661 ** sqlite3_value objects even when not strictly required.
4662 **
4663 ** ^The sqlite3_value objects that are passed as parameters into the
4664 ** implementation of [application-defined SQL functions] are protected.
4665 ** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
4666 ** are protected.
4667 ** ^The sqlite3_value object returned by
4668 ** [sqlite3_column_value()] is unprotected.
4669 ** Unprotected sqlite3_value objects may only be used as arguments
4670 ** to [sqlite3_result_value()], [sqlite3_bind_value()], and
4671 ** [sqlite3_value_dup()].
@@ -5276,10 +5282,14 @@
5282 ** bytes in the string, not the number of characters.
5283 **
5284 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
5285 ** even empty strings, are always zero-terminated. ^The return
5286 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
5287 **
5288 ** ^Strings returned by sqlite3_column_text16() always have the endianness
5289 ** which is native to the platform, regardless of the text encoding set
5290 ** for the database.
5291 **
5292 ** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
5293 ** [unprotected sqlite3_value] object. In a multithreaded environment,
5294 ** an unprotected sqlite3_value object may only be used safely with
5295 ** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -5290,11 +5300,11 @@
5300 ** Hence, the sqlite3_column_value() interface
5301 ** is normally only useful within the implementation of
5302 ** [application-defined SQL functions] or [virtual tables], not within
5303 ** top-level application code.
5304 **
5305 ** These routines may attempt to convert the datatype of the result.
5306 ** ^For example, if the internal representation is FLOAT and a text result
5307 ** is requested, [sqlite3_snprintf()] is used internally to perform the
5308 ** conversion automatically. ^(The following table details the conversions
5309 ** that are applied:
5310 **
@@ -5315,11 +5325,11 @@
5325 ** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
5326 ** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
5327 ** <tr><td> TEXT <td> BLOB <td> No change
5328 ** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
5329 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5330 ** <tr><td> BLOB <td> TEXT <td> [CAST] to TEXT, ensure zero terminator
5331 ** </table>
5332 ** </blockquote>)^
5333 **
5334 ** Note that when type conversions occur, pointers returned by prior
5335 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5887,11 +5897,12 @@
5897 **
5898 ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
5899 ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
5900 ** is a [protected sqlite3_value] object even if the input is not.
5901 ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5902 ** memory allocation fails. ^If V is a [pointer value], then the result
5903 ** of sqlite3_value_dup(V) is a NULL value.
5904 **
5905 ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
5906 ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
5907 ** then sqlite3_value_free(V) is a harmless no-op.
5908 */
@@ -7435,28 +7446,60 @@
7446 /*
7447 ** CAPI3REF: Virtual Table Constraint Operator Codes
7448 **
7449 ** These macros define the allowed values for the
7450 ** [sqlite3_index_info].aConstraint[].op field. Each value represents
7451 ** an operator that is part of a constraint term in the WHERE clause of
7452 ** a query that uses a [virtual table].
7453 **
7454 ** ^The left-hand operand of the operator is given by the corresponding
7455 ** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand
7456 ** operand is the rowid.
7457 ** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
7458 ** operators have no left-hand operand, and so for those operators the
7459 ** corresponding aConstraint[].iColumn is meaningless and should not be
7460 ** used.
7461 **
7462 ** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through
7463 ** value 255 are reserved to represent functions that are overloaded
7464 ** by the [xFindFunction|xFindFunction method] of the virtual table
7465 ** implementation.
7466 **
7467 ** The right-hand operands for each constraint might be accessible using
7468 ** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand
7469 ** operand is only available if it appears as a single constant literal
7470 ** in the input SQL. If the right-hand operand is another column or an
7471 ** expression (even a constant expression) or a parameter, then the
7472 ** sqlite3_vtab_rhs_value() probably will not be able to extract it.
7473 ** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and
7474 ** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand
7475 ** and hence calls to sqlite3_vtab_rhs_value() for those operators will
7476 ** always return SQLITE_NOTFOUND.
7477 **
7478 ** The collating sequence to be used for comparison can be found using
7479 ** the [sqlite3_vtab_collation()] interface. For most real-world virtual
7480 ** tables, the collating sequence of constraints does not matter (for example
7481 ** because the constraints are numeric) and so the sqlite3_vtab_collation()
7482 ** interface is no commonly needed.
7483 */
7484 #define SQLITE_INDEX_CONSTRAINT_EQ 2
7485 #define SQLITE_INDEX_CONSTRAINT_GT 4
7486 #define SQLITE_INDEX_CONSTRAINT_LE 8
7487 #define SQLITE_INDEX_CONSTRAINT_LT 16
7488 #define SQLITE_INDEX_CONSTRAINT_GE 32
7489 #define SQLITE_INDEX_CONSTRAINT_MATCH 64
7490 #define SQLITE_INDEX_CONSTRAINT_LIKE 65
7491 #define SQLITE_INDEX_CONSTRAINT_GLOB 66
7492 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7493 #define SQLITE_INDEX_CONSTRAINT_NE 68
7494 #define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7495 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7496 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7497 #define SQLITE_INDEX_CONSTRAINT_IS 72
7498 #define SQLITE_INDEX_CONSTRAINT_LIMIT 73
7499 #define SQLITE_INDEX_CONSTRAINT_OFFSET 74
7500 #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
7501
7502 /*
7503 ** CAPI3REF: Register A Virtual Table Implementation
7504 ** METHOD: sqlite3
7505 **
@@ -7481,11 +7524,11 @@
7524 ** ^The sqlite3_create_module()
7525 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
7526 ** destructor.
7527 **
7528 ** ^If the third parameter (the pointer to the sqlite3_module object) is
7529 ** NULL then no new module is created and any existing modules with the
7530 ** same name are dropped.
7531 **
7532 ** See also: [sqlite3_drop_modules()]
7533 */
7534 SQLITE_API int sqlite3_create_module(
@@ -9812,28 +9855,29 @@
9855
9856 /*
9857 ** CAPI3REF: Determine if a virtual table query is DISTINCT
9858 ** METHOD: sqlite3_index_info
9859 **
9860 ** This API may only be used from within an [xBestIndex|xBestIndex method]
9861 ** of a [virtual table] implementation. The result of calling this
9862 ** interface from outside of xBestIndex() is undefined and probably harmful.
9863 **
9864 ** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and
9865 ** 3. The integer returned by sqlite3_vtab_distinct()
9866 ** gives the virtual table additional information about how the query
9867 ** planner wants the output to be ordered. As long as the virtual table
9868 ** can meet the ordering requirements of the query planner, it may set
9869 ** the "orderByConsumed" flag.
9870 **
9871 ** <ol><li value="0"><p>
9872 ** ^If the sqlite3_vtab_distinct() interface returns 0, that means
9873 ** that the query planner needs the virtual table to return all rows in the
9874 ** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
9875 ** [sqlite3_index_info] object. This is the default expectation. If the
9876 ** virtual table outputs all rows in sorted order, then it is always safe for
9877 ** the xBestIndex method to set the "orderByConsumed" flag, regardless of
9878 ** the return value from sqlite3_vtab_distinct().
9879 ** <li value="1"><p>
9880 ** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
9881 ** that the query planner does not need the rows to be returned in sorted order
9882 ** as long as all rows with the same values in all columns identified by the
9883 ** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
@@ -9842,16 +9886,23 @@
9886 ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
9887 ** that the query planner does not need the rows returned in any particular
9888 ** order, as long as rows with the same values in all "aOrderBy" columns
9889 ** are adjacent.)^ ^(Furthermore, only a single row for each particular
9890 ** combination of values in the columns identified by the "aOrderBy" field
9891 ** needs to be returned.)^ ^It is always ok for two or more rows with the same
9892 ** values in all "aOrderBy" columns to be returned, as long as all such rows
9893 ** are adjacent. ^The virtual table may, if it chooses, omit extra rows
9894 ** that have the same value for all columns identified by "aOrderBy".
9895 ** ^However omitting the extra rows is optional.
9896 ** This mode is used for a DISTINCT query.
9897 ** <li value="3"><p>
9898 ** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
9899 ** that the query planner needs only distinct rows but it does need the
9900 ** rows to be sorted.)^ ^The virtual table implementation is free to omit
9901 ** rows that are identical in all aOrderBy columns, if it wants to, but
9902 ** it is not required to omit any rows. This mode is used for queries
9903 ** that have both DISTINCT and ORDER BY clauses.
9904 ** </ol>
9905 **
9906 ** ^For the purposes of comparing virtual table output values to see if the
9907 ** values are same value for sorting purposes, two NULL values are considered
9908 ** to be the same. In other words, the comparison operator is "IS"
@@ -9873,35 +9924,171 @@
9924 ** valid to do so, on the other hand, might cause SQLite to return incorrect
9925 ** results.
9926 */
9927 SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
9928
9929 /*
9930 ** CAPI3REF: Identify and handle IN constraints in xBestIndex
9931 **
9932 ** This interface may only be used from within an
9933 ** [xBestIndex|xBestIndex() method] of a [virtual table] implementation.
9934 ** The result of invoking this interface from any other context is
9935 ** undefined and probably harmful.
9936 **
9937 ** ^(A constraint on a virtual table of the form
9938 ** "[IN operator|column IN (...)]" is
9939 ** communicated to the xBestIndex method as a
9940 ** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
9941 ** this constraint, it must set the corresponding
9942 ** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
9943 ** the usual mode of handling IN operators, SQLite generates [bytecode]
9944 ** that invokes the [xFilter|xFilter() method] once for each value
9945 ** on the right-hand side of the IN operator.)^ Thus the virtual table
9946 ** only sees a single value from the right-hand side of the IN operator
9947 ** at a time.
9948 **
9949 ** In some cases, however, it would be advantageous for the virtual
9950 ** table to see all values on the right-hand of the IN operator all at
9951 ** once. The sqlite3_vtab_in() interfaces facilitates this in two ways:
9952 **
9953 ** <ol>
9954 ** <li><p>
9955 ** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero)
9956 ** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint
9957 ** is an [IN operator] that can be processed all at once. ^In other words,
9958 ** sqlite3_vtab_in() with -1 in the third argument is a mechanism
9959 ** by which the virtual table can ask SQLite if all-at-once processing
9960 ** of the IN operator is even possible.
9961 **
9962 ** <li><p>
9963 ** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates
9964 ** to SQLite that the virtual table does or does not want to process
9965 ** the IN operator all-at-once, respectively. ^Thus when the third
9966 ** parameter (F) is non-negative, this interface is the mechanism by
9967 ** which the virtual table tells SQLite how it wants to process the
9968 ** IN operator.
9969 ** </ol>
9970 **
9971 ** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times
9972 ** within the same xBestIndex method call. ^For any given P,N pair,
9973 ** the return value from sqlite3_vtab_in(P,N,F) will always be the same
9974 ** within the same xBestIndex call. ^If the interface returns true
9975 ** (non-zero), that means that the constraint is an IN operator
9976 ** that can be processed all-at-once. ^If the constraint is not an IN
9977 ** operator or cannot be processed all-at-once, then the interface returns
9978 ** false.
9979 **
9980 ** ^(All-at-once processing of the IN operator is selected if both of the
9981 ** following conditions are met:
9982 **
9983 ** <ol>
9984 ** <li><p> The P->aConstraintUsage[N].argvIndex value is set to a positive
9985 ** integer. This is how the virtual table tells SQLite that it wants to
9986 ** use the N-th constraint.
9987 **
9988 ** <li><p> The last call to sqlite3_vtab_in(P,N,F) for which F was
9989 ** non-negative had F>=1.
9990 ** </ol>)^
9991 **
9992 ** ^If either or both of the conditions above are false, then SQLite uses
9993 ** the traditional one-at-a-time processing strategy for the IN constraint.
9994 ** ^If both conditions are true, then the argvIndex-th parameter to the
9995 ** xFilter method will be an [sqlite3_value] that appears to be NULL,
9996 ** but which can be passed to [sqlite3_vtab_in_first()] and
9997 ** [sqlite3_vtab_in_next()] to find all values on the right-hand side
9998 ** of the IN constraint.
9999 */
10000 SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
10001
10002 /*
10003 ** CAPI3REF: Find all elements on the right-hand side of an IN constraint.
10004 **
10005 ** These interfaces are only useful from within the
10006 ** [xFilter|xFilter() method] of a [virtual table] implementation.
10007 ** The result of invoking these interfaces from any other context
10008 ** is undefined and probably harmful.
10009 **
10010 ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
10011 ** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
10012 ** xFilter method which invokes these routines, and specifically
10013 ** a parameter that was previously selected for all-at-once IN constraint
10014 ** processing use the [sqlite3_vtab_in()] interface in the
10015 ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
10016 ** an xFilter argument that was selected for all-at-once IN constraint
10017 ** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
10018 ** exhibit some other undefined or harmful behavior.
10019 **
10020 ** ^(Use these routines to access all values on the right-hand side
10021 ** of the IN constraint using code like the following:
10022 **
10023 ** <blockquote><pre>
10024 ** &nbsp; for(rc=sqlite3_vtab_in_first(pList, &pVal);
10025 ** &nbsp; rc==SQLITE_OK && pVal
10026 ** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
10027 ** &nbsp; ){
10028 ** &nbsp; // do something with pVal
10029 ** &nbsp; }
10030 ** &nbsp; if( rc!=SQLITE_OK ){
10031 ** &nbsp; // an error has occurred
10032 ** &nbsp; }
10033 ** </pre></blockquote>)^
10034 **
10035 ** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
10036 ** routines return SQLITE_OK and set *P to point to the first or next value
10037 ** on the RHS of the IN constraint. ^If there are no more values on the
10038 ** right hand side of the IN constraint, then *P is set to NULL and these
10039 ** routines return [SQLITE_DONE]. ^The return value might be
10040 ** some other value, such as SQLITE_NOMEM, in the event of a malfunction.
10041 **
10042 ** The *ppOut values returned by these routines are only valid until the
10043 ** next call to either of these routines or until the end of the xFilter
10044 ** method from which these routines were called. If the virtual table
10045 ** implementation needs to retain the *ppOut values for longer, it must make
10046 ** copies. The *ppOut values are [protected sqlite3_value|protected].
10047 */
10048 SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
10049 SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
10050
10051 /*
10052 ** CAPI3REF: Constraint values in xBestIndex()
10053 ** METHOD: sqlite3_index_info
10054 **
10055 ** This API may only be used from within the [xBestIndex|xBestIndex method]
10056 ** of a [virtual table] implementation. The result of calling this interface
10057 ** from outside of an xBestIndex method are undefined and probably harmful.
10058 **
10059 ** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
10060 ** the [xBestIndex] method of a [virtual table] implementation, with P being
10061 ** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
10062 ** J being a 0-based index into P->aConstraint[], then this routine
10063 ** attempts to set *V to the value of the right-hand operand of
10064 ** that constraint if the right-hand operand is known. ^If the
10065 ** right-hand operand is not known, then *V is set to a NULL pointer.
10066 ** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
10067 ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
10068 ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
10069 ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
10070 ** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
10071 ** something goes wrong.
10072 **
10073 ** The sqlite3_vtab_rhs_value() interface is usually only successful if
10074 ** the right-hand operand of a constraint is a literal value in the original
10075 ** SQL statement. If the right-hand operand is an expression or a reference
10076 ** to some other column or a [host parameter], then sqlite3_vtab_rhs_value()
10077 ** will probably return [SQLITE_NOTFOUND].
10078 **
10079 ** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and
10080 ** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such
10081 ** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^
10082 **
10083 ** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value
10084 ** and remains valid for the duration of the xBestIndex method call.
10085 ** ^When xBestIndex returns, the sqlite3_value object returned by
10086 ** sqlite3_vtab_rhs_value() is automatically deallocated.
10087 **
10088 ** The "_rhs_" in the name of this routine is an abbreviation for
10089 ** "Right-Hand Side".
10090 */
10091 SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
10092
10093 /*
10094 ** CAPI3REF: Conflict resolution modes
@@ -14340,11 +14527,11 @@
14527 ** one parameter that destructors normally want. So we have to introduce
14528 ** this magic value that the code knows to handle differently. Any
14529 ** pointer will work here as long as it is distinct from SQLITE_STATIC
14530 ** and SQLITE_TRANSIENT.
14531 */
14532 #define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3OomClear)
14533
14534 /*
14535 ** When SQLITE_OMIT_WSD is defined, it means that the target platform does
14536 ** not support Writable Static Data (WSD) such as global and static variables.
14537 ** All variables must either be on the stack or dynamically allocated from
@@ -14468,14 +14655,15 @@
14655 #define BMS ((int)(sizeof(Bitmask)*8))
14656
14657 /*
14658 ** A bit in a Bitmask
14659 */
14660 #define MASKBIT(n) (((Bitmask)1)<<(n))
14661 #define MASKBIT64(n) (((u64)1)<<(n))
14662 #define MASKBIT32(n) (((unsigned int)1)<<(n))
14663 #define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0)
14664 #define ALLBITS ((Bitmask)-1)
14665
14666 /* A VList object records a mapping between parameters/variables/wildcards
14667 ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
14668 ** variable number associated with that parameter. See the format description
14669 ** on the sqlite3VListAdd() routine for more information. A VList is really
@@ -14533,18 +14721,19 @@
14721 ** Handle type for pages.
14722 */
14723 typedef struct PgHdr DbPage;
14724
14725 /*
14726 ** Page number PAGER_SJ_PGNO is never used in an SQLite database (it is
14727 ** reserved for working around a windows/posix incompatibility). It is
14728 ** used in the journal to signify that the remainder of the journal file
14729 ** is devoted to storing a super-journal name - there are no more pages to
14730 ** roll back. See comments for function writeSuperJournal() in pager.c
14731 ** for details.
14732 */
14733 #define PAGER_SJ_PGNO_COMPUTED(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
14734 #define PAGER_SJ_PGNO(x) ((x)->lckPgno)
14735
14736 /*
14737 ** Allowed values for the flags parameter to sqlite3PagerOpen().
14738 **
14739 ** NOTE: These values must match the corresponding BTREE_ values in btree.h.
@@ -15217,11 +15406,10 @@
15406 SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
15407 Table *pTab; /* Used when p4type is P4_TABLE */
15408 #ifdef SQLITE_ENABLE_CURSOR_HINTS
15409 Expr *pExpr; /* Used when p4type is P4_EXPR */
15410 #endif
 
15411 } p4;
15412 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
15413 char *zComment; /* Comment to improve readability */
15414 #endif
15415 #ifdef VDBE_PROFILE
@@ -15268,25 +15456,23 @@
15456 #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
15457 #define P4_STATIC (-1) /* Pointer to a static string */
15458 #define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */
15459 #define P4_INT32 (-3) /* P4 is a 32-bit signed integer */
15460 #define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */
15461 #define P4_TABLE (-5) /* P4 is a pointer to a Table structure */
 
15462 /* Above do not own any resources. Must free those below */
15463 #define P4_FREE_IF_LE (-6)
15464 #define P4_DYNAMIC (-6) /* Pointer to memory from sqliteMalloc() */
15465 #define P4_FUNCDEF (-7) /* P4 is a pointer to a FuncDef structure */
15466 #define P4_KEYINFO (-8) /* P4 is a pointer to a KeyInfo structure */
15467 #define P4_EXPR (-9) /* P4 is a pointer to an Expr tree */
15468 #define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */
15469 #define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */
15470 #define P4_REAL (-12) /* P4 is a 64-bit floating point value */
15471 #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
15472 #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */
15473 #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */
 
15474
15475 /* Error message codes for OP_Halt */
15476 #define P5_ConstraintNotNull 1
15477 #define P5_ConstraintUnique 2
15478 #define P5_ConstraintCheck 3
@@ -15327,46 +15513,46 @@
15513 /* Automatically generated. Do not edit */
15514 /* See the tool/mkopcodeh.tcl script for details */
15515 #define OP_Savepoint 0
15516 #define OP_AutoCommit 1
15517 #define OP_Transaction 2
15518 #define OP_Checkpoint 3
15519 #define OP_JournalMode 4
15520 #define OP_Vacuum 5
15521 #define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */
15522 #define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */
15523 #define OP_Goto 8 /* jump */
15524 #define OP_Gosub 9 /* jump */
15525 #define OP_InitCoroutine 10 /* jump */
15526 #define OP_Yield 11 /* jump */
15527 #define OP_MustBeInt 12 /* jump */
15528 #define OP_Jump 13 /* jump */
15529 #define OP_Once 14 /* jump */
15530 #define OP_If 15 /* jump */
15531 #define OP_IfNot 16 /* jump */
15532 #define OP_IsNullOrType 17 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */
15533 #define OP_IfNullRow 18 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
15534 #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
15535 #define OP_SeekLT 20 /* jump, synopsis: key=r[P3@P4] */
15536 #define OP_SeekLE 21 /* jump, synopsis: key=r[P3@P4] */
15537 #define OP_SeekGE 22 /* jump, synopsis: key=r[P3@P4] */
15538 #define OP_SeekGT 23 /* jump, synopsis: key=r[P3@P4] */
15539 #define OP_IfNotOpen 24 /* jump, synopsis: if( !csr[P1] ) goto P2 */
15540 #define OP_IfNoHope 25 /* jump, synopsis: key=r[P3@P4] */
15541 #define OP_NoConflict 26 /* jump, synopsis: key=r[P3@P4] */
15542 #define OP_NotFound 27 /* jump, synopsis: key=r[P3@P4] */
15543 #define OP_Found 28 /* jump, synopsis: key=r[P3@P4] */
15544 #define OP_SeekRowid 29 /* jump, synopsis: intkey=r[P3] */
15545 #define OP_NotExists 30 /* jump, synopsis: intkey=r[P3] */
15546 #define OP_Last 31 /* jump */
15547 #define OP_IfSmaller 32 /* jump */
15548 #define OP_SorterSort 33 /* jump */
15549 #define OP_Sort 34 /* jump */
15550 #define OP_Rewind 35 /* jump */
15551 #define OP_SorterNext 36 /* jump */
15552 #define OP_Prev 37 /* jump */
15553 #define OP_Next 38 /* jump */
15554 #define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */
15555 #define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */
15556 #define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */
15557 #define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */
15558 #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
@@ -15395,41 +15581,41 @@
15581 #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
15582 #define OP_Return 67
15583 #define OP_EndCoroutine 68
15584 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
15585 #define OP_Halt 70
15586 #define OP_BeginSubrtn 71 /* synopsis: r[P2]=P1 */
15587 #define OP_Integer 72 /* synopsis: r[P2]=P1 */
15588 #define OP_Int64 73 /* synopsis: r[P2]=P4 */
15589 #define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */
15590 #define OP_Null 75 /* synopsis: r[P2..P3]=NULL */
15591 #define OP_SoftNull 76 /* synopsis: r[P1]=NULL */
15592 #define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */
15593 #define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */
15594 #define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */
15595 #define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15596 #define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */
15597 #define OP_IntCopy 82 /* synopsis: r[P2]=r[P1] */
15598 #define OP_FkCheck 83
15599 #define OP_ResultRow 84 /* synopsis: output=r[P1@P2] */
15600 #define OP_CollSeq 85
15601 #define OP_AddImm 86 /* synopsis: r[P1]=r[P1]+P2 */
15602 #define OP_RealAffinity 87
15603 #define OP_Cast 88 /* synopsis: affinity(r[P1]) */
15604 #define OP_Permutation 89
15605 #define OP_Compare 90 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15606 #define OP_IsTrue 91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15607 #define OP_ZeroOrNull 92 /* synopsis: r[P2] = 0 OR NULL */
15608 #define OP_Offset 93 /* synopsis: r[P3] = sqlite_offset(P1) */
15609 #define OP_Column 94 /* synopsis: r[P3]=PX */
15610 #define OP_TypeCheck 95 /* synopsis: typecheck(r[P1@P2]) */
15611 #define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */
15612 #define OP_MakeRecord 97 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15613 #define OP_Count 98 /* synopsis: r[P2]=count() */
15614 #define OP_ReadCookie 99
15615 #define OP_SetCookie 100
15616 #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */
15617 #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
15618 #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
15619 #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
15620 #define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
15621 #define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
@@ -15436,82 +15622,84 @@
15622 #define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
15623 #define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
15624 #define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
15625 #define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
15626 #define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
15627 #define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */
15628 #define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */
15629 #define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
15630 #define OP_OpenDup 115
15631 #define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */
15632 #define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */
15633 #define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */
15634 #define OP_SorterOpen 119
15635 #define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15636 #define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */
15637 #define OP_Close 122
15638 #define OP_ColumnsUsed 123
15639 #define OP_SeekScan 124 /* synopsis: Scan-ahead up to P1 rows */
15640 #define OP_SeekHit 125 /* synopsis: set P2<=seekHit<=P3 */
15641 #define OP_Sequence 126 /* synopsis: r[P2]=cursor[P1].ctr++ */
15642 #define OP_NewRowid 127 /* synopsis: r[P2]=rowid */
15643 #define OP_Insert 128 /* synopsis: intkey=r[P3] data=r[P2] */
15644 #define OP_RowCell 129
15645 #define OP_Delete 130
15646 #define OP_ResetCount 131
15647 #define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15648 #define OP_SorterData 133 /* synopsis: r[P2]=data */
15649 #define OP_RowData 134 /* synopsis: r[P2]=data */
15650 #define OP_Rowid 135 /* synopsis: r[P2]=rowid */
15651 #define OP_NullRow 136
15652 #define OP_SeekEnd 137
15653 #define OP_IdxInsert 138 /* synopsis: key=r[P2] */
15654 #define OP_SorterInsert 139 /* synopsis: key=r[P2] */
15655 #define OP_IdxDelete 140 /* synopsis: key=r[P2@P3] */
15656 #define OP_DeferredSeek 141 /* synopsis: Move P3 to P1.rowid if needed */
15657 #define OP_IdxRowid 142 /* synopsis: r[P2]=rowid */
15658 #define OP_FinishSeek 143
15659 #define OP_Destroy 144
15660 #define OP_Clear 145
15661 #define OP_ResetSorter 146
15662 #define OP_CreateBtree 147 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15663 #define OP_SqlExec 148
15664 #define OP_ParseSchema 149
15665 #define OP_LoadAnalysis 150
15666 #define OP_DropTable 151
15667 #define OP_DropIndex 152
15668 #define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
15669 #define OP_DropTrigger 154
15670 #define OP_IntegrityCk 155
15671 #define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */
15672 #define OP_Param 157
15673 #define OP_FkCounter 158 /* synopsis: fkctr[P1]+=P2 */
15674 #define OP_MemMax 159 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15675 #define OP_OffsetLimit 160 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15676 #define OP_AggInverse 161 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15677 #define OP_AggStep 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15678 #define OP_AggStep1 163 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15679 #define OP_AggValue 164 /* synopsis: r[P3]=value N=P2 */
15680 #define OP_AggFinal 165 /* synopsis: accum=r[P1] N=P2 */
15681 #define OP_Expire 166
15682 #define OP_CursorLock 167
15683 #define OP_CursorUnlock 168
15684 #define OP_TableLock 169 /* synopsis: iDb=P1 root=P2 write=P3 */
15685 #define OP_VBegin 170
15686 #define OP_VCreate 171
15687 #define OP_VDestroy 172
15688 #define OP_VOpen 173
15689 #define OP_VInitIn 174 /* synopsis: r[P2]=ValueList(P1,P3) */
15690 #define OP_VColumn 175 /* synopsis: r[P3]=vcolumn(P2) */
15691 #define OP_VRename 176
15692 #define OP_Pagecount 177
15693 #define OP_MaxPgcnt 178
15694 #define OP_FilterAdd 179 /* synopsis: filter(P1) += key(P3@P4) */
15695 #define OP_Trace 180
15696 #define OP_CursorHint 181
15697 #define OP_ReleaseReg 182 /* synopsis: release r[P1@P2] mask P3 */
15698 #define OP_Noop 183
15699 #define OP_Explain 184
15700 #define OP_Abortable 185
15701
15702 /* Properties such as "out2" or "jump" that are specified in
15703 ** comments following the "case" for each opcode in the vdbe.c
15704 ** are encoded into bitvectors as follows:
15705 */
@@ -15520,34 +15708,34 @@
15708 #define OPFLG_IN2 0x04 /* in2: P2 is an input */
15709 #define OPFLG_IN3 0x08 /* in3: P3 is an input */
15710 #define OPFLG_OUT2 0x10 /* out2: P2 is an output */
15711 #define OPFLG_OUT3 0x20 /* out3: P3 is an output */
15712 #define OPFLG_INITIALIZER {\
15713 /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\
15714 /* 8 */ 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03,\
15715 /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x09, 0x09, 0x09, 0x09,\
15716 /* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\
15717 /* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
15718 /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
15719 /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
15720 /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15721 /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x00,\
15722 /* 72 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
15723 /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\
15724 /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\
15725 /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\
15726 /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
15727 /* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\
15728 /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
15729 /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
15730 /* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\
15731 /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
15732 /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
15733 /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15734 /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15735 /* 176 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15736 /* 184 */ 0x00, 0x00,}
15737
15738 /* The resolve3P2Values() routine is able to run faster if it knows
15739 ** the value of the largest JUMP opcode. The smaller the maximum
15740 ** JUMP opcode the better, so the mkopcodeh.tcl script that
15741 ** generated this include file strives to group all JUMP opcodes
@@ -17601,10 +17789,15 @@
17789 ** b-tree.
17790 */
17791 struct UnpackedRecord {
17792 KeyInfo *pKeyInfo; /* Collation and sort-order information */
17793 Mem *aMem; /* Values */
17794 union {
17795 char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */
17796 i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */
17797 } u;
17798 int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */
17799 u16 nField; /* Number of entries in apMem[] */
17800 i8 default_rc; /* Comparison result if keys are equal */
17801 u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
17802 i8 r1; /* Value to return if (lhs < rhs) */
17803 i8 r2; /* Value to return if (lhs > rhs) */
@@ -17908,11 +18101,14 @@
18101 ** TK_SELECT: 1st register of result vector */
18102 ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
18103 ** TK_VARIABLE: variable number (always >= 1).
18104 ** TK_SELECT_COLUMN: column of the result vector */
18105 i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
18106 union {
18107 int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
18108 int iOfst; /* else: start of token from start of statement */
18109 } w;
18110 AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
18111 union {
18112 Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
18113 ** for a column of an index on an expression */
18114 Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */
@@ -19017,10 +19213,11 @@
19213 #endif
19214 #ifndef SQLITE_UNTESTABLE
19215 int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
19216 #endif
19217 int bLocaltimeFault; /* True to fail localtime() calls */
19218 int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
19219 int iOnceResetThreshold; /* When to reset OP_Once counters */
19220 u32 szSorterRef; /* Min size in bytes to use sorter-refs */
19221 unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
19222 /* vvvv--- must be last ---vvv */
19223 #ifdef SQLITE_DEBUG
@@ -19221,11 +19418,11 @@
19418 Expr *pStart; /* Expression for "<expr> PRECEDING" */
19419 Expr *pEnd; /* Expression for "<expr> FOLLOWING" */
19420 Window **ppThis; /* Pointer to this object in Select.pWin list */
19421 Window *pNextWin; /* Next window function belonging to this SELECT */
19422 Expr *pFilter; /* The FILTER expression */
19423 FuncDef *pWFunc; /* The function */
19424 int iEphCsr; /* Partition buffer or Peer buffer */
19425 int regAccum; /* Accumulator */
19426 int regResult; /* Interim result */
19427 int csrApp; /* Function cursor (used by min/max) */
19428 int regApp; /* Function register (also used by min/max) */
@@ -19662,11 +19859,12 @@
19859 #endif
19860 SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*);
19861 SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
19862 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
19863 Upsert*);
19864 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,
19865 ExprList*,Select*,u16,int);
19866 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
19867 SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
19868 SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
19869 SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
19870 SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
@@ -20075,10 +20273,11 @@
20273 SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
20274 SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
20275 SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
20276 SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
20277 SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*);
20278 SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3*,const Expr*);
20279
20280 SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
20281 SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
20282
20283 #ifndef SQLITE_OMIT_SUBQUERY
@@ -20179,11 +20378,16 @@
20378 SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
20379 SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
20380 SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*);
20381 SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
20382 SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
20383
20384 SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
20385 #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
20386 && !defined(SQLITE_OMIT_VIRTUALTABLE)
20387 SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info*);
20388 #endif
20389 SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
20390 SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
20391 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
20392 SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*);
20393 SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse*);
@@ -21695,13 +21899,17 @@
21899 #endif
21900 #ifndef SQLITE_UNTESTABLE
21901 0, /* xTestCallback */
21902 #endif
21903 0, /* bLocaltimeFault */
21904 0, /* xAltLocaltime */
21905 0x7ffffffe, /* iOnceResetThreshold */
21906 SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
21907 0, /* iPrngSeed */
21908 #ifdef SQLITE_DEBUG
21909 {0,0,0,0,0,0} /* aTune */
21910 #endif
21911 };
21912
21913 /*
21914 ** Hash table for global functions - functions common to all
21915 ** database connections. After initialization, this table is
@@ -22041,20 +22249,20 @@
22249 i64 i; /* Integer value used when MEM_Int is set in flags */
22250 int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
22251 const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
22252 FuncDef *pDef; /* Used only when flags==MEM_Agg */
22253 } u;
22254 char *z; /* String or BLOB value */
22255 int n; /* Number of characters in string value, excluding '\0' */
22256 u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
22257 u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
22258 u8 eSubtype; /* Subtype for this value */
 
 
22259 /* ShallowCopy only needs to copy the information above */
22260 sqlite3 *db; /* The associated database connection */
22261 int szMalloc; /* Size of the zMalloc allocation */
22262 u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */
22263 char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
22264 void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
22265 #ifdef SQLITE_DEBUG
22266 Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
22267 u16 mScopyFlags; /* flags value immediately after the shallow copy */
22268 #endif
@@ -22062,15 +22270,47 @@
22270
22271 /*
22272 ** Size of struct Mem not including the Mem.zMalloc member or anything that
22273 ** follows.
22274 */
22275 #define MEMCELLSIZE offsetof(Mem,db)
22276
22277 /* One or more of the following flags are set to indicate the
22278 ** representations of the value stored in the Mem struct.
22279 **
22280 ** * MEM_Null An SQL NULL value
22281 **
22282 ** * MEM_Null|MEM_Zero An SQL NULL with the virtual table
22283 ** UPDATE no-change flag set
22284 **
22285 ** * MEM_Null|MEM_Term| An SQL NULL, but also contains a
22286 ** MEM_Subtype pointer accessible using
22287 ** sqlite3_value_pointer().
22288 **
22289 ** * MEM_Null|MEM_Cleared Special SQL NULL that compares non-equal
22290 ** to other NULLs even using the IS operator.
22291 **
22292 ** * MEM_Str A string, stored in Mem.z with
22293 ** length Mem.n. Zero-terminated if
22294 ** MEM_Term is set. This flag is
22295 ** incompatible with MEM_Blob and
22296 ** MEM_Null, but can appear with MEM_Int,
22297 ** MEM_Real, and MEM_IntReal.
22298 **
22299 ** * MEM_Blob A blob, stored in Mem.z length Mem.n.
22300 ** Incompatible with MEM_Str, MEM_Null,
22301 ** MEM_Int, MEM_Real, and MEM_IntReal.
22302 **
22303 ** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus
22304 ** MEM.u.i extra 0x00 bytes at the end.
22305 **
22306 ** * MEM_Int Integer stored in Mem.u.i.
22307 **
22308 ** * MEM_Real Real stored in Mem.u.r.
22309 **
22310 ** * MEM_IntReal Real stored as an integer in Mem.u.i.
22311 **
22312 ** If the MEM_Null flag is set, then the value is an SQL NULL value.
22313 ** For a pointer type created using sqlite3_bind_pointer() or
22314 ** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
22315 **
22316 ** If the MEM_Str flag is set then Mem.z points at a string representation.
@@ -22077,39 +22317,36 @@
22317 ** Usually this is encoded in the same unicode encoding as the main
22318 ** database (see below for exceptions). If the MEM_Term flag is also
22319 ** set, then the string is nul terminated. The MEM_Int and MEM_Real
22320 ** flags may coexist with the MEM_Str flag.
22321 */
22322 #define MEM_Undefined 0x0000 /* Value is undefined */
22323 #define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
22324 #define MEM_Str 0x0002 /* Value is a string */
22325 #define MEM_Int 0x0004 /* Value is an integer */
22326 #define MEM_Real 0x0008 /* Value is a real number */
22327 #define MEM_Blob 0x0010 /* Value is a BLOB */
22328 #define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
22329 #define MEM_AffMask 0x003f /* Mask of affinity bits */
22330
22331 /* Extra bits that modify the meanings of the core datatypes above
22332 */
22333 #define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
22334 /* 0x0080 // Available */
22335 #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
 
 
 
 
 
 
 
 
22336 #define MEM_Term 0x0200 /* String in Mem.z is zero terminated */
22337 #define MEM_Zero 0x0400 /* Mem.i contains count of 0s appended to blob */
22338 #define MEM_Subtype 0x0800 /* Mem.eSubtype is valid */
22339 #define MEM_TypeMask 0x0dbf /* Mask of type bits */
22340
22341 /* Bits that determine the storage for Mem.z for a string or blob or
22342 ** aggregate accumulator.
22343 */
22344 #define MEM_Dyn 0x1000 /* Need to call Mem.xDel() on Mem.z */
22345 #define MEM_Static 0x2000 /* Mem.z points to a static string */
22346 #define MEM_Ephem 0x4000 /* Mem.z points to an ephemeral string */
22347 #define MEM_Agg 0x8000 /* Mem.z points to an agg function context */
22348
22349 /* Return TRUE if Mem X contains dynamically allocated content - anything
22350 ** that needs to be deallocated to avoid a leak.
22351 */
22352 #define VdbeMemDynamic(X) \
@@ -22127,15 +22364,19 @@
22364 #define MemNullNochng(X) \
22365 (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \
22366 && (X)->n==0 && (X)->u.nZero==0)
22367
22368 /*
22369 ** Return true if a memory cell has been initialized and is valid.
22370 ** is for use inside assert() statements only.
22371 **
22372 ** A Memory cell is initialized if at least one of the
22373 ** MEM_Null, MEM_Str, MEM_Int, MEM_Real, MEM_Blob, or MEM_IntReal bits
22374 ** is set. It is "undefined" if all those bits are zero.
22375 */
22376 #ifdef SQLITE_DEBUG
22377 #define memIsValid(M) ((M)->flags & MEM_AffMask)!=0
22378 #endif
22379
22380 /*
22381 ** Each auxiliary data pointer stored by a user defined function
22382 ** implementation calling sqlite3_set_auxdata() is stored in an instance
@@ -22169,10 +22410,11 @@
22410 FuncDef *pFunc; /* Pointer to function information */
22411 Mem *pMem; /* Memory cell used to store aggregate context */
22412 Vdbe *pVdbe; /* The VM that owns this context */
22413 int iOp; /* Instruction number of OP_Function */
22414 int isError; /* Error code returned by the function. */
22415 u8 enc; /* Encoding to use for results */
22416 u8 skipFlag; /* Skip accumulator loading if true */
22417 u8 argc; /* Number of arguments */
22418 sqlite3_value *argv[1]; /* Argument set */
22419 };
22420
@@ -22217,11 +22459,10 @@
22459 struct Vdbe {
22460 sqlite3 *db; /* The database connection that owns this statement */
22461 Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
22462 Parse *pParse; /* Parsing context used to create this Vdbe */
22463 ynVar nVar; /* Number of entries in aVar[] */
 
22464 int nMem; /* Number of memory locations currently allocated */
22465 int nCursor; /* Number of slots in apCsr[] */
22466 u32 cacheCtr; /* VdbeCursor row cache generation counter */
22467 int pc; /* The program counter */
22468 int rc; /* Value to return */
@@ -22256,10 +22497,11 @@
22497 u16 nResColumn; /* Number of columns in one row of the result set */
22498 u8 errorAction; /* Recovery action to do in case of an error */
22499 u8 minWriteFileFormat; /* Minimum file format for writable database files */
22500 u8 prepFlags; /* SQLITE_PREPARE_* flags */
22501 u8 doingRerun; /* True if rerunning after an auto-reprepare */
22502 u8 eVdbeState; /* On of the VDBE_*_STATE values */
22503 bft expired:2; /* 1: recompile VM immediately 2: when convenient */
22504 bft explain:2; /* True if EXPLAIN present on SQL command */
22505 bft changeCntOn:1; /* True to update the change-counter */
22506 bft runOnlyOnce:1; /* Automatically expire on reset */
22507 bft usesStmtJournal:1; /* True if uses a statement journal */
@@ -22286,17 +22528,16 @@
22528 ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */
22529 #endif
22530 };
22531
22532 /*
22533 ** The following are allowed values for Vdbe.eVdbeState
22534 */
22535 #define VDBE_INIT_STATE 0 /* Prepared statement under construction */
22536 #define VDBE_READY_STATE 1 /* Ready to run but not yet started */
22537 #define VDBE_RUN_STATE 2 /* Run in progress */
22538 #define VDBE_HALT_STATE 3 /* Finished. Need reset() or finalize() */
 
22539
22540 /*
22541 ** Structure used to store the context required by the
22542 ** sqlite3_preupdate_*() API functions.
22543 */
@@ -22315,18 +22556,36 @@
22556 Mem *aNew; /* Array of new.* values */
22557 Table *pTab; /* Schema object being upated */
22558 Index *pPk; /* PK index if pTab is WITHOUT ROWID */
22559 };
22560
22561 /*
22562 ** An instance of this object is used to pass an vector of values into
22563 ** OP_VFilter, the xFilter method of a virtual table. The vector is the
22564 ** set of values on the right-hand side of an IN constraint.
22565 **
22566 ** The value as passed into xFilter is an sqlite3_value with a "pointer"
22567 ** type, such as is generated by sqlite3_result_pointer() and read by
22568 ** sqlite3_value_pointer. Such values have MEM_Term|MEM_Subtype|MEM_Null
22569 ** and a subtype of 'p'. The sqlite3_vtab_in_first() and _next() interfaces
22570 ** know how to use this object to step through all the values in the
22571 ** right operand of the IN constraint.
22572 */
22573 typedef struct ValueList ValueList;
22574 struct ValueList {
22575 BtCursor *pCsr; /* An ephemeral table holding all values */
22576 sqlite3_value *pOut; /* Register to hold each decoded output value */
22577 };
22578
22579 /*
22580 ** Function prototypes
22581 */
22582 SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
22583 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
22584 void sqliteVdbePopStack(Vdbe*,int);
22585 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p);
22586 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
 
22587 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
22588 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
22589 SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
22590 SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
22591 SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
@@ -22384,10 +22643,11 @@
22643 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
22644 SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8);
22645 SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
22646 SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
22647 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
22648 SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem*p);
22649 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
22650 #ifndef SQLITE_OMIT_WINDOWFUNC
22651 SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
22652 #endif
22653 #if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
@@ -23351,12 +23611,14 @@
23611 ** The following routine implements the rough equivalent of localtime_r()
23612 ** using whatever operating-system specific localtime facility that
23613 ** is available. This routine returns 0 on success and
23614 ** non-zero on any kind of error.
23615 **
23616 ** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this
23617 ** routine will always fail. If bLocaltimeFault is nonzero and
23618 ** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is
23619 ** invoked in place of the OS-defined localtime() function.
23620 **
23621 ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
23622 ** library function localtime_r() is used to assist in the calculation of
23623 ** local time.
23624 */
@@ -23368,20 +23630,34 @@
23630 sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
23631 #endif
23632 sqlite3_mutex_enter(mutex);
23633 pX = localtime(t);
23634 #ifndef SQLITE_UNTESTABLE
23635 if( sqlite3GlobalConfig.bLocaltimeFault ){
23636 if( sqlite3GlobalConfig.xAltLocaltime!=0
23637 && 0==sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm)
23638 ){
23639 pX = pTm;
23640 }else{
23641 pX = 0;
23642 }
23643 }
23644 #endif
23645 if( pX ) *pTm = *pX;
23646 #if SQLITE_THREADSAFE>0
23647 sqlite3_mutex_leave(mutex);
23648 #endif
23649 rc = pX==0;
23650 #else
23651 #ifndef SQLITE_UNTESTABLE
23652 if( sqlite3GlobalConfig.bLocaltimeFault ){
23653 if( sqlite3GlobalConfig.xAltLocaltime!=0 ){
23654 return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm);
23655 }else{
23656 return 1;
23657 }
23658 }
23659 #endif
23660 #if HAVE_LOCALTIME_R
23661 rc = localtime_r(t, pTm)==0;
23662 #else
23663 rc = localtime_s(pTm, t);
@@ -23392,71 +23668,60 @@
23668 #endif /* SQLITE_OMIT_LOCALTIME */
23669
23670
23671 #ifndef SQLITE_OMIT_LOCALTIME
23672 /*
23673 ** Assuming the input DateTime is UTC, move it to its localtime equivalent.
 
 
 
 
 
23674 */
23675 static int toLocaltime(
23676 DateTime *p, /* Date at which to calculate offset */
23677 sqlite3_context *pCtx /* Write error here if one occurs */
 
23678 ){
 
23679 time_t t;
23680 struct tm sLocal;
23681 int iYearDiff;
23682
23683 /* Initialize the contents of sLocal to avoid a compiler warning. */
23684 memset(&sLocal, 0, sizeof(sLocal));
23685
23686 computeJD(p);
23687 if( p->iJD<2108667600*(i64)100000 /* 1970-01-01 */
23688 || p->iJD>2130141456*(i64)100000 /* 2038-01-18 */
23689 ){
23690 /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
23691 ** works for years between 1970 and 2037. For dates outside this range,
23692 ** SQLite attempts to map the year into an equivalent year within this
23693 ** range, do the calculation, then map the year back.
23694 */
23695 DateTime x = *p;
23696 computeYMD_HMS(&x);
23697 iYearDiff = (2000 + x.Y%4) - x.Y;
23698 x.Y += iYearDiff;
23699 x.validJD = 0;
23700 computeJD(&x);
23701 t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
23702 }else{
23703 iYearDiff = 0;
23704 t = (time_t)(p->iJD/1000 - 21086676*(i64)10000);
23705 }
 
 
 
23706 if( osLocaltime(&t, &sLocal) ){
23707 sqlite3_result_error(pCtx, "local time unavailable", -1);
23708 return SQLITE_ERROR;
23709 }
23710 p->Y = sLocal.tm_year + 1900 - iYearDiff;
23711 p->M = sLocal.tm_mon + 1;
23712 p->D = sLocal.tm_mday;
23713 p->h = sLocal.tm_hour;
23714 p->m = sLocal.tm_min;
23715 p->s = sLocal.tm_sec + (p->iJD%1000)*0.001;
23716 p->validYMD = 1;
23717 p->validHMS = 1;
23718 p->validJD = 0;
23719 p->rawS = 0;
23720 p->validTZ = 0;
23721 p->isError = 0;
23722 return SQLITE_OK;
 
 
 
23723 }
23724 #endif /* SQLITE_OMIT_LOCALTIME */
23725
23726 /*
23727 ** The following table defines various date transformations of the form
@@ -23524,11 +23789,13 @@
23789 if( sqlite3_stricmp(z, "auto")==0 ){
23790 if( idx>1 ) return 1; /* IMP: R-33611-57934 */
23791 if( !p->rawS || p->validJD ){
23792 rc = 0;
23793 p->rawS = 0;
23794 }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */
23795 && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */
23796 ){
23797 r = p->s*1000.0 + 210866760000000.0;
23798 clearYMD_HMS_TZ(p);
23799 p->iJD = (sqlite3_int64)(r + 0.5);
23800 p->validJD = 1;
23801 p->rawS = 0;
@@ -23545,11 +23812,11 @@
23812 ** is not the first modifier, or if the prior argument is not a numeric
23813 ** value in the allowed range of julian day numbers understood by
23814 ** SQLite (0..5373484.5) then the result will be NULL.
23815 */
23816 if( sqlite3_stricmp(z, "julianday")==0 ){
23817 if( idx>1 ) return 1; /* IMP: R-31176-64601 */
23818 if( p->validJD && p->rawS ){
23819 rc = 0;
23820 p->rawS = 0;
23821 }
23822 }
@@ -23561,13 +23828,11 @@
23828 **
23829 ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
23830 ** show local time.
23831 */
23832 if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
23833 rc = toLocaltime(p, pCtx);
 
 
23834 }
23835 break;
23836 }
23837 #endif
23838 case 'u': {
@@ -23576,10 +23841,11 @@
23841 **
23842 ** Treat the current value of p->s as the number of
23843 ** seconds since 1970. Convert to a real julian day number.
23844 */
23845 if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
23846 if( idx>1 ) return 1; /* IMP: R-49255-55373 */
23847 r = p->s*1000.0 + 210866760000000.0;
23848 if( r>=0.0 && r<464269060800000.0 ){
23849 clearYMD_HMS_TZ(p);
23850 p->iJD = (sqlite3_int64)(r + 0.5);
23851 p->validJD = 1;
@@ -23588,22 +23854,35 @@
23854 }
23855 }
23856 #ifndef SQLITE_OMIT_LOCALTIME
23857 else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
23858 if( p->tzSet==0 ){
23859 i64 iOrigJD; /* Original localtime */
23860 i64 iGuess; /* Guess at the corresponding utc time */
23861 int cnt = 0; /* Safety to prevent infinite loop */
23862 int iErr; /* Guess is off by this much */
23863
23864 computeJD(p);
23865 iGuess = iOrigJD = p->iJD;
23866 iErr = 0;
23867 do{
23868 DateTime new;
23869 memset(&new, 0, sizeof(new));
23870 iGuess -= iErr;
23871 new.iJD = iGuess;
23872 new.validJD = 1;
23873 rc = toLocaltime(&new, pCtx);
23874 if( rc ) return rc;
23875 computeJD(&new);
23876 iErr = new.iJD - iOrigJD;
23877 }while( iErr && cnt++<3 );
23878 memset(p, 0, sizeof(*p));
23879 p->iJD = iGuess;
23880 p->validJD = 1;
23881 p->tzSet = 1;
 
 
23882 }
23883 rc = SQLITE_OK;
23884 }
23885 #endif
23886 break;
23887 }
23888 case 'w': {
@@ -23849,15 +24128,42 @@
24128 int argc,
24129 sqlite3_value **argv
24130 ){
24131 DateTime x;
24132 if( isDate(context, argc, argv, &x)==0 ){
24133 int Y, s;
24134 char zBuf[24];
24135 computeYMD_HMS(&x);
24136 Y = x.Y;
24137 if( Y<0 ) Y = -Y;
24138 zBuf[1] = '0' + (Y/1000)%10;
24139 zBuf[2] = '0' + (Y/100)%10;
24140 zBuf[3] = '0' + (Y/10)%10;
24141 zBuf[4] = '0' + (Y)%10;
24142 zBuf[5] = '-';
24143 zBuf[6] = '0' + (x.M/10)%10;
24144 zBuf[7] = '0' + (x.M)%10;
24145 zBuf[8] = '-';
24146 zBuf[9] = '0' + (x.D/10)%10;
24147 zBuf[10] = '0' + (x.D)%10;
24148 zBuf[11] = ' ';
24149 zBuf[12] = '0' + (x.h/10)%10;
24150 zBuf[13] = '0' + (x.h)%10;
24151 zBuf[14] = ':';
24152 zBuf[15] = '0' + (x.m/10)%10;
24153 zBuf[16] = '0' + (x.m)%10;
24154 zBuf[17] = ':';
24155 s = (int)x.s;
24156 zBuf[18] = '0' + (s/10)%10;
24157 zBuf[19] = '0' + (s)%10;
24158 zBuf[20] = 0;
24159 if( x.Y<0 ){
24160 zBuf[0] = '-';
24161 sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT);
24162 }else{
24163 sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT);
24164 }
24165 }
24166 }
24167
24168 /*
24169 ** time( TIMESTRING, MOD, MOD, ...)
@@ -23869,14 +24175,24 @@
24175 int argc,
24176 sqlite3_value **argv
24177 ){
24178 DateTime x;
24179 if( isDate(context, argc, argv, &x)==0 ){
24180 int s;
24181 char zBuf[16];
24182 computeHMS(&x);
24183 zBuf[0] = '0' + (x.h/10)%10;
24184 zBuf[1] = '0' + (x.h)%10;
24185 zBuf[2] = ':';
24186 zBuf[3] = '0' + (x.m/10)%10;
24187 zBuf[4] = '0' + (x.m)%10;
24188 zBuf[5] = ':';
24189 s = (int)x.s;
24190 zBuf[6] = '0' + (s/10)%10;
24191 zBuf[7] = '0' + (s)%10;
24192 zBuf[8] = 0;
24193 sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT);
24194 }
24195 }
24196
24197 /*
24198 ** date( TIMESTRING, MOD, MOD, ...)
@@ -23888,14 +24204,32 @@
24204 int argc,
24205 sqlite3_value **argv
24206 ){
24207 DateTime x;
24208 if( isDate(context, argc, argv, &x)==0 ){
24209 int Y;
24210 char zBuf[16];
24211 computeYMD(&x);
24212 Y = x.Y;
24213 if( Y<0 ) Y = -Y;
24214 zBuf[1] = '0' + (Y/1000)%10;
24215 zBuf[2] = '0' + (Y/100)%10;
24216 zBuf[3] = '0' + (Y/10)%10;
24217 zBuf[4] = '0' + (Y)%10;
24218 zBuf[5] = '-';
24219 zBuf[6] = '0' + (x.M/10)%10;
24220 zBuf[7] = '0' + (x.M)%10;
24221 zBuf[8] = '-';
24222 zBuf[9] = '0' + (x.D/10)%10;
24223 zBuf[10] = '0' + (x.D)%10;
24224 zBuf[11] = 0;
24225 if( x.Y<0 ){
24226 zBuf[0] = '-';
24227 sqlite3_result_text(context, zBuf, 11, SQLITE_TRANSIENT);
24228 }else{
24229 sqlite3_result_text(context, &zBuf[1], 10, SQLITE_TRANSIENT);
24230 }
24231 }
24232 }
24233
24234 /*
24235 ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
@@ -26668,12 +27002,17 @@
27002 ** 32-bit signed integer. Hence the largest allocation is 0x40000000
27003 ** or 1073741824 bytes.
27004 */
27005 static int memsys5Roundup(int n){
27006 int iFullSz;
27007 if( n<=mem5.szAtom*2 ){
27008 if( n<=mem5.szAtom ) return mem5.szAtom;
27009 return mem5.szAtom*2;
27010 }
27011 if( n>0x40000000 ) return 0;
27012 for(iFullSz=mem5.szAtom*8; iFullSz<n; iFullSz *= 4);
27013 if( (iFullSz/2)>=n ) return iFullSz/2;
27014 return iFullSz;
27015 }
27016
27017 /*
27018 ** Return the ceiling of the logarithm base 2 of iValue.
@@ -29988,17 +30327,26 @@
30327 bufpt[j] = 0;
30328 length = j;
30329 goto adjust_width_for_utf8;
30330 }
30331 case etTOKEN: {
 
30332 if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
30333 if( flag_alternateform ){
30334 /* %#T means an Expr pointer that uses Expr.u.zToken */
30335 Expr *pExpr = va_arg(ap,Expr*);
30336 if( ALWAYS(pExpr) && ALWAYS(!ExprHasProperty(pExpr,EP_IntValue)) ){
30337 sqlite3_str_appendall(pAccum, (const char*)pExpr->u.zToken);
30338 sqlite3RecordErrorOffsetOfExpr(pAccum->db, pExpr);
30339 }
30340 }else{
30341 /* %T means a Token pointer */
30342 Token *pToken = va_arg(ap, Token*);
30343 assert( bArgList==0 );
30344 if( pToken && pToken->n ){
30345 sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
30346 sqlite3RecordErrorByteOffset(pAccum->db, pToken->z);
30347 }
30348 }
30349 length = width = 0;
30350 break;
30351 }
30352 case etSRCITEM: {
@@ -30072,10 +30420,22 @@
30420 zEnd = &zText[strlen(zText)];
30421 if( SQLITE_WITHIN(z,zText,zEnd) ){
30422 db->errByteOffset = (int)(z-zText);
30423 }
30424 }
30425
30426 /*
30427 ** If pExpr has a byte offset for the start of a token, record that as
30428 ** as the error offset.
30429 */
30430 SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){
30431 while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){
30432 pExpr = pExpr->pLeft;
30433 }
30434 if( pExpr==0 ) return;
30435 db->errByteOffset = pExpr->w.iOfst;
30436 }
30437
30438 /*
30439 ** Enlarge the memory allocation on a StrAccum object so that it is
30440 ** able to accept at least N more bytes of text.
30441 **
@@ -30535,11 +30895,11 @@
30895 memset(p, 0, sizeof(*p));
30896 }else{
30897 p->iLevel++;
30898 }
30899 assert( moreToFollow==0 || moreToFollow==1 );
30900 if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
30901 return p;
30902 }
30903
30904 /*
30905 ** Finished with one layer of the tree
@@ -30559,11 +30919,11 @@
30919 int i;
30920 StrAccum acc;
30921 char zBuf[500];
30922 sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
30923 if( p ){
30924 for(i=0; i<p->iLevel && i<(int)sizeof(p->bLine)-1; i++){
30925 sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4);
30926 }
30927 sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
30928 }
30929 if( zFormat!=0 ){
@@ -30889,11 +31249,11 @@
31249 ** Generate a human-readable explanation for a Window Function object
31250 */
31251 SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
31252 pView = sqlite3TreeViewPush(pView, more);
31253 sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
31254 pWin->pWFunc->zName, pWin->pWFunc->nArg);
31255 sqlite3TreeViewWindow(pView, pWin, 0);
31256 sqlite3TreeViewPop(pView);
31257 }
31258 #endif /* SQLITE_OMIT_WINDOWFUNC */
31259
@@ -30914,11 +31274,11 @@
31274 StrAccum x;
31275 sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
31276 sqlite3_str_appendf(&x, " fg.af=%x.%c",
31277 pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
31278 if( ExprHasProperty(pExpr, EP_FromJoin) ){
31279 sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable);
31280 }
31281 if( ExprHasProperty(pExpr, EP_FromDDL) ){
31282 sqlite3_str_appendf(&x, " DDL");
31283 }
31284 if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
@@ -34282,46 +34642,46 @@
34642 SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
34643 static const char *const azName[] = {
34644 /* 0 */ "Savepoint" OpHelp(""),
34645 /* 1 */ "AutoCommit" OpHelp(""),
34646 /* 2 */ "Transaction" OpHelp(""),
34647 /* 3 */ "Checkpoint" OpHelp(""),
34648 /* 4 */ "JournalMode" OpHelp(""),
34649 /* 5 */ "Vacuum" OpHelp(""),
34650 /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"),
34651 /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"),
34652 /* 8 */ "Goto" OpHelp(""),
34653 /* 9 */ "Gosub" OpHelp(""),
34654 /* 10 */ "InitCoroutine" OpHelp(""),
34655 /* 11 */ "Yield" OpHelp(""),
34656 /* 12 */ "MustBeInt" OpHelp(""),
34657 /* 13 */ "Jump" OpHelp(""),
34658 /* 14 */ "Once" OpHelp(""),
34659 /* 15 */ "If" OpHelp(""),
34660 /* 16 */ "IfNot" OpHelp(""),
34661 /* 17 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
34662 /* 18 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
34663 /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
34664 /* 20 */ "SeekLT" OpHelp("key=r[P3@P4]"),
34665 /* 21 */ "SeekLE" OpHelp("key=r[P3@P4]"),
34666 /* 22 */ "SeekGE" OpHelp("key=r[P3@P4]"),
34667 /* 23 */ "SeekGT" OpHelp("key=r[P3@P4]"),
34668 /* 24 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"),
34669 /* 25 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
34670 /* 26 */ "NoConflict" OpHelp("key=r[P3@P4]"),
34671 /* 27 */ "NotFound" OpHelp("key=r[P3@P4]"),
34672 /* 28 */ "Found" OpHelp("key=r[P3@P4]"),
34673 /* 29 */ "SeekRowid" OpHelp("intkey=r[P3]"),
34674 /* 30 */ "NotExists" OpHelp("intkey=r[P3]"),
34675 /* 31 */ "Last" OpHelp(""),
34676 /* 32 */ "IfSmaller" OpHelp(""),
34677 /* 33 */ "SorterSort" OpHelp(""),
34678 /* 34 */ "Sort" OpHelp(""),
34679 /* 35 */ "Rewind" OpHelp(""),
34680 /* 36 */ "SorterNext" OpHelp(""),
34681 /* 37 */ "Prev" OpHelp(""),
34682 /* 38 */ "Next" OpHelp(""),
34683 /* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"),
34684 /* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"),
34685 /* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"),
34686 /* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"),
34687 /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
@@ -34350,41 +34710,41 @@
34710 /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
34711 /* 67 */ "Return" OpHelp(""),
34712 /* 68 */ "EndCoroutine" OpHelp(""),
34713 /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
34714 /* 70 */ "Halt" OpHelp(""),
34715 /* 71 */ "BeginSubrtn" OpHelp("r[P2]=P1"),
34716 /* 72 */ "Integer" OpHelp("r[P2]=P1"),
34717 /* 73 */ "Int64" OpHelp("r[P2]=P4"),
34718 /* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34719 /* 75 */ "Null" OpHelp("r[P2..P3]=NULL"),
34720 /* 76 */ "SoftNull" OpHelp("r[P1]=NULL"),
34721 /* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34722 /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34723 /* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
34724 /* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
34725 /* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"),
34726 /* 82 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
34727 /* 83 */ "FkCheck" OpHelp(""),
34728 /* 84 */ "ResultRow" OpHelp("output=r[P1@P2]"),
34729 /* 85 */ "CollSeq" OpHelp(""),
34730 /* 86 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
34731 /* 87 */ "RealAffinity" OpHelp(""),
34732 /* 88 */ "Cast" OpHelp("affinity(r[P1])"),
34733 /* 89 */ "Permutation" OpHelp(""),
34734 /* 90 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34735 /* 91 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34736 /* 92 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34737 /* 93 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34738 /* 94 */ "Column" OpHelp("r[P3]=PX"),
34739 /* 95 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34740 /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34741 /* 97 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34742 /* 98 */ "Count" OpHelp("r[P2]=count()"),
34743 /* 99 */ "ReadCookie" OpHelp(""),
34744 /* 100 */ "SetCookie" OpHelp(""),
34745 /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
34746 /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
34747 /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
34748 /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
34749 /* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
34750 /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
@@ -34391,82 +34751,84 @@
34751 /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
34752 /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
34753 /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
34754 /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
34755 /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
34756 /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
34757 /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
34758 /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
34759 /* 115 */ "OpenDup" OpHelp(""),
34760 /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"),
34761 /* 117 */ "String8" OpHelp("r[P2]='P4'"),
34762 /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34763 /* 119 */ "SorterOpen" OpHelp(""),
34764 /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34765 /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34766 /* 122 */ "Close" OpHelp(""),
34767 /* 123 */ "ColumnsUsed" OpHelp(""),
34768 /* 124 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34769 /* 125 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34770 /* 126 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34771 /* 127 */ "NewRowid" OpHelp("r[P2]=rowid"),
34772 /* 128 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34773 /* 129 */ "RowCell" OpHelp(""),
34774 /* 130 */ "Delete" OpHelp(""),
34775 /* 131 */ "ResetCount" OpHelp(""),
34776 /* 132 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34777 /* 133 */ "SorterData" OpHelp("r[P2]=data"),
34778 /* 134 */ "RowData" OpHelp("r[P2]=data"),
34779 /* 135 */ "Rowid" OpHelp("r[P2]=rowid"),
34780 /* 136 */ "NullRow" OpHelp(""),
34781 /* 137 */ "SeekEnd" OpHelp(""),
34782 /* 138 */ "IdxInsert" OpHelp("key=r[P2]"),
34783 /* 139 */ "SorterInsert" OpHelp("key=r[P2]"),
34784 /* 140 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34785 /* 141 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34786 /* 142 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34787 /* 143 */ "FinishSeek" OpHelp(""),
34788 /* 144 */ "Destroy" OpHelp(""),
34789 /* 145 */ "Clear" OpHelp(""),
34790 /* 146 */ "ResetSorter" OpHelp(""),
34791 /* 147 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34792 /* 148 */ "SqlExec" OpHelp(""),
34793 /* 149 */ "ParseSchema" OpHelp(""),
34794 /* 150 */ "LoadAnalysis" OpHelp(""),
34795 /* 151 */ "DropTable" OpHelp(""),
34796 /* 152 */ "DropIndex" OpHelp(""),
34797 /* 153 */ "Real" OpHelp("r[P2]=P4"),
34798 /* 154 */ "DropTrigger" OpHelp(""),
34799 /* 155 */ "IntegrityCk" OpHelp(""),
34800 /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34801 /* 157 */ "Param" OpHelp(""),
34802 /* 158 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34803 /* 159 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34804 /* 160 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34805 /* 161 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34806 /* 162 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34807 /* 163 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34808 /* 164 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34809 /* 165 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34810 /* 166 */ "Expire" OpHelp(""),
34811 /* 167 */ "CursorLock" OpHelp(""),
34812 /* 168 */ "CursorUnlock" OpHelp(""),
34813 /* 169 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34814 /* 170 */ "VBegin" OpHelp(""),
34815 /* 171 */ "VCreate" OpHelp(""),
34816 /* 172 */ "VDestroy" OpHelp(""),
34817 /* 173 */ "VOpen" OpHelp(""),
34818 /* 174 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"),
34819 /* 175 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34820 /* 176 */ "VRename" OpHelp(""),
34821 /* 177 */ "Pagecount" OpHelp(""),
34822 /* 178 */ "MaxPgcnt" OpHelp(""),
34823 /* 179 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
34824 /* 180 */ "Trace" OpHelp(""),
34825 /* 181 */ "CursorHint" OpHelp(""),
34826 /* 182 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34827 /* 183 */ "Noop" OpHelp(""),
34828 /* 184 */ "Explain" OpHelp(""),
34829 /* 185 */ "Abortable" OpHelp(""),
34830 };
34831 return azName[i];
34832 }
34833 #endif
34834
@@ -39382,15 +39744,21 @@
39744 int ofst, /* First lock to acquire or release */
39745 int n, /* Number of locks to acquire or release */
39746 int flags /* What to do with the lock */
39747 ){
39748 unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
39749 unixShm *p; /* The shared memory being locked */
39750 unixShmNode *pShmNode; /* The underlying file iNode */
39751 int rc = SQLITE_OK; /* Result code */
39752 u16 mask; /* Mask of locks to take or release */
39753 int *aLock;
39754
39755 p = pDbFd->pShm;
39756 if( p==0 ) return SQLITE_IOERR_SHMLOCK;
39757 pShmNode = p->pShmNode;
39758 if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
39759 aLock = pShmNode->aLock;
39760
39761 assert( pShmNode==pDbFd->pInode->pShmNode );
39762 assert( pShmNode->pInode==pDbFd->pInode );
39763 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
39764 assert( n>=1 );
@@ -40483,24 +40851,27 @@
40851 ** "<path to db>-journalNN"
40852 ** "<path to db>-walNN"
40853 **
40854 ** where NN is a decimal number. The NN naming schemes are
40855 ** used by the test_multiplex.c module.
40856 **
40857 ** In normal operation, the journal file name will always contain
40858 ** a '-' character. However in 8+3 filename mode, or if a corrupt
40859 ** rollback journal specifies a super-journal with a goofy name, then
40860 ** the '-' might be missing or the '-' might be the first character in
40861 ** the filename. In that case, just return SQLITE_OK with *pMode==0.
40862 */
40863 nDb = sqlite3Strlen30(zPath) - 1;
40864 while( nDb>0 && zPath[nDb]!='.' ){
40865 if( zPath[nDb]=='-' ){
40866 memcpy(zDb, zPath, nDb);
40867 zDb[nDb] = '\0';
40868 rc = getFileMode(zDb, pMode, pUid, pGid);
40869 break;
40870 }
40871 nDb--;
40872 }
 
 
 
 
40873 }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
40874 *pMode = 0600;
40875 }else if( flags & SQLITE_OPEN_URI ){
40876 /* If this is a main database file and the file was opened using a URI
40877 ** filename, check for the "modeof" parameter. If present, interpret
@@ -46674,14 +47045,18 @@
47045 int flags /* What to do with the lock */
47046 ){
47047 winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */
47048 winShm *p = pDbFd->pShm; /* The shared memory being locked */
47049 winShm *pX; /* For looping over all siblings */
47050 winShmNode *pShmNode;
47051 int rc = SQLITE_OK; /* Result code */
47052 u16 mask; /* Mask of locks to take or release */
47053
47054 if( p==0 ) return SQLITE_IOERR_SHMLOCK;
47055 pShmNode = p->pShmNode;
47056 if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK;
47057
47058 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
47059 assert( n>=1 );
47060 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
47061 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
47062 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
@@ -53576,10 +53951,11 @@
53951 u16 nExtra; /* Add this many bytes to each in-memory page */
53952 i16 nReserve; /* Number of unused bytes at end of each page */
53953 u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
53954 u32 sectorSize; /* Assumed sector size during rollback */
53955 Pgno mxPgno; /* Maximum allowed size of the database */
53956 Pgno lckPgno; /* Page number for the locking page */
53957 i64 pageSize; /* Number of bytes in a page */
53958 i64 journalSizeLimit; /* Size limit for persistent journal files */
53959 char *zFilename; /* Name of the database file */
53960 char *zJournal; /* Name of the journal file */
53961 int (*xBusyHandler)(void*); /* Function to call when busy */
@@ -54562,11 +54938,11 @@
54938 ** pPager at the current location. The super-journal name must be the last
54939 ** thing written to a journal file. If the pager is in full-sync mode, the
54940 ** journal file descriptor is advanced to the next sector boundary before
54941 ** anything is written. The format is:
54942 **
54943 ** + 4 bytes: PAGER_SJ_PGNO.
54944 ** + N bytes: super-journal filename in utf-8.
54945 ** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator).
54946 ** + 4 bytes: super-journal name checksum.
54947 ** + 8 bytes: aJournalMagic[].
54948 **
@@ -54610,11 +54986,11 @@
54986 iHdrOff = pPager->journalOff;
54987
54988 /* Write the super-journal data to the end of the journal file. If
54989 ** an error occurs, return the error code to the caller.
54990 */
54991 if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_SJ_PGNO(pPager))))
54992 || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4)))
54993 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper)))
54994 || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum)))
54995 || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8,
54996 iHdrOff+4+nSuper+8)))
@@ -55120,11 +55496,11 @@
55496 ** to the database file, then the IO error code is returned. If data
55497 ** is successfully read from the (sub-)journal file but appears to be
55498 ** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
55499 ** two circumstances:
55500 **
55501 ** * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or
55502 ** * If the record is being rolled back from the main journal file
55503 ** and the checksum field does not match the record content.
55504 **
55505 ** Neither of these two scenarios are possible during a savepoint rollback.
55506 **
@@ -55180,11 +55556,11 @@
55556 /* Sanity checking on the page. This is more important that I originally
55557 ** thought. If a power failure occurs while the journal is being written,
55558 ** it could cause invalid data to be written into the journal. We need to
55559 ** detect this invalid data (with high probability) and ignore it.
55560 */
55561 if( pgno==0 || pgno==PAGER_SJ_PGNO(pPager) ){
55562 assert( !isSavepnt );
55563 return SQLITE_DONE;
55564 }
55565 if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
55566 return SQLITE_OK;
@@ -55739,10 +56115,13 @@
56115 rc = pager_truncate(pPager, mxPg);
56116 if( rc!=SQLITE_OK ){
56117 goto end_playback;
56118 }
56119 pPager->dbSize = mxPg;
56120 if( pPager->mxPgno<mxPg ){
56121 pPager->mxPgno = mxPg;
56122 }
56123 }
56124
56125 /* Copy original pages out of the journal and back into the
56126 ** database file and/or page cache.
56127 */
@@ -56635,10 +57014,11 @@
57014 if( rc==SQLITE_OK ){
57015 sqlite3PageFree(pPager->pTmpSpace);
57016 pPager->pTmpSpace = pNew;
57017 pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
57018 pPager->pageSize = pageSize;
57019 pPager->lckPgno = (Pgno)(PENDING_BYTE/pageSize) + 1;
57020 }else{
57021 sqlite3PageFree(pNew);
57022 }
57023 }
57024
@@ -56840,11 +57220,11 @@
57220 ** Once this function has been called, the transaction must either be
57221 ** rolled back or committed. It is not safe to call this function and
57222 ** then continue writing to the database.
57223 */
57224 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
57225 assert( pPager->dbSize>=nPage || CORRUPT_DB );
57226 assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
57227 pPager->dbSize = nPage;
57228
57229 /* At one point the code here called assertTruncateConstraint() to
57230 ** ensure that all pages being truncated away by this operation are,
@@ -58404,11 +58784,11 @@
58784
58785 noContent = (flags & PAGER_GET_NOCONTENT)!=0;
58786 if( pPg->pPager && !noContent ){
58787 /* In this case the pcache already contains an initialized copy of
58788 ** the page. Return without further ado. */
58789 assert( pgno!=PAGER_SJ_PGNO(pPager) );
58790 pPager->aStat[PAGER_STAT_HIT]++;
58791 return SQLITE_OK;
58792
58793 }else{
58794 /* The pager cache has created a new page. Its content needs to
@@ -58415,11 +58795,11 @@
58795 ** be initialized. But first some error checks:
58796 **
58797 ** (*) obsolete. Was: maximum page number is 2^31
58798 ** (2) Never try to fetch the locking page
58799 */
58800 if( pgno==PAGER_SJ_PGNO(pPager) ){
58801 rc = SQLITE_CORRUPT_BKPT;
58802 goto pager_acquire_err;
58803 }
58804
58805 pPg->pPager = pPager;
@@ -58814,11 +59194,11 @@
59194 i64 iOff = pPager->journalOff;
59195
59196 /* We should never write to the journal file the page that
59197 ** contains the database locks. The following assert verifies
59198 ** that we do not. */
59199 assert( pPg->pgno!=PAGER_SJ_PGNO(pPager) );
59200
59201 assert( pPager->journalHdr<=pPager->journalOff );
59202 pData2 = pPg->pData;
59203 cksum = pager_cksum(pPager, (u8*)pData2);
59204
@@ -58993,11 +59373,11 @@
59373
59374 for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
59375 Pgno pg = pg1+ii;
59376 PgHdr *pPage;
59377 if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
59378 if( pg!=PAGER_SJ_PGNO(pPager) ){
59379 rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
59380 if( rc==SQLITE_OK ){
59381 rc = pager_write(pPage);
59382 if( pPage->flags&PGHDR_NEED_SYNC ){
59383 needSync = 1;
@@ -59471,11 +59851,11 @@
59851 ** image was extended as part of the current transaction and then the
59852 ** last page in the db image moved to the free-list. In this case the
59853 ** last page is never written out to disk, leaving the database file
59854 ** undersized. Fix this now if it is the case. */
59855 if( pPager->dbSize>pPager->dbFileSize ){
59856 Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_SJ_PGNO(pPager));
59857 assert( pPager->eState==PAGER_WRITER_DBMOD );
59858 rc = pager_truncate(pPager, nNew);
59859 if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
59860 }
59861
@@ -60320,10 +60700,22 @@
60700 int eMode, /* Type of checkpoint */
60701 int *pnLog, /* OUT: Final number of frames in log */
60702 int *pnCkpt /* OUT: Final number of checkpointed frames */
60703 ){
60704 int rc = SQLITE_OK;
60705 if( pPager->pWal==0 && pPager->journalMode==PAGER_JOURNALMODE_WAL ){
60706 /* This only happens when a database file is zero bytes in size opened and
60707 ** then "PRAGMA journal_mode=WAL" is run and then sqlite3_wal_checkpoint()
60708 ** is invoked without any intervening transactions. We need to start
60709 ** a transaction to initialize pWal. The PRAGMA table_list statement is
60710 ** used for this since it starts transactions on every database file,
60711 ** including all ATTACHed databases. This seems expensive for a single
60712 ** sqlite3_wal_checkpoint() call, but it happens very rarely.
60713 ** https://sqlite.org/forum/forumpost/fd0f19d229156939
60714 */
60715 sqlite3_exec(db, "PRAGMA table_list",0,0,0);
60716 }
60717 if( pPager->pWal ){
60718 rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
60719 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
60720 pPager->pBusyHandlerArg,
60721 pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
@@ -65086,11 +65478,13 @@
65478 u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th
65479 ** non-overflow cell */
65480 u8 *apOvfl[4]; /* Pointers to the body of overflow cells */
65481 BtShared *pBt; /* Pointer to BtShared that this page is part of */
65482 u8 *aData; /* Pointer to disk image of the page data */
65483 u8 *aDataEnd; /* One byte past the end of the entire page - not just
65484 ** the usable space, the entire page. Used to prevent
65485 ** corruption-induced buffer overflow. */
65486 u8 *aCellIdx; /* The cell index area */
65487 u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */
65488 DbPage *pDbPage; /* Pager page handle */
65489 u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
65490 void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
@@ -65391,11 +65785,11 @@
65785 #define CURSOR_FAULT 4
65786
65787 /*
65788 ** The database page the PENDING_BYTE occupies. This page is never used.
65789 */
65790 #define PENDING_BYTE_PAGE(pBt) ((Pgno)((PENDING_BYTE/((pBt)->pageSize))+1))
65791
65792 /*
65793 ** These macros define the location of the pointer-map entry for a
65794 ** database page. The first argument to each is the number of usable
65795 ** bytes on each page of the database (often 1024). The second is the
@@ -66032,11 +66426,11 @@
66426 if( isIndex ){
66427 HashElem *p;
66428 int bSeen = 0;
66429 for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
66430 Index *pIdx = (Index *)sqliteHashData(p);
66431 if( pIdx->tnum==iRoot ){
66432 if( bSeen ){
66433 /* Two or more indexes share the same root page. There must
66434 ** be imposter tables. So just return true. The assert is not
66435 ** useful in that case. */
66436 return 1;
@@ -66625,11 +67019,11 @@
67019 }
67020
67021 /*
67022 ** In this version of BtreeMoveto, pKey is a packed index record
67023 ** such as is generated by the OP_MakeRecord opcode. Unpack the
67024 ** record and then call sqlite3BtreeIndexMoveto() to do the work.
67025 */
67026 static int btreeMoveto(
67027 BtCursor *pCur, /* Cursor open on the btree to be searched */
67028 const void *pKey, /* Packed key if the btree is an index */
67029 i64 nKey, /* Integer key for tables. Size of pKey for indices */
@@ -67145,10 +67539,11 @@
67539 ** data area of the btree-page. The return number includes the cell
67540 ** data header and the local payload, but not any overflow page or
67541 ** the space used by the cell pointer.
67542 **
67543 ** cellSizePtrNoPayload() => table internal nodes
67544 ** cellSizePtrTableLeaf() => table leaf nodes
67545 ** cellSizePtr() => all index nodes & table leaf nodes
67546 */
67547 static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
67548 u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
67549 u8 *pEnd; /* End mark for a varint */
@@ -67170,17 +67565,10 @@
67565 do{
67566 nSize = (nSize<<7) | (*++pIter & 0x7f);
67567 }while( *(pIter)>=0x80 && pIter<pEnd );
67568 }
67569 pIter++;
 
 
 
 
 
 
 
67570 testcase( nSize==pPage->maxLocal );
67571 testcase( nSize==(u32)pPage->maxLocal+1 );
67572 if( nSize<=pPage->maxLocal ){
67573 nSize += (u32)(pIter - pCell);
67574 if( nSize<4 ) nSize = 4;
@@ -67216,10 +67604,62 @@
67604 pEnd = pIter + 9;
67605 while( (*pIter++)&0x80 && pIter<pEnd );
67606 assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB );
67607 return (u16)(pIter - pCell);
67608 }
67609 static u16 cellSizePtrTableLeaf(MemPage *pPage, u8 *pCell){
67610 u8 *pIter = pCell; /* For looping over bytes of pCell */
67611 u8 *pEnd; /* End mark for a varint */
67612 u32 nSize; /* Size value to return */
67613
67614 #ifdef SQLITE_DEBUG
67615 /* The value returned by this function should always be the same as
67616 ** the (CellInfo.nSize) value found by doing a full parse of the
67617 ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
67618 ** this function verifies that this invariant is not violated. */
67619 CellInfo debuginfo;
67620 pPage->xParseCell(pPage, pCell, &debuginfo);
67621 #endif
67622
67623 nSize = *pIter;
67624 if( nSize>=0x80 ){
67625 pEnd = &pIter[8];
67626 nSize &= 0x7f;
67627 do{
67628 nSize = (nSize<<7) | (*++pIter & 0x7f);
67629 }while( *(pIter)>=0x80 && pIter<pEnd );
67630 }
67631 pIter++;
67632 /* pIter now points at the 64-bit integer key value, a variable length
67633 ** integer. The following block moves pIter to point at the first byte
67634 ** past the end of the key value. */
67635 if( (*pIter++)&0x80
67636 && (*pIter++)&0x80
67637 && (*pIter++)&0x80
67638 && (*pIter++)&0x80
67639 && (*pIter++)&0x80
67640 && (*pIter++)&0x80
67641 && (*pIter++)&0x80
67642 && (*pIter++)&0x80 ){ pIter++; }
67643 testcase( nSize==pPage->maxLocal );
67644 testcase( nSize==(u32)pPage->maxLocal+1 );
67645 if( nSize<=pPage->maxLocal ){
67646 nSize += (u32)(pIter - pCell);
67647 if( nSize<4 ) nSize = 4;
67648 }else{
67649 int minLocal = pPage->minLocal;
67650 nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
67651 testcase( nSize==pPage->maxLocal );
67652 testcase( nSize==(u32)pPage->maxLocal+1 );
67653 if( nSize>pPage->maxLocal ){
67654 nSize = minLocal;
67655 }
67656 nSize += 4 + (u16)(pIter - pCell);
67657 }
67658 assert( nSize==debuginfo.nSize || CORRUPT_DB );
67659 return (u16)nSize;
67660 }
67661
67662
67663 #ifdef SQLITE_DEBUG
67664 /* This variation on cellSizePtr() is used inside of assert() statements
67665 ** only. */
@@ -67229,11 +67669,11 @@
67669 #endif
67670
67671 #ifndef SQLITE_OMIT_AUTOVACUUM
67672 /*
67673 ** The cell pCell is currently part of page pSrc but will ultimately be part
67674 ** of pPage. (pSrc and pPage are often the same.) If pCell contains a
67675 ** pointer to an overflow page, insert an entry into the pointer-map for
67676 ** the overflow page that will be valid after pCell has been moved to pPage.
67677 */
67678 static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
67679 CellInfo info;
@@ -67404,21 +67844,23 @@
67844 */
67845 static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
67846 const int hdr = pPg->hdrOffset; /* Offset to page header */
67847 u8 * const aData = pPg->aData; /* Page data */
67848 int iAddr = hdr + 1; /* Address of ptr to pc */
67849 u8 *pTmp = &aData[iAddr]; /* Temporary ptr into aData[] */
67850 int pc = get2byte(pTmp); /* Address of a free slot */
67851 int x; /* Excess size of the slot */
67852 int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */
67853 int size; /* Size of the free slot */
67854
67855 assert( pc>0 );
67856 while( pc<=maxPC ){
67857 /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
67858 ** freeblock form a big-endian integer which is the size of the freeblock
67859 ** in bytes, including the 4-byte header. */
67860 pTmp = &aData[pc+2];
67861 size = get2byte(pTmp);
67862 if( (x = size - nByte)>=0 ){
67863 testcase( x==4 );
67864 testcase( x==3 );
67865 if( x<4 ){
67866 /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
@@ -67439,11 +67881,12 @@
67881 put2byte(&aData[pc+2], x);
67882 }
67883 return &aData[pc + x];
67884 }
67885 iAddr = pc;
67886 pTmp = &aData[pc];
67887 pc = get2byte(pTmp);
67888 if( pc<=iAddr+size ){
67889 if( pc ){
67890 /* The next slot in the chain is not past the end of the current slot */
67891 *pRc = SQLITE_CORRUPT_PAGE(pPg);
67892 }
@@ -67473,10 +67916,11 @@
67916 static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
67917 const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
67918 u8 * const data = pPage->aData; /* Local cache of pPage->aData */
67919 int top; /* First byte of cell content area */
67920 int rc = SQLITE_OK; /* Integer return code */
67921 u8 *pTmp; /* Temp ptr into data[] */
67922 int gap; /* First byte of gap between cell pointers and cell content */
67923
67924 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
67925 assert( pPage->pBt );
67926 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
@@ -67491,11 +67935,12 @@
67935 /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
67936 ** and the reserved space is zero (the usual value for reserved space)
67937 ** then the cell content offset of an empty page wants to be 65536.
67938 ** However, that integer is too large to be stored in a 2-byte unsigned
67939 ** integer, so a value of 0 is used in its place. */
67940 pTmp = &data[hdr+5];
67941 top = get2byte(pTmp);
67942 assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
67943 if( gap>top ){
67944 if( top==0 && pPage->pBt->usableSize==65536 ){
67945 top = 65536;
67946 }else{
@@ -67573,10 +68018,11 @@
68018 u8 nFrag = 0; /* Reduction in fragmentation */
68019 u16 iOrigSize = iSize; /* Original value of iSize */
68020 u16 x; /* Offset to cell content area */
68021 u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
68022 unsigned char *data = pPage->aData; /* Page content */
68023 u8 *pTmp; /* Temporary ptr into data[] */
68024
68025 assert( pPage->pBt!=0 );
68026 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
68027 assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
68028 assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
@@ -67600,11 +68046,11 @@
68046 iPtr = iFreeBlk;
68047 }
68048 if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
68049 return SQLITE_CORRUPT_PAGE(pPage);
68050 }
68051 assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB );
68052
68053 /* At this point:
68054 ** iFreeBlk: First freeblock after iStart, or zero if none
68055 ** iPtr: The address of a pointer to iFreeBlk
68056 **
@@ -67635,11 +68081,12 @@
68081 }
68082 }
68083 if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
68084 data[hdr+7] -= nFrag;
68085 }
68086 pTmp = &data[hdr+5];
68087 x = get2byte(pTmp);
68088 if( iStart<=x ){
68089 /* The new freeblock is at the beginning of the cell content area,
68090 ** so just extend the cell content area rather than create another
68091 ** freelist entry */
68092 if( iStart<x ) return SQLITE_CORRUPT_PAGE(pPage);
@@ -67679,11 +68126,10 @@
68126 assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
68127 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
68128 pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 );
68129 flagByte &= ~PTF_LEAF;
68130 pPage->childPtrSize = 4-4*pPage->leaf;
 
68131 pBt = pPage->pBt;
68132 if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
68133 /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
68134 ** interior table b-tree page. */
68135 assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
@@ -67691,10 +68137,11 @@
68137 ** leaf table b-tree page. */
68138 assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
68139 pPage->intKey = 1;
68140 if( pPage->leaf ){
68141 pPage->intKeyLeaf = 1;
68142 pPage->xCellSize = cellSizePtrTableLeaf;
68143 pPage->xParseCell = btreeParseCellPtr;
68144 }else{
68145 pPage->intKeyLeaf = 0;
68146 pPage->xCellSize = cellSizePtrNoPayload;
68147 pPage->xParseCell = btreeParseCellPtrNoPayload;
@@ -67708,16 +68155,21 @@
68155 /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
68156 ** leaf index b-tree page. */
68157 assert( (PTF_ZERODATA|PTF_LEAF)==10 );
68158 pPage->intKey = 0;
68159 pPage->intKeyLeaf = 0;
68160 pPage->xCellSize = cellSizePtr;
68161 pPage->xParseCell = btreeParseCellPtrIndex;
68162 pPage->maxLocal = pBt->maxLocal;
68163 pPage->minLocal = pBt->minLocal;
68164 }else{
68165 /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
68166 ** an error. */
68167 pPage->intKey = 0;
68168 pPage->intKeyLeaf = 0;
68169 pPage->xCellSize = cellSizePtr;
68170 pPage->xParseCell = btreeParseCellPtrIndex;
68171 return SQLITE_CORRUPT_PAGE(pPage);
68172 }
68173 pPage->max1bytePayload = pBt->max1bytePayload;
68174 return SQLITE_OK;
68175 }
@@ -67871,11 +68323,11 @@
68323 assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
68324 pPage->maskPage = (u16)(pBt->pageSize - 1);
68325 pPage->nOverflow = 0;
68326 pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize;
68327 pPage->aCellIdx = data + pPage->childPtrSize + 8;
68328 pPage->aDataEnd = pPage->aData + pBt->pageSize;
68329 pPage->aDataOfst = pPage->aData + pPage->childPtrSize;
68330 /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
68331 ** number of cells on the page. */
68332 pPage->nCell = get2byte(&data[3]);
68333 if( pPage->nCell>MX_CELL(pBt) ){
@@ -67906,11 +68358,11 @@
68358 unsigned char *data = pPage->aData;
68359 BtShared *pBt = pPage->pBt;
68360 u8 hdr = pPage->hdrOffset;
68361 u16 first;
68362
68363 assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB );
68364 assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
68365 assert( sqlite3PagerGetData(pPage->pDbPage) == data );
68366 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
68367 assert( sqlite3_mutex_held(pBt->mutex) );
68368 if( pBt->btsFlags & BTS_FAST_SECURE ){
@@ -67922,11 +68374,11 @@
68374 data[hdr+7] = 0;
68375 put2byte(&data[hdr+5], pBt->usableSize);
68376 pPage->nFree = (u16)(pBt->usableSize - first);
68377 decodeFlags(pPage, flags);
68378 pPage->cellOffset = first;
68379 pPage->aDataEnd = &data[pBt->pageSize];
68380 pPage->aCellIdx = &data[first];
68381 pPage->aDataOfst = &data[pPage->childPtrSize];
68382 pPage->nOverflow = 0;
68383 assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
68384 pPage->maskPage = (u16)(pBt->pageSize - 1);
@@ -68048,11 +68500,11 @@
68500 rc = btreeInitPage(*ppPage);
68501 if( rc!=SQLITE_OK ){
68502 goto getAndInitPage_error2;
68503 }
68504 }
68505 assert( (*ppPage)->pgno==pgno || CORRUPT_DB );
68506 assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
68507
68508 /* If obtaining a child page for a cursor, we must verify that the page is
68509 ** compatible with the root page. */
68510 if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
@@ -68067,11 +68519,13 @@
68519 if( pCur ){
68520 pCur->iPage--;
68521 pCur->pPage = pCur->apPage[pCur->iPage];
68522 }
68523 testcase( pgno==0 );
68524 assert( pgno!=0 || rc==SQLITE_CORRUPT
68525 || rc==SQLITE_IOERR_NOMEM
68526 || rc==SQLITE_NOMEM );
68527 return rc;
68528 }
68529
68530 /*
68531 ** Release a MemPage. This should be called once for each prior
@@ -71135,11 +71589,11 @@
71589 }
71590 pCur->iPage = 0;
71591 pCur->curIntKey = pCur->pPage->intKey;
71592 }
71593 pRoot = pCur->pPage;
71594 assert( pRoot->pgno==pCur->pgnoRoot || CORRUPT_DB );
71595
71596 /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
71597 ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
71598 ** NULL, the caller expects a table b-tree. If this is not the case,
71599 ** return an SQLITE_CORRUPT error.
@@ -71455,10 +71909,73 @@
71909 moveto_table_finish:
71910 pCur->info.nSize = 0;
71911 assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
71912 return rc;
71913 }
71914
71915 /*
71916 ** Compare the "idx"-th cell on the page the cursor pCur is currently
71917 ** pointing to to pIdxKey using xRecordCompare. Return negative or
71918 ** zero if the cell is less than or equal pIdxKey. Return positive
71919 ** if unknown.
71920 **
71921 ** Return value negative: Cell at pCur[idx] less than pIdxKey
71922 **
71923 ** Return value is zero: Cell at pCur[idx] equals pIdxKey
71924 **
71925 ** Return value positive: Nothing is known about the relationship
71926 ** of the cell at pCur[idx] and pIdxKey.
71927 **
71928 ** This routine is part of an optimization. It is always safe to return
71929 ** a positive value as that will cause the optimization to be skipped.
71930 */
71931 static int indexCellCompare(
71932 BtCursor *pCur,
71933 int idx,
71934 UnpackedRecord *pIdxKey,
71935 RecordCompare xRecordCompare
71936 ){
71937 MemPage *pPage = pCur->pPage;
71938 int c;
71939 int nCell; /* Size of the pCell cell in bytes */
71940 u8 *pCell = findCellPastPtr(pPage, idx);
71941
71942 nCell = pCell[0];
71943 if( nCell<=pPage->max1bytePayload ){
71944 /* This branch runs if the record-size field of the cell is a
71945 ** single byte varint and the record fits entirely on the main
71946 ** b-tree page. */
71947 testcase( pCell+nCell+1==pPage->aDataEnd );
71948 c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
71949 }else if( !(pCell[1] & 0x80)
71950 && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
71951 ){
71952 /* The record-size field is a 2 byte varint and the record
71953 ** fits entirely on the main b-tree page. */
71954 testcase( pCell+nCell+2==pPage->aDataEnd );
71955 c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
71956 }else{
71957 /* If the record extends into overflow pages, do not attempt
71958 ** the optimization. */
71959 c = 99;
71960 }
71961 return c;
71962 }
71963
71964 /*
71965 ** Return true (non-zero) if pCur is current pointing to the last
71966 ** page of a table.
71967 */
71968 static int cursorOnLastPage(BtCursor *pCur){
71969 int i;
71970 assert( pCur->eState==CURSOR_VALID );
71971 for(i=0; i<pCur->iPage; i++){
71972 MemPage *pPage = pCur->apPage[i];
71973 if( pCur->aiIdx[i]<pPage->nCell ) return 0;
71974 }
71975 return 1;
71976 }
71977
71978 /* Move the cursor so that it points to an entry in an index table
71979 ** near the key pIdxKey. Return a success code.
71980 **
71981 ** If an exact match is not found, then the cursor is always
@@ -71506,25 +72023,61 @@
72023 assert( pIdxKey->default_rc==1
72024 || pIdxKey->default_rc==0
72025 || pIdxKey->default_rc==-1
72026 );
72027
72028
72029 /* Check to see if we can skip a lot of work. Two cases:
72030 **
72031 ** (1) If the cursor is already pointing to the very last cell
72032 ** in the table and the pIdxKey search key is greater than or
72033 ** equal to that last cell, then no movement is required.
72034 **
72035 ** (2) If the cursor is on the last page of the table and the first
72036 ** cell on that last page is less than or equal to the pIdxKey
72037 ** search key, then we can start the search on the current page
72038 ** without needing to go back to root.
72039 */
72040 if( pCur->eState==CURSOR_VALID
72041 && pCur->pPage->leaf
72042 && cursorOnLastPage(pCur)
72043 ){
72044 int c;
72045 if( pCur->ix==pCur->pPage->nCell-1
72046 && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0
72047 && pIdxKey->errCode==SQLITE_OK
72048 ){
72049 *pRes = c;
72050 return SQLITE_OK; /* Cursor already pointing at the correct spot */
72051 }
72052 if( pCur->iPage>0
72053 && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
72054 && pIdxKey->errCode==SQLITE_OK
72055 ){
72056 pCur->curFlags &= ~BTCF_ValidOvfl;
72057 goto bypass_moveto_root; /* Start search on the current page */
72058 }
72059 pIdxKey->errCode = SQLITE_OK;
72060 }
72061
72062 rc = moveToRoot(pCur);
72063 if( rc ){
72064 if( rc==SQLITE_EMPTY ){
72065 assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
72066 *pRes = -1;
72067 return SQLITE_OK;
72068 }
72069 return rc;
72070 }
72071
72072 bypass_moveto_root:
72073 assert( pCur->pPage );
72074 assert( pCur->pPage->isInit );
72075 assert( pCur->eState==CURSOR_VALID );
72076 assert( pCur->pPage->nCell > 0 );
72077 assert( pCur->curIntKey==0 );
72078 assert( pIdxKey!=0 );
72079 for(;;){
72080 int lwr, upr, idx, c;
72081 Pgno chldPg;
72082 MemPage *pPage = pCur->pPage;
72083 u8 *pCell; /* Pointer to current cell in pPage */
@@ -71534,11 +72087,11 @@
72087 ** not run. If this is not the root-page, then the moveToChild() routine
72088 ** would have already detected db corruption. Similarly, pPage must
72089 ** be the right kind (index or table) of b-tree page. Otherwise
72090 ** a moveToChild() or moveToRoot() call would have detected corruption. */
72091 assert( pPage->nCell>0 );
72092 assert( pPage->intKey==0 );
72093 lwr = 0;
72094 upr = pPage->nCell-1;
72095 idx = upr>>1; /* idx = (lwr+upr)/2; */
72096 for(;;){
72097 int nCell; /* Size of the pCell cell in bytes */
@@ -72229,11 +72782,11 @@
72782
72783 assert( sqlite3_mutex_held(pBt->mutex) );
72784 assert( CORRUPT_DB || iPage>1 );
72785 assert( !pMemPage || pMemPage->pgno==iPage );
72786
72787 if( iPage<2 || iPage>pBt->nPage ){
72788 return SQLITE_CORRUPT_BKPT;
72789 }
72790 if( pMemPage ){
72791 pPage = pMemPage;
72792 sqlite3PagerRef(pPage->pDbPage);
@@ -72664,10 +73217,16 @@
73217 data = pPage->aData;
73218 ptr = &pPage->aCellIdx[2*idx];
73219 assert( pPage->pBt->usableSize > (u32)(ptr-data) );
73220 pc = get2byte(ptr);
73221 hdr = pPage->hdrOffset;
73222 #if 0 /* Not required. Omit for efficiency */
73223 if( pc<hdr+pPage->nCell*2 ){
73224 *pRC = SQLITE_CORRUPT_BKPT;
73225 return;
73226 }
73227 #endif
73228 testcase( pc==(u32)get2byte(&data[hdr+5]) );
73229 testcase( pc+sz==pPage->pBt->usableSize );
73230 if( pc+sz > pPage->pBt->usableSize ){
73231 *pRC = SQLITE_CORRUPT_BKPT;
73232 return;
@@ -74395,11 +74954,10 @@
74954 ** balance_deeper()
74955 ** balance_nonroot()
74956 */
74957 static int balance(BtCursor *pCur){
74958 int rc = SQLITE_OK;
 
74959 u8 aBalanceQuickSpace[13];
74960 u8 *pFree = 0;
74961
74962 VVA_ONLY( int balance_quick_called = 0 );
74963 VVA_ONLY( int balance_deeper_called = 0 );
@@ -74407,11 +74965,15 @@
74965 do {
74966 int iPage;
74967 MemPage *pPage = pCur->pPage;
74968
74969 if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
74970 if( pPage->nOverflow==0 && pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){
74971 /* No rebalance required as long as:
74972 ** (1) There are no overflow cells
74973 ** (2) The amount of free space on the page is less than 2/3rds of
74974 ** the total usable space on the page. */
74975 break;
74976 }else if( (iPage = pCur->iPage)==0 ){
74977 if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){
74978 /* The root page of the b-tree is overfull. In this case call the
74979 ** balance_deeper() function to create a new child for the root-page
@@ -74627,11 +75189,11 @@
75189 ** For an index btree (used for indexes and WITHOUT ROWID tables), the
75190 ** key is an arbitrary byte sequence stored in pX.pKey,nKey. The
75191 ** pX.pData,nData,nZero fields must be zero.
75192 **
75193 ** If the seekResult parameter is non-zero, then a successful call to
75194 ** sqlite3BtreeIndexMoveto() to seek cursor pCur to (pKey,nKey) has already
75195 ** been performed. In other words, if seekResult!=0 then the cursor
75196 ** is currently pointing to a cell that will be adjacent to the cell
75197 ** to be inserted. If seekResult<0 then pCur points to a cell that is
75198 ** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell
75199 ** that is larger than (pKey,nKey).
@@ -74645,11 +75207,11 @@
75207 */
75208 SQLITE_PRIVATE int sqlite3BtreeInsert(
75209 BtCursor *pCur, /* Insert data into the table of this cursor */
75210 const BtreePayload *pX, /* Content of the row to be inserted */
75211 int flags, /* True if this is likely an append */
75212 int seekResult /* Result of prior IndexMoveto() call */
75213 ){
75214 int rc;
75215 int loc = seekResult; /* -1: before desired location +1: after */
75216 int szNew = 0;
75217 int idx;
@@ -74660,28 +75222,10 @@
75222 unsigned char *newCell = 0;
75223
75224 assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
75225 assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 );
75226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75227 /* Save the positions of any other cursors open on this table.
75228 **
75229 ** In some cases, the call to btreeMoveto() below is a no-op. For
75230 ** example, when inserting data into a table with auto-generated integer
75231 ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
@@ -74702,10 +75246,33 @@
75246 ** set the flag, load the schema, and then unset the flag. */
75247 return SQLITE_CORRUPT_BKPT;
75248 }
75249 }
75250
75251 /* Ensure that the cursor is not in the CURSOR_FAULT state and that it
75252 ** points to a valid cell.
75253 */
75254 if( pCur->eState>=CURSOR_REQUIRESEEK ){
75255 testcase( pCur->eState==CURSOR_REQUIRESEEK );
75256 testcase( pCur->eState==CURSOR_FAULT );
75257 rc = moveToRoot(pCur);
75258 if( rc && rc!=SQLITE_EMPTY ) return rc;
75259 }
75260
75261 assert( cursorOwnsBtShared(pCur) );
75262 assert( (pCur->curFlags & BTCF_WriteFlag)!=0
75263 && pBt->inTransaction==TRANS_WRITE
75264 && (pBt->btsFlags & BTS_READ_ONLY)==0 );
75265 assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
75266
75267 /* Assert that the caller has been consistent. If this cursor was opened
75268 ** expecting an index b-tree, then the caller should be inserting blob
75269 ** keys with no associated data. If the cursor was opened expecting an
75270 ** intkey table, the caller should be inserting integer keys with a
75271 ** blob of associated data. */
75272 assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) );
75273
75274 if( pCur->pKeyInfo==0 ){
75275 assert( pX->pKey==0 );
75276 /* If this is an insert into a table b-tree, invalidate any incrblob
75277 ** cursors open on the row being replaced */
75278 if( p->hasIncrblobCur ){
@@ -74790,18 +75357,18 @@
75357 return btreeOverwriteCell(pCur, &x2);
75358 }
75359 }
75360 }
75361 assert( pCur->eState==CURSOR_VALID
75362 || (pCur->eState==CURSOR_INVALID && loc) );
 
75363
75364 pPage = pCur->pPage;
75365 assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
75366 assert( pPage->leaf || !pPage->intKey );
75367 if( pPage->nFree<0 ){
75368 if( NEVER(pCur->eState>CURSOR_INVALID) ){
75369 /* ^^^^^--- due to the moveToRoot() call above */
75370 rc = SQLITE_CORRUPT_BKPT;
75371 }else{
75372 rc = btreeComputeFreeSpace(pPage);
75373 }
75374 if( rc ) return rc;
@@ -75078,16 +75645,20 @@
75645 assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
75646 assert( pCur->curFlags & BTCF_WriteFlag );
75647 assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
75648 assert( !hasReadConflicts(p, pCur->pgnoRoot) );
75649 assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
75650 if( pCur->eState!=CURSOR_VALID ){
75651 if( pCur->eState>=CURSOR_REQUIRESEEK ){
75652 rc = btreeRestoreCursorPosition(pCur);
75653 assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
75654 if( rc || pCur->eState!=CURSOR_VALID ) return rc;
75655 }else{
75656 return SQLITE_CORRUPT_BKPT;
75657 }
75658 }
75659 assert( pCur->eState==CURSOR_VALID );
75660
75661 iCellDepth = pCur->iPage;
75662 iCellIdx = pCur->ix;
75663 pPage = pCur->pPage;
75664 if( pPage->nCell<=iCellIdx ){
@@ -75115,11 +75686,12 @@
75686 ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT.
75687 */
75688 bPreserve = (flags & BTREE_SAVEPOSITION)!=0;
75689 if( bPreserve ){
75690 if( !pPage->leaf
75691 || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2) >
75692 (int)(pBt->usableSize*2/3)
75693 || pPage->nCell==1 /* See dbfuzz001.test for a test case */
75694 ){
75695 /* A b-tree rebalance will be required after deleting this entry.
75696 ** Save the cursor key. */
75697 rc = saveCursorKey(pCur);
@@ -75211,11 +75783,19 @@
75783 ** on the leaf node first. If the balance proceeds far enough up the
75784 ** tree that we can be sure that any problem in the internal node has
75785 ** been corrected, so be it. Otherwise, after balancing the leaf node,
75786 ** walk the cursor up the tree to the internal node and balance it as
75787 ** well. */
75788 assert( pCur->pPage->nOverflow==0 );
75789 assert( pCur->pPage->nFree>=0 );
75790 if( pCur->pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){
75791 /* Optimization: If the free space is less than 2/3rds of the page,
75792 ** then balance() will always be a no-op. No need to invoke it. */
75793 rc = SQLITE_OK;
75794 }else{
75795 rc = balance(pCur);
75796 }
75797 if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
75798 releasePageNotNull(pCur->pPage);
75799 pCur->iPage--;
75800 while( pCur->iPage>iCellDepth ){
75801 releasePage(pCur->apPage[pCur->iPage--]);
@@ -75434,11 +76014,11 @@
76014 return SQLITE_CORRUPT_BKPT;
76015 }
76016 rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
76017 if( rc ) return rc;
76018 if( (pBt->openFlags & BTREE_SINGLE)==0
76019 && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1))
76020 ){
76021 rc = SQLITE_CORRUPT_BKPT;
76022 goto cleardatabasepage_out;
76023 }
76024 hdr = pPage->hdrOffset;
@@ -76814,11 +77394,11 @@
77394 int i = sqlite3FindDbName(pDb, zDb);
77395
77396 if( i==1 ){
77397 Parse sParse;
77398 int rc = 0;
77399 sqlite3ParseObjectInit(&sParse,pDb);
77400 if( sqlite3OpenTempDatabase(&sParse) ){
77401 sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
77402 rc = SQLITE_ERROR;
77403 }
77404 sqlite3DbFree(pErrorDb, sParse.zErrMsg);
@@ -77706,11 +78286,15 @@
78286 #endif
78287 assert( pMem!=0 );
78288 assert( !sqlite3VdbeMemIsRowSet(pMem) );
78289 assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
78290 || desiredEnc==SQLITE_UTF16BE );
78291 if( !(pMem->flags&MEM_Str) ){
78292 pMem->enc = desiredEnc;
78293 return SQLITE_OK;
78294 }
78295 if( pMem->enc==desiredEnc ){
78296 return SQLITE_OK;
78297 }
78298 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
78299 #ifdef SQLITE_OMIT_UTF16
78300 return SQLITE_ERROR;
@@ -77965,10 +78549,11 @@
78549 t.flags = MEM_Null;
78550 t.db = pMem->db;
78551 ctx.pOut = &t;
78552 ctx.pMem = pMem;
78553 ctx.pFunc = pFunc;
78554 ctx.enc = ENC(t.db);
78555 pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
78556 assert( (pMem->flags & MEM_Dyn)==0 );
78557 if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
78558 memcpy(pMem, &t, sizeof(t));
78559 return ctx.isError;
@@ -77992,10 +78577,11 @@
78577 memset(&ctx, 0, sizeof(ctx));
78578 sqlite3VdbeMemSetNull(pOut);
78579 ctx.pOut = pOut;
78580 ctx.pMem = pAccum;
78581 ctx.pFunc = pFunc;
78582 ctx.enc = ENC(pAccum->db);
78583 pFunc->xValue(&ctx);
78584 return ctx.isError;
78585 }
78586 #endif /* SQLITE_OMIT_WINDOWFUNC */
78587
@@ -78056,10 +78642,18 @@
78642 assert( sqlite3VdbeCheckMemInvariants(p) );
78643 if( VdbeMemDynamic(p) || p->szMalloc ){
78644 vdbeMemClear(p);
78645 }
78646 }
78647
78648 /* Like sqlite3VdbeMemRelease() but faster for cases where we
78649 ** know in advance that the Mem is not MEM_Dyn or MEM_Agg.
78650 */
78651 SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){
78652 assert( !VdbeMemDynamic(p) );
78653 if( p->szMalloc ) vdbeMemClear(p);
78654 }
78655
78656 /*
78657 ** Convert a 64-bit IEEE double into a 64-bit signed integer.
78658 ** If the double is out of range of a 64-bit signed integer then
78659 ** return the closest available 64-bit signed integer.
@@ -78418,10 +79012,11 @@
79012 void *pPtr,
79013 const char *zPType,
79014 void (*xDestructor)(void*)
79015 ){
79016 assert( pMem->flags==MEM_Null );
79017 vdbeMemClear(pMem);
79018 pMem->u.zPType = zPType ? zPType : "";
79019 pMem->z = pPtr;
79020 pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
79021 pMem->eSubtype = 'p';
79022 pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
@@ -78600,10 +79195,17 @@
79195 ** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH
79196 ** size limit) then no memory allocation occurs. If the string can be
79197 ** stored without allocating memory, then it is. If a memory allocation
79198 ** is required to store the string, then value of pMem is unchanged. In
79199 ** either case, SQLITE_TOOBIG is returned.
79200 **
79201 ** The "enc" parameter is the text encoding for the string, or zero
79202 ** to store a blob.
79203 **
79204 ** If n is negative, then the string consists of all bytes up to but
79205 ** excluding the first zero character. The n parameter must be
79206 ** non-negative for blobs.
79207 */
79208 SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
79209 Mem *pMem, /* Memory cell to set to string value */
79210 const char *z, /* String pointer */
79211 i64 n, /* Bytes in string, or negative */
@@ -78610,15 +79212,16 @@
79212 u8 enc, /* Encoding of z. 0 for BLOBs */
79213 void (*xDel)(void*) /* Destructor function */
79214 ){
79215 i64 nByte = n; /* New value for pMem->n */
79216 int iLimit; /* Maximum allowed string or blob size */
79217 u16 flags; /* New value for pMem->flags */
79218
79219 assert( pMem!=0 );
79220 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
79221 assert( !sqlite3VdbeMemIsRowSet(pMem) );
79222 assert( enc!=0 || n>=0 );
79223
79224 /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
79225 if( !z ){
79226 sqlite3VdbeMemSetNull(pMem);
79227 return SQLITE_OK;
@@ -78627,19 +79230,34 @@
79230 if( pMem->db ){
79231 iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH];
79232 }else{
79233 iLimit = SQLITE_MAX_LENGTH;
79234 }
 
79235 if( nByte<0 ){
79236 assert( enc!=0 );
79237 if( enc==SQLITE_UTF8 ){
79238 nByte = strlen(z);
79239 }else{
79240 for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
79241 }
79242 flags= MEM_Str|MEM_Term;
79243 }else if( enc==0 ){
79244 flags = MEM_Blob;
79245 enc = SQLITE_UTF8;
79246 }else{
79247 flags = MEM_Str;
79248 }
79249 if( nByte>iLimit ){
79250 if( xDel && xDel!=SQLITE_TRANSIENT ){
79251 if( xDel==SQLITE_DYNAMIC ){
79252 sqlite3DbFree(pMem->db, (void*)z);
79253 }else{
79254 xDel((void*)z);
79255 }
79256 }
79257 sqlite3VdbeMemSetNull(pMem);
79258 return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
79259 }
79260
79261 /* The following block sets the new values of Mem.z and Mem.xDel. It
79262 ** also sets a flag in local variable "flags" to indicate the memory
79263 ** management (one of MEM_Dyn or MEM_Static).
@@ -78647,13 +79265,10 @@
79265 if( xDel==SQLITE_TRANSIENT ){
79266 i64 nAlloc = nByte;
79267 if( flags&MEM_Term ){
79268 nAlloc += (enc==SQLITE_UTF8?1:2);
79269 }
 
 
 
79270 testcase( nAlloc==0 );
79271 testcase( nAlloc==31 );
79272 testcase( nAlloc==32 );
79273 if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
79274 return SQLITE_NOMEM_BKPT;
@@ -78671,30 +79286,18 @@
79286 }
79287 }
79288
79289 pMem->n = (int)(nByte & 0x7fffffff);
79290 pMem->flags = flags;
79291 pMem->enc = enc;
 
 
 
 
 
 
 
 
 
79292
79293 #ifndef SQLITE_OMIT_UTF16
79294 if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
79295 return SQLITE_NOMEM_BKPT;
79296 }
79297 #endif
79298
 
 
 
79299
79300 return SQLITE_OK;
79301 }
79302
79303 /*
@@ -78972,10 +79575,11 @@
79575
79576 assert( pCtx->pParse->rc==SQLITE_OK );
79577 memset(&ctx, 0, sizeof(ctx));
79578 ctx.pOut = pVal;
79579 ctx.pFunc = pFunc;
79580 ctx.enc = ENC(db);
79581 pFunc->xSFunc(&ctx, nVal, apVal);
79582 if( ctx.isError ){
79583 rc = ctx.isError;
79584 sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
79585 }else{
@@ -79032,15 +79636,11 @@
79636 const char *zNeg = "";
79637 int rc = SQLITE_OK;
79638
79639 assert( pExpr!=0 );
79640 while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
 
79641 if( op==TK_REGISTER ) op = pExpr->op2;
 
 
 
79642
79643 /* Compressed expressions only appear when parsing the DEFAULT clause
79644 ** on a table column definition, and hence only when pCtx==0. This
79645 ** check ensures that an EP_TokenOnly expression is never passed down
79646 ** into valueFromFunction(). */
@@ -79151,11 +79751,11 @@
79751 *ppVal = pVal;
79752 return rc;
79753
79754 no_mem:
79755 #ifdef SQLITE_ENABLE_STAT4
79756 if( pCtx==0 || NEVER(pCtx->pParse->nErr==0) )
79757 #endif
79758 sqlite3OomFault(db);
79759 sqlite3DbFree(db, zVal);
79760 assert( *ppVal==0 );
79761 #ifdef SQLITE_ENABLE_STAT4
@@ -79486,11 +80086,11 @@
80086 db->pVdbe->pPrev = p;
80087 }
80088 p->pNext = db->pVdbe;
80089 p->pPrev = 0;
80090 db->pVdbe = p;
80091 assert( p->eVdbeState==VDBE_INIT_STATE );
80092 p->pParse = pParse;
80093 pParse->pVdbe = p;
80094 assert( pParse->aLabel==0 );
80095 assert( pParse->nLabel==0 );
80096 assert( p->nOpAlloc==0 );
@@ -79631,11 +80231,11 @@
80231 if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
80232 sqlite3OomFault(p->db);
80233 return SQLITE_NOMEM;
80234 }
80235
80236 assert( nOp<=(int)(1024/sizeof(Op)) );
80237 assert( nNew>=(v->nOpAlloc+nOp) );
80238 pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
80239 if( pNew ){
80240 p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
80241 v->nOpAlloc = p->szOpAlloc/sizeof(Op);
@@ -79687,11 +80287,11 @@
80287 SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
80288 int i;
80289 VdbeOp *pOp;
80290
80291 i = p->nOp;
80292 assert( p->eVdbeState==VDBE_INIT_STATE );
80293 assert( op>=0 && op<0xff );
80294 if( p->nOpAlloc<=i ){
80295 return growOp3(p, op, p1, p2, p3);
80296 }
80297 assert( p->aOp!=0 );
@@ -80019,11 +80619,11 @@
80619 }
80620 }
80621 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
80622 Parse *p = v->pParse;
80623 int j = ADDR(x);
80624 assert( v->eVdbeState==VDBE_INIT_STATE );
80625 assert( j<-p->nLabel );
80626 assert( j>=0 );
80627 #ifdef SQLITE_DEBUG
80628 if( p->db->flags & SQLITE_VdbeAddopTrace ){
80629 printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
@@ -80150,10 +80750,12 @@
80750 int hasCreateTable = 0;
80751 int hasCreateIndex = 0;
80752 int hasInitCoroutine = 0;
80753 Op *pOp;
80754 VdbeOpIter sIter;
80755
80756 if( v==0 ) return 0;
80757 memset(&sIter, 0, sizeof(sIter));
80758 sIter.v = v;
80759
80760 while( (pOp = opIterNext(&sIter))!=0 ){
80761 int opcode = pOp->opcode;
@@ -80233,11 +80835,11 @@
80835 ** and store that value in *pMaxFuncArgs.
80836 **
80837 ** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
80838 ** indicate what the prepared statement actually does.
80839 **
80840 ** (4) (discontinued)
80841 **
80842 ** (5) Reclaim the memory allocated for storing labels.
80843 **
80844 ** This routine will only function correctly if the mkopcodeh.tcl generator
80845 ** script numbers the opcodes correctly. Changes to this routine must be
@@ -80279,29 +80881,10 @@
80881 case OP_JournalMode: {
80882 p->readOnly = 0;
80883 p->bIsReader = 1;
80884 break;
80885 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80886 #ifndef SQLITE_OMIT_VIRTUALTABLE
80887 case OP_VUpdate: {
80888 if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
80889 break;
80890 }
@@ -80333,22 +80916,24 @@
80916 assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0);
80917 }
80918 if( pOp==p->aOp ) break;
80919 pOp--;
80920 }
80921 if( aLabel ){
80922 sqlite3DbFreeNN(p->db, pParse->aLabel);
80923 pParse->aLabel = 0;
80924 }
80925 pParse->nLabel = 0;
80926 *pMaxFuncArgs = nMaxArgs;
80927 assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
80928 }
80929
80930 /*
80931 ** Return the address of the next instruction to be inserted.
80932 */
80933 SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){
80934 assert( p->eVdbeState==VDBE_INIT_STATE );
80935 return p->nOp;
80936 }
80937
80938 /*
80939 ** Verify that at least N opcode slots are available in p without
@@ -80429,11 +81014,11 @@
81014 int iLineno /* Source-file line number of first opcode */
81015 ){
81016 int i;
81017 VdbeOp *pOut, *pFirst;
81018 assert( nOp>0 );
81019 assert( p->eVdbeState==VDBE_INIT_STATE );
81020 if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
81021 return 0;
81022 }
81023 pFirst = pOut = &p->aOp[p->nOp];
81024 for(i=0; i<nOp; i++, aOp++, pOut++){
@@ -80581,11 +81166,10 @@
81166 break;
81167 }
81168 case P4_REAL:
81169 case P4_INT64:
81170 case P4_DYNAMIC:
 
81171 case P4_INTARRAY: {
81172 sqlite3DbFree(db, p4);
81173 break;
81174 }
81175 case P4_KEYINFO: {
@@ -80621,17 +81205,20 @@
81205 ** Free the space allocated for aOp and any p4 values allocated for the
81206 ** opcodes contained within. If aOp is not NULL it is assumed to contain
81207 ** nOp entries.
81208 */
81209 static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
81210 assert( nOp>=0 );
81211 if( aOp ){
81212 Op *pOp = &aOp[nOp-1];
81213 while(1){ /* Exit via break */
81214 if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p);
81215 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
81216 sqlite3DbFree(db, pOp->zComment);
81217 #endif
81218 if( pOp==aOp ) break;
81219 pOp--;
81220 }
81221 sqlite3DbFreeNN(db, aOp);
81222 }
81223 }
81224
@@ -80753,11 +81340,11 @@
81340 SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
81341 Op *pOp;
81342 sqlite3 *db;
81343 assert( p!=0 );
81344 db = p->db;
81345 assert( p->eVdbeState==VDBE_INIT_STATE );
81346 assert( p->aOp!=0 || db->mallocFailed );
81347 if( db->mallocFailed ){
81348 if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
81349 return;
81350 }
@@ -80881,11 +81468,11 @@
81468 */
81469 SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
81470 /* C89 specifies that the constant "dummy" will be initialized to all
81471 ** zeros, which is correct. MSVC generates a warning, nevertheless. */
81472 static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */
81473 assert( p->eVdbeState==VDBE_INIT_STATE );
81474 if( addr<0 ){
81475 addr = p->nOp - 1;
81476 }
81477 assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
81478 if( p->db->mallocFailed ){
@@ -81178,14 +81765,10 @@
81765 }
81766 case P4_SUBPROGRAM: {
81767 zP4 = "program";
81768 break;
81769 }
 
 
 
 
81770 case P4_TABLE: {
81771 zP4 = pOp->p4.pTab->zName;
81772 break;
81773 }
81774 default: {
@@ -81313,25 +81896,44 @@
81896 }
81897 #endif
81898
81899 /*
81900 ** Initialize an array of N Mem element.
81901 **
81902 ** This is a high-runner, so only those fields that really do need to
81903 ** be initialized are set. The Mem structure is organized so that
81904 ** the fields that get initialized are nearby and hopefully on the same
81905 ** cache line.
81906 **
81907 ** Mem.flags = flags
81908 ** Mem.db = db
81909 ** Mem.szMalloc = 0
81910 **
81911 ** All other fields of Mem can safely remain uninitialized for now. They
81912 ** will be initialized before use.
81913 */
81914 static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
81915 if( N>0 ){
81916 do{
81917 p->flags = flags;
81918 p->db = db;
81919 p->szMalloc = 0;
81920 #ifdef SQLITE_DEBUG
81921 p->pScopyFrom = 0;
81922 #endif
81923 p++;
81924 }while( (--N)>0 );
81925 }
81926 }
81927
81928 /*
81929 ** Release auxiliary memory held in an array of N Mem elements.
81930 **
81931 ** After this routine returns, all Mem elements in the array will still
81932 ** be valid. Those Mem elements that were not holding auxiliary resources
81933 ** will be unchanged. Mem elements which had something freed will be
81934 ** set to MEM_Undefined.
81935 */
81936 static void releaseMemArray(Mem *p, int N){
81937 if( p && N ){
81938 Mem *pEnd = &p[N];
81939 sqlite3 *db = p->db;
@@ -81360,16 +81962,21 @@
81962 testcase( p->flags & MEM_Agg );
81963 testcase( p->flags & MEM_Dyn );
81964 if( p->flags&(MEM_Agg|MEM_Dyn) ){
81965 testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel );
81966 sqlite3VdbeMemRelease(p);
81967 p->flags = MEM_Undefined;
81968 }else if( p->szMalloc ){
81969 sqlite3DbFreeNN(db, p->zMalloc);
81970 p->szMalloc = 0;
81971 p->flags = MEM_Undefined;
81972 }
81973 #ifdef SQLITE_DEBUG
81974 else{
81975 p->flags = MEM_Undefined;
81976 }
81977 #endif
81978 }while( (++p)<pEnd );
81979 }
81980 }
81981
81982 #ifdef SQLITE_DEBUG
@@ -81563,11 +82170,11 @@
82170 int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
82171 Op *aOp; /* Array of opcodes */
82172 Op *pOp; /* Current opcode */
82173
82174 assert( p->explain );
82175 assert( p->eVdbeState==VDBE_RUN_STATE );
82176 assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
82177
82178 /* Even though this opcode does not use dynamic strings for
82179 ** the result, result columns may become dynamic if the user calls
82180 ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
@@ -81743,18 +82350,19 @@
82350 SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
82351 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
82352 int i;
82353 #endif
82354 assert( p!=0 );
82355 assert( p->eVdbeState==VDBE_INIT_STATE
82356 || p->eVdbeState==VDBE_READY_STATE
82357 || p->eVdbeState==VDBE_HALT_STATE );
82358
82359 /* There should be at least one opcode.
82360 */
82361 assert( p->nOp>0 );
82362
82363 p->eVdbeState = VDBE_READY_STATE;
 
82364
82365 #ifdef SQLITE_DEBUG
82366 for(i=0; i<p->nMem; i++){
82367 assert( p->aMem[i].db==p->db );
82368 }
@@ -81806,11 +82414,11 @@
82414 struct ReusableSpace x; /* Reusable bulk memory */
82415
82416 assert( p!=0 );
82417 assert( p->nOp>0 );
82418 assert( pParse!=0 );
82419 assert( p->eVdbeState==VDBE_INIT_STATE );
82420 assert( pParse==p->pParse );
82421 p->pVList = pParse->pVList;
82422 pParse->pVList = 0;
82423 db = p->db;
82424 assert( db->mallocFailed==0 );
@@ -81947,18 +82555,16 @@
82555
82556 /*
82557 ** Close all cursors in the current frame.
82558 */
82559 static void closeCursorsInFrame(Vdbe *p){
82560 int i;
82561 for(i=0; i<p->nCursor; i++){
82562 VdbeCursor *pC = p->apCsr[i];
82563 if( pC ){
82564 sqlite3VdbeFreeCursor(p, pC);
82565 p->apCsr[i] = 0;
 
 
82566 }
82567 }
82568 }
82569
82570 /*
@@ -82003,13 +82609,11 @@
82609 p->pFrame = 0;
82610 p->nFrame = 0;
82611 }
82612 assert( p->nFrame==0 );
82613 closeCursorsInFrame(p);
82614 releaseMemArray(p->aMem, p->nMem);
 
 
82615 while( p->pDelFrame ){
82616 VdbeFrame *pDel = p->pDelFrame;
82617 p->pDelFrame = pDel->pParent;
82618 sqlite3VdbeFrameDelete(pDel);
82619 }
@@ -82445,11 +83049,12 @@
83049 || (!deferred && p->nFkConstraint>0)
83050 ){
83051 p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
83052 p->errorAction = OE_Abort;
83053 sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
83054 if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR;
83055 return SQLITE_CONSTRAINT_FOREIGNKEY;
83056 }
83057 return SQLITE_OK;
83058 }
83059 #endif
83060
@@ -82484,11 +83089,11 @@
83089 ** Then the internal cache might have been left in an inconsistent
83090 ** state. We need to rollback the statement transaction, if there is
83091 ** one, or the complete transaction if there is no statement transaction.
83092 */
83093
83094 if( p->eVdbeState!=VDBE_RUN_STATE ){
83095 return SQLITE_OK;
83096 }
83097 if( db->mallocFailed ){
83098 p->rc = SQLITE_NOMEM_BKPT;
83099 }
@@ -82495,11 +83100,11 @@
83100 closeAllCursors(p);
83101 checkActiveVdbeCnt(db);
83102
83103 /* No commit or rollback needed if the program never started or if the
83104 ** SQL statement does not read or write a database file. */
83105 if( p->bIsReader ){
83106 int mrc; /* Primary error code from p->rc */
83107 int eStatementOp = 0;
83108 int isSpecialError; /* Set to true if a 'special' error */
83109
83110 /* Lock all btrees used by the statement */
@@ -82643,19 +83248,17 @@
83248 /* Release the locks */
83249 sqlite3VdbeLeave(p);
83250 }
83251
83252 /* We have successfully halted and closed the VM. Record this fact. */
83253 db->nVdbeActive--;
83254 if( !p->readOnly ) db->nVdbeWrite--;
83255 if( p->bIsReader ) db->nVdbeRead--;
83256 assert( db->nVdbeActive>=db->nVdbeRead );
83257 assert( db->nVdbeRead>=db->nVdbeWrite );
83258 assert( db->nVdbeWrite>=0 );
83259 p->eVdbeState = VDBE_HALT_STATE;
 
 
83260 checkActiveVdbeCnt(db);
83261 if( db->mallocFailed ){
83262 p->rc = SQLITE_NOMEM_BKPT;
83263 }
83264
@@ -82700,10 +83303,11 @@
83303 db->bBenignMalloc--;
83304 }else if( db->pErr ){
83305 sqlite3ValueSetNull(db->pErr);
83306 }
83307 db->errCode = rc;
83308 db->errByteOffset = -1;
83309 return rc;
83310 }
83311
83312 #ifdef SQLITE_ENABLE_SQLLOG
83313 /*
@@ -82732,12 +83336,12 @@
83336 **
83337 ** After this routine is run, the VDBE should be ready to be executed
83338 ** again.
83339 **
83340 ** To look at it another way, this routine resets the state of the
83341 ** virtual machine from VDBE_RUN_STATE or VDBE_HALT_STATE back to
83342 ** VDBE_READY_STATE.
83343 */
83344 SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
83345 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
83346 int i;
83347 #endif
@@ -82762,16 +83366,10 @@
83366 sqlite3VdbeTransferError(p);
83367 }else{
83368 db->errCode = p->rc;
83369 }
83370 if( p->runOnlyOnce ) p->expired = 1;
 
 
 
 
 
 
83371 }
83372
83373 /* Reset register contents and reclaim error message memory.
83374 */
83375 #ifdef SQLITE_DEBUG
@@ -82824,21 +83422,23 @@
83422 }
83423 fclose(out);
83424 }
83425 }
83426 #endif
 
83427 return p->rc & db->errMask;
83428 }
83429
83430 /*
83431 ** Clean up and delete a VDBE after execution. Return an integer which is
83432 ** the result code. Write any error message text into *pzErrMsg.
83433 */
83434 SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
83435 int rc = SQLITE_OK;
83436 assert( VDBE_RUN_STATE>VDBE_READY_STATE );
83437 assert( VDBE_HALT_STATE>VDBE_READY_STATE );
83438 assert( VDBE_INIT_STATE<VDBE_READY_STATE );
83439 if( p->eVdbeState>=VDBE_READY_STATE ){
83440 rc = sqlite3VdbeReset(p);
83441 assert( (rc & p->db->errMask)==rc );
83442 }
83443 sqlite3VdbeDelete(p);
83444 return rc;
@@ -82889,23 +83489,25 @@
83489 ** the database connection and frees the object itself.
83490 */
83491 SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
83492 SubProgram *pSub, *pNext;
83493 assert( p->db==0 || p->db==db );
83494 if( p->aColName ){
83495 releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
83496 sqlite3DbFreeNN(db, p->aColName);
83497 }
83498 for(pSub=p->pProgram; pSub; pSub=pNext){
83499 pNext = pSub->pNext;
83500 vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
83501 sqlite3DbFree(db, pSub);
83502 }
83503 if( p->eVdbeState!=VDBE_INIT_STATE ){
83504 releaseMemArray(p->aVar, p->nVar);
83505 if( p->pVList ) sqlite3DbFreeNN(db, p->pVList);
83506 if( p->pFree ) sqlite3DbFreeNN(db, p->pFree);
83507 }
83508 vdbeFreeOpArray(db, p->aOp, p->nOp);
 
83509 sqlite3DbFree(db, p->zSql);
83510 #ifdef SQLITE_ENABLE_NORMALIZE
83511 sqlite3DbFree(db, p->zNormSql);
83512 {
83513 DblquoteStr *pThis, *pNext;
@@ -82943,12 +83545,10 @@
83545 db->pVdbe = p->pNext;
83546 }
83547 if( p->pNext ){
83548 p->pNext->pPrev = p->pPrev;
83549 }
 
 
83550 sqlite3DbFreeNN(db, p);
83551 }
83552
83553 /*
83554 ** The cursor "p" has a pending seek operation that has not yet been
@@ -82979,11 +83579,11 @@
83579 ** pointed to was deleted out from under it. Or maybe the btree was
83580 ** rebalanced. Whatever the cause, try to restore "p" to the place it
83581 ** is supposed to be pointing. If the row was deleted out from under the
83582 ** cursor, set the cursor to point to a NULL row.
83583 */
83584 SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){
83585 int isDifferentRow, rc;
83586 assert( p->eCurType==CURTYPE_BTREE );
83587 assert( p->uc.pCursor!=0 );
83588 assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) );
83589 rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow);
@@ -82997,43 +83597,11 @@
83597 ** if need be. Return any I/O error from the restore operation.
83598 */
83599 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
83600 assert( p->eCurType==CURTYPE_BTREE );
83601 if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
83602 return sqlite3VdbeHandleMovedCursor(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83603 }
83604 return SQLITE_OK;
83605 }
83606
83607 /*
@@ -83691,12 +84259,12 @@
84259 if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
84260 rc = 0;
84261 }else{
84262 rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2);
84263 }
84264 sqlite3VdbeMemReleaseMalloc(&c1);
84265 sqlite3VdbeMemReleaseMalloc(&c2);
84266 return rc;
84267 }
84268 }
84269
84270 /*
@@ -84216,11 +84784,12 @@
84784
84785 default:
84786 return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
84787 }
84788
84789 assert( pPKey2->u.i == pPKey2->aMem[0].u.i );
84790 v = pPKey2->u.i;
84791 if( v>lhs ){
84792 res = pPKey2->r1;
84793 }else if( v<lhs ){
84794 res = pPKey2->r2;
84795 }else if( pPKey2->nField>1 ){
@@ -84251,16 +84820,22 @@
84820 const u8 *aKey1 = (const u8*)pKey1;
84821 int serial_type;
84822 int res;
84823
84824 assert( pPKey2->aMem[0].flags & MEM_Str );
84825 assert( pPKey2->aMem[0].n == pPKey2->n );
84826 assert( pPKey2->aMem[0].z == pPKey2->u.z );
84827 vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
84828 serial_type = (signed char)(aKey1[1]);
84829
84830 vrcs_restart:
 
84831 if( serial_type<12 ){
84832 if( serial_type<0 ){
84833 sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
84834 if( serial_type>=12 ) goto vrcs_restart;
84835 assert( CORRUPT_DB );
84836 }
84837 res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
84838 }else if( !(serial_type & 0x01) ){
84839 res = pPKey2->r2; /* (pKey1/nKey1) is a blob */
84840 }else{
84841 int nCmp;
@@ -84270,19 +84845,19 @@
84845 nStr = (serial_type-12) / 2;
84846 if( (szHdr + nStr) > nKey1 ){
84847 pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
84848 return 0; /* Corruption */
84849 }
84850 nCmp = MIN( pPKey2->n, nStr );
84851 res = memcmp(&aKey1[szHdr], pPKey2->u.z, nCmp);
84852
84853 if( res>0 ){
84854 res = pPKey2->r2;
84855 }else if( res<0 ){
84856 res = pPKey2->r1;
84857 }else{
84858 res = nStr - pPKey2->n;
84859 if( res==0 ){
84860 if( pPKey2->nField>1 ){
84861 res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
84862 }else{
84863 res = pPKey2->default_rc;
@@ -84333,19 +84908,22 @@
84908 }else{
84909 p->r1 = -1;
84910 p->r2 = 1;
84911 }
84912 if( (flags & MEM_Int) ){
84913 p->u.i = p->aMem[0].u.i;
84914 return vdbeRecordCompareInt;
84915 }
84916 testcase( flags & MEM_Real );
84917 testcase( flags & MEM_Null );
84918 testcase( flags & MEM_Blob );
84919 if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
84920 && p->pKeyInfo->aColl[0]==0
84921 ){
84922 assert( flags & MEM_Str );
84923 p->u.z = p->aMem[0].z;
84924 p->n = p->aMem[0].n;
84925 return vdbeRecordCompareString;
84926 }
84927 }
84928
84929 return sqlite3VdbeRecordCompare;
@@ -84414,18 +84992,18 @@
84992 }
84993
84994 /* Fetch the integer off the end of the index record */
84995 sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
84996 *rowid = v.u.i;
84997 sqlite3VdbeMemReleaseMalloc(&m);
84998 return SQLITE_OK;
84999
85000 /* Jump here if database corruption is detected after m has been
85001 ** allocated. Free the m object and return SQLITE_CORRUPT. */
85002 idx_rowid_corruption:
85003 testcase( m.szMalloc!=0 );
85004 sqlite3VdbeMemReleaseMalloc(&m);
85005 return SQLITE_CORRUPT_BKPT;
85006 }
85007
85008 /*
85009 ** Compare the key of the index entry that cursor pC is pointing to against
@@ -84463,11 +85041,11 @@
85041 rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
85042 if( rc ){
85043 return rc;
85044 }
85045 *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
85046 sqlite3VdbeMemReleaseMalloc(&m);
85047 return SQLITE_OK;
85048 }
85049
85050 /*
85051 ** This routine sets the value to be returned by subsequent calls to
@@ -84630,11 +85208,11 @@
85208 static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
85209 if( p ){
85210 int i;
85211 for(i=0; i<nField; i++){
85212 Mem *pMem = &p->aMem[i];
85213 if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem);
85214 }
85215 sqlite3DbFreeNN(db, p);
85216 }
85217 }
85218 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -85057,10 +85635,13 @@
85635 pNew->flags |= MEM_Ephem;
85636 if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
85637 sqlite3ValueFree(pNew);
85638 pNew = 0;
85639 }
85640 }else if( pNew->flags & MEM_Null ){
85641 /* Do not duplicate pointer values */
85642 pNew->flags &= ~(MEM_Term|MEM_Subtype);
85643 }
85644 return pNew;
85645 }
85646
85647 /* Destroy an sqlite3_value object previously obtained from
@@ -85087,20 +85668,26 @@
85668 const char *z, /* String pointer */
85669 int n, /* Bytes in string, or negative */
85670 u8 enc, /* Encoding of z. 0 for BLOBs */
85671 void (*xDel)(void*) /* Destructor function */
85672 ){
85673 Mem *pOut = pCtx->pOut;
85674 int rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel);
85675 if( rc ){
85676 if( rc==SQLITE_TOOBIG ){
85677 sqlite3_result_error_toobig(pCtx);
85678 }else{
85679 /* The only errors possible from sqlite3VdbeMemSetStr are
85680 ** SQLITE_TOOBIG and SQLITE_NOMEM */
85681 assert( rc==SQLITE_NOMEM );
85682 sqlite3_result_error_nomem(pCtx);
85683 }
85684 return;
85685 }
85686 sqlite3VdbeChangeEncoding(pOut, pCtx->enc);
85687 if( sqlite3VdbeMemTooBig(pOut) ){
85688 sqlite3_result_error_toobig(pCtx);
85689 }
85690 }
85691 static int invokeValueDestructor(
85692 const void *p, /* Value to destroy */
85693 void (*xDel)(void*), /* The destructor */
@@ -85240,21 +85827,26 @@
85827 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
85828 setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
85829 }
85830 #endif /* SQLITE_OMIT_UTF16 */
85831 SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
85832 Mem *pOut = pCtx->pOut;
85833 assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
85834 sqlite3VdbeMemCopy(pOut, pValue);
85835 sqlite3VdbeChangeEncoding(pOut, pCtx->enc);
85836 if( sqlite3VdbeMemTooBig(pOut) ){
85837 sqlite3_result_error_toobig(pCtx);
85838 }
85839 }
85840 SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
85841 sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0);
 
85842 }
85843 SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
85844 Mem *pOut = pCtx->pOut;
85845 assert( sqlite3_mutex_held(pOut->db->mutex) );
85846 if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
85847 sqlite3_result_error_toobig(pCtx);
85848 return SQLITE_TOOBIG;
85849 }
85850 #ifndef SQLITE_OMIT_INCRBLOB
85851 sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
85852 return SQLITE_OK;
@@ -85266,12 +85858,12 @@
85858 pCtx->isError = errCode ? errCode : -1;
85859 #ifdef SQLITE_DEBUG
85860 if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
85861 #endif
85862 if( pCtx->pOut->flags & MEM_Null ){
85863 setResultStrOrError(pCtx, sqlite3ErrStr(errCode), -1, SQLITE_UTF8,
85864 SQLITE_STATIC);
85865 }
85866 }
85867
85868 /* Force an SQLITE_TOOBIG error. */
85869 SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
@@ -85340,85 +85932,94 @@
85932 */
85933 static int sqlite3Step(Vdbe *p){
85934 sqlite3 *db;
85935 int rc;
85936
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85937 /* Check that malloc() has not failed. If it has, return early. */
85938 db = p->db;
85939 if( db->mallocFailed ){
85940 p->rc = SQLITE_NOMEM;
85941 return SQLITE_NOMEM_BKPT;
85942 }
85943
85944 assert(p);
85945 if( p->eVdbeState!=VDBE_RUN_STATE ){
85946 restart_step:
85947 if( p->eVdbeState==VDBE_READY_STATE ){
85948 if( p->expired ){
85949 p->rc = SQLITE_SCHEMA;
85950 rc = SQLITE_ERROR;
85951 if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){
85952 /* If this statement was prepared using saved SQL and an
85953 ** error has occurred, then return the error code in p->rc to the
85954 ** caller. Set the error code in the database handle to the same
85955 ** value.
85956 */
85957 rc = sqlite3VdbeTransferError(p);
85958 }
85959 goto end_of_step;
85960 }
85961
85962 /* If there are no other statements currently running, then
85963 ** reset the interrupt flag. This prevents a call to sqlite3_interrupt
85964 ** from interrupting a statement that has not yet started.
85965 */
85966 if( db->nVdbeActive==0 ){
85967 AtomicStore(&db->u1.isInterrupted, 0);
85968 }
85969
85970 assert( db->nVdbeWrite>0 || db->autoCommit==0
85971 || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
85972 );
85973
85974 #ifndef SQLITE_OMIT_TRACE
85975 if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
85976 && !db->init.busy && p->zSql ){
85977 sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
85978 }else{
85979 assert( p->startTime==0 );
85980 }
85981 #endif
85982
85983 db->nVdbeActive++;
85984 if( p->readOnly==0 ) db->nVdbeWrite++;
85985 if( p->bIsReader ) db->nVdbeRead++;
85986 p->pc = 0;
85987 p->eVdbeState = VDBE_RUN_STATE;
85988 }else
85989
85990 if( ALWAYS(p->eVdbeState==VDBE_HALT_STATE) ){
85991 /* We used to require that sqlite3_reset() be called before retrying
85992 ** sqlite3_step() after any error or after SQLITE_DONE. But beginning
85993 ** with version 3.7.0, we changed this so that sqlite3_reset() would
85994 ** be called automatically instead of throwing the SQLITE_MISUSE error.
85995 ** This "automatic-reset" change is not technically an incompatibility,
85996 ** since any application that receives an SQLITE_MISUSE is broken by
85997 ** definition.
85998 **
85999 ** Nevertheless, some published applications that were originally written
86000 ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
86001 ** returns, and those were broken by the automatic-reset change. As a
86002 ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
86003 ** legacy behavior of returning SQLITE_MISUSE for cases where the
86004 ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
86005 ** or SQLITE_BUSY error.
86006 */
86007 #ifdef SQLITE_OMIT_AUTORESET
86008 if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
86009 sqlite3_reset((sqlite3_stmt*)p);
86010 }else{
86011 return SQLITE_MISUSE_BKPT;
86012 }
86013 #else
86014 sqlite3_reset((sqlite3_stmt*)p);
86015 #endif
86016 assert( p->eVdbeState==VDBE_READY_STATE );
86017 goto restart_step;
86018 }
86019 }
86020
86021 #ifdef SQLITE_DEBUG
86022 p->rcApp = SQLITE_OK;
86023 #endif
86024 #ifndef SQLITE_OMIT_EXPLAIN
86025 if( p->explain ){
@@ -85429,11 +86030,16 @@
86030 db->nVdbeExec++;
86031 rc = sqlite3VdbeExec(p);
86032 db->nVdbeExec--;
86033 }
86034
86035 if( rc==SQLITE_ROW ){
86036 assert( p->rc==SQLITE_OK );
86037 assert( db->mallocFailed==0 );
86038 db->errCode = SQLITE_ROW;
86039 return SQLITE_ROW;
86040 }else{
86041 #ifndef SQLITE_OMIT_TRACE
86042 /* If the statement completed successfully, invoke the profile callback */
86043 checkProfileCallback(db, p);
86044 #endif
86045
@@ -85557,10 +86163,74 @@
86163 */
86164 SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
86165 assert( p );
86166 return sqlite3_value_nochange(p->pOut);
86167 }
86168
86169 /*
86170 ** Implementation of sqlite3_vtab_in_first() (if bNext==0) and
86171 ** sqlite3_vtab_in_next() (if bNext!=0).
86172 */
86173 static int valueFromValueList(
86174 sqlite3_value *pVal, /* Pointer to the ValueList object */
86175 sqlite3_value **ppOut, /* Store the next value from the list here */
86176 int bNext /* 1 for _next(). 0 for _first() */
86177 ){
86178 int rc;
86179 ValueList *pRhs;
86180
86181 *ppOut = 0;
86182 if( pVal==0 ) return SQLITE_MISUSE;
86183 pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList");
86184 if( pRhs==0 ) return SQLITE_MISUSE;
86185 if( bNext ){
86186 rc = sqlite3BtreeNext(pRhs->pCsr, 0);
86187 }else{
86188 int dummy = 0;
86189 rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy);
86190 assert( rc==SQLITE_OK || sqlite3BtreeEof(pRhs->pCsr) );
86191 if( sqlite3BtreeEof(pRhs->pCsr) ) rc = SQLITE_DONE;
86192 }
86193 if( rc==SQLITE_OK ){
86194 u32 sz; /* Size of current row in bytes */
86195 Mem sMem; /* Raw content of current row */
86196 memset(&sMem, 0, sizeof(sMem));
86197 sz = sqlite3BtreePayloadSize(pRhs->pCsr);
86198 rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem);
86199 if( rc==SQLITE_OK ){
86200 u8 *zBuf = (u8*)sMem.z;
86201 u32 iSerial;
86202 sqlite3_value *pOut = pRhs->pOut;
86203 int iOff = 1 + getVarint32(&zBuf[1], iSerial);
86204 sqlite3VdbeSerialGet(&zBuf[iOff], iSerial, pOut);
86205 pOut->enc = ENC(pOut->db);
86206 if( (pOut->flags & MEM_Ephem)!=0 && sqlite3VdbeMemMakeWriteable(pOut) ){
86207 rc = SQLITE_NOMEM;
86208 }else{
86209 *ppOut = pOut;
86210 }
86211 }
86212 sqlite3VdbeMemRelease(&sMem);
86213 }
86214 return rc;
86215 }
86216
86217 /*
86218 ** Set the iterator value pVal to point to the first value in the set.
86219 ** Set (*ppOut) to point to this value before returning.
86220 */
86221 SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut){
86222 return valueFromValueList(pVal, ppOut, 0);
86223 }
86224
86225 /*
86226 ** Set the iterator value pVal to point to the next value in the set.
86227 ** Set (*ppOut) to point to this value before returning.
86228 */
86229 SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut){
86230 return valueFromValueList(pVal, ppOut, 1);
86231 }
86232
86233 /*
86234 ** Return the current time for a statement. If the current time
86235 ** is requested more than once within the same run of a single prepared
86236 ** statement, the exact same time is returned for each invocation regardless
@@ -85752,19 +86422,19 @@
86422 #if defined(SQLITE_DEBUG) && defined(__GNUC__)
86423 __attribute__((aligned(8)))
86424 #endif
86425 = {
86426 /* .u = */ {0},
86427 /* .z = */ (char*)0,
86428 /* .n = */ (int)0,
86429 /* .flags = */ (u16)MEM_Null,
86430 /* .enc = */ (u8)0,
86431 /* .eSubtype = */ (u8)0,
86432 /* .db = */ (sqlite3*)0,
 
 
86433 /* .szMalloc = */ (int)0,
86434 /* .uTemp = */ (u32)0,
86435 /* .zMalloc = */ (char*)0,
86436 /* .xDel = */ (void(*)(void*))0,
86437 #ifdef SQLITE_DEBUG
86438 /* .pScopyFrom = */ (Mem*)0,
86439 /* .mScopyFlags= */ 0,
86440 #endif
@@ -86057,11 +86727,11 @@
86727 Mem *pVar;
86728 if( vdbeSafetyNotNull(p) ){
86729 return SQLITE_MISUSE_BKPT;
86730 }
86731 sqlite3_mutex_enter(p->db->mutex);
86732 if( p->eVdbeState!=VDBE_READY_STATE ){
86733 sqlite3Error(p->db, SQLITE_MISUSE);
86734 sqlite3_mutex_leave(p->db->mutex);
86735 sqlite3_log(SQLITE_MISUSE,
86736 "bind on a busy prepared statement: [%s]", p->zSql);
86737 return SQLITE_MISUSE_BKPT;
@@ -86242,11 +86912,14 @@
86912 case SQLITE_INTEGER: {
86913 rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
86914 break;
86915 }
86916 case SQLITE_FLOAT: {
86917 assert( pValue->flags & (MEM_Real|MEM_IntReal) );
86918 rc = sqlite3_bind_double(pStmt, i,
86919 (pValue->flags & MEM_Real) ? pValue->u.r : (double)pValue->u.i
86920 );
86921 break;
86922 }
86923 case SQLITE_BLOB: {
86924 if( pValue->flags & MEM_Zero ){
86925 rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero);
@@ -86407,11 +87080,11 @@
87080 /*
87081 ** Return true if the prepared statement is in need of being reset.
87082 */
87083 SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
87084 Vdbe *v = (Vdbe*)pStmt;
87085 return v!=0 && v->eVdbeState==VDBE_RUN_STATE;
87086 }
87087
87088 /*
87089 ** Return a pointer to the next prepared statement after pStmt associated
87090 ** with database connection pDb. If pStmt is NULL, return the first
@@ -87721,11 +88394,11 @@
88394 #ifdef VDBE_PROFILE
88395 u64 start; /* CPU clock count at start of opcode */
88396 #endif
88397 /*** INSERT STACK UNION HERE ***/
88398
88399 assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */
88400 sqlite3VdbeEnter(p);
88401 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
88402 if( db->xProgress ){
88403 u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
88404 assert( 0 < db->nProgressOps );
@@ -87972,14 +88645,18 @@
88645 jump_to_p2:
88646 pOp = &aOp[pOp->p2 - 1];
88647 break;
88648 }
88649
88650 /* Opcode: Return P1 * P3 * *
88651 **
88652 ** Jump to the next instruction after the address in register P1. After
88653 ** the jump, register P1 becomes undefined.
88654 **
88655 ** P3 is not used by the byte-code engine. However, the code generator
88656 ** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is
88657 ** one.
88658 */
88659 case OP_Return: { /* in1 */
88660 pIn1 = &aMem[pOp->p1];
88661 assert( pIn1->flags==MEM_Int );
88662 pOp = &aOp[pIn1->u.i];
@@ -88163,15 +88840,26 @@
88840 rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
88841 }
88842 goto vdbe_return;
88843 }
88844
88845 /* Opcode: BeginSubrtn P1 P2 * * *
88846 ** Synopsis: r[P2]=P1
88847 **
88848 ** Mark the beginning of a subroutine by loading the integer value P1
88849 ** into register r[P2]. The P2 register is used to store the return
88850 ** address of the subroutine call.
88851 **
88852 ** This opcode is identical to OP_Integer. It has a different name
88853 ** only to make the byte code easier to read and verify.
88854 */
88855 /* Opcode: Integer P1 P2 * * *
88856 ** Synopsis: r[P2]=P1
88857 **
88858 ** The 32-bit integer value P1 is written into register P2.
88859 */
88860 case OP_BeginSubrtn:
88861 case OP_Integer: { /* out2 */
88862 pOut = out2Prerelease(p, pOp);
88863 pOut->u.i = pOp->p1;
88864 break;
88865 }
@@ -89608,14 +90296,22 @@
90296 case OP_Offset: { /* out3 */
90297 VdbeCursor *pC; /* The VDBE cursor */
90298 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
90299 pC = p->apCsr[pOp->p1];
90300 pOut = &p->aMem[pOp->p3];
90301 if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){
90302 sqlite3VdbeMemSetNull(pOut);
90303 }else{
90304 if( pC->deferredMoveto ){
90305 rc = sqlite3VdbeFinishMoveto(pC);
90306 if( rc ) goto abort_due_to_error;
90307 }
90308 if( sqlite3BtreeEof(pC->uc.pCursor) ){
90309 sqlite3VdbeMemSetNull(pOut);
90310 }else{
90311 sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
90312 }
90313 }
90314 break;
90315 }
90316 #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
90317
@@ -89640,11 +90336,11 @@
90336 ** skipped for length() and all content loading can be skipped for typeof().
90337 */
90338 case OP_Column: {
90339 u32 p2; /* column number to retrieve */
90340 VdbeCursor *pC; /* The VDBE cursor */
90341 BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */
90342 u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
90343 int len; /* The length of the serialized data for the column */
90344 int i; /* Loop counter */
90345 Mem *pDest; /* Where to write the extracted value */
90346 Mem sMem; /* For storing the record being decoded */
@@ -89654,23 +90350,15 @@
90350 u64 offset64; /* 64-bit offset */
90351 u32 t; /* A type code from the record header */
90352 Mem *pReg; /* PseudoTable input register */
90353
90354 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
90355 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
90356 pC = p->apCsr[pOp->p1];
 
90357 p2 = (u32)pOp->p2;
90358
90359 op_column_restart:
 
 
 
 
 
 
 
 
90360 assert( pC!=0 );
90361 assert( p2<(u32)pC->nField );
90362 aOffset = pC->aOffset;
90363 assert( aOffset==pC->aType+pC->nField );
90364 assert( pC->eCurType!=CURTYPE_VTAB );
@@ -89687,30 +90375,43 @@
90375 assert( pReg->flags & MEM_Blob );
90376 assert( memIsValid(pReg) );
90377 pC->payloadSize = pC->szRow = pReg->n;
90378 pC->aRow = (u8*)pReg->z;
90379 }else{
90380 pDest = &aMem[pOp->p3];
90381 memAboutToChange(p, pDest);
90382 sqlite3VdbeMemSetNull(pDest);
90383 goto op_column_out;
90384 }
90385 }else{
90386 pCrsr = pC->uc.pCursor;
90387 if( pC->deferredMoveto ){
90388 u32 iMap;
90389 assert( !pC->isEphemeral );
90390 if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){
90391 pC = pC->pAltCursor;
90392 p2 = iMap - 1;
90393 goto op_column_restart;
90394 }
90395 rc = sqlite3VdbeFinishMoveto(pC);
90396 if( rc ) goto abort_due_to_error;
90397 }else if( sqlite3BtreeCursorHasMoved(pCrsr) ){
90398 rc = sqlite3VdbeHandleMovedCursor(pC);
90399 if( rc ) goto abort_due_to_error;
90400 goto op_column_restart;
90401 }
90402 assert( pC->eCurType==CURTYPE_BTREE );
90403 assert( pCrsr );
90404 assert( sqlite3BtreeCursorIsValid(pCrsr) );
90405 pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
90406 pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
90407 assert( pC->szRow<=pC->payloadSize );
90408 assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
 
 
 
90409 }
90410 pC->cacheStatus = p->cacheCtr;
90411 pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
90412 pC->nHdrParsed = 0;
 
90413
90414 if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
90415 /* pC->aRow does not have to hold the entire row, but it does at least
90416 ** need to cover the header of the record. If pC->aRow does not contain
90417 ** the complete header, then set it to zero, forcing the header to be
@@ -89747,10 +90448,14 @@
90448 zData = pC->aRow;
90449 assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
90450 testcase( aOffset[0]==0 );
90451 goto op_column_read_header;
90452 }
90453 }else if( sqlite3BtreeCursorHasMoved(pC->uc.pCursor) ){
90454 rc = sqlite3VdbeHandleMovedCursor(pC);
90455 if( rc ) goto abort_due_to_error;
90456 goto op_column_restart;
90457 }
90458
90459 /* Make sure at least the first p2+1 entries of the header have been
90460 ** parsed and valid information is in aOffset[] and pC->aType[].
90461 */
@@ -89815,10 +90520,12 @@
90520 /* If after trying to extract new entries from the header, nHdrParsed is
90521 ** still not up to p2, that means that the record has fewer than p2
90522 ** columns. So the result will be either the default value or a NULL.
90523 */
90524 if( pC->nHdrParsed<=p2 ){
90525 pDest = &aMem[pOp->p3];
90526 memAboutToChange(p, pDest);
90527 if( pOp->p4type==P4_MEM ){
90528 sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
90529 }else{
90530 sqlite3VdbeMemSetNull(pDest);
90531 }
@@ -89832,10 +90539,12 @@
90539 ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
90540 ** all valid.
90541 */
90542 assert( p2<pC->nHdrParsed );
90543 assert( rc==SQLITE_OK );
90544 pDest = &aMem[pOp->p3];
90545 memAboutToChange(p, pDest);
90546 assert( sqlite3VdbeCheckMemInvariants(pDest) );
90547 if( VdbeMemDynamic(pDest) ){
90548 sqlite3VdbeMemSetNull(pDest);
90549 }
90550 assert( t==pC->aType[p2] );
@@ -89852,10 +90561,11 @@
90561 */
90562 static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term };
90563 pDest->n = len = (t-12)/2;
90564 pDest->enc = encoding;
90565 if( pDest->szMalloc < len+2 ){
90566 if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
90567 pDest->flags = MEM_Null;
90568 if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem;
90569 }else{
90570 pDest->z = pDest->zMalloc;
90571 }
@@ -89884,10 +90594,11 @@
90594 ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
90595 ** and it begins with a bunch of zeros.
90596 */
90597 sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
90598 }else{
90599 if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
90600 rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
90601 if( rc!=SQLITE_OK ) goto abort_due_to_error;
90602 sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
90603 pDest->flags &= ~MEM_Ephem;
90604 }
@@ -90096,11 +90807,10 @@
90807 u32 serial_type; /* Type field */
90808 Mem *pData0; /* First field to be combined into the record */
90809 Mem *pLast; /* Last field of the record */
90810 int nField; /* Number of fields in the record */
90811 char *zAffinity; /* The affinity string for the record */
 
90812 u32 len; /* Length of a field */
90813 u8 *zHdr; /* Where to write next byte of the header */
90814 u8 *zPayload; /* Where to write next byte of the payload */
90815
90816 /* Assuming the record contains N fields, the record format looks
@@ -90125,11 +90835,10 @@
90835 zAffinity = pOp->p4.z;
90836 assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 );
90837 pData0 = &aMem[nField];
90838 nField = pOp->p2;
90839 pLast = &pData0[nField-1];
 
90840
90841 /* Identify the output register */
90842 assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
90843 pOut = &aMem[pOp->p3];
90844 memAboutToChange(p, pOut);
@@ -90224,14 +90933,14 @@
90933 }
90934 nHdr++;
90935 testcase( uu==127 ); testcase( uu==128 );
90936 testcase( uu==32767 ); testcase( uu==32768 );
90937 testcase( uu==8388607 ); testcase( uu==8388608 );
90938 testcase( uu==2147483647 ); testcase( uu==2147483648LL );
90939 testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL );
90940 if( uu<=127 ){
90941 if( (i&1)==i && p->minWriteFileFormat>=4 ){
90942 pRec->uTemp = 8+(u32)uu;
90943 }else{
90944 nData++;
90945 pRec->uTemp = 1;
90946 }
@@ -92690,10 +93399,14 @@
93399 /* Opcode: NullRow P1 * * * *
93400 **
93401 ** Move the cursor P1 to a null row. Any OP_Column operations
93402 ** that occur while the cursor is on the null row will always
93403 ** write a NULL.
93404 **
93405 ** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo)
93406 ** just reset the cache for that cursor. This causes the row of
93407 ** content held by the pseudo-cursor to be reparsed.
93408 */
93409 case OP_NullRow: {
93410 VdbeCursor *pC;
93411
93412 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
@@ -92869,11 +93582,11 @@
93582 VdbeBranchTaken(res!=0,2);
93583 if( res ) goto jump_to_p2;
93584 break;
93585 }
93586
93587 /* Opcode: Next P1 P2 P3 * P5
93588 **
93589 ** Advance cursor P1 so that it points to the next key/data pair in its
93590 ** table or index. If there are no more key/value pairs then fall through
93591 ** to the following instruction. But if the cursor advance was successful,
93592 ** jump immediately to P2.
@@ -92888,19 +93601,16 @@
93601 ** The P3 value is a hint to the btree implementation. If P3==1, that
93602 ** means P1 is an SQL index and that this instruction could have been
93603 ** omitted if that index had been unique. P3 is usually 0. P3 is
93604 ** always either 0 or 1.
93605 **
 
 
 
93606 ** If P5 is positive and the jump is taken, then event counter
93607 ** number P5-1 in the prepared statement is incremented.
93608 **
93609 ** See also: Prev
93610 */
93611 /* Opcode: Prev P1 P2 P3 * P5
93612 **
93613 ** Back up cursor P1 so that it points to the previous key/data pair in its
93614 ** table or index. If there is no previous key/value pairs then fall through
93615 ** to the following instruction. But if the cursor backup was successful,
93616 ** jump immediately to P2.
@@ -92916,13 +93626,10 @@
93626 ** The P3 value is a hint to the btree implementation. If P3==1, that
93627 ** means P1 is an SQL index and that this instruction could have been
93628 ** omitted if that index had been unique. P3 is usually 0. P3 is
93629 ** always either 0 or 1.
93630 **
 
 
 
93631 ** If P5 is positive and the jump is taken, then event counter
93632 ** number P5-1 in the prepared statement is incremented.
93633 */
93634 /* Opcode: SorterNext P1 P2 * * P5
93635 **
@@ -92936,34 +93643,37 @@
93643
93644 pC = p->apCsr[pOp->p1];
93645 assert( isSorter(pC) );
93646 rc = sqlite3VdbeSorterNext(db, pC);
93647 goto next_tail;
93648
93649 case OP_Prev: /* jump */
93650 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93651 assert( pOp->p5<ArraySize(p->aCounter) );
93652 pC = p->apCsr[pOp->p1];
93653 assert( pC!=0 );
93654 assert( pC->deferredMoveto==0 );
93655 assert( pC->eCurType==CURTYPE_BTREE );
93656 assert( pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
93657 || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope
93658 || pC->seekOp==OP_NullRow);
93659 rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3);
93660 goto next_tail;
93661
93662 case OP_Next: /* jump */
93663 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
93664 assert( pOp->p5<ArraySize(p->aCounter) );
93665 pC = p->apCsr[pOp->p1];
93666 assert( pC!=0 );
93667 assert( pC->deferredMoveto==0 );
93668 assert( pC->eCurType==CURTYPE_BTREE );
93669 assert( pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
 
 
 
 
 
 
93670 || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
93671 || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid
93672 || pC->seekOp==OP_IfNoHope);
93673 rc = sqlite3BtreeNext(pC->uc.pCursor, pOp->p3);
 
 
 
93674
 
93675 next_tail:
93676 pC->cacheStatus = CACHE_STALE;
93677 VdbeBranchTaken(rc==SQLITE_OK,2);
93678 if( rc==SQLITE_OK ){
93679 pC->nullRow = 0;
@@ -93177,10 +93887,11 @@
93887 assert( pTabCur->uc.pCursor!=0 );
93888 assert( pTabCur->isTable );
93889 pTabCur->nullRow = 0;
93890 pTabCur->movetoTarget = rowid;
93891 pTabCur->deferredMoveto = 1;
93892 pTabCur->cacheStatus = CACHE_STALE;
93893 assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
93894 assert( !pTabCur->isEphemeral );
93895 pTabCur->ub.aAltMap = pOp->p4.ai;
93896 assert( !pC->isEphemeral );
93897 pTabCur->pAltCursor = pC;
@@ -93311,11 +94022,11 @@
94022 }
94023 sqlite3VdbeMemInit(&m, db, 0);
94024 rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
94025 if( rc ) goto abort_due_to_error;
94026 res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0);
94027 sqlite3VdbeMemReleaseMalloc(&m);
94028 }
94029 /* End of inlined sqlite3VdbeIdxKeyCompare() */
94030
94031 assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
94032 if( (pOp->opcode&1)==(OP_IdxLT&1) ){
@@ -94192,10 +94903,11 @@
94903 pCtx->pFunc = pOp->p4.pFunc;
94904 pCtx->iOp = (int)(pOp - aOp);
94905 pCtx->pVdbe = p;
94906 pCtx->skipFlag = 0;
94907 pCtx->isError = 0;
94908 pCtx->enc = encoding;
94909 pCtx->argc = n;
94910 pOp->p4type = P4_FUNCCTX;
94911 pOp->p4.pCtx = pCtx;
94912
94913 /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */
@@ -94321,13 +95033,10 @@
95033 sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
95034 goto abort_due_to_error;
95035 }
95036 sqlite3VdbeChangeEncoding(pMem, encoding);
95037 UPDATE_MAX_BLOBSIZE(pMem);
 
 
 
95038 break;
95039 }
95040
95041 #ifndef SQLITE_OMIT_WAL
95042 /* Opcode: Checkpoint P1 P2 P3 * *
@@ -94714,10 +95423,38 @@
95423 goto no_mem;
95424 }
95425 break;
95426 }
95427 #endif /* SQLITE_OMIT_VIRTUALTABLE */
95428
95429 #ifndef SQLITE_OMIT_VIRTUALTABLE
95430 /* Opcode: VInitIn P1 P2 P3 * *
95431 ** Synopsis: r[P2]=ValueList(P1,P3)
95432 **
95433 ** Set register P2 to be a pointer to a ValueList object for cursor P1
95434 ** with cache register P3 and output register P3+1. This ValueList object
95435 ** can be used as the first argument to sqlite3_vtab_in_first() and
95436 ** sqlite3_vtab_in_next() to extract all of the values stored in the P1
95437 ** cursor. Register P3 is used to hold the values returned by
95438 ** sqlite3_vtab_in_first() and sqlite3_vtab_in_next().
95439 */
95440 case OP_VInitIn: { /* out2 */
95441 VdbeCursor *pC; /* The cursor containing the RHS values */
95442 ValueList *pRhs; /* New ValueList object to put in reg[P2] */
95443
95444 pC = p->apCsr[pOp->p1];
95445 pRhs = sqlite3_malloc64( sizeof(*pRhs) );
95446 if( pRhs==0 ) goto no_mem;
95447 pRhs->pCsr = pC->uc.pCursor;
95448 pRhs->pOut = &aMem[pOp->p3];
95449 pOut = out2Prerelease(p, pOp);
95450 pOut->flags = MEM_Null;
95451 sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free);
95452 break;
95453 }
95454 #endif /* SQLITE_OMIT_VIRTUALTABLE */
95455
95456
95457 #ifndef SQLITE_OMIT_VIRTUALTABLE
95458 /* Opcode: VFilter P1 P2 P3 P4 *
95459 ** Synopsis: iplan=r[P3] zplan='P4'
95460 **
@@ -94816,10 +95553,11 @@
95553 pVtab = pCur->uc.pVCur->pVtab;
95554 pModule = pVtab->pModule;
95555 assert( pModule->xColumn );
95556 memset(&sContext, 0, sizeof(sContext));
95557 sContext.pOut = pDest;
95558 sContext.enc = encoding;
95559 assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
95560 if( pOp->p5 & OPFLAG_NOCHNG ){
95561 sqlite3VdbeMemSetNull(pDest);
95562 pDest->flags = MEM_Null|MEM_Zero;
95563 pDest->u.nZero = 0;
@@ -94834,13 +95572,10 @@
95572 }
95573 sqlite3VdbeChangeEncoding(pDest, encoding);
95574 REGISTER_TRACE(pOp->p3, pDest);
95575 UPDATE_MAX_BLOBSIZE(pDest);
95576
 
 
 
95577 if( rc ) goto abort_due_to_error;
95578 break;
95579 }
95580 #endif /* SQLITE_OMIT_VIRTUALTABLE */
95581
@@ -95103,10 +95838,11 @@
95838 ** reinitializes the relavant parts of the sqlite3_context object */
95839 pOut = &aMem[pOp->p3];
95840 if( pCtx->pOut != pOut ){
95841 pCtx->pVdbe = p;
95842 pCtx->pOut = pOut;
95843 pCtx->enc = encoding;
95844 for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
95845 }
95846 assert( pCtx->pVdbe==p );
95847
95848 memAboutToChange(p, pOut);
@@ -95129,15 +95865,14 @@
95865 sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
95866 pCtx->isError = 0;
95867 if( rc ) goto abort_due_to_error;
95868 }
95869
95870 assert( (pOut->flags&MEM_Str)==0
95871 || pOut->enc==encoding
95872 || db->mallocFailed );
95873 assert( !sqlite3VdbeMemTooBig(pOut) );
 
95874
95875 REGISTER_TRACE(pOp->p3, pOut);
95876 UPDATE_MAX_BLOBSIZE(pOut);
95877 break;
95878 }
@@ -99442,10 +100177,13 @@
100177 }
100178 return rc;
100179 }
100180
100181
100182 /* Forward reference */
100183 static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size);
100184
100185 /*
100186 ** Write data to the file.
100187 */
100188 static int memjrnlWrite(
100189 sqlite3_file *pJfd, /* The journal file into which to write */
@@ -99472,26 +100210,24 @@
100210 /* An in-memory journal file should only ever be appended to. Random
100211 ** access writes are not required. The only exception to this is when
100212 ** the in-memory journal is being used by a connection using the
100213 ** atomic-write optimization. In this case the first 28 bytes of the
100214 ** journal file may be written as part of committing the transaction. */
100215 assert( iOfst<=p->endpoint.iOffset );
100216 if( iOfst>0 && iOfst!=p->endpoint.iOffset ){
100217 memjrnlTruncate(pJfd, iOfst);
100218 }
100219 if( iOfst==0 && p->pFirst ){
100220 assert( p->nChunkSize>iAmt );
100221 memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
100222 }else{
 
 
 
 
100223 while( nWrite>0 ){
100224 FileChunk *pChunk = p->endpoint.pChunk;
100225 int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
100226 int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
100227
100228 assert( pChunk!=0 || iChunkOffset==0 );
100229 if( iChunkOffset==0 ){
100230 /* New chunk is required to extend the file. */
100231 FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
100232 if( !pNew ){
100233 return SQLITE_IOERR_NOMEM_BKPT;
@@ -99502,14 +100238,15 @@
100238 pChunk->pNext = pNew;
100239 }else{
100240 assert( !p->pFirst );
100241 p->pFirst = pNew;
100242 }
100243 pChunk = p->endpoint.pChunk = pNew;
100244 }
100245
100246 assert( pChunk!=0 );
100247 memcpy((u8*)pChunk->zChunk + iChunkOffset, zWrite, iSpace);
100248 zWrite += iSpace;
100249 nWrite -= iSpace;
100250 p->endpoint.iOffset += iSpace;
100251 }
100252 }
@@ -100583,10 +101320,11 @@
101320 }else if( zTab ){
101321 sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
101322 }else{
101323 sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
101324 }
101325 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
101326 pParse->checkSchema = 1;
101327 pTopNC->nNcErr++;
101328 }
101329
101330 /* If a column from a table in pSrcList is referenced, then record
@@ -100691,11 +101429,12 @@
101429 */
101430 static void notValidImpl(
101431 Parse *pParse, /* Leave error message here */
101432 NameContext *pNC, /* The name context */
101433 const char *zMsg, /* Type of error */
101434 Expr *pExpr, /* Invalidate this expression on error */
101435 Expr *pError /* Associate error with this expression */
101436 ){
101437 const char *zIn = "partial index WHERE clauses";
101438 if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
101439 #ifndef SQLITE_OMIT_CHECK
101440 else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
@@ -100703,14 +101442,15 @@
101442 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
101443 else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns";
101444 #endif
101445 sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
101446 if( pExpr ) pExpr->op = TK_NULL;
101447 sqlite3RecordErrorOffsetOfExpr(pParse->db, pError);
101448 }
101449 #define sqlite3ResolveNotValid(P,N,M,X,E,R) \
101450 assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \
101451 if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E,R);
101452
101453 /*
101454 ** Expression p should encode a floating point value between 1.0 and 0.0.
101455 ** Return 1024 times this value. Or return -1 if p is not a floating point
101456 ** value between 1.0 and 0.0.
@@ -100841,11 +101581,11 @@
101581 }else{
101582 Expr *pLeft = pExpr->pLeft;
101583 testcase( pNC->ncFlags & NC_IdxExpr );
101584 testcase( pNC->ncFlags & NC_GenCol );
101585 sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator",
101586 NC_IdxExpr|NC_GenCol, 0, pExpr);
101587 pRight = pExpr->pRight;
101588 if( pRight->op==TK_ID ){
101589 zDb = 0;
101590 }else{
101591 assert( pRight->op==TK_DOT );
@@ -100872,21 +101612,19 @@
101612 ExprList *pList = pExpr->x.pList; /* The argument list */
101613 int n = pList ? pList->nExpr : 0; /* Number of arguments */
101614 int no_such_func = 0; /* True if no such function exists */
101615 int wrong_num_args = 0; /* True if wrong number of arguments */
101616 int is_agg = 0; /* True if is an aggregate function */
 
101617 const char *zId; /* The function name. */
101618 FuncDef *pDef; /* Information about the function */
101619 u8 enc = ENC(pParse->db); /* The database encoding */
101620 int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
101621 #ifndef SQLITE_OMIT_WINDOWFUNC
101622 Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
101623 #endif
101624 assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
101625 zId = pExpr->u.zToken;
 
101626 pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
101627 if( pDef==0 ){
101628 pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
101629 if( pDef==0 ){
101630 no_such_func = 1;
@@ -100899,12 +101637,12 @@
101637 ExprSetProperty(pExpr, EP_Unlikely);
101638 if( n==2 ){
101639 pExpr->iTable = exprProbability(pList->a[1].pExpr);
101640 if( pExpr->iTable<0 ){
101641 sqlite3ErrorMsg(pParse,
101642 "second argument to %#T() must be a "
101643 "constant between 0.0 and 1.0", pExpr);
101644 pNC->nNcErr++;
101645 }
101646 }else{
101647 /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
101648 ** equivalent to likelihood(X, 0.0625).
@@ -100921,12 +101659,12 @@
101659 #ifndef SQLITE_OMIT_AUTHORIZATION
101660 {
101661 int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
101662 if( auth!=SQLITE_OK ){
101663 if( auth==SQLITE_DENY ){
101664 sqlite3ErrorMsg(pParse, "not authorized to use function: %#T",
101665 pExpr);
101666 pNC->nNcErr++;
101667 }
101668 pExpr->op = TK_NULL;
101669 return WRC_Prune;
101670 }
@@ -100945,11 +101683,11 @@
101683 ** sqlite_version() that might change over time cannot be used
101684 ** in an index or generated column. Curiously, they can be used
101685 ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
101686 ** all this. */
101687 sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
101688 NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr);
101689 }else{
101690 assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
101691 pExpr->op2 = pNC->ncFlags & NC_SelfRef;
101692 if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
101693 }
@@ -100958,11 +101696,11 @@
101696 && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
101697 ){
101698 /* Internal-use-only functions are disallowed unless the
101699 ** SQL is being compiled using sqlite3NestedParse() or
101700 ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
101701 ** used to activate internal functions for testing purposes */
101702 no_such_func = 1;
101703 pDef = 0;
101704 }else
101705 if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
101706 && !IN_RENAME_OBJECT
@@ -100977,11 +101715,11 @@
101715 || (pDef->xValue==0 && pDef->xInverse==0)
101716 || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
101717 );
101718 if( pDef && pDef->xValue==0 && pWin ){
101719 sqlite3ErrorMsg(pParse,
101720 "%#T() may not be used as a window function", pExpr
101721 );
101722 pNC->nNcErr++;
101723 }else if(
101724 (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
101725 || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin)
@@ -100991,38 +101729,38 @@
101729 if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){
101730 zType = "window";
101731 }else{
101732 zType = "aggregate";
101733 }
101734 sqlite3ErrorMsg(pParse, "misuse of %s function %#T()",zType,pExpr);
101735 pNC->nNcErr++;
101736 is_agg = 0;
101737 }
101738 #else
101739 if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
101740 sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr);
101741 pNC->nNcErr++;
101742 is_agg = 0;
101743 }
101744 #endif
101745 else if( no_such_func && pParse->db->init.busy==0
101746 #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
101747 && pParse->explain==0
101748 #endif
101749 ){
101750 sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr);
101751 pNC->nNcErr++;
101752 }else if( wrong_num_args ){
101753 sqlite3ErrorMsg(pParse,"wrong number of arguments to function %#T()",
101754 pExpr);
101755 pNC->nNcErr++;
101756 }
101757 #ifndef SQLITE_OMIT_WINDOWFUNC
101758 else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
101759 sqlite3ErrorMsg(pParse,
101760 "FILTER may not be used with non-aggregate %#T()",
101761 pExpr
101762 );
101763 pNC->nNcErr++;
101764 }
101765 #endif
101766 if( is_agg ){
@@ -101103,11 +101841,11 @@
101841 testcase( pNC->ncFlags & NC_IsCheck );
101842 testcase( pNC->ncFlags & NC_PartIdx );
101843 testcase( pNC->ncFlags & NC_IdxExpr );
101844 testcase( pNC->ncFlags & NC_GenCol );
101845 if( pNC->ncFlags & NC_SelfRef ){
101846 notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr);
101847 }else{
101848 sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
101849 }
101850 assert( pNC->nRef>=nRef );
101851 if( nRef!=pNC->nRef ){
@@ -101121,11 +101859,11 @@
101859 testcase( pNC->ncFlags & NC_IsCheck );
101860 testcase( pNC->ncFlags & NC_PartIdx );
101861 testcase( pNC->ncFlags & NC_IdxExpr );
101862 testcase( pNC->ncFlags & NC_GenCol );
101863 sqlite3ResolveNotValid(pParse, pNC, "parameters",
101864 NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr, pExpr);
101865 break;
101866 }
101867 case TK_IS:
101868 case TK_ISNOT: {
101869 Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
@@ -101173,10 +101911,11 @@
101911 testcase( pExpr->op==TK_GE );
101912 testcase( pExpr->op==TK_IS );
101913 testcase( pExpr->op==TK_ISNOT );
101914 testcase( pExpr->op==TK_BETWEEN );
101915 sqlite3ErrorMsg(pParse, "row value misused");
101916 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
101917 }
101918 break;
101919 }
101920 }
101921 assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
@@ -101286,15 +102025,17 @@
102025 */
102026 static void resolveOutOfRangeError(
102027 Parse *pParse, /* The error context into which to write the error */
102028 const char *zType, /* "ORDER" or "GROUP" */
102029 int i, /* The index (1-based) of the term out of range */
102030 int mx, /* Largest permissible value of i */
102031 Expr *pError /* Associate the error with the expression */
102032 ){
102033 sqlite3ErrorMsg(pParse,
102034 "%r %s BY term out of range - should be "
102035 "between 1 and %d", i, zType, mx);
102036 sqlite3RecordErrorOffsetOfExpr(pParse->db, pError);
102037 }
102038
102039 /*
102040 ** Analyze the ORDER BY clause in a compound SELECT statement. Modify
102041 ** each term of the ORDER BY clause is a constant integer between 1
@@ -101346,11 +102087,11 @@
102087 if( pItem->done ) continue;
102088 pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
102089 if( NEVER(pE==0) ) continue;
102090 if( sqlite3ExprIsInteger(pE, &iCol) ){
102091 if( iCol<=0 || iCol>pEList->nExpr ){
102092 resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE);
102093 return 1;
102094 }
102095 }else{
102096 iCol = resolveAsName(pParse, pEList, pE);
102097 if( iCol==0 ){
@@ -101442,11 +102183,11 @@
102183 pEList = pSelect->pEList;
102184 assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
102185 for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
102186 if( pItem->u.x.iOrderByCol ){
102187 if( pItem->u.x.iOrderByCol>pEList->nExpr ){
102188 resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr, 0);
102189 return 1;
102190 }
102191 resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0);
102192 }
102193 }
@@ -101534,11 +102275,11 @@
102275 if( sqlite3ExprIsInteger(pE2, &iCol) ){
102276 /* The ORDER BY term is an integer constant. Again, set the column
102277 ** number so that sqlite3ResolveOrderGroupBy() will convert the
102278 ** order-by term to a copy of the result-set expression */
102279 if( iCol<1 || iCol>0xffff ){
102280 resolveOutOfRangeError(pParse, zType, i+1, nResult, pE2);
102281 return 1;
102282 }
102283 pItem->u.x.iOrderByCol = (u16)iCol;
102284 continue;
102285 }
@@ -102787,13 +103528,12 @@
103528 **
103529 ** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
103530 ** if appropriate.
103531 */
103532 static void exprSetHeight(Expr *p){
103533 int nHeight = p->pLeft ? p->pLeft->nHeight : 0;
103534 if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight;
 
103535 if( ExprUseXSelect(p) ){
103536 heightOfSelect(p->x.pSelect, &nHeight);
103537 }else if( p->x.pList ){
103538 heightOfExprList(p->x.pList, &nHeight);
103539 p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
@@ -103088,10 +103828,11 @@
103828 pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
103829 if( pNew==0 ){
103830 sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
103831 return 0;
103832 }
103833 pNew->w.iOfst = (int)(pToken->z - pParse->zTail);
103834 if( pList
103835 && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
103836 && !pParse->nested
103837 ){
103838 sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
@@ -103131,11 +103872,11 @@
103872 ** (2) not tagged with SQLITE_INNOCUOUS (which means it
103873 ** is tagged with SQLITE_FUNC_UNSAFE) and
103874 ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
103875 ** that the schema is possibly tainted).
103876 */
103877 sqlite3ErrorMsg(pParse, "unsafe use of %#T()", pExpr);
103878 }
103879 }
103880 }
103881
103882 /*
@@ -103187,10 +103928,11 @@
103928 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
103929 testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
103930 if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103931 sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
103932 db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
103933 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
103934 return;
103935 }
103936 x = (ynVar)i;
103937 if( x>pParse->nVar ){
103938 pParse->nVar = (int)x;
@@ -103214,10 +103956,11 @@
103956 }
103957 }
103958 pExpr->iColumn = x;
103959 if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
103960 sqlite3ErrorMsg(pParse, "too many SQL variables");
103961 sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
103962 }
103963 }
103964
103965 /*
103966 ** Recursively delete an expression tree.
@@ -105056,12 +105799,11 @@
105799 assert( !ExprUseYWin(pExpr) );
105800 ExprSetProperty(pExpr, EP_Subrtn);
105801 assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
105802 pExpr->y.sub.regReturn = ++pParse->nMem;
105803 pExpr->y.sub.iAddr =
105804 sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
 
105805
105806 addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
105807 }
105808
105809 /* Check to see if this is a vector IN operator */
@@ -105159,10 +105901,11 @@
105901 ** disable the test that was generated above that makes sure
105902 ** this code only executes once. Because for a non-constant
105903 ** expression we need to rerun this code each time.
105904 */
105905 if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
105906 sqlite3VdbeChangeToNoop(v, addrOnce-1);
105907 sqlite3VdbeChangeToNoop(v, addrOnce);
105908 ExprClearProperty(pExpr, EP_Subrtn);
105909 addrOnce = 0;
105910 }
105911
@@ -105179,11 +105922,14 @@
105922 }
105923 if( addrOnce ){
105924 sqlite3VdbeJumpHere(v, addrOnce);
105925 /* Subroutine return */
105926 assert( ExprUseYSub(pExpr) );
105927 assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
105928 || pParse->nErr );
105929 sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
105930 pExpr->y.sub.iAddr-1);
105931 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105932 sqlite3ClearTempRegCache(pParse);
105933 }
105934 }
105935 #endif /* SQLITE_OMIT_SUBQUERY */
@@ -105234,13 +105980,11 @@
105980 assert( !ExprUseYWin(pExpr) );
105981 assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
105982 ExprSetProperty(pExpr, EP_Subrtn);
105983 pExpr->y.sub.regReturn = ++pParse->nMem;
105984 pExpr->y.sub.iAddr =
105985 sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
 
 
105986
105987 /* The evaluation of the EXISTS/SELECT must be repeated every time it
105988 ** is encountered if any of the following is true:
105989 **
105990 ** * The right-hand side is a correlated subquery
@@ -105309,11 +106053,14 @@
106053 sqlite3VdbeJumpHere(v, addrOnce);
106054 }
106055
106056 /* Subroutine return */
106057 assert( ExprUseYSub(pExpr) );
106058 assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
106059 || pParse->nErr );
106060 sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
106061 pExpr->y.sub.iAddr-1);
106062 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
106063 sqlite3ClearTempRegCache(pParse);
106064 return rReg;
106065 }
106066 #endif /* SQLITE_OMIT_SUBQUERY */
@@ -105515,11 +106262,10 @@
106262 if( destIfNull==destIfFalse ){
106263 destStep2 = destIfFalse;
106264 }else{
106265 destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
106266 }
 
106267 for(i=0; i<nVector; i++){
106268 Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
106269 if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error;
106270 if( sqlite3ExprCanBeNull(p) ){
106271 sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
@@ -105656,15 +106402,16 @@
106402 const char *z = pExpr->u.zToken;
106403 assert( z!=0 );
106404 c = sqlite3DecOrHexToI64(z, &value);
106405 if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
106406 #ifdef SQLITE_OMIT_FLOATING_POINT
106407 sqlite3ErrorMsg(pParse, "oversized integer: %s%#T", negFlag?"-":"",pExpr);
106408 #else
106409 #ifndef SQLITE_OMIT_HEX_INTEGER
106410 if( sqlite3_strnicmp(z,"0x",2)==0 ){
106411 sqlite3ErrorMsg(pParse, "hex literal too big: %s%#T",
106412 negFlag?"-":"",pExpr);
106413 }else
106414 #endif
106415 {
106416 codeReal(v, z, negFlag, iMem);
106417 }
@@ -106336,11 +107083,11 @@
107083 if( pInfo==0
107084 || NEVER(pExpr->iAgg<0)
107085 || NEVER(pExpr->iAgg>=pInfo->nFunc)
107086 ){
107087 assert( !ExprHasProperty(pExpr, EP_IntValue) );
107088 sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr);
107089 }else{
107090 return pInfo->aFunc[pExpr->iAgg].iMem;
107091 }
107092 break;
107093 }
@@ -106377,11 +107124,11 @@
107124 if( pDef==0 && pParse->explain ){
107125 pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
107126 }
107127 #endif
107128 if( pDef==0 || pDef->xFinalize!=0 ){
107129 sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr);
107130 break;
107131 }
107132 if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
107133 assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
107134 assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
@@ -109000,11 +109747,11 @@
109747 if( !zOld ) goto exit_rename_column;
109748 for(iCol=0; iCol<pTab->nCol; iCol++){
109749 if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break;
109750 }
109751 if( iCol==pTab->nCol ){
109752 sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld);
109753 goto exit_rename_column;
109754 }
109755
109756 /* Ensure the schema contains no double-quoted strings */
109757 renameTestSchema(pParse, zDb, iSchema==1, "", 0);
@@ -109430,16 +110177,16 @@
110177 ){
110178 const char *zT = (const char*)sqlite3_value_text(pType);
110179 const char *zN = (const char*)sqlite3_value_text(pObject);
110180 char *zErr;
110181
110182 zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s",
110183 zT, zN, (zWhen[0] ? " " : ""), zWhen,
110184 pParse->zErrMsg
110185 );
110186 sqlite3_result_error(pCtx, zErr, -1);
110187 sqlite3DbFree(pParse->db, zErr);
110188 }
110189
110190 /*
110191 ** For each name in the the expression-list pEList (i.e. each
110192 ** pEList->a[i].zName) that matches the string in zOld, extract the
@@ -109500,23 +110247,25 @@
110247 const char *zSql, /* SQL to parse */
110248 int bTemp /* True if SQL is from temp schema */
110249 ){
110250 int rc;
110251
 
 
 
 
 
110252 sqlite3ParseObjectInit(p, db);
110253 if( zSql==0 ){
110254 return SQLITE_NOMEM;
110255 }
110256 if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){
110257 return SQLITE_CORRUPT_BKPT;
110258 }
110259 db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
110260 p->eParseMode = PARSE_MODE_RENAME;
110261 p->db = db;
110262 p->nQueryLoop = 1;
110263 rc = sqlite3RunParser(p, zSql);
110264 if( db->mallocFailed ) rc = SQLITE_NOMEM;
110265 if( rc==SQLITE_OK
110266 && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0)
110267 ){
110268 rc = SQLITE_CORRUPT_BKPT;
110269 }
110270
110271 #ifdef SQLITE_DEBUG
@@ -109796,11 +110545,11 @@
110545 }
110546
110547 /*
110548 ** SQL function:
110549 **
110550 ** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP)
110551 **
110552 ** 0. zSql: SQL statement to rewrite
110553 ** 1. type: Type of object ("table", "view" etc.)
110554 ** 2. object: Name of object
110555 ** 3. Database: Database name (e.g. "main")
@@ -109814,11 +110563,12 @@
110563 ** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
110564 ** into zNew. The name should be quoted if bQuote is true.
110565 **
110566 ** This function is used internally by the ALTER TABLE RENAME COLUMN command.
110567 ** It is only accessible to SQL created using sqlite3NestedParse(). It is
110568 ** not reachable from ordinary SQL passed into sqlite3_prepare() unless the
110569 ** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled.
110570 */
110571 static void renameColumnFunc(
110572 sqlite3_context *context,
110573 int NotUsed,
110574 sqlite3_value **argv
@@ -109963,11 +110713,13 @@
110713 assert( rc==SQLITE_OK );
110714 rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);
110715
110716 renameColumnFunc_done:
110717 if( rc!=SQLITE_OK ){
110718 if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){
110719 sqlite3_result_value(context, argv[0]);
110720 }else if( sParse.zErrMsg ){
110721 renameColumnParseError(context, "", argv[1], argv[2], &sParse);
110722 }else{
110723 sqlite3_result_error_code(context, rc);
110724 }
110725 }
@@ -110162,11 +110914,13 @@
110914
110915 if( rc==SQLITE_OK ){
110916 rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
110917 }
110918 if( rc!=SQLITE_OK ){
110919 if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){
110920 sqlite3_result_value(context, argv[3]);
110921 }else if( sParse.zErrMsg ){
110922 renameColumnParseError(context, "", argv[1], argv[2], &sParse);
110923 }else{
110924 sqlite3_result_error_code(context, rc);
110925 }
110926 }
@@ -110187,14 +110941,14 @@
110941 renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr);
110942 }
110943 return WRC_Continue;
110944 }
110945
110946 /* SQL function: sqlite_rename_quotefix(DB,SQL)
110947 **
110948 ** Rewrite the DDL statement "SQL" so that any string literals that use
110949 ** double-quotes use single quotes instead.
110950 **
110951 ** Two arguments must be passed:
110952 **
110953 ** 0: Database name ("main", "temp" etc.).
110954 ** 1: SQL statement to edit.
@@ -110209,10 +110963,14 @@
110963 ** );
110964 **
110965 ** returns the string:
110966 **
110967 ** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1
110968 **
110969 ** If there is a error in the input SQL, then raise an error, except
110970 ** if PRAGMA writable_schema=ON, then just return the input string
110971 ** unmodified following an error.
110972 */
110973 static void renameQuotefixFunc(
110974 sqlite3_context *context,
110975 int NotUsed,
110976 sqlite3_value **argv
@@ -110283,11 +111041,15 @@
111041 rc = renameEditSql(context, &sCtx, zInput, 0, 0);
111042 }
111043 renameTokenFree(db, sCtx.pList);
111044 }
111045 if( rc!=SQLITE_OK ){
111046 if( sqlite3WritableSchema(db) && rc==SQLITE_ERROR ){
111047 sqlite3_result_value(context, argv[1]);
111048 }else{
111049 sqlite3_result_error_code(context, rc);
111050 }
111051 }
111052 renameParseCleanup(&sParse);
111053 }
111054
111055 #ifndef SQLITE_OMIT_AUTHORIZATION
@@ -110295,11 +111057,12 @@
111057 #endif
111058
111059 sqlite3BtreeLeaveAll(db);
111060 }
111061
111062 /* Function: sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS)
111063 **
111064 ** An SQL user function that checks that there are no parse or symbol
111065 ** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
111066 ** After an ALTER TABLE .. RENAME operation is performed and the schema
111067 ** reloaded, this function is called on each SQL statement in the schema
111068 ** to ensure that it is still usable.
@@ -110310,15 +111073,17 @@
111073 ** 3: Object name.
111074 ** 4: True if object is from temp schema.
111075 ** 5: "when" part of error message.
111076 ** 6: True to disable the DQS quirk when parsing SQL.
111077 **
111078 ** The return value is computed as follows:
 
111079 **
111080 ** A. If an error is seen and not in PRAGMA writable_schema=ON mode,
111081 ** then raise the error.
111082 ** B. Else if a trigger is created and the the table that the trigger is
111083 ** attached to is in database zDb, then return 1.
111084 ** C. Otherwise return NULL.
111085 */
111086 static void renameTableTest(
111087 sqlite3_context *context,
111088 int NotUsed,
111089 sqlite3_value **argv
@@ -110359,16 +111124,20 @@
111124 rc = renameResolveTrigger(&sParse);
111125 }
111126 if( rc==SQLITE_OK ){
111127 int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
111128 int i2 = sqlite3FindDbName(db, zDb);
111129 if( i1==i2 ){
111130 /* Handle output case B */
111131 sqlite3_result_int(context, 1);
111132 }
111133 }
111134 }
111135 }
111136
111137 if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){
111138 /* Output case A */
111139 renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse);
111140 }
111141 renameParseCleanup(&sParse);
111142 }
111143
@@ -110480,11 +111249,11 @@
111249 assert( db->mallocFailed );
111250 goto exit_drop_column;
111251 }
111252 iCol = sqlite3ColumnIndex(pTab, zCol);
111253 if( iCol<0 ){
111254 sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName);
111255 goto exit_drop_column;
111256 }
111257
111258 /* Do not allow the user to drop a PRIMARY KEY column or a column
111259 ** constrained by a UNIQUE constraint. */
@@ -111633,11 +112402,11 @@
112402 if( pStat1==0 ) return;
112403 pStat1->zName = (char*)&pStat1[1];
112404 memcpy(pStat1->zName, "sqlite_stat1", 13);
112405 pStat1->nCol = 3;
112406 pStat1->iPKey = -1;
112407 sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNAMIC);
112408 }
112409 #endif
112410
112411 /* Establish a read-lock on the table at the shared-cache level.
112412 ** Open a read-only cursor on the table. Also allocate a cursor number
@@ -113629,11 +114398,13 @@
114398 && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr)
114399 ){
114400 int iDb, i;
114401 assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
114402 sqlite3VdbeJumpHere(v, 0);
114403 assert( db->nDb>0 );
114404 iDb = 0;
114405 do{
114406 Schema *pSchema;
114407 if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
114408 sqlite3VdbeUsesBtree(v, iDb);
114409 pSchema = db->aDb[iDb].pSchema;
114410 sqlite3VdbeAddOp4Int(v,
@@ -113644,11 +114415,11 @@
114415 pSchema->iGeneration /* P4 */
114416 );
114417 if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
114418 VdbeComment((v,
114419 "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
114420 }while( ++iDb<db->nDb );
114421 #ifndef SQLITE_OMIT_VIRTUALTABLE
114422 for(i=0; i<pParse->nVtabLock; i++){
114423 char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
114424 sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
114425 }
@@ -113748,10 +114519,12 @@
114519 pParse->nested++;
114520 memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
114521 memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
114522 db->mDbFlags |= DBFLAG_PreferBuiltin;
114523 sqlite3RunParser(pParse, zSql);
114524 sqlite3DbFree(db, pParse->zErrMsg);
114525 pParse->zErrMsg = 0;
114526 db->mDbFlags = savedDbFlags;
114527 sqlite3DbFree(db, zSql);
114528 memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
114529 pParse->nested--;
114530 }
@@ -114708,11 +115481,12 @@
115481 goto begin_table_error;
115482 }
115483 pTable = sqlite3FindTable(db, zName, zDb);
115484 if( pTable ){
115485 if( !noErr ){
115486 sqlite3ErrorMsg(pParse, "%s %T already exists",
115487 (IsView(pTable)? "view" : "table"), pName);
115488 }else{
115489 assert( !db->init.busy || CORRUPT_DB );
115490 sqlite3CodeVerifySchema(pParse, iDb);
115491 sqlite3ForceNotReadOnly(pParse);
115492 }
@@ -116238,10 +117012,15 @@
117012 int regRec; /* A record to be insert into the new table */
117013 int regRowid; /* Rowid of the next row to insert */
117014 int addrInsLoop; /* Top of the loop for inserting rows */
117015 Table *pSelTab; /* A table that describes the SELECT results */
117016
117017 if( IN_SPECIAL_PARSE ){
117018 pParse->rc = SQLITE_ERROR;
117019 pParse->nErr++;
117020 return;
117021 }
117022 regYield = ++pParse->nMem;
117023 regRec = ++pParse->nMem;
117024 regRowid = ++pParse->nMem;
117025 assert(pParse->nTab==1);
117026 sqlite3MayAbort(pParse);
@@ -120069,11 +120848,11 @@
120848 **
120849 ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
120850 ** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
120851 ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
120852 */
120853 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1);
120854 if( pWInfo==0 ) goto delete_from_cleanup;
120855 eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
120856 assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
120857 assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
120858 if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
@@ -120682,10 +121461,11 @@
121461 static void subtypeFunc(
121462 sqlite3_context *context,
121463 int argc,
121464 sqlite3_value **argv
121465 ){
121466 UNUSED_PARAMETER(argc);
121467 sqlite3_result_int(context, sqlite3_value_subtype(argv[0]));
121468 }
121469
121470 /*
121471 ** Implementation of the length() function
@@ -121695,12 +122475,13 @@
122475 UNUSED_PARAMETER(argc);
122476 sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
122477 sqlite3QuoteValue(&str,argv[0]);
122478 sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar,
122479 SQLITE_DYNAMIC);
122480 if( str.accError!=SQLITE_OK ){
122481 sqlite3_result_null(context);
122482 sqlite3_result_error_code(context, str.accError);
122483 }
122484 }
122485
122486 /*
122487 ** The unicode() function. Return the integer unicode code-point value
@@ -122815,12 +123596,12 @@
123596 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
123597 INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
123598 INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
123599 INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
123600 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
123601 {1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF,
123602 0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} },
123603 #endif
123604 FUNCTION(ltrim, 1, 1, 0, trimFunc ),
123605 FUNCTION(ltrim, 2, 1, 0, trimFunc ),
123606 FUNCTION(rtrim, 1, 2, 0, trimFunc ),
123607 FUNCTION(rtrim, 2, 2, 0, trimFunc ),
@@ -123612,11 +124393,11 @@
124393
124394 /* Create VDBE to loop through the entries in pSrc that match the WHERE
124395 ** clause. For each row found, increment either the deferred or immediate
124396 ** foreign key constraint counter. */
124397 if( pParse->nErr==0 ){
124398 pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0, 0);
124399 sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
124400 if( pWInfo ){
124401 sqlite3WhereEnd(pWInfo);
124402 }
124403 }
@@ -124620,11 +125401,11 @@
125401 sqlite3OomFault(db);
125402 return;
125403 }
125404
125405 for(i=j=0; i<pTab->nCol; i++){
125406 assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 );
125407 if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){
125408 zColAff[j++] = pTab->aCol[i].affinity;
125409 }
125410 }
125411 do{
@@ -125234,11 +126015,15 @@
126015 ** Then special optimizations can be applied that make the transfer
126016 ** very fast and which reduce fragmentation of indices.
126017 **
126018 ** This is the 2nd template.
126019 */
126020 if( pColumn==0
126021 && pSelect!=0
126022 && pTrigger==0
126023 && xferOptimization(pParse, pTab, pSelect, onError, iDb)
126024 ){
126025 assert( !pTrigger );
126026 assert( pList==0 );
126027 goto insert_end;
126028 }
126029 #endif /* SQLITE_OMIT_XFER_OPT */
@@ -126717,11 +127502,11 @@
127502 }
127503 }
127504 if( isUpdate ){
127505 /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
127506 ** table, only conflict if the new PRIMARY KEY values are actually
127507 ** different from the old. See TH3 withoutrowid04.test.
127508 **
127509 ** For a UNIQUE index, only conflict if the PRIMARY KEY values
127510 ** of the matched index row are different from the original PRIMARY
127511 ** KEY values of this row before the update. */
127512 int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
@@ -127205,22 +127990,17 @@
127990 Vdbe *v; /* The VDBE we are building */
127991 int regAutoinc; /* Memory register used by AUTOINC */
127992 int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
127993 int regData, regRowid; /* Registers holding data and rowid */
127994
127995 assert( pSelect!=0 );
 
 
127996 if( pParse->pWith || pSelect->pWith ){
127997 /* Do not attempt to process this query if there are an WITH clauses
127998 ** attached to it. Proceeding may generate a false "no such table: xxx"
127999 ** error if pSelect reads from a CTE named "xxx". */
128000 return 0;
128001 }
 
 
 
128002 #ifndef SQLITE_OMIT_VIRTUALTABLE
128003 if( IsVirtual(pDest) ){
128004 return 0; /* tab1 must not be a virtual table */
128005 }
128006 #endif
@@ -128083,10 +128863,18 @@
128863 void*, void(*)(void*));
128864 /* Version 3.38.0 and later */
128865 int (*error_offset)(sqlite3*);
128866 int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
128867 int (*vtab_distinct)(sqlite3_index_info*);
128868 int (*vtab_in)(sqlite3_index_info*,int,int);
128869 int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
128870 int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
128871 /* Version 3.39.0 and later */
128872 int (*deserialize)(sqlite3*,const char*,unsigned char*,
128873 sqlite3_int64,sqlite3_int64,unsigned);
128874 unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
128875 unsigned int);
128876 };
128877
128878 /*
128879 ** This is the function signature used for all extension entry points. It
128880 ** is also defined in the file "loadext.c".
@@ -128398,10 +129186,17 @@
129186 #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
129187 /* Version 3.38.0 and later */
129188 #define sqlite3_error_offset sqlite3_api->error_offset
129189 #define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
129190 #define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
129191 #define sqlite3_vtab_in sqlite3_api->vtab_in
129192 #define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
129193 #define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
129194 #ifndef SQLITE_OMIT_DESERIALIZE
129195 #define sqlite3_deserialize sqlite3_api->deserialize
129196 #define sqlite3_serialize sqlite3_api->serialize
129197 #endif
129198 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
129199
129200 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
129201 /* This case when the file really is being compiled as a loadable
129202 ** extension */
@@ -128891,10 +129686,21 @@
129686 sqlite3_autovacuum_pages,
129687 /* Version 3.38.0 and later */
129688 sqlite3_error_offset,
129689 sqlite3_vtab_rhs_value,
129690 sqlite3_vtab_distinct,
129691 sqlite3_vtab_in,
129692 sqlite3_vtab_in_first,
129693 sqlite3_vtab_in_next,
129694 /* Version 3.39.0 and later */
129695 #ifndef SQLITE_OMIT_DESERIALIZE
129696 sqlite3_deserialize,
129697 sqlite3_serialize
129698 #else
129699 0,
129700 0
129701 #endif
129702 };
129703
129704 /* True if x is the directory separator character
129705 */
129706 #if SQLITE_OS_WIN
@@ -129561,11 +130367,11 @@
130367 /* iArg: */ BTREE_DATA_VERSION },
130368 #endif
130369 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
130370 {/* zName: */ "database_list",
130371 /* ePragTyp: */ PragTyp_DATABASE_LIST,
130372 /* ePragFlg: */ PragFlg_Result0,
130373 /* ColNames: */ 47, 3,
130374 /* iArg: */ 0 },
130375 #endif
130376 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
130377 {/* zName: */ "default_cache_size",
@@ -130249,19 +131055,20 @@
131055 Vdbe *v, /* The prepared statement being created */
131056 FuncDef *p, /* A particular function definition */
131057 int isBuiltin, /* True if this is a built-in function */
131058 int showInternFuncs /* True if showing internal functions */
131059 ){
131060 u32 mask =
131061 SQLITE_DETERMINISTIC |
131062 SQLITE_DIRECTONLY |
131063 SQLITE_SUBTYPE |
131064 SQLITE_INNOCUOUS |
131065 SQLITE_FUNC_INTERNAL
131066 ;
131067 if( showInternFuncs ) mask = 0xffffffff;
131068 for(; p; p=p->pNext){
131069 const char *zType;
 
 
 
 
 
 
 
131070 static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" };
131071
131072 assert( SQLITE_FUNC_ENCMASK==0x3 );
131073 assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 );
131074 assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 );
@@ -130749,11 +131556,11 @@
131556 **
131557 ** Do N steps of incremental vacuuming on a database.
131558 */
131559 #ifndef SQLITE_OMIT_AUTOVACUUM
131560 case PragTyp_INCREMENTAL_VACUUM: {
131561 int iLimit = 0, addr;
131562 if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){
131563 iLimit = 0x7fffffff;
131564 }
131565 sqlite3BeginWriteOperation(pParse, 0, iDb);
131566 sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
@@ -133053,11 +133860,11 @@
133860 if( db->mallocFailed ){
133861 rc = SQLITE_NOMEM_BKPT;
133862 sqlite3ResetAllSchemasOfConnection(db);
133863 pDb = &db->aDb[iDb];
133864 }else
133865 if( rc==SQLITE_OK || ((db->flags&SQLITE_NoSchemaError) && rc!=SQLITE_NOMEM)){
133866 /* Hack: If the SQLITE_NoSchemaError flag is set, then consider
133867 ** the schema loaded, even if errors (other than OOM) occurred. In
133868 ** this situation the current sqlite3_prepare() operation will fail,
133869 ** but the following one will attempt to compile the supplied statement
133870 ** against whatever subset of the schema was loaded before the error
@@ -133324,10 +134131,11 @@
134131 memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
134132 assert( db->pParse!=pParse );
134133 pParse->pOuterParse = db->pParse;
134134 db->pParse = pParse;
134135 pParse->db = db;
134136 if( db->mallocFailed ) sqlite3ErrorMsg(pParse, "out of memory");
134137 }
134138
134139 /*
134140 ** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
134141 */
@@ -133350,11 +134158,11 @@
134158 sParse.pOuterParse = db->pParse;
134159 db->pParse = &sParse;
134160 sParse.db = db;
134161 sParse.pReprepare = pReprepare;
134162 assert( ppStmt && *ppStmt==0 );
134163 if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory");
134164 assert( sqlite3_mutex_held(db->mutex) );
134165
134166 /* For a long-term use prepared statement avoid the use of
134167 ** lookaside memory.
134168 */
@@ -133741,11 +134549,11 @@
134549 ** how to process the DISTINCT keyword, to simplify passing that information
134550 ** into the selectInnerLoop() routine.
134551 */
134552 typedef struct DistinctCtx DistinctCtx;
134553 struct DistinctCtx {
134554 u8 isTnct; /* 0: Not distinct. 1: DISTICT 2: DISTINCT and ORDER BY */
134555 u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */
134556 int tabTnct; /* Ephemeral table used for DISTINCT processing */
134557 int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */
134558 };
134559
@@ -134074,29 +134882,29 @@
134882 ** sqlite3PExpr(). */
134883 if( pEq && isOuterJoin ){
134884 ExprSetProperty(pEq, EP_FromJoin);
134885 assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
134886 ExprSetVVAProperty(pEq, EP_NoReduce);
134887 pEq->w.iRightJoinTable = pE2->iTable;
134888 }
134889 *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
134890 }
134891
134892 /*
134893 ** Set the EP_FromJoin property on all terms of the given expression.
134894 ** And set the Expr.w.iRightJoinTable to iTable for every term in the
134895 ** expression.
134896 **
134897 ** The EP_FromJoin property is used on terms of an expression to tell
134898 ** the LEFT OUTER JOIN processing logic that this term is part of the
134899 ** join restriction specified in the ON or USING clause and not a part
134900 ** of the more general WHERE clause. These terms are moved over to the
134901 ** WHERE clause during join processing but we need to remember that they
134902 ** originated in the ON or USING clause.
134903 **
134904 ** The Expr.w.iRightJoinTable tells the WHERE clause processing that the
134905 ** expression depends on table w.iRightJoinTable even if that table is not
134906 ** explicitly mentioned in the expression. That information is needed
134907 ** for cases like this:
134908 **
134909 ** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
134910 **
@@ -134110,11 +134918,11 @@
134918 SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){
134919 while( p ){
134920 ExprSetProperty(p, EP_FromJoin);
134921 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
134922 ExprSetVVAProperty(p, EP_NoReduce);
134923 p->w.iRightJoinTable = iTable;
134924 if( p->op==TK_FUNCTION ){
134925 assert( ExprUseXList(p) );
134926 if( p->x.pList ){
134927 int i;
134928 for(i=0; i<p->x.pList->nExpr; i++){
@@ -134126,19 +134934,19 @@
134934 p = p->pRight;
134935 }
134936 }
134937
134938 /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
134939 ** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into
134940 ** an ordinary term that omits the EP_FromJoin mark.
134941 **
134942 ** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
134943 */
134944 static void unsetJoinExpr(Expr *p, int iTable){
134945 while( p ){
134946 if( ExprHasProperty(p, EP_FromJoin)
134947 && (iTable<0 || p->w.iRightJoinTable==iTable) ){
134948 ExprClearProperty(p, EP_FromJoin);
134949 }
134950 if( p->op==TK_COLUMN && p->iTable==iTable ){
134951 ExprClearProperty(p, EP_CanBeNull);
134952 }
@@ -136343,11 +137151,11 @@
137151 ** (3) There is no ORDER BY clause
137152 **
137153 ** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
137154 ** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
137155 ** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
137156 ** Since the limit is exactly 1, we only need to evaluate the left-most VALUES.
137157 */
137158 static int multiSelectValues(
137159 Parse *pParse, /* Parsing context */
137160 Select *p, /* The right-most of SELECTs to be coded */
137161 SelectDest *pDest /* What to do with query results */
@@ -137368,13 +138176,13 @@
138176 SubstContext *pSubst, /* Description of the substitution */
138177 Expr *pExpr /* Expr in which substitution occurs */
138178 ){
138179 if( pExpr==0 ) return 0;
138180 if( ExprHasProperty(pExpr, EP_FromJoin)
138181 && pExpr->w.iRightJoinTable==pSubst->iTable
138182 ){
138183 pExpr->w.iRightJoinTable = pSubst->iNewTable;
138184 }
138185 if( pExpr->op==TK_COLUMN
138186 && pExpr->iTable==pSubst->iTable
138187 && !ExprHasProperty(pExpr, EP_FixedCol)
138188 ){
@@ -137409,11 +138217,11 @@
138217 }
138218 if( pSubst->isLeftJoin ){
138219 ExprSetProperty(pNew, EP_CanBeNull);
138220 }
138221 if( ExprHasProperty(pExpr,EP_FromJoin) ){
138222 sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable);
138223 }
138224 sqlite3ExprDelete(db, pExpr);
138225 pExpr = pNew;
138226
138227 /* Ensure that the expression now has an implicit collation sequence,
@@ -137574,11 +138382,11 @@
138382 int op = pExpr->op;
138383 if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
138384 renumberCursorDoMapping(pWalker, &pExpr->iTable);
138385 }
138386 if( ExprHasProperty(pExpr, EP_FromJoin) ){
138387 renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable);
138388 }
138389 return WRC_Continue;
138390 }
138391
138392 /*
@@ -138584,15 +139392,17 @@
139392 iCursor, isLeftJoin);
139393 pWhere = pWhere->pLeft;
139394 }
139395 if( isLeftJoin
139396 && (ExprHasProperty(pWhere,EP_FromJoin)==0
139397 || pWhere->w.iRightJoinTable!=iCursor)
139398 ){
139399 return 0; /* restriction (4) */
139400 }
139401 if( ExprHasProperty(pWhere,EP_FromJoin)
139402 && pWhere->w.iRightJoinTable!=iCursor
139403 ){
139404 return 0; /* restriction (5) */
139405 }
139406 if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
139407 nChng++;
139408 pSubq->selFlags |= SF_PushDown;
@@ -140539,10 +141349,11 @@
141349 p->selFlags |= SF_Aggregate;
141350 /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
141351 ** the sDistinct.isTnct is still set. Hence, isTnct represents the
141352 ** original setting of the SF_Distinct flag, not the current setting */
141353 assert( sDistinct.isTnct );
141354 sDistinct.isTnct = 2;
141355
141356 #if SELECTTRACE_ENABLED
141357 if( sqlite3SelectTrace & 0x400 ){
141358 SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
141359 sqlite3TreeViewSelect(0, p, 0);
@@ -140618,11 +141429,11 @@
141429
141430
141431 /* Begin the database scan. */
141432 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
141433 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
141434 p->pEList, p, wctrlFlags, p->nSelectRow);
141435 if( pWInfo==0 ) goto select_end;
141436 if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
141437 p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
141438 }
141439 if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
@@ -140882,11 +141693,12 @@
141693 ** in the right order to begin with.
141694 */
141695 sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
141696 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
141697 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct,
141698 0, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY)
141699 | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
141700 );
141701 if( pWInfo==0 ){
141702 sqlite3ExprListDelete(db, pDistinct);
141703 goto select_end;
141704 }
@@ -141064,11 +141876,11 @@
141876 resetAccumulator(pParse, pAggInfo);
141877 sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
141878 VdbeComment((v, "indicate accumulator empty"));
141879 sqlite3VdbeAddOp1(v, OP_Return, regReset);
141880
141881 if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){
141882 struct AggInfo_func *pF = &pAggInfo->aFunc[0];
141883 fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
141884 }
141885 } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
141886 else {
@@ -141180,11 +141992,11 @@
141992 assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
141993 assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
141994
141995 SELECTTRACE(1,pParse,p,("WhereBegin\n"));
141996 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
141997 pDistinct, 0, minMaxFlag|distFlag, 0);
141998 if( pWInfo==0 ){
141999 goto select_end;
142000 }
142001 SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
142002 eDist = sqlite3WhereIsDistinct(pWInfo);
@@ -141538,15 +142350,14 @@
142350 && 0==sqlite3StrICmp(pTrig->table, pTab->zName)
142351 && pTrig->pTabSchema!=pTmpSchema
142352 ){
142353 pTrig->pNext = pList;
142354 pList = pTrig;
142355 }else if( pTrig->op==TK_RETURNING ){
142356 #ifndef SQLITE_OMIT_VIRTUALTABLE
142357 assert( pParse->db->pVtabCtx==0 );
142358 #endif
 
142359 assert( pParse->bReturning );
142360 assert( &(pParse->u1.pReturning->retTrig) == pTrig );
142361 pTrig->table = pTab->zName;
142362 pTrig->pTabSchema = pTab->pSchema;
142363 pTrig->pNext = pList;
@@ -141917,10 +142728,11 @@
142728 const char *zEnd /* End of SQL text */
142729 ){
142730 sqlite3 *db = pParse->db;
142731 TriggerStep *pTriggerStep;
142732
142733 if( pParse->nErr ) return 0;
142734 pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
142735 if( pTriggerStep ){
142736 char *z = (char*)&pTriggerStep[1];
142737 memcpy(z, pName->z, pName->n);
142738 sqlite3Dequote(z);
@@ -142707,10 +143519,11 @@
143519 );
143520
143521 /* If an existing TriggerPrg could not be located, create a new one. */
143522 if( !pPrg ){
143523 pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
143524 pParse->db->errByteOffset = -1;
143525 }
143526
143527 return pPrg;
143528 }
143529
@@ -143623,11 +144436,11 @@
144436 ** or index, causing a single-pass approach to malfunction. */
144437 flags = WHERE_ONEPASS_DESIRED;
144438 if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
144439 flags |= WHERE_ONEPASS_MULTIROW;
144440 }
144441 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
144442 if( pWInfo==0 ) goto update_cleanup;
144443
144444 /* A one-pass strategy that might update more than one row may not
144445 ** be used if any column of the index used for the scan is being
144446 ** updated. Otherwise, if there is an index on "b", statements like
@@ -144145,11 +144958,13 @@
144958 }else{
144959 regRec = ++pParse->nMem;
144960 regRowid = ++pParse->nMem;
144961
144962 /* Start scanning the virtual table */
144963 pWInfo = sqlite3WhereBegin(
144964 pParse, pSrc, pWhere, 0, 0, 0, WHERE_ONEPASS_DESIRED, 0
144965 );
144966 if( pWInfo==0 ) return;
144967
144968 /* Populate the argument registers. */
144969 for(i=0; i<pTab->nCol; i++){
144970 assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 );
@@ -145792,10 +146607,11 @@
146607 pTab = pCtx->pTab;
146608 assert( IsVirtual(pTab) );
146609
146610 sqlite3ParseObjectInit(&sParse, db);
146611 sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
146612 sParse.disableTriggers = 1;
146613 /* We should never be able to reach this point while loading the
146614 ** schema. Nevertheless, defend against that (turn off db->init.busy)
146615 ** in case a bug arises. */
146616 assert( db->init.busy==0 );
146617 initBusy = db->init.busy;
@@ -146456,14 +147272,16 @@
147272 u16 nDistinctCol; /* Index columns used to sort for DISTINCT */
147273 Index *pIndex; /* Index used, or NULL */
147274 } btree;
147275 struct { /* Information for virtual tables */
147276 int idxNum; /* Index number */
147277 u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
147278 u32 bOmitOffset : 1; /* True to let virtual table handle offset */
147279 i8 isOrdered; /* True if satisfies ORDER BY */
147280 u16 omitMask; /* Terms that may be omitted */
147281 char *idxStr; /* Index identifier string */
147282 u32 mHandleIn; /* Terms to handle as IN(...) instead of == */
147283 } vtab;
147284 } u;
147285 u32 wsFlags; /* WHERE_* flags describing the plan */
147286 u16 nLTerm; /* Number of entries in aLTerm[] */
147287 u16 nSkip; /* Number of NULL aLTerm[] entries */
@@ -146616,10 +147434,11 @@
147434 #ifdef SQLITE_ENABLE_STAT4
147435 # define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */
147436 #else
147437 # define TERM_HIGHTRUTH 0 /* Only used with STAT4 */
147438 #endif
147439 #define TERM_SLICE 0x8000 /* One slice of a row-value/vector comparison */
147440
147441 /*
147442 ** An instance of the WhereScan object is used as an iterator for locating
147443 ** terms in the WHERE clause that are useful to the query planner.
147444 */
@@ -146786,10 +147605,13 @@
147605 Parse *pParse; /* Parsing and code generating context */
147606 SrcList *pTabList; /* List of tables in the join */
147607 ExprList *pOrderBy; /* The ORDER BY clause or NULL */
147608 ExprList *pResultSet; /* Result set of the query */
147609 Expr *pWhere; /* The complete WHERE clause */
147610 #ifndef SQLITE_OMIT_VIRTUALTABLE
147611 Select *pLimit; /* Used to access LIMIT expr/registers for vtabs */
147612 #endif
147613 int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
147614 int iContinue; /* Jump here to continue with next record */
147615 int iBreak; /* Jump here to break out of the loop */
147616 int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
147617 u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
@@ -146871,10 +147693,11 @@
147693
147694 /* whereexpr.c: */
147695 SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
147696 SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
147697 SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
147698 SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause*, Select*);
147699 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
147700 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
147701 SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
147702 SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
147703 SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
@@ -146941,10 +147764,11 @@
147764 #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
147765 #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
147766 #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
147767 #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
147768 #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
147769 #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */
147770
147771 #endif /* !defined(SQLITE_WHEREINT_H) */
147772
147773 /************** End of whereInt.h ********************************************/
147774 /************** Continuing where we left off in wherecode.c ******************/
@@ -147719,10 +148543,11 @@
148543 sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
148544 VdbeCoverageIf(v, bRev==0);
148545 VdbeCoverageIf(v, bRev!=0);
148546 VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
148547 j = sqlite3VdbeAddOp0(v, OP_Goto);
148548 assert( pLevel->addrSkip==0 );
148549 pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
148550 iIdxCur, 0, regBase, nSkip);
148551 VdbeCoverageIf(v, bRev==0);
148552 VdbeCoverageIf(v, bRev!=0);
148553 sqlite3VdbeJumpHere(v, j);
@@ -147989,11 +148814,11 @@
148814 ** are also excluded. See codeCursorHintIsOrFunction() for details.
148815 */
148816 if( pTabItem->fg.jointype & JT_LEFT ){
148817 Expr *pExpr = pTerm->pExpr;
148818 if( !ExprHasProperty(pExpr, EP_FromJoin)
148819 || pExpr->w.iRightJoinTable!=pTabItem->iCursor
148820 ){
148821 sWalker.eCode = 0;
148822 sWalker.xExprCallback = codeCursorHintIsOrFunction;
148823 sqlite3WalkExpr(&sWalker, pTerm->pExpr);
148824 if( sWalker.eCode ) continue;
@@ -148044,18 +148869,26 @@
148869 ** rowid stored in register iRowid.
148870 **
148871 ** Normally, this is just:
148872 **
148873 ** OP_DeferredSeek $iCur $iRowid
148874 **
148875 ** Which causes a seek on $iCur to the row with rowid $iRowid.
148876 **
148877 ** However, if the scan currently being coded is a branch of an OR-loop and
148878 ** the statement currently being coded is a SELECT, then additional information
148879 ** is added that might allow OP_Column to omit the seek and instead do its
148880 ** lookup on the index, thus avoiding an expensive seek operation. To
148881 ** enable this optimization, the P3 of OP_DeferredSeek is set to iIdxCur
148882 ** and P4 is set to an array of integers containing one entry for each column
148883 ** in the table. For each table column, if the column is the i'th
148884 ** column of the index, then the corresponding array entry is set to (i+1).
148885 ** If the column does not appear in the index at all, the array entry is set
148886 ** to 0. The OP_Column opcode can check this array to see if the column it
148887 ** wants is in the index and if it is, it will substitute the index cursor
148888 ** and column number and continue with those new values, rather than seeking
148889 ** the table cursor.
148890 */
148891 static void codeDeferredSeek(
148892 WhereInfo *pWInfo, /* Where clause context */
148893 Index *pIdx, /* Index scan is using */
148894 int iCur, /* Cursor for IPK b-tree */
@@ -148316,10 +149149,11 @@
149149 ){
149150 while( ++iLevel < pWInfo->nLevel ){
149151 WhereLevel *pLevel = &pWInfo->a[iLevel];
149152 WhereLoop *pLoop = pLevel->pWLoop;
149153 if( pLevel->regFilter==0 ) continue;
149154 if( pLevel->pWLoop->nSkip ) continue;
149155 /* ,--- Because sqlite3ConstructBloomFilter() has will not have set
149156 ** vvvvv--' pLevel->regFilter if this were true. */
149157 if( NEVER(pLoop->prereq & notReady) ) continue;
149158 if( pLoop->wsFlags & WHERE_IPK ){
149159 WhereTerm *pTerm = pLoop->aLTerm[0];
@@ -148450,24 +149284,39 @@
149284 ** to access the data.
149285 */
149286 int iReg; /* P3 Value for OP_VFilter */
149287 int addrNotFound;
149288 int nConstraint = pLoop->nLTerm;
 
149289
149290 iReg = sqlite3GetTempRange(pParse, nConstraint+2);
149291 addrNotFound = pLevel->addrBrk;
149292 for(j=0; j<nConstraint; j++){
149293 int iTarget = iReg+j+2;
149294 pTerm = pLoop->aLTerm[j];
149295 if( NEVER(pTerm==0) ) continue;
149296 if( pTerm->eOperator & WO_IN ){
149297 if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){
149298 int iTab = pParse->nTab++;
149299 int iCache = ++pParse->nMem;
149300 sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab);
149301 sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache);
149302 }else{
149303 codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
149304 addrNotFound = pLevel->addrNxt;
149305 }
149306 }else{
149307 Expr *pRight = pTerm->pExpr->pRight;
149308 codeExprOrVector(pParse, pRight, iTarget, 1);
149309 if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET
149310 && pLoop->u.vtab.bOmitOffset
149311 ){
149312 assert( pTerm->eOperator==WO_AUX );
149313 assert( pWInfo->pLimit!=0 );
149314 assert( pWInfo->pLimit->iOffset>0 );
149315 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset);
149316 VdbeComment((v,"Zero OFFSET counter"));
149317 }
149318 }
149319 }
149320 sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
149321 sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
149322 sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
@@ -148480,61 +149329,71 @@
149329 if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
149330 pLevel->p1 = iCur;
149331 pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
149332 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
149333 assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
149334
149335 for(j=0; j<nConstraint; j++){
 
 
 
 
149336 pTerm = pLoop->aLTerm[j];
 
149337 if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
149338 disableTerm(pLevel, pTerm);
149339 continue;
149340 }
149341 if( (pTerm->eOperator & WO_IN)!=0
149342 && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0
149343 && !db->mallocFailed
149344 ){
149345 Expr *pCompare; /* The comparison operator */
149346 Expr *pRight; /* RHS of the comparison */
149347 VdbeOp *pOp; /* Opcode to access the value of the IN constraint */
149348 int iIn; /* IN loop corresponding to the j-th constraint */
149349
149350 /* Reload the constraint value into reg[iReg+j+2]. The same value
149351 ** was loaded into the same register prior to the OP_VFilter, but
149352 ** the xFilter implementation might have changed the datatype or
149353 ** encoding of the value in the register, so it *must* be reloaded.
149354 */
149355 for(iIn=0; ALWAYS(iIn<pLevel->u.in.nIn); iIn++){
 
149356 pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop);
149357 if( (pOp->opcode==OP_Column && pOp->p3==iReg+j+2)
149358 || (pOp->opcode==OP_Rowid && pOp->p2==iReg+j+2)
149359 ){
149360 testcase( pOp->opcode==OP_Rowid );
149361 sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
149362 break;
149363 }
149364 }
149365
149366 /* Generate code that will continue to the next row if
149367 ** the IN constraint is not satisfied
149368 */
149369 pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
149370 if( !db->mallocFailed ){
149371 int iFld = pTerm->u.x.iField;
149372 Expr *pLeft = pTerm->pExpr->pLeft;
149373 assert( pLeft!=0 );
149374 if( iFld>0 ){
149375 assert( pLeft->op==TK_VECTOR );
149376 assert( ExprUseXList(pLeft) );
149377 assert( iFld<=pLeft->x.pList->nExpr );
149378 pCompare->pLeft = pLeft->x.pList->a[iFld-1].pExpr;
149379 }else{
149380 pCompare->pLeft = pLeft;
149381 }
149382 pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
149383 if( pRight ){
149384 pRight->iTable = iReg+j+2;
149385 sqlite3ExprIfFalse(
149386 pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL
149387 );
149388 }
149389 pCompare->pLeft = 0;
 
149390 }
149391 sqlite3ExprDelete(db, pCompare);
149392 }
149393 }
149394
149395 /* These registers need to be preserved in case there is an IN operator
149396 ** loop. So we could deallocate the registers here (and potentially
149397 ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
149398 ** simpler and safer to simply not reuse the registers.
149399 **
@@ -149222,11 +150081,11 @@
150081 regRowid = ++pParse->nMem;
150082 }
150083 iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
150084
150085 /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
150086 ** Then for every term xN, evaluate as the subexpression: xN AND y
150087 ** That way, terms in y that are factored into the disjunction will
150088 ** be picked up by the recursive calls to sqlite3WhereBegin() below.
150089 **
150090 ** Actually, each subexpression is converted to "xN AND w" where w is
150091 ** the "interesting" terms of z - terms that did not originate in the
@@ -149234,21 +150093,38 @@
150093 ** indices.
150094 **
150095 ** This optimization also only applies if the (x1 OR x2 OR ...) term
150096 ** is not contained in the ON clause of a LEFT JOIN.
150097 ** See ticket http://www.sqlite.org/src/info/f2369304e4
150098 **
150099 ** 2022-02-04: Do not push down slices of a row-value comparison.
150100 ** In other words, "w" or "y" may not be a slice of a vector. Otherwise,
150101 ** the initialization of the right-hand operand of the vector comparison
150102 ** might not occur, or might occur only in an OR branch that is not
150103 ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1.
150104 **
150105 ** 2022-03-03: Do not push down expressions that involve subqueries.
150106 ** The subquery might get coded as a subroutine. Any table-references
150107 ** in the subquery might be resolved to index-references for the index on
150108 ** the OR branch in which the subroutine is coded. But if the subroutine
150109 ** is invoked from a different OR branch that uses a different index, such
150110 ** index-references will not work. tag-20220303a
150111 ** https://sqlite.org/forum/forumpost/36937b197273d403
150112 */
150113 if( pWC->nTerm>1 ){
150114 int iTerm;
150115 for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
150116 Expr *pExpr = pWC->a[iTerm].pExpr;
150117 if( &pWC->a[iTerm] == pTerm ) continue;
150118 testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
150119 testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
150120 testcase( pWC->a[iTerm].wtFlags & TERM_SLICE );
150121 if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){
150122 continue;
150123 }
150124 if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
150125 if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */
150126 pExpr = sqlite3ExprDup(db, pExpr, 0);
150127 pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
150128 }
150129 if( pAndExpr ){
150130 /* The extra 0x10000 bit on the opcode is masked off and does not
@@ -149285,11 +150161,11 @@
150161 pOrExpr = pAndExpr;
150162 }
150163 /* Loop through table entries that match term pOrTerm. */
150164 ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
150165 WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
150166 pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0,
150167 WHERE_OR_SUBCLAUSE, iCovCur);
150168 assert( pSubWInfo || pParse->nErr );
150169 if( pSubWInfo ){
150170 WhereLoop *pSubLoop;
150171 int addrExplain = sqlite3WhereExplainOneScan(
@@ -150025,11 +150901,11 @@
150901 void *pNotUsed;
150902 pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
150903 assert( pVtab!=0 );
150904 assert( pVtab->pModule!=0 );
150905 assert( !ExprHasProperty(pExpr, EP_IntValue) );
150906 pMod = (sqlite3_module *)pVtab->pModule;
150907 if( pMod->xFindFunction!=0 ){
150908 i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
150909 if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
150910 *peOp2 = i;
150911 *ppRight = pList->a[1].pExpr;
@@ -150069,11 +150945,11 @@
150945 ** a join, then transfer the appropriate markings over to derived.
150946 */
150947 static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
150948 if( pDerived ){
150949 pDerived->flags |= pBase->flags & EP_FromJoin;
150950 pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable;
150951 }
150952 }
150953
150954 /*
150955 ** Mark term iChild as being a child of term iParent
@@ -150714,11 +151590,11 @@
151590 abort();
151591 }
151592 #endif
151593
151594 if( ExprHasProperty(pExpr, EP_FromJoin) ){
151595 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable);
151596 prereqAll |= x;
151597 extraRight = x-1; /* ON clause terms may not be used with an index
151598 ** on left table of a LEFT JOIN. Ticket #3015 */
151599 if( (prereqAll>>1)>=x ){
151600 sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
@@ -150982,11 +151858,14 @@
151858 ** new terms for each component comparison - "a = ?" and "b = ?". The
151859 ** new terms completely replace the original vector comparison, which is
151860 ** no longer used.
151861 **
151862 ** This is only required if at least one side of the comparison operation
151863 ** is not a sub-select.
151864 **
151865 ** tag-20220128a
151866 */
151867 if( (pExpr->op==TK_EQ || pExpr->op==TK_IS)
151868 && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
151869 && sqlite3ExprVectorSize(pExpr->pRight)==nLeft
151870 && ( (pExpr->pLeft->flags & EP_xIsSelect)==0
151871 || (pExpr->pRight->flags & EP_xIsSelect)==0)
@@ -150999,11 +151878,11 @@
151878 Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, nLeft);
151879 Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, nLeft);
151880
151881 pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
151882 transferJoinMarkings(pNew, pExpr);
151883 idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE);
151884 exprAnalyze(pSrc, pWC, idxNew);
151885 }
151886 pTerm = &pWC->a[idxTerm];
151887 pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
151888 pTerm->eOperator = 0;
@@ -151029,11 +151908,11 @@
151908 && pWC->op==TK_AND
151909 ){
151910 int i;
151911 for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
151912 int idxNew;
151913 idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE);
151914 pWC->a[idxNew].u.x.iField = i+1;
151915 exprAnalyze(pSrc, pWC, idxNew);
151916 markTermAsChild(pWC, idxNew, idxTerm);
151917 }
151918 }
@@ -151062,11 +151941,11 @@
151941 Expr *pNewExpr;
151942 pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
151943 0, sqlite3ExprDup(db, pRight, 0));
151944 if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
151945 ExprSetProperty(pNewExpr, EP_FromJoin);
151946 pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable;
151947 }
151948 idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
151949 testcase( idxNew==0 );
151950 pNewTerm = &pWC->a[idxNew];
151951 pNewTerm->prereqRight = prereqExpr;
@@ -151124,10 +152003,117 @@
152003 }else{
152004 sqlite3WhereSplit(pWC, pE2->pLeft, op);
152005 sqlite3WhereSplit(pWC, pE2->pRight, op);
152006 }
152007 }
152008
152009 /*
152010 ** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or
152011 ** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the
152012 ** where-clause passed as the first argument. The value for the term
152013 ** is found in register iReg.
152014 **
152015 ** In the common case where the value is a simple integer
152016 ** (example: "LIMIT 5 OFFSET 10") then the expression codes as a
152017 ** TK_INTEGER so that it will be available to sqlite3_vtab_rhs_value().
152018 ** If not, then it codes as a TK_REGISTER expression.
152019 */
152020 static void whereAddLimitExpr(
152021 WhereClause *pWC, /* Add the constraint to this WHERE clause */
152022 int iReg, /* Register that will hold value of the limit/offset */
152023 Expr *pExpr, /* Expression that defines the limit/offset */
152024 int iCsr, /* Cursor to which the constraint applies */
152025 int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */
152026 ){
152027 Parse *pParse = pWC->pWInfo->pParse;
152028 sqlite3 *db = pParse->db;
152029 Expr *pNew;
152030 int iVal = 0;
152031
152032 if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){
152033 Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0);
152034 if( pVal==0 ) return;
152035 ExprSetProperty(pVal, EP_IntValue);
152036 pVal->u.iValue = iVal;
152037 pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
152038 }else{
152039 Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0);
152040 if( pVal==0 ) return;
152041 pVal->iTable = iReg;
152042 pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal);
152043 }
152044 if( pNew ){
152045 WhereTerm *pTerm;
152046 int idx;
152047 idx = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_VIRTUAL);
152048 pTerm = &pWC->a[idx];
152049 pTerm->leftCursor = iCsr;
152050 pTerm->eOperator = WO_AUX;
152051 pTerm->eMatchOp = eMatchOp;
152052 }
152053 }
152054
152055 /*
152056 ** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the
152057 ** SELECT statement passed as the second argument. These terms are only
152058 ** added if:
152059 **
152060 ** 1. The SELECT statement has a LIMIT clause, and
152061 ** 2. The SELECT statement is not an aggregate or DISTINCT query, and
152062 ** 3. The SELECT statement has exactly one object in its from clause, and
152063 ** that object is a virtual table, and
152064 ** 4. There are no terms in the WHERE clause that will not be passed
152065 ** to the virtual table xBestIndex method.
152066 ** 5. The ORDER BY clause, if any, will be made available to the xBestIndex
152067 ** method.
152068 **
152069 ** LIMIT and OFFSET terms are ignored by most of the planner code. They
152070 ** exist only so that they may be passed to the xBestIndex method of the
152071 ** single virtual table in the FROM clause of the SELECT.
152072 */
152073 SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
152074 assert( p==0 || (p->pGroupBy==0 && (p->selFlags & SF_Aggregate)==0) );
152075 if( (p && p->pLimit) /* 1 */
152076 && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */
152077 && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */
152078 ){
152079 ExprList *pOrderBy = p->pOrderBy;
152080 int iCsr = p->pSrc->a[0].iCursor;
152081 int ii;
152082
152083 /* Check condition (4). Return early if it is not met. */
152084 for(ii=0; ii<pWC->nTerm; ii++){
152085 if( pWC->a[ii].wtFlags & TERM_CODED ){
152086 /* This term is a vector operation that has been decomposed into
152087 ** other, subsequent terms. It can be ignored. See tag-20220128a */
152088 assert( pWC->a[ii].wtFlags & TERM_VIRTUAL );
152089 assert( pWC->a[ii].eOperator==0 );
152090 continue;
152091 }
152092 if( pWC->a[ii].leftCursor!=iCsr ) return;
152093 }
152094
152095 /* Check condition (5). Return early if it is not met. */
152096 if( pOrderBy ){
152097 for(ii=0; ii<pOrderBy->nExpr; ii++){
152098 Expr *pExpr = pOrderBy->a[ii].pExpr;
152099 if( pExpr->op!=TK_COLUMN ) return;
152100 if( pExpr->iTable!=iCsr ) return;
152101 if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return;
152102 }
152103 }
152104
152105 /* All conditions are met. Add the terms to the where-clause object. */
152106 assert( p->pLimit->op==TK_LIMIT );
152107 whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft,
152108 iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT);
152109 if( p->iOffset>0 ){
152110 whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight,
152111 iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET);
152112 }
152113 }
152114 }
152115
152116 /*
152117 ** Initialize a preallocated WhereClause structure.
152118 */
152119 SQLITE_PRIVATE void sqlite3WhereClauseInit(
@@ -151160,10 +152146,11 @@
152146 for(i=pWC->nBase; i<pWC->nTerm; i++){
152147 assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 );
152148 }
152149 #endif
152150 while(1){
152151 assert( a->eMatchOp==0 || a->eOperator==WO_AUX );
152152 if( a->wtFlags & TERM_DYNAMIC ){
152153 sqlite3ExprDelete(db, a->pExpr);
152154 }
152155 if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){
152156 if( a->wtFlags & TERM_ORINFO ){
@@ -151317,10 +152304,11 @@
152304 if( pColRef==0 ) return;
152305 pColRef->iTable = pItem->iCursor;
152306 pColRef->iColumn = k++;
152307 assert( ExprUseYTab(pColRef) );
152308 pColRef->y.pTab = pTab;
152309 pItem->colUsed |= sqlite3ExprColUsed(pColRef);
152310 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
152311 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
152312 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
152313 if( pItem->fg.jointype & JT_LEFT ){
152314 sqlite3SetJoinExpr(pTerm, pItem->iCursor);
@@ -151364,10 +152352,12 @@
152352 typedef struct HiddenIndexInfo HiddenIndexInfo;
152353 struct HiddenIndexInfo {
152354 WhereClause *pWC; /* The Where clause being analyzed */
152355 Parse *pParse; /* The parsing context */
152356 int eDistinct; /* Value to return from sqlite3_vtab_distinct() */
152357 u32 mIn; /* Mask of terms that are <col> IN (...) */
152358 u32 mHandleIn; /* Terms that vtab will handle as <col> IN (...) */
152359 sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST
152360 ** because extra space is allocated to hold up
152361 ** to nTerm such values */
152362 };
152363
@@ -152407,11 +153397,14 @@
153397 VdbeCoverage(v);
153398 sqlite3VdbeJumpHere(v, addrTop);
153399 pLoop->wsFlags &= ~WHERE_BLOOMFILTER;
153400 if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
153401 while( ++iLevel < pWInfo->nLevel ){
153402 const SrcItem *pTabItem;
153403 pLevel = &pWInfo->a[iLevel];
153404 pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
153405 if( pTabItem->fg.jointype & JT_LEFT ) continue;
153406 pLoop = pLevel->pWLoop;
153407 if( NEVER(pLoop==0) ) continue;
153408 if( pLoop->prereq & notReady ) continue;
153409 if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN))
153410 ==WHERE_BLOOMFILTER
@@ -152474,10 +153467,11 @@
153467 testcase( pTerm->eOperator & WO_ISNULL );
153468 testcase( pTerm->eOperator & WO_IS );
153469 testcase( pTerm->eOperator & WO_ALL );
153470 if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
153471 if( pTerm->wtFlags & TERM_VNULL ) continue;
153472
153473 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
153474 assert( pTerm->u.x.leftColumn>=XN_ROWID );
153475 assert( pTerm->u.x.leftColumn<pTab->nCol );
153476
153477 /* tag-20191211-002: WHERE-clause constraints are not useful to the
@@ -152535,14 +153529,16 @@
153529 }
153530
153531 /* No matches cause a break out of the loop */
153532 break;
153533 }
153534 if( i==n ){
153535 nOrderBy = n;
153536 if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){
153537 eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0);
153538 }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){
153539 eDistinct = 1;
153540 }
153541 }
153542 }
153543
153544 /* Allocate the sqlite3_index_info structure
@@ -152563,17 +153559,23 @@
153559 pIdxInfo->aOrderBy = pIdxOrderBy;
153560 pIdxInfo->aConstraintUsage = pUsage;
153561 pHidden->pWC = pWC;
153562 pHidden->pParse = pParse;
153563 pHidden->eDistinct = eDistinct;
153564 pHidden->mIn = 0;
153565 for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
153566 u16 op;
153567 if( (pTerm->wtFlags & TERM_OK)==0 ) continue;
153568 pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
153569 pIdxCons[j].iTermOffset = i;
153570 op = pTerm->eOperator & WO_ALL;
153571 if( op==WO_IN ){
153572 if( (pTerm->wtFlags & TERM_SLICE)==0 ){
153573 pHidden->mIn |= SMASKBIT32(j);
153574 }
153575 op = WO_EQ;
153576 }
153577 if( op==WO_AUX ){
153578 pIdxCons[j].op = pTerm->eMatchOp;
153579 }else if( op & (WO_ISNULL|WO_IS) ){
153580 if( op==WO_ISNULL ){
153581 pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
@@ -152659,11 +153661,13 @@
153661 static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
153662 sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
153663 int rc;
153664
153665 whereTraceIndexInfoInputs(p);
153666 pParse->db->nSchemaLock++;
153667 rc = pVtab->pModule->xBestIndex(pVtab, p);
153668 pParse->db->nSchemaLock--;
153669 whereTraceIndexInfoOutputs(p);
153670
153671 if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
153672 if( rc==SQLITE_NOMEM ){
153673 sqlite3OomFault(pParse->db);
@@ -153911,12 +154915,21 @@
154915 if( j<0 ){
154916 if( pLoop->maskSelf==pTerm->prereqAll ){
154917 /* If there are extra terms in the WHERE clause not used by an index
154918 ** that depend only on the table being scanned, and that will tend to
154919 ** cause many rows to be omitted, then mark that table as
154920 ** "self-culling".
154921 **
154922 ** 2022-03-24: Self-culling only applies if either the extra terms
154923 ** are straight comparison operators that are non-true with NULL
154924 ** operand, or if the loop is not a LEFT JOIN.
154925 */
154926 if( (pTerm->eOperator & 0x3f)!=0
154927 || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0
154928 ){
154929 pLoop->wsFlags |= WHERE_SELFCULL;
154930 }
154931 }
154932 if( pTerm->truthProb<=0 ){
154933 /* If a truth probability is specified using the likelihood() hints,
154934 ** then use the probability provided by the application. */
154935 pLoop->nOut += pTerm->truthProb;
@@ -154488,11 +155501,11 @@
155501 }
155502 if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
155503 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
155504 Expr *pExpr;
155505 pExpr = pTerm->pExpr;
155506 if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab)
155507 && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
155508 && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
155509 && (pTerm->wtFlags & TERM_VNULL)==0
155510 ){
155511 return 1;
@@ -154789,10 +155802,19 @@
155802 }
155803 return rc;
155804 }
155805
155806 #ifndef SQLITE_OMIT_VIRTUALTABLE
155807
155808 /*
155809 ** Return true if pTerm is a virtual table LIMIT or OFFSET term.
155810 */
155811 static int isLimitTerm(WhereTerm *pTerm){
155812 assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 );
155813 return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT
155814 && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET;
155815 }
155816
155817 /*
155818 ** Argument pIdxInfo is already populated with all constraints that may
155819 ** be used by the virtual table identified by pBuilder->pNew->iTab. This
155820 ** function marks a subset of those constraints usable, invokes the
@@ -154817,13 +155839,15 @@
155839 Bitmask mPrereq, /* Mask of tables that must be used. */
155840 Bitmask mUsable, /* Mask of usable tables */
155841 u16 mExclude, /* Exclude terms using these operators */
155842 sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
155843 u16 mNoOmit, /* Do not omit these constraints */
155844 int *pbIn, /* OUT: True if plan uses an IN(...) op */
155845 int *pbRetryLimit /* OUT: Retry without LIMIT/OFFSET */
155846 ){
155847 WhereClause *pWC = pBuilder->pWC;
155848 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
155849 struct sqlite3_index_constraint *pIdxCons;
155850 struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage;
155851 int i;
155852 int mxTerm;
155853 int rc = SQLITE_OK;
@@ -154842,10 +155866,11 @@
155866 for(i=0; i<nConstraint; i++, pIdxCons++){
155867 WhereTerm *pTerm = &pWC->a[pIdxCons->iTermOffset];
155868 pIdxCons->usable = 0;
155869 if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight
155870 && (pTerm->eOperator & mExclude)==0
155871 && (pbRetryLimit || !isLimitTerm(pTerm))
155872 ){
155873 pIdxCons->usable = 1;
155874 }
155875 }
155876
@@ -154857,10 +155882,11 @@
155882 pIdxInfo->orderByConsumed = 0;
155883 pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
155884 pIdxInfo->estimatedRows = 25;
155885 pIdxInfo->idxFlags = 0;
155886 pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
155887 pHidden->mHandleIn = 0;
155888
155889 /* Invoke the virtual table xBestIndex() method */
155890 rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
155891 if( rc ){
155892 if( rc==SQLITE_CONSTRAINT ){
@@ -154874,12 +155900,12 @@
155900 return rc;
155901 }
155902
155903 mxTerm = -1;
155904 assert( pNew->nLSlot>=nConstraint );
155905 memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint );
155906 memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab));
155907 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
155908 for(i=0; i<nConstraint; i++, pIdxCons++){
155909 int iTerm;
155910 if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
155911 WhereTerm *pTerm;
@@ -154909,21 +155935,41 @@
155935 testcase( i!=iTerm );
155936 pNew->u.vtab.omitMask |= 1<<iTerm;
155937 }else{
155938 testcase( i!=iTerm );
155939 }
155940 if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET ){
155941 pNew->u.vtab.bOmitOffset = 1;
155942 }
155943 }
155944 if( SMASKBIT32(i) & pHidden->mHandleIn ){
155945 pNew->u.vtab.mHandleIn |= MASKBIT32(iTerm);
155946 }else if( (pTerm->eOperator & WO_IN)!=0 ){
155947 /* A virtual table that is constrained by an IN clause may not
155948 ** consume the ORDER BY clause because (1) the order of IN terms
155949 ** is not necessarily related to the order of output terms and
155950 ** (2) Multiple outputs from a single IN value will not merge
155951 ** together. */
155952 pIdxInfo->orderByConsumed = 0;
155953 pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
155954 *pbIn = 1; assert( (mExclude & WO_IN)==0 );
155955 }
155956
155957 if( isLimitTerm(pTerm) && *pbIn ){
155958 /* If there is an IN(...) term handled as an == (separate call to
155959 ** xFilter for each value on the RHS of the IN) and a LIMIT or
155960 ** OFFSET term handled as well, the plan is unusable. Set output
155961 ** variable *pbRetryLimit to true to tell the caller to retry with
155962 ** LIMIT and OFFSET disabled. */
155963 if( pIdxInfo->needToFreeIdxStr ){
155964 sqlite3_free(pIdxInfo->idxStr);
155965 pIdxInfo->idxStr = 0;
155966 pIdxInfo->needToFreeIdxStr = 0;
155967 }
155968 *pbRetryLimit = 1;
155969 return SQLITE_OK;
155970 }
155971 }
155972 }
155973
155974 pNew->nLTerm = mxTerm+1;
155975 for(i=0; i<=mxTerm; i++){
@@ -154992,10 +156038,29 @@
156038 }
156039 zRet = (pC ? pC->zName : sqlite3StrBINARY);
156040 }
156041 return zRet;
156042 }
156043
156044 /*
156045 ** Return true if constraint iCons is really an IN(...) constraint, or
156046 ** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0)
156047 ** or clear (if bHandle==0) the flag to handle it using an iterator.
156048 */
156049 SQLITE_API int sqlite3_vtab_in(sqlite3_index_info *pIdxInfo, int iCons, int bHandle){
156050 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156051 u32 m = SMASKBIT32(iCons);
156052 if( m & pHidden->mIn ){
156053 if( bHandle==0 ){
156054 pHidden->mHandleIn &= ~m;
156055 }else if( bHandle>0 ){
156056 pHidden->mHandleIn |= m;
156057 }
156058 return 1;
156059 }
156060 return 0;
156061 }
156062
156063 /*
156064 ** This interface is callable from within the xBestIndex callback only.
156065 **
156066 ** If possible, set (*ppVal) to point to an object containing the value
@@ -155029,21 +156094,34 @@
156094 }
156095
156096 return rc;
156097 }
156098
 
156099 /*
156100 ** Return true if ORDER BY clause may be handled as DISTINCT.
156101 */
156102 SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){
156103 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156104 assert( pHidden->eDistinct>=0 && pHidden->eDistinct<=3 );
 
 
156105 return pHidden->eDistinct;
156106 }
156107
156108 #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
156109 && !defined(SQLITE_OMIT_VIRTUALTABLE)
156110 /*
156111 ** Cause the prepared statement that is associated with a call to
156112 ** xBestIndex to open write transactions on all attached schemas.
156113 ** This is used by the (built-in) sqlite_dbpage virtual table.
156114 */
156115 SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){
156116 HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
156117 Parse *pParse = pHidden->pParse;
156118 int nDb = pParse->db->nDb;
156119 int i;
156120 for(i=0; i<nDb; i++) sqlite3BeginWriteOperation(pParse, 0, i);
156121 }
156122 #endif
156123
156124 /*
156125 ** Add all WhereLoop objects for a table of the join identified by
156126 ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
156127 **
@@ -155082,10 +156160,11 @@
156160 int nConstraint; /* Number of constraints in p */
156161 int bIn; /* True if plan uses IN(...) operator */
156162 WhereLoop *pNew;
156163 Bitmask mBest; /* Tables used by best possible plan */
156164 u16 mNoOmit;
156165 int bRetry = 0; /* True to retry with LIMIT/OFFSET disabled */
156166
156167 assert( (mPrereq & mUnusable)==0 );
156168 pWInfo = pBuilder->pWInfo;
156169 pParse = pWInfo->pParse;
156170 pWC = pBuilder->pWC;
@@ -155105,11 +156184,19 @@
156184 }
156185
156186 /* First call xBestIndex() with all constraints usable. */
156187 WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
156188 WHERETRACE(0x40, (" VirtualOne: all usable\n"));
156189 rc = whereLoopAddVirtualOne(
156190 pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry
156191 );
156192 if( bRetry ){
156193 assert( rc==SQLITE_OK );
156194 rc = whereLoopAddVirtualOne(
156195 pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, 0
156196 );
156197 }
156198
156199 /* If the call to xBestIndex() with all terms enabled produced a plan
156200 ** that does not require any source tables (IOW: a plan with mBest==0)
156201 ** and does not use an IN(...) operator, then there is no point in making
156202 ** any further calls to xBestIndex() since they will all return the same
@@ -155123,11 +156210,11 @@
156210 /* If the plan produced by the earlier call uses an IN(...) term, call
156211 ** xBestIndex again, this time with IN(...) terms disabled. */
156212 if( bIn ){
156213 WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
156214 rc = whereLoopAddVirtualOne(
156215 pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0);
156216 assert( bIn==0 );
156217 mBestNoIn = pNew->prereq & ~mPrereq;
156218 if( mBestNoIn==0 ){
156219 seenZero = 1;
156220 seenZeroNoIN = 1;
@@ -155150,11 +156237,11 @@
156237 if( mNext==ALLBITS ) break;
156238 if( mNext==mBest || mNext==mBestNoIn ) continue;
156239 WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
156240 (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
156241 rc = whereLoopAddVirtualOne(
156242 pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn, 0);
156243 if( pNew->prereq==mPrereq ){
156244 seenZero = 1;
156245 if( bIn==0 ) seenZeroNoIN = 1;
156246 }
156247 }
@@ -155163,21 +156250,21 @@
156250 ** that requires no source tables at all (i.e. one guaranteed to be
156251 ** usable), make a call here with all source tables disabled */
156252 if( rc==SQLITE_OK && seenZero==0 ){
156253 WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
156254 rc = whereLoopAddVirtualOne(
156255 pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0);
156256 if( bIn==0 ) seenZeroNoIN = 1;
156257 }
156258
156259 /* If the calls to xBestIndex() have so far failed to find a plan
156260 ** that requires no source tables at all and does not use an IN(...)
156261 ** operator, make a final call to obtain one here. */
156262 if( rc==SQLITE_OK && seenZeroNoIN==0 ){
156263 WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
156264 rc = whereLoopAddVirtualOne(
156265 pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0);
156266 }
156267 }
156268
156269 if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
156270 freeIndexInfo(pParse->db, p);
@@ -155471,11 +156558,13 @@
156558 if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue;
156559 }else{
156560 pLoop = pLast;
156561 }
156562 if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
156563 if( pLoop->u.vtab.isOrdered
156564 && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY)
156565 ){
156566 obSat = obDone;
156567 }
156568 break;
156569 }else if( wctrlFlags & WHERE_DISTINCTBY ){
156570 pLoop->u.btree.nDistinctCol = 0;
@@ -155738,11 +156827,11 @@
156827 **
156828 ** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1
156829 ** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0
156830 */
156831 SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){
156832 assert( pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY) );
156833 assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP );
156834 return pWInfo->sorted;
156835 }
156836
156837 #ifdef WHERETRACE_ENABLED
@@ -156139,16 +157228,16 @@
157228 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
157229 }
157230 }
157231 pWInfo->bOrderedInnerLoop = 0;
157232 if( pWInfo->pOrderBy ){
157233 pWInfo->nOBSat = pFrom->isOrdered;
157234 if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
157235 if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
157236 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
157237 }
157238 }else{
 
157239 pWInfo->revMask = pFrom->revLoop;
157240 if( pWInfo->nOBSat<=0 ){
157241 pWInfo->nOBSat = 0;
157242 if( nLoop>0 ){
157243 u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
@@ -156407,11 +157496,11 @@
157496 if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
157497 pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
157498 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
157499 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
157500 if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
157501 || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor
157502 ){
157503 break;
157504 }
157505 }
157506 }
@@ -156579,10 +157668,11 @@
157668 Parse *pParse, /* The parser context */
157669 SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
157670 Expr *pWhere, /* The WHERE clause */
157671 ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
157672 ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
157673 Select *pLimit, /* Use this LIMIT/OFFSET clause, if any */
157674 u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
157675 int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
157676 ** If WHERE_USE_LIMIT, then the limit amount */
157677 ){
157678 int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
@@ -156655,10 +157745,13 @@
157745 pWInfo->nLevel = nTabList;
157746 pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
157747 pWInfo->wctrlFlags = wctrlFlags;
157748 pWInfo->iLimit = iAuxArg;
157749 pWInfo->savedNQueryLoop = pParse->nQueryLoop;
157750 #ifndef SQLITE_OMIT_VIRTUALTABLE
157751 pWInfo->pLimit = pLimit;
157752 #endif
157753 memset(&pWInfo->nOBSat, 0,
157754 offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
157755 memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
157756 assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
157757 pMaskSet = &pWInfo->sMaskSet;
@@ -156723,10 +157816,11 @@
157816 #endif
157817 }
157818
157819 /* Analyze all of the subexpressions. */
157820 sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
157821 sqlite3WhereAddLimit(&pWInfo->sWC, pLimit);
157822 if( db->mallocFailed ) goto whereBeginError;
157823
157824 /* Special case: WHERE terms that do not refer to any tables in the join
157825 ** (constant expressions). Evaluate each such term, and jump over all the
157826 ** generated code if the result is not true.
@@ -156969,10 +158063,11 @@
158063 testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
158064 testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
158065 if( pWInfo->eOnePass==ONEPASS_OFF
158066 && pTab->nCol<BMS
158067 && (pTab->tabFlags & (TF_HasGenerated|TF_WithoutRowid))==0
158068 && (pLoop->wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))==0
158069 ){
158070 /* If we know that only a prefix of the record will be used,
158071 ** it is advantageous to reduce the "column count" field in
158072 ** the P4 operand of the OP_OpenRead/Write opcode. */
158073 Bitmask b = pTabItem->colUsed;
@@ -157129,10 +158224,30 @@
158224 if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
158225 sqlite3VdbePrintOp(0, pc, pOp);
158226 }
158227 #endif
158228
158229 #ifdef SQLITE_DEBUG
158230 /*
158231 ** Return true if cursor iCur is opened by instruction k of the
158232 ** bytecode. Used inside of assert() only.
158233 */
158234 static int cursorIsOpen(Vdbe *v, int iCur, int k){
158235 while( k>=0 ){
158236 VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
158237 if( pOp->p1!=iCur ) continue;
158238 if( pOp->opcode==OP_Close ) return 0;
158239 if( pOp->opcode==OP_OpenRead ) return 1;
158240 if( pOp->opcode==OP_OpenWrite ) return 1;
158241 if( pOp->opcode==OP_OpenDup ) return 1;
158242 if( pOp->opcode==OP_OpenAutoindex ) return 1;
158243 if( pOp->opcode==OP_OpenEphemeral ) return 1;
158244 }
158245 return 0;
158246 }
158247 #endif /* SQLITE_DEBUG */
158248
158249 /*
158250 ** Generate the end of the WHERE loop. See comments on
158251 ** sqlite3WhereBegin() for additional information.
158252 */
158253 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
@@ -157381,10 +158496,15 @@
158496 || pOp->opcode==OP_Offset
158497 #endif
158498 ){
158499 int x = pOp->p2;
158500 assert( pIdx->pTable==pTab );
158501 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158502 if( pOp->opcode==OP_Offset ){
158503 /* Do not need to translate the column number */
158504 }else
158505 #endif
158506 if( !HasRowid(pTab) ){
158507 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
158508 x = pPk->aiColumn[x];
158509 assert( x>=0 );
158510 }else{
@@ -157394,13 +158514,26 @@
158514 x = sqlite3TableColumnToIndex(pIdx, x);
158515 if( x>=0 ){
158516 pOp->p2 = x;
158517 pOp->p1 = pLevel->iIdxCur;
158518 OpcodeRewriteTrace(db, k, pOp);
158519 }else{
158520 /* Unable to translate the table reference into an index
158521 ** reference. Verify that this is harmless - that the
158522 ** table being referenced really is open.
158523 */
158524 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
158525 assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158526 || cursorIsOpen(v,pOp->p1,k)
158527 || pOp->opcode==OP_Offset
158528 );
158529 #else
158530 assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
158531 || cursorIsOpen(v,pOp->p1,k)
158532 );
158533 #endif
158534 }
 
 
158535 }else if( pOp->opcode==OP_Rowid ){
158536 pOp->p1 = pLevel->iIdxCur;
158537 pOp->opcode = OP_IdxRowid;
158538 OpcodeRewriteTrace(db, k, pOp);
158539 }else if( pOp->opcode==OP_IfNullRow ){
@@ -158151,11 +159284,11 @@
159284 break;
159285 }
159286 }
159287 }
159288 }
159289 pWin->pWFunc = pFunc;
159290 }
159291
159292 /*
159293 ** Context object passed through sqlite3WalkExprList() to
159294 ** selectWindowRewriteExprCb() by selectWindowRewriteEList().
@@ -158384,11 +159517,15 @@
159517 ** are invoked in the correct order as described under "SELECT REWRITING"
159518 ** at the top of this file.
159519 */
159520 SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
159521 int rc = SQLITE_OK;
159522 if( p->pWin
159523 && p->pPrior==0
159524 && ALWAYS((p->selFlags & SF_WinRewrite)==0)
159525 && ALWAYS(!IN_RENAME_OBJECT)
159526 ){
159527 Vdbe *v = sqlite3GetVdbe(pParse);
159528 sqlite3 *db = pParse->db;
159529 Select *pSub = 0; /* The subquery */
159530 SrcList *pSrc = p->pSrc;
159531 Expr *pWhere = p->pWhere;
@@ -158459,12 +159596,13 @@
159596 ** window function - one for the accumulator, another for interim
159597 ** results. */
159598 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159599 ExprList *pArgs;
159600 assert( ExprUseXList(pWin->pOwner) );
159601 assert( pWin->pWFunc!=0 );
159602 pArgs = pWin->pOwner->x.pList;
159603 if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
159604 selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
159605 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
159606 pWin->bExprArgs = 1;
159607 }else{
159608 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
@@ -158842,11 +159980,11 @@
159980 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
159981 return;
159982 }
159983
159984 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
159985 FuncDef *p = pWin->pWFunc;
159986 if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
159987 /* The inline versions of min() and max() require a single ephemeral
159988 ** table and 3 registers. The registers are used as follows:
159989 **
159990 ** regApp+0: slot to copy min()/max() argument to for MakeRecord
@@ -158859,11 +159997,11 @@
159997 pList = pWin->pOwner->x.pList;
159998 pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
159999 pWin->csrApp = pParse->nTab++;
160000 pWin->regApp = pParse->nMem+1;
160001 pParse->nMem += 3;
160002 if( pKeyInfo && pWin->pWFunc->zName[1]=='i' ){
160003 assert( pKeyInfo->aSortFlags[0]==0 );
160004 pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
160005 }
160006 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
160007 sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
@@ -159082,11 +160220,11 @@
160220 ){
160221 Parse *pParse = p->pParse;
160222 Vdbe *v = sqlite3GetVdbe(pParse);
160223 Window *pWin;
160224 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
160225 FuncDef *pFunc = pWin->pWFunc;
160226 int regArg;
160227 int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
160228 int i;
160229
160230 assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
@@ -159196,11 +160334,11 @@
160334 Vdbe *v = sqlite3GetVdbe(pParse);
160335 Window *pWin;
160336
160337 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
160338 if( pMWin->regStartRowid==0
160339 && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX)
160340 && (pWin->eStart!=TK_UNBOUNDED)
160341 ){
160342 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
160343 sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
160344 VdbeCoverage(v);
@@ -159210,16 +160348,16 @@
160348 assert( pMWin->regStartRowid==0 );
160349 }else{
160350 int nArg = windowArgCount(pWin);
160351 if( bFin ){
160352 sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
160353 sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
160354 sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
160355 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
160356 }else{
160357 sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
160358 sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
160359 }
160360 }
160361 }
160362 }
160363
@@ -159344,11 +160482,11 @@
160482 }else{
160483 Parse *pParse = p->pParse;
160484 Window *pWin;
160485
160486 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
160487 FuncDef *pFunc = pWin->pWFunc;
160488 assert( ExprUseXList(pWin->pOwner) );
160489 if( pFunc->zName==nth_valueName
160490 || pFunc->zName==first_valueName
160491 ){
160492 int csr = pWin->csrApp;
@@ -159416,11 +160554,11 @@
160554 Vdbe *v = sqlite3GetVdbe(pParse);
160555 int regArg;
160556 int nArg = 0;
160557 Window *pWin;
160558 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
160559 FuncDef *pFunc = pWin->pWFunc;
160560 assert( pWin->regAccum );
160561 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
160562 nArg = MAX(nArg, windowArgCount(pWin));
160563 if( pMWin->regStartRowid==0 ){
160564 if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
@@ -159446,11 +160584,11 @@
160584 */
160585 static int windowCacheFrame(Window *pMWin){
160586 Window *pWin;
160587 if( pMWin->regStartRowid ) return 1;
160588 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
160589 FuncDef *pFunc = pWin->pWFunc;
160590 if( (pFunc->zName==nth_valueName)
160591 || (pFunc->zName==first_valueName)
160592 || (pFunc->zName==leadName)
160593 || (pFunc->zName==lagName)
160594 ){
@@ -159804,11 +160942,11 @@
160942 pNew = sqlite3DbMallocZero(db, sizeof(Window));
160943 if( pNew ){
160944 pNew->zName = sqlite3DbStrDup(db, p->zName);
160945 pNew->zBase = sqlite3DbStrDup(db, p->zBase);
160946 pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
160947 pNew->pWFunc = p->pWFunc;
160948 pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
160949 pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
160950 pNew->eFrmType = p->eFrmType;
160951 pNew->eEnd = p->eEnd;
160952 pNew->eStart = p->eStart;
@@ -160681,14 +161819,11 @@
161819 }
161820 return pSelect;
161821 }
161822
161823
161824 /* Construct a new Expr object from a single token */
 
 
 
161825 static Expr *tokenExpr(Parse *pParse, int op, Token t){
161826 Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
161827 if( p ){
161828 /* memset(p, 0, sizeof(Expr)); */
161829 p->op = (u8)op;
@@ -160704,10 +161839,11 @@
161839 p->iTable = 0;
161840 p->iColumn = 0;
161841 p->u.zToken = (char*)&p[1];
161842 memcpy(p->u.zToken, t.z, t.n);
161843 p->u.zToken[t.n] = 0;
161844 p->w.iOfst = (int)(t.z - pParse->zTail);
161845 if( sqlite3Isquote(p->u.zToken[0]) ){
161846 sqlite3DequoteExpr(p);
161847 }
161848 #if SQLITE_MAX_EXPR_DEPTH>0
161849 p->nHeight = 1;
@@ -164515,11 +165651,11 @@
165651 }
165652 break;
165653 case 102: /* selcollist ::= sclp scanpt nm DOT STAR */
165654 {
165655 Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
165656 Expr *pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0);
165657 Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
165658 yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
165659 }
165660 break;
165661 case 103: /* as ::= AS nm */
@@ -164800,29 +165936,24 @@
165936 case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179);
165937 {yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
165938 break;
165939 case 180: /* expr ::= nm DOT nm */
165940 {
165941 Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
165942 Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
 
 
 
 
165943 yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
165944 }
165945 yymsp[-2].minor.yy528 = yylhsminor.yy528;
165946 break;
165947 case 181: /* expr ::= nm DOT nm DOT nm */
165948 {
165949 Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0);
165950 Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
165951 Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
165952 Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
165953 if( IN_RENAME_OBJECT ){
165954 sqlite3RenameTokenRemap(pParse, 0, temp1);
 
165955 }
165956 yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
165957 }
165958 yymsp[-4].minor.yy528 = yylhsminor.yy528;
165959 break;
@@ -164831,10 +165962,11 @@
165962 {yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
165963 break;
165964 case 184: /* term ::= INTEGER */
165965 {
165966 yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
165967 if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
165968 }
165969 yymsp[0].minor.yy528 = yylhsminor.yy528;
165970 break;
165971 case 185: /* expr ::= VARIABLE */
165972 {
@@ -167075,11 +168207,14 @@
168207 }else if( tokenType==TK_FILTER ){
168208 assert( n==6 );
168209 tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
168210 #endif /* SQLITE_OMIT_WINDOWFUNC */
168211 }else{
168212 Token x;
168213 x.z = zSql;
168214 x.n = n;
168215 sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
168216 break;
168217 }
168218 }
168219 pParse->sLastToken.z = zSql;
168220 pParse->sLastToken.n = n;
@@ -167125,11 +168260,11 @@
168260 sqlite3DeleteTable(db, pParse->pNewTable);
168261 }
168262 if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){
168263 sqlite3DeleteTrigger(db, pParse->pNewTrigger);
168264 }
168265 if( pParse->pVList ) sqlite3DbFreeNN(db, pParse->pVList);
168266 db->pParse = pParentParse;
168267 assert( nErr==0 || pParse->rc!=SQLITE_OK );
168268 return nErr;
168269 }
168270
@@ -171686,16 +172821,20 @@
172821 ** is called immediately after installing the new callback and the return
172822 ** value from sqlite3FaultSim(0) becomes the return from
172823 ** sqlite3_test_control().
172824 */
172825 case SQLITE_TESTCTRL_FAULT_INSTALL: {
172826 /* A bug in MSVC prevents it from understanding pointers to functions
172827 ** types in the second argument to va_arg(). Work around the problem
172828 ** using a typedef.
172829 ** http://support.microsoft.com/kb/47961 <-- dead hyperlink
172830 ** Search at http://web.archive.org/ to find the 2015-03-16 archive
172831 ** of the link above to see the original text.
172832 ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
172833 */
172834 typedef int(*sqlite3FaultFuncType)(int);
172835 sqlite3GlobalConfig.xTestCallback = va_arg(ap, sqlite3FaultFuncType);
172836 rc = sqlite3FaultSim(0);
172837 break;
172838 }
172839
172840 /*
@@ -171818,17 +172957,31 @@
172957 sqlite3 *db = va_arg(ap, sqlite3*);
172958 db->dbOptFlags = va_arg(ap, u32);
172959 break;
172960 }
172961
172962 /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
172963 **
172964 ** If parameter onoff is 1, subsequent calls to localtime() fail.
172965 ** If 2, then invoke xAlt() instead of localtime(). If 0, normal
172966 ** processing.
172967 **
172968 ** xAlt arguments are void pointers, but they really want to be:
172969 **
172970 ** int xAlt(const time_t*, struct tm*);
172971 **
172972 ** xAlt should write results in to struct tm object of its 2nd argument
172973 ** and return zero on success, or return non-zero on failure.
172974 */
172975 case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
172976 sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
172977 if( sqlite3GlobalConfig.bLocaltimeFault==2 ){
172978 typedef int(*sqlite3LocaltimeType)(const void*,void*);
172979 sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType);
172980 }else{
172981 sqlite3GlobalConfig.xAltLocaltime = 0;
172982 }
172983 break;
172984 }
172985
172986 /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*);
172987 **
@@ -172026,14 +173179,16 @@
173179 ** Test access for the LogEst conversion routines.
173180 */
173181 case SQLITE_TESTCTRL_LOGEST: {
173182 double rIn = va_arg(ap, double);
173183 LogEst rLogEst = sqlite3LogEstFromDouble(rIn);
173184 int *pI1 = va_arg(ap,int*);
173185 u64 *pU64 = va_arg(ap,u64*);
173186 int *pI2 = va_arg(ap,int*);
173187 *pI1 = rLogEst;
173188 *pU64 = sqlite3LogEstToInt(rLogEst);
173189 *pI2 = sqlite3LogEst(*pU64);
173190 break;
173191 }
173192
173193
173194 #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
@@ -193960,11 +195115,11 @@
195115 u32 iRoot;
195116 JsonNode *pTarget;
195117 if( pPatch->eType!=JSON_OBJECT ){
195118 return pPatch;
195119 }
195120 assert( iTarget<pParse->nNode );
195121 pTarget = &pParse->aNode[iTarget];
195122 assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
195123 if( pTarget->eType!=JSON_OBJECT ){
195124 jsonRemoveAllNulls(pPatch);
195125 return pPatch;
@@ -195001,11 +196156,11 @@
196156 sqlite3_module *pModule;
196157 } aMod[] = {
196158 { "json_each", &jsonEachModule },
196159 { "json_tree", &jsonTreeModule },
196160 };
196161 unsigned int i;
196162 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
196163 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
196164 }
196165 return rc;
196166 }
@@ -209255,10 +210410,11 @@
210410 && pIdxInfo->aOrderBy[0].iColumn<=0
210411 && pIdxInfo->aOrderBy[0].desc==0
210412 ){
210413 pIdxInfo->orderByConsumed = 1;
210414 }
210415 sqlite3VtabWriteAll(pIdxInfo);
210416 return SQLITE_OK;
210417 }
210418
210419 /*
210420 ** Open a new dbpagevfs cursor.
@@ -209432,11 +210588,11 @@
210588 if( iDb<0 ){
210589 zErr = "no such schema";
210590 goto update_fail;
210591 }
210592 pBt = pTab->db->aDb[iDb].pBt;
210593 if( pgno<1 || pBt==0 || pgno>sqlite3BtreeLastPage(pBt) ){
210594 zErr = "bad page number";
210595 goto update_fail;
210596 }
210597 szPage = sqlite3BtreeGetPageSize(pBt);
210598 if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
@@ -231609,11 +232765,11 @@
232765 int rc;
232766
232767 rc = sqlite3_step(pSorter->pStmt);
232768 if( rc==SQLITE_DONE ){
232769 rc = SQLITE_OK;
232770 CsrFlagSet(pCsr, FTS5CSR_EOF|FTS5CSR_REQUIRE_CONTENT);
232771 }else if( rc==SQLITE_ROW ){
232772 const u8 *a;
232773 const u8 *aBlob;
232774 int nBlob;
232775 int i;
@@ -233598,11 +234754,11 @@
234754 int nArg, /* Number of args */
234755 sqlite3_value **apUnused /* Function arguments */
234756 ){
234757 assert( nArg==0 );
234758 UNUSED_PARAM2(nArg, apUnused);
234759 sqlite3_result_text(pCtx, "fts5: 2022-03-31 11:12:56 f2d9262e4427ab37ba26c004fc7a4790c86c1856d695a6b4ec3e72732ea54c09", -1, SQLITE_TRANSIENT);
234760 }
234761
234762 /*
234763 ** Return true if zName is the extension on one of the shadow tables used
234764 ** by this module.
234765
+232 -45
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,13 +144,13 @@
144144
**
145145
** See also: [sqlite3_libversion()],
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149
-#define SQLITE_VERSION "3.38.0"
150
-#define SQLITE_VERSION_NUMBER 3038000
151
-#define SQLITE_SOURCE_ID "2022-01-25 00:03:25 a8db69411b0d1275909adeb21027784ada17af24efe3a59ae0ae2a897659ff17"
149
+#define SQLITE_VERSION "3.39.0"
150
+#define SQLITE_VERSION_NUMBER 3039000
151
+#define SQLITE_SOURCE_ID "2022-04-01 17:23:17 a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -564,11 +564,11 @@
564564
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
565565
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
566566
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
567567
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
568568
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
569
-#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
569
+#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
570570
571571
/*
572572
** CAPI3REF: Flags For File Open Operations
573573
**
574574
** These bit values are intended for use in the
@@ -3848,11 +3848,11 @@
38483848
**
38493849
** ^If the most recent error references a specific token in the input
38503850
** SQL, the sqlite3_error_offset() interface returns the byte offset
38513851
** of the start of that token. ^The byte offset returned by
38523852
** sqlite3_error_offset() assumes that the input SQL is UTF8.
3853
-** ^If the most error does not reference a specific token in the input
3853
+** ^If the most recent error does not reference a specific token in the input
38543854
** SQL, then the sqlite3_error_offset() function returns -1.
38553855
**
38563856
** When the serialized [threading mode] is in use, it might be the
38573857
** case that a second error occurs on a separate thread in between
38583858
** the time of the first error and the call to these interfaces.
@@ -4282,10 +4282,14 @@
42824282
** ^For example, an UPDATE statement might have a WHERE clause that
42834283
** makes it a no-op, but the sqlite3_stmt_readonly() result would still
42844284
** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
42854285
** read-only no-op if the table already exists, but
42864286
** sqlite3_stmt_readonly() still returns false for such a statement.
4287
+**
4288
+** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN]
4289
+** statement, then sqlite3_stmt_readonly(X) returns the same value as
4290
+** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted.
42874291
*/
42884292
SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
42894293
42904294
/*
42914295
** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4350,10 +4354,12 @@
43504354
** still make the distinction between protected and unprotected
43514355
** sqlite3_value objects even when not strictly required.
43524356
**
43534357
** ^The sqlite3_value objects that are passed as parameters into the
43544358
** implementation of [application-defined SQL functions] are protected.
4359
+** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
4360
+** are protected.
43554361
** ^The sqlite3_value object returned by
43564362
** [sqlite3_column_value()] is unprotected.
43574363
** Unprotected sqlite3_value objects may only be used as arguments
43584364
** to [sqlite3_result_value()], [sqlite3_bind_value()], and
43594365
** [sqlite3_value_dup()].
@@ -4970,10 +4976,14 @@
49704976
** bytes in the string, not the number of characters.
49714977
**
49724978
** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
49734979
** even empty strings, are always zero-terminated. ^The return
49744980
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
4981
+**
4982
+** ^Strings returned by sqlite3_column_text16() always have the endianness
4983
+** which is native to the platform, regardless of the text encoding set
4984
+** for the database.
49754985
**
49764986
** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
49774987
** [unprotected sqlite3_value] object. In a multithreaded environment,
49784988
** an unprotected sqlite3_value object may only be used safely with
49794989
** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -4984,11 +4994,11 @@
49844994
** Hence, the sqlite3_column_value() interface
49854995
** is normally only useful within the implementation of
49864996
** [application-defined SQL functions] or [virtual tables], not within
49874997
** top-level application code.
49884998
**
4989
-** The these routines may attempt to convert the datatype of the result.
4999
+** These routines may attempt to convert the datatype of the result.
49905000
** ^For example, if the internal representation is FLOAT and a text result
49915001
** is requested, [sqlite3_snprintf()] is used internally to perform the
49925002
** conversion automatically. ^(The following table details the conversions
49935003
** that are applied:
49945004
**
@@ -5009,11 +5019,11 @@
50095019
** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
50105020
** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
50115021
** <tr><td> TEXT <td> BLOB <td> No change
50125022
** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
50135023
** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5014
-** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
5024
+** <tr><td> BLOB <td> TEXT <td> [CAST] to TEXT, ensure zero terminator
50155025
** </table>
50165026
** </blockquote>)^
50175027
**
50185028
** Note that when type conversions occur, pointers returned by prior
50195029
** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5581,11 +5591,12 @@
55815591
**
55825592
** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
55835593
** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
55845594
** is a [protected sqlite3_value] object even if the input is not.
55855595
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5586
-** memory allocation fails.
5596
+** memory allocation fails. ^If V is a [pointer value], then the result
5597
+** of sqlite3_value_dup(V) is a NULL value.
55875598
**
55885599
** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
55895600
** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
55905601
** then sqlite3_value_free(V) is a harmless no-op.
55915602
*/
@@ -7129,28 +7140,60 @@
71297140
/*
71307141
** CAPI3REF: Virtual Table Constraint Operator Codes
71317142
**
71327143
** These macros define the allowed values for the
71337144
** [sqlite3_index_info].aConstraint[].op field. Each value represents
7134
-** an operator that is part of a constraint term in the wHERE clause of
7145
+** an operator that is part of a constraint term in the WHERE clause of
71357146
** a query that uses a [virtual table].
7147
+**
7148
+** ^The left-hand operand of the operator is given by the corresponding
7149
+** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand
7150
+** operand is the rowid.
7151
+** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
7152
+** operators have no left-hand operand, and so for those operators the
7153
+** corresponding aConstraint[].iColumn is meaningless and should not be
7154
+** used.
7155
+**
7156
+** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through
7157
+** value 255 are reserved to represent functions that are overloaded
7158
+** by the [xFindFunction|xFindFunction method] of the virtual table
7159
+** implementation.
7160
+**
7161
+** The right-hand operands for each constraint might be accessible using
7162
+** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand
7163
+** operand is only available if it appears as a single constant literal
7164
+** in the input SQL. If the right-hand operand is another column or an
7165
+** expression (even a constant expression) or a parameter, then the
7166
+** sqlite3_vtab_rhs_value() probably will not be able to extract it.
7167
+** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and
7168
+** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand
7169
+** and hence calls to sqlite3_vtab_rhs_value() for those operators will
7170
+** always return SQLITE_NOTFOUND.
7171
+**
7172
+** The collating sequence to be used for comparison can be found using
7173
+** the [sqlite3_vtab_collation()] interface. For most real-world virtual
7174
+** tables, the collating sequence of constraints does not matter (for example
7175
+** because the constraints are numeric) and so the sqlite3_vtab_collation()
7176
+** interface is no commonly needed.
71367177
*/
7137
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
7138
-#define SQLITE_INDEX_CONSTRAINT_GT 4
7139
-#define SQLITE_INDEX_CONSTRAINT_LE 8
7140
-#define SQLITE_INDEX_CONSTRAINT_LT 16
7141
-#define SQLITE_INDEX_CONSTRAINT_GE 32
7142
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
7143
-#define SQLITE_INDEX_CONSTRAINT_LIKE 65
7144
-#define SQLITE_INDEX_CONSTRAINT_GLOB 66
7145
-#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7146
-#define SQLITE_INDEX_CONSTRAINT_NE 68
7147
-#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7148
-#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7149
-#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7150
-#define SQLITE_INDEX_CONSTRAINT_IS 72
7151
-#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
7178
+#define SQLITE_INDEX_CONSTRAINT_EQ 2
7179
+#define SQLITE_INDEX_CONSTRAINT_GT 4
7180
+#define SQLITE_INDEX_CONSTRAINT_LE 8
7181
+#define SQLITE_INDEX_CONSTRAINT_LT 16
7182
+#define SQLITE_INDEX_CONSTRAINT_GE 32
7183
+#define SQLITE_INDEX_CONSTRAINT_MATCH 64
7184
+#define SQLITE_INDEX_CONSTRAINT_LIKE 65
7185
+#define SQLITE_INDEX_CONSTRAINT_GLOB 66
7186
+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7187
+#define SQLITE_INDEX_CONSTRAINT_NE 68
7188
+#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7189
+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7190
+#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7191
+#define SQLITE_INDEX_CONSTRAINT_IS 72
7192
+#define SQLITE_INDEX_CONSTRAINT_LIMIT 73
7193
+#define SQLITE_INDEX_CONSTRAINT_OFFSET 74
7194
+#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
71527195
71537196
/*
71547197
** CAPI3REF: Register A Virtual Table Implementation
71557198
** METHOD: sqlite3
71567199
**
@@ -7175,11 +7218,11 @@
71757218
** ^The sqlite3_create_module()
71767219
** interface is equivalent to sqlite3_create_module_v2() with a NULL
71777220
** destructor.
71787221
**
71797222
** ^If the third parameter (the pointer to the sqlite3_module object) is
7180
-** NULL then no new module is create and any existing modules with the
7223
+** NULL then no new module is created and any existing modules with the
71817224
** same name are dropped.
71827225
**
71837226
** See also: [sqlite3_drop_modules()]
71847227
*/
71857228
SQLITE_API int sqlite3_create_module(
@@ -9506,28 +9549,29 @@
95069549
95079550
/*
95089551
** CAPI3REF: Determine if a virtual table query is DISTINCT
95099552
** METHOD: sqlite3_index_info
95109553
**
9511
-** This API may only be used from within an xBestIndex() callback. The
9512
-** results of calling it from outside of an xBestIndex() callback are
9513
-** undefined and probably harmful.
9554
+** This API may only be used from within an [xBestIndex|xBestIndex method]
9555
+** of a [virtual table] implementation. The result of calling this
9556
+** interface from outside of xBestIndex() is undefined and probably harmful.
95149557
**
9515
-** ^The sqlite3_vtab_distinct() returns an integer that is either 0, 1, or
9516
-** 2. The integer returned by sqlite3_vtab_distinct() gives the virtual table
9517
-** additional information about how the query planner wants the output to be
9518
-** ordered. As long as the virtual table can meet the ordering requirements
9519
-** of the query planner, it may set the "orderByConsumed" flag.
9558
+** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and
9559
+** 3. The integer returned by sqlite3_vtab_distinct()
9560
+** gives the virtual table additional information about how the query
9561
+** planner wants the output to be ordered. As long as the virtual table
9562
+** can meet the ordering requirements of the query planner, it may set
9563
+** the "orderByConsumed" flag.
95209564
**
95219565
** <ol><li value="0"><p>
95229566
** ^If the sqlite3_vtab_distinct() interface returns 0, that means
95239567
** that the query planner needs the virtual table to return all rows in the
95249568
** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
95259569
** [sqlite3_index_info] object. This is the default expectation. If the
95269570
** virtual table outputs all rows in sorted order, then it is always safe for
95279571
** the xBestIndex method to set the "orderByConsumed" flag, regardless of
9528
-** what the return value from sqlite3_vtab_distinct().
9572
+** the return value from sqlite3_vtab_distinct().
95299573
** <li value="1"><p>
95309574
** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
95319575
** that the query planner does not need the rows to be returned in sorted order
95329576
** as long as all rows with the same values in all columns identified by the
95339577
** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
@@ -9536,16 +9580,23 @@
95369580
** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
95379581
** that the query planner does not need the rows returned in any particular
95389582
** order, as long as rows with the same values in all "aOrderBy" columns
95399583
** are adjacent.)^ ^(Furthermore, only a single row for each particular
95409584
** combination of values in the columns identified by the "aOrderBy" field
9541
-** needs to be returned.)^ ^It is ok always for two or more rows with the same
9585
+** needs to be returned.)^ ^It is always ok for two or more rows with the same
95429586
** values in all "aOrderBy" columns to be returned, as long as all such rows
95439587
** are adjacent. ^The virtual table may, if it chooses, omit extra rows
95449588
** that have the same value for all columns identified by "aOrderBy".
95459589
** ^However omitting the extra rows is optional.
95469590
** This mode is used for a DISTINCT query.
9591
+** <li value="3"><p>
9592
+** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
9593
+** that the query planner needs only distinct rows but it does need the
9594
+** rows to be sorted.)^ ^The virtual table implementation is free to omit
9595
+** rows that are identical in all aOrderBy columns, if it wants to, but
9596
+** it is not required to omit any rows. This mode is used for queries
9597
+** that have both DISTINCT and ORDER BY clauses.
95479598
** </ol>
95489599
**
95499600
** ^For the purposes of comparing virtual table output values to see if the
95509601
** values are same value for sorting purposes, two NULL values are considered
95519602
** to be the same. In other words, the comparison operator is "IS"
@@ -9567,35 +9618,171 @@
95679618
** valid to do so, on the other hand, might cause SQLite to return incorrect
95689619
** results.
95699620
*/
95709621
SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
95719622
9623
+/*
9624
+** CAPI3REF: Identify and handle IN constraints in xBestIndex
9625
+**
9626
+** This interface may only be used from within an
9627
+** [xBestIndex|xBestIndex() method] of a [virtual table] implementation.
9628
+** The result of invoking this interface from any other context is
9629
+** undefined and probably harmful.
9630
+**
9631
+** ^(A constraint on a virtual table of the form
9632
+** "[IN operator|column IN (...)]" is
9633
+** communicated to the xBestIndex method as a
9634
+** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
9635
+** this constraint, it must set the corresponding
9636
+** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
9637
+** the usual mode of handling IN operators, SQLite generates [bytecode]
9638
+** that invokes the [xFilter|xFilter() method] once for each value
9639
+** on the right-hand side of the IN operator.)^ Thus the virtual table
9640
+** only sees a single value from the right-hand side of the IN operator
9641
+** at a time.
9642
+**
9643
+** In some cases, however, it would be advantageous for the virtual
9644
+** table to see all values on the right-hand of the IN operator all at
9645
+** once. The sqlite3_vtab_in() interfaces facilitates this in two ways:
9646
+**
9647
+** <ol>
9648
+** <li><p>
9649
+** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero)
9650
+** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint
9651
+** is an [IN operator] that can be processed all at once. ^In other words,
9652
+** sqlite3_vtab_in() with -1 in the third argument is a mechanism
9653
+** by which the virtual table can ask SQLite if all-at-once processing
9654
+** of the IN operator is even possible.
9655
+**
9656
+** <li><p>
9657
+** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates
9658
+** to SQLite that the virtual table does or does not want to process
9659
+** the IN operator all-at-once, respectively. ^Thus when the third
9660
+** parameter (F) is non-negative, this interface is the mechanism by
9661
+** which the virtual table tells SQLite how it wants to process the
9662
+** IN operator.
9663
+** </ol>
9664
+**
9665
+** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times
9666
+** within the same xBestIndex method call. ^For any given P,N pair,
9667
+** the return value from sqlite3_vtab_in(P,N,F) will always be the same
9668
+** within the same xBestIndex call. ^If the interface returns true
9669
+** (non-zero), that means that the constraint is an IN operator
9670
+** that can be processed all-at-once. ^If the constraint is not an IN
9671
+** operator or cannot be processed all-at-once, then the interface returns
9672
+** false.
9673
+**
9674
+** ^(All-at-once processing of the IN operator is selected if both of the
9675
+** following conditions are met:
9676
+**
9677
+** <ol>
9678
+** <li><p> The P->aConstraintUsage[N].argvIndex value is set to a positive
9679
+** integer. This is how the virtual table tells SQLite that it wants to
9680
+** use the N-th constraint.
9681
+**
9682
+** <li><p> The last call to sqlite3_vtab_in(P,N,F) for which F was
9683
+** non-negative had F>=1.
9684
+** </ol>)^
9685
+**
9686
+** ^If either or both of the conditions above are false, then SQLite uses
9687
+** the traditional one-at-a-time processing strategy for the IN constraint.
9688
+** ^If both conditions are true, then the argvIndex-th parameter to the
9689
+** xFilter method will be an [sqlite3_value] that appears to be NULL,
9690
+** but which can be passed to [sqlite3_vtab_in_first()] and
9691
+** [sqlite3_vtab_in_next()] to find all values on the right-hand side
9692
+** of the IN constraint.
9693
+*/
9694
+SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
9695
+
9696
+/*
9697
+** CAPI3REF: Find all elements on the right-hand side of an IN constraint.
9698
+**
9699
+** These interfaces are only useful from within the
9700
+** [xFilter|xFilter() method] of a [virtual table] implementation.
9701
+** The result of invoking these interfaces from any other context
9702
+** is undefined and probably harmful.
9703
+**
9704
+** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
9705
+** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
9706
+** xFilter method which invokes these routines, and specifically
9707
+** a parameter that was previously selected for all-at-once IN constraint
9708
+** processing use the [sqlite3_vtab_in()] interface in the
9709
+** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
9710
+** an xFilter argument that was selected for all-at-once IN constraint
9711
+** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
9712
+** exhibit some other undefined or harmful behavior.
9713
+**
9714
+** ^(Use these routines to access all values on the right-hand side
9715
+** of the IN constraint using code like the following:
9716
+**
9717
+** <blockquote><pre>
9718
+** &nbsp; for(rc=sqlite3_vtab_in_first(pList, &pVal);
9719
+** &nbsp; rc==SQLITE_OK && pVal
9720
+** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
9721
+** &nbsp; ){
9722
+** &nbsp; // do something with pVal
9723
+** &nbsp; }
9724
+** &nbsp; if( rc!=SQLITE_OK ){
9725
+** &nbsp; // an error has occurred
9726
+** &nbsp; }
9727
+** </pre></blockquote>)^
9728
+**
9729
+** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
9730
+** routines return SQLITE_OK and set *P to point to the first or next value
9731
+** on the RHS of the IN constraint. ^If there are no more values on the
9732
+** right hand side of the IN constraint, then *P is set to NULL and these
9733
+** routines return [SQLITE_DONE]. ^The return value might be
9734
+** some other value, such as SQLITE_NOMEM, in the event of a malfunction.
9735
+**
9736
+** The *ppOut values returned by these routines are only valid until the
9737
+** next call to either of these routines or until the end of the xFilter
9738
+** method from which these routines were called. If the virtual table
9739
+** implementation needs to retain the *ppOut values for longer, it must make
9740
+** copies. The *ppOut values are [protected sqlite3_value|protected].
9741
+*/
9742
+SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
9743
+SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
9744
+
95729745
/*
95739746
** CAPI3REF: Constraint values in xBestIndex()
95749747
** METHOD: sqlite3_index_info
95759748
**
9576
-** This API may only be used from within an xBestIndex() callback. The
9577
-** results of calling it from outside of an xBestIndex() callback are
9578
-** undefined and probably harmful.
9749
+** This API may only be used from within the [xBestIndex|xBestIndex method]
9750
+** of a [virtual table] implementation. The result of calling this interface
9751
+** from outside of an xBestIndex method are undefined and probably harmful.
95799752
**
95809753
** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
95819754
** the [xBestIndex] method of a [virtual table] implementation, with P being
95829755
** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
95839756
** J being a 0-based index into P->aConstraint[], then this routine
9584
-** attempts to set *V to be the value on the right-hand side of
9585
-** that constraint if the right-hand side is a known constant. ^If the
9586
-** right-hand side of the constraint is not known, then *V is set to a NULL
9587
-** pointer. ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
9757
+** attempts to set *V to the value of the right-hand operand of
9758
+** that constraint if the right-hand operand is known. ^If the
9759
+** right-hand operand is not known, then *V is set to a NULL pointer.
9760
+** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
95889761
** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
95899762
** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
95909763
** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
95919764
** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
95929765
** something goes wrong.
95939766
**
9594
-** ^The sqlite3_value object returned in *V remains valid for the duration of
9595
-** the xBestIndex method code. ^When xBestIndex returns, the sqlite3_value
9596
-** object returned by sqlite3_vtab_rhs_value() is automatically deallocated.
9767
+** The sqlite3_vtab_rhs_value() interface is usually only successful if
9768
+** the right-hand operand of a constraint is a literal value in the original
9769
+** SQL statement. If the right-hand operand is an expression or a reference
9770
+** to some other column or a [host parameter], then sqlite3_vtab_rhs_value()
9771
+** will probably return [SQLITE_NOTFOUND].
9772
+**
9773
+** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and
9774
+** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such
9775
+** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^
9776
+**
9777
+** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value
9778
+** and remains valid for the duration of the xBestIndex method call.
9779
+** ^When xBestIndex returns, the sqlite3_value object returned by
9780
+** sqlite3_vtab_rhs_value() is automatically deallocated.
9781
+**
9782
+** The "_rhs_" in the name of this routine is an abbreviation for
9783
+** "Right-Hand Side".
95979784
*/
95989785
SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
95999786
96009787
/*
96019788
** CAPI3REF: Conflict resolution modes
96029789
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,13 +144,13 @@
144 **
145 ** See also: [sqlite3_libversion()],
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.38.0"
150 #define SQLITE_VERSION_NUMBER 3038000
151 #define SQLITE_SOURCE_ID "2022-01-25 00:03:25 a8db69411b0d1275909adeb21027784ada17af24efe3a59ae0ae2a897659ff17"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -564,11 +564,11 @@
564 #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
565 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
566 #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
567 #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
568 #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
569 #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
570
571 /*
572 ** CAPI3REF: Flags For File Open Operations
573 **
574 ** These bit values are intended for use in the
@@ -3848,11 +3848,11 @@
3848 **
3849 ** ^If the most recent error references a specific token in the input
3850 ** SQL, the sqlite3_error_offset() interface returns the byte offset
3851 ** of the start of that token. ^The byte offset returned by
3852 ** sqlite3_error_offset() assumes that the input SQL is UTF8.
3853 ** ^If the most error does not reference a specific token in the input
3854 ** SQL, then the sqlite3_error_offset() function returns -1.
3855 **
3856 ** When the serialized [threading mode] is in use, it might be the
3857 ** case that a second error occurs on a separate thread in between
3858 ** the time of the first error and the call to these interfaces.
@@ -4282,10 +4282,14 @@
4282 ** ^For example, an UPDATE statement might have a WHERE clause that
4283 ** makes it a no-op, but the sqlite3_stmt_readonly() result would still
4284 ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
4285 ** read-only no-op if the table already exists, but
4286 ** sqlite3_stmt_readonly() still returns false for such a statement.
 
 
 
 
4287 */
4288 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
4289
4290 /*
4291 ** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4350,10 +4354,12 @@
4350 ** still make the distinction between protected and unprotected
4351 ** sqlite3_value objects even when not strictly required.
4352 **
4353 ** ^The sqlite3_value objects that are passed as parameters into the
4354 ** implementation of [application-defined SQL functions] are protected.
 
 
4355 ** ^The sqlite3_value object returned by
4356 ** [sqlite3_column_value()] is unprotected.
4357 ** Unprotected sqlite3_value objects may only be used as arguments
4358 ** to [sqlite3_result_value()], [sqlite3_bind_value()], and
4359 ** [sqlite3_value_dup()].
@@ -4970,10 +4976,14 @@
4970 ** bytes in the string, not the number of characters.
4971 **
4972 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
4973 ** even empty strings, are always zero-terminated. ^The return
4974 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
 
 
 
 
4975 **
4976 ** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
4977 ** [unprotected sqlite3_value] object. In a multithreaded environment,
4978 ** an unprotected sqlite3_value object may only be used safely with
4979 ** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -4984,11 +4994,11 @@
4984 ** Hence, the sqlite3_column_value() interface
4985 ** is normally only useful within the implementation of
4986 ** [application-defined SQL functions] or [virtual tables], not within
4987 ** top-level application code.
4988 **
4989 ** The these routines may attempt to convert the datatype of the result.
4990 ** ^For example, if the internal representation is FLOAT and a text result
4991 ** is requested, [sqlite3_snprintf()] is used internally to perform the
4992 ** conversion automatically. ^(The following table details the conversions
4993 ** that are applied:
4994 **
@@ -5009,11 +5019,11 @@
5009 ** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
5010 ** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
5011 ** <tr><td> TEXT <td> BLOB <td> No change
5012 ** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
5013 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5014 ** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
5015 ** </table>
5016 ** </blockquote>)^
5017 **
5018 ** Note that when type conversions occur, pointers returned by prior
5019 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5581,11 +5591,12 @@
5581 **
5582 ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
5583 ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
5584 ** is a [protected sqlite3_value] object even if the input is not.
5585 ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5586 ** memory allocation fails.
 
5587 **
5588 ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
5589 ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
5590 ** then sqlite3_value_free(V) is a harmless no-op.
5591 */
@@ -7129,28 +7140,60 @@
7129 /*
7130 ** CAPI3REF: Virtual Table Constraint Operator Codes
7131 **
7132 ** These macros define the allowed values for the
7133 ** [sqlite3_index_info].aConstraint[].op field. Each value represents
7134 ** an operator that is part of a constraint term in the wHERE clause of
7135 ** a query that uses a [virtual table].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7136 */
7137 #define SQLITE_INDEX_CONSTRAINT_EQ 2
7138 #define SQLITE_INDEX_CONSTRAINT_GT 4
7139 #define SQLITE_INDEX_CONSTRAINT_LE 8
7140 #define SQLITE_INDEX_CONSTRAINT_LT 16
7141 #define SQLITE_INDEX_CONSTRAINT_GE 32
7142 #define SQLITE_INDEX_CONSTRAINT_MATCH 64
7143 #define SQLITE_INDEX_CONSTRAINT_LIKE 65
7144 #define SQLITE_INDEX_CONSTRAINT_GLOB 66
7145 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7146 #define SQLITE_INDEX_CONSTRAINT_NE 68
7147 #define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7148 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7149 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7150 #define SQLITE_INDEX_CONSTRAINT_IS 72
7151 #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
 
 
7152
7153 /*
7154 ** CAPI3REF: Register A Virtual Table Implementation
7155 ** METHOD: sqlite3
7156 **
@@ -7175,11 +7218,11 @@
7175 ** ^The sqlite3_create_module()
7176 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
7177 ** destructor.
7178 **
7179 ** ^If the third parameter (the pointer to the sqlite3_module object) is
7180 ** NULL then no new module is create and any existing modules with the
7181 ** same name are dropped.
7182 **
7183 ** See also: [sqlite3_drop_modules()]
7184 */
7185 SQLITE_API int sqlite3_create_module(
@@ -9506,28 +9549,29 @@
9506
9507 /*
9508 ** CAPI3REF: Determine if a virtual table query is DISTINCT
9509 ** METHOD: sqlite3_index_info
9510 **
9511 ** This API may only be used from within an xBestIndex() callback. The
9512 ** results of calling it from outside of an xBestIndex() callback are
9513 ** undefined and probably harmful.
9514 **
9515 ** ^The sqlite3_vtab_distinct() returns an integer that is either 0, 1, or
9516 ** 2. The integer returned by sqlite3_vtab_distinct() gives the virtual table
9517 ** additional information about how the query planner wants the output to be
9518 ** ordered. As long as the virtual table can meet the ordering requirements
9519 ** of the query planner, it may set the "orderByConsumed" flag.
 
9520 **
9521 ** <ol><li value="0"><p>
9522 ** ^If the sqlite3_vtab_distinct() interface returns 0, that means
9523 ** that the query planner needs the virtual table to return all rows in the
9524 ** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
9525 ** [sqlite3_index_info] object. This is the default expectation. If the
9526 ** virtual table outputs all rows in sorted order, then it is always safe for
9527 ** the xBestIndex method to set the "orderByConsumed" flag, regardless of
9528 ** what the return value from sqlite3_vtab_distinct().
9529 ** <li value="1"><p>
9530 ** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
9531 ** that the query planner does not need the rows to be returned in sorted order
9532 ** as long as all rows with the same values in all columns identified by the
9533 ** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
@@ -9536,16 +9580,23 @@
9536 ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
9537 ** that the query planner does not need the rows returned in any particular
9538 ** order, as long as rows with the same values in all "aOrderBy" columns
9539 ** are adjacent.)^ ^(Furthermore, only a single row for each particular
9540 ** combination of values in the columns identified by the "aOrderBy" field
9541 ** needs to be returned.)^ ^It is ok always for two or more rows with the same
9542 ** values in all "aOrderBy" columns to be returned, as long as all such rows
9543 ** are adjacent. ^The virtual table may, if it chooses, omit extra rows
9544 ** that have the same value for all columns identified by "aOrderBy".
9545 ** ^However omitting the extra rows is optional.
9546 ** This mode is used for a DISTINCT query.
 
 
 
 
 
 
 
9547 ** </ol>
9548 **
9549 ** ^For the purposes of comparing virtual table output values to see if the
9550 ** values are same value for sorting purposes, two NULL values are considered
9551 ** to be the same. In other words, the comparison operator is "IS"
@@ -9567,35 +9618,171 @@
9567 ** valid to do so, on the other hand, might cause SQLite to return incorrect
9568 ** results.
9569 */
9570 SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
9571
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9572 /*
9573 ** CAPI3REF: Constraint values in xBestIndex()
9574 ** METHOD: sqlite3_index_info
9575 **
9576 ** This API may only be used from within an xBestIndex() callback. The
9577 ** results of calling it from outside of an xBestIndex() callback are
9578 ** undefined and probably harmful.
9579 **
9580 ** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
9581 ** the [xBestIndex] method of a [virtual table] implementation, with P being
9582 ** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
9583 ** J being a 0-based index into P->aConstraint[], then this routine
9584 ** attempts to set *V to be the value on the right-hand side of
9585 ** that constraint if the right-hand side is a known constant. ^If the
9586 ** right-hand side of the constraint is not known, then *V is set to a NULL
9587 ** pointer. ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
9588 ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
9589 ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
9590 ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
9591 ** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
9592 ** something goes wrong.
9593 **
9594 ** ^The sqlite3_value object returned in *V remains valid for the duration of
9595 ** the xBestIndex method code. ^When xBestIndex returns, the sqlite3_value
9596 ** object returned by sqlite3_vtab_rhs_value() is automatically deallocated.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9597 */
9598 SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
9599
9600 /*
9601 ** CAPI3REF: Conflict resolution modes
9602
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -144,13 +144,13 @@
144 **
145 ** See also: [sqlite3_libversion()],
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.39.0"
150 #define SQLITE_VERSION_NUMBER 3039000
151 #define SQLITE_SOURCE_ID "2022-04-01 17:23:17 a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -564,11 +564,11 @@
564 #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
565 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
566 #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
567 #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
568 #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
569 #define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
570
571 /*
572 ** CAPI3REF: Flags For File Open Operations
573 **
574 ** These bit values are intended for use in the
@@ -3848,11 +3848,11 @@
3848 **
3849 ** ^If the most recent error references a specific token in the input
3850 ** SQL, the sqlite3_error_offset() interface returns the byte offset
3851 ** of the start of that token. ^The byte offset returned by
3852 ** sqlite3_error_offset() assumes that the input SQL is UTF8.
3853 ** ^If the most recent error does not reference a specific token in the input
3854 ** SQL, then the sqlite3_error_offset() function returns -1.
3855 **
3856 ** When the serialized [threading mode] is in use, it might be the
3857 ** case that a second error occurs on a separate thread in between
3858 ** the time of the first error and the call to these interfaces.
@@ -4282,10 +4282,14 @@
4282 ** ^For example, an UPDATE statement might have a WHERE clause that
4283 ** makes it a no-op, but the sqlite3_stmt_readonly() result would still
4284 ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
4285 ** read-only no-op if the table already exists, but
4286 ** sqlite3_stmt_readonly() still returns false for such a statement.
4287 **
4288 ** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN]
4289 ** statement, then sqlite3_stmt_readonly(X) returns the same value as
4290 ** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted.
4291 */
4292 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
4293
4294 /*
4295 ** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
@@ -4350,10 +4354,12 @@
4354 ** still make the distinction between protected and unprotected
4355 ** sqlite3_value objects even when not strictly required.
4356 **
4357 ** ^The sqlite3_value objects that are passed as parameters into the
4358 ** implementation of [application-defined SQL functions] are protected.
4359 ** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()]
4360 ** are protected.
4361 ** ^The sqlite3_value object returned by
4362 ** [sqlite3_column_value()] is unprotected.
4363 ** Unprotected sqlite3_value objects may only be used as arguments
4364 ** to [sqlite3_result_value()], [sqlite3_bind_value()], and
4365 ** [sqlite3_value_dup()].
@@ -4970,10 +4976,14 @@
4976 ** bytes in the string, not the number of characters.
4977 **
4978 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
4979 ** even empty strings, are always zero-terminated. ^The return
4980 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
4981 **
4982 ** ^Strings returned by sqlite3_column_text16() always have the endianness
4983 ** which is native to the platform, regardless of the text encoding set
4984 ** for the database.
4985 **
4986 ** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
4987 ** [unprotected sqlite3_value] object. In a multithreaded environment,
4988 ** an unprotected sqlite3_value object may only be used safely with
4989 ** [sqlite3_bind_value()] and [sqlite3_result_value()].
@@ -4984,11 +4994,11 @@
4994 ** Hence, the sqlite3_column_value() interface
4995 ** is normally only useful within the implementation of
4996 ** [application-defined SQL functions] or [virtual tables], not within
4997 ** top-level application code.
4998 **
4999 ** These routines may attempt to convert the datatype of the result.
5000 ** ^For example, if the internal representation is FLOAT and a text result
5001 ** is requested, [sqlite3_snprintf()] is used internally to perform the
5002 ** conversion automatically. ^(The following table details the conversions
5003 ** that are applied:
5004 **
@@ -5009,11 +5019,11 @@
5019 ** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
5020 ** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
5021 ** <tr><td> TEXT <td> BLOB <td> No change
5022 ** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
5023 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
5024 ** <tr><td> BLOB <td> TEXT <td> [CAST] to TEXT, ensure zero terminator
5025 ** </table>
5026 ** </blockquote>)^
5027 **
5028 ** Note that when type conversions occur, pointers returned by prior
5029 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
@@ -5581,11 +5591,12 @@
5591 **
5592 ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
5593 ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
5594 ** is a [protected sqlite3_value] object even if the input is not.
5595 ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
5596 ** memory allocation fails. ^If V is a [pointer value], then the result
5597 ** of sqlite3_value_dup(V) is a NULL value.
5598 **
5599 ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
5600 ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
5601 ** then sqlite3_value_free(V) is a harmless no-op.
5602 */
@@ -7129,28 +7140,60 @@
7140 /*
7141 ** CAPI3REF: Virtual Table Constraint Operator Codes
7142 **
7143 ** These macros define the allowed values for the
7144 ** [sqlite3_index_info].aConstraint[].op field. Each value represents
7145 ** an operator that is part of a constraint term in the WHERE clause of
7146 ** a query that uses a [virtual table].
7147 **
7148 ** ^The left-hand operand of the operator is given by the corresponding
7149 ** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand
7150 ** operand is the rowid.
7151 ** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET
7152 ** operators have no left-hand operand, and so for those operators the
7153 ** corresponding aConstraint[].iColumn is meaningless and should not be
7154 ** used.
7155 **
7156 ** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through
7157 ** value 255 are reserved to represent functions that are overloaded
7158 ** by the [xFindFunction|xFindFunction method] of the virtual table
7159 ** implementation.
7160 **
7161 ** The right-hand operands for each constraint might be accessible using
7162 ** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand
7163 ** operand is only available if it appears as a single constant literal
7164 ** in the input SQL. If the right-hand operand is another column or an
7165 ** expression (even a constant expression) or a parameter, then the
7166 ** sqlite3_vtab_rhs_value() probably will not be able to extract it.
7167 ** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and
7168 ** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand
7169 ** and hence calls to sqlite3_vtab_rhs_value() for those operators will
7170 ** always return SQLITE_NOTFOUND.
7171 **
7172 ** The collating sequence to be used for comparison can be found using
7173 ** the [sqlite3_vtab_collation()] interface. For most real-world virtual
7174 ** tables, the collating sequence of constraints does not matter (for example
7175 ** because the constraints are numeric) and so the sqlite3_vtab_collation()
7176 ** interface is no commonly needed.
7177 */
7178 #define SQLITE_INDEX_CONSTRAINT_EQ 2
7179 #define SQLITE_INDEX_CONSTRAINT_GT 4
7180 #define SQLITE_INDEX_CONSTRAINT_LE 8
7181 #define SQLITE_INDEX_CONSTRAINT_LT 16
7182 #define SQLITE_INDEX_CONSTRAINT_GE 32
7183 #define SQLITE_INDEX_CONSTRAINT_MATCH 64
7184 #define SQLITE_INDEX_CONSTRAINT_LIKE 65
7185 #define SQLITE_INDEX_CONSTRAINT_GLOB 66
7186 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67
7187 #define SQLITE_INDEX_CONSTRAINT_NE 68
7188 #define SQLITE_INDEX_CONSTRAINT_ISNOT 69
7189 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
7190 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71
7191 #define SQLITE_INDEX_CONSTRAINT_IS 72
7192 #define SQLITE_INDEX_CONSTRAINT_LIMIT 73
7193 #define SQLITE_INDEX_CONSTRAINT_OFFSET 74
7194 #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
7195
7196 /*
7197 ** CAPI3REF: Register A Virtual Table Implementation
7198 ** METHOD: sqlite3
7199 **
@@ -7175,11 +7218,11 @@
7218 ** ^The sqlite3_create_module()
7219 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
7220 ** destructor.
7221 **
7222 ** ^If the third parameter (the pointer to the sqlite3_module object) is
7223 ** NULL then no new module is created and any existing modules with the
7224 ** same name are dropped.
7225 **
7226 ** See also: [sqlite3_drop_modules()]
7227 */
7228 SQLITE_API int sqlite3_create_module(
@@ -9506,28 +9549,29 @@
9549
9550 /*
9551 ** CAPI3REF: Determine if a virtual table query is DISTINCT
9552 ** METHOD: sqlite3_index_info
9553 **
9554 ** This API may only be used from within an [xBestIndex|xBestIndex method]
9555 ** of a [virtual table] implementation. The result of calling this
9556 ** interface from outside of xBestIndex() is undefined and probably harmful.
9557 **
9558 ** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and
9559 ** 3. The integer returned by sqlite3_vtab_distinct()
9560 ** gives the virtual table additional information about how the query
9561 ** planner wants the output to be ordered. As long as the virtual table
9562 ** can meet the ordering requirements of the query planner, it may set
9563 ** the "orderByConsumed" flag.
9564 **
9565 ** <ol><li value="0"><p>
9566 ** ^If the sqlite3_vtab_distinct() interface returns 0, that means
9567 ** that the query planner needs the virtual table to return all rows in the
9568 ** sort order defined by the "nOrderBy" and "aOrderBy" fields of the
9569 ** [sqlite3_index_info] object. This is the default expectation. If the
9570 ** virtual table outputs all rows in sorted order, then it is always safe for
9571 ** the xBestIndex method to set the "orderByConsumed" flag, regardless of
9572 ** the return value from sqlite3_vtab_distinct().
9573 ** <li value="1"><p>
9574 ** ^(If the sqlite3_vtab_distinct() interface returns 1, that means
9575 ** that the query planner does not need the rows to be returned in sorted order
9576 ** as long as all rows with the same values in all columns identified by the
9577 ** "aOrderBy" field are adjacent.)^ This mode is used when the query planner
@@ -9536,16 +9580,23 @@
9580 ** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
9581 ** that the query planner does not need the rows returned in any particular
9582 ** order, as long as rows with the same values in all "aOrderBy" columns
9583 ** are adjacent.)^ ^(Furthermore, only a single row for each particular
9584 ** combination of values in the columns identified by the "aOrderBy" field
9585 ** needs to be returned.)^ ^It is always ok for two or more rows with the same
9586 ** values in all "aOrderBy" columns to be returned, as long as all such rows
9587 ** are adjacent. ^The virtual table may, if it chooses, omit extra rows
9588 ** that have the same value for all columns identified by "aOrderBy".
9589 ** ^However omitting the extra rows is optional.
9590 ** This mode is used for a DISTINCT query.
9591 ** <li value="3"><p>
9592 ** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
9593 ** that the query planner needs only distinct rows but it does need the
9594 ** rows to be sorted.)^ ^The virtual table implementation is free to omit
9595 ** rows that are identical in all aOrderBy columns, if it wants to, but
9596 ** it is not required to omit any rows. This mode is used for queries
9597 ** that have both DISTINCT and ORDER BY clauses.
9598 ** </ol>
9599 **
9600 ** ^For the purposes of comparing virtual table output values to see if the
9601 ** values are same value for sorting purposes, two NULL values are considered
9602 ** to be the same. In other words, the comparison operator is "IS"
@@ -9567,35 +9618,171 @@
9618 ** valid to do so, on the other hand, might cause SQLite to return incorrect
9619 ** results.
9620 */
9621 SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*);
9622
9623 /*
9624 ** CAPI3REF: Identify and handle IN constraints in xBestIndex
9625 **
9626 ** This interface may only be used from within an
9627 ** [xBestIndex|xBestIndex() method] of a [virtual table] implementation.
9628 ** The result of invoking this interface from any other context is
9629 ** undefined and probably harmful.
9630 **
9631 ** ^(A constraint on a virtual table of the form
9632 ** "[IN operator|column IN (...)]" is
9633 ** communicated to the xBestIndex method as a
9634 ** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use
9635 ** this constraint, it must set the corresponding
9636 ** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under
9637 ** the usual mode of handling IN operators, SQLite generates [bytecode]
9638 ** that invokes the [xFilter|xFilter() method] once for each value
9639 ** on the right-hand side of the IN operator.)^ Thus the virtual table
9640 ** only sees a single value from the right-hand side of the IN operator
9641 ** at a time.
9642 **
9643 ** In some cases, however, it would be advantageous for the virtual
9644 ** table to see all values on the right-hand of the IN operator all at
9645 ** once. The sqlite3_vtab_in() interfaces facilitates this in two ways:
9646 **
9647 ** <ol>
9648 ** <li><p>
9649 ** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero)
9650 ** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint
9651 ** is an [IN operator] that can be processed all at once. ^In other words,
9652 ** sqlite3_vtab_in() with -1 in the third argument is a mechanism
9653 ** by which the virtual table can ask SQLite if all-at-once processing
9654 ** of the IN operator is even possible.
9655 **
9656 ** <li><p>
9657 ** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates
9658 ** to SQLite that the virtual table does or does not want to process
9659 ** the IN operator all-at-once, respectively. ^Thus when the third
9660 ** parameter (F) is non-negative, this interface is the mechanism by
9661 ** which the virtual table tells SQLite how it wants to process the
9662 ** IN operator.
9663 ** </ol>
9664 **
9665 ** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times
9666 ** within the same xBestIndex method call. ^For any given P,N pair,
9667 ** the return value from sqlite3_vtab_in(P,N,F) will always be the same
9668 ** within the same xBestIndex call. ^If the interface returns true
9669 ** (non-zero), that means that the constraint is an IN operator
9670 ** that can be processed all-at-once. ^If the constraint is not an IN
9671 ** operator or cannot be processed all-at-once, then the interface returns
9672 ** false.
9673 **
9674 ** ^(All-at-once processing of the IN operator is selected if both of the
9675 ** following conditions are met:
9676 **
9677 ** <ol>
9678 ** <li><p> The P->aConstraintUsage[N].argvIndex value is set to a positive
9679 ** integer. This is how the virtual table tells SQLite that it wants to
9680 ** use the N-th constraint.
9681 **
9682 ** <li><p> The last call to sqlite3_vtab_in(P,N,F) for which F was
9683 ** non-negative had F>=1.
9684 ** </ol>)^
9685 **
9686 ** ^If either or both of the conditions above are false, then SQLite uses
9687 ** the traditional one-at-a-time processing strategy for the IN constraint.
9688 ** ^If both conditions are true, then the argvIndex-th parameter to the
9689 ** xFilter method will be an [sqlite3_value] that appears to be NULL,
9690 ** but which can be passed to [sqlite3_vtab_in_first()] and
9691 ** [sqlite3_vtab_in_next()] to find all values on the right-hand side
9692 ** of the IN constraint.
9693 */
9694 SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
9695
9696 /*
9697 ** CAPI3REF: Find all elements on the right-hand side of an IN constraint.
9698 **
9699 ** These interfaces are only useful from within the
9700 ** [xFilter|xFilter() method] of a [virtual table] implementation.
9701 ** The result of invoking these interfaces from any other context
9702 ** is undefined and probably harmful.
9703 **
9704 ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
9705 ** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
9706 ** xFilter method which invokes these routines, and specifically
9707 ** a parameter that was previously selected for all-at-once IN constraint
9708 ** processing use the [sqlite3_vtab_in()] interface in the
9709 ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not
9710 ** an xFilter argument that was selected for all-at-once IN constraint
9711 ** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
9712 ** exhibit some other undefined or harmful behavior.
9713 **
9714 ** ^(Use these routines to access all values on the right-hand side
9715 ** of the IN constraint using code like the following:
9716 **
9717 ** <blockquote><pre>
9718 ** &nbsp; for(rc=sqlite3_vtab_in_first(pList, &pVal);
9719 ** &nbsp; rc==SQLITE_OK && pVal
9720 ** &nbsp; rc=sqlite3_vtab_in_next(pList, &pVal)
9721 ** &nbsp; ){
9722 ** &nbsp; // do something with pVal
9723 ** &nbsp; }
9724 ** &nbsp; if( rc!=SQLITE_OK ){
9725 ** &nbsp; // an error has occurred
9726 ** &nbsp; }
9727 ** </pre></blockquote>)^
9728 **
9729 ** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
9730 ** routines return SQLITE_OK and set *P to point to the first or next value
9731 ** on the RHS of the IN constraint. ^If there are no more values on the
9732 ** right hand side of the IN constraint, then *P is set to NULL and these
9733 ** routines return [SQLITE_DONE]. ^The return value might be
9734 ** some other value, such as SQLITE_NOMEM, in the event of a malfunction.
9735 **
9736 ** The *ppOut values returned by these routines are only valid until the
9737 ** next call to either of these routines or until the end of the xFilter
9738 ** method from which these routines were called. If the virtual table
9739 ** implementation needs to retain the *ppOut values for longer, it must make
9740 ** copies. The *ppOut values are [protected sqlite3_value|protected].
9741 */
9742 SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
9743 SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
9744
9745 /*
9746 ** CAPI3REF: Constraint values in xBestIndex()
9747 ** METHOD: sqlite3_index_info
9748 **
9749 ** This API may only be used from within the [xBestIndex|xBestIndex method]
9750 ** of a [virtual table] implementation. The result of calling this interface
9751 ** from outside of an xBestIndex method are undefined and probably harmful.
9752 **
9753 ** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within
9754 ** the [xBestIndex] method of a [virtual table] implementation, with P being
9755 ** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and
9756 ** J being a 0-based index into P->aConstraint[], then this routine
9757 ** attempts to set *V to the value of the right-hand operand of
9758 ** that constraint if the right-hand operand is known. ^If the
9759 ** right-hand operand is not known, then *V is set to a NULL pointer.
9760 ** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if
9761 ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V)
9762 ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th
9763 ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface
9764 ** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if
9765 ** something goes wrong.
9766 **
9767 ** The sqlite3_vtab_rhs_value() interface is usually only successful if
9768 ** the right-hand operand of a constraint is a literal value in the original
9769 ** SQL statement. If the right-hand operand is an expression or a reference
9770 ** to some other column or a [host parameter], then sqlite3_vtab_rhs_value()
9771 ** will probably return [SQLITE_NOTFOUND].
9772 **
9773 ** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and
9774 ** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such
9775 ** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^
9776 **
9777 ** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value
9778 ** and remains valid for the duration of the xBestIndex method call.
9779 ** ^When xBestIndex returns, the sqlite3_value object returned by
9780 ** sqlite3_vtab_rhs_value() is automatically deallocated.
9781 **
9782 ** The "_rhs_" in the name of this routine is an abbreviation for
9783 ** "Right-Hand Side".
9784 */
9785 SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
9786
9787 /*
9788 ** CAPI3REF: Conflict resolution modes
9789
+3 -3
--- src/alerts.c
+++ src/alerts.c
@@ -314,11 +314,11 @@
314314
entry_attribute("Pipe Email Text Into This Command", 60, "email-send-command",
315315
"ecmd", "sendmail -ti", 0);
316316
@ <p>When the send method is "pipe to a command", this is the command
317317
@ that is run. Email messages are piped into the standard input of this
318318
@ command. The command is expected to extract the sender address,
319
- @ recepient addresses, and subject from the header of the piped email
319
+ @ recipient addresses, and subject from the header of the piped email
320320
@ text. (Property: "email-send-command")</p>
321321
322322
entry_attribute("Store Emails In This Database", 60, "email-send-db",
323323
"esdb", "", 0);
324324
@ <p>When the send method is "store in a database", each email message is
@@ -816,11 +816,11 @@
816816
}
817817
818818
/*
819819
** Send a single email message.
820820
**
821
-** The recepient(s) must be specified using "To:" or "Cc:" or "Bcc:" fields
821
+** The recipient(s) must be specified using "To:" or "Cc:" or "Bcc:" fields
822822
** in the header. Likewise, the header must contains a "Subject:" line.
823823
** The header might also include fields like "Message-Id:" or
824824
** "In-Reply-To:".
825825
**
826826
** This routine will add fields to the header as follows:
@@ -2325,11 +2325,11 @@
23252325
sqlite3_int64 iMtime = db_column_int64(&q, 6);
23262326
double rAge = (iNow - iMtime)/86400.0;
23272327
int uid = db_column_int(&q, 8);
23282328
const char *zUname = db_column_text(&q, 3);
23292329
sqlite3_int64 iContact = db_column_int64(&q, 9);
2330
- double rContact = (iNow/86400) - iContact;
2330
+ double rContact = (iNow/86400.0) - iContact;
23312331
@ <tr>
23322332
@ <td><a href='%R/alerts?sid=%d(db_column_int(&q,0))'>\
23332333
@ %h(db_column_text(&q,1))</a></td>
23342334
@ <td>%h(db_column_text(&q,2))</td>
23352335
@ <td>%s(db_column_int(&q,5)?"digest":"")</td>
23362336
--- src/alerts.c
+++ src/alerts.c
@@ -314,11 +314,11 @@
314 entry_attribute("Pipe Email Text Into This Command", 60, "email-send-command",
315 "ecmd", "sendmail -ti", 0);
316 @ <p>When the send method is "pipe to a command", this is the command
317 @ that is run. Email messages are piped into the standard input of this
318 @ command. The command is expected to extract the sender address,
319 @ recepient addresses, and subject from the header of the piped email
320 @ text. (Property: "email-send-command")</p>
321
322 entry_attribute("Store Emails In This Database", 60, "email-send-db",
323 "esdb", "", 0);
324 @ <p>When the send method is "store in a database", each email message is
@@ -816,11 +816,11 @@
816 }
817
818 /*
819 ** Send a single email message.
820 **
821 ** The recepient(s) must be specified using "To:" or "Cc:" or "Bcc:" fields
822 ** in the header. Likewise, the header must contains a "Subject:" line.
823 ** The header might also include fields like "Message-Id:" or
824 ** "In-Reply-To:".
825 **
826 ** This routine will add fields to the header as follows:
@@ -2325,11 +2325,11 @@
2325 sqlite3_int64 iMtime = db_column_int64(&q, 6);
2326 double rAge = (iNow - iMtime)/86400.0;
2327 int uid = db_column_int(&q, 8);
2328 const char *zUname = db_column_text(&q, 3);
2329 sqlite3_int64 iContact = db_column_int64(&q, 9);
2330 double rContact = (iNow/86400) - iContact;
2331 @ <tr>
2332 @ <td><a href='%R/alerts?sid=%d(db_column_int(&q,0))'>\
2333 @ %h(db_column_text(&q,1))</a></td>
2334 @ <td>%h(db_column_text(&q,2))</td>
2335 @ <td>%s(db_column_int(&q,5)?"digest":"")</td>
2336
--- src/alerts.c
+++ src/alerts.c
@@ -314,11 +314,11 @@
314 entry_attribute("Pipe Email Text Into This Command", 60, "email-send-command",
315 "ecmd", "sendmail -ti", 0);
316 @ <p>When the send method is "pipe to a command", this is the command
317 @ that is run. Email messages are piped into the standard input of this
318 @ command. The command is expected to extract the sender address,
319 @ recipient addresses, and subject from the header of the piped email
320 @ text. (Property: "email-send-command")</p>
321
322 entry_attribute("Store Emails In This Database", 60, "email-send-db",
323 "esdb", "", 0);
324 @ <p>When the send method is "store in a database", each email message is
@@ -816,11 +816,11 @@
816 }
817
818 /*
819 ** Send a single email message.
820 **
821 ** The recipient(s) must be specified using "To:" or "Cc:" or "Bcc:" fields
822 ** in the header. Likewise, the header must contains a "Subject:" line.
823 ** The header might also include fields like "Message-Id:" or
824 ** "In-Reply-To:".
825 **
826 ** This routine will add fields to the header as follows:
@@ -2325,11 +2325,11 @@
2325 sqlite3_int64 iMtime = db_column_int64(&q, 6);
2326 double rAge = (iNow - iMtime)/86400.0;
2327 int uid = db_column_int(&q, 8);
2328 const char *zUname = db_column_text(&q, 3);
2329 sqlite3_int64 iContact = db_column_int64(&q, 9);
2330 double rContact = (iNow/86400.0) - iContact;
2331 @ <tr>
2332 @ <td><a href='%R/alerts?sid=%d(db_column_int(&q,0))'>\
2333 @ %h(db_column_text(&q,1))</a></td>
2334 @ <td>%h(db_column_text(&q,2))</td>
2335 @ <td>%s(db_column_int(&q,5)?"digest":"")</td>
2336
--- src/bisect.c
+++ src/bisect.c
@@ -238,10 +238,11 @@
238238
i-1, zDesc+1
239239
);
240240
if( rid==0 ) break;
241241
blob_appendf(&log, "%d", rid);
242242
zDesc += i;
243
+ while( zDesc[0]=='-' ) zDesc++;
243244
}
244245
}else{
245246
zLog = db_lget("bisect-log","");
246247
blob_init(&log, zLog, -1);
247248
}
@@ -327,10 +328,11 @@
327328
cPrefix = 'n';
328329
rid = -rid;
329330
}
330331
}
331332
zUuid = db_text(0,"SELECT lower(uuid) FROM blob WHERE rid=%d", rid);
333
+ if( blob_size(&link)>0 ) blob_append(&link, "-", 1);
332334
blob_appendf(&link, "%c%.10s", cPrefix, zUuid);
333335
}
334336
zResult = mprintf("%s", blob_str(&link));
335337
blob_reset(&link);
336338
blob_reset(&log);
337339
--- src/bisect.c
+++ src/bisect.c
@@ -238,10 +238,11 @@
238 i-1, zDesc+1
239 );
240 if( rid==0 ) break;
241 blob_appendf(&log, "%d", rid);
242 zDesc += i;
 
243 }
244 }else{
245 zLog = db_lget("bisect-log","");
246 blob_init(&log, zLog, -1);
247 }
@@ -327,10 +328,11 @@
327 cPrefix = 'n';
328 rid = -rid;
329 }
330 }
331 zUuid = db_text(0,"SELECT lower(uuid) FROM blob WHERE rid=%d", rid);
 
332 blob_appendf(&link, "%c%.10s", cPrefix, zUuid);
333 }
334 zResult = mprintf("%s", blob_str(&link));
335 blob_reset(&link);
336 blob_reset(&log);
337
--- src/bisect.c
+++ src/bisect.c
@@ -238,10 +238,11 @@
238 i-1, zDesc+1
239 );
240 if( rid==0 ) break;
241 blob_appendf(&log, "%d", rid);
242 zDesc += i;
243 while( zDesc[0]=='-' ) zDesc++;
244 }
245 }else{
246 zLog = db_lget("bisect-log","");
247 blob_init(&log, zLog, -1);
248 }
@@ -327,10 +328,11 @@
328 cPrefix = 'n';
329 rid = -rid;
330 }
331 }
332 zUuid = db_text(0,"SELECT lower(uuid) FROM blob WHERE rid=%d", rid);
333 if( blob_size(&link)>0 ) blob_append(&link, "-", 1);
334 blob_appendf(&link, "%c%.10s", cPrefix, zUuid);
335 }
336 zResult = mprintf("%s", blob_str(&link));
337 blob_reset(&link);
338 blob_reset(&log);
339
+1 -1
--- src/branch.c
+++ src/branch.c
@@ -221,11 +221,11 @@
221221
222222
/* Commit */
223223
db_end_transaction(0);
224224
225225
/* Do an autosync push, if requested */
226
- if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries",1),0);
226
+ if( !isPrivate ) autosync_loop(SYNC_PUSH, 0, "branch");
227227
}
228228
229229
/*
230230
** Create a TEMP table named "tmp_brlist" with 7 columns:
231231
**
232232
--- src/branch.c
+++ src/branch.c
@@ -221,11 +221,11 @@
221
222 /* Commit */
223 db_end_transaction(0);
224
225 /* Do an autosync push, if requested */
226 if( !isPrivate ) autosync_loop(SYNC_PUSH, db_get_int("autosync-tries",1),0);
227 }
228
229 /*
230 ** Create a TEMP table named "tmp_brlist" with 7 columns:
231 **
232
--- src/branch.c
+++ src/branch.c
@@ -221,11 +221,11 @@
221
222 /* Commit */
223 db_end_transaction(0);
224
225 /* Do an autosync push, if requested */
226 if( !isPrivate ) autosync_loop(SYNC_PUSH, 0, "branch");
227 }
228
229 /*
230 ** Create a TEMP table named "tmp_brlist" with 7 columns:
231 **
232
+5 -4
--- src/browse.c
+++ src/browse.c
@@ -330,11 +330,12 @@
330330
** directory.
331331
*/
332332
mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
333333
if( mxLen<12 ) mxLen = 12;
334334
mxLen += (mxLen+9)/10;
335
- db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
335
+ db_prepare(&q,
336
+ "SELECT x, u FROM localfiles ORDER BY x COLLATE uintnocase /*scan*/");
336337
@ <div class="columns files" style="columns: %d(mxLen)ex auto">
337338
@ <ul class="browser">
338339
while( db_step(&q)==SQLITE_ROW ){
339340
const char *zFN;
340341
zFN = db_column_text(&q, 0);
@@ -368,11 +369,11 @@
368369
*/
369370
db_prepare(&q,
370371
"SELECT x, u FROM localfiles"
371372
" WHERE x COLLATE nocase IN"
372373
" ('readme','readme.txt','readme.md','readme.wiki','readme.markdown',"
373
- " 'readme.html') ORDER BY x LIMIT 1;"
374
+ " 'readme.html') ORDER BY x COLLATE uintnocase LIMIT 1;"
374375
);
375376
if( db_step(&q)==SQLITE_ROW ){
376377
const char *zName = db_column_text(&q,0);
377378
const char *zUuid = db_column_text(&q,1);
378379
if( zUuid ){
@@ -790,11 +791,11 @@
790791
db_prepare(&q,
791792
"SELECT filename.name, blob.uuid, fileage.mtime\n"
792793
" FROM fileage, filename, blob\n"
793794
" WHERE filename.fnid=fileage.fnid\n"
794795
" AND blob.rid=fileage.fid\n"
795
- " ORDER BY filename.name COLLATE nocase;"
796
+ " ORDER BY filename.name COLLATE uintnocase;"
796797
);
797798
while( db_step(&q)==SQLITE_ROW ){
798799
const char *zFile = db_column_text(&q,0);
799800
const char *zUuid = db_column_text(&q,1);
800801
double mtime = db_column_double(&q,2);
@@ -813,11 +814,11 @@
813814
" (SELECT name FROM filename WHERE filename.fnid=mlink.fnid),\n"
814815
" (SELECT uuid FROM blob WHERE blob.rid=mlink.fid),\n"
815816
" max(event.mtime)\n"
816817
" FROM mlink JOIN event ON event.objid=mlink.mid\n"
817818
" GROUP BY mlink.fnid\n"
818
- " ORDER BY 1 COLLATE nocase;");
819
+ " ORDER BY 1 COLLATE uintnocase;");
819820
while( db_step(&q)==SQLITE_ROW ){
820821
const char *zName = db_column_text(&q, 0);
821822
const char *zUuid = db_column_text(&q,1);
822823
double mtime = db_column_double(&q,2);
823824
if( nD>0 && (fossil_strncmp(zName, zD, nD-1)!=0 || zName[nD-1]!='/') ){
824825
--- src/browse.c
+++ src/browse.c
@@ -330,11 +330,12 @@
330 ** directory.
331 */
332 mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
333 if( mxLen<12 ) mxLen = 12;
334 mxLen += (mxLen+9)/10;
335 db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
 
336 @ <div class="columns files" style="columns: %d(mxLen)ex auto">
337 @ <ul class="browser">
338 while( db_step(&q)==SQLITE_ROW ){
339 const char *zFN;
340 zFN = db_column_text(&q, 0);
@@ -368,11 +369,11 @@
368 */
369 db_prepare(&q,
370 "SELECT x, u FROM localfiles"
371 " WHERE x COLLATE nocase IN"
372 " ('readme','readme.txt','readme.md','readme.wiki','readme.markdown',"
373 " 'readme.html') ORDER BY x LIMIT 1;"
374 );
375 if( db_step(&q)==SQLITE_ROW ){
376 const char *zName = db_column_text(&q,0);
377 const char *zUuid = db_column_text(&q,1);
378 if( zUuid ){
@@ -790,11 +791,11 @@
790 db_prepare(&q,
791 "SELECT filename.name, blob.uuid, fileage.mtime\n"
792 " FROM fileage, filename, blob\n"
793 " WHERE filename.fnid=fileage.fnid\n"
794 " AND blob.rid=fileage.fid\n"
795 " ORDER BY filename.name COLLATE nocase;"
796 );
797 while( db_step(&q)==SQLITE_ROW ){
798 const char *zFile = db_column_text(&q,0);
799 const char *zUuid = db_column_text(&q,1);
800 double mtime = db_column_double(&q,2);
@@ -813,11 +814,11 @@
813 " (SELECT name FROM filename WHERE filename.fnid=mlink.fnid),\n"
814 " (SELECT uuid FROM blob WHERE blob.rid=mlink.fid),\n"
815 " max(event.mtime)\n"
816 " FROM mlink JOIN event ON event.objid=mlink.mid\n"
817 " GROUP BY mlink.fnid\n"
818 " ORDER BY 1 COLLATE nocase;");
819 while( db_step(&q)==SQLITE_ROW ){
820 const char *zName = db_column_text(&q, 0);
821 const char *zUuid = db_column_text(&q,1);
822 double mtime = db_column_double(&q,2);
823 if( nD>0 && (fossil_strncmp(zName, zD, nD-1)!=0 || zName[nD-1]!='/') ){
824
--- src/browse.c
+++ src/browse.c
@@ -330,11 +330,12 @@
330 ** directory.
331 */
332 mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
333 if( mxLen<12 ) mxLen = 12;
334 mxLen += (mxLen+9)/10;
335 db_prepare(&q,
336 "SELECT x, u FROM localfiles ORDER BY x COLLATE uintnocase /*scan*/");
337 @ <div class="columns files" style="columns: %d(mxLen)ex auto">
338 @ <ul class="browser">
339 while( db_step(&q)==SQLITE_ROW ){
340 const char *zFN;
341 zFN = db_column_text(&q, 0);
@@ -368,11 +369,11 @@
369 */
370 db_prepare(&q,
371 "SELECT x, u FROM localfiles"
372 " WHERE x COLLATE nocase IN"
373 " ('readme','readme.txt','readme.md','readme.wiki','readme.markdown',"
374 " 'readme.html') ORDER BY x COLLATE uintnocase LIMIT 1;"
375 );
376 if( db_step(&q)==SQLITE_ROW ){
377 const char *zName = db_column_text(&q,0);
378 const char *zUuid = db_column_text(&q,1);
379 if( zUuid ){
@@ -790,11 +791,11 @@
791 db_prepare(&q,
792 "SELECT filename.name, blob.uuid, fileage.mtime\n"
793 " FROM fileage, filename, blob\n"
794 " WHERE filename.fnid=fileage.fnid\n"
795 " AND blob.rid=fileage.fid\n"
796 " ORDER BY filename.name COLLATE uintnocase;"
797 );
798 while( db_step(&q)==SQLITE_ROW ){
799 const char *zFile = db_column_text(&q,0);
800 const char *zUuid = db_column_text(&q,1);
801 double mtime = db_column_double(&q,2);
@@ -813,11 +814,11 @@
814 " (SELECT name FROM filename WHERE filename.fnid=mlink.fnid),\n"
815 " (SELECT uuid FROM blob WHERE blob.rid=mlink.fid),\n"
816 " max(event.mtime)\n"
817 " FROM mlink JOIN event ON event.objid=mlink.mid\n"
818 " GROUP BY mlink.fnid\n"
819 " ORDER BY 1 COLLATE uintnocase;");
820 while( db_step(&q)==SQLITE_ROW ){
821 const char *zName = db_column_text(&q, 0);
822 const char *zUuid = db_column_text(&q,1);
823 double mtime = db_column_double(&q,2);
824 if( nD>0 && (fossil_strncmp(zName, zD, nD-1)!=0 || zName[nD-1]!='/') ){
825
+1 -1
--- src/builtin.c
+++ src/builtin.c
@@ -156,11 +156,11 @@
156156
}
157157
return;
158158
}
159159
160160
/*
161
-** WEBPAGE: builtin
161
+** WEBPAGE: builtin loadavg-exempt
162162
**
163163
** Return one of many built-in content files. Query parameters:
164164
**
165165
** name=FILENAME Return the single file whose name is FILENAME.
166166
** mimetype=TYPE Override the mimetype in the returned file to
167167
--- src/builtin.c
+++ src/builtin.c
@@ -156,11 +156,11 @@
156 }
157 return;
158 }
159
160 /*
161 ** WEBPAGE: builtin
162 **
163 ** Return one of many built-in content files. Query parameters:
164 **
165 ** name=FILENAME Return the single file whose name is FILENAME.
166 ** mimetype=TYPE Override the mimetype in the returned file to
167
--- src/builtin.c
+++ src/builtin.c
@@ -156,11 +156,11 @@
156 }
157 return;
158 }
159
160 /*
161 ** WEBPAGE: builtin loadavg-exempt
162 **
163 ** Return one of many built-in content files. Query parameters:
164 **
165 ** name=FILENAME Return the single file whose name is FILENAME.
166 ** mimetype=TYPE Override the mimetype in the returned file to
167
--- src/capabilities.c
+++ src/capabilities.c
@@ -275,11 +275,11 @@
275275
{ 'q', CAPCLASS_TKT|CAPCLASS_SUPER, 0,
276276
"Mod-Tkt", "Moderate tickets" },
277277
{ 'r', CAPCLASS_TKT, 0,
278278
"Read-Tkt", "View tickets" },
279279
{ 's', CAPCLASS_SUPER, 0,
280
- "Superuser", "Setup and configure the respository" },
280
+ "Superuser", "Setup and configure the repository" },
281281
{ 't', CAPCLASS_TKT, 0,
282282
"Reports", "Create new ticket report formats" },
283283
{ 'u', CAPCLASS_OTHER, 0,
284284
"Reader", "Inherit all the capabilities of the \"reader\" user" },
285285
{ 'v', CAPCLASS_OTHER, 0,
286286
--- src/capabilities.c
+++ src/capabilities.c
@@ -275,11 +275,11 @@
275 { 'q', CAPCLASS_TKT|CAPCLASS_SUPER, 0,
276 "Mod-Tkt", "Moderate tickets" },
277 { 'r', CAPCLASS_TKT, 0,
278 "Read-Tkt", "View tickets" },
279 { 's', CAPCLASS_SUPER, 0,
280 "Superuser", "Setup and configure the respository" },
281 { 't', CAPCLASS_TKT, 0,
282 "Reports", "Create new ticket report formats" },
283 { 'u', CAPCLASS_OTHER, 0,
284 "Reader", "Inherit all the capabilities of the \"reader\" user" },
285 { 'v', CAPCLASS_OTHER, 0,
286
--- src/capabilities.c
+++ src/capabilities.c
@@ -275,11 +275,11 @@
275 { 'q', CAPCLASS_TKT|CAPCLASS_SUPER, 0,
276 "Mod-Tkt", "Moderate tickets" },
277 { 'r', CAPCLASS_TKT, 0,
278 "Read-Tkt", "View tickets" },
279 { 's', CAPCLASS_SUPER, 0,
280 "Superuser", "Setup and configure the repository" },
281 { 't', CAPCLASS_TKT, 0,
282 "Reports", "Create new ticket report formats" },
283 { 'u', CAPCLASS_OTHER, 0,
284 "Reader", "Inherit all the capabilities of the \"reader\" user" },
285 { 'v', CAPCLASS_OTHER, 0,
286
+46 -93
--- src/cgi.c
+++ src/cgi.c
@@ -364,19 +364,19 @@
364364
}
365365
366366
/* Works like fread():
367367
**
368368
** Read as many as bytes of content as we can, up to a maximum of nmemb
369
-** bytes. Return the number of bytes read. Return -1 if there is no
369
+** bytes. Return the number of bytes read. Return 0 if there is no
370370
** further input or if an I/O error occurs.
371371
*/
372372
size_t cgi_fread(void *ptr, size_t nmemb){
373373
if( !g.httpUseSSL ){
374374
return fread(ptr, 1, nmemb, g.httpIn);
375375
}
376376
#ifdef FOSSIL_ENABLE_SSL
377
- return ssl_read_server(g.httpSSLConn, ptr, nmemb);
377
+ return ssl_read_server(g.httpSSLConn, ptr, nmemb, 1);
378378
#else
379379
fossil_fatal("SSL not available");
380380
#endif
381381
}
382382
@@ -1061,71 +1061,23 @@
10611061
}
10621062
10631063
10641064
#ifdef FOSSIL_ENABLE_JSON
10651065
/*
1066
-** Internal helper for cson_data_source_FILE_n().
1067
-*/
1068
-typedef struct CgiPostReadState_ {
1069
- FILE * fh;
1070
- unsigned int len;
1071
- unsigned int pos;
1072
-} CgiPostReadState;
1073
-
1074
-/*
1075
-** cson_data_source_f() impl which reads only up to
1076
-** a specified amount of data from its input FILE.
1077
-** state MUST be a full populated (CgiPostReadState*).
1078
-*/
1079
-static int cson_data_source_FILE_n( void * state,
1080
- void * dest,
1081
- unsigned int * n ){
1082
- if( ! state || !dest || !n ) return cson_rc.ArgError;
1083
- else {
1084
- CgiPostReadState * st = (CgiPostReadState *)state;
1085
- if( st->pos >= st->len ){
1086
- *n = 0;
1087
- return 0;
1088
- }else if( !*n || ((st->pos + *n) > st->len) ){
1089
- return cson_rc.RangeError;
1090
- }else{
1091
- unsigned int rsz = (unsigned int)fread( dest, 1, *n, st->fh );
1092
- if( ! rsz ){
1093
- *n = rsz;
1094
- return feof(st->fh) ? 0 : cson_rc.IOError;
1095
- }else{
1096
- *n = rsz;
1097
- st->pos += *n;
1098
- return 0;
1099
- }
1100
- }
1101
- }
1102
-}
1103
-
1104
-/*
1105
-** Reads a JSON object from the first contentLen bytes of zIn. On
1106
-** g.json.post is updated to hold the content. On error a
1107
-** FSL_JSON_E_INVALID_REQUEST response is output and fossil_exit() is
1108
-** called (in HTTP mode exit code 0 is used).
1109
-**
1110
-** If contentLen is 0 then the whole file is read.
1111
-*/
1112
-void cgi_parse_POST_JSON( FILE * zIn, unsigned int contentLen ){
1113
- cson_value * jv = NULL;
1114
- int rc;
1115
- CgiPostReadState state;
1116
- cson_parse_opt popt = cson_parse_opt_empty;
1066
+** Reads a JSON object from the given blob, which is assumed to have
1067
+** been populated by the caller from stdin, the SSL API, or a file, as
1068
+** appropriate for the particular use case. On success g.json.post is
1069
+** updated to hold the content. On error a FSL_JSON_E_INVALID_REQUEST
1070
+** response is output and fossil_exit() is called (in HTTP mode exit
1071
+** code 0 is used).
1072
+*/
1073
+void cgi_parse_POST_JSON( Blob * pIn ){
1074
+ cson_value * jv = NULL;
11171075
cson_parse_info pinfo = cson_parse_info_empty;
11181076
assert(g.json.gc.a && "json_bootstrap_early() was not called!");
1119
- popt.maxDepth = 15;
1120
- state.fh = zIn;
1121
- state.len = contentLen;
1122
- state.pos = 0;
1123
- rc = cson_parse( &jv,
1124
- contentLen ? cson_data_source_FILE_n : cson_data_source_FILE,
1125
- contentLen ? (void *)&state : (void *)zIn, &popt, &pinfo );
1126
- if(rc){
1077
+ jv = cson_parse_Blob(pIn, &pinfo);
1078
+ if( jv==NULL ){
11271079
goto invalidRequest;
11281080
}else{
11291081
json_gc_add( "POST.JSON", jv );
11301082
g.json.post.v = jv;
11311083
g.json.post.o = cson_value_get_object( jv );
@@ -1140,11 +1092,11 @@
11401092
char * msg = mprintf("JSON parse error at line %u, column %u, "
11411093
"byte offset %u: %s",
11421094
pinfo.line, pinfo.col, pinfo.length,
11431095
cson_rc_string(pinfo.errorCode));
11441096
json_err( FSL_JSON_E_INVALID_REQUEST, msg, 1 );
1145
- free(msg);
1097
+ fossil_free(msg);
11461098
}else if(jv && !g.json.post.o){
11471099
json_err( FSL_JSON_E_INVALID_REQUEST,
11481100
"Request envelope must be a JSON Object (not array).", 1 );
11491101
}else{ /* generic error message */
11501102
json_err( FSL_JSON_E_INVALID_REQUEST, NULL, 1 );
@@ -1222,10 +1174,14 @@
12221174
**
12231175
** REQUEST_URI, PATH_INFO, and SCRIPT_NAME are related as follows:
12241176
**
12251177
** REQUEST_URI == SCRIPT_NAME + PATH_INFO
12261178
**
1179
+** Or if QUERY_STRING is not empty:
1180
+**
1181
+** REQUEST_URI == SCRIPT_NAME + PATH_INFO + '?' + QUERY_STRING
1182
+**
12271183
** Where "+" means concatenate. Fossil requires SCRIPT_NAME. If
12281184
** REQUEST_URI is provided but PATH_INFO is not, then PATH_INFO is
12291185
** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided
12301186
** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and
12311187
** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then
@@ -1240,18 +1196,20 @@
12401196
** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
12411197
** PATH_INFO when it is empty.
12421198
**
12431199
** CGI Parameter quick reference:
12441200
**
1245
-** REQUEST_URI
1246
-** _____________|____________
1247
-** / \
1248
-** https://www.fossil-scm.org/forum/info/12736b30c072551a?t=c
1249
-** \________________/\____/\____________________/ \_/
1250
-** | | | |
1251
-** HTTP_HOST | PATH_INFO QUERY_STRING
1252
-** SCRIPT_NAME
1201
+** REQUEST_URI
1202
+** _____________|________________
1203
+** / \
1204
+** https://fossil-scm.org/forum/info/12736b30c072551a?t=c
1205
+** \___/ \____________/\____/\____________________/ \_/
1206
+** | | | | |
1207
+** | HTTP_HOST | PATH_INFO QUERY_STRING
1208
+** | |
1209
+** REQUEST_SCHEMA SCRIPT_NAME
1210
+**
12531211
*/
12541212
void cgi_init(void){
12551213
char *z;
12561214
const char *zType;
12571215
char *zSemi;
@@ -1270,20 +1228,18 @@
12701228
cgi_destination(CGI_BODY);
12711229
12721230
/* We must have SCRIPT_NAME. If the web server did not supply it, try
12731231
** to compute it from REQUEST_URI and PATH_INFO. */
12741232
if( zScriptName==0 ){
1275
- size_t nRU, nPI;
12761233
if( zRequestUri==0 || zPathInfo==0 ){
12771234
malformed_request("missing SCRIPT_NAME"); /* Does not return */
12781235
}
1279
- nRU = strlen(zRequestUri);
1280
- nPI = strlen(zPathInfo);
1281
- if( nRU<nPI ){
1282
- malformed_request("PATH_INFO is longer than REQUEST_URI");
1236
+ z = strstr(zRequestUri,zPathInfo);
1237
+ if( z==0 ){
1238
+ malformed_request("PATH_INFO not found in REQUEST_URI");
12831239
}
1284
- zScriptName = fossil_strndup(zRequestUri,(int)(nRU-nPI));
1240
+ zScriptName = fossil_strndup(zRequestUri,(int)(z-zRequestUri));
12851241
cgi_set_parameter("SCRIPT_NAME", zScriptName);
12861242
}
12871243
12881244
#ifdef _WIN32
12891245
/* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
@@ -1299,15 +1255,20 @@
12991255
cgi_replace_parameter("PATH_INFO", zPathInfo);
13001256
}
13011257
#endif
13021258
if( zRequestUri==0 ){
13031259
const char *z = zPathInfo;
1260
+ const char *zQS = cgi_parameter("QUERY_STRING",0);
13041261
if( zPathInfo==0 ){
13051262
malformed_request("missing PATH_INFO and/or REQUEST_URI");
13061263
}
13071264
if( z[0]=='/' ) z++;
1308
- zRequestUri = mprintf("%s/%s", zScriptName, z);
1265
+ if( zQS && zQS[0] ){
1266
+ zRequestUri = mprintf("%s/%s?%s", zScriptName, z, zQS);
1267
+ }else{
1268
+ zRequestUri = mprintf("%s/%s", zScriptName, z);
1269
+ }
13091270
cgi_set_parameter("REQUEST_URI", zRequestUri);
13101271
}
13111272
if( zPathInfo==0 ){
13121273
int i, j;
13131274
for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){}
@@ -1362,33 +1323,25 @@
13621323
}else{
13631324
g.zContentType = zType;
13641325
}
13651326
blob_zero(&g.cgiIn);
13661327
if( len>0 && zType ){
1328
+ if( blob_read_from_cgi(&g.cgiIn, len)<len ){
1329
+ char *zMsg = mprintf("CGI content-length mismatch: Wanted %d bytes"
1330
+ " but got only %d\n", len, blob_size(&g.cgiIn));
1331
+ malformed_request(zMsg);
1332
+ }
13671333
if( fossil_strcmp(zType, "application/x-fossil")==0 ){
1368
- if( blob_read_from_cgi(&g.cgiIn, len)!=len ){
1369
- malformed_request("CGI content-length mismatch");
1370
- }
13711334
blob_uncompress(&g.cgiIn, &g.cgiIn);
13721335
}
13731336
#ifdef FOSSIL_ENABLE_JSON
1374
- else if( noJson==0 && g.json.isJsonMode!=0
1375
- && json_can_consume_content_type(zType)!=0 ){
1376
- assert( !g.httpUseSSL );
1377
- cgi_parse_POST_JSON(g.httpIn, (unsigned int)len);
1378
- /*
1379
- Potential TODOs:
1380
-
1381
- 1) If parsing fails, immediately return an error response
1382
- without dispatching the ostensibly-upcoming JSON API.
1383
- */
1337
+ if( noJson==0 && g.json.isJsonMode!=0
1338
+ && json_can_consume_content_type(zType)!=0 ){
1339
+ cgi_parse_POST_JSON(&g.cgiIn);
13841340
cgi_set_content_type(json_guess_content_type());
13851341
}
13861342
#endif /* FOSSIL_ENABLE_JSON */
1387
- else{
1388
- blob_read_from_cgi(&g.cgiIn, len);
1389
- }
13901343
}
13911344
}
13921345
13931346
/*
13941347
** Decode POST parameter information in the cgiIn content, if any.
13951348
--- src/cgi.c
+++ src/cgi.c
@@ -364,19 +364,19 @@
364 }
365
366 /* Works like fread():
367 **
368 ** Read as many as bytes of content as we can, up to a maximum of nmemb
369 ** bytes. Return the number of bytes read. Return -1 if there is no
370 ** further input or if an I/O error occurs.
371 */
372 size_t cgi_fread(void *ptr, size_t nmemb){
373 if( !g.httpUseSSL ){
374 return fread(ptr, 1, nmemb, g.httpIn);
375 }
376 #ifdef FOSSIL_ENABLE_SSL
377 return ssl_read_server(g.httpSSLConn, ptr, nmemb);
378 #else
379 fossil_fatal("SSL not available");
380 #endif
381 }
382
@@ -1061,71 +1061,23 @@
1061 }
1062
1063
1064 #ifdef FOSSIL_ENABLE_JSON
1065 /*
1066 ** Internal helper for cson_data_source_FILE_n().
1067 */
1068 typedef struct CgiPostReadState_ {
1069 FILE * fh;
1070 unsigned int len;
1071 unsigned int pos;
1072 } CgiPostReadState;
1073
1074 /*
1075 ** cson_data_source_f() impl which reads only up to
1076 ** a specified amount of data from its input FILE.
1077 ** state MUST be a full populated (CgiPostReadState*).
1078 */
1079 static int cson_data_source_FILE_n( void * state,
1080 void * dest,
1081 unsigned int * n ){
1082 if( ! state || !dest || !n ) return cson_rc.ArgError;
1083 else {
1084 CgiPostReadState * st = (CgiPostReadState *)state;
1085 if( st->pos >= st->len ){
1086 *n = 0;
1087 return 0;
1088 }else if( !*n || ((st->pos + *n) > st->len) ){
1089 return cson_rc.RangeError;
1090 }else{
1091 unsigned int rsz = (unsigned int)fread( dest, 1, *n, st->fh );
1092 if( ! rsz ){
1093 *n = rsz;
1094 return feof(st->fh) ? 0 : cson_rc.IOError;
1095 }else{
1096 *n = rsz;
1097 st->pos += *n;
1098 return 0;
1099 }
1100 }
1101 }
1102 }
1103
1104 /*
1105 ** Reads a JSON object from the first contentLen bytes of zIn. On
1106 ** g.json.post is updated to hold the content. On error a
1107 ** FSL_JSON_E_INVALID_REQUEST response is output and fossil_exit() is
1108 ** called (in HTTP mode exit code 0 is used).
1109 **
1110 ** If contentLen is 0 then the whole file is read.
1111 */
1112 void cgi_parse_POST_JSON( FILE * zIn, unsigned int contentLen ){
1113 cson_value * jv = NULL;
1114 int rc;
1115 CgiPostReadState state;
1116 cson_parse_opt popt = cson_parse_opt_empty;
1117 cson_parse_info pinfo = cson_parse_info_empty;
1118 assert(g.json.gc.a && "json_bootstrap_early() was not called!");
1119 popt.maxDepth = 15;
1120 state.fh = zIn;
1121 state.len = contentLen;
1122 state.pos = 0;
1123 rc = cson_parse( &jv,
1124 contentLen ? cson_data_source_FILE_n : cson_data_source_FILE,
1125 contentLen ? (void *)&state : (void *)zIn, &popt, &pinfo );
1126 if(rc){
1127 goto invalidRequest;
1128 }else{
1129 json_gc_add( "POST.JSON", jv );
1130 g.json.post.v = jv;
1131 g.json.post.o = cson_value_get_object( jv );
@@ -1140,11 +1092,11 @@
1140 char * msg = mprintf("JSON parse error at line %u, column %u, "
1141 "byte offset %u: %s",
1142 pinfo.line, pinfo.col, pinfo.length,
1143 cson_rc_string(pinfo.errorCode));
1144 json_err( FSL_JSON_E_INVALID_REQUEST, msg, 1 );
1145 free(msg);
1146 }else if(jv && !g.json.post.o){
1147 json_err( FSL_JSON_E_INVALID_REQUEST,
1148 "Request envelope must be a JSON Object (not array).", 1 );
1149 }else{ /* generic error message */
1150 json_err( FSL_JSON_E_INVALID_REQUEST, NULL, 1 );
@@ -1222,10 +1174,14 @@
1222 **
1223 ** REQUEST_URI, PATH_INFO, and SCRIPT_NAME are related as follows:
1224 **
1225 ** REQUEST_URI == SCRIPT_NAME + PATH_INFO
1226 **
 
 
 
 
1227 ** Where "+" means concatenate. Fossil requires SCRIPT_NAME. If
1228 ** REQUEST_URI is provided but PATH_INFO is not, then PATH_INFO is
1229 ** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided
1230 ** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and
1231 ** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then
@@ -1240,18 +1196,20 @@
1240 ** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
1241 ** PATH_INFO when it is empty.
1242 **
1243 ** CGI Parameter quick reference:
1244 **
1245 ** REQUEST_URI
1246 ** _____________|____________
1247 ** / \
1248 ** https://www.fossil-scm.org/forum/info/12736b30c072551a?t=c
1249 ** \________________/\____/\____________________/ \_/
1250 ** | | | |
1251 ** HTTP_HOST | PATH_INFO QUERY_STRING
1252 ** SCRIPT_NAME
 
 
1253 */
1254 void cgi_init(void){
1255 char *z;
1256 const char *zType;
1257 char *zSemi;
@@ -1270,20 +1228,18 @@
1270 cgi_destination(CGI_BODY);
1271
1272 /* We must have SCRIPT_NAME. If the web server did not supply it, try
1273 ** to compute it from REQUEST_URI and PATH_INFO. */
1274 if( zScriptName==0 ){
1275 size_t nRU, nPI;
1276 if( zRequestUri==0 || zPathInfo==0 ){
1277 malformed_request("missing SCRIPT_NAME"); /* Does not return */
1278 }
1279 nRU = strlen(zRequestUri);
1280 nPI = strlen(zPathInfo);
1281 if( nRU<nPI ){
1282 malformed_request("PATH_INFO is longer than REQUEST_URI");
1283 }
1284 zScriptName = fossil_strndup(zRequestUri,(int)(nRU-nPI));
1285 cgi_set_parameter("SCRIPT_NAME", zScriptName);
1286 }
1287
1288 #ifdef _WIN32
1289 /* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
@@ -1299,15 +1255,20 @@
1299 cgi_replace_parameter("PATH_INFO", zPathInfo);
1300 }
1301 #endif
1302 if( zRequestUri==0 ){
1303 const char *z = zPathInfo;
 
1304 if( zPathInfo==0 ){
1305 malformed_request("missing PATH_INFO and/or REQUEST_URI");
1306 }
1307 if( z[0]=='/' ) z++;
1308 zRequestUri = mprintf("%s/%s", zScriptName, z);
 
 
 
 
1309 cgi_set_parameter("REQUEST_URI", zRequestUri);
1310 }
1311 if( zPathInfo==0 ){
1312 int i, j;
1313 for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){}
@@ -1362,33 +1323,25 @@
1362 }else{
1363 g.zContentType = zType;
1364 }
1365 blob_zero(&g.cgiIn);
1366 if( len>0 && zType ){
 
 
 
 
 
1367 if( fossil_strcmp(zType, "application/x-fossil")==0 ){
1368 if( blob_read_from_cgi(&g.cgiIn, len)!=len ){
1369 malformed_request("CGI content-length mismatch");
1370 }
1371 blob_uncompress(&g.cgiIn, &g.cgiIn);
1372 }
1373 #ifdef FOSSIL_ENABLE_JSON
1374 else if( noJson==0 && g.json.isJsonMode!=0
1375 && json_can_consume_content_type(zType)!=0 ){
1376 assert( !g.httpUseSSL );
1377 cgi_parse_POST_JSON(g.httpIn, (unsigned int)len);
1378 /*
1379 Potential TODOs:
1380
1381 1) If parsing fails, immediately return an error response
1382 without dispatching the ostensibly-upcoming JSON API.
1383 */
1384 cgi_set_content_type(json_guess_content_type());
1385 }
1386 #endif /* FOSSIL_ENABLE_JSON */
1387 else{
1388 blob_read_from_cgi(&g.cgiIn, len);
1389 }
1390 }
1391 }
1392
1393 /*
1394 ** Decode POST parameter information in the cgiIn content, if any.
1395
--- src/cgi.c
+++ src/cgi.c
@@ -364,19 +364,19 @@
364 }
365
366 /* Works like fread():
367 **
368 ** Read as many as bytes of content as we can, up to a maximum of nmemb
369 ** bytes. Return the number of bytes read. Return 0 if there is no
370 ** further input or if an I/O error occurs.
371 */
372 size_t cgi_fread(void *ptr, size_t nmemb){
373 if( !g.httpUseSSL ){
374 return fread(ptr, 1, nmemb, g.httpIn);
375 }
376 #ifdef FOSSIL_ENABLE_SSL
377 return ssl_read_server(g.httpSSLConn, ptr, nmemb, 1);
378 #else
379 fossil_fatal("SSL not available");
380 #endif
381 }
382
@@ -1061,71 +1061,23 @@
1061 }
1062
1063
1064 #ifdef FOSSIL_ENABLE_JSON
1065 /*
1066 ** Reads a JSON object from the given blob, which is assumed to have
1067 ** been populated by the caller from stdin, the SSL API, or a file, as
1068 ** appropriate for the particular use case. On success g.json.post is
1069 ** updated to hold the content. On error a FSL_JSON_E_INVALID_REQUEST
1070 ** response is output and fossil_exit() is called (in HTTP mode exit
1071 ** code 0 is used).
1072 */
1073 void cgi_parse_POST_JSON( Blob * pIn ){
1074 cson_value * jv = NULL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1075 cson_parse_info pinfo = cson_parse_info_empty;
1076 assert(g.json.gc.a && "json_bootstrap_early() was not called!");
1077 jv = cson_parse_Blob(pIn, &pinfo);
1078 if( jv==NULL ){
 
 
 
 
 
 
1079 goto invalidRequest;
1080 }else{
1081 json_gc_add( "POST.JSON", jv );
1082 g.json.post.v = jv;
1083 g.json.post.o = cson_value_get_object( jv );
@@ -1140,11 +1092,11 @@
1092 char * msg = mprintf("JSON parse error at line %u, column %u, "
1093 "byte offset %u: %s",
1094 pinfo.line, pinfo.col, pinfo.length,
1095 cson_rc_string(pinfo.errorCode));
1096 json_err( FSL_JSON_E_INVALID_REQUEST, msg, 1 );
1097 fossil_free(msg);
1098 }else if(jv && !g.json.post.o){
1099 json_err( FSL_JSON_E_INVALID_REQUEST,
1100 "Request envelope must be a JSON Object (not array).", 1 );
1101 }else{ /* generic error message */
1102 json_err( FSL_JSON_E_INVALID_REQUEST, NULL, 1 );
@@ -1222,10 +1174,14 @@
1174 **
1175 ** REQUEST_URI, PATH_INFO, and SCRIPT_NAME are related as follows:
1176 **
1177 ** REQUEST_URI == SCRIPT_NAME + PATH_INFO
1178 **
1179 ** Or if QUERY_STRING is not empty:
1180 **
1181 ** REQUEST_URI == SCRIPT_NAME + PATH_INFO + '?' + QUERY_STRING
1182 **
1183 ** Where "+" means concatenate. Fossil requires SCRIPT_NAME. If
1184 ** REQUEST_URI is provided but PATH_INFO is not, then PATH_INFO is
1185 ** computed from REQUEST_URI and SCRIPT_NAME. If PATH_INFO is provided
1186 ** but REQUEST_URI is not, then compute REQUEST_URI from PATH_INFO and
1187 ** SCRIPT_NAME. If neither REQUEST_URI nor PATH_INFO are provided, then
@@ -1240,18 +1196,20 @@
1196 ** SCGI typically omits PATH_INFO. CGI sometimes omits REQUEST_URI and
1197 ** PATH_INFO when it is empty.
1198 **
1199 ** CGI Parameter quick reference:
1200 **
1201 ** REQUEST_URI
1202 ** _____________|________________
1203 ** / \
1204 ** https://fossil-scm.org/forum/info/12736b30c072551a?t=c
1205 ** \___/ \____________/\____/\____________________/ \_/
1206 ** | | | | |
1207 ** | HTTP_HOST | PATH_INFO QUERY_STRING
1208 ** | |
1209 ** REQUEST_SCHEMA SCRIPT_NAME
1210 **
1211 */
1212 void cgi_init(void){
1213 char *z;
1214 const char *zType;
1215 char *zSemi;
@@ -1270,20 +1228,18 @@
1228 cgi_destination(CGI_BODY);
1229
1230 /* We must have SCRIPT_NAME. If the web server did not supply it, try
1231 ** to compute it from REQUEST_URI and PATH_INFO. */
1232 if( zScriptName==0 ){
 
1233 if( zRequestUri==0 || zPathInfo==0 ){
1234 malformed_request("missing SCRIPT_NAME"); /* Does not return */
1235 }
1236 z = strstr(zRequestUri,zPathInfo);
1237 if( z==0 ){
1238 malformed_request("PATH_INFO not found in REQUEST_URI");
 
1239 }
1240 zScriptName = fossil_strndup(zRequestUri,(int)(z-zRequestUri));
1241 cgi_set_parameter("SCRIPT_NAME", zScriptName);
1242 }
1243
1244 #ifdef _WIN32
1245 /* The Microsoft IIS web server does not define REQUEST_URI, instead it uses
@@ -1299,15 +1255,20 @@
1255 cgi_replace_parameter("PATH_INFO", zPathInfo);
1256 }
1257 #endif
1258 if( zRequestUri==0 ){
1259 const char *z = zPathInfo;
1260 const char *zQS = cgi_parameter("QUERY_STRING",0);
1261 if( zPathInfo==0 ){
1262 malformed_request("missing PATH_INFO and/or REQUEST_URI");
1263 }
1264 if( z[0]=='/' ) z++;
1265 if( zQS && zQS[0] ){
1266 zRequestUri = mprintf("%s/%s?%s", zScriptName, z, zQS);
1267 }else{
1268 zRequestUri = mprintf("%s/%s", zScriptName, z);
1269 }
1270 cgi_set_parameter("REQUEST_URI", zRequestUri);
1271 }
1272 if( zPathInfo==0 ){
1273 int i, j;
1274 for(i=0; zRequestUri[i]==zScriptName[i] && zRequestUri[i]; i++){}
@@ -1362,33 +1323,25 @@
1323 }else{
1324 g.zContentType = zType;
1325 }
1326 blob_zero(&g.cgiIn);
1327 if( len>0 && zType ){
1328 if( blob_read_from_cgi(&g.cgiIn, len)<len ){
1329 char *zMsg = mprintf("CGI content-length mismatch: Wanted %d bytes"
1330 " but got only %d\n", len, blob_size(&g.cgiIn));
1331 malformed_request(zMsg);
1332 }
1333 if( fossil_strcmp(zType, "application/x-fossil")==0 ){
 
 
 
1334 blob_uncompress(&g.cgiIn, &g.cgiIn);
1335 }
1336 #ifdef FOSSIL_ENABLE_JSON
1337 if( noJson==0 && g.json.isJsonMode!=0
1338 && json_can_consume_content_type(zType)!=0 ){
1339 cgi_parse_POST_JSON(&g.cgiIn);
 
 
 
 
 
 
 
1340 cgi_set_content_type(json_guess_content_type());
1341 }
1342 #endif /* FOSSIL_ENABLE_JSON */
 
 
 
1343 }
1344 }
1345
1346 /*
1347 ** Decode POST parameter information in the cgiIn content, if any.
1348
+118 -6
--- src/chat.c
+++ src/chat.c
@@ -128,11 +128,11 @@
128128
**
129129
** This is the name of the builtin sound file to use for the alert tone.
130130
** The value must be the name of a builtin WAV file.
131131
*/
132132
/*
133
-** WEBPAGE: chat
133
+** WEBPAGE: chat loadavg-exempt
134134
**
135135
** Start up a browser-based chat session.
136136
**
137137
** This is the main page that humans use to access the chatroom. Simply
138138
** point a web-browser at /chat and the screen fills with the latest
@@ -342,11 +342,11 @@
342342
}
343343
fossil_free(zTime);
344344
}
345345
346346
/*
347
-** WEBPAGE: chat-send hidden
347
+** WEBPAGE: chat-send hidden loadavg-exempt
348348
**
349349
** This page receives (via XHR) a new chat-message and/or a new file
350350
** to be entered into the chat history.
351351
**
352352
** On success it responds with an empty response: the new message
@@ -448,11 +448,11 @@
448448
fossil_free(zOut);
449449
}
450450
}
451451
452452
/*
453
-** WEBPAGE: chat-poll hidden
453
+** WEBPAGE: chat-poll hidden loadavg-exempt
454454
**
455455
** The chat page generated by /chat using an XHR to this page to
456456
** request new chat content. A typical invocation is:
457457
**
458458
** /chat-poll/N
@@ -667,11 +667,11 @@
667667
cgi_set_content(&json);
668668
return;
669669
}
670670
671671
/*
672
-** WEBPAGE: chat-fetch-one hidden
672
+** WEBPAGE: chat-fetch-one hidden loadavg-exempt
673673
**
674674
** /chat-fetch-one/N
675675
**
676676
** Fetches a single message with the given ID, if available.
677677
**
@@ -744,11 +744,11 @@
744744
}
745745
db_finalize(&q);
746746
}
747747
748748
/*
749
-** WEBPAGE: chat-download hidden
749
+** WEBPAGE: chat-download hidden loadavg-exempt
750750
**
751751
** Download the CHAT.FILE attachment associated with a single chat
752752
** entry. The "name" query parameter begins with an integer that
753753
** identifies the particular chat message. The integer may be followed
754754
** by a / and a filename, which will indicate to the browser to use
@@ -777,11 +777,11 @@
777777
cgi_set_content(&r);
778778
}
779779
780780
781781
/*
782
-** WEBPAGE: chat-delete hidden
782
+** WEBPAGE: chat-delete hidden loadavg-exempt
783783
**
784784
** Delete the chat entry identified by the name query parameter.
785785
** Invoking fetch("chat-delete/"+msgid) from javascript in the client
786786
** will delete a chat entry from the CHAT table.
787787
**
@@ -815,10 +815,42 @@
815815
" VALUES(julianday('now'), %Q, %d);\n"
816816
"COMMIT;",
817817
mdel, g.zLogin, mdel
818818
);
819819
}
820
+
821
+/*
822
+** WEBPAGE: chat-backup hidden
823
+**
824
+** Download an SQLite database containing all chat content with a
825
+** message-id larger than the "msgid" query parameter. Setup
826
+** privilege is required to use this URL.
827
+**
828
+** This is used to implement the "fossil chat pull" command.
829
+*/
830
+void chat_backup_webpage(void){
831
+ int msgid;
832
+ unsigned char *pDb = 0;
833
+ sqlite3_int64 szDb = 0;
834
+ Blob chatDb;
835
+ login_check_credentials();
836
+ if( !g.perm.Setup ) return;
837
+ msgid = atoi(PD("msgid","0"));
838
+ db_multi_exec(
839
+ "ATTACH ':memory:' AS mem1;\n"
840
+ "PRAGMA mem1.page_size=512;\n"
841
+ "CREATE TABLE mem1.chat AS SELECT * FROM repository.chat WHERE msgid>%d;\n",
842
+ msgid
843
+ );
844
+ pDb = sqlite3_serialize(g.db, "mem1", &szDb, 0);
845
+ if( pDb==0 ){
846
+ fossil_fatal("Out of memory");
847
+ }
848
+ blob_init(&chatDb, (const char*)pDb, (int)szDb);
849
+ cgi_set_content_type("application/x-sqlite3");
850
+ cgi_set_content(&chatDb);
851
+}
820852
821853
/*
822854
** COMMAND: chat
823855
**
824856
** Usage: %fossil chat [SUBCOMMAND] [--remote URL] [ARGS...]
@@ -838,10 +870,22 @@
838870
** the response is to bring up a web-browser window to the chatroom
839871
** on the default system web-browser. You can accomplish the same by
840872
** typing the appropriate URL into the web-browser yourself. This
841873
** command is merely a convenience for command-line oriented people.
842874
**
875
+** > fossil chat pull
876
+**
877
+** Copy chat content from the server down into the local clone,
878
+** as a backup or archive. Setup privilege is required on the server.
879
+**
880
+** --all Download all chat content. Normally only
881
+** previously undownloaded content is retrieved.
882
+** --debug Additional debugging output.
883
+** --out DATABASE Store CHAT table in separate database file
884
+** DATABASE rather that adding to local clone
885
+** --unsafe Allow the use of unencrypted http://
886
+**
843887
** > fossil chat send [ARGUMENTS]
844888
**
845889
** This command sends a new message to the chatroom. The message
846890
** to be sent is determined by arguments as follows:
847891
**
@@ -981,12 +1025,80 @@
9811025
fossil_print("ERROR: %s\n", blob_str(&down));
9821026
}
9831027
fossil_fatal("unable to send the chat message");
9841028
}
9851029
blob_reset(&down);
1030
+ }else if( strcmp(g.argv[2],"pull")==0 ){
1031
+ /* Pull the CHAT table from the default server down into the repository
1032
+ ** here on the local side */
1033
+ int allowUnsafe = find_option("unsafe",0,0)!=0;
1034
+ int bDebug = find_option("debug",0,0)!=0;
1035
+ const char *zOut = find_option("out",0,1);
1036
+ int bAll = find_option("all",0,0)!=0;
1037
+ int mFlags = HTTP_GENERIC | HTTP_QUIET | HTTP_NOCOMPRESS;
1038
+ int msgid;
1039
+ Blob reqUri; /* The REQUEST_URI: .../chat-backup?msgid=... */
1040
+ char *zObs;
1041
+ const char *zPw;
1042
+ Blob up, down;
1043
+ int nChat;
1044
+ int rc;
1045
+ verify_all_options();
1046
+ chat_create_tables();
1047
+ msgid = bAll ? 0 : db_int(0,"SELECT max(msgid) FROM chat");
1048
+ if( !g.url.isHttps && !allowUnsafe ){
1049
+ fossil_fatal("URL \"%s\" is unencrypted. Use https:// instead", zUrl);
1050
+ }
1051
+ blob_init(&reqUri, g.url.path, -1);
1052
+ blob_appendf(&reqUri, "/chat-backup?msgid=%d", msgid);
1053
+ if( g.url.user && g.url.user[0] ){
1054
+ zObs = obscure(g.url.user);
1055
+ blob_appendf(&reqUri, "&resid=%t", zObs);
1056
+ fossil_free(zObs);
1057
+ }
1058
+ zPw = g.url.passwd;
1059
+ if( zPw==0 && isDefaultUrl ) zPw = unobscure(db_get("last-sync-pw", 0));
1060
+ if( zPw && zPw[0] ){
1061
+ zObs = obscure(zPw);
1062
+ blob_appendf(&reqUri, "&token=%t", zObs);
1063
+ fossil_free(zObs);
1064
+ }
1065
+ g.url.path = blob_str(&reqUri);
1066
+ if( bDebug ){
1067
+ fossil_print("REQUEST_URI: %s\n", g.url.path);
1068
+ mFlags &= ~HTTP_QUIET;
1069
+ mFlags |= HTTP_VERBOSE;
1070
+ }
1071
+ blob_init(&up, 0, 0);
1072
+ blob_init(&down, 0, 0);
1073
+ http_exchange(&up, &down, mFlags, 4, 0);
1074
+ if( zOut ){
1075
+ blob_write_to_file(&down, zOut);
1076
+ fossil_print("Chat database at %s is %d bytes\n", zOut, blob_size(&down));
1077
+ }else{
1078
+ db_multi_exec("ATTACH ':memory:' AS chatbu;");
1079
+ if( g.fSqlTrace ){
1080
+ fossil_trace("-- deserialize(\"chatbu\", pData, %d);\n",
1081
+ blob_size(&down));
1082
+ }
1083
+ rc = sqlite3_deserialize(g.db, "chatbu",
1084
+ (unsigned char*)blob_buffer(&down),
1085
+ blob_size(&down), blob_size(&down), 0);
1086
+ if( rc ){
1087
+ fossil_fatal("cannot open patch database: %s", sqlite3_errmsg(g.db));
1088
+ }
1089
+ nChat = db_int(0, "SELECT count(*) FROM chatbu.chat");
1090
+ fossil_print("Got %d new records, %d bytes\n", nChat, blob_size(&down));
1091
+ db_multi_exec(
1092
+ "REPLACE INTO repository.chat(msgid,mtime,lmtime,xfrom,xmsg,"
1093
+ "fname,fmime,mdel,file)"
1094
+ " SELECT msgid,mtime,lmtime,xfrom,xmsg,fname,fmime,mdel,file"
1095
+ " FROM chatbu.chat;"
1096
+ );
1097
+ }
9861098
}else if( strcmp(g.argv[2],"url")==0 ){
9871099
/* Show the URL to access chat. */
9881100
fossil_print("%s/chat\n", zUrl);
9891101
}else{
9901102
fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
9911103
}
9921104
}
9931105
--- src/chat.c
+++ src/chat.c
@@ -128,11 +128,11 @@
128 **
129 ** This is the name of the builtin sound file to use for the alert tone.
130 ** The value must be the name of a builtin WAV file.
131 */
132 /*
133 ** WEBPAGE: chat
134 **
135 ** Start up a browser-based chat session.
136 **
137 ** This is the main page that humans use to access the chatroom. Simply
138 ** point a web-browser at /chat and the screen fills with the latest
@@ -342,11 +342,11 @@
342 }
343 fossil_free(zTime);
344 }
345
346 /*
347 ** WEBPAGE: chat-send hidden
348 **
349 ** This page receives (via XHR) a new chat-message and/or a new file
350 ** to be entered into the chat history.
351 **
352 ** On success it responds with an empty response: the new message
@@ -448,11 +448,11 @@
448 fossil_free(zOut);
449 }
450 }
451
452 /*
453 ** WEBPAGE: chat-poll hidden
454 **
455 ** The chat page generated by /chat using an XHR to this page to
456 ** request new chat content. A typical invocation is:
457 **
458 ** /chat-poll/N
@@ -667,11 +667,11 @@
667 cgi_set_content(&json);
668 return;
669 }
670
671 /*
672 ** WEBPAGE: chat-fetch-one hidden
673 **
674 ** /chat-fetch-one/N
675 **
676 ** Fetches a single message with the given ID, if available.
677 **
@@ -744,11 +744,11 @@
744 }
745 db_finalize(&q);
746 }
747
748 /*
749 ** WEBPAGE: chat-download hidden
750 **
751 ** Download the CHAT.FILE attachment associated with a single chat
752 ** entry. The "name" query parameter begins with an integer that
753 ** identifies the particular chat message. The integer may be followed
754 ** by a / and a filename, which will indicate to the browser to use
@@ -777,11 +777,11 @@
777 cgi_set_content(&r);
778 }
779
780
781 /*
782 ** WEBPAGE: chat-delete hidden
783 **
784 ** Delete the chat entry identified by the name query parameter.
785 ** Invoking fetch("chat-delete/"+msgid) from javascript in the client
786 ** will delete a chat entry from the CHAT table.
787 **
@@ -815,10 +815,42 @@
815 " VALUES(julianday('now'), %Q, %d);\n"
816 "COMMIT;",
817 mdel, g.zLogin, mdel
818 );
819 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
820
821 /*
822 ** COMMAND: chat
823 **
824 ** Usage: %fossil chat [SUBCOMMAND] [--remote URL] [ARGS...]
@@ -838,10 +870,22 @@
838 ** the response is to bring up a web-browser window to the chatroom
839 ** on the default system web-browser. You can accomplish the same by
840 ** typing the appropriate URL into the web-browser yourself. This
841 ** command is merely a convenience for command-line oriented people.
842 **
 
 
 
 
 
 
 
 
 
 
 
 
843 ** > fossil chat send [ARGUMENTS]
844 **
845 ** This command sends a new message to the chatroom. The message
846 ** to be sent is determined by arguments as follows:
847 **
@@ -981,12 +1025,80 @@
981 fossil_print("ERROR: %s\n", blob_str(&down));
982 }
983 fossil_fatal("unable to send the chat message");
984 }
985 blob_reset(&down);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
986 }else if( strcmp(g.argv[2],"url")==0 ){
987 /* Show the URL to access chat. */
988 fossil_print("%s/chat\n", zUrl);
989 }else{
990 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
991 }
992 }
993
--- src/chat.c
+++ src/chat.c
@@ -128,11 +128,11 @@
128 **
129 ** This is the name of the builtin sound file to use for the alert tone.
130 ** The value must be the name of a builtin WAV file.
131 */
132 /*
133 ** WEBPAGE: chat loadavg-exempt
134 **
135 ** Start up a browser-based chat session.
136 **
137 ** This is the main page that humans use to access the chatroom. Simply
138 ** point a web-browser at /chat and the screen fills with the latest
@@ -342,11 +342,11 @@
342 }
343 fossil_free(zTime);
344 }
345
346 /*
347 ** WEBPAGE: chat-send hidden loadavg-exempt
348 **
349 ** This page receives (via XHR) a new chat-message and/or a new file
350 ** to be entered into the chat history.
351 **
352 ** On success it responds with an empty response: the new message
@@ -448,11 +448,11 @@
448 fossil_free(zOut);
449 }
450 }
451
452 /*
453 ** WEBPAGE: chat-poll hidden loadavg-exempt
454 **
455 ** The chat page generated by /chat using an XHR to this page to
456 ** request new chat content. A typical invocation is:
457 **
458 ** /chat-poll/N
@@ -667,11 +667,11 @@
667 cgi_set_content(&json);
668 return;
669 }
670
671 /*
672 ** WEBPAGE: chat-fetch-one hidden loadavg-exempt
673 **
674 ** /chat-fetch-one/N
675 **
676 ** Fetches a single message with the given ID, if available.
677 **
@@ -744,11 +744,11 @@
744 }
745 db_finalize(&q);
746 }
747
748 /*
749 ** WEBPAGE: chat-download hidden loadavg-exempt
750 **
751 ** Download the CHAT.FILE attachment associated with a single chat
752 ** entry. The "name" query parameter begins with an integer that
753 ** identifies the particular chat message. The integer may be followed
754 ** by a / and a filename, which will indicate to the browser to use
@@ -777,11 +777,11 @@
777 cgi_set_content(&r);
778 }
779
780
781 /*
782 ** WEBPAGE: chat-delete hidden loadavg-exempt
783 **
784 ** Delete the chat entry identified by the name query parameter.
785 ** Invoking fetch("chat-delete/"+msgid) from javascript in the client
786 ** will delete a chat entry from the CHAT table.
787 **
@@ -815,10 +815,42 @@
815 " VALUES(julianday('now'), %Q, %d);\n"
816 "COMMIT;",
817 mdel, g.zLogin, mdel
818 );
819 }
820
821 /*
822 ** WEBPAGE: chat-backup hidden
823 **
824 ** Download an SQLite database containing all chat content with a
825 ** message-id larger than the "msgid" query parameter. Setup
826 ** privilege is required to use this URL.
827 **
828 ** This is used to implement the "fossil chat pull" command.
829 */
830 void chat_backup_webpage(void){
831 int msgid;
832 unsigned char *pDb = 0;
833 sqlite3_int64 szDb = 0;
834 Blob chatDb;
835 login_check_credentials();
836 if( !g.perm.Setup ) return;
837 msgid = atoi(PD("msgid","0"));
838 db_multi_exec(
839 "ATTACH ':memory:' AS mem1;\n"
840 "PRAGMA mem1.page_size=512;\n"
841 "CREATE TABLE mem1.chat AS SELECT * FROM repository.chat WHERE msgid>%d;\n",
842 msgid
843 );
844 pDb = sqlite3_serialize(g.db, "mem1", &szDb, 0);
845 if( pDb==0 ){
846 fossil_fatal("Out of memory");
847 }
848 blob_init(&chatDb, (const char*)pDb, (int)szDb);
849 cgi_set_content_type("application/x-sqlite3");
850 cgi_set_content(&chatDb);
851 }
852
853 /*
854 ** COMMAND: chat
855 **
856 ** Usage: %fossil chat [SUBCOMMAND] [--remote URL] [ARGS...]
@@ -838,10 +870,22 @@
870 ** the response is to bring up a web-browser window to the chatroom
871 ** on the default system web-browser. You can accomplish the same by
872 ** typing the appropriate URL into the web-browser yourself. This
873 ** command is merely a convenience for command-line oriented people.
874 **
875 ** > fossil chat pull
876 **
877 ** Copy chat content from the server down into the local clone,
878 ** as a backup or archive. Setup privilege is required on the server.
879 **
880 ** --all Download all chat content. Normally only
881 ** previously undownloaded content is retrieved.
882 ** --debug Additional debugging output.
883 ** --out DATABASE Store CHAT table in separate database file
884 ** DATABASE rather that adding to local clone
885 ** --unsafe Allow the use of unencrypted http://
886 **
887 ** > fossil chat send [ARGUMENTS]
888 **
889 ** This command sends a new message to the chatroom. The message
890 ** to be sent is determined by arguments as follows:
891 **
@@ -981,12 +1025,80 @@
1025 fossil_print("ERROR: %s\n", blob_str(&down));
1026 }
1027 fossil_fatal("unable to send the chat message");
1028 }
1029 blob_reset(&down);
1030 }else if( strcmp(g.argv[2],"pull")==0 ){
1031 /* Pull the CHAT table from the default server down into the repository
1032 ** here on the local side */
1033 int allowUnsafe = find_option("unsafe",0,0)!=0;
1034 int bDebug = find_option("debug",0,0)!=0;
1035 const char *zOut = find_option("out",0,1);
1036 int bAll = find_option("all",0,0)!=0;
1037 int mFlags = HTTP_GENERIC | HTTP_QUIET | HTTP_NOCOMPRESS;
1038 int msgid;
1039 Blob reqUri; /* The REQUEST_URI: .../chat-backup?msgid=... */
1040 char *zObs;
1041 const char *zPw;
1042 Blob up, down;
1043 int nChat;
1044 int rc;
1045 verify_all_options();
1046 chat_create_tables();
1047 msgid = bAll ? 0 : db_int(0,"SELECT max(msgid) FROM chat");
1048 if( !g.url.isHttps && !allowUnsafe ){
1049 fossil_fatal("URL \"%s\" is unencrypted. Use https:// instead", zUrl);
1050 }
1051 blob_init(&reqUri, g.url.path, -1);
1052 blob_appendf(&reqUri, "/chat-backup?msgid=%d", msgid);
1053 if( g.url.user && g.url.user[0] ){
1054 zObs = obscure(g.url.user);
1055 blob_appendf(&reqUri, "&resid=%t", zObs);
1056 fossil_free(zObs);
1057 }
1058 zPw = g.url.passwd;
1059 if( zPw==0 && isDefaultUrl ) zPw = unobscure(db_get("last-sync-pw", 0));
1060 if( zPw && zPw[0] ){
1061 zObs = obscure(zPw);
1062 blob_appendf(&reqUri, "&token=%t", zObs);
1063 fossil_free(zObs);
1064 }
1065 g.url.path = blob_str(&reqUri);
1066 if( bDebug ){
1067 fossil_print("REQUEST_URI: %s\n", g.url.path);
1068 mFlags &= ~HTTP_QUIET;
1069 mFlags |= HTTP_VERBOSE;
1070 }
1071 blob_init(&up, 0, 0);
1072 blob_init(&down, 0, 0);
1073 http_exchange(&up, &down, mFlags, 4, 0);
1074 if( zOut ){
1075 blob_write_to_file(&down, zOut);
1076 fossil_print("Chat database at %s is %d bytes\n", zOut, blob_size(&down));
1077 }else{
1078 db_multi_exec("ATTACH ':memory:' AS chatbu;");
1079 if( g.fSqlTrace ){
1080 fossil_trace("-- deserialize(\"chatbu\", pData, %d);\n",
1081 blob_size(&down));
1082 }
1083 rc = sqlite3_deserialize(g.db, "chatbu",
1084 (unsigned char*)blob_buffer(&down),
1085 blob_size(&down), blob_size(&down), 0);
1086 if( rc ){
1087 fossil_fatal("cannot open patch database: %s", sqlite3_errmsg(g.db));
1088 }
1089 nChat = db_int(0, "SELECT count(*) FROM chatbu.chat");
1090 fossil_print("Got %d new records, %d bytes\n", nChat, blob_size(&down));
1091 db_multi_exec(
1092 "REPLACE INTO repository.chat(msgid,mtime,lmtime,xfrom,xmsg,"
1093 "fname,fmime,mdel,file)"
1094 " SELECT msgid,mtime,lmtime,xfrom,xmsg,fname,fmime,mdel,file"
1095 " FROM chatbu.chat;"
1096 );
1097 }
1098 }else if( strcmp(g.argv[2],"url")==0 ){
1099 /* Show the URL to access chat. */
1100 fossil_print("%s/chat\n", zUrl);
1101 }else{
1102 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
1103 }
1104 }
1105
+3 -4
--- src/checkin.c
+++ src/checkin.c
@@ -2346,11 +2346,11 @@
23462346
if( !g.markPrivate ){
23472347
int syncFlags = SYNC_PULL;
23482348
if( vid!=0 && !allowFork && !forceFlag ){
23492349
syncFlags |= SYNC_CKIN_LOCK;
23502350
}
2351
- if( autosync_loop(syncFlags, db_get_int("autosync-tries", 1), 1) ){
2351
+ if( autosync_loop(syncFlags, 1, "commit") ){
23522352
fossil_exit(1);
23532353
}
23542354
}
23552355
23562356
/* So that older versions of Fossil (that do not understand delta-
@@ -2552,11 +2552,11 @@
25522552
if( !g.markPrivate && vid!=0 && !allowFork && !forceFlag ){
25532553
/* Do another auto-pull, renewing the check-in lock. Then set
25542554
** bRecheck so that we loop back above to verify that the check-in
25552555
** is still not against a closed branch and still won't fork. */
25562556
int syncFlags = SYNC_PULL|SYNC_CKIN_LOCK;
2557
- if( autosync_loop(syncFlags, db_get_int("autosync-tries", 1), 1) ){
2557
+ if( autosync_loop(syncFlags, 1, "commit") ){
25582558
fossil_fatal("Auto-pull failed. Commit aborted.");
25592559
}
25602560
bRecheck = 1;
25612561
}
25622562
}else{
@@ -2865,14 +2865,13 @@
28652865
free(zManifestFile);
28662866
}
28672867
28682868
if( !g.markPrivate ){
28692869
int syncFlags = SYNC_PUSH | SYNC_PULL | SYNC_IFABLE;
2870
- int nTries = db_get_int("autosync-tries",1);
2871
- autosync_loop(syncFlags, nTries, 0);
2870
+ autosync_loop(syncFlags, 0, "commit");
28722871
}
28732872
if( count_nonbranch_children(vid)>1 ){
28742873
fossil_print("**** warning: a fork has occurred *****\n");
28752874
}else{
28762875
leaf_ambiguity_warning(nvid,nvid);
28772876
}
28782877
}
28792878
--- src/checkin.c
+++ src/checkin.c
@@ -2346,11 +2346,11 @@
2346 if( !g.markPrivate ){
2347 int syncFlags = SYNC_PULL;
2348 if( vid!=0 && !allowFork && !forceFlag ){
2349 syncFlags |= SYNC_CKIN_LOCK;
2350 }
2351 if( autosync_loop(syncFlags, db_get_int("autosync-tries", 1), 1) ){
2352 fossil_exit(1);
2353 }
2354 }
2355
2356 /* So that older versions of Fossil (that do not understand delta-
@@ -2552,11 +2552,11 @@
2552 if( !g.markPrivate && vid!=0 && !allowFork && !forceFlag ){
2553 /* Do another auto-pull, renewing the check-in lock. Then set
2554 ** bRecheck so that we loop back above to verify that the check-in
2555 ** is still not against a closed branch and still won't fork. */
2556 int syncFlags = SYNC_PULL|SYNC_CKIN_LOCK;
2557 if( autosync_loop(syncFlags, db_get_int("autosync-tries", 1), 1) ){
2558 fossil_fatal("Auto-pull failed. Commit aborted.");
2559 }
2560 bRecheck = 1;
2561 }
2562 }else{
@@ -2865,14 +2865,13 @@
2865 free(zManifestFile);
2866 }
2867
2868 if( !g.markPrivate ){
2869 int syncFlags = SYNC_PUSH | SYNC_PULL | SYNC_IFABLE;
2870 int nTries = db_get_int("autosync-tries",1);
2871 autosync_loop(syncFlags, nTries, 0);
2872 }
2873 if( count_nonbranch_children(vid)>1 ){
2874 fossil_print("**** warning: a fork has occurred *****\n");
2875 }else{
2876 leaf_ambiguity_warning(nvid,nvid);
2877 }
2878 }
2879
--- src/checkin.c
+++ src/checkin.c
@@ -2346,11 +2346,11 @@
2346 if( !g.markPrivate ){
2347 int syncFlags = SYNC_PULL;
2348 if( vid!=0 && !allowFork && !forceFlag ){
2349 syncFlags |= SYNC_CKIN_LOCK;
2350 }
2351 if( autosync_loop(syncFlags, 1, "commit") ){
2352 fossil_exit(1);
2353 }
2354 }
2355
2356 /* So that older versions of Fossil (that do not understand delta-
@@ -2552,11 +2552,11 @@
2552 if( !g.markPrivate && vid!=0 && !allowFork && !forceFlag ){
2553 /* Do another auto-pull, renewing the check-in lock. Then set
2554 ** bRecheck so that we loop back above to verify that the check-in
2555 ** is still not against a closed branch and still won't fork. */
2556 int syncFlags = SYNC_PULL|SYNC_CKIN_LOCK;
2557 if( autosync_loop(syncFlags, 1, "commit") ){
2558 fossil_fatal("Auto-pull failed. Commit aborted.");
2559 }
2560 bRecheck = 1;
2561 }
2562 }else{
@@ -2865,14 +2865,13 @@
2865 free(zManifestFile);
2866 }
2867
2868 if( !g.markPrivate ){
2869 int syncFlags = SYNC_PUSH | SYNC_PULL | SYNC_IFABLE;
2870 autosync_loop(syncFlags, 0, "commit");
 
2871 }
2872 if( count_nonbranch_children(vid)>1 ){
2873 fossil_print("**** warning: a fork has occurred *****\n");
2874 }else{
2875 leaf_ambiguity_warning(nvid,nvid);
2876 }
2877 }
2878
+193 -34
--- src/db.c
+++ src/db.c
@@ -1376,16 +1376,68 @@
13761376
return;
13771377
}
13781378
zSetting = (const char*)sqlite3_value_text(argv[0]);
13791379
sqlite3_result_int(context, db_setting_is_protected(zSetting));
13801380
}
1381
+
1382
+/*
1383
+** Copied from SQLite ext/misc/uint.c...
1384
+**
1385
+** Compare text in lexicographic order, except strings of digits
1386
+** compare in numeric order.
1387
+**
1388
+** This version modified to also ignore case.
1389
+*/
1390
+static int uintNocaseCollFunc(
1391
+ void *notUsed,
1392
+ int nKey1, const void *pKey1,
1393
+ int nKey2, const void *pKey2
1394
+){
1395
+ const unsigned char *zA = (const unsigned char*)pKey1;
1396
+ const unsigned char *zB = (const unsigned char*)pKey2;
1397
+ int i=0, j=0, x;
1398
+ (void)notUsed;
1399
+ while( i<nKey1 && j<nKey2 ){
1400
+ if( fossil_isdigit(zA[i]) && fossil_isdigit(zB[j]) ){
1401
+ int k;
1402
+ while( i<nKey1 && zA[i]=='0' ){ i++; }
1403
+ while( j<nKey2 && zB[j]=='0' ){ j++; }
1404
+ k = 0;
1405
+ while( i+k<nKey1 && fossil_isdigit(zA[i+k])
1406
+ && j+k<nKey2 && fossil_isdigit(zB[j+k]) ){
1407
+ k++;
1408
+ }
1409
+ if( i+k<nKey1 && fossil_isdigit(zA[i+k]) ){
1410
+ return +1;
1411
+ }else if( j+k<nKey2 && fossil_isdigit(zB[j+k]) ){
1412
+ return -1;
1413
+ }else{
1414
+ x = memcmp(zA+i, zB+j, k);
1415
+ if( x ) return x;
1416
+ i += k;
1417
+ j += k;
1418
+ }
1419
+ }else
1420
+ if( zA[i]!=zB[j]
1421
+ && (x = fossil_tolower(zA[i]) - fossil_tolower(zB[j]))!=0
1422
+ ){
1423
+ return x;
1424
+ }else{
1425
+ i++;
1426
+ j++;
1427
+ }
1428
+ }
1429
+ return (nKey1 - i) - (nKey2 - j);
1430
+}
1431
+
13811432
13821433
/*
13831434
** Register the SQL functions that are useful both to the internal
13841435
** representation and to the "fossil sql" command.
13851436
*/
13861437
void db_add_aux_functions(sqlite3 *db){
1438
+ sqlite3_create_collation(db, "uintnocase", SQLITE_UTF8,0,uintNocaseCollFunc);
13871439
sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0,
13881440
db_checkin_mtime_function, 0, 0);
13891441
sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0,
13901442
db_sym2rid_function, 0, 0);
13911443
sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0,
@@ -1635,19 +1687,26 @@
16351687
** connection. An error results in process abort.
16361688
*/
16371689
LOCAL sqlite3 *db_open(const char *zDbName){
16381690
int rc;
16391691
sqlite3 *db;
1692
+ Blob bNameCheck = BLOB_INITIALIZER;
16401693
16411694
if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
1642
- if( strcmp(zDbName, g.nameOfExe)==0 ){
1695
+ file_canonical_name(zDbName, &bNameCheck, 0)
1696
+ /* For purposes of the apndvfs check, g.nameOfExe and zDbName must
1697
+ ** both be canonicalized, else chances are very good that they
1698
+ ** will not match even if they're the same file. Details:
1699
+ ** https://fossil-scm.org/forum/forumpost/16880a28aad1a868 */;
1700
+ if( strcmp(blob_str(&bNameCheck), g.nameOfExe)==0 ){
16431701
extern int sqlite3_appendvfs_init(
16441702
sqlite3 *, char **, const sqlite3_api_routines *
16451703
);
16461704
sqlite3_appendvfs_init(0,0,0);
16471705
g.zVfsName = "apndvfs";
16481706
}
1707
+ blob_zero(&bNameCheck);
16491708
rc = sqlite3_open_v2(
16501709
zDbName, &db,
16511710
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
16521711
g.zVfsName
16531712
);
@@ -2140,13 +2199,13 @@
21402199
int res = 0;
21412200
sqlite3_stmt *pStmt = 0;
21422201
21432202
sz = file_size(zDbName, ExtFILE);
21442203
if( sz<16834 ) return 0;
2145
- if( sz & 0x1ff ) return 0;
2146
- rc = sqlite3_open(zDbName, &db);
2147
- if( rc ) goto is_repo_end;
2204
+ db = db_open(zDbName);
2205
+ if( !db ) return 0;
2206
+ if( !g.zVfsName && sz%512 ) return 0;
21482207
rc = sqlite3_prepare_v2(db,
21492208
"SELECT count(*) FROM sqlite_schema"
21502209
" WHERE name COLLATE nocase IN"
21512210
"('blob','delta','rcvfrom','user','config','mlink','plink');",
21522211
-1, &pStmt, 0);
@@ -2179,24 +2238,20 @@
21792238
/*
21802239
** Open the repository database given by zDbName. If zDbName==NULL then
21812240
** get the name from the already open local database.
21822241
*/
21832242
void db_open_repository(const char *zDbName){
2184
- i64 sz;
21852243
if( g.repositoryOpen ) return;
21862244
if( zDbName==0 ){
21872245
if( g.localOpen ){
21882246
zDbName = db_repository_filename();
21892247
}
21902248
if( zDbName==0 ){
21912249
db_err("unable to find the name of a repository database");
21922250
}
21932251
}
2194
- if( file_access(zDbName, R_OK)
2195
- || (sz = file_size(zDbName, ExtFILE))<16384
2196
- || (sz&0x1ff)!=0
2197
- ){
2252
+ if( !db_looks_like_a_repository(zDbName) ){
21982253
if( file_access(zDbName, F_OK) ){
21992254
#ifdef FOSSIL_ENABLE_JSON
22002255
g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
22012256
#endif
22022257
fossil_fatal("repository does not exist or"
@@ -3423,11 +3478,58 @@
34233478
va_end(ap);
34243479
db_unset(zName/*works-like:"x"*/, iGlobal);
34253480
fossil_free(zName);
34263481
}
34273482
3428
-
3483
+/*
3484
+** Get a setting that is tailored to subsystem. The return value is
3485
+** NULL if the setting does not exist, or a string obtained from mprintf()
3486
+** if the setting is available.
3487
+**
3488
+** The actual setting can be a comma-separated list of values of the form:
3489
+**
3490
+** * VALUE
3491
+** * SUBSYSTEM=VALUE
3492
+**
3493
+** A VALUE without the SUBSYSTEM= prefix is the default. This routine
3494
+** returns the VALUE that with the matching SUBSYSTEM, or the default
3495
+** VALUE if there is no match.
3496
+*/
3497
+char *db_get_for_subsystem(const char *zName, const char *zSubsys){
3498
+ int nSubsys;
3499
+ char *zToFree = 0;
3500
+ char *zCopy;
3501
+ char *zNext;
3502
+ char *zResult = 0;
3503
+ const char *zSetting = db_get(zName, 0);
3504
+ if( zSetting==0 ) return 0;
3505
+ zCopy = zToFree = fossil_strdup(zSetting);
3506
+ if( zSubsys==0 ) zSubsys = "";
3507
+ nSubsys = (int)strlen(zSubsys);
3508
+ while( zCopy ){
3509
+ zNext = strchr(zCopy, ',');
3510
+ if( zNext ){
3511
+ zNext[0] = 0;
3512
+ do{ zNext++; }while( fossil_isspace(zNext[0]) );
3513
+ if( zNext[0]==0 ) zNext = 0;
3514
+ }
3515
+ if( strchr(zCopy,'=')==0 ){
3516
+ if( zResult==0 ) zResult = zCopy;
3517
+ }else
3518
+ if( nSubsys
3519
+ && strncmp(zCopy, zSubsys, nSubsys)==0
3520
+ && zCopy[nSubsys]=='='
3521
+ ){
3522
+ zResult = &zCopy[nSubsys+1];
3523
+ break;
3524
+ }
3525
+ zCopy = zNext;
3526
+ }
3527
+ if( zResult ) zResult = fossil_strdup(zResult);
3528
+ fossil_free(zToFree);
3529
+ return zResult;
3530
+}
34293531
34303532
#if INTERFACE
34313533
/* Manifest generation flags */
34323534
#define MFESTFLG_RAW 0x01
34333535
#define MFESTFLG_UUID 0x02
@@ -3569,16 +3671,19 @@
35693671
** -f|--force Continue with the open even if the working directory is
35703672
** not empty.
35713673
** --force-missing Force opening a repository with missing content
35723674
** -k|--keep Only modify the manifest and manifest.uuid files
35733675
** --nested Allow opening a repository inside an opened checkout
3574
-** --nosync Do not auto-sync the repository prior to opening
3676
+** --nosync Do not auto-sync the repository prior to opening even
3677
+** if the autosync setting is on.
35753678
** --repodir DIR If REPOSITORY is a URI that will be cloned, store
35763679
** the clone in DIR rather than in "."
35773680
** --setmtime Set timestamps of all files to match their SCM-side
35783681
** times (the timestamp of the last checkin which modified
35793682
** them).
3683
+** --sync Auto-sync prior to opening even if the autosync setting
3684
+** is off.
35803685
** --verbose If passed a URI then this flag is passed on to the clone
35813686
** operation, otherwise it has no effect.
35823687
** --workdir DIR Use DIR as the working directory instead of ".". The DIR
35833688
** directory is created if it does not exist.
35843689
**
@@ -3596,11 +3701,10 @@
35963701
const char *zRepo = 0; /* Name of the repository file */
35973702
const char *zRepoDir = 0; /* --repodir value */
35983703
char *zPwd; /* Initial working directory */
35993704
int isUri = 0; /* True if REPOSITORY is a URI */
36003705
int nLocal; /* Number of preexisting files in cwd */
3601
- int bNosync = 0; /* --nosync. Omit auto-sync */
36023706
int bVerbose = 0; /* --verbose option for clone */
36033707
36043708
url_proxy_options();
36053709
emptyFlag = find_option("empty",0,0)!=0;
36063710
keepFlag = find_option("keep","k",0)!=0;
@@ -3607,15 +3711,14 @@
36073711
forceMissingFlag = find_option("force-missing",0,0)!=0;
36083712
allowNested = find_option("nested",0,0)!=0;
36093713
setmtimeFlag = find_option("setmtime",0,0)!=0;
36103714
zWorkDir = find_option("workdir",0,1);
36113715
zRepoDir = find_option("repodir",0,1);
3612
- bForce = find_option("force","f",0)!=0;
3613
- bNosync = find_option("nosync",0,0)!=0;
3716
+ bForce = find_option("force","f",0)!=0;
3717
+ if( find_option("nosync",0,0) ) g.fNoSync = 1;
36143718
bVerbose = find_option("verbose",0,0)!=0;
36153719
zPwd = file_getcwd(0,0);
3616
-
36173720
36183721
/* We should be done with options.. */
36193722
verify_all_options();
36203723
36213724
if( g.argc!=3 && g.argc!=4 ){
@@ -3701,23 +3804,21 @@
37013804
fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
37023805
"argument is a URI that begins with http:, https:, ssh:, "
37033806
"or file:");
37043807
}
37053808
3809
+ db_open_config(0,0);
37063810
db_open_repository(zRepo);
37073811
37083812
/* Figure out which revision to open. */
37093813
if( !emptyFlag ){
37103814
if( g.argc==4 ){
37113815
g.zOpenRevision = g.argv[3];
37123816
}else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
37133817
g.zOpenRevision = db_get("main-branch", 0);
37143818
}
3715
- if( !bNosync
3716
- && autosync_loop(SYNC_PULL, db_get_int("autosync-tries", 1), 1)
3717
- && !bForce
3718
- ){
3819
+ if( autosync_loop(SYNC_PULL, !bForce, "open") && !bForce ){
37193820
fossil_fatal("unable to auto-sync the repository");
37203821
}
37213822
}
37223823
37233824
@@ -3869,33 +3970,78 @@
38693970
** If enabled, the /login page provides a button that will automatically
38703971
** fill in the captcha password. This makes things easier for human users,
38713972
** at the expense of also making logins easier for malicious robots.
38723973
*/
38733974
/*
3874
-** SETTING: auto-hyperlink boolean default=on
3875
-** Use javascript to enable hyperlinks on web pages
3876
-** for all users (regardless of the "h" privilege) if the
3877
-** User-Agent string in the HTTP header look like it came
3878
-** from real person, not a spider or bot.
3975
+** SETTING: auto-hyperlink width=16 default=1
3976
+**
3977
+** If non-zero, enable hyperlinks on web pages even for users that lack
3978
+** the "h" privilege as long as the UserAgent string in the HTTP request
3979
+** (The HTTP_USER_AGENT cgi variable) looks like it comes from a human and
3980
+** not a robot. Details depend on the value of the setting.
3981
+**
3982
+** (0) Off: No adjustments are made to the 'h' privilege based on
3983
+** the user agent.
3984
+**
3985
+** (1) UserAgent and Javascript: The the href= values of hyperlinks
3986
+** initially point to /honeypot and are changed to point to the
3987
+** correct target by javascript that runs after the page loads.
3988
+** The auto-hyperlink-delay and auto-hyperlink-mouseover settings
3989
+** influence that javascript.
3990
+**
3991
+** (2) UserAgent only: If the HTTP_USER_AGENT looks human
3992
+** then generate hyperlinks, otherwise do not.
3993
+**
3994
+** Better robot exclusion is obtained when this setting is 1 versus 2.
3995
+** However, a value of 1 causes the visited/unvisited colors of hyperlinks
3996
+** to stop working on Safari-derived web browsers. When this setting is 2,
3997
+** the hyperlinks work better on Safari, but more robots are able to sneak
3998
+** in.
3999
+*/
4000
+/*
4001
+** SETTING: auto-hyperlink-delay width=16 default=0
4002
+**
4003
+** When the auto-hyperlink setting is 1, the javascript that runs to set
4004
+** the href= attributes of hyperlinks delays by this many milliseconds
4005
+** after the page load. Suggested values: 50 to 200.
4006
+*/
4007
+/*
4008
+** SETTING: auto-hyperlink-mouseover boolean default=off
4009
+**
4010
+** When the auto-hyperlink setting is 1 and this setting is on, the
4011
+** javascript that runs to set the href= attributes of hyperlinks waits
4012
+** until either a mousedown or mousemove event is seen. This helps
4013
+** to distinguish real users from robots. For maximum robot defense,
4014
+** the recommended setting is ON.
38794015
*/
38804016
/*
38814017
** SETTING: auto-shun boolean default=on
38824018
** If enabled, automatically pull the shunning list
38834019
** from a server to which the client autosyncs.
38844020
*/
38854021
/*
38864022
** SETTING: autosync width=16 default=on
3887
-** This setting can be a boolean value (0, 1, on, off, true, false)
3888
-** or "pullonly" or "all".
4023
+** This setting determines when autosync occurs. The setting is a
4024
+** string that provides a lot of flexibility for determining when and
4025
+** when not to autosync. Examples:
4026
+**
4027
+** on Always autosync for command where autosync
4028
+** makes sense ("commit", "merge", "open", "update")
4029
+**
4030
+** off Never autosync.
4031
+**
4032
+** pullonly Only to pull autosyncs
4033
+**
4034
+** on,open=off Autosync for most commands, but not for "open"
4035
+**
4036
+** off,commit=pullonly Do not autosync, except do a pull before each
4037
+** "commit", presumably to avoid undesirable
4038
+** forks.
38894039
**
3890
-** If not false, automatically pull prior to commit
3891
-** or update and automatically push after commit or
3892
-** tag or branch creation. Except, if the value is
3893
-** "pullonly" then only pull operations occur automatically.
3894
-** Normally, only the default remote is used, but if the
3895
-** value is "all" then push/pull operations occur on all
3896
-** remotes.
4040
+** The syntax is a comma-separated list of VALUE and COMMAND=VALUE entries.
4041
+** A plain VALUE entry is the default that is used if no COMMAND matches.
4042
+** Otherwise, the VALUE of the matching command is used.
38974043
*/
38984044
/*
38994045
** SETTING: autosync-tries width=16 default=1
39004046
** If autosync is enabled setting this to a value greater
39014047
** than zero will cause autosync to try no more than this
@@ -4470,10 +4616,13 @@
44704616
*/
44714617
void setting_cmd(void){
44724618
int i;
44734619
int globalFlag = find_option("global","g",0)!=0;
44744620
int exactFlag = find_option("exact",0,0)!=0;
4621
+ /* Undocumented "--test-for-subsystem SUBSYS" option used to test
4622
+ ** the db_get_for_subsystem() interface: */
4623
+ const char *zSubsys = find_option("test-for-subsystem",0,1);
44754624
int unsetFlag = g.argv[1][0]=='u';
44764625
int nSetting;
44774626
const Setting *aSetting = setting_info(&nSetting);
44784627
find_repository_option();
44794628
verify_all_options();
@@ -4534,11 +4683,21 @@
45344683
if( exactFlag ){
45354684
if( fossil_strcmp(pSetting->name,zName)!=0 ) break;
45364685
}else{
45374686
if( fossil_strncmp(pSetting->name,zName,n)!=0 ) break;
45384687
}
4539
- print_setting(pSetting);
4688
+ if( zSubsys ){
4689
+ char *zValue = db_get_for_subsystem(pSetting->name, zSubsys);
4690
+ fossil_print("%s (subsystem %s) ->", pSetting->name, zSubsys);
4691
+ if( zValue ){
4692
+ fossil_print(" [%s]", zValue);
4693
+ fossil_free(zValue);
4694
+ }
4695
+ fossil_print("\n");
4696
+ }else{
4697
+ print_setting(pSetting);
4698
+ }
45404699
pSetting++;
45414700
}
45424701
}
45434702
}else{
45444703
usage("?PROPERTY? ?VALUE? ?-global?");
45454704
--- src/db.c
+++ src/db.c
@@ -1376,16 +1376,68 @@
1376 return;
1377 }
1378 zSetting = (const char*)sqlite3_value_text(argv[0]);
1379 sqlite3_result_int(context, db_setting_is_protected(zSetting));
1380 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1381
1382 /*
1383 ** Register the SQL functions that are useful both to the internal
1384 ** representation and to the "fossil sql" command.
1385 */
1386 void db_add_aux_functions(sqlite3 *db){
 
1387 sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0,
1388 db_checkin_mtime_function, 0, 0);
1389 sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0,
1390 db_sym2rid_function, 0, 0);
1391 sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0,
@@ -1635,19 +1687,26 @@
1635 ** connection. An error results in process abort.
1636 */
1637 LOCAL sqlite3 *db_open(const char *zDbName){
1638 int rc;
1639 sqlite3 *db;
 
1640
1641 if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
1642 if( strcmp(zDbName, g.nameOfExe)==0 ){
 
 
 
 
 
1643 extern int sqlite3_appendvfs_init(
1644 sqlite3 *, char **, const sqlite3_api_routines *
1645 );
1646 sqlite3_appendvfs_init(0,0,0);
1647 g.zVfsName = "apndvfs";
1648 }
 
1649 rc = sqlite3_open_v2(
1650 zDbName, &db,
1651 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1652 g.zVfsName
1653 );
@@ -2140,13 +2199,13 @@
2140 int res = 0;
2141 sqlite3_stmt *pStmt = 0;
2142
2143 sz = file_size(zDbName, ExtFILE);
2144 if( sz<16834 ) return 0;
2145 if( sz & 0x1ff ) return 0;
2146 rc = sqlite3_open(zDbName, &db);
2147 if( rc ) goto is_repo_end;
2148 rc = sqlite3_prepare_v2(db,
2149 "SELECT count(*) FROM sqlite_schema"
2150 " WHERE name COLLATE nocase IN"
2151 "('blob','delta','rcvfrom','user','config','mlink','plink');",
2152 -1, &pStmt, 0);
@@ -2179,24 +2238,20 @@
2179 /*
2180 ** Open the repository database given by zDbName. If zDbName==NULL then
2181 ** get the name from the already open local database.
2182 */
2183 void db_open_repository(const char *zDbName){
2184 i64 sz;
2185 if( g.repositoryOpen ) return;
2186 if( zDbName==0 ){
2187 if( g.localOpen ){
2188 zDbName = db_repository_filename();
2189 }
2190 if( zDbName==0 ){
2191 db_err("unable to find the name of a repository database");
2192 }
2193 }
2194 if( file_access(zDbName, R_OK)
2195 || (sz = file_size(zDbName, ExtFILE))<16384
2196 || (sz&0x1ff)!=0
2197 ){
2198 if( file_access(zDbName, F_OK) ){
2199 #ifdef FOSSIL_ENABLE_JSON
2200 g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
2201 #endif
2202 fossil_fatal("repository does not exist or"
@@ -3423,11 +3478,58 @@
3423 va_end(ap);
3424 db_unset(zName/*works-like:"x"*/, iGlobal);
3425 fossil_free(zName);
3426 }
3427
3428
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3429
3430 #if INTERFACE
3431 /* Manifest generation flags */
3432 #define MFESTFLG_RAW 0x01
3433 #define MFESTFLG_UUID 0x02
@@ -3569,16 +3671,19 @@
3569 ** -f|--force Continue with the open even if the working directory is
3570 ** not empty.
3571 ** --force-missing Force opening a repository with missing content
3572 ** -k|--keep Only modify the manifest and manifest.uuid files
3573 ** --nested Allow opening a repository inside an opened checkout
3574 ** --nosync Do not auto-sync the repository prior to opening
 
3575 ** --repodir DIR If REPOSITORY is a URI that will be cloned, store
3576 ** the clone in DIR rather than in "."
3577 ** --setmtime Set timestamps of all files to match their SCM-side
3578 ** times (the timestamp of the last checkin which modified
3579 ** them).
 
 
3580 ** --verbose If passed a URI then this flag is passed on to the clone
3581 ** operation, otherwise it has no effect.
3582 ** --workdir DIR Use DIR as the working directory instead of ".". The DIR
3583 ** directory is created if it does not exist.
3584 **
@@ -3596,11 +3701,10 @@
3596 const char *zRepo = 0; /* Name of the repository file */
3597 const char *zRepoDir = 0; /* --repodir value */
3598 char *zPwd; /* Initial working directory */
3599 int isUri = 0; /* True if REPOSITORY is a URI */
3600 int nLocal; /* Number of preexisting files in cwd */
3601 int bNosync = 0; /* --nosync. Omit auto-sync */
3602 int bVerbose = 0; /* --verbose option for clone */
3603
3604 url_proxy_options();
3605 emptyFlag = find_option("empty",0,0)!=0;
3606 keepFlag = find_option("keep","k",0)!=0;
@@ -3607,15 +3711,14 @@
3607 forceMissingFlag = find_option("force-missing",0,0)!=0;
3608 allowNested = find_option("nested",0,0)!=0;
3609 setmtimeFlag = find_option("setmtime",0,0)!=0;
3610 zWorkDir = find_option("workdir",0,1);
3611 zRepoDir = find_option("repodir",0,1);
3612 bForce = find_option("force","f",0)!=0;
3613 bNosync = find_option("nosync",0,0)!=0;
3614 bVerbose = find_option("verbose",0,0)!=0;
3615 zPwd = file_getcwd(0,0);
3616
3617
3618 /* We should be done with options.. */
3619 verify_all_options();
3620
3621 if( g.argc!=3 && g.argc!=4 ){
@@ -3701,23 +3804,21 @@
3701 fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
3702 "argument is a URI that begins with http:, https:, ssh:, "
3703 "or file:");
3704 }
3705
 
3706 db_open_repository(zRepo);
3707
3708 /* Figure out which revision to open. */
3709 if( !emptyFlag ){
3710 if( g.argc==4 ){
3711 g.zOpenRevision = g.argv[3];
3712 }else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
3713 g.zOpenRevision = db_get("main-branch", 0);
3714 }
3715 if( !bNosync
3716 && autosync_loop(SYNC_PULL, db_get_int("autosync-tries", 1), 1)
3717 && !bForce
3718 ){
3719 fossil_fatal("unable to auto-sync the repository");
3720 }
3721 }
3722
3723
@@ -3869,33 +3970,78 @@
3869 ** If enabled, the /login page provides a button that will automatically
3870 ** fill in the captcha password. This makes things easier for human users,
3871 ** at the expense of also making logins easier for malicious robots.
3872 */
3873 /*
3874 ** SETTING: auto-hyperlink boolean default=on
3875 ** Use javascript to enable hyperlinks on web pages
3876 ** for all users (regardless of the "h" privilege) if the
3877 ** User-Agent string in the HTTP header look like it came
3878 ** from real person, not a spider or bot.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3879 */
3880 /*
3881 ** SETTING: auto-shun boolean default=on
3882 ** If enabled, automatically pull the shunning list
3883 ** from a server to which the client autosyncs.
3884 */
3885 /*
3886 ** SETTING: autosync width=16 default=on
3887 ** This setting can be a boolean value (0, 1, on, off, true, false)
3888 ** or "pullonly" or "all".
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3889 **
3890 ** If not false, automatically pull prior to commit
3891 ** or update and automatically push after commit or
3892 ** tag or branch creation. Except, if the value is
3893 ** "pullonly" then only pull operations occur automatically.
3894 ** Normally, only the default remote is used, but if the
3895 ** value is "all" then push/pull operations occur on all
3896 ** remotes.
3897 */
3898 /*
3899 ** SETTING: autosync-tries width=16 default=1
3900 ** If autosync is enabled setting this to a value greater
3901 ** than zero will cause autosync to try no more than this
@@ -4470,10 +4616,13 @@
4470 */
4471 void setting_cmd(void){
4472 int i;
4473 int globalFlag = find_option("global","g",0)!=0;
4474 int exactFlag = find_option("exact",0,0)!=0;
 
 
 
4475 int unsetFlag = g.argv[1][0]=='u';
4476 int nSetting;
4477 const Setting *aSetting = setting_info(&nSetting);
4478 find_repository_option();
4479 verify_all_options();
@@ -4534,11 +4683,21 @@
4534 if( exactFlag ){
4535 if( fossil_strcmp(pSetting->name,zName)!=0 ) break;
4536 }else{
4537 if( fossil_strncmp(pSetting->name,zName,n)!=0 ) break;
4538 }
4539 print_setting(pSetting);
 
 
 
 
 
 
 
 
 
 
4540 pSetting++;
4541 }
4542 }
4543 }else{
4544 usage("?PROPERTY? ?VALUE? ?-global?");
4545
--- src/db.c
+++ src/db.c
@@ -1376,16 +1376,68 @@
1376 return;
1377 }
1378 zSetting = (const char*)sqlite3_value_text(argv[0]);
1379 sqlite3_result_int(context, db_setting_is_protected(zSetting));
1380 }
1381
1382 /*
1383 ** Copied from SQLite ext/misc/uint.c...
1384 **
1385 ** Compare text in lexicographic order, except strings of digits
1386 ** compare in numeric order.
1387 **
1388 ** This version modified to also ignore case.
1389 */
1390 static int uintNocaseCollFunc(
1391 void *notUsed,
1392 int nKey1, const void *pKey1,
1393 int nKey2, const void *pKey2
1394 ){
1395 const unsigned char *zA = (const unsigned char*)pKey1;
1396 const unsigned char *zB = (const unsigned char*)pKey2;
1397 int i=0, j=0, x;
1398 (void)notUsed;
1399 while( i<nKey1 && j<nKey2 ){
1400 if( fossil_isdigit(zA[i]) && fossil_isdigit(zB[j]) ){
1401 int k;
1402 while( i<nKey1 && zA[i]=='0' ){ i++; }
1403 while( j<nKey2 && zB[j]=='0' ){ j++; }
1404 k = 0;
1405 while( i+k<nKey1 && fossil_isdigit(zA[i+k])
1406 && j+k<nKey2 && fossil_isdigit(zB[j+k]) ){
1407 k++;
1408 }
1409 if( i+k<nKey1 && fossil_isdigit(zA[i+k]) ){
1410 return +1;
1411 }else if( j+k<nKey2 && fossil_isdigit(zB[j+k]) ){
1412 return -1;
1413 }else{
1414 x = memcmp(zA+i, zB+j, k);
1415 if( x ) return x;
1416 i += k;
1417 j += k;
1418 }
1419 }else
1420 if( zA[i]!=zB[j]
1421 && (x = fossil_tolower(zA[i]) - fossil_tolower(zB[j]))!=0
1422 ){
1423 return x;
1424 }else{
1425 i++;
1426 j++;
1427 }
1428 }
1429 return (nKey1 - i) - (nKey2 - j);
1430 }
1431
1432
1433 /*
1434 ** Register the SQL functions that are useful both to the internal
1435 ** representation and to the "fossil sql" command.
1436 */
1437 void db_add_aux_functions(sqlite3 *db){
1438 sqlite3_create_collation(db, "uintnocase", SQLITE_UTF8,0,uintNocaseCollFunc);
1439 sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0,
1440 db_checkin_mtime_function, 0, 0);
1441 sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0,
1442 db_sym2rid_function, 0, 0);
1443 sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0,
@@ -1635,19 +1687,26 @@
1687 ** connection. An error results in process abort.
1688 */
1689 LOCAL sqlite3 *db_open(const char *zDbName){
1690 int rc;
1691 sqlite3 *db;
1692 Blob bNameCheck = BLOB_INITIALIZER;
1693
1694 if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
1695 file_canonical_name(zDbName, &bNameCheck, 0)
1696 /* For purposes of the apndvfs check, g.nameOfExe and zDbName must
1697 ** both be canonicalized, else chances are very good that they
1698 ** will not match even if they're the same file. Details:
1699 ** https://fossil-scm.org/forum/forumpost/16880a28aad1a868 */;
1700 if( strcmp(blob_str(&bNameCheck), g.nameOfExe)==0 ){
1701 extern int sqlite3_appendvfs_init(
1702 sqlite3 *, char **, const sqlite3_api_routines *
1703 );
1704 sqlite3_appendvfs_init(0,0,0);
1705 g.zVfsName = "apndvfs";
1706 }
1707 blob_zero(&bNameCheck);
1708 rc = sqlite3_open_v2(
1709 zDbName, &db,
1710 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
1711 g.zVfsName
1712 );
@@ -2140,13 +2199,13 @@
2199 int res = 0;
2200 sqlite3_stmt *pStmt = 0;
2201
2202 sz = file_size(zDbName, ExtFILE);
2203 if( sz<16834 ) return 0;
2204 db = db_open(zDbName);
2205 if( !db ) return 0;
2206 if( !g.zVfsName && sz%512 ) return 0;
2207 rc = sqlite3_prepare_v2(db,
2208 "SELECT count(*) FROM sqlite_schema"
2209 " WHERE name COLLATE nocase IN"
2210 "('blob','delta','rcvfrom','user','config','mlink','plink');",
2211 -1, &pStmt, 0);
@@ -2179,24 +2238,20 @@
2238 /*
2239 ** Open the repository database given by zDbName. If zDbName==NULL then
2240 ** get the name from the already open local database.
2241 */
2242 void db_open_repository(const char *zDbName){
 
2243 if( g.repositoryOpen ) return;
2244 if( zDbName==0 ){
2245 if( g.localOpen ){
2246 zDbName = db_repository_filename();
2247 }
2248 if( zDbName==0 ){
2249 db_err("unable to find the name of a repository database");
2250 }
2251 }
2252 if( !db_looks_like_a_repository(zDbName) ){
 
 
 
2253 if( file_access(zDbName, F_OK) ){
2254 #ifdef FOSSIL_ENABLE_JSON
2255 g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
2256 #endif
2257 fossil_fatal("repository does not exist or"
@@ -3423,11 +3478,58 @@
3478 va_end(ap);
3479 db_unset(zName/*works-like:"x"*/, iGlobal);
3480 fossil_free(zName);
3481 }
3482
3483 /*
3484 ** Get a setting that is tailored to subsystem. The return value is
3485 ** NULL if the setting does not exist, or a string obtained from mprintf()
3486 ** if the setting is available.
3487 **
3488 ** The actual setting can be a comma-separated list of values of the form:
3489 **
3490 ** * VALUE
3491 ** * SUBSYSTEM=VALUE
3492 **
3493 ** A VALUE without the SUBSYSTEM= prefix is the default. This routine
3494 ** returns the VALUE that with the matching SUBSYSTEM, or the default
3495 ** VALUE if there is no match.
3496 */
3497 char *db_get_for_subsystem(const char *zName, const char *zSubsys){
3498 int nSubsys;
3499 char *zToFree = 0;
3500 char *zCopy;
3501 char *zNext;
3502 char *zResult = 0;
3503 const char *zSetting = db_get(zName, 0);
3504 if( zSetting==0 ) return 0;
3505 zCopy = zToFree = fossil_strdup(zSetting);
3506 if( zSubsys==0 ) zSubsys = "";
3507 nSubsys = (int)strlen(zSubsys);
3508 while( zCopy ){
3509 zNext = strchr(zCopy, ',');
3510 if( zNext ){
3511 zNext[0] = 0;
3512 do{ zNext++; }while( fossil_isspace(zNext[0]) );
3513 if( zNext[0]==0 ) zNext = 0;
3514 }
3515 if( strchr(zCopy,'=')==0 ){
3516 if( zResult==0 ) zResult = zCopy;
3517 }else
3518 if( nSubsys
3519 && strncmp(zCopy, zSubsys, nSubsys)==0
3520 && zCopy[nSubsys]=='='
3521 ){
3522 zResult = &zCopy[nSubsys+1];
3523 break;
3524 }
3525 zCopy = zNext;
3526 }
3527 if( zResult ) zResult = fossil_strdup(zResult);
3528 fossil_free(zToFree);
3529 return zResult;
3530 }
3531
3532 #if INTERFACE
3533 /* Manifest generation flags */
3534 #define MFESTFLG_RAW 0x01
3535 #define MFESTFLG_UUID 0x02
@@ -3569,16 +3671,19 @@
3671 ** -f|--force Continue with the open even if the working directory is
3672 ** not empty.
3673 ** --force-missing Force opening a repository with missing content
3674 ** -k|--keep Only modify the manifest and manifest.uuid files
3675 ** --nested Allow opening a repository inside an opened checkout
3676 ** --nosync Do not auto-sync the repository prior to opening even
3677 ** if the autosync setting is on.
3678 ** --repodir DIR If REPOSITORY is a URI that will be cloned, store
3679 ** the clone in DIR rather than in "."
3680 ** --setmtime Set timestamps of all files to match their SCM-side
3681 ** times (the timestamp of the last checkin which modified
3682 ** them).
3683 ** --sync Auto-sync prior to opening even if the autosync setting
3684 ** is off.
3685 ** --verbose If passed a URI then this flag is passed on to the clone
3686 ** operation, otherwise it has no effect.
3687 ** --workdir DIR Use DIR as the working directory instead of ".". The DIR
3688 ** directory is created if it does not exist.
3689 **
@@ -3596,11 +3701,10 @@
3701 const char *zRepo = 0; /* Name of the repository file */
3702 const char *zRepoDir = 0; /* --repodir value */
3703 char *zPwd; /* Initial working directory */
3704 int isUri = 0; /* True if REPOSITORY is a URI */
3705 int nLocal; /* Number of preexisting files in cwd */
 
3706 int bVerbose = 0; /* --verbose option for clone */
3707
3708 url_proxy_options();
3709 emptyFlag = find_option("empty",0,0)!=0;
3710 keepFlag = find_option("keep","k",0)!=0;
@@ -3607,15 +3711,14 @@
3711 forceMissingFlag = find_option("force-missing",0,0)!=0;
3712 allowNested = find_option("nested",0,0)!=0;
3713 setmtimeFlag = find_option("setmtime",0,0)!=0;
3714 zWorkDir = find_option("workdir",0,1);
3715 zRepoDir = find_option("repodir",0,1);
3716 bForce = find_option("force","f",0)!=0;
3717 if( find_option("nosync",0,0) ) g.fNoSync = 1;
3718 bVerbose = find_option("verbose",0,0)!=0;
3719 zPwd = file_getcwd(0,0);
 
3720
3721 /* We should be done with options.. */
3722 verify_all_options();
3723
3724 if( g.argc!=3 && g.argc!=4 ){
@@ -3701,23 +3804,21 @@
3804 fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
3805 "argument is a URI that begins with http:, https:, ssh:, "
3806 "or file:");
3807 }
3808
3809 db_open_config(0,0);
3810 db_open_repository(zRepo);
3811
3812 /* Figure out which revision to open. */
3813 if( !emptyFlag ){
3814 if( g.argc==4 ){
3815 g.zOpenRevision = g.argv[3];
3816 }else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
3817 g.zOpenRevision = db_get("main-branch", 0);
3818 }
3819 if( autosync_loop(SYNC_PULL, !bForce, "open") && !bForce ){
 
 
 
3820 fossil_fatal("unable to auto-sync the repository");
3821 }
3822 }
3823
3824
@@ -3869,33 +3970,78 @@
3970 ** If enabled, the /login page provides a button that will automatically
3971 ** fill in the captcha password. This makes things easier for human users,
3972 ** at the expense of also making logins easier for malicious robots.
3973 */
3974 /*
3975 ** SETTING: auto-hyperlink width=16 default=1
3976 **
3977 ** If non-zero, enable hyperlinks on web pages even for users that lack
3978 ** the "h" privilege as long as the UserAgent string in the HTTP request
3979 ** (The HTTP_USER_AGENT cgi variable) looks like it comes from a human and
3980 ** not a robot. Details depend on the value of the setting.
3981 **
3982 ** (0) Off: No adjustments are made to the 'h' privilege based on
3983 ** the user agent.
3984 **
3985 ** (1) UserAgent and Javascript: The the href= values of hyperlinks
3986 ** initially point to /honeypot and are changed to point to the
3987 ** correct target by javascript that runs after the page loads.
3988 ** The auto-hyperlink-delay and auto-hyperlink-mouseover settings
3989 ** influence that javascript.
3990 **
3991 ** (2) UserAgent only: If the HTTP_USER_AGENT looks human
3992 ** then generate hyperlinks, otherwise do not.
3993 **
3994 ** Better robot exclusion is obtained when this setting is 1 versus 2.
3995 ** However, a value of 1 causes the visited/unvisited colors of hyperlinks
3996 ** to stop working on Safari-derived web browsers. When this setting is 2,
3997 ** the hyperlinks work better on Safari, but more robots are able to sneak
3998 ** in.
3999 */
4000 /*
4001 ** SETTING: auto-hyperlink-delay width=16 default=0
4002 **
4003 ** When the auto-hyperlink setting is 1, the javascript that runs to set
4004 ** the href= attributes of hyperlinks delays by this many milliseconds
4005 ** after the page load. Suggested values: 50 to 200.
4006 */
4007 /*
4008 ** SETTING: auto-hyperlink-mouseover boolean default=off
4009 **
4010 ** When the auto-hyperlink setting is 1 and this setting is on, the
4011 ** javascript that runs to set the href= attributes of hyperlinks waits
4012 ** until either a mousedown or mousemove event is seen. This helps
4013 ** to distinguish real users from robots. For maximum robot defense,
4014 ** the recommended setting is ON.
4015 */
4016 /*
4017 ** SETTING: auto-shun boolean default=on
4018 ** If enabled, automatically pull the shunning list
4019 ** from a server to which the client autosyncs.
4020 */
4021 /*
4022 ** SETTING: autosync width=16 default=on
4023 ** This setting determines when autosync occurs. The setting is a
4024 ** string that provides a lot of flexibility for determining when and
4025 ** when not to autosync. Examples:
4026 **
4027 ** on Always autosync for command where autosync
4028 ** makes sense ("commit", "merge", "open", "update")
4029 **
4030 ** off Never autosync.
4031 **
4032 ** pullonly Only to pull autosyncs
4033 **
4034 ** on,open=off Autosync for most commands, but not for "open"
4035 **
4036 ** off,commit=pullonly Do not autosync, except do a pull before each
4037 ** "commit", presumably to avoid undesirable
4038 ** forks.
4039 **
4040 ** The syntax is a comma-separated list of VALUE and COMMAND=VALUE entries.
4041 ** A plain VALUE entry is the default that is used if no COMMAND matches.
4042 ** Otherwise, the VALUE of the matching command is used.
 
 
 
 
4043 */
4044 /*
4045 ** SETTING: autosync-tries width=16 default=1
4046 ** If autosync is enabled setting this to a value greater
4047 ** than zero will cause autosync to try no more than this
@@ -4470,10 +4616,13 @@
4616 */
4617 void setting_cmd(void){
4618 int i;
4619 int globalFlag = find_option("global","g",0)!=0;
4620 int exactFlag = find_option("exact",0,0)!=0;
4621 /* Undocumented "--test-for-subsystem SUBSYS" option used to test
4622 ** the db_get_for_subsystem() interface: */
4623 const char *zSubsys = find_option("test-for-subsystem",0,1);
4624 int unsetFlag = g.argv[1][0]=='u';
4625 int nSetting;
4626 const Setting *aSetting = setting_info(&nSetting);
4627 find_repository_option();
4628 verify_all_options();
@@ -4534,11 +4683,21 @@
4683 if( exactFlag ){
4684 if( fossil_strcmp(pSetting->name,zName)!=0 ) break;
4685 }else{
4686 if( fossil_strncmp(pSetting->name,zName,n)!=0 ) break;
4687 }
4688 if( zSubsys ){
4689 char *zValue = db_get_for_subsystem(pSetting->name, zSubsys);
4690 fossil_print("%s (subsystem %s) ->", pSetting->name, zSubsys);
4691 if( zValue ){
4692 fossil_print(" [%s]", zValue);
4693 fossil_free(zValue);
4694 }
4695 fossil_print("\n");
4696 }else{
4697 print_setting(pSetting);
4698 }
4699 pSetting++;
4700 }
4701 }
4702 }else{
4703 usage("?PROPERTY? ?VALUE? ?-global?");
4704
+72 -12
--- src/diff.c
+++ src/diff.c
@@ -2589,11 +2589,11 @@
25892589
p->aEdit[p->nEdit++] = nDel;
25902590
p->aEdit[p->nEdit++] = nIns;
25912591
}
25922592
25932593
/*
2594
-** A common subsequene between p->aFrom and p->aTo has been found.
2594
+** A common subsequence between p->aFrom and p->aTo has been found.
25952595
** This routine tries to judge if the subsequence really is a valid
25962596
** match or rather is just an artifact of an indentation change.
25972597
**
25982598
** Return non-zero if the subsequence is valid. Return zero if the
25992599
** subsequence seems likely to be an editing artifact and should be
@@ -2618,33 +2618,92 @@
26182618
** ALGORITHM (subject to change and refinement):
26192619
**
26202620
** 1. If the subsequence is larger than 1/7th of the original span,
26212621
** then consider it valid. --> return 1
26222622
**
2623
-** 2. If the subsequence contains any charaters other than '}', '{",
2624
-** or whitespace, then consider it valid. --> return 1
2623
+** 2. If no lines of the subsequence contains more than one
2624
+** non-whitespace character, --> return 0
2625
+**
2626
+** 3. If any line of the subsequence contains more than one non-whitespace
2627
+** character and is unique across the entire sequence after ignoring
2628
+** leading and trailing whitespace --> return 1
26252629
**
2626
-** 3. Otherwise, it is potentially an artifact of an indentation
2630
+** 4. Otherwise, it is potentially an artifact of an indentation
26272631
** change. --> return 0
26282632
*/
26292633
static int likelyNotIndentChngArtifact(
26302634
DContext *p, /* The complete diff context */
26312635
int iS1, /* Start of the main segment */
26322636
int iSX, /* Start of the subsequence */
26332637
int iEX, /* First row past the end of the subsequence */
26342638
int iE1 /* First row past the end of the main segment */
26352639
){
2636
- int i, j;
2640
+ int i, j, n;
2641
+
2642
+ /* Rule (1) */
26372643
if( (iEX-iSX)*7 >= (iE1-iS1) ) return 1;
2644
+
2645
+ /* Compute DLine.indent and DLine.nw for all lines of the subsequence.
2646
+ ** If no lines contain more than one non-whitespace character return
2647
+ ** 0 because the subsequence could be due to an indentation change.
2648
+ ** Rule (2).
2649
+ */
2650
+ n = 0;
2651
+ for(i=iSX; i<iEX; i++){
2652
+ DLine *pA = &p->aFrom[i];
2653
+ if( pA->nw==0 && pA->n ){
2654
+ const char *zA = pA->z;
2655
+ const int nn = pA->n;
2656
+ int ii, jj;
2657
+ for(ii=0; ii<nn && diff_isspace(zA[ii]); ii++){}
2658
+ pA->indent = ii;
2659
+ for(jj=nn-1; jj>ii && diff_isspace(zA[jj]); jj--){}
2660
+ pA->nw = jj - ii + 1;
2661
+ }
2662
+ if( pA->nw>1 ) n++;
2663
+ }
2664
+ if( n==0 ) return 0;
2665
+
2666
+ /* Compute DLine.indent and DLine.nw for the entire sequence */
2667
+ for(i=iS1; i<iE1; i++){
2668
+ DLine *pA;
2669
+ if( i==iSX ){
2670
+ i = iEX;
2671
+ if( i>=iE1 ) break;
2672
+ }
2673
+ pA = &p->aFrom[i];
2674
+ if( pA->nw==0 && pA->n ){
2675
+ const char *zA = pA->z;
2676
+ const int nn = pA->n;
2677
+ int ii, jj;
2678
+ for(ii=0; ii<nn && diff_isspace(zA[ii]); ii++){}
2679
+ pA->indent = ii;
2680
+ for(jj=nn-1; jj>ii && diff_isspace(zA[jj]); jj--){}
2681
+ pA->nw = jj - ii + 1;
2682
+ }
2683
+ }
2684
+
2685
+ /* Check to see if any subsequence line that has more than one
2686
+ ** non-whitespace character is unique across the entire sequence.
2687
+ ** Rule (3)
2688
+ */
26382689
for(i=iSX; i<iEX; i++){
2639
- const char *z = p->aFrom[i].z;
2640
- for(j=p->aFrom[i].n-1; j>=0; j--){
2641
- char c = z[j];
2642
- if( c!='}' && c!='{' && !diff_isspace(c) ) return 1;
2690
+ const char *z = p->aFrom[i].z + p->aFrom[i].indent;
2691
+ const int nw = p->aFrom[i].nw;
2692
+ if( nw<=1 ) continue;
2693
+ for(j=iS1; j<iSX; j++){
2694
+ if( p->aFrom[j].nw!=nw ) continue;
2695
+ if( memcmp(p->aFrom[j].z+p->aFrom[j].indent,z,nw)==0 ) break;
2696
+ }
2697
+ if( j<iSX ) continue;
2698
+ for(j=iEX; j<iE1; j++){
2699
+ if( p->aFrom[j].nw!=nw ) continue;
2700
+ if( memcmp(p->aFrom[j].z+p->aFrom[j].indent,z,nw)==0 ) break;
26432701
}
2702
+ if( j>=iE1 ) break;
26442703
}
2645
- return 0;
2704
+ return i<iEX;
26462705
}
26472706
26482707
26492708
/*
26502709
** Do a single step in the difference. Compute a sequence of
@@ -3355,11 +3414,12 @@
33553414
if( strcmp(zLimit,"none")==0 ){
33563415
iLimit = 0;
33573416
mxTime = 0;
33583417
}else if( sqlite3_strglob("*[0-9]s", zLimit)==0 ){
33593418
iLimit = 0;
3360
- mxTime = current_time_in_milliseconds() + 1000.0*atof(zLimit);
3419
+ mxTime =
3420
+ (sqlite3_int64)(current_time_in_milliseconds() + 1000.0*atof(zLimit));
33613421
}else{
33623422
iLimit = atoi(zLimit);
33633423
if( iLimit<=0 ) iLimit = 30;
33643424
mxTime = 0;
33653425
}
@@ -3534,11 +3594,11 @@
35343594
35353595
/* Gather query parameters */
35363596
login_check_credentials();
35373597
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
35383598
if( exclude_spiders() ) return;
3539
- load_control();
3599
+ fossil_nice_default();
35403600
zFilename = P("filename");
35413601
zRevision = PD("checkin",0);
35423602
zOrigin = P("origin");
35433603
zLimit = P("limit");
35443604
showLog = PB("log");
35453605
--- src/diff.c
+++ src/diff.c
@@ -2589,11 +2589,11 @@
2589 p->aEdit[p->nEdit++] = nDel;
2590 p->aEdit[p->nEdit++] = nIns;
2591 }
2592
2593 /*
2594 ** A common subsequene between p->aFrom and p->aTo has been found.
2595 ** This routine tries to judge if the subsequence really is a valid
2596 ** match or rather is just an artifact of an indentation change.
2597 **
2598 ** Return non-zero if the subsequence is valid. Return zero if the
2599 ** subsequence seems likely to be an editing artifact and should be
@@ -2618,33 +2618,92 @@
2618 ** ALGORITHM (subject to change and refinement):
2619 **
2620 ** 1. If the subsequence is larger than 1/7th of the original span,
2621 ** then consider it valid. --> return 1
2622 **
2623 ** 2. If the subsequence contains any charaters other than '}', '{",
2624 ** or whitespace, then consider it valid. --> return 1
 
 
 
 
2625 **
2626 ** 3. Otherwise, it is potentially an artifact of an indentation
2627 ** change. --> return 0
2628 */
2629 static int likelyNotIndentChngArtifact(
2630 DContext *p, /* The complete diff context */
2631 int iS1, /* Start of the main segment */
2632 int iSX, /* Start of the subsequence */
2633 int iEX, /* First row past the end of the subsequence */
2634 int iE1 /* First row past the end of the main segment */
2635 ){
2636 int i, j;
 
 
2637 if( (iEX-iSX)*7 >= (iE1-iS1) ) return 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2638 for(i=iSX; i<iEX; i++){
2639 const char *z = p->aFrom[i].z;
2640 for(j=p->aFrom[i].n-1; j>=0; j--){
2641 char c = z[j];
2642 if( c!='}' && c!='{' && !diff_isspace(c) ) return 1;
 
 
 
 
 
 
 
2643 }
 
2644 }
2645 return 0;
2646 }
2647
2648
2649 /*
2650 ** Do a single step in the difference. Compute a sequence of
@@ -3355,11 +3414,12 @@
3355 if( strcmp(zLimit,"none")==0 ){
3356 iLimit = 0;
3357 mxTime = 0;
3358 }else if( sqlite3_strglob("*[0-9]s", zLimit)==0 ){
3359 iLimit = 0;
3360 mxTime = current_time_in_milliseconds() + 1000.0*atof(zLimit);
 
3361 }else{
3362 iLimit = atoi(zLimit);
3363 if( iLimit<=0 ) iLimit = 30;
3364 mxTime = 0;
3365 }
@@ -3534,11 +3594,11 @@
3534
3535 /* Gather query parameters */
3536 login_check_credentials();
3537 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
3538 if( exclude_spiders() ) return;
3539 load_control();
3540 zFilename = P("filename");
3541 zRevision = PD("checkin",0);
3542 zOrigin = P("origin");
3543 zLimit = P("limit");
3544 showLog = PB("log");
3545
--- src/diff.c
+++ src/diff.c
@@ -2589,11 +2589,11 @@
2589 p->aEdit[p->nEdit++] = nDel;
2590 p->aEdit[p->nEdit++] = nIns;
2591 }
2592
2593 /*
2594 ** A common subsequence between p->aFrom and p->aTo has been found.
2595 ** This routine tries to judge if the subsequence really is a valid
2596 ** match or rather is just an artifact of an indentation change.
2597 **
2598 ** Return non-zero if the subsequence is valid. Return zero if the
2599 ** subsequence seems likely to be an editing artifact and should be
@@ -2618,33 +2618,92 @@
2618 ** ALGORITHM (subject to change and refinement):
2619 **
2620 ** 1. If the subsequence is larger than 1/7th of the original span,
2621 ** then consider it valid. --> return 1
2622 **
2623 ** 2. If no lines of the subsequence contains more than one
2624 ** non-whitespace character, --> return 0
2625 **
2626 ** 3. If any line of the subsequence contains more than one non-whitespace
2627 ** character and is unique across the entire sequence after ignoring
2628 ** leading and trailing whitespace --> return 1
2629 **
2630 ** 4. Otherwise, it is potentially an artifact of an indentation
2631 ** change. --> return 0
2632 */
2633 static int likelyNotIndentChngArtifact(
2634 DContext *p, /* The complete diff context */
2635 int iS1, /* Start of the main segment */
2636 int iSX, /* Start of the subsequence */
2637 int iEX, /* First row past the end of the subsequence */
2638 int iE1 /* First row past the end of the main segment */
2639 ){
2640 int i, j, n;
2641
2642 /* Rule (1) */
2643 if( (iEX-iSX)*7 >= (iE1-iS1) ) return 1;
2644
2645 /* Compute DLine.indent and DLine.nw for all lines of the subsequence.
2646 ** If no lines contain more than one non-whitespace character return
2647 ** 0 because the subsequence could be due to an indentation change.
2648 ** Rule (2).
2649 */
2650 n = 0;
2651 for(i=iSX; i<iEX; i++){
2652 DLine *pA = &p->aFrom[i];
2653 if( pA->nw==0 && pA->n ){
2654 const char *zA = pA->z;
2655 const int nn = pA->n;
2656 int ii, jj;
2657 for(ii=0; ii<nn && diff_isspace(zA[ii]); ii++){}
2658 pA->indent = ii;
2659 for(jj=nn-1; jj>ii && diff_isspace(zA[jj]); jj--){}
2660 pA->nw = jj - ii + 1;
2661 }
2662 if( pA->nw>1 ) n++;
2663 }
2664 if( n==0 ) return 0;
2665
2666 /* Compute DLine.indent and DLine.nw for the entire sequence */
2667 for(i=iS1; i<iE1; i++){
2668 DLine *pA;
2669 if( i==iSX ){
2670 i = iEX;
2671 if( i>=iE1 ) break;
2672 }
2673 pA = &p->aFrom[i];
2674 if( pA->nw==0 && pA->n ){
2675 const char *zA = pA->z;
2676 const int nn = pA->n;
2677 int ii, jj;
2678 for(ii=0; ii<nn && diff_isspace(zA[ii]); ii++){}
2679 pA->indent = ii;
2680 for(jj=nn-1; jj>ii && diff_isspace(zA[jj]); jj--){}
2681 pA->nw = jj - ii + 1;
2682 }
2683 }
2684
2685 /* Check to see if any subsequence line that has more than one
2686 ** non-whitespace character is unique across the entire sequence.
2687 ** Rule (3)
2688 */
2689 for(i=iSX; i<iEX; i++){
2690 const char *z = p->aFrom[i].z + p->aFrom[i].indent;
2691 const int nw = p->aFrom[i].nw;
2692 if( nw<=1 ) continue;
2693 for(j=iS1; j<iSX; j++){
2694 if( p->aFrom[j].nw!=nw ) continue;
2695 if( memcmp(p->aFrom[j].z+p->aFrom[j].indent,z,nw)==0 ) break;
2696 }
2697 if( j<iSX ) continue;
2698 for(j=iEX; j<iE1; j++){
2699 if( p->aFrom[j].nw!=nw ) continue;
2700 if( memcmp(p->aFrom[j].z+p->aFrom[j].indent,z,nw)==0 ) break;
2701 }
2702 if( j>=iE1 ) break;
2703 }
2704 return i<iEX;
2705 }
2706
2707
2708 /*
2709 ** Do a single step in the difference. Compute a sequence of
@@ -3355,11 +3414,12 @@
3414 if( strcmp(zLimit,"none")==0 ){
3415 iLimit = 0;
3416 mxTime = 0;
3417 }else if( sqlite3_strglob("*[0-9]s", zLimit)==0 ){
3418 iLimit = 0;
3419 mxTime =
3420 (sqlite3_int64)(current_time_in_milliseconds() + 1000.0*atof(zLimit));
3421 }else{
3422 iLimit = atoi(zLimit);
3423 if( iLimit<=0 ) iLimit = 30;
3424 mxTime = 0;
3425 }
@@ -3534,11 +3594,11 @@
3594
3595 /* Gather query parameters */
3596 login_check_credentials();
3597 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
3598 if( exclude_spiders() ) return;
3599 fossil_nice_default();
3600 zFilename = P("filename");
3601 zRevision = PD("checkin",0);
3602 zOrigin = P("origin");
3603 zLimit = P("limit");
3604 showLog = PB("log");
3605
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1182,9 +1182,10 @@
11821182
DiffConfig DCfg;
11831183
login_check_credentials();
11841184
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
11851185
if( zFrom==0 || zTo==0 ) fossil_redirect_home();
11861186
1187
+ fossil_nice_default();
11871188
cgi_set_content_type("text/plain");
11881189
diff_config_init(&DCfg, DIFF_VERBOSE);
11891190
diff_two_versions(zFrom, zTo, &DCfg, 0);
11901191
}
11911192
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1182,9 +1182,10 @@
1182 DiffConfig DCfg;
1183 login_check_credentials();
1184 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1185 if( zFrom==0 || zTo==0 ) fossil_redirect_home();
1186
 
1187 cgi_set_content_type("text/plain");
1188 diff_config_init(&DCfg, DIFF_VERBOSE);
1189 diff_two_versions(zFrom, zTo, &DCfg, 0);
1190 }
1191
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1182,9 +1182,10 @@
1182 DiffConfig DCfg;
1183 login_check_credentials();
1184 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1185 if( zFrom==0 || zTo==0 ) fossil_redirect_home();
1186
1187 fossil_nice_default();
1188 cgi_set_content_type("text/plain");
1189 diff_config_init(&DCfg, DIFF_VERBOSE);
1190 diff_two_versions(zFrom, zTo, &DCfg, 0);
1191 }
1192
+26 -15
--- src/dispatch.c
+++ src/dispatch.c
@@ -38,22 +38,23 @@
3838
3939
/***************************************************************************
4040
** These macros must match similar macros in mkindex.c
4141
** Allowed values for CmdOrPage.eCmdFlags.
4242
*/
43
-#define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
44
-#define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
45
-#define CMDFLAG_TEST 0x0004 /* Commands for testing only */
46
-#define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
47
-#define CMDFLAG_COMMAND 0x0010 /* A command */
48
-#define CMDFLAG_SETTING 0x0020 /* A setting */
49
-#define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
50
-#define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
51
-#define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
52
-#define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret POST content */
53
-/* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
54
-#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
43
+#define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
44
+#define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
45
+#define CMDFLAG_TEST 0x0004 /* Commands for testing only */
46
+#define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
47
+#define CMDFLAG_COMMAND 0x0010 /* A command */
48
+#define CMDFLAG_SETTING 0x0020 /* A setting */
49
+#define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
50
+#define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
51
+#define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
52
+#define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret POST content */
53
+/* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
54
+#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
55
+#define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
5556
/**************************************************************************/
5657
5758
/* Values for the 2nd parameter to dispatch_name_search() */
5859
#define CMDFLAG_ANY 0x0038 /* Match anything */
5960
#define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
@@ -125,11 +126,13 @@
125126
&& strncmp(zName, aCommand[lwr].zName, nName)==0; ++lwr ){
126127
if( aCommand[lwr].eCmdFlags & eType ){
127128
if( mid<0 ){
128129
mid = lwr; /* Potential ambiguous prefix */
129130
}else{
130
- return 2; /* Confirmed ambiguous prefix */
131
+ if( aCommand[lwr].xFunc != aCommand[mid].xFunc ){
132
+ return 2; /* Confirmed ambiguous prefix */
133
+ }
131134
}
132135
}
133136
}
134137
if( mid>=0 ){
135138
*ppCmd = &aCommand[mid];
@@ -207,16 +210,21 @@
207210
return 0;
208211
}
209212
210213
/*
211214
** Fill Blob with a space-separated list of all command names that
212
-** match the prefix zPrefix.
215
+** match the prefix zPrefix and the eType CMDFLAGS_ bits.
213216
*/
214
-void dispatch_matching_names(const char *zPrefix, Blob *pList){
217
+void dispatch_matching_names(
218
+ const char *zPrefix, /* name prefix */
219
+ unsigned eType, /* CMDFLAG_ bits */
220
+ Blob *pList /* space-separated list of command names */
221
+){
215222
int i;
216223
int nPrefix = (int)strlen(zPrefix);
217224
for(i=FOSSIL_FIRST_CMD; i<MX_COMMAND; i++){
225
+ if( (aCommand[i].eCmdFlags & eType)==0 ) continue;
218226
if( strncmp(zPrefix, aCommand[i].zName, nPrefix)==0 ){
219227
blob_appendf(pList, " %s", aCommand[i].zName);
220228
}
221229
}
222230
}
@@ -1008,17 +1016,20 @@
10081016
/* @-comment: # */
10091017
static const char zOptions[] =
10101018
@ Command-line options common to all commands:
10111019
@
10121020
@ --args FILENAME Read additional arguments and options from FILENAME
1021
+@ --case-sensitive BOOL Set case sensitivity for file names
10131022
@ --cgitrace Active CGI tracing
1023
+@ --chdir PATH Change to PATH before performing any operations
10141024
@ --comfmtflags VALUE Set comment formatting flags to VALUE
10151025
@ --comment-format VALUE Alias for --comfmtflags
10161026
@ --errorlog FILENAME Log errors to FILENAME
10171027
@ --help Show help on the command rather than running it
10181028
@ --httptrace Trace outbound HTTP requests
10191029
@ --localtime Display times using the local timezone
1030
+@ --nocgi Do not act as CGI
10201031
@ --no-th-hook Do not run TH1 hooks
10211032
@ --quiet Reduce the amount of output
10221033
@ --sqlstats Show SQL usage statistics when done
10231034
@ --sqltrace Trace all SQL commands
10241035
@ --sshtrace Trace SSH activity
10251036
--- src/dispatch.c
+++ src/dispatch.c
@@ -38,22 +38,23 @@
38
39 /***************************************************************************
40 ** These macros must match similar macros in mkindex.c
41 ** Allowed values for CmdOrPage.eCmdFlags.
42 */
43 #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
44 #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
45 #define CMDFLAG_TEST 0x0004 /* Commands for testing only */
46 #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
47 #define CMDFLAG_COMMAND 0x0010 /* A command */
48 #define CMDFLAG_SETTING 0x0020 /* A setting */
49 #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
50 #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
51 #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
52 #define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret POST content */
53 /* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
54 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
 
55 /**************************************************************************/
56
57 /* Values for the 2nd parameter to dispatch_name_search() */
58 #define CMDFLAG_ANY 0x0038 /* Match anything */
59 #define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
@@ -125,11 +126,13 @@
125 && strncmp(zName, aCommand[lwr].zName, nName)==0; ++lwr ){
126 if( aCommand[lwr].eCmdFlags & eType ){
127 if( mid<0 ){
128 mid = lwr; /* Potential ambiguous prefix */
129 }else{
130 return 2; /* Confirmed ambiguous prefix */
 
 
131 }
132 }
133 }
134 if( mid>=0 ){
135 *ppCmd = &aCommand[mid];
@@ -207,16 +210,21 @@
207 return 0;
208 }
209
210 /*
211 ** Fill Blob with a space-separated list of all command names that
212 ** match the prefix zPrefix.
213 */
214 void dispatch_matching_names(const char *zPrefix, Blob *pList){
 
 
 
 
215 int i;
216 int nPrefix = (int)strlen(zPrefix);
217 for(i=FOSSIL_FIRST_CMD; i<MX_COMMAND; i++){
 
218 if( strncmp(zPrefix, aCommand[i].zName, nPrefix)==0 ){
219 blob_appendf(pList, " %s", aCommand[i].zName);
220 }
221 }
222 }
@@ -1008,17 +1016,20 @@
1008 /* @-comment: # */
1009 static const char zOptions[] =
1010 @ Command-line options common to all commands:
1011 @
1012 @ --args FILENAME Read additional arguments and options from FILENAME
 
1013 @ --cgitrace Active CGI tracing
 
1014 @ --comfmtflags VALUE Set comment formatting flags to VALUE
1015 @ --comment-format VALUE Alias for --comfmtflags
1016 @ --errorlog FILENAME Log errors to FILENAME
1017 @ --help Show help on the command rather than running it
1018 @ --httptrace Trace outbound HTTP requests
1019 @ --localtime Display times using the local timezone
 
1020 @ --no-th-hook Do not run TH1 hooks
1021 @ --quiet Reduce the amount of output
1022 @ --sqlstats Show SQL usage statistics when done
1023 @ --sqltrace Trace all SQL commands
1024 @ --sshtrace Trace SSH activity
1025
--- src/dispatch.c
+++ src/dispatch.c
@@ -38,22 +38,23 @@
38
39 /***************************************************************************
40 ** These macros must match similar macros in mkindex.c
41 ** Allowed values for CmdOrPage.eCmdFlags.
42 */
43 #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
44 #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
45 #define CMDFLAG_TEST 0x0004 /* Commands for testing only */
46 #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
47 #define CMDFLAG_COMMAND 0x0010 /* A command */
48 #define CMDFLAG_SETTING 0x0020 /* A setting */
49 #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
50 #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
51 #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
52 #define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret POST content */
53 /* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
54 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
55 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
56 /**************************************************************************/
57
58 /* Values for the 2nd parameter to dispatch_name_search() */
59 #define CMDFLAG_ANY 0x0038 /* Match anything */
60 #define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
@@ -125,11 +126,13 @@
126 && strncmp(zName, aCommand[lwr].zName, nName)==0; ++lwr ){
127 if( aCommand[lwr].eCmdFlags & eType ){
128 if( mid<0 ){
129 mid = lwr; /* Potential ambiguous prefix */
130 }else{
131 if( aCommand[lwr].xFunc != aCommand[mid].xFunc ){
132 return 2; /* Confirmed ambiguous prefix */
133 }
134 }
135 }
136 }
137 if( mid>=0 ){
138 *ppCmd = &aCommand[mid];
@@ -207,16 +210,21 @@
210 return 0;
211 }
212
213 /*
214 ** Fill Blob with a space-separated list of all command names that
215 ** match the prefix zPrefix and the eType CMDFLAGS_ bits.
216 */
217 void dispatch_matching_names(
218 const char *zPrefix, /* name prefix */
219 unsigned eType, /* CMDFLAG_ bits */
220 Blob *pList /* space-separated list of command names */
221 ){
222 int i;
223 int nPrefix = (int)strlen(zPrefix);
224 for(i=FOSSIL_FIRST_CMD; i<MX_COMMAND; i++){
225 if( (aCommand[i].eCmdFlags & eType)==0 ) continue;
226 if( strncmp(zPrefix, aCommand[i].zName, nPrefix)==0 ){
227 blob_appendf(pList, " %s", aCommand[i].zName);
228 }
229 }
230 }
@@ -1008,17 +1016,20 @@
1016 /* @-comment: # */
1017 static const char zOptions[] =
1018 @ Command-line options common to all commands:
1019 @
1020 @ --args FILENAME Read additional arguments and options from FILENAME
1021 @ --case-sensitive BOOL Set case sensitivity for file names
1022 @ --cgitrace Active CGI tracing
1023 @ --chdir PATH Change to PATH before performing any operations
1024 @ --comfmtflags VALUE Set comment formatting flags to VALUE
1025 @ --comment-format VALUE Alias for --comfmtflags
1026 @ --errorlog FILENAME Log errors to FILENAME
1027 @ --help Show help on the command rather than running it
1028 @ --httptrace Trace outbound HTTP requests
1029 @ --localtime Display times using the local timezone
1030 @ --nocgi Do not act as CGI
1031 @ --no-th-hook Do not run TH1 hooks
1032 @ --quiet Reduce the amount of output
1033 @ --sqlstats Show SQL usage statistics when done
1034 @ --sqltrace Trace all SQL commands
1035 @ --sshtrace Trace SSH activity
1036
-3
--- src/file.c
+++ src/file.c
@@ -1295,13 +1295,10 @@
12951295
/*
12961296
** The input is the name of an executable, such as one might
12971297
** type on a command-line. This routine resolves that name into
12981298
** a full pathname. The result is obtained from fossil_malloc()
12991299
** and should be freed by the caller.
1300
-**
1301
-** This routine only works on unix. On Windows, simply return
1302
-** a copy of the input.
13031300
*/
13041301
char *file_fullexename(const char *zCmd){
13051302
#ifdef _WIN32
13061303
char *zPath;
13071304
char *z = 0;
13081305
--- src/file.c
+++ src/file.c
@@ -1295,13 +1295,10 @@
1295 /*
1296 ** The input is the name of an executable, such as one might
1297 ** type on a command-line. This routine resolves that name into
1298 ** a full pathname. The result is obtained from fossil_malloc()
1299 ** and should be freed by the caller.
1300 **
1301 ** This routine only works on unix. On Windows, simply return
1302 ** a copy of the input.
1303 */
1304 char *file_fullexename(const char *zCmd){
1305 #ifdef _WIN32
1306 char *zPath;
1307 char *z = 0;
1308
--- src/file.c
+++ src/file.c
@@ -1295,13 +1295,10 @@
1295 /*
1296 ** The input is the name of an executable, such as one might
1297 ** type on a command-line. This routine resolves that name into
1298 ** a full pathname. The result is obtained from fossil_malloc()
1299 ** and should be freed by the caller.
 
 
 
1300 */
1301 char *file_fullexename(const char *zCmd){
1302 #ifdef _WIN32
1303 char *zPath;
1304 char *z = 0;
1305
+7 -2
--- src/fusefs.c
+++ src/fusefs.c
@@ -20,14 +20,14 @@
2020
**
2121
** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS.
2222
** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for
2323
** the Fuse Filesystem, of course.
2424
*/
25
-#ifdef FOSSIL_HAVE_FUSEFS
2625
#include "config.h"
2726
#include <stdio.h>
2827
#include <string.h>
28
+#ifdef FOSSIL_HAVE_FUSEFS
2929
#include <errno.h>
3030
#include <fcntl.h>
3131
#include <stdlib.h>
3232
#include <unistd.h>
3333
#include <sys/types.h>
@@ -283,10 +283,11 @@
283283
static struct fuse_operations fusefs_methods = {
284284
.getattr = fusefs_getattr,
285285
.readdir = fusefs_readdir,
286286
.read = fusefs_read,
287287
};
288
+#endif /* FOSSIL_HAVE_FUSEFS */
288289
289290
/*
290291
** COMMAND: fusefs*
291292
**
292293
** Usage: %fossil fusefs [--debug] DIRECTORY
@@ -314,10 +315,11 @@
314315
** After stopping the "fossil fusefs" command, it might also be necessary
315316
** to run "fusermount -u DIRECTORY" to reset the FuseFS before using it
316317
** again.
317318
*/
318319
void fusefs_cmd(void){
320
+#ifdef FOSSIL_HAVE_FUSEFS
319321
char *zMountPoint;
320322
char *azNewArgv[5];
321323
int doDebug = find_option("debug","d",0)!=0;
322324
323325
db_find_and_open_repository(0,0);
@@ -335,12 +337,15 @@
335337
azNewArgv[4] = 0;
336338
g.localOpen = 0; /* Prevent tags like "current" and "prev" */
337339
fuse_main(4, azNewArgv, &fusefs_methods, NULL);
338340
fusefs_reset();
339341
fusefs_clear_path();
340
-}
342
+#else
343
+ fprintf(stderr, "The FuseFS is not available in this build.\n");
344
+ exit(1);
341345
#endif /* FOSSIL_HAVE_FUSEFS */
346
+}
342347
343348
/*
344349
** Return version numbers for the FUSE header that was used at compile-time
345350
** and/or the FUSE library that was loaded at runtime.
346351
*/
347352
--- src/fusefs.c
+++ src/fusefs.c
@@ -20,14 +20,14 @@
20 **
21 ** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS.
22 ** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for
23 ** the Fuse Filesystem, of course.
24 */
25 #ifdef FOSSIL_HAVE_FUSEFS
26 #include "config.h"
27 #include <stdio.h>
28 #include <string.h>
 
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <sys/types.h>
@@ -283,10 +283,11 @@
283 static struct fuse_operations fusefs_methods = {
284 .getattr = fusefs_getattr,
285 .readdir = fusefs_readdir,
286 .read = fusefs_read,
287 };
 
288
289 /*
290 ** COMMAND: fusefs*
291 **
292 ** Usage: %fossil fusefs [--debug] DIRECTORY
@@ -314,10 +315,11 @@
314 ** After stopping the "fossil fusefs" command, it might also be necessary
315 ** to run "fusermount -u DIRECTORY" to reset the FuseFS before using it
316 ** again.
317 */
318 void fusefs_cmd(void){
 
319 char *zMountPoint;
320 char *azNewArgv[5];
321 int doDebug = find_option("debug","d",0)!=0;
322
323 db_find_and_open_repository(0,0);
@@ -335,12 +337,15 @@
335 azNewArgv[4] = 0;
336 g.localOpen = 0; /* Prevent tags like "current" and "prev" */
337 fuse_main(4, azNewArgv, &fusefs_methods, NULL);
338 fusefs_reset();
339 fusefs_clear_path();
340 }
 
 
341 #endif /* FOSSIL_HAVE_FUSEFS */
 
342
343 /*
344 ** Return version numbers for the FUSE header that was used at compile-time
345 ** and/or the FUSE library that was loaded at runtime.
346 */
347
--- src/fusefs.c
+++ src/fusefs.c
@@ -20,14 +20,14 @@
20 **
21 ** This module is a mostly a no-op unless compiled with -DFOSSIL_HAVE_FUSEFS.
22 ** The FOSSIL_HAVE_FUSEFS should be omitted on systems that lack support for
23 ** the Fuse Filesystem, of course.
24 */
 
25 #include "config.h"
26 #include <stdio.h>
27 #include <string.h>
28 #ifdef FOSSIL_HAVE_FUSEFS
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <sys/types.h>
@@ -283,10 +283,11 @@
283 static struct fuse_operations fusefs_methods = {
284 .getattr = fusefs_getattr,
285 .readdir = fusefs_readdir,
286 .read = fusefs_read,
287 };
288 #endif /* FOSSIL_HAVE_FUSEFS */
289
290 /*
291 ** COMMAND: fusefs*
292 **
293 ** Usage: %fossil fusefs [--debug] DIRECTORY
@@ -314,10 +315,11 @@
315 ** After stopping the "fossil fusefs" command, it might also be necessary
316 ** to run "fusermount -u DIRECTORY" to reset the FuseFS before using it
317 ** again.
318 */
319 void fusefs_cmd(void){
320 #ifdef FOSSIL_HAVE_FUSEFS
321 char *zMountPoint;
322 char *azNewArgv[5];
323 int doDebug = find_option("debug","d",0)!=0;
324
325 db_find_and_open_repository(0,0);
@@ -335,12 +337,15 @@
337 azNewArgv[4] = 0;
338 g.localOpen = 0; /* Prevent tags like "current" and "prev" */
339 fuse_main(4, azNewArgv, &fusefs_methods, NULL);
340 fusefs_reset();
341 fusefs_clear_path();
342 #else
343 fprintf(stderr, "The FuseFS is not available in this build.\n");
344 exit(1);
345 #endif /* FOSSIL_HAVE_FUSEFS */
346 }
347
348 /*
349 ** Return version numbers for the FUSE header that was used at compile-time
350 ** and/or the FUSE library that was loaded at runtime.
351 */
352
+200 -27
--- src/graph.c
+++ src/graph.c
@@ -82,11 +82,12 @@
8282
int idx; /* Row index. Top row is smallest. */
8383
int idxTop; /* Direct descendent highest up on the graph */
8484
GraphRow *pChild; /* Child immediately above this node */
8585
u8 isDup; /* True if this is duplicate of a prior entry */
8686
u8 isLeaf; /* True if this is a leaf node */
87
- u8 isStepParent; /* pChild is actually a step-child */
87
+ u8 isStepParent; /* pChild is actually a step-child. The thick
88
+ ** arrow up to the child is dashed, not solid */
8889
u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
8990
u8 timeWarp; /* Child is earlier in time */
9091
u8 bDescender; /* True if riser from bottom of graph to here. */
9192
u8 selfUp; /* Space above this node but belonging */
9293
i8 iRail; /* Which rail this check-in appears on. 0-based.*/
@@ -109,10 +110,13 @@
109110
GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
110111
int nBranch; /* Number of distinct branches */
111112
char **azBranch; /* Names of the branches */
112113
int nRow; /* Number of rows */
113114
int nHash; /* Number of slots in apHash[] */
115
+ u8 hasOffsetMergeRiser; /* Merge arrow from leaf goes up on a different
116
+ ** rail that the node */
117
+ u64 mergeRail; /* Rails used for merge lines */
114118
GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
115119
u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */
116120
};
117121
118122
#endif
@@ -119,11 +123,11 @@
119123
120124
/* The N-th bit */
121125
#define BIT(N) (((u64)1)<<(N))
122126
123127
/*
124
-** Number of rows before and answer a node with a riser or descender
128
+** Number of rows before and after a node with a riser or descender
125129
** that goes off-screen before we can reuse that rail.
126130
*/
127131
#define RISER_MARGIN 4
128132
129133
@@ -275,11 +279,12 @@
275279
** top and bottom, inclusive.
276280
*/
277281
static int findFreeRail(
278282
GraphContext *p, /* The graph context */
279283
int top, int btm, /* Span of rows for which the rail is needed */
280
- int iNearto /* Find rail nearest to this rail */
284
+ int iNearto, /* Find rail nearest to this rail */
285
+ int bMergeRail /* This rail will be used for a merge line */
281286
){
282287
GraphRow *pRow;
283288
int i;
284289
int iBest = 0;
285290
int iBestDist = 9999;
@@ -287,15 +292,38 @@
287292
for(pRow=p->pFirst; pRow && pRow->idx<top; pRow=pRow->pNext){}
288293
while( pRow && pRow->idx<=btm ){
289294
inUseMask |= pRow->railInUse;
290295
pRow = pRow->pNext;
291296
}
292
- for(i=0; i<GR_MAX_RAIL; i++){
293
- if( (inUseMask & BIT(i))==0 ){
297
+
298
+ /* First look for a match that honors bMergeRail */
299
+ for(i=0; i<=p->mxRail; i++){
300
+ u64 m = BIT(i);
301
+ int dist;
302
+ if( inUseMask & m ) continue;
303
+ if( (bMergeRail!=0) != ((p->mergeRail & m)!=0) ) continue;
304
+ if( iNearto<=0 ){
305
+ iBest = i;
306
+ iBestDist = 1;
307
+ break;
308
+ }
309
+ dist = i - iNearto;
310
+ if( dist<0 ) dist = -dist;
311
+ if( dist<iBestDist ){
312
+ iBestDist = dist;
313
+ iBest = i;
314
+ }
315
+ }
316
+
317
+ /* If no match, consider all possible rails */
318
+ if( iBestDist>1000 ){
319
+ for(i=0; i<=p->mxRail+1; i++){
294320
int dist;
321
+ if( inUseMask & BIT(i) ) continue;
295322
if( iNearto<=0 ){
296323
iBest = i;
324
+ iBestDist = 1;
297325
break;
298326
}
299327
dist = i - iNearto;
300328
if( dist<0 ) dist = -dist;
301329
if( dist<iBestDist ){
@@ -304,10 +332,11 @@
304332
}
305333
}
306334
}
307335
if( iBestDist>1000 ) p->nErr++;
308336
if( iBest>p->mxRail ) p->mxRail = iBest;
337
+ if( bMergeRail ) p->mergeRail |= BIT(iBest);
309338
return iBest;
310339
}
311340
312341
/*
313342
** Assign all children of node pBottom to the same rail as pBottom.
@@ -343,26 +372,48 @@
343372
p->railInUse |= mask;
344373
}
345374
}
346375
}
347376
377
+
378
+/*
379
+** Check to see if rail iRail is clear from pBottom up to and including
380
+** pTop.
381
+*/
382
+static int railIsClear(GraphRow *pBottom, int iTop, int iRail){
383
+ u64 m = BIT(iRail);
384
+ while( pBottom && pBottom->idx>=iTop ){
385
+ if( pBottom->railInUse & m ) return 0;
386
+ pBottom = pBottom->pPrev;
387
+ }
388
+ return 1;
389
+}
390
+
348391
/*
349392
** Create a merge-arrow riser going from pParent up to pChild.
350393
*/
351394
static void createMergeRiser(
352395
GraphContext *p,
353
- GraphRow *pParent,
354
- GraphRow *pChild,
355
- int isCherrypick
396
+ GraphRow *pParent, /* Lower node from which the merge line begins */
397
+ GraphRow *pChild, /* Upper node at which the merge line ends */
398
+ int isCherrypick /* True for a cherry-pick merge */
356399
){
357400
int u;
358401
u64 mask;
359402
GraphRow *pLoop;
360403
361404
if( pParent->mergeOut<0 ){
362405
u = pParent->aiRiser[pParent->iRail];
363
- if( u>0 && u<pChild->idx ){
406
+ if( u<0 && railIsClear(pParent->pPrev, pChild->idx, pParent->iRail) ){
407
+ /* pParent is a leaf and the merge-line can be drawn straight up.*/
408
+ pParent->mergeOut = pParent->iRail;
409
+ mask = BIT(pParent->iRail);
410
+ for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
411
+ pLoop=pLoop->pNext){
412
+ pLoop->railInUse |= mask;
413
+ }
414
+ }else if( u>0 && u<pChild->idx ){
364415
/* The thick arrow up to the next primary child of pDesc goes
365416
** further up than the thin merge arrow riser, so draw them both
366417
** on the same rail. */
367418
pParent->mergeOut = pParent->iRail;
368419
}else if( pParent->idx - pChild->idx < pParent->selfUp ){
@@ -369,11 +420,13 @@
369420
pParent->mergeOut = pParent->iRail;
370421
}else{
371422
/* The thin merge arrow riser is taller than the thick primary
372423
** child riser, so use separate rails. */
373424
int iTarget = pParent->iRail;
374
- pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1, iTarget);
425
+ if( u<0 ) p->hasOffsetMergeRiser = 1;
426
+ pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1,
427
+ iTarget, 1);
375428
mask = BIT(pParent->mergeOut);
376429
for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
377430
pLoop=pLoop->pNext){
378431
pLoop->railInUse |= mask;
379432
}
@@ -420,11 +473,10 @@
420473
while( pRow && (n--)>0 ){
421474
pRow->railInUse |= mask;
422475
pRow = pRow->pPrev;
423476
}
424477
}
425
-
426478
427479
/*
428480
** Compute the complete graph
429481
**
430482
** When primary or merge parents are off-screen, normally a line is drawn
@@ -646,11 +698,11 @@
646698
if( i==0 && pRow->zBranch!=zTrunk ) continue;
647699
if( pRow->iRail>=0 ) continue;
648700
if( pRow->isDup ) continue;
649701
if( pRow->nParent<0 ) continue;
650702
if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){
651
- pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin, 0);
703
+ pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin,0,0);
652704
if( p->mxRail>=GR_MAX_RAIL ) return;
653705
mask = BIT(pRow->iRail);
654706
if( !omitDescenders ){
655707
int n = RISER_MARGIN;
656708
pRow->bDescender = pRow->nParent>0;
@@ -690,11 +742,11 @@
690742
}
691743
if( pParent->idx>pRow->idx ){
692744
/* Common case: Child occurs after parent and is above the
693745
** parent in the timeline */
694746
pRow->iRail = findFreeRail(p, pRow->idxTop, pParent->idx,
695
- pParent->iRail);
747
+ pParent->iRail, 0);
696748
if( p->mxRail>=GR_MAX_RAIL ) return;
697749
pParent->aiRiser[pRow->iRail] = pRow->idx;
698750
}else{
699751
/* Timewarp case: Child occurs earlier in time than parent and
700752
** appears below the parent in the timeline. */
@@ -741,11 +793,11 @@
741793
int isCherrypick = 0;
742794
for(i=1; i<pRow->nParent; i++){
743795
GraphRowId parentRid = pRow->aParent[i];
744796
if( i==pRow->nNonCherrypick ){
745797
/* Because full merges are laid out before cherrypicks,
746
- ** it is ok to use a full-merge raise for a cherrypick.
798
+ ** it is ok to use a full-merge raiser for a cherrypick.
747799
** See the graph on check-in 8ac66ef33b464d28 for example
748800
** iReuseIdx = -1;
749801
** iReuseRail = -1; */
750802
isCherrypick = 1;
751803
}
@@ -761,11 +813,11 @@
761813
iMrail = j;
762814
break;
763815
}
764816
}
765817
if( iMrail==-1 ){
766
- iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0);
818
+ iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1);
767819
if( p->mxRail>=GR_MAX_RAIL ) return;
768820
mergeRiserFrom[iMrail] = parentRid;
769821
}
770822
iReuseIdx = p->nRow+1;
771823
iReuseRail = iMrail;
@@ -838,29 +890,150 @@
838890
839891
/*
840892
** Find the maximum rail number.
841893
*/
842894
find_max_rail(p);
895
+
896
+ /* If a leaf node has a merge riser going up on a different rail,
897
+ ** try to move the rail of the node (and its ancestors) to be underneath
898
+ ** the merge riser. This is an optimization that improves the
899
+ ** appearance of graph but is not strictly necessary.
900
+ */
901
+ if( nTimewarp==0 && p->hasOffsetMergeRiser ){
902
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
903
+ GraphRow *pBottom; /* Bottom row of a branch */
904
+ GraphRow *pRoot; /* Node off of which the branch diverges */
905
+ int iFrom; /* Proposed to move from this rail */
906
+ int iTo; /* Move the branch to this rail */
907
+
908
+ iFrom = pRow->iRail;
909
+ if( pRow->aiRiser[iFrom]>=0 ) continue; /* Not a leaf */
910
+ if( pRow->mergeOut<0 ) continue; /* No merge riser */
911
+ if( pRow->mergeOut==iFrom ) continue; /* Riser already aligned */
912
+ iTo = pRow->mergeOut;
913
+
914
+ /* Find the bottom (oldest) node in the branch */
915
+ pBottom = 0;
916
+ for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
917
+ if( pLoop->idxTop==pRow->idx ) pBottom = pLoop;
918
+ }
919
+ if( pBottom==0 ) continue; /* Not possible */
920
+
921
+ /* Verify that the rail we want to shift into is clear */
922
+ pLoop = pBottom;
923
+ if( pLoop->pNext ) pLoop = pLoop->pNext;
924
+ if( !railIsClear(pLoop, pRow->idx+1, iTo) ){
925
+ /* Other nodes or risers are already using the space that
926
+ ** we propose to move the pRow branch into. */
927
+ continue;
928
+ }
929
+
930
+ /* Find the "root" of the branch. The root is a different branch
931
+ ** from which the pRow branch emerges. There might not be a root
932
+ ** if the pRow branch started off the bottom of the screen.
933
+ */
934
+ for(pRoot=pBottom->pNext; pRoot; pRoot=pRoot->pNext){
935
+ if( pRoot->aiRiser[iFrom]>=0 ) break;
936
+ }
937
+ if( pRoot && pRoot->iRail==iTo ){
938
+ /* The parent branch from which this branch emerges is on the
939
+ ** same rail as pRow. Do not shift as that would stack a child
940
+ ** branch directly above its parent. */
941
+ continue;
942
+ }
943
+
944
+ /* All clear. Make the translation
945
+ */
946
+ for(pLoop=pRow; pLoop && pLoop->idx<=pBottom->idx; pLoop=pLoop->pNext){
947
+ if( pLoop->iRail==iFrom ){
948
+ pLoop->iRail = iTo;
949
+ pLoop->aiRiser[iTo] = pLoop->aiRiser[iFrom];
950
+ pLoop->aiRiser[iFrom] = -1;
951
+ }
952
+ }
953
+ if( pRoot ){
954
+ pRoot->aiRiser[iTo] = pRoot->aiRiser[iFrom];
955
+ pRoot->aiRiser[iFrom] = -1;
956
+ }
957
+ }
958
+ }
843959
844960
/*
845
- ** Compute the rail mapping.
961
+ ** Compute the rail mapping that tries to put the branch named
962
+ ** zLeftBranch at the left margin. Other branches that merge
963
+ ** with zLeftBranch are to the right with merge rails in between.
964
+ **
965
+ ** aMap[X]=Y means that the X-th rail is drawn as the Y-th rail.
966
+ **
967
+ ** Do not move rails around if there are timewarps, because that can
968
+ ** seriously mess up the display of timewarps. Timewarps should be
969
+ ** rare so this should not be a serious limitation to the algorithm.
846970
*/
847971
aMap = p->aiRailMap;
848
- for(i=0; i<=p->mxRail; i++) aMap[i] = i;
849
- if( zLeftBranch && nTimewarp==0 ){
850
- char *zLeft = persistBranchName(p, zLeftBranch);
851
- j = 0;
852
- for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
853
- if( pRow->zBranch==zLeft && aMap[pRow->iRail]>=j ){
854
- for(i=0; i<=p->mxRail; i++){
855
- if( aMap[i]>=j && aMap[i]<=pRow->iRail ) aMap[i]++;
856
- }
857
- aMap[pRow->iRail] = j++;
858
- }
972
+ for(i=0; i<=p->mxRail; i++) aMap[i] = i; /* Set up a default mapping */
973
+ if( nTimewarp==0 ){
974
+ /* Priority bits:
975
+ **
976
+ ** 0x04 The preferred branch
977
+ **
978
+ ** 0x02 A merge rail - a rail that contains merge lines
979
+ **
980
+ ** 0x01 A rail that merges with the preferred branch
981
+ */
982
+ u8 aPriority[GR_MAX_RAIL];
983
+ memset(aPriority, 0, p->mxRail+1);
984
+ if( zLeftBranch ){
985
+ char *zLeft = persistBranchName(p, zLeftBranch);
986
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
987
+ if( pRow->zBranch==zLeft ){
988
+ aPriority[pRow->iRail] |= 4;
989
+ for(i=0; i<=p->mxRail; i++){
990
+ if( pRow->mergeIn[i] ) aPriority[i] |= 1;
991
+ }
992
+ if( pRow->mergeOut>=0 ) aPriority[pRow->mergeOut] |= 1;
993
+ }
994
+ }
995
+ }else{
996
+ j = 1;
997
+ aPriority[0] = 4;
998
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
999
+ if( pRow->iRail==0 ){
1000
+ for(i=0; i<=p->mxRail; i++){
1001
+ if( pRow->mergeIn[i] ) aPriority[i] |= 1;
1002
+ }
1003
+ if( pRow->mergeOut>=0 ) aPriority[pRow->mergeOut] |= 1;
1004
+ }
1005
+ }
1006
+ }
1007
+ for(i=0; i<=p->mxRail; i++){
1008
+ if( p->mergeRail & BIT(i) ){
1009
+ aPriority[i] |= 2;
1010
+ }
1011
+ }
1012
+
1013
+#if 0
1014
+ fprintf(stderr,"mergeRail: 0x%llx\n", p->mergeRail);
1015
+ fprintf(stderr,"Priority:");
1016
+ for(i=0; i<=p->mxRail; i++) fprintf(stderr," %d", aPriority[i]);
1017
+ fprintf(stderr,"\n");
1018
+#endif
1019
+
1020
+ j = 0;
1021
+ for(i=0; i<=p->mxRail; i++){
1022
+ if( aPriority[i]>=4 ) aMap[i] = j++;
1023
+ }
1024
+ for(i=p->mxRail; i>=0; i--){
1025
+ if( aPriority[i]==3 ) aMap[i] = j++;
1026
+ }
1027
+ for(i=0; i<=p->mxRail; i++){
1028
+ if( aPriority[i]==1 || aPriority[i]==2 ) aMap[i] = j++;
1029
+ }
1030
+ for(i=0; i<=p->mxRail; i++){
1031
+ if( aPriority[i]==0 ) aMap[i] = j++;
8591032
}
8601033
cgi_printf("<!-- aiRailMap =");
8611034
for(i=0; i<=p->mxRail; i++) cgi_printf(" %d", aMap[i]);
8621035
cgi_printf(" -->\n");
8631036
}
8641037
8651038
p->nErr = 0;
8661039
}
8671040
--- src/graph.c
+++ src/graph.c
@@ -82,11 +82,12 @@
82 int idx; /* Row index. Top row is smallest. */
83 int idxTop; /* Direct descendent highest up on the graph */
84 GraphRow *pChild; /* Child immediately above this node */
85 u8 isDup; /* True if this is duplicate of a prior entry */
86 u8 isLeaf; /* True if this is a leaf node */
87 u8 isStepParent; /* pChild is actually a step-child */
 
88 u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
89 u8 timeWarp; /* Child is earlier in time */
90 u8 bDescender; /* True if riser from bottom of graph to here. */
91 u8 selfUp; /* Space above this node but belonging */
92 i8 iRail; /* Which rail this check-in appears on. 0-based.*/
@@ -109,10 +110,13 @@
109 GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
110 int nBranch; /* Number of distinct branches */
111 char **azBranch; /* Names of the branches */
112 int nRow; /* Number of rows */
113 int nHash; /* Number of slots in apHash[] */
 
 
 
114 GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
115 u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */
116 };
117
118 #endif
@@ -119,11 +123,11 @@
119
120 /* The N-th bit */
121 #define BIT(N) (((u64)1)<<(N))
122
123 /*
124 ** Number of rows before and answer a node with a riser or descender
125 ** that goes off-screen before we can reuse that rail.
126 */
127 #define RISER_MARGIN 4
128
129
@@ -275,11 +279,12 @@
275 ** top and bottom, inclusive.
276 */
277 static int findFreeRail(
278 GraphContext *p, /* The graph context */
279 int top, int btm, /* Span of rows for which the rail is needed */
280 int iNearto /* Find rail nearest to this rail */
 
281 ){
282 GraphRow *pRow;
283 int i;
284 int iBest = 0;
285 int iBestDist = 9999;
@@ -287,15 +292,38 @@
287 for(pRow=p->pFirst; pRow && pRow->idx<top; pRow=pRow->pNext){}
288 while( pRow && pRow->idx<=btm ){
289 inUseMask |= pRow->railInUse;
290 pRow = pRow->pNext;
291 }
292 for(i=0; i<GR_MAX_RAIL; i++){
293 if( (inUseMask & BIT(i))==0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294 int dist;
 
295 if( iNearto<=0 ){
296 iBest = i;
 
297 break;
298 }
299 dist = i - iNearto;
300 if( dist<0 ) dist = -dist;
301 if( dist<iBestDist ){
@@ -304,10 +332,11 @@
304 }
305 }
306 }
307 if( iBestDist>1000 ) p->nErr++;
308 if( iBest>p->mxRail ) p->mxRail = iBest;
 
309 return iBest;
310 }
311
312 /*
313 ** Assign all children of node pBottom to the same rail as pBottom.
@@ -343,26 +372,48 @@
343 p->railInUse |= mask;
344 }
345 }
346 }
347
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348 /*
349 ** Create a merge-arrow riser going from pParent up to pChild.
350 */
351 static void createMergeRiser(
352 GraphContext *p,
353 GraphRow *pParent,
354 GraphRow *pChild,
355 int isCherrypick
356 ){
357 int u;
358 u64 mask;
359 GraphRow *pLoop;
360
361 if( pParent->mergeOut<0 ){
362 u = pParent->aiRiser[pParent->iRail];
363 if( u>0 && u<pChild->idx ){
 
 
 
 
 
 
 
 
364 /* The thick arrow up to the next primary child of pDesc goes
365 ** further up than the thin merge arrow riser, so draw them both
366 ** on the same rail. */
367 pParent->mergeOut = pParent->iRail;
368 }else if( pParent->idx - pChild->idx < pParent->selfUp ){
@@ -369,11 +420,13 @@
369 pParent->mergeOut = pParent->iRail;
370 }else{
371 /* The thin merge arrow riser is taller than the thick primary
372 ** child riser, so use separate rails. */
373 int iTarget = pParent->iRail;
374 pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1, iTarget);
 
 
375 mask = BIT(pParent->mergeOut);
376 for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
377 pLoop=pLoop->pNext){
378 pLoop->railInUse |= mask;
379 }
@@ -420,11 +473,10 @@
420 while( pRow && (n--)>0 ){
421 pRow->railInUse |= mask;
422 pRow = pRow->pPrev;
423 }
424 }
425
426
427 /*
428 ** Compute the complete graph
429 **
430 ** When primary or merge parents are off-screen, normally a line is drawn
@@ -646,11 +698,11 @@
646 if( i==0 && pRow->zBranch!=zTrunk ) continue;
647 if( pRow->iRail>=0 ) continue;
648 if( pRow->isDup ) continue;
649 if( pRow->nParent<0 ) continue;
650 if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){
651 pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin, 0);
652 if( p->mxRail>=GR_MAX_RAIL ) return;
653 mask = BIT(pRow->iRail);
654 if( !omitDescenders ){
655 int n = RISER_MARGIN;
656 pRow->bDescender = pRow->nParent>0;
@@ -690,11 +742,11 @@
690 }
691 if( pParent->idx>pRow->idx ){
692 /* Common case: Child occurs after parent and is above the
693 ** parent in the timeline */
694 pRow->iRail = findFreeRail(p, pRow->idxTop, pParent->idx,
695 pParent->iRail);
696 if( p->mxRail>=GR_MAX_RAIL ) return;
697 pParent->aiRiser[pRow->iRail] = pRow->idx;
698 }else{
699 /* Timewarp case: Child occurs earlier in time than parent and
700 ** appears below the parent in the timeline. */
@@ -741,11 +793,11 @@
741 int isCherrypick = 0;
742 for(i=1; i<pRow->nParent; i++){
743 GraphRowId parentRid = pRow->aParent[i];
744 if( i==pRow->nNonCherrypick ){
745 /* Because full merges are laid out before cherrypicks,
746 ** it is ok to use a full-merge raise for a cherrypick.
747 ** See the graph on check-in 8ac66ef33b464d28 for example
748 ** iReuseIdx = -1;
749 ** iReuseRail = -1; */
750 isCherrypick = 1;
751 }
@@ -761,11 +813,11 @@
761 iMrail = j;
762 break;
763 }
764 }
765 if( iMrail==-1 ){
766 iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0);
767 if( p->mxRail>=GR_MAX_RAIL ) return;
768 mergeRiserFrom[iMrail] = parentRid;
769 }
770 iReuseIdx = p->nRow+1;
771 iReuseRail = iMrail;
@@ -838,29 +890,150 @@
838
839 /*
840 ** Find the maximum rail number.
841 */
842 find_max_rail(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
843
844 /*
845 ** Compute the rail mapping.
 
 
 
 
 
 
 
 
846 */
847 aMap = p->aiRailMap;
848 for(i=0; i<=p->mxRail; i++) aMap[i] = i;
849 if( zLeftBranch && nTimewarp==0 ){
850 char *zLeft = persistBranchName(p, zLeftBranch);
851 j = 0;
852 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
853 if( pRow->zBranch==zLeft && aMap[pRow->iRail]>=j ){
854 for(i=0; i<=p->mxRail; i++){
855 if( aMap[i]>=j && aMap[i]<=pRow->iRail ) aMap[i]++;
856 }
857 aMap[pRow->iRail] = j++;
858 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
859 }
860 cgi_printf("<!-- aiRailMap =");
861 for(i=0; i<=p->mxRail; i++) cgi_printf(" %d", aMap[i]);
862 cgi_printf(" -->\n");
863 }
864
865 p->nErr = 0;
866 }
867
--- src/graph.c
+++ src/graph.c
@@ -82,11 +82,12 @@
82 int idx; /* Row index. Top row is smallest. */
83 int idxTop; /* Direct descendent highest up on the graph */
84 GraphRow *pChild; /* Child immediately above this node */
85 u8 isDup; /* True if this is duplicate of a prior entry */
86 u8 isLeaf; /* True if this is a leaf node */
87 u8 isStepParent; /* pChild is actually a step-child. The thick
88 ** arrow up to the child is dashed, not solid */
89 u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
90 u8 timeWarp; /* Child is earlier in time */
91 u8 bDescender; /* True if riser from bottom of graph to here. */
92 u8 selfUp; /* Space above this node but belonging */
93 i8 iRail; /* Which rail this check-in appears on. 0-based.*/
@@ -109,10 +110,13 @@
110 GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
111 int nBranch; /* Number of distinct branches */
112 char **azBranch; /* Names of the branches */
113 int nRow; /* Number of rows */
114 int nHash; /* Number of slots in apHash[] */
115 u8 hasOffsetMergeRiser; /* Merge arrow from leaf goes up on a different
116 ** rail that the node */
117 u64 mergeRail; /* Rails used for merge lines */
118 GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
119 u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */
120 };
121
122 #endif
@@ -119,11 +123,11 @@
123
124 /* The N-th bit */
125 #define BIT(N) (((u64)1)<<(N))
126
127 /*
128 ** Number of rows before and after a node with a riser or descender
129 ** that goes off-screen before we can reuse that rail.
130 */
131 #define RISER_MARGIN 4
132
133
@@ -275,11 +279,12 @@
279 ** top and bottom, inclusive.
280 */
281 static int findFreeRail(
282 GraphContext *p, /* The graph context */
283 int top, int btm, /* Span of rows for which the rail is needed */
284 int iNearto, /* Find rail nearest to this rail */
285 int bMergeRail /* This rail will be used for a merge line */
286 ){
287 GraphRow *pRow;
288 int i;
289 int iBest = 0;
290 int iBestDist = 9999;
@@ -287,15 +292,38 @@
292 for(pRow=p->pFirst; pRow && pRow->idx<top; pRow=pRow->pNext){}
293 while( pRow && pRow->idx<=btm ){
294 inUseMask |= pRow->railInUse;
295 pRow = pRow->pNext;
296 }
297
298 /* First look for a match that honors bMergeRail */
299 for(i=0; i<=p->mxRail; i++){
300 u64 m = BIT(i);
301 int dist;
302 if( inUseMask & m ) continue;
303 if( (bMergeRail!=0) != ((p->mergeRail & m)!=0) ) continue;
304 if( iNearto<=0 ){
305 iBest = i;
306 iBestDist = 1;
307 break;
308 }
309 dist = i - iNearto;
310 if( dist<0 ) dist = -dist;
311 if( dist<iBestDist ){
312 iBestDist = dist;
313 iBest = i;
314 }
315 }
316
317 /* If no match, consider all possible rails */
318 if( iBestDist>1000 ){
319 for(i=0; i<=p->mxRail+1; i++){
320 int dist;
321 if( inUseMask & BIT(i) ) continue;
322 if( iNearto<=0 ){
323 iBest = i;
324 iBestDist = 1;
325 break;
326 }
327 dist = i - iNearto;
328 if( dist<0 ) dist = -dist;
329 if( dist<iBestDist ){
@@ -304,10 +332,11 @@
332 }
333 }
334 }
335 if( iBestDist>1000 ) p->nErr++;
336 if( iBest>p->mxRail ) p->mxRail = iBest;
337 if( bMergeRail ) p->mergeRail |= BIT(iBest);
338 return iBest;
339 }
340
341 /*
342 ** Assign all children of node pBottom to the same rail as pBottom.
@@ -343,26 +372,48 @@
372 p->railInUse |= mask;
373 }
374 }
375 }
376
377
378 /*
379 ** Check to see if rail iRail is clear from pBottom up to and including
380 ** pTop.
381 */
382 static int railIsClear(GraphRow *pBottom, int iTop, int iRail){
383 u64 m = BIT(iRail);
384 while( pBottom && pBottom->idx>=iTop ){
385 if( pBottom->railInUse & m ) return 0;
386 pBottom = pBottom->pPrev;
387 }
388 return 1;
389 }
390
391 /*
392 ** Create a merge-arrow riser going from pParent up to pChild.
393 */
394 static void createMergeRiser(
395 GraphContext *p,
396 GraphRow *pParent, /* Lower node from which the merge line begins */
397 GraphRow *pChild, /* Upper node at which the merge line ends */
398 int isCherrypick /* True for a cherry-pick merge */
399 ){
400 int u;
401 u64 mask;
402 GraphRow *pLoop;
403
404 if( pParent->mergeOut<0 ){
405 u = pParent->aiRiser[pParent->iRail];
406 if( u<0 && railIsClear(pParent->pPrev, pChild->idx, pParent->iRail) ){
407 /* pParent is a leaf and the merge-line can be drawn straight up.*/
408 pParent->mergeOut = pParent->iRail;
409 mask = BIT(pParent->iRail);
410 for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
411 pLoop=pLoop->pNext){
412 pLoop->railInUse |= mask;
413 }
414 }else if( u>0 && u<pChild->idx ){
415 /* The thick arrow up to the next primary child of pDesc goes
416 ** further up than the thin merge arrow riser, so draw them both
417 ** on the same rail. */
418 pParent->mergeOut = pParent->iRail;
419 }else if( pParent->idx - pChild->idx < pParent->selfUp ){
@@ -369,11 +420,13 @@
420 pParent->mergeOut = pParent->iRail;
421 }else{
422 /* The thin merge arrow riser is taller than the thick primary
423 ** child riser, so use separate rails. */
424 int iTarget = pParent->iRail;
425 if( u<0 ) p->hasOffsetMergeRiser = 1;
426 pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1,
427 iTarget, 1);
428 mask = BIT(pParent->mergeOut);
429 for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
430 pLoop=pLoop->pNext){
431 pLoop->railInUse |= mask;
432 }
@@ -420,11 +473,10 @@
473 while( pRow && (n--)>0 ){
474 pRow->railInUse |= mask;
475 pRow = pRow->pPrev;
476 }
477 }
 
478
479 /*
480 ** Compute the complete graph
481 **
482 ** When primary or merge parents are off-screen, normally a line is drawn
@@ -646,11 +698,11 @@
698 if( i==0 && pRow->zBranch!=zTrunk ) continue;
699 if( pRow->iRail>=0 ) continue;
700 if( pRow->isDup ) continue;
701 if( pRow->nParent<0 ) continue;
702 if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){
703 pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin,0,0);
704 if( p->mxRail>=GR_MAX_RAIL ) return;
705 mask = BIT(pRow->iRail);
706 if( !omitDescenders ){
707 int n = RISER_MARGIN;
708 pRow->bDescender = pRow->nParent>0;
@@ -690,11 +742,11 @@
742 }
743 if( pParent->idx>pRow->idx ){
744 /* Common case: Child occurs after parent and is above the
745 ** parent in the timeline */
746 pRow->iRail = findFreeRail(p, pRow->idxTop, pParent->idx,
747 pParent->iRail, 0);
748 if( p->mxRail>=GR_MAX_RAIL ) return;
749 pParent->aiRiser[pRow->iRail] = pRow->idx;
750 }else{
751 /* Timewarp case: Child occurs earlier in time than parent and
752 ** appears below the parent in the timeline. */
@@ -741,11 +793,11 @@
793 int isCherrypick = 0;
794 for(i=1; i<pRow->nParent; i++){
795 GraphRowId parentRid = pRow->aParent[i];
796 if( i==pRow->nNonCherrypick ){
797 /* Because full merges are laid out before cherrypicks,
798 ** it is ok to use a full-merge raiser for a cherrypick.
799 ** See the graph on check-in 8ac66ef33b464d28 for example
800 ** iReuseIdx = -1;
801 ** iReuseRail = -1; */
802 isCherrypick = 1;
803 }
@@ -761,11 +813,11 @@
813 iMrail = j;
814 break;
815 }
816 }
817 if( iMrail==-1 ){
818 iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1);
819 if( p->mxRail>=GR_MAX_RAIL ) return;
820 mergeRiserFrom[iMrail] = parentRid;
821 }
822 iReuseIdx = p->nRow+1;
823 iReuseRail = iMrail;
@@ -838,29 +890,150 @@
890
891 /*
892 ** Find the maximum rail number.
893 */
894 find_max_rail(p);
895
896 /* If a leaf node has a merge riser going up on a different rail,
897 ** try to move the rail of the node (and its ancestors) to be underneath
898 ** the merge riser. This is an optimization that improves the
899 ** appearance of graph but is not strictly necessary.
900 */
901 if( nTimewarp==0 && p->hasOffsetMergeRiser ){
902 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
903 GraphRow *pBottom; /* Bottom row of a branch */
904 GraphRow *pRoot; /* Node off of which the branch diverges */
905 int iFrom; /* Proposed to move from this rail */
906 int iTo; /* Move the branch to this rail */
907
908 iFrom = pRow->iRail;
909 if( pRow->aiRiser[iFrom]>=0 ) continue; /* Not a leaf */
910 if( pRow->mergeOut<0 ) continue; /* No merge riser */
911 if( pRow->mergeOut==iFrom ) continue; /* Riser already aligned */
912 iTo = pRow->mergeOut;
913
914 /* Find the bottom (oldest) node in the branch */
915 pBottom = 0;
916 for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
917 if( pLoop->idxTop==pRow->idx ) pBottom = pLoop;
918 }
919 if( pBottom==0 ) continue; /* Not possible */
920
921 /* Verify that the rail we want to shift into is clear */
922 pLoop = pBottom;
923 if( pLoop->pNext ) pLoop = pLoop->pNext;
924 if( !railIsClear(pLoop, pRow->idx+1, iTo) ){
925 /* Other nodes or risers are already using the space that
926 ** we propose to move the pRow branch into. */
927 continue;
928 }
929
930 /* Find the "root" of the branch. The root is a different branch
931 ** from which the pRow branch emerges. There might not be a root
932 ** if the pRow branch started off the bottom of the screen.
933 */
934 for(pRoot=pBottom->pNext; pRoot; pRoot=pRoot->pNext){
935 if( pRoot->aiRiser[iFrom]>=0 ) break;
936 }
937 if( pRoot && pRoot->iRail==iTo ){
938 /* The parent branch from which this branch emerges is on the
939 ** same rail as pRow. Do not shift as that would stack a child
940 ** branch directly above its parent. */
941 continue;
942 }
943
944 /* All clear. Make the translation
945 */
946 for(pLoop=pRow; pLoop && pLoop->idx<=pBottom->idx; pLoop=pLoop->pNext){
947 if( pLoop->iRail==iFrom ){
948 pLoop->iRail = iTo;
949 pLoop->aiRiser[iTo] = pLoop->aiRiser[iFrom];
950 pLoop->aiRiser[iFrom] = -1;
951 }
952 }
953 if( pRoot ){
954 pRoot->aiRiser[iTo] = pRoot->aiRiser[iFrom];
955 pRoot->aiRiser[iFrom] = -1;
956 }
957 }
958 }
959
960 /*
961 ** Compute the rail mapping that tries to put the branch named
962 ** zLeftBranch at the left margin. Other branches that merge
963 ** with zLeftBranch are to the right with merge rails in between.
964 **
965 ** aMap[X]=Y means that the X-th rail is drawn as the Y-th rail.
966 **
967 ** Do not move rails around if there are timewarps, because that can
968 ** seriously mess up the display of timewarps. Timewarps should be
969 ** rare so this should not be a serious limitation to the algorithm.
970 */
971 aMap = p->aiRailMap;
972 for(i=0; i<=p->mxRail; i++) aMap[i] = i; /* Set up a default mapping */
973 if( nTimewarp==0 ){
974 /* Priority bits:
975 **
976 ** 0x04 The preferred branch
977 **
978 ** 0x02 A merge rail - a rail that contains merge lines
979 **
980 ** 0x01 A rail that merges with the preferred branch
981 */
982 u8 aPriority[GR_MAX_RAIL];
983 memset(aPriority, 0, p->mxRail+1);
984 if( zLeftBranch ){
985 char *zLeft = persistBranchName(p, zLeftBranch);
986 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
987 if( pRow->zBranch==zLeft ){
988 aPriority[pRow->iRail] |= 4;
989 for(i=0; i<=p->mxRail; i++){
990 if( pRow->mergeIn[i] ) aPriority[i] |= 1;
991 }
992 if( pRow->mergeOut>=0 ) aPriority[pRow->mergeOut] |= 1;
993 }
994 }
995 }else{
996 j = 1;
997 aPriority[0] = 4;
998 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
999 if( pRow->iRail==0 ){
1000 for(i=0; i<=p->mxRail; i++){
1001 if( pRow->mergeIn[i] ) aPriority[i] |= 1;
1002 }
1003 if( pRow->mergeOut>=0 ) aPriority[pRow->mergeOut] |= 1;
1004 }
1005 }
1006 }
1007 for(i=0; i<=p->mxRail; i++){
1008 if( p->mergeRail & BIT(i) ){
1009 aPriority[i] |= 2;
1010 }
1011 }
1012
1013 #if 0
1014 fprintf(stderr,"mergeRail: 0x%llx\n", p->mergeRail);
1015 fprintf(stderr,"Priority:");
1016 for(i=0; i<=p->mxRail; i++) fprintf(stderr," %d", aPriority[i]);
1017 fprintf(stderr,"\n");
1018 #endif
1019
1020 j = 0;
1021 for(i=0; i<=p->mxRail; i++){
1022 if( aPriority[i]>=4 ) aMap[i] = j++;
1023 }
1024 for(i=p->mxRail; i>=0; i--){
1025 if( aPriority[i]==3 ) aMap[i] = j++;
1026 }
1027 for(i=0; i<=p->mxRail; i++){
1028 if( aPriority[i]==1 || aPriority[i]==2 ) aMap[i] = j++;
1029 }
1030 for(i=0; i<=p->mxRail; i++){
1031 if( aPriority[i]==0 ) aMap[i] = j++;
1032 }
1033 cgi_printf("<!-- aiRailMap =");
1034 for(i=0; i<=p->mxRail; i++) cgi_printf(" %d", aMap[i]);
1035 cgi_printf(" -->\n");
1036 }
1037
1038 p->nErr = 0;
1039 }
1040
+11 -8
--- src/graph.js
+++ src/graph.js
@@ -53,14 +53,13 @@
5353
** is the rail on which the riser should run and the second integer
5454
** is the id of the node upto which the riser should run. If there
5555
** are no risers, this array does not exist.
5656
** mi: "merge-in". An array of integer rail positions from which
5757
** merge arrows should be drawn into this node. If the value is
58
-** negative, then the rail position is the absolute value of mi[]
59
-** and a thin merge-arrow descender is drawn to the bottom of
60
-** the screen. This array is omitted if there are no inbound
61
-** merges.
58
+** negative, then the rail position is -1-mi[] and a thin merge-arrow
59
+** descender is drawn to the bottom of the screen. This array is
60
+** omitted if there are no inbound merges.
6261
** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
6362
** omitted if there are no cherrypick merges.
6463
** h: The artifact hash of the object being graphed
6564
*/
6665
/* The amendCss() function does a one-time change to the CSS to account
@@ -355,11 +354,11 @@
355354
}
356355
function drawCherrypickLine(x0,y0,x1,y1){
357356
drawLine(cpLine,null,x0,y0,x1,y1);
358357
}
359358
/* Draw an arrow representing an in-bound merge from the "rail"-th rail
360
- ** over to the node of "p". Make is a checkpoint merge is "isCP" is true */
359
+ ** over to the node of "p". Make it a checkpoint merge is "isCP" is true */
361360
function drawMergeArrow(p,rail,isCP){
362361
var x0 = rail*railPitch + node.w/2;
363362
if( rail in mergeLines ){
364363
x0 += mergeLines[rail];
365364
if( p.r<rail ) x0 += mLine.w;
@@ -422,14 +421,18 @@
422421
}
423422
if( p.hasOwnProperty('mo') ){
424423
var x0 = p.x + node.w/2;
425424
var x1 = p.mo*railPitch + node.w/2;
426425
var u = tx.rowinfo[p.mu-tx.iTopRow];
426
+ var mtop = u;
427
+ if( p.hasOwnProperty('cu') ){
428
+ mtop = tx.rowinfo[p.cu-tx.iTopRow];
429
+ }
427430
var y1 = miLineY(u);
428431
if( p.u<=0 || p.mo!=p.r ){
429432
if( p.u==0 && p.mo==p.r ){
430
- mergeLines[p.mo] = u.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
433
+ mergeLines[p.mo] = mtop.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
431434
}else{
432435
mergeLines[p.mo] = -mLine.w/2;
433436
}
434437
x1 += mergeLines[p.mo]
435438
var y0 = p.y+2;
@@ -458,11 +461,11 @@
458461
var u2 = tx.rowinfo[p.cu-tx.iTopRow];
459462
var y2 = miLineY(u2);
460463
drawCherrypickLine(x1,y1,null,y2);
461464
}
462465
}else if( mergeOffset ){
463
- mergeLines[p.mo] = u.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
466
+ mergeLines[p.mo] = mtop.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
464467
x1 += mergeLines[p.mo];
465468
if( p.mu<p.id ){
466469
drawMergeLine(x1,p.y+node.h/2,null,y1);
467470
}
468471
if( p.hasOwnProperty('cu') ){
@@ -508,11 +511,11 @@
508511
}
509512
if( p.hasOwnProperty('mi') ){
510513
for( var i=0; i<p.mi.length; i++ ){
511514
var rail = p.mi[i];
512515
if( rail<0 ){
513
- rail = -rail;
516
+ rail = -1-rail;
514517
mergeLines[rail] = -mLine.w/2;
515518
var x = rail*railPitch + (node.w-mLine.w)/2;
516519
var y = miLineY(p);
517520
drawMergeLine(x,y,null,mergeBtm[rail]);
518521
mergeBtm[rail] = y;
519522
--- src/graph.js
+++ src/graph.js
@@ -53,14 +53,13 @@
53 ** is the rail on which the riser should run and the second integer
54 ** is the id of the node upto which the riser should run. If there
55 ** are no risers, this array does not exist.
56 ** mi: "merge-in". An array of integer rail positions from which
57 ** merge arrows should be drawn into this node. If the value is
58 ** negative, then the rail position is the absolute value of mi[]
59 ** and a thin merge-arrow descender is drawn to the bottom of
60 ** the screen. This array is omitted if there are no inbound
61 ** merges.
62 ** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
63 ** omitted if there are no cherrypick merges.
64 ** h: The artifact hash of the object being graphed
65 */
66 /* The amendCss() function does a one-time change to the CSS to account
@@ -355,11 +354,11 @@
355 }
356 function drawCherrypickLine(x0,y0,x1,y1){
357 drawLine(cpLine,null,x0,y0,x1,y1);
358 }
359 /* Draw an arrow representing an in-bound merge from the "rail"-th rail
360 ** over to the node of "p". Make is a checkpoint merge is "isCP" is true */
361 function drawMergeArrow(p,rail,isCP){
362 var x0 = rail*railPitch + node.w/2;
363 if( rail in mergeLines ){
364 x0 += mergeLines[rail];
365 if( p.r<rail ) x0 += mLine.w;
@@ -422,14 +421,18 @@
422 }
423 if( p.hasOwnProperty('mo') ){
424 var x0 = p.x + node.w/2;
425 var x1 = p.mo*railPitch + node.w/2;
426 var u = tx.rowinfo[p.mu-tx.iTopRow];
 
 
 
 
427 var y1 = miLineY(u);
428 if( p.u<=0 || p.mo!=p.r ){
429 if( p.u==0 && p.mo==p.r ){
430 mergeLines[p.mo] = u.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
431 }else{
432 mergeLines[p.mo] = -mLine.w/2;
433 }
434 x1 += mergeLines[p.mo]
435 var y0 = p.y+2;
@@ -458,11 +461,11 @@
458 var u2 = tx.rowinfo[p.cu-tx.iTopRow];
459 var y2 = miLineY(u2);
460 drawCherrypickLine(x1,y1,null,y2);
461 }
462 }else if( mergeOffset ){
463 mergeLines[p.mo] = u.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
464 x1 += mergeLines[p.mo];
465 if( p.mu<p.id ){
466 drawMergeLine(x1,p.y+node.h/2,null,y1);
467 }
468 if( p.hasOwnProperty('cu') ){
@@ -508,11 +511,11 @@
508 }
509 if( p.hasOwnProperty('mi') ){
510 for( var i=0; i<p.mi.length; i++ ){
511 var rail = p.mi[i];
512 if( rail<0 ){
513 rail = -rail;
514 mergeLines[rail] = -mLine.w/2;
515 var x = rail*railPitch + (node.w-mLine.w)/2;
516 var y = miLineY(p);
517 drawMergeLine(x,y,null,mergeBtm[rail]);
518 mergeBtm[rail] = y;
519
--- src/graph.js
+++ src/graph.js
@@ -53,14 +53,13 @@
53 ** is the rail on which the riser should run and the second integer
54 ** is the id of the node upto which the riser should run. If there
55 ** are no risers, this array does not exist.
56 ** mi: "merge-in". An array of integer rail positions from which
57 ** merge arrows should be drawn into this node. If the value is
58 ** negative, then the rail position is -1-mi[] and a thin merge-arrow
59 ** descender is drawn to the bottom of the screen. This array is
60 ** omitted if there are no inbound merges.
 
61 ** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
62 ** omitted if there are no cherrypick merges.
63 ** h: The artifact hash of the object being graphed
64 */
65 /* The amendCss() function does a one-time change to the CSS to account
@@ -355,11 +354,11 @@
354 }
355 function drawCherrypickLine(x0,y0,x1,y1){
356 drawLine(cpLine,null,x0,y0,x1,y1);
357 }
358 /* Draw an arrow representing an in-bound merge from the "rail"-th rail
359 ** over to the node of "p". Make it a checkpoint merge is "isCP" is true */
360 function drawMergeArrow(p,rail,isCP){
361 var x0 = rail*railPitch + node.w/2;
362 if( rail in mergeLines ){
363 x0 += mergeLines[rail];
364 if( p.r<rail ) x0 += mLine.w;
@@ -422,14 +421,18 @@
421 }
422 if( p.hasOwnProperty('mo') ){
423 var x0 = p.x + node.w/2;
424 var x1 = p.mo*railPitch + node.w/2;
425 var u = tx.rowinfo[p.mu-tx.iTopRow];
426 var mtop = u;
427 if( p.hasOwnProperty('cu') ){
428 mtop = tx.rowinfo[p.cu-tx.iTopRow];
429 }
430 var y1 = miLineY(u);
431 if( p.u<=0 || p.mo!=p.r ){
432 if( p.u==0 && p.mo==p.r ){
433 mergeLines[p.mo] = mtop.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
434 }else{
435 mergeLines[p.mo] = -mLine.w/2;
436 }
437 x1 += mergeLines[p.mo]
438 var y0 = p.y+2;
@@ -458,11 +461,11 @@
461 var u2 = tx.rowinfo[p.cu-tx.iTopRow];
462 var y2 = miLineY(u2);
463 drawCherrypickLine(x1,y1,null,y2);
464 }
465 }else if( mergeOffset ){
466 mergeLines[p.mo] = mtop.r<p.r ? -mergeOffset-mLine.w : mergeOffset;
467 x1 += mergeLines[p.mo];
468 if( p.mu<p.id ){
469 drawMergeLine(x1,p.y+node.h/2,null,y1);
470 }
471 if( p.hasOwnProperty('cu') ){
@@ -508,11 +511,11 @@
511 }
512 if( p.hasOwnProperty('mi') ){
513 for( var i=0; i<p.mi.length; i++ ){
514 var rail = p.mi[i];
515 if( rail<0 ){
516 rail = -1-rail;
517 mergeLines[rail] = -mLine.w/2;
518 var x = rail*railPitch + (node.w-mLine.w)/2;
519 var y = miLineY(p);
520 drawMergeLine(x,y,null,mergeBtm[rail]);
521 mergeBtm[rail] = y;
522
+27 -9
--- src/href.js
+++ src/href.js
@@ -12,14 +12,18 @@
1212
**
1313
** {"delay":MILLISECONDS, "mouseover":BOOLEAN}
1414
**
1515
** The <script> must have an id='href-data'. DELAY is the number
1616
** milliseconds delay prior to populating href= and action=. If the
17
-** mouseover boolean is true, then the timer does not start until a
18
-** mouse motion event occurs over top of the document.
17
+** mouseover boolean is true, then the href= rewrite is further delayed
18
+** until the first mousedown event that occurs after the timer expires.
1919
*/
20
-function setAllHrefs(){
20
+var antiRobot = 0;
21
+var antiRobotBody = document.getElementsByTagName("body")[0];
22
+function antiRobotGo(){
23
+ if( antiRobot!=3 ) return;
24
+ antiRobot = 7;
2125
var anchors = document.getElementsByTagName("a");
2226
for(var i=0; i<anchors.length; i++){
2327
var j = anchors[i];
2428
if(j.hasAttribute("data-href")) j.href=j.getAttribute("data-href");
2529
}
@@ -31,16 +35,30 @@
3135
}
3236
function antiRobotDefense(){
3337
var x = document.getElementById("href-data");
3438
var jx = x.textContent || x.innerText;
3539
var g = JSON.parse(jx);
36
- var isOperaMini =
37
- Object.prototype.toString.call(window.operamini)==="[object OperaMini]";
38
- if(g.mouseover && !isOperaMini){
39
- document.getElementsByTagName("body")[0].onmousemove=function(){
40
- setTimeout(setAllHrefs, g.delay);
40
+ if( g.mouseover ){
41
+ antiRobotBody.onmousedown=function(){
42
+ antiRobot |= 2;
43
+ antiRobotGo();
44
+ antiRobotBody.onmousedown=null;
45
+ }
46
+ antiRobotBody.onmousemove=function(){
47
+ antiRobot |= 2;
48
+ antiRobotGo();
49
+ antiRobotBody.onmousemove=null;
4150
}
4251
}else{
43
- setTimeout(setAllHrefs, g.delay);
52
+ antiRobot |= 2;
53
+ }
54
+ if( g.delay>0 ){
55
+ setTimeout(function(){
56
+ antiRobot |= 1;
57
+ antiRobotGo();
58
+ }, g.delay)
59
+ }else{
60
+ antiRobot |= 1;
4461
}
62
+ antiRobotGo();
4563
}
4664
antiRobotDefense();
4765
--- src/href.js
+++ src/href.js
@@ -12,14 +12,18 @@
12 **
13 ** {"delay":MILLISECONDS, "mouseover":BOOLEAN}
14 **
15 ** The <script> must have an id='href-data'. DELAY is the number
16 ** milliseconds delay prior to populating href= and action=. If the
17 ** mouseover boolean is true, then the timer does not start until a
18 ** mouse motion event occurs over top of the document.
19 */
20 function setAllHrefs(){
 
 
 
 
21 var anchors = document.getElementsByTagName("a");
22 for(var i=0; i<anchors.length; i++){
23 var j = anchors[i];
24 if(j.hasAttribute("data-href")) j.href=j.getAttribute("data-href");
25 }
@@ -31,16 +35,30 @@
31 }
32 function antiRobotDefense(){
33 var x = document.getElementById("href-data");
34 var jx = x.textContent || x.innerText;
35 var g = JSON.parse(jx);
36 var isOperaMini =
37 Object.prototype.toString.call(window.operamini)==="[object OperaMini]";
38 if(g.mouseover && !isOperaMini){
39 document.getElementsByTagName("body")[0].onmousemove=function(){
40 setTimeout(setAllHrefs, g.delay);
 
 
 
 
 
41 }
42 }else{
43 setTimeout(setAllHrefs, g.delay);
 
 
 
 
 
 
 
 
44 }
 
45 }
46 antiRobotDefense();
47
--- src/href.js
+++ src/href.js
@@ -12,14 +12,18 @@
12 **
13 ** {"delay":MILLISECONDS, "mouseover":BOOLEAN}
14 **
15 ** The <script> must have an id='href-data'. DELAY is the number
16 ** milliseconds delay prior to populating href= and action=. If the
17 ** mouseover boolean is true, then the href= rewrite is further delayed
18 ** until the first mousedown event that occurs after the timer expires.
19 */
20 var antiRobot = 0;
21 var antiRobotBody = document.getElementsByTagName("body")[0];
22 function antiRobotGo(){
23 if( antiRobot!=3 ) return;
24 antiRobot = 7;
25 var anchors = document.getElementsByTagName("a");
26 for(var i=0; i<anchors.length; i++){
27 var j = anchors[i];
28 if(j.hasAttribute("data-href")) j.href=j.getAttribute("data-href");
29 }
@@ -31,16 +35,30 @@
35 }
36 function antiRobotDefense(){
37 var x = document.getElementById("href-data");
38 var jx = x.textContent || x.innerText;
39 var g = JSON.parse(jx);
40 if( g.mouseover ){
41 antiRobotBody.onmousedown=function(){
42 antiRobot |= 2;
43 antiRobotGo();
44 antiRobotBody.onmousedown=null;
45 }
46 antiRobotBody.onmousemove=function(){
47 antiRobot |= 2;
48 antiRobotGo();
49 antiRobotBody.onmousemove=null;
50 }
51 }else{
52 antiRobot |= 2;
53 }
54 if( g.delay>0 ){
55 setTimeout(function(){
56 antiRobot |= 1;
57 antiRobotGo();
58 }, g.delay)
59 }else{
60 antiRobot |= 1;
61 }
62 antiRobotGo();
63 }
64 antiRobotDefense();
65
+3 -3
--- src/http.c
+++ src/http.c
@@ -454,13 +454,13 @@
454454
isCompressed = 0;
455455
}else if( fossil_strnicmp(&zLine[14],
456456
"application/x-fossil-uncompressed", -1)==0 ){
457457
isCompressed = 0;
458458
}else{
459
- if( (mHttpFlags & HTTP_GENERIC)==0
460
- && fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0
461
- ){
459
+ if( mHttpFlags & HTTP_GENERIC ){
460
+ if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
461
+ }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
462462
isError = 1;
463463
}
464464
}
465465
}
466466
}
467467
--- src/http.c
+++ src/http.c
@@ -454,13 +454,13 @@
454 isCompressed = 0;
455 }else if( fossil_strnicmp(&zLine[14],
456 "application/x-fossil-uncompressed", -1)==0 ){
457 isCompressed = 0;
458 }else{
459 if( (mHttpFlags & HTTP_GENERIC)==0
460 && fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0
461 ){
462 isError = 1;
463 }
464 }
465 }
466 }
467
--- src/http.c
+++ src/http.c
@@ -454,13 +454,13 @@
454 isCompressed = 0;
455 }else if( fossil_strnicmp(&zLine[14],
456 "application/x-fossil-uncompressed", -1)==0 ){
457 isCompressed = 0;
458 }else{
459 if( mHttpFlags & HTTP_GENERIC ){
460 if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
461 }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
462 isError = 1;
463 }
464 }
465 }
466 }
467
+23 -17
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,39 +811,41 @@
811811
}
812812
813813
/*
814814
** Read cleartext bytes that have been received from the client and
815815
** decrypted by the SSL server codec.
816
+**
817
+** If the expected payload size unknown, i.e. if the HTTP
818
+** Content-Length: header field has not been parsed, the doLoop
819
+** argument should be 0, or SSL_read() may block and wait for more
820
+** data than is eventually going to arrive (on Windows). On
821
+** non-Windows builds, it has been our experience that the final
822
+** argument must always be true, as discussed at length at:
823
+**
824
+** https://fossil-scm.org/forum/forumpost/2f818850abb72719
816825
*/
817
-size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
826
+size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int doLoop){
818827
int n;
819828
size_t rc = 0;
820829
SslServerConn *pServer = (SslServerConn*)pServerArg;
821830
if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
822
- else if( BIO_eof(pServer->bio) ) return 0;
823
- while( nBuf!=rc ){
831
+ while( nBuf!=rc && BIO_eof(pServer->bio)==0 ){
824832
n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
825
- if( n==0 ){
826
- break;
827
- }else if(n>0){
833
+ if( n>0 ){
828834
rc += n;
829
- }else{
830
- fossil_fatal("SSL read error.");
831
- }
832
-#ifdef _WIN32
833
- /* Windows (XP and 10 tested with openssl 1.1.1m and 3.0.1) does
834
- ** not require reading in a loop, returning all data in a single
835
- ** call. If we read in a loop on Windows, SSL reads fail. Details:
836
- ** https://fossil-scm.org/forum/forumpost/2f818850abb72719 */
837
- break;
838
-#endif
835
+ }
836
+ if( doLoop==0 || n<=0 ){
837
+ break;
838
+ }
839839
}
840840
return rc;
841841
}
842842
843843
/*
844
-** Read a single line of text from the client.
844
+** Read a single line of text from the client, up to nBuf-1 bytes. On
845
+** success, writes nBuf-1 bytes to zBuf and NUL-terminates zBuf.
846
+** Returns NULL on an I/O error or at EOF.
845847
*/
846848
char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
847849
int n = 0;
848850
int i;
849851
SslServerConn *pServer = (SslServerConn*)pServerArg;
@@ -878,10 +880,11 @@
878880
}
879881
}
880882
881883
#endif /* FOSSIL_ENABLE_SSL */
882884
885
+#ifdef FOSSIL_ENABLE_SSL
883886
/*
884887
** zPath is a name that might be a file or directory containing a trust
885888
** store. *pzStore is the name of the trust store to actually use.
886889
**
887890
** If *pzStore is not NULL (meaning no trust store has been found yet)
@@ -889,10 +892,11 @@
889892
*/
890893
static void trust_location_usable(const char *zPath, const char **pzStore){
891894
if( *pzStore!=0 ) return;
892895
if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
893896
}
897
+#endif /* FOSSIL_ENABLE_SSL */
894898
895899
/*
896900
** COMMAND: tls-config*
897901
** COMMAND: ssl-config
898902
**
@@ -949,13 +953,15 @@
949953
"DELETE FROM config WHERE name GLOB 'ssl-*';"
950954
);
951955
db_protect_pop();
952956
}else
953957
if( strncmp("show",zCmd,nCmd)==0 ){
958
+#if defined(FOSSIL_ENABLE_SSL)
954959
const char *zName, *zValue;
955960
const char *zUsed = 0; /* Trust store location actually used */
956961
size_t nName;
962
+#endif
957963
Stmt q;
958964
int verbose = find_option("verbose","v",0)!=0;
959965
verify_all_options();
960966
961967
#if !defined(FOSSIL_ENABLE_SSL)
962968
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,39 +811,41 @@
811 }
812
813 /*
814 ** Read cleartext bytes that have been received from the client and
815 ** decrypted by the SSL server codec.
 
 
 
 
 
 
 
 
 
816 */
817 size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
818 int n;
819 size_t rc = 0;
820 SslServerConn *pServer = (SslServerConn*)pServerArg;
821 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
822 else if( BIO_eof(pServer->bio) ) return 0;
823 while( nBuf!=rc ){
824 n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
825 if( n==0 ){
826 break;
827 }else if(n>0){
828 rc += n;
829 }else{
830 fossil_fatal("SSL read error.");
831 }
832 #ifdef _WIN32
833 /* Windows (XP and 10 tested with openssl 1.1.1m and 3.0.1) does
834 ** not require reading in a loop, returning all data in a single
835 ** call. If we read in a loop on Windows, SSL reads fail. Details:
836 ** https://fossil-scm.org/forum/forumpost/2f818850abb72719 */
837 break;
838 #endif
839 }
840 return rc;
841 }
842
843 /*
844 ** Read a single line of text from the client.
 
 
845 */
846 char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
847 int n = 0;
848 int i;
849 SslServerConn *pServer = (SslServerConn*)pServerArg;
@@ -878,10 +880,11 @@
878 }
879 }
880
881 #endif /* FOSSIL_ENABLE_SSL */
882
 
883 /*
884 ** zPath is a name that might be a file or directory containing a trust
885 ** store. *pzStore is the name of the trust store to actually use.
886 **
887 ** If *pzStore is not NULL (meaning no trust store has been found yet)
@@ -889,10 +892,11 @@
889 */
890 static void trust_location_usable(const char *zPath, const char **pzStore){
891 if( *pzStore!=0 ) return;
892 if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
893 }
 
894
895 /*
896 ** COMMAND: tls-config*
897 ** COMMAND: ssl-config
898 **
@@ -949,13 +953,15 @@
949 "DELETE FROM config WHERE name GLOB 'ssl-*';"
950 );
951 db_protect_pop();
952 }else
953 if( strncmp("show",zCmd,nCmd)==0 ){
 
954 const char *zName, *zValue;
955 const char *zUsed = 0; /* Trust store location actually used */
956 size_t nName;
 
957 Stmt q;
958 int verbose = find_option("verbose","v",0)!=0;
959 verify_all_options();
960
961 #if !defined(FOSSIL_ENABLE_SSL)
962
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,39 +811,41 @@
811 }
812
813 /*
814 ** Read cleartext bytes that have been received from the client and
815 ** decrypted by the SSL server codec.
816 **
817 ** If the expected payload size unknown, i.e. if the HTTP
818 ** Content-Length: header field has not been parsed, the doLoop
819 ** argument should be 0, or SSL_read() may block and wait for more
820 ** data than is eventually going to arrive (on Windows). On
821 ** non-Windows builds, it has been our experience that the final
822 ** argument must always be true, as discussed at length at:
823 **
824 ** https://fossil-scm.org/forum/forumpost/2f818850abb72719
825 */
826 size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int doLoop){
827 int n;
828 size_t rc = 0;
829 SslServerConn *pServer = (SslServerConn*)pServerArg;
830 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
831 while( nBuf!=rc && BIO_eof(pServer->bio)==0 ){
 
832 n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
833 if( n>0 ){
 
 
834 rc += n;
835 }
836 if( doLoop==0 || n<=0 ){
837 break;
838 }
 
 
 
 
 
 
839 }
840 return rc;
841 }
842
843 /*
844 ** Read a single line of text from the client, up to nBuf-1 bytes. On
845 ** success, writes nBuf-1 bytes to zBuf and NUL-terminates zBuf.
846 ** Returns NULL on an I/O error or at EOF.
847 */
848 char *ssl_gets(void *pServerArg, char *zBuf, int nBuf){
849 int n = 0;
850 int i;
851 SslServerConn *pServer = (SslServerConn*)pServerArg;
@@ -878,10 +880,11 @@
880 }
881 }
882
883 #endif /* FOSSIL_ENABLE_SSL */
884
885 #ifdef FOSSIL_ENABLE_SSL
886 /*
887 ** zPath is a name that might be a file or directory containing a trust
888 ** store. *pzStore is the name of the trust store to actually use.
889 **
890 ** If *pzStore is not NULL (meaning no trust store has been found yet)
@@ -889,10 +892,11 @@
892 */
893 static void trust_location_usable(const char *zPath, const char **pzStore){
894 if( *pzStore!=0 ) return;
895 if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
896 }
897 #endif /* FOSSIL_ENABLE_SSL */
898
899 /*
900 ** COMMAND: tls-config*
901 ** COMMAND: ssl-config
902 **
@@ -949,13 +953,15 @@
953 "DELETE FROM config WHERE name GLOB 'ssl-*';"
954 );
955 db_protect_pop();
956 }else
957 if( strncmp("show",zCmd,nCmd)==0 ){
958 #if defined(FOSSIL_ENABLE_SSL)
959 const char *zName, *zValue;
960 const char *zUsed = 0; /* Trust store location actually used */
961 size_t nName;
962 #endif
963 Stmt q;
964 int verbose = find_option("verbose","v",0)!=0;
965 verify_all_options();
966
967 #if !defined(FOSSIL_ENABLE_SSL)
968
+200 -6
--- src/info.c
+++ src/info.c
@@ -735,11 +735,14 @@
735735
style_copy_button(1, "name-br", 0, 0, "%z%h</a>",
736736
href("%R/timeline?r=%T&unhide",zTagName), zTagName);
737737
cgi_printf("\n");
738738
if( wiki_tagid2("branch",zTagName)!=0 ){
739739
blob_appendf(&wiki_read_links, " | %z%h</a>",
740
- href("%R/wiki?name=branch/%h",zTagName), zTagName);
740
+ href("%R/%s?name=branch/%h",
741
+ (g.perm.Write && g.perm.WrWiki)
742
+ ? "wikiedit" : "wiki",
743
+ zTagName), zTagName);
741744
}else if( g.perm.Write && g.perm.WrWiki ){
742745
blob_appendf(&wiki_add_links, " | %z%h</a>",
743746
href("%R/wikiedit?name=branch/%h",zTagName), zTagName);
744747
}
745748
}else{
@@ -986,13 +989,13 @@
986989
}
987990
}
988991
style_header("Update of \"%h\"", pWiki->zWikiTitle);
989992
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
990993
zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate);
991
- style_submenu_element("Raw", "artifact/%s", zUuid);
992
- style_submenu_element("History", "whistory?name=%t", pWiki->zWikiTitle);
993
- style_submenu_element("Page", "wiki?name=%t", pWiki->zWikiTitle);
994
+ style_submenu_element("Raw", "%R/artifact/%s", zUuid);
995
+ style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle);
996
+ style_submenu_element("Page", "%R/wiki?name=%t", pWiki->zWikiTitle);
994997
login_anonymous_available();
995998
@ <div class="section">Overview</div>
996999
@ <p><table class="label-value">
9971000
@ <tr><th>Artifact&nbsp;ID:</th>
9981001
@ <td>%z(href("%R/artifact/%!S",zUuid))%s(zUuid)</a>
@@ -1014,11 +1017,11 @@
10141017
if( pWiki->nParent>0 ){
10151018
int i;
10161019
@ <tr><th>Parent%s(pWiki->nParent==1?"":"s"):</th><td>
10171020
for(i=0; i<pWiki->nParent; i++){
10181021
char *zParent = pWiki->azParent[i];
1019
- @ %z(href("info/%!S",zParent))%s(zParent)</a>
1022
+ @ %z(href("%R/info/%!S",zParent))%s(zParent)</a>
10201023
@ %z(href("%R/wdiff?id=%!S&pid=%!S",zUuid,zParent))(diff)</a>
10211024
}
10221025
@ </td></tr>
10231026
}
10241027
tagid = wiki_tagid(pWiki->zWikiTitle);
@@ -1179,11 +1182,11 @@
11791182
int bInvert = PB("inv");
11801183
11811184
login_check_credentials();
11821185
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
11831186
login_anonymous_available();
1184
- load_control();
1187
+ fossil_nice_default();
11851188
blob_init(&qp, 0, 0);
11861189
diffType = preferred_diff_type();
11871190
zRe = P("regex");
11881191
if( zRe ) re_compile(&pRe, zRe, 0);
11891192
zBranch = P("branch");
@@ -3678,5 +3681,196 @@
36783681
db_column_text(&q,2),
36793682
db_column_text(&q,3));
36803683
}
36813684
db_finalize(&q);
36823685
}
3686
+
3687
+#if INTERFACE
3688
+/*
3689
+** Description of a check-in relative to an earlier, tagged check-in.
3690
+*/
3691
+typedef struct CommitDescr {
3692
+ char *zRelTagname; /* Tag name on the relative check-in */
3693
+ int nCommitsSince; /* Number of commits since then */
3694
+ char *zCommitHash; /* Hash of the described check-in */
3695
+ int isDirty; /* Working directory has uncommitted changes */
3696
+} CommitDescr;
3697
+#endif
3698
+
3699
+/*
3700
+** Describe the check-in given by 'zName', and possibly matching 'matchGlob',
3701
+** relative to an earlier, tagged check-in. Use 'descr' for the output.
3702
+**
3703
+** Finds the closest ancestor (ignoring merge-ins) that has a non-propagating
3704
+** label tag and the number of steps backwards that we had to search in
3705
+** order to find that tag. Tags applied to more than one check-in are ignored.
3706
+**
3707
+** Return values:
3708
+** 0: ok
3709
+** -1: zName does not resolve to a commit
3710
+** -2: zName resolves to more than a commit
3711
+** -3: no ancestor commit with a fitting non-propagating tag found
3712
+*/
3713
+int describe_commit(
3714
+ const char *zName, /* Name of the commit to be described */
3715
+ const char *matchGlob, /* Glob pattern for the tag */
3716
+ CommitDescr *descr /* Write the description here */
3717
+){
3718
+ int rid; /* rid for zName */
3719
+ const char *zUuid; /* Hash of rid */
3720
+ int nRet = 0; /* Value to be returned */
3721
+ Stmt q; /* Query for tagged ancestors */
3722
+
3723
+ rid = symbolic_name_to_rid(zName, "ci"); /* only commits */
3724
+
3725
+ if( rid<=0 ){
3726
+ /* Commit does not exist or is ambiguous */
3727
+ descr->zRelTagname = mprintf("");
3728
+ descr->nCommitsSince = -1;
3729
+ descr->zCommitHash = mprintf("");
3730
+ descr->isDirty = -1;
3731
+ return (rid-1);
3732
+ }
3733
+
3734
+ zUuid = rid_to_uuid(rid);
3735
+ descr->zCommitHash = mprintf("%s", zUuid);
3736
+ descr->isDirty = unsaved_changes(0);
3737
+
3738
+ db_multi_exec(
3739
+ "DROP TABLE IF EXISTS temp.singletonTag;"
3740
+ "CREATE TEMP TABLE singletonTag("
3741
+ " rid INT,"
3742
+ " tagname TEXT,"
3743
+ " PRIMARY KEY (rid,tagname)"
3744
+ ") WITHOUT ROWID;"
3745
+ "INSERT OR IGNORE INTO singletonTag(rid, tagname)"
3746
+ " SELECT min(rid),"
3747
+ " substr(tagname,5)"
3748
+ " FROM tag, tagxref"
3749
+ " WHERE tag.tagid=tagxref.tagid"
3750
+ " AND tagxref.tagtype=1"
3751
+ " AND tagname GLOB 'sym-%q'"
3752
+ " GROUP BY tagname"
3753
+ " HAVING count(*)==1;",
3754
+ (matchGlob ? matchGlob : "*")
3755
+ );
3756
+
3757
+ db_prepare(&q,
3758
+ "WITH RECURSIVE"
3759
+ " ancestor(rid,mtime,tagname,n) AS ("
3760
+ " SELECT %d, event.mtime, singletonTag.tagname, 0 "
3761
+ " FROM event"
3762
+ " LEFT JOIN singletonTag ON singletonTag.rid=event.objid"
3763
+ " WHERE event.objid=%d"
3764
+ " UNION ALL"
3765
+ " SELECT plink.pid, event.mtime, singletonTag.tagname, n+1"
3766
+ " FROM ancestor, plink, event"
3767
+ " LEFT JOIN singletonTag ON singletonTag.rid=plink.pid"
3768
+ " WHERE plink.cid=ancestor.rid"
3769
+ " AND event.objid=plink.pid"
3770
+ " AND ancestor.tagname IS NULL"
3771
+ " ORDER BY mtime DESC"
3772
+ " )"
3773
+ "SELECT tagname, n"
3774
+ " FROM ancestor"
3775
+ " WHERE tagname IS NOT NULL"
3776
+ " ORDER BY n LIMIT 1;",
3777
+ rid, rid
3778
+ );
3779
+
3780
+ if( db_step(&q)==SQLITE_ROW ){
3781
+ const char *lastTag = db_column_text(&q, 0);
3782
+ descr->zRelTagname = mprintf("%s", lastTag);
3783
+ descr->nCommitsSince = db_column_int(&q, 1);
3784
+ nRet = 0;
3785
+ }else{
3786
+ /* no ancestor commit with a fitting singleton tag found */
3787
+ descr->zRelTagname = mprintf("");
3788
+ descr->nCommitsSince = -1;
3789
+ nRet = -3;
3790
+ }
3791
+
3792
+ db_finalize(&q);
3793
+ return nRet;
3794
+}
3795
+
3796
+/*
3797
+** COMMAND: describe
3798
+**
3799
+** Usage: %fossil describe ?VERSION? ?OPTIONS?
3800
+**
3801
+** Provide a description of the given VERSION by showing a non-propagating
3802
+** tag of the youngest tagged ancestor, followed by the number of commits
3803
+** since that, and the short hash of VERSION. Only tags applied to a single
3804
+** check-in are considered.
3805
+**
3806
+** If no VERSION is provided, describe the current checked-out version.
3807
+**
3808
+** If VERSION and the found ancestor refer to the same commit, the last two
3809
+** components are omitted, unless --long is provided. When no fitting tagged
3810
+** ancestor is found, show only the short hash of VERSION.
3811
+**
3812
+** Options:
3813
+**
3814
+** --digits Display so many hex digits of the hash
3815
+** (default: the larger of 6 and the 'hash-digit' setting)
3816
+** -d|--dirty Show whether there are changes to be committed
3817
+** --long Always show all three components
3818
+** --match GLOB Consider only non-propagating tags matching GLOB
3819
+*/
3820
+void describe_cmd(void){
3821
+ const char *zName;
3822
+ const char *zMatchGlob;
3823
+ const char *zDigits;
3824
+ int nDigits;
3825
+ int bDirtyFlag = 0;
3826
+ int bLongFlag = 0;
3827
+ CommitDescr descr;
3828
+
3829
+ db_find_and_open_repository(0,0);
3830
+ bDirtyFlag = find_option("dirty","d",0)!=0;
3831
+ bLongFlag = find_option("long","",0)!=0;
3832
+ zMatchGlob = find_option("match", 0, 1);
3833
+ zDigits = find_option("digits", 0, 1);
3834
+
3835
+ if ( !zDigits || ((nDigits=atoi(zDigits))==0) ){
3836
+ nDigits = hash_digits(0);
3837
+ }
3838
+
3839
+ /* We should be done with options.. */
3840
+ verify_all_options();
3841
+ if( g.argc<3 ){
3842
+ zName = "current";
3843
+ }else{
3844
+ zName = g.argv[2];
3845
+ }
3846
+
3847
+ if( bDirtyFlag ){
3848
+ if ( g.argc>=3 ) fossil_fatal("cannot use --dirty with specific checkin");
3849
+ }
3850
+
3851
+ switch( describe_commit(zName, zMatchGlob, &descr) ){
3852
+ case -1:
3853
+ fossil_fatal("commit %s does not exist", zName);
3854
+ break;
3855
+ case -2:
3856
+ fossil_fatal("commit %s is ambiguous", zName);
3857
+ break;
3858
+ case -3:
3859
+ fossil_print("%.*s%s\n", nDigits, descr.zCommitHash,
3860
+ bDirtyFlag ? (descr.isDirty ? "-dirty" : "") : "");
3861
+ break;
3862
+ case 0:
3863
+ if( descr.nCommitsSince==0 && !bLongFlag ){
3864
+ fossil_print("%s%s\n", descr.zRelTagname,
3865
+ bDirtyFlag ? (descr.isDirty ? "-dirty" : "") : "");
3866
+ }else{
3867
+ fossil_print("%s-%d-%.*s%s\n", descr.zRelTagname,
3868
+ descr.nCommitsSince, nDigits, descr.zCommitHash,
3869
+ bDirtyFlag ? (descr.isDirty ? "-dirty" : "") : "");
3870
+ }
3871
+ break;
3872
+ default:
3873
+ fossil_fatal("cannot describe commit");
3874
+ break;
3875
+ }
3876
+}
36833877
--- src/info.c
+++ src/info.c
@@ -735,11 +735,14 @@
735 style_copy_button(1, "name-br", 0, 0, "%z%h</a>",
736 href("%R/timeline?r=%T&unhide",zTagName), zTagName);
737 cgi_printf("\n");
738 if( wiki_tagid2("branch",zTagName)!=0 ){
739 blob_appendf(&wiki_read_links, " | %z%h</a>",
740 href("%R/wiki?name=branch/%h",zTagName), zTagName);
 
 
 
741 }else if( g.perm.Write && g.perm.WrWiki ){
742 blob_appendf(&wiki_add_links, " | %z%h</a>",
743 href("%R/wikiedit?name=branch/%h",zTagName), zTagName);
744 }
745 }else{
@@ -986,13 +989,13 @@
986 }
987 }
988 style_header("Update of \"%h\"", pWiki->zWikiTitle);
989 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
990 zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate);
991 style_submenu_element("Raw", "artifact/%s", zUuid);
992 style_submenu_element("History", "whistory?name=%t", pWiki->zWikiTitle);
993 style_submenu_element("Page", "wiki?name=%t", pWiki->zWikiTitle);
994 login_anonymous_available();
995 @ <div class="section">Overview</div>
996 @ <p><table class="label-value">
997 @ <tr><th>Artifact&nbsp;ID:</th>
998 @ <td>%z(href("%R/artifact/%!S",zUuid))%s(zUuid)</a>
@@ -1014,11 +1017,11 @@
1014 if( pWiki->nParent>0 ){
1015 int i;
1016 @ <tr><th>Parent%s(pWiki->nParent==1?"":"s"):</th><td>
1017 for(i=0; i<pWiki->nParent; i++){
1018 char *zParent = pWiki->azParent[i];
1019 @ %z(href("info/%!S",zParent))%s(zParent)</a>
1020 @ %z(href("%R/wdiff?id=%!S&pid=%!S",zUuid,zParent))(diff)</a>
1021 }
1022 @ </td></tr>
1023 }
1024 tagid = wiki_tagid(pWiki->zWikiTitle);
@@ -1179,11 +1182,11 @@
1179 int bInvert = PB("inv");
1180
1181 login_check_credentials();
1182 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1183 login_anonymous_available();
1184 load_control();
1185 blob_init(&qp, 0, 0);
1186 diffType = preferred_diff_type();
1187 zRe = P("regex");
1188 if( zRe ) re_compile(&pRe, zRe, 0);
1189 zBranch = P("branch");
@@ -3678,5 +3681,196 @@
3678 db_column_text(&q,2),
3679 db_column_text(&q,3));
3680 }
3681 db_finalize(&q);
3682 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3683
--- src/info.c
+++ src/info.c
@@ -735,11 +735,14 @@
735 style_copy_button(1, "name-br", 0, 0, "%z%h</a>",
736 href("%R/timeline?r=%T&unhide",zTagName), zTagName);
737 cgi_printf("\n");
738 if( wiki_tagid2("branch",zTagName)!=0 ){
739 blob_appendf(&wiki_read_links, " | %z%h</a>",
740 href("%R/%s?name=branch/%h",
741 (g.perm.Write && g.perm.WrWiki)
742 ? "wikiedit" : "wiki",
743 zTagName), zTagName);
744 }else if( g.perm.Write && g.perm.WrWiki ){
745 blob_appendf(&wiki_add_links, " | %z%h</a>",
746 href("%R/wikiedit?name=branch/%h",zTagName), zTagName);
747 }
748 }else{
@@ -986,13 +989,13 @@
989 }
990 }
991 style_header("Update of \"%h\"", pWiki->zWikiTitle);
992 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
993 zDate = db_text(0, "SELECT datetime(%.17g)", pWiki->rDate);
994 style_submenu_element("Raw", "%R/artifact/%s", zUuid);
995 style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle);
996 style_submenu_element("Page", "%R/wiki?name=%t", pWiki->zWikiTitle);
997 login_anonymous_available();
998 @ <div class="section">Overview</div>
999 @ <p><table class="label-value">
1000 @ <tr><th>Artifact&nbsp;ID:</th>
1001 @ <td>%z(href("%R/artifact/%!S",zUuid))%s(zUuid)</a>
@@ -1014,11 +1017,11 @@
1017 if( pWiki->nParent>0 ){
1018 int i;
1019 @ <tr><th>Parent%s(pWiki->nParent==1?"":"s"):</th><td>
1020 for(i=0; i<pWiki->nParent; i++){
1021 char *zParent = pWiki->azParent[i];
1022 @ %z(href("%R/info/%!S",zParent))%s(zParent)</a>
1023 @ %z(href("%R/wdiff?id=%!S&pid=%!S",zUuid,zParent))(diff)</a>
1024 }
1025 @ </td></tr>
1026 }
1027 tagid = wiki_tagid(pWiki->zWikiTitle);
@@ -1179,11 +1182,11 @@
1182 int bInvert = PB("inv");
1183
1184 login_check_credentials();
1185 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1186 login_anonymous_available();
1187 fossil_nice_default();
1188 blob_init(&qp, 0, 0);
1189 diffType = preferred_diff_type();
1190 zRe = P("regex");
1191 if( zRe ) re_compile(&pRe, zRe, 0);
1192 zBranch = P("branch");
@@ -3678,5 +3681,196 @@
3681 db_column_text(&q,2),
3682 db_column_text(&q,3));
3683 }
3684 db_finalize(&q);
3685 }
3686
3687 #if INTERFACE
3688 /*
3689 ** Description of a check-in relative to an earlier, tagged check-in.
3690 */
3691 typedef struct CommitDescr {
3692 char *zRelTagname; /* Tag name on the relative check-in */
3693 int nCommitsSince; /* Number of commits since then */
3694 char *zCommitHash; /* Hash of the described check-in */
3695 int isDirty; /* Working directory has uncommitted changes */
3696 } CommitDescr;
3697 #endif
3698
3699 /*
3700 ** Describe the check-in given by 'zName', and possibly matching 'matchGlob',
3701 ** relative to an earlier, tagged check-in. Use 'descr' for the output.
3702 **
3703 ** Finds the closest ancestor (ignoring merge-ins) that has a non-propagating
3704 ** label tag and the number of steps backwards that we had to search in
3705 ** order to find that tag. Tags applied to more than one check-in are ignored.
3706 **
3707 ** Return values:
3708 ** 0: ok
3709 ** -1: zName does not resolve to a commit
3710 ** -2: zName resolves to more than a commit
3711 ** -3: no ancestor commit with a fitting non-propagating tag found
3712 */
3713 int describe_commit(
3714 const char *zName, /* Name of the commit to be described */
3715 const char *matchGlob, /* Glob pattern for the tag */
3716 CommitDescr *descr /* Write the description here */
3717 ){
3718 int rid; /* rid for zName */
3719 const char *zUuid; /* Hash of rid */
3720 int nRet = 0; /* Value to be returned */
3721 Stmt q; /* Query for tagged ancestors */
3722
3723 rid = symbolic_name_to_rid(zName, "ci"); /* only commits */
3724
3725 if( rid<=0 ){
3726 /* Commit does not exist or is ambiguous */
3727 descr->zRelTagname = mprintf("");
3728 descr->nCommitsSince = -1;
3729 descr->zCommitHash = mprintf("");
3730 descr->isDirty = -1;
3731 return (rid-1);
3732 }
3733
3734 zUuid = rid_to_uuid(rid);
3735 descr->zCommitHash = mprintf("%s", zUuid);
3736 descr->isDirty = unsaved_changes(0);
3737
3738 db_multi_exec(
3739 "DROP TABLE IF EXISTS temp.singletonTag;"
3740 "CREATE TEMP TABLE singletonTag("
3741 " rid INT,"
3742 " tagname TEXT,"
3743 " PRIMARY KEY (rid,tagname)"
3744 ") WITHOUT ROWID;"
3745 "INSERT OR IGNORE INTO singletonTag(rid, tagname)"
3746 " SELECT min(rid),"
3747 " substr(tagname,5)"
3748 " FROM tag, tagxref"
3749 " WHERE tag.tagid=tagxref.tagid"
3750 " AND tagxref.tagtype=1"
3751 " AND tagname GLOB 'sym-%q'"
3752 " GROUP BY tagname"
3753 " HAVING count(*)==1;",
3754 (matchGlob ? matchGlob : "*")
3755 );
3756
3757 db_prepare(&q,
3758 "WITH RECURSIVE"
3759 " ancestor(rid,mtime,tagname,n) AS ("
3760 " SELECT %d, event.mtime, singletonTag.tagname, 0 "
3761 " FROM event"
3762 " LEFT JOIN singletonTag ON singletonTag.rid=event.objid"
3763 " WHERE event.objid=%d"
3764 " UNION ALL"
3765 " SELECT plink.pid, event.mtime, singletonTag.tagname, n+1"
3766 " FROM ancestor, plink, event"
3767 " LEFT JOIN singletonTag ON singletonTag.rid=plink.pid"
3768 " WHERE plink.cid=ancestor.rid"
3769 " AND event.objid=plink.pid"
3770 " AND ancestor.tagname IS NULL"
3771 " ORDER BY mtime DESC"
3772 " )"
3773 "SELECT tagname, n"
3774 " FROM ancestor"
3775 " WHERE tagname IS NOT NULL"
3776 " ORDER BY n LIMIT 1;",
3777 rid, rid
3778 );
3779
3780 if( db_step(&q)==SQLITE_ROW ){
3781 const char *lastTag = db_column_text(&q, 0);
3782 descr->zRelTagname = mprintf("%s", lastTag);
3783 descr->nCommitsSince = db_column_int(&q, 1);
3784 nRet = 0;
3785 }else{
3786 /* no ancestor commit with a fitting singleton tag found */
3787 descr->zRelTagname = mprintf("");
3788 descr->nCommitsSince = -1;
3789 nRet = -3;
3790 }
3791
3792 db_finalize(&q);
3793 return nRet;
3794 }
3795
3796 /*
3797 ** COMMAND: describe
3798 **
3799 ** Usage: %fossil describe ?VERSION? ?OPTIONS?
3800 **
3801 ** Provide a description of the given VERSION by showing a non-propagating
3802 ** tag of the youngest tagged ancestor, followed by the number of commits
3803 ** since that, and the short hash of VERSION. Only tags applied to a single
3804 ** check-in are considered.
3805 **
3806 ** If no VERSION is provided, describe the current checked-out version.
3807 **
3808 ** If VERSION and the found ancestor refer to the same commit, the last two
3809 ** components are omitted, unless --long is provided. When no fitting tagged
3810 ** ancestor is found, show only the short hash of VERSION.
3811 **
3812 ** Options:
3813 **
3814 ** --digits Display so many hex digits of the hash
3815 ** (default: the larger of 6 and the 'hash-digit' setting)
3816 ** -d|--dirty Show whether there are changes to be committed
3817 ** --long Always show all three components
3818 ** --match GLOB Consider only non-propagating tags matching GLOB
3819 */
3820 void describe_cmd(void){
3821 const char *zName;
3822 const char *zMatchGlob;
3823 const char *zDigits;
3824 int nDigits;
3825 int bDirtyFlag = 0;
3826 int bLongFlag = 0;
3827 CommitDescr descr;
3828
3829 db_find_and_open_repository(0,0);
3830 bDirtyFlag = find_option("dirty","d",0)!=0;
3831 bLongFlag = find_option("long","",0)!=0;
3832 zMatchGlob = find_option("match", 0, 1);
3833 zDigits = find_option("digits", 0, 1);
3834
3835 if ( !zDigits || ((nDigits=atoi(zDigits))==0) ){
3836 nDigits = hash_digits(0);
3837 }
3838
3839 /* We should be done with options.. */
3840 verify_all_options();
3841 if( g.argc<3 ){
3842 zName = "current";
3843 }else{
3844 zName = g.argv[2];
3845 }
3846
3847 if( bDirtyFlag ){
3848 if ( g.argc>=3 ) fossil_fatal("cannot use --dirty with specific checkin");
3849 }
3850
3851 switch( describe_commit(zName, zMatchGlob, &descr) ){
3852 case -1:
3853 fossil_fatal("commit %s does not exist", zName);
3854 break;
3855 case -2:
3856 fossil_fatal("commit %s is ambiguous", zName);
3857 break;
3858 case -3:
3859 fossil_print("%.*s%s\n", nDigits, descr.zCommitHash,
3860 bDirtyFlag ? (descr.isDirty ? "-dirty" : "") : "");
3861 break;
3862 case 0:
3863 if( descr.nCommitsSince==0 && !bLongFlag ){
3864 fossil_print("%s%s\n", descr.zRelTagname,
3865 bDirtyFlag ? (descr.isDirty ? "-dirty" : "") : "");
3866 }else{
3867 fossil_print("%s-%d-%.*s%s\n", descr.zRelTagname,
3868 descr.nCommitsSince, nDigits, descr.zCommitHash,
3869 bDirtyFlag ? (descr.isDirty ? "-dirty" : "") : "");
3870 }
3871 break;
3872 default:
3873 fossil_fatal("cannot describe commit");
3874 break;
3875 }
3876 }
3877
+8 -17
--- src/json.c
+++ src/json.c
@@ -1,8 +1,8 @@
11
#ifdef FOSSIL_ENABLE_JSON
22
/*
3
-** Copyright (c) 2011 D. Richard Hipp
3
+** Copyright (c) 2011-2022 D. Richard Hipp
44
**
55
** This program is free software; you can redistribute it and/or
66
** modify it under the terms of the Simplified BSD License (also
77
** known as the "2-Clause License" or "FreeBSD License".)
88
@@ -172,21 +172,10 @@
172172
Blob * b = (Blob*)pState;
173173
blob_append( b, (char const *)src, (int)n ) /* will die on OOM */;
174174
return 0;
175175
}
176176
177
-/*
178
-** Implements the cson_data_source_f() interface and reads input from
179
-** a fossil Blob object. pState must be-a (Blob*) populated with JSON
180
-** data.
181
-*/
182
-int cson_data_src_Blob(void * pState, void * dest, unsigned int * n){
183
- Blob * b = (Blob*)pState;
184
- *n = blob_read( b, dest, *n );
185
- return 0;
186
-}
187
-
188177
/*
189178
** Convenience wrapper around cson_output() which appends the output
190179
** to pDest. pOpt may be NULL, in which case g.json.outOpt will be used.
191180
*/
192181
int cson_output_Blob( cson_value const * pVal, Blob * pDest, cson_output_opt const * pOpt ){
@@ -204,12 +193,11 @@
204193
** On success a new JSON Object or Array is returned (owned by the
205194
** caller). On error NULL is returned.
206195
*/
207196
cson_value * cson_parse_Blob( Blob * pSrc, cson_parse_info * pInfo ){
208197
cson_value * root = NULL;
209
- blob_rewind( pSrc );
210
- cson_parse( &root, cson_data_src_Blob, pSrc, NULL, pInfo );
198
+ cson_parse_string( &root, blob_str(pSrc), blob_size(pSrc), NULL, pInfo );
211199
return root;
212200
}
213201
214202
/*
215203
** Implements the cson_data_dest_f() interface and outputs the data to
@@ -751,11 +739,11 @@
751739
** been called. In general, this function should be used sparingly,
752740
** e.g. from low-level support functions like fossil_warning() where
753741
** there is genuine uncertainty about whether (or not) the JSON setup
754742
** has already been called.
755743
*/
756
-int json_is_bootstrapped_early(){
744
+int json_is_bootstrapped_early(void){
757745
return ((g.json.gc.v != NULL) && (g.json.gc.a != NULL));
758746
}
759747
760748
/*
761749
** Initializes some JSON bits which need to be initialized relatively
@@ -770,11 +758,11 @@
770758
** up. e.g. it must not use cgi_parameter() and friends because this
771759
** must be called before those data are initialized.
772760
**
773761
** If called multiple times, calls after the first are a no-op.
774762
*/
775
-void json_bootstrap_early(){
763
+void json_bootstrap_early(void){
776764
cson_value * v;
777765
778766
if(g.json.gc.v!=NULL){
779767
/* Avoid multiple bootstrappings. */
780768
return;
@@ -1065,10 +1053,11 @@
10651053
because outOpt cannot (generically) be configured until after
10661054
POST-reading is finished.
10671055
*/
10681056
FILE * inFile = NULL;
10691057
char const * jfile = find_option("json-input",NULL,1);
1058
+ Blob json = BLOB_INITIALIZER;
10701059
if(!jfile || !*jfile){
10711060
break;
10721061
}
10731062
inFile = (0==strcmp("-",jfile))
10741063
? stdin
@@ -1077,12 +1066,14 @@
10771066
g.json.resultCode = FSL_JSON_E_FILE_OPEN_FAILED;
10781067
fossil_fatal("Could not open JSON file [%s].",jfile)
10791068
/* Does not return. */
10801069
;
10811070
}
1082
- cgi_parse_POST_JSON(inFile, 0);
1071
+ blob_read_from_channel(&json, inFile, -1);
10831072
fossil_fclose(inFile);
1073
+ cgi_parse_POST_JSON(&json);
1074
+ blob_reset(&json);
10841075
break;
10851076
}
10861077
10871078
/* g.json.reqPayload exists only to simplify some of our access to
10881079
the request payload. We currently only use this in the context of
10891080
--- src/json.c
+++ src/json.c
@@ -1,8 +1,8 @@
1 #ifdef FOSSIL_ENABLE_JSON
2 /*
3 ** Copyright (c) 2011 D. Richard Hipp
4 **
5 ** This program is free software; you can redistribute it and/or
6 ** modify it under the terms of the Simplified BSD License (also
7 ** known as the "2-Clause License" or "FreeBSD License".)
8
@@ -172,21 +172,10 @@
172 Blob * b = (Blob*)pState;
173 blob_append( b, (char const *)src, (int)n ) /* will die on OOM */;
174 return 0;
175 }
176
177 /*
178 ** Implements the cson_data_source_f() interface and reads input from
179 ** a fossil Blob object. pState must be-a (Blob*) populated with JSON
180 ** data.
181 */
182 int cson_data_src_Blob(void * pState, void * dest, unsigned int * n){
183 Blob * b = (Blob*)pState;
184 *n = blob_read( b, dest, *n );
185 return 0;
186 }
187
188 /*
189 ** Convenience wrapper around cson_output() which appends the output
190 ** to pDest. pOpt may be NULL, in which case g.json.outOpt will be used.
191 */
192 int cson_output_Blob( cson_value const * pVal, Blob * pDest, cson_output_opt const * pOpt ){
@@ -204,12 +193,11 @@
204 ** On success a new JSON Object or Array is returned (owned by the
205 ** caller). On error NULL is returned.
206 */
207 cson_value * cson_parse_Blob( Blob * pSrc, cson_parse_info * pInfo ){
208 cson_value * root = NULL;
209 blob_rewind( pSrc );
210 cson_parse( &root, cson_data_src_Blob, pSrc, NULL, pInfo );
211 return root;
212 }
213
214 /*
215 ** Implements the cson_data_dest_f() interface and outputs the data to
@@ -751,11 +739,11 @@
751 ** been called. In general, this function should be used sparingly,
752 ** e.g. from low-level support functions like fossil_warning() where
753 ** there is genuine uncertainty about whether (or not) the JSON setup
754 ** has already been called.
755 */
756 int json_is_bootstrapped_early(){
757 return ((g.json.gc.v != NULL) && (g.json.gc.a != NULL));
758 }
759
760 /*
761 ** Initializes some JSON bits which need to be initialized relatively
@@ -770,11 +758,11 @@
770 ** up. e.g. it must not use cgi_parameter() and friends because this
771 ** must be called before those data are initialized.
772 **
773 ** If called multiple times, calls after the first are a no-op.
774 */
775 void json_bootstrap_early(){
776 cson_value * v;
777
778 if(g.json.gc.v!=NULL){
779 /* Avoid multiple bootstrappings. */
780 return;
@@ -1065,10 +1053,11 @@
1065 because outOpt cannot (generically) be configured until after
1066 POST-reading is finished.
1067 */
1068 FILE * inFile = NULL;
1069 char const * jfile = find_option("json-input",NULL,1);
 
1070 if(!jfile || !*jfile){
1071 break;
1072 }
1073 inFile = (0==strcmp("-",jfile))
1074 ? stdin
@@ -1077,12 +1066,14 @@
1077 g.json.resultCode = FSL_JSON_E_FILE_OPEN_FAILED;
1078 fossil_fatal("Could not open JSON file [%s].",jfile)
1079 /* Does not return. */
1080 ;
1081 }
1082 cgi_parse_POST_JSON(inFile, 0);
1083 fossil_fclose(inFile);
 
 
1084 break;
1085 }
1086
1087 /* g.json.reqPayload exists only to simplify some of our access to
1088 the request payload. We currently only use this in the context of
1089
--- src/json.c
+++ src/json.c
@@ -1,8 +1,8 @@
1 #ifdef FOSSIL_ENABLE_JSON
2 /*
3 ** Copyright (c) 2011-2022 D. Richard Hipp
4 **
5 ** This program is free software; you can redistribute it and/or
6 ** modify it under the terms of the Simplified BSD License (also
7 ** known as the "2-Clause License" or "FreeBSD License".)
8
@@ -172,21 +172,10 @@
172 Blob * b = (Blob*)pState;
173 blob_append( b, (char const *)src, (int)n ) /* will die on OOM */;
174 return 0;
175 }
176
 
 
 
 
 
 
 
 
 
 
 
177 /*
178 ** Convenience wrapper around cson_output() which appends the output
179 ** to pDest. pOpt may be NULL, in which case g.json.outOpt will be used.
180 */
181 int cson_output_Blob( cson_value const * pVal, Blob * pDest, cson_output_opt const * pOpt ){
@@ -204,12 +193,11 @@
193 ** On success a new JSON Object or Array is returned (owned by the
194 ** caller). On error NULL is returned.
195 */
196 cson_value * cson_parse_Blob( Blob * pSrc, cson_parse_info * pInfo ){
197 cson_value * root = NULL;
198 cson_parse_string( &root, blob_str(pSrc), blob_size(pSrc), NULL, pInfo );
 
199 return root;
200 }
201
202 /*
203 ** Implements the cson_data_dest_f() interface and outputs the data to
@@ -751,11 +739,11 @@
739 ** been called. In general, this function should be used sparingly,
740 ** e.g. from low-level support functions like fossil_warning() where
741 ** there is genuine uncertainty about whether (or not) the JSON setup
742 ** has already been called.
743 */
744 int json_is_bootstrapped_early(void){
745 return ((g.json.gc.v != NULL) && (g.json.gc.a != NULL));
746 }
747
748 /*
749 ** Initializes some JSON bits which need to be initialized relatively
@@ -770,11 +758,11 @@
758 ** up. e.g. it must not use cgi_parameter() and friends because this
759 ** must be called before those data are initialized.
760 **
761 ** If called multiple times, calls after the first are a no-op.
762 */
763 void json_bootstrap_early(void){
764 cson_value * v;
765
766 if(g.json.gc.v!=NULL){
767 /* Avoid multiple bootstrappings. */
768 return;
@@ -1065,10 +1053,11 @@
1053 because outOpt cannot (generically) be configured until after
1054 POST-reading is finished.
1055 */
1056 FILE * inFile = NULL;
1057 char const * jfile = find_option("json-input",NULL,1);
1058 Blob json = BLOB_INITIALIZER;
1059 if(!jfile || !*jfile){
1060 break;
1061 }
1062 inFile = (0==strcmp("-",jfile))
1063 ? stdin
@@ -1077,12 +1066,14 @@
1066 g.json.resultCode = FSL_JSON_E_FILE_OPEN_FAILED;
1067 fossil_fatal("Could not open JSON file [%s].",jfile)
1068 /* Does not return. */
1069 ;
1070 }
1071 blob_read_from_channel(&json, inFile, -1);
1072 fossil_fclose(inFile);
1073 cgi_parse_POST_JSON(&json);
1074 blob_reset(&json);
1075 break;
1076 }
1077
1078 /* g.json.reqPayload exists only to simplify some of our access to
1079 the request payload. We currently only use this in the context of
1080
--- src/json_branch.c
+++ src/json_branch.c
@@ -306,14 +306,10 @@
306306
}
307307
308308
/* Commit */
309309
db_end_transaction(0);
310310
311
-#if 0 /* Do an autosync push, if requested */
312
- /* arugable for JSON mode? */
313
- if( !g.isHTTP && !isPrivate ) autosync(SYNC_PUSH);
314
-#endif
315311
return 0;
316312
}
317313
318314
319315
/*
320316
--- src/json_branch.c
+++ src/json_branch.c
@@ -306,14 +306,10 @@
306 }
307
308 /* Commit */
309 db_end_transaction(0);
310
311 #if 0 /* Do an autosync push, if requested */
312 /* arugable for JSON mode? */
313 if( !g.isHTTP && !isPrivate ) autosync(SYNC_PUSH);
314 #endif
315 return 0;
316 }
317
318
319 /*
320
--- src/json_branch.c
+++ src/json_branch.c
@@ -306,14 +306,10 @@
306 }
307
308 /* Commit */
309 db_end_transaction(0);
310
 
 
 
 
311 return 0;
312 }
313
314
315 /*
316
+27 -6
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -273,30 +273,51 @@
273273
return json_wiki_get_by_name_or_symname( zPageName, zSymName, contentFormat );
274274
}
275275
276276
/*
277277
** Implementation of /json/wiki/preview.
278
-**
279278
*/
280279
static cson_value * json_wiki_preview(){
281280
char const * zContent = NULL;
281
+ char const * zMime = NULL;
282
+ cson_string * sContent = NULL;
282283
cson_value * pay = NULL;
283284
Blob contentOrig = empty_blob;
284285
Blob contentHtml = empty_blob;
285286
if( !g.perm.WrWiki ){
286287
json_set_err(FSL_JSON_E_DENIED,
287288
"Requires 'k' access.");
288289
return NULL;
289290
}
290
- zContent = cson_string_cstr(cson_value_get_string(g.json.reqPayload.v));
291
- if(!zContent) {
291
+
292
+ if(g.json.reqPayload.o){
293
+ sContent = cson_value_get_string(
294
+ cson_object_get(g.json.reqPayload.o, "body"));
295
+ zMime = cson_value_get_cstr(cson_object_get(g.json.reqPayload.o,
296
+ "mimetype"));
297
+ }else{
298
+ sContent = cson_value_get_string(g.json.reqPayload.v);
299
+ }
300
+ if(!sContent) {
292301
json_set_err(FSL_JSON_E_MISSING_ARGS,
293
- "The 'payload' property must be a string containing the wiki code to preview.");
302
+ "The 'payload' property must be either a string containing the "
303
+ "Fossil wiki code to preview or an object with body + mimetype "
304
+ "properties.");
294305
return NULL;
295306
}
296
- blob_append( &contentOrig, zContent, (int)cson_string_length_bytes(cson_value_get_string(g.json.reqPayload.v)) );
297
- wiki_convert( &contentOrig, &contentHtml, 0 );
307
+ zContent = cson_string_cstr(sContent);
308
+ blob_append( &contentOrig, zContent, (int)cson_string_length_bytes(sContent) );
309
+ zMime = wiki_filter_mimetypes(zMime);
310
+ if( 0==fossil_strcmp(zMime, "text/x-markdown") ){
311
+ markdown_to_html(&contentOrig, 0, &contentHtml);
312
+ }else if( 0==fossil_strcmp(zMime, "text/plain") ){
313
+ blob_append(&contentHtml, "<pre class='textPlain'>", -1);
314
+ blob_append(&contentHtml, blob_str(&contentOrig), blob_size(&contentOrig));
315
+ blob_append(&contentHtml, "</pre>", -1);
316
+ }else{
317
+ wiki_convert( &contentOrig, &contentHtml, 0 );
318
+ }
298319
blob_reset( &contentOrig );
299320
pay = cson_value_new_string( blob_str(&contentHtml), (unsigned int)blob_size(&contentHtml));
300321
blob_reset( &contentHtml );
301322
return pay;
302323
}
303324
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -273,30 +273,51 @@
273 return json_wiki_get_by_name_or_symname( zPageName, zSymName, contentFormat );
274 }
275
276 /*
277 ** Implementation of /json/wiki/preview.
278 **
279 */
280 static cson_value * json_wiki_preview(){
281 char const * zContent = NULL;
 
 
282 cson_value * pay = NULL;
283 Blob contentOrig = empty_blob;
284 Blob contentHtml = empty_blob;
285 if( !g.perm.WrWiki ){
286 json_set_err(FSL_JSON_E_DENIED,
287 "Requires 'k' access.");
288 return NULL;
289 }
290 zContent = cson_string_cstr(cson_value_get_string(g.json.reqPayload.v));
291 if(!zContent) {
 
 
 
 
 
 
 
 
292 json_set_err(FSL_JSON_E_MISSING_ARGS,
293 "The 'payload' property must be a string containing the wiki code to preview.");
 
 
294 return NULL;
295 }
296 blob_append( &contentOrig, zContent, (int)cson_string_length_bytes(cson_value_get_string(g.json.reqPayload.v)) );
297 wiki_convert( &contentOrig, &contentHtml, 0 );
 
 
 
 
 
 
 
 
 
 
298 blob_reset( &contentOrig );
299 pay = cson_value_new_string( blob_str(&contentHtml), (unsigned int)blob_size(&contentHtml));
300 blob_reset( &contentHtml );
301 return pay;
302 }
303
--- src/json_wiki.c
+++ src/json_wiki.c
@@ -273,30 +273,51 @@
273 return json_wiki_get_by_name_or_symname( zPageName, zSymName, contentFormat );
274 }
275
276 /*
277 ** Implementation of /json/wiki/preview.
 
278 */
279 static cson_value * json_wiki_preview(){
280 char const * zContent = NULL;
281 char const * zMime = NULL;
282 cson_string * sContent = NULL;
283 cson_value * pay = NULL;
284 Blob contentOrig = empty_blob;
285 Blob contentHtml = empty_blob;
286 if( !g.perm.WrWiki ){
287 json_set_err(FSL_JSON_E_DENIED,
288 "Requires 'k' access.");
289 return NULL;
290 }
291
292 if(g.json.reqPayload.o){
293 sContent = cson_value_get_string(
294 cson_object_get(g.json.reqPayload.o, "body"));
295 zMime = cson_value_get_cstr(cson_object_get(g.json.reqPayload.o,
296 "mimetype"));
297 }else{
298 sContent = cson_value_get_string(g.json.reqPayload.v);
299 }
300 if(!sContent) {
301 json_set_err(FSL_JSON_E_MISSING_ARGS,
302 "The 'payload' property must be either a string containing the "
303 "Fossil wiki code to preview or an object with body + mimetype "
304 "properties.");
305 return NULL;
306 }
307 zContent = cson_string_cstr(sContent);
308 blob_append( &contentOrig, zContent, (int)cson_string_length_bytes(sContent) );
309 zMime = wiki_filter_mimetypes(zMime);
310 if( 0==fossil_strcmp(zMime, "text/x-markdown") ){
311 markdown_to_html(&contentOrig, 0, &contentHtml);
312 }else if( 0==fossil_strcmp(zMime, "text/plain") ){
313 blob_append(&contentHtml, "<pre class='textPlain'>", -1);
314 blob_append(&contentHtml, blob_str(&contentOrig), blob_size(&contentOrig));
315 blob_append(&contentHtml, "</pre>", -1);
316 }else{
317 wiki_convert( &contentOrig, &contentHtml, 0 );
318 }
319 blob_reset( &contentOrig );
320 pay = cson_value_new_string( blob_str(&contentHtml), (unsigned int)blob_size(&contentHtml));
321 blob_reset( &contentHtml );
322 return pay;
323 }
324
+11 -2
--- src/loadctrl.c
+++ src/loadctrl.c
@@ -45,16 +45,25 @@
4545
void loadavg_test_cmd(void){
4646
fossil_print("load-average: %f\n", load_average());
4747
}
4848
4949
/*
50
-** Abort the current operation of the load average of the host computer
51
-** is too high.
50
+** Abort the current page request if the load average of the host
51
+** computer is too high. Admin and Setup users are exempt from this
52
+** restriction.
5253
*/
5354
void load_control(void){
5455
double mxLoad = atof(db_get("max-loadavg", 0));
56
+#if 1
57
+ /* Disable this block only to test load restrictions */
5558
if( mxLoad<=0.0 || mxLoad>=load_average() ) return;
59
+
60
+ login_check_credentials();
61
+ if(g.perm.Admin || g.perm.Setup){
62
+ return;
63
+ }
64
+#endif
5665
5766
style_set_current_feature("test");
5867
style_header("Server Overload");
5968
@ <h2>The server load is currently too high.
6069
@ Please try again later.</h2>
6170
--- src/loadctrl.c
+++ src/loadctrl.c
@@ -45,16 +45,25 @@
45 void loadavg_test_cmd(void){
46 fossil_print("load-average: %f\n", load_average());
47 }
48
49 /*
50 ** Abort the current operation of the load average of the host computer
51 ** is too high.
 
52 */
53 void load_control(void){
54 double mxLoad = atof(db_get("max-loadavg", 0));
 
 
55 if( mxLoad<=0.0 || mxLoad>=load_average() ) return;
 
 
 
 
 
 
56
57 style_set_current_feature("test");
58 style_header("Server Overload");
59 @ <h2>The server load is currently too high.
60 @ Please try again later.</h2>
61
--- src/loadctrl.c
+++ src/loadctrl.c
@@ -45,16 +45,25 @@
45 void loadavg_test_cmd(void){
46 fossil_print("load-average: %f\n", load_average());
47 }
48
49 /*
50 ** Abort the current page request if the load average of the host
51 ** computer is too high. Admin and Setup users are exempt from this
52 ** restriction.
53 */
54 void load_control(void){
55 double mxLoad = atof(db_get("max-loadavg", 0));
56 #if 1
57 /* Disable this block only to test load restrictions */
58 if( mxLoad<=0.0 || mxLoad>=load_average() ) return;
59
60 login_check_credentials();
61 if(g.perm.Admin || g.perm.Setup){
62 return;
63 }
64 #endif
65
66 style_set_current_feature("test");
67 style_header("Server Overload");
68 @ <h2>The server load is currently too high.
69 @ Please try again later.</h2>
70
+9 -7
--- src/login.c
+++ src/login.c
@@ -985,10 +985,11 @@
985985
** g.userUid Database USER.UID value. Might be -1 for "nobody"
986986
** g.zLogin Database USER.LOGIN value. NULL for user "nobody"
987987
** g.perm Permissions granted to this user
988988
** g.anon Permissions that would be available to anonymous
989989
** g.isHuman True if the user is human, not a spider or robot
990
+** g.perm Populated based on user account's capabilities
990991
**
991992
*/
992993
void login_check_credentials(void){
993994
int uid = 0; /* User id */
994995
const char *zCookie; /* Text of the login cookie */
@@ -1178,17 +1179,18 @@
11781179
** enabled for this repository and make appropriate adjustments to the
11791180
** permission flags if it is. This should be done before the permissions
11801181
** are (potentially) copied to the anonymous permission set; otherwise,
11811182
** those will be out-of-sync.
11821183
*/
1183
- if( zCap[0]
1184
- && !g.perm.Hyperlink
1185
- && g.isHuman
1186
- && db_get_boolean("auto-hyperlink",1)
1187
- ){
1188
- g.perm.Hyperlink = 1;
1189
- g.javascriptHyperlink = 1;
1184
+ if( zCap[0] && !g.perm.Hyperlink && g.isHuman ){
1185
+ int autoLink = db_get_int("auto-hyperlink",1);
1186
+ if( autoLink==1 ){
1187
+ g.jsHref = 1;
1188
+ g.perm.Hyperlink = 1;
1189
+ }else if( autoLink==2 ){
1190
+ g.perm.Hyperlink = 1;
1191
+ }
11901192
}
11911193
11921194
/*
11931195
** At this point, the capabilities for the logged in user are not going
11941196
** to be modified anymore; therefore, we can copy them over to the ones
11951197
--- src/login.c
+++ src/login.c
@@ -985,10 +985,11 @@
985 ** g.userUid Database USER.UID value. Might be -1 for "nobody"
986 ** g.zLogin Database USER.LOGIN value. NULL for user "nobody"
987 ** g.perm Permissions granted to this user
988 ** g.anon Permissions that would be available to anonymous
989 ** g.isHuman True if the user is human, not a spider or robot
 
990 **
991 */
992 void login_check_credentials(void){
993 int uid = 0; /* User id */
994 const char *zCookie; /* Text of the login cookie */
@@ -1178,17 +1179,18 @@
1178 ** enabled for this repository and make appropriate adjustments to the
1179 ** permission flags if it is. This should be done before the permissions
1180 ** are (potentially) copied to the anonymous permission set; otherwise,
1181 ** those will be out-of-sync.
1182 */
1183 if( zCap[0]
1184 && !g.perm.Hyperlink
1185 && g.isHuman
1186 && db_get_boolean("auto-hyperlink",1)
1187 ){
1188 g.perm.Hyperlink = 1;
1189 g.javascriptHyperlink = 1;
 
1190 }
1191
1192 /*
1193 ** At this point, the capabilities for the logged in user are not going
1194 ** to be modified anymore; therefore, we can copy them over to the ones
1195
--- src/login.c
+++ src/login.c
@@ -985,10 +985,11 @@
985 ** g.userUid Database USER.UID value. Might be -1 for "nobody"
986 ** g.zLogin Database USER.LOGIN value. NULL for user "nobody"
987 ** g.perm Permissions granted to this user
988 ** g.anon Permissions that would be available to anonymous
989 ** g.isHuman True if the user is human, not a spider or robot
990 ** g.perm Populated based on user account's capabilities
991 **
992 */
993 void login_check_credentials(void){
994 int uid = 0; /* User id */
995 const char *zCookie; /* Text of the login cookie */
@@ -1178,17 +1179,18 @@
1179 ** enabled for this repository and make appropriate adjustments to the
1180 ** permission flags if it is. This should be done before the permissions
1181 ** are (potentially) copied to the anonymous permission set; otherwise,
1182 ** those will be out-of-sync.
1183 */
1184 if( zCap[0] && !g.perm.Hyperlink && g.isHuman ){
1185 int autoLink = db_get_int("auto-hyperlink",1);
1186 if( autoLink==1 ){
1187 g.jsHref = 1;
1188 g.perm.Hyperlink = 1;
1189 }else if( autoLink==2 ){
1190 g.perm.Hyperlink = 1;
1191 }
1192 }
1193
1194 /*
1195 ** At this point, the capabilities for the logged in user are not going
1196 ** to be modified anymore; therefore, we can copy them over to the ones
1197
+57 -49
--- src/main.c
+++ src/main.c
@@ -206,11 +206,11 @@
206206
int markPrivate; /* All new artifacts are private if true */
207207
char *ckinLockFail; /* Check-in lock failure received from server */
208208
int clockSkewSeen; /* True if clocks on client and server out of sync */
209209
int wikiFlags; /* Wiki conversion flags applied to %W */
210210
char isHTTP; /* True if server/CGI modes, else assume CLI. */
211
- char javascriptHyperlink; /* If true, set href= using script, not HTML */
211
+ char jsHref; /* If true, set href= using javascript, not HTML */
212212
Blob httpHeader; /* Complete text of the HTTP request header */
213213
UrlData url; /* Information about current URL */
214214
const char *zLogin; /* Login name. NULL or "" if not logged in. */
215215
const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */
216216
const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */
@@ -421,28 +421,20 @@
421421
unsigned int nArg; /* Number of new arguments */
422422
char *z; /* General use string pointer */
423423
char **newArgv; /* New expanded g.argv under construction */
424424
const char *zFileName; /* input file name */
425425
FILE *inFile; /* input FILE */
426
-#if defined(_WIN32)
427
- wchar_t buf[MAX_PATH];
428
-#endif
429426
430427
g.argc = argc;
431428
g.argv = argv;
432429
sqlite3_initialize();
433430
#if defined(_WIN32) && defined(BROKEN_MINGW_CMDLINE)
434431
for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
435432
#else
436433
for(i=0; i<g.argc; i++) g.argv[i] = fossil_path_to_utf8(g.argv[i]);
437434
#endif
438
-#if defined(_WIN32)
439
- GetModuleFileNameW(NULL, buf, MAX_PATH);
440
- g.nameOfExe = fossil_path_to_utf8(buf);
441
-#else
442
- g.nameOfExe = g.argv[0];
443
-#endif
435
+ g.nameOfExe = file_fullexename(g.argv[0]);
444436
for(i=1; i<g.argc-1; i++){
445437
z = g.argv[i];
446438
if( z[0]!='-' ) continue;
447439
z++;
448440
if( z[0]=='-' ) z++;
@@ -920,11 +912,11 @@
920912
fossil_exit(0);
921913
#endif
922914
}else if( rc==2 ){
923915
Blob couldbe;
924916
blob_init(&couldbe,0,0);
925
- dispatch_matching_names(zCmdName, &couldbe);
917
+ dispatch_matching_names(zCmdName, CMDFLAG_COMMAND, &couldbe);
926918
fossil_print("%s: ambiguous command prefix: %s\n"
927919
"%s: could be any of:%s\n"
928920
"%s: use \"help\" for more information\n",
929921
g.argv[0], zCmdName, g.argv[0], blob_str(&couldbe), g.argv[0]);
930922
fossil_exit(1);
@@ -1597,10 +1589,30 @@
15971589
cgi_redirect_with_status(zURL, 301, "Moved Permanently");
15981590
return 1;
15991591
}
16001592
return 0;
16011593
}
1594
+
1595
+/*
1596
+** Send a 404 Not Found reply
1597
+*/
1598
+void fossil_not_found_page(void){
1599
+#ifdef FOSSIL_ENABLE_JSON
1600
+ if(g.json.isJsonMode){
1601
+ json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1602
+ return;
1603
+ }
1604
+#endif
1605
+ @ <html><head>
1606
+ @ <meta name="viewport" \
1607
+ @ content="width=device-width, initial-scale=1.0">
1608
+ @ </head><body>
1609
+ @ <h1>Not Found</h1>
1610
+ @ </body>
1611
+ cgi_set_status(404, "Not Found");
1612
+ cgi_reply();
1613
+}
16021614
16031615
/*
16041616
** Preconditions:
16051617
**
16061618
** * Environment variables are set up according to the CGI standard.
@@ -1820,24 +1832,11 @@
18201832
&& repo_list_page() ){
18211833
/* Will return a list of repositories */
18221834
}else if( zNotFound ){
18231835
cgi_redirect(zNotFound);
18241836
}else{
1825
-#ifdef FOSSIL_ENABLE_JSON
1826
- if(g.json.isJsonMode){
1827
- json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1828
- return;
1829
- }
1830
-#endif
1831
- @ <html><head>
1832
- @ <meta name="viewport" \
1833
- @ content="width=device-width, initial-scale=1.0">
1834
- @ </head><body>
1835
- @ <h1>Not Found</h1>
1836
- @ </body>
1837
- cgi_set_status(404, "Not Found");
1838
- cgi_reply();
1837
+ fossil_not_found_page();
18391838
}
18401839
return;
18411840
}
18421841
break;
18431842
}
@@ -1875,11 +1874,10 @@
18751874
18761875
/* At this point, the appropriate repository database file will have
18771876
** been opened.
18781877
*/
18791878
1880
-
18811879
/*
18821880
** Check to see if the first term of PATH_INFO specifies an
18831881
** alternative skin. This will be the case if the first term of
18841882
** PATH_INFO begins with "draftN/" where N is an integer between 1
18851883
** and 9. If so, activate the skin associated with that draft.
@@ -1888,10 +1886,15 @@
18881886
&& zPathInfo[6]>='1' && zPathInfo[6]<='9'
18891887
&& (zPathInfo[7]=='/' || zPathInfo[7]==0)
18901888
){
18911889
int iSkin = zPathInfo[6] - '0';
18921890
char *zNewScript;
1891
+ if( db_int(0,"SELECT count(*) FROM config WHERE name GLOB 'draft%d-*'",
1892
+ iSkin)<5 ){
1893
+ fossil_not_found_page();
1894
+ fossil_exit(0);
1895
+ }
18931896
skin_use_draft(iSkin);
18941897
zNewScript = mprintf("%T/draft%d", P("SCRIPT_NAME"), iSkin);
18951898
if( g.zTop ) g.zTop = mprintf("%R/draft%d", iSkin);
18961899
if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
18971900
zPathInfo += 7;
@@ -2013,10 +2016,13 @@
20132016
@ <h1>Server Configuration Error</h1>
20142017
@ <p>The database schema on the server is out-of-date. Please ask
20152018
@ the administrator to run <b>fossil rebuild</b>.</p>
20162019
}
20172020
}else{
2021
+ if(0==(CMDFLAG_LDAVG_EXEMPT & pCmd->eCmdFlags)){
2022
+ load_control();
2023
+ }
20182024
#ifdef FOSSIL_ENABLE_JSON
20192025
static int jsonOnce = 0;
20202026
if( jsonOnce==0 && g.json.isJsonMode!=0 ){
20212027
assert(json_is_bootstrapped_early());
20222028
json_bootstrap_late();
@@ -2617,12 +2623,12 @@
26172623
**
26182624
** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
26192625
**
26202626
** Handle a single HTTP request appearing on stdin. The resulting webpage
26212627
** is delivered on stdout. This method is used to launch an HTTP request
2622
-** handler from inetd, for example. The argument is the name of the
2623
-** repository.
2628
+** handler from inetd, for example. The REPOSITORY argument is the name of
2629
+** the repository.
26242630
**
26252631
** If REPOSITORY is a directory that contains one or more repositories,
26262632
** either directly in REPOSITORY itself or in subdirectories, and
26272633
** with names of the form "*.fossil" then a prefix of the URL pathname
26282634
** selects from among the various repositories. If the pathname does
@@ -2633,31 +2639,24 @@
26332639
** and every "." must be surrounded on both sides by alphanumerics or else
26342640
** a 404 error is returned. Static content files in the directory are
26352641
** returned if they match comma-separate GLOB pattern specified by --files
26362642
** and do not match "*.fossil*" and have a well-known suffix.
26372643
**
2638
-** The --host option can be used to specify the hostname for the server.
2639
-** The --https option indicates that the request came from HTTPS rather
2640
-** than HTTP. If --nossl is given, then SSL connections will not be available,
2641
-** thus also no redirecting from http: to https: will take place.
2642
-**
2643
-** If the --localauth option is given, then automatic login is performed
2644
-** for requests coming from localhost, if the "localauth" setting is not
2645
-** enabled.
2646
-**
26472644
** Options:
26482645
** --acme Deliver files from the ".well-known" subdirectory
26492646
** --baseurl URL base URL (useful with reverse proxies)
26502647
** --cert FILE Use TLS (HTTPS) encryption with the certificate (the
26512648
** fullchain.pem) taken from FILE.
26522649
** --chroot DIR Use directory for chroot instead of repository path.
26532650
** --ckout-alias N Treat URIs of the form /doc/N/... as if they were
26542651
** /doc/ckout/...
2655
-** --extroot DIR document root for the /ext extension mechanism
2656
-** --files GLOB comma-separate glob patterns for static file to serve
2657
-** --host NAME specify hostname of the server
2658
-** --https signal a request coming in via https
2652
+** --extroot DIR Document root for the /ext extension mechanism
2653
+** --files GLOB Comma-separate glob patterns for static file to serve
2654
+** --host NAME DNS Hostname of the server
2655
+** --https The HTTP request originated from https but has already
2656
+** been decoded by a reverse proxy. Hence, URLs created
2657
+** by Fossil should use "https:" rather than "http:".
26592658
** --in FILE Take input from FILE instead of standard input
26602659
** --ipaddr ADDR Assume the request comes from the given IP address
26612660
** --jsmode MODE Determine how JavaScript is delivered with pages.
26622661
** Mode can be one of:
26632662
** inline All JavaScript is inserted inline at
@@ -2669,25 +2668,28 @@
26692668
** concatenate scripts together.
26702669
** Depending on the needs of any given page, inline
26712670
** and bundled modes might result in a single
26722671
** amalgamated script or several, but both approaches
26732672
** result in fewer HTTP requests than the separate mode.
2674
-** --localauth enable automatic login for local connections
2673
+** --localauth Connections from localhost are given "setup"
2674
+** privileges without having to log in.
26752675
** --mainmenu FILE Override the mainmenu config setting with the contents
26762676
** of the given file.
2677
-** --nocompress do not compress HTTP replies
2678
-** --nodelay omit backoffice processing if it would delay
2677
+** --nocompress Do not compress HTTP replies
2678
+** --nodelay Omit backoffice processing if it would delay
26792679
** process exit
2680
-** --nojail drop root privilege but do not enter the chroot jail
2681
-** --nossl signal that no SSL connections are available
2682
-** --notfound URL use URL as "HTTP 404, object not found" page.
2683
-** --out FILE write results to FILE instead of to standard output
2680
+** --nojail Drop root privilege but do not enter the chroot jail
2681
+** --nossl Do not do http: to https: redirects, regardless of
2682
+** the redirect-to-https setting.
2683
+** --notfound URL Use URL as the "HTTP 404, object not found" page.
2684
+** --out FILE Write the HTTP reply to FILE instead of to
2685
+** standard output
26842686
** --pkey FILE Read the private key used for TLS from FILE.
26852687
** --repolist If REPOSITORY is directory, URL "/" lists all repos
26862688
** --scgi Interpret input as SCGI rather than HTTP
26872689
** --skin LABEL Use override skin LABEL
2688
-** --th-trace trace TH1 execution (for debugging purposes)
2690
+** --th-trace Trace TH1 execution (for debugging purposes)
26892691
** --usepidkey Use saved encryption key from parent process. This is
26902692
** only necessary when using SEE on Windows.
26912693
**
26922694
** See also: [[cgi]], [[server]], [[winsrv]]
26932695
*/
@@ -2734,17 +2736,23 @@
27342736
backoffice_disable();
27352737
g.httpIn = fossil_fopen(zInFile, "rb");
27362738
if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
27372739
}else{
27382740
g.httpIn = stdin;
2741
+#if defined(_WIN32)
2742
+ _setmode(_fileno(stdin), _O_BINARY);
2743
+#endif
27392744
}
27402745
zOutFile = find_option("out",0,1);
27412746
if( zOutFile ){
27422747
g.httpOut = fossil_fopen(zOutFile, "wb");
27432748
if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
27442749
}else{
27452750
g.httpOut = stdout;
2751
+#if defined(_WIN32)
2752
+ _setmode(_fileno(stdout), _O_BINARY);
2753
+#endif
27462754
}
27472755
zIpAddr = find_option("ipaddr",0,1);
27482756
useSCGI = find_option("scgi", 0, 0)!=0;
27492757
zAltBase = find_option("baseurl", 0, 1);
27502758
if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
27512759
--- src/main.c
+++ src/main.c
@@ -206,11 +206,11 @@
206 int markPrivate; /* All new artifacts are private if true */
207 char *ckinLockFail; /* Check-in lock failure received from server */
208 int clockSkewSeen; /* True if clocks on client and server out of sync */
209 int wikiFlags; /* Wiki conversion flags applied to %W */
210 char isHTTP; /* True if server/CGI modes, else assume CLI. */
211 char javascriptHyperlink; /* If true, set href= using script, not HTML */
212 Blob httpHeader; /* Complete text of the HTTP request header */
213 UrlData url; /* Information about current URL */
214 const char *zLogin; /* Login name. NULL or "" if not logged in. */
215 const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */
216 const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */
@@ -421,28 +421,20 @@
421 unsigned int nArg; /* Number of new arguments */
422 char *z; /* General use string pointer */
423 char **newArgv; /* New expanded g.argv under construction */
424 const char *zFileName; /* input file name */
425 FILE *inFile; /* input FILE */
426 #if defined(_WIN32)
427 wchar_t buf[MAX_PATH];
428 #endif
429
430 g.argc = argc;
431 g.argv = argv;
432 sqlite3_initialize();
433 #if defined(_WIN32) && defined(BROKEN_MINGW_CMDLINE)
434 for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
435 #else
436 for(i=0; i<g.argc; i++) g.argv[i] = fossil_path_to_utf8(g.argv[i]);
437 #endif
438 #if defined(_WIN32)
439 GetModuleFileNameW(NULL, buf, MAX_PATH);
440 g.nameOfExe = fossil_path_to_utf8(buf);
441 #else
442 g.nameOfExe = g.argv[0];
443 #endif
444 for(i=1; i<g.argc-1; i++){
445 z = g.argv[i];
446 if( z[0]!='-' ) continue;
447 z++;
448 if( z[0]=='-' ) z++;
@@ -920,11 +912,11 @@
920 fossil_exit(0);
921 #endif
922 }else if( rc==2 ){
923 Blob couldbe;
924 blob_init(&couldbe,0,0);
925 dispatch_matching_names(zCmdName, &couldbe);
926 fossil_print("%s: ambiguous command prefix: %s\n"
927 "%s: could be any of:%s\n"
928 "%s: use \"help\" for more information\n",
929 g.argv[0], zCmdName, g.argv[0], blob_str(&couldbe), g.argv[0]);
930 fossil_exit(1);
@@ -1597,10 +1589,30 @@
1597 cgi_redirect_with_status(zURL, 301, "Moved Permanently");
1598 return 1;
1599 }
1600 return 0;
1601 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1602
1603 /*
1604 ** Preconditions:
1605 **
1606 ** * Environment variables are set up according to the CGI standard.
@@ -1820,24 +1832,11 @@
1820 && repo_list_page() ){
1821 /* Will return a list of repositories */
1822 }else if( zNotFound ){
1823 cgi_redirect(zNotFound);
1824 }else{
1825 #ifdef FOSSIL_ENABLE_JSON
1826 if(g.json.isJsonMode){
1827 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1828 return;
1829 }
1830 #endif
1831 @ <html><head>
1832 @ <meta name="viewport" \
1833 @ content="width=device-width, initial-scale=1.0">
1834 @ </head><body>
1835 @ <h1>Not Found</h1>
1836 @ </body>
1837 cgi_set_status(404, "Not Found");
1838 cgi_reply();
1839 }
1840 return;
1841 }
1842 break;
1843 }
@@ -1875,11 +1874,10 @@
1875
1876 /* At this point, the appropriate repository database file will have
1877 ** been opened.
1878 */
1879
1880
1881 /*
1882 ** Check to see if the first term of PATH_INFO specifies an
1883 ** alternative skin. This will be the case if the first term of
1884 ** PATH_INFO begins with "draftN/" where N is an integer between 1
1885 ** and 9. If so, activate the skin associated with that draft.
@@ -1888,10 +1886,15 @@
1888 && zPathInfo[6]>='1' && zPathInfo[6]<='9'
1889 && (zPathInfo[7]=='/' || zPathInfo[7]==0)
1890 ){
1891 int iSkin = zPathInfo[6] - '0';
1892 char *zNewScript;
 
 
 
 
 
1893 skin_use_draft(iSkin);
1894 zNewScript = mprintf("%T/draft%d", P("SCRIPT_NAME"), iSkin);
1895 if( g.zTop ) g.zTop = mprintf("%R/draft%d", iSkin);
1896 if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
1897 zPathInfo += 7;
@@ -2013,10 +2016,13 @@
2013 @ <h1>Server Configuration Error</h1>
2014 @ <p>The database schema on the server is out-of-date. Please ask
2015 @ the administrator to run <b>fossil rebuild</b>.</p>
2016 }
2017 }else{
 
 
 
2018 #ifdef FOSSIL_ENABLE_JSON
2019 static int jsonOnce = 0;
2020 if( jsonOnce==0 && g.json.isJsonMode!=0 ){
2021 assert(json_is_bootstrapped_early());
2022 json_bootstrap_late();
@@ -2617,12 +2623,12 @@
2617 **
2618 ** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
2619 **
2620 ** Handle a single HTTP request appearing on stdin. The resulting webpage
2621 ** is delivered on stdout. This method is used to launch an HTTP request
2622 ** handler from inetd, for example. The argument is the name of the
2623 ** repository.
2624 **
2625 ** If REPOSITORY is a directory that contains one or more repositories,
2626 ** either directly in REPOSITORY itself or in subdirectories, and
2627 ** with names of the form "*.fossil" then a prefix of the URL pathname
2628 ** selects from among the various repositories. If the pathname does
@@ -2633,31 +2639,24 @@
2633 ** and every "." must be surrounded on both sides by alphanumerics or else
2634 ** a 404 error is returned. Static content files in the directory are
2635 ** returned if they match comma-separate GLOB pattern specified by --files
2636 ** and do not match "*.fossil*" and have a well-known suffix.
2637 **
2638 ** The --host option can be used to specify the hostname for the server.
2639 ** The --https option indicates that the request came from HTTPS rather
2640 ** than HTTP. If --nossl is given, then SSL connections will not be available,
2641 ** thus also no redirecting from http: to https: will take place.
2642 **
2643 ** If the --localauth option is given, then automatic login is performed
2644 ** for requests coming from localhost, if the "localauth" setting is not
2645 ** enabled.
2646 **
2647 ** Options:
2648 ** --acme Deliver files from the ".well-known" subdirectory
2649 ** --baseurl URL base URL (useful with reverse proxies)
2650 ** --cert FILE Use TLS (HTTPS) encryption with the certificate (the
2651 ** fullchain.pem) taken from FILE.
2652 ** --chroot DIR Use directory for chroot instead of repository path.
2653 ** --ckout-alias N Treat URIs of the form /doc/N/... as if they were
2654 ** /doc/ckout/...
2655 ** --extroot DIR document root for the /ext extension mechanism
2656 ** --files GLOB comma-separate glob patterns for static file to serve
2657 ** --host NAME specify hostname of the server
2658 ** --https signal a request coming in via https
 
 
2659 ** --in FILE Take input from FILE instead of standard input
2660 ** --ipaddr ADDR Assume the request comes from the given IP address
2661 ** --jsmode MODE Determine how JavaScript is delivered with pages.
2662 ** Mode can be one of:
2663 ** inline All JavaScript is inserted inline at
@@ -2669,25 +2668,28 @@
2669 ** concatenate scripts together.
2670 ** Depending on the needs of any given page, inline
2671 ** and bundled modes might result in a single
2672 ** amalgamated script or several, but both approaches
2673 ** result in fewer HTTP requests than the separate mode.
2674 ** --localauth enable automatic login for local connections
 
2675 ** --mainmenu FILE Override the mainmenu config setting with the contents
2676 ** of the given file.
2677 ** --nocompress do not compress HTTP replies
2678 ** --nodelay omit backoffice processing if it would delay
2679 ** process exit
2680 ** --nojail drop root privilege but do not enter the chroot jail
2681 ** --nossl signal that no SSL connections are available
2682 ** --notfound URL use URL as "HTTP 404, object not found" page.
2683 ** --out FILE write results to FILE instead of to standard output
 
 
2684 ** --pkey FILE Read the private key used for TLS from FILE.
2685 ** --repolist If REPOSITORY is directory, URL "/" lists all repos
2686 ** --scgi Interpret input as SCGI rather than HTTP
2687 ** --skin LABEL Use override skin LABEL
2688 ** --th-trace trace TH1 execution (for debugging purposes)
2689 ** --usepidkey Use saved encryption key from parent process. This is
2690 ** only necessary when using SEE on Windows.
2691 **
2692 ** See also: [[cgi]], [[server]], [[winsrv]]
2693 */
@@ -2734,17 +2736,23 @@
2734 backoffice_disable();
2735 g.httpIn = fossil_fopen(zInFile, "rb");
2736 if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
2737 }else{
2738 g.httpIn = stdin;
 
 
 
2739 }
2740 zOutFile = find_option("out",0,1);
2741 if( zOutFile ){
2742 g.httpOut = fossil_fopen(zOutFile, "wb");
2743 if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
2744 }else{
2745 g.httpOut = stdout;
 
 
 
2746 }
2747 zIpAddr = find_option("ipaddr",0,1);
2748 useSCGI = find_option("scgi", 0, 0)!=0;
2749 zAltBase = find_option("baseurl", 0, 1);
2750 if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
2751
--- src/main.c
+++ src/main.c
@@ -206,11 +206,11 @@
206 int markPrivate; /* All new artifacts are private if true */
207 char *ckinLockFail; /* Check-in lock failure received from server */
208 int clockSkewSeen; /* True if clocks on client and server out of sync */
209 int wikiFlags; /* Wiki conversion flags applied to %W */
210 char isHTTP; /* True if server/CGI modes, else assume CLI. */
211 char jsHref; /* If true, set href= using javascript, not HTML */
212 Blob httpHeader; /* Complete text of the HTTP request header */
213 UrlData url; /* Information about current URL */
214 const char *zLogin; /* Login name. NULL or "" if not logged in. */
215 const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */
216 const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */
@@ -421,28 +421,20 @@
421 unsigned int nArg; /* Number of new arguments */
422 char *z; /* General use string pointer */
423 char **newArgv; /* New expanded g.argv under construction */
424 const char *zFileName; /* input file name */
425 FILE *inFile; /* input FILE */
 
 
 
426
427 g.argc = argc;
428 g.argv = argv;
429 sqlite3_initialize();
430 #if defined(_WIN32) && defined(BROKEN_MINGW_CMDLINE)
431 for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
432 #else
433 for(i=0; i<g.argc; i++) g.argv[i] = fossil_path_to_utf8(g.argv[i]);
434 #endif
435 g.nameOfExe = file_fullexename(g.argv[0]);
 
 
 
 
 
436 for(i=1; i<g.argc-1; i++){
437 z = g.argv[i];
438 if( z[0]!='-' ) continue;
439 z++;
440 if( z[0]=='-' ) z++;
@@ -920,11 +912,11 @@
912 fossil_exit(0);
913 #endif
914 }else if( rc==2 ){
915 Blob couldbe;
916 blob_init(&couldbe,0,0);
917 dispatch_matching_names(zCmdName, CMDFLAG_COMMAND, &couldbe);
918 fossil_print("%s: ambiguous command prefix: %s\n"
919 "%s: could be any of:%s\n"
920 "%s: use \"help\" for more information\n",
921 g.argv[0], zCmdName, g.argv[0], blob_str(&couldbe), g.argv[0]);
922 fossil_exit(1);
@@ -1597,10 +1589,30 @@
1589 cgi_redirect_with_status(zURL, 301, "Moved Permanently");
1590 return 1;
1591 }
1592 return 0;
1593 }
1594
1595 /*
1596 ** Send a 404 Not Found reply
1597 */
1598 void fossil_not_found_page(void){
1599 #ifdef FOSSIL_ENABLE_JSON
1600 if(g.json.isJsonMode){
1601 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1602 return;
1603 }
1604 #endif
1605 @ <html><head>
1606 @ <meta name="viewport" \
1607 @ content="width=device-width, initial-scale=1.0">
1608 @ </head><body>
1609 @ <h1>Not Found</h1>
1610 @ </body>
1611 cgi_set_status(404, "Not Found");
1612 cgi_reply();
1613 }
1614
1615 /*
1616 ** Preconditions:
1617 **
1618 ** * Environment variables are set up according to the CGI standard.
@@ -1820,24 +1832,11 @@
1832 && repo_list_page() ){
1833 /* Will return a list of repositories */
1834 }else if( zNotFound ){
1835 cgi_redirect(zNotFound);
1836 }else{
1837 fossil_not_found_page();
 
 
 
 
 
 
 
 
 
 
 
 
 
1838 }
1839 return;
1840 }
1841 break;
1842 }
@@ -1875,11 +1874,10 @@
1874
1875 /* At this point, the appropriate repository database file will have
1876 ** been opened.
1877 */
1878
 
1879 /*
1880 ** Check to see if the first term of PATH_INFO specifies an
1881 ** alternative skin. This will be the case if the first term of
1882 ** PATH_INFO begins with "draftN/" where N is an integer between 1
1883 ** and 9. If so, activate the skin associated with that draft.
@@ -1888,10 +1886,15 @@
1886 && zPathInfo[6]>='1' && zPathInfo[6]<='9'
1887 && (zPathInfo[7]=='/' || zPathInfo[7]==0)
1888 ){
1889 int iSkin = zPathInfo[6] - '0';
1890 char *zNewScript;
1891 if( db_int(0,"SELECT count(*) FROM config WHERE name GLOB 'draft%d-*'",
1892 iSkin)<5 ){
1893 fossil_not_found_page();
1894 fossil_exit(0);
1895 }
1896 skin_use_draft(iSkin);
1897 zNewScript = mprintf("%T/draft%d", P("SCRIPT_NAME"), iSkin);
1898 if( g.zTop ) g.zTop = mprintf("%R/draft%d", iSkin);
1899 if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
1900 zPathInfo += 7;
@@ -2013,10 +2016,13 @@
2016 @ <h1>Server Configuration Error</h1>
2017 @ <p>The database schema on the server is out-of-date. Please ask
2018 @ the administrator to run <b>fossil rebuild</b>.</p>
2019 }
2020 }else{
2021 if(0==(CMDFLAG_LDAVG_EXEMPT & pCmd->eCmdFlags)){
2022 load_control();
2023 }
2024 #ifdef FOSSIL_ENABLE_JSON
2025 static int jsonOnce = 0;
2026 if( jsonOnce==0 && g.json.isJsonMode!=0 ){
2027 assert(json_is_bootstrapped_early());
2028 json_bootstrap_late();
@@ -2617,12 +2623,12 @@
2623 **
2624 ** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
2625 **
2626 ** Handle a single HTTP request appearing on stdin. The resulting webpage
2627 ** is delivered on stdout. This method is used to launch an HTTP request
2628 ** handler from inetd, for example. The REPOSITORY argument is the name of
2629 ** the repository.
2630 **
2631 ** If REPOSITORY is a directory that contains one or more repositories,
2632 ** either directly in REPOSITORY itself or in subdirectories, and
2633 ** with names of the form "*.fossil" then a prefix of the URL pathname
2634 ** selects from among the various repositories. If the pathname does
@@ -2633,31 +2639,24 @@
2639 ** and every "." must be surrounded on both sides by alphanumerics or else
2640 ** a 404 error is returned. Static content files in the directory are
2641 ** returned if they match comma-separate GLOB pattern specified by --files
2642 ** and do not match "*.fossil*" and have a well-known suffix.
2643 **
 
 
 
 
 
 
 
 
 
2644 ** Options:
2645 ** --acme Deliver files from the ".well-known" subdirectory
2646 ** --baseurl URL base URL (useful with reverse proxies)
2647 ** --cert FILE Use TLS (HTTPS) encryption with the certificate (the
2648 ** fullchain.pem) taken from FILE.
2649 ** --chroot DIR Use directory for chroot instead of repository path.
2650 ** --ckout-alias N Treat URIs of the form /doc/N/... as if they were
2651 ** /doc/ckout/...
2652 ** --extroot DIR Document root for the /ext extension mechanism
2653 ** --files GLOB Comma-separate glob patterns for static file to serve
2654 ** --host NAME DNS Hostname of the server
2655 ** --https The HTTP request originated from https but has already
2656 ** been decoded by a reverse proxy. Hence, URLs created
2657 ** by Fossil should use "https:" rather than "http:".
2658 ** --in FILE Take input from FILE instead of standard input
2659 ** --ipaddr ADDR Assume the request comes from the given IP address
2660 ** --jsmode MODE Determine how JavaScript is delivered with pages.
2661 ** Mode can be one of:
2662 ** inline All JavaScript is inserted inline at
@@ -2669,25 +2668,28 @@
2668 ** concatenate scripts together.
2669 ** Depending on the needs of any given page, inline
2670 ** and bundled modes might result in a single
2671 ** amalgamated script or several, but both approaches
2672 ** result in fewer HTTP requests than the separate mode.
2673 ** --localauth Connections from localhost are given "setup"
2674 ** privileges without having to log in.
2675 ** --mainmenu FILE Override the mainmenu config setting with the contents
2676 ** of the given file.
2677 ** --nocompress Do not compress HTTP replies
2678 ** --nodelay Omit backoffice processing if it would delay
2679 ** process exit
2680 ** --nojail Drop root privilege but do not enter the chroot jail
2681 ** --nossl Do not do http: to https: redirects, regardless of
2682 ** the redirect-to-https setting.
2683 ** --notfound URL Use URL as the "HTTP 404, object not found" page.
2684 ** --out FILE Write the HTTP reply to FILE instead of to
2685 ** standard output
2686 ** --pkey FILE Read the private key used for TLS from FILE.
2687 ** --repolist If REPOSITORY is directory, URL "/" lists all repos
2688 ** --scgi Interpret input as SCGI rather than HTTP
2689 ** --skin LABEL Use override skin LABEL
2690 ** --th-trace Trace TH1 execution (for debugging purposes)
2691 ** --usepidkey Use saved encryption key from parent process. This is
2692 ** only necessary when using SEE on Windows.
2693 **
2694 ** See also: [[cgi]], [[server]], [[winsrv]]
2695 */
@@ -2734,17 +2736,23 @@
2736 backoffice_disable();
2737 g.httpIn = fossil_fopen(zInFile, "rb");
2738 if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
2739 }else{
2740 g.httpIn = stdin;
2741 #if defined(_WIN32)
2742 _setmode(_fileno(stdin), _O_BINARY);
2743 #endif
2744 }
2745 zOutFile = find_option("out",0,1);
2746 if( zOutFile ){
2747 g.httpOut = fossil_fopen(zOutFile, "wb");
2748 if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
2749 }else{
2750 g.httpOut = stdout;
2751 #if defined(_WIN32)
2752 _setmode(_fileno(stdout), _O_BINARY);
2753 #endif
2754 }
2755 zIpAddr = find_option("ipaddr",0,1);
2756 useSCGI = find_option("scgi", 0, 0)!=0;
2757 zAltBase = find_option("baseurl", 0, 1);
2758 if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
2759
+57 -49
--- src/main.c
+++ src/main.c
@@ -206,11 +206,11 @@
206206
int markPrivate; /* All new artifacts are private if true */
207207
char *ckinLockFail; /* Check-in lock failure received from server */
208208
int clockSkewSeen; /* True if clocks on client and server out of sync */
209209
int wikiFlags; /* Wiki conversion flags applied to %W */
210210
char isHTTP; /* True if server/CGI modes, else assume CLI. */
211
- char javascriptHyperlink; /* If true, set href= using script, not HTML */
211
+ char jsHref; /* If true, set href= using javascript, not HTML */
212212
Blob httpHeader; /* Complete text of the HTTP request header */
213213
UrlData url; /* Information about current URL */
214214
const char *zLogin; /* Login name. NULL or "" if not logged in. */
215215
const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */
216216
const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */
@@ -421,28 +421,20 @@
421421
unsigned int nArg; /* Number of new arguments */
422422
char *z; /* General use string pointer */
423423
char **newArgv; /* New expanded g.argv under construction */
424424
const char *zFileName; /* input file name */
425425
FILE *inFile; /* input FILE */
426
-#if defined(_WIN32)
427
- wchar_t buf[MAX_PATH];
428
-#endif
429426
430427
g.argc = argc;
431428
g.argv = argv;
432429
sqlite3_initialize();
433430
#if defined(_WIN32) && defined(BROKEN_MINGW_CMDLINE)
434431
for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
435432
#else
436433
for(i=0; i<g.argc; i++) g.argv[i] = fossil_path_to_utf8(g.argv[i]);
437434
#endif
438
-#if defined(_WIN32)
439
- GetModuleFileNameW(NULL, buf, MAX_PATH);
440
- g.nameOfExe = fossil_path_to_utf8(buf);
441
-#else
442
- g.nameOfExe = g.argv[0];
443
-#endif
435
+ g.nameOfExe = file_fullexename(g.argv[0]);
444436
for(i=1; i<g.argc-1; i++){
445437
z = g.argv[i];
446438
if( z[0]!='-' ) continue;
447439
z++;
448440
if( z[0]=='-' ) z++;
@@ -920,11 +912,11 @@
920912
fossil_exit(0);
921913
#endif
922914
}else if( rc==2 ){
923915
Blob couldbe;
924916
blob_init(&couldbe,0,0);
925
- dispatch_matching_names(zCmdName, &couldbe);
917
+ dispatch_matching_names(zCmdName, CMDFLAG_COMMAND, &couldbe);
926918
fossil_print("%s: ambiguous command prefix: %s\n"
927919
"%s: could be any of:%s\n"
928920
"%s: use \"help\" for more information\n",
929921
g.argv[0], zCmdName, g.argv[0], blob_str(&couldbe), g.argv[0]);
930922
fossil_exit(1);
@@ -1597,10 +1589,30 @@
15971589
cgi_redirect_with_status(zURL, 301, "Moved Permanently");
15981590
return 1;
15991591
}
16001592
return 0;
16011593
}
1594
+
1595
+/*
1596
+** Send a 404 Not Found reply
1597
+*/
1598
+void fossil_not_found_page(void){
1599
+#ifdef FOSSIL_ENABLE_JSON
1600
+ if(g.json.isJsonMode){
1601
+ json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1602
+ return;
1603
+ }
1604
+#endif
1605
+ @ <html><head>
1606
+ @ <meta name="viewport" \
1607
+ @ content="width=device-width, initial-scale=1.0">
1608
+ @ </head><body>
1609
+ @ <h1>Not Found</h1>
1610
+ @ </body>
1611
+ cgi_set_status(404, "Not Found");
1612
+ cgi_reply();
1613
+}
16021614
16031615
/*
16041616
** Preconditions:
16051617
**
16061618
** * Environment variables are set up according to the CGI standard.
@@ -1820,24 +1832,11 @@
18201832
&& repo_list_page() ){
18211833
/* Will return a list of repositories */
18221834
}else if( zNotFound ){
18231835
cgi_redirect(zNotFound);
18241836
}else{
1825
-#ifdef FOSSIL_ENABLE_JSON
1826
- if(g.json.isJsonMode){
1827
- json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1828
- return;
1829
- }
1830
-#endif
1831
- @ <html><head>
1832
- @ <meta name="viewport" \
1833
- @ content="width=device-width, initial-scale=1.0">
1834
- @ </head><body>
1835
- @ <h1>Not Found</h1>
1836
- @ </body>
1837
- cgi_set_status(404, "Not Found");
1838
- cgi_reply();
1837
+ fossil_not_found_page();
18391838
}
18401839
return;
18411840
}
18421841
break;
18431842
}
@@ -1875,11 +1874,10 @@
18751874
18761875
/* At this point, the appropriate repository database file will have
18771876
** been opened.
18781877
*/
18791878
1880
-
18811879
/*
18821880
** Check to see if the first term of PATH_INFO specifies an
18831881
** alternative skin. This will be the case if the first term of
18841882
** PATH_INFO begins with "draftN/" where N is an integer between 1
18851883
** and 9. If so, activate the skin associated with that draft.
@@ -1888,10 +1886,15 @@
18881886
&& zPathInfo[6]>='1' && zPathInfo[6]<='9'
18891887
&& (zPathInfo[7]=='/' || zPathInfo[7]==0)
18901888
){
18911889
int iSkin = zPathInfo[6] - '0';
18921890
char *zNewScript;
1891
+ if( db_int(0,"SELECT count(*) FROM config WHERE name GLOB 'draft%d-*'",
1892
+ iSkin)<5 ){
1893
+ fossil_not_found_page();
1894
+ fossil_exit(0);
1895
+ }
18931896
skin_use_draft(iSkin);
18941897
zNewScript = mprintf("%T/draft%d", P("SCRIPT_NAME"), iSkin);
18951898
if( g.zTop ) g.zTop = mprintf("%R/draft%d", iSkin);
18961899
if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
18971900
zPathInfo += 7;
@@ -2013,10 +2016,13 @@
20132016
@ <h1>Server Configuration Error</h1>
20142017
@ <p>The database schema on the server is out-of-date. Please ask
20152018
@ the administrator to run <b>fossil rebuild</b>.</p>
20162019
}
20172020
}else{
2021
+ if(0==(CMDFLAG_LDAVG_EXEMPT & pCmd->eCmdFlags)){
2022
+ load_control();
2023
+ }
20182024
#ifdef FOSSIL_ENABLE_JSON
20192025
static int jsonOnce = 0;
20202026
if( jsonOnce==0 && g.json.isJsonMode!=0 ){
20212027
assert(json_is_bootstrapped_early());
20222028
json_bootstrap_late();
@@ -2617,12 +2623,12 @@
26172623
**
26182624
** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
26192625
**
26202626
** Handle a single HTTP request appearing on stdin. The resulting webpage
26212627
** is delivered on stdout. This method is used to launch an HTTP request
2622
-** handler from inetd, for example. The argument is the name of the
2623
-** repository.
2628
+** handler from inetd, for example. The REPOSITORY argument is the name of
2629
+** the repository.
26242630
**
26252631
** If REPOSITORY is a directory that contains one or more repositories,
26262632
** either directly in REPOSITORY itself or in subdirectories, and
26272633
** with names of the form "*.fossil" then a prefix of the URL pathname
26282634
** selects from among the various repositories. If the pathname does
@@ -2633,31 +2639,24 @@
26332639
** and every "." must be surrounded on both sides by alphanumerics or else
26342640
** a 404 error is returned. Static content files in the directory are
26352641
** returned if they match comma-separate GLOB pattern specified by --files
26362642
** and do not match "*.fossil*" and have a well-known suffix.
26372643
**
2638
-** The --host option can be used to specify the hostname for the server.
2639
-** The --https option indicates that the request came from HTTPS rather
2640
-** than HTTP. If --nossl is given, then SSL connections will not be available,
2641
-** thus also no redirecting from http: to https: will take place.
2642
-**
2643
-** If the --localauth option is given, then automatic login is performed
2644
-** for requests coming from localhost, if the "localauth" setting is not
2645
-** enabled.
2646
-**
26472644
** Options:
26482645
** --acme Deliver files from the ".well-known" subdirectory
26492646
** --baseurl URL base URL (useful with reverse proxies)
26502647
** --cert FILE Use TLS (HTTPS) encryption with the certificate (the
26512648
** fullchain.pem) taken from FILE.
26522649
** --chroot DIR Use directory for chroot instead of repository path.
26532650
** --ckout-alias N Treat URIs of the form /doc/N/... as if they were
26542651
** /doc/ckout/...
2655
-** --extroot DIR document root for the /ext extension mechanism
2656
-** --files GLOB comma-separate glob patterns for static file to serve
2657
-** --host NAME specify hostname of the server
2658
-** --https signal a request coming in via https
2652
+** --extroot DIR Document root for the /ext extension mechanism
2653
+** --files GLOB Comma-separate glob patterns for static file to serve
2654
+** --host NAME DNS Hostname of the server
2655
+** --https The HTTP request originated from https but has already
2656
+** been decoded by a reverse proxy. Hence, URLs created
2657
+** by Fossil should use "https:" rather than "http:".
26592658
** --in FILE Take input from FILE instead of standard input
26602659
** --ipaddr ADDR Assume the request comes from the given IP address
26612660
** --jsmode MODE Determine how JavaScript is delivered with pages.
26622661
** Mode can be one of:
26632662
** inline All JavaScript is inserted inline at
@@ -2669,25 +2668,28 @@
26692668
** concatenate scripts together.
26702669
** Depending on the needs of any given page, inline
26712670
** and bundled modes might result in a single
26722671
** amalgamated script or several, but both approaches
26732672
** result in fewer HTTP requests than the separate mode.
2674
-** --localauth enable automatic login for local connections
2673
+** --localauth Connections from localhost are given "setup"
2674
+** privileges without having to log in.
26752675
** --mainmenu FILE Override the mainmenu config setting with the contents
26762676
** of the given file.
2677
-** --nocompress do not compress HTTP replies
2678
-** --nodelay omit backoffice processing if it would delay
2677
+** --nocompress Do not compress HTTP replies
2678
+** --nodelay Omit backoffice processing if it would delay
26792679
** process exit
2680
-** --nojail drop root privilege but do not enter the chroot jail
2681
-** --nossl signal that no SSL connections are available
2682
-** --notfound URL use URL as "HTTP 404, object not found" page.
2683
-** --out FILE write results to FILE instead of to standard output
2680
+** --nojail Drop root privilege but do not enter the chroot jail
2681
+** --nossl Do not do http: to https: redirects, regardless of
2682
+** the redirect-to-https setting.
2683
+** --notfound URL Use URL as the "HTTP 404, object not found" page.
2684
+** --out FILE Write the HTTP reply to FILE instead of to
2685
+** standard output
26842686
** --pkey FILE Read the private key used for TLS from FILE.
26852687
** --repolist If REPOSITORY is directory, URL "/" lists all repos
26862688
** --scgi Interpret input as SCGI rather than HTTP
26872689
** --skin LABEL Use override skin LABEL
2688
-** --th-trace trace TH1 execution (for debugging purposes)
2690
+** --th-trace Trace TH1 execution (for debugging purposes)
26892691
** --usepidkey Use saved encryption key from parent process. This is
26902692
** only necessary when using SEE on Windows.
26912693
**
26922694
** See also: [[cgi]], [[server]], [[winsrv]]
26932695
*/
@@ -2734,17 +2736,23 @@
27342736
backoffice_disable();
27352737
g.httpIn = fossil_fopen(zInFile, "rb");
27362738
if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
27372739
}else{
27382740
g.httpIn = stdin;
2741
+#if defined(_WIN32)
2742
+ _setmode(_fileno(stdin), _O_BINARY);
2743
+#endif
27392744
}
27402745
zOutFile = find_option("out",0,1);
27412746
if( zOutFile ){
27422747
g.httpOut = fossil_fopen(zOutFile, "wb");
27432748
if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
27442749
}else{
27452750
g.httpOut = stdout;
2751
+#if defined(_WIN32)
2752
+ _setmode(_fileno(stdout), _O_BINARY);
2753
+#endif
27462754
}
27472755
zIpAddr = find_option("ipaddr",0,1);
27482756
useSCGI = find_option("scgi", 0, 0)!=0;
27492757
zAltBase = find_option("baseurl", 0, 1);
27502758
if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
27512759
--- src/main.c
+++ src/main.c
@@ -206,11 +206,11 @@
206 int markPrivate; /* All new artifacts are private if true */
207 char *ckinLockFail; /* Check-in lock failure received from server */
208 int clockSkewSeen; /* True if clocks on client and server out of sync */
209 int wikiFlags; /* Wiki conversion flags applied to %W */
210 char isHTTP; /* True if server/CGI modes, else assume CLI. */
211 char javascriptHyperlink; /* If true, set href= using script, not HTML */
212 Blob httpHeader; /* Complete text of the HTTP request header */
213 UrlData url; /* Information about current URL */
214 const char *zLogin; /* Login name. NULL or "" if not logged in. */
215 const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */
216 const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */
@@ -421,28 +421,20 @@
421 unsigned int nArg; /* Number of new arguments */
422 char *z; /* General use string pointer */
423 char **newArgv; /* New expanded g.argv under construction */
424 const char *zFileName; /* input file name */
425 FILE *inFile; /* input FILE */
426 #if defined(_WIN32)
427 wchar_t buf[MAX_PATH];
428 #endif
429
430 g.argc = argc;
431 g.argv = argv;
432 sqlite3_initialize();
433 #if defined(_WIN32) && defined(BROKEN_MINGW_CMDLINE)
434 for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
435 #else
436 for(i=0; i<g.argc; i++) g.argv[i] = fossil_path_to_utf8(g.argv[i]);
437 #endif
438 #if defined(_WIN32)
439 GetModuleFileNameW(NULL, buf, MAX_PATH);
440 g.nameOfExe = fossil_path_to_utf8(buf);
441 #else
442 g.nameOfExe = g.argv[0];
443 #endif
444 for(i=1; i<g.argc-1; i++){
445 z = g.argv[i];
446 if( z[0]!='-' ) continue;
447 z++;
448 if( z[0]=='-' ) z++;
@@ -920,11 +912,11 @@
920 fossil_exit(0);
921 #endif
922 }else if( rc==2 ){
923 Blob couldbe;
924 blob_init(&couldbe,0,0);
925 dispatch_matching_names(zCmdName, &couldbe);
926 fossil_print("%s: ambiguous command prefix: %s\n"
927 "%s: could be any of:%s\n"
928 "%s: use \"help\" for more information\n",
929 g.argv[0], zCmdName, g.argv[0], blob_str(&couldbe), g.argv[0]);
930 fossil_exit(1);
@@ -1597,10 +1589,30 @@
1597 cgi_redirect_with_status(zURL, 301, "Moved Permanently");
1598 return 1;
1599 }
1600 return 0;
1601 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1602
1603 /*
1604 ** Preconditions:
1605 **
1606 ** * Environment variables are set up according to the CGI standard.
@@ -1820,24 +1832,11 @@
1820 && repo_list_page() ){
1821 /* Will return a list of repositories */
1822 }else if( zNotFound ){
1823 cgi_redirect(zNotFound);
1824 }else{
1825 #ifdef FOSSIL_ENABLE_JSON
1826 if(g.json.isJsonMode){
1827 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1828 return;
1829 }
1830 #endif
1831 @ <html><head>
1832 @ <meta name="viewport" \
1833 @ content="width=device-width, initial-scale=1.0">
1834 @ </head><body>
1835 @ <h1>Not Found</h1>
1836 @ </body>
1837 cgi_set_status(404, "Not Found");
1838 cgi_reply();
1839 }
1840 return;
1841 }
1842 break;
1843 }
@@ -1875,11 +1874,10 @@
1875
1876 /* At this point, the appropriate repository database file will have
1877 ** been opened.
1878 */
1879
1880
1881 /*
1882 ** Check to see if the first term of PATH_INFO specifies an
1883 ** alternative skin. This will be the case if the first term of
1884 ** PATH_INFO begins with "draftN/" where N is an integer between 1
1885 ** and 9. If so, activate the skin associated with that draft.
@@ -1888,10 +1886,15 @@
1888 && zPathInfo[6]>='1' && zPathInfo[6]<='9'
1889 && (zPathInfo[7]=='/' || zPathInfo[7]==0)
1890 ){
1891 int iSkin = zPathInfo[6] - '0';
1892 char *zNewScript;
 
 
 
 
 
1893 skin_use_draft(iSkin);
1894 zNewScript = mprintf("%T/draft%d", P("SCRIPT_NAME"), iSkin);
1895 if( g.zTop ) g.zTop = mprintf("%R/draft%d", iSkin);
1896 if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
1897 zPathInfo += 7;
@@ -2013,10 +2016,13 @@
2013 @ <h1>Server Configuration Error</h1>
2014 @ <p>The database schema on the server is out-of-date. Please ask
2015 @ the administrator to run <b>fossil rebuild</b>.</p>
2016 }
2017 }else{
 
 
 
2018 #ifdef FOSSIL_ENABLE_JSON
2019 static int jsonOnce = 0;
2020 if( jsonOnce==0 && g.json.isJsonMode!=0 ){
2021 assert(json_is_bootstrapped_early());
2022 json_bootstrap_late();
@@ -2617,12 +2623,12 @@
2617 **
2618 ** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
2619 **
2620 ** Handle a single HTTP request appearing on stdin. The resulting webpage
2621 ** is delivered on stdout. This method is used to launch an HTTP request
2622 ** handler from inetd, for example. The argument is the name of the
2623 ** repository.
2624 **
2625 ** If REPOSITORY is a directory that contains one or more repositories,
2626 ** either directly in REPOSITORY itself or in subdirectories, and
2627 ** with names of the form "*.fossil" then a prefix of the URL pathname
2628 ** selects from among the various repositories. If the pathname does
@@ -2633,31 +2639,24 @@
2633 ** and every "." must be surrounded on both sides by alphanumerics or else
2634 ** a 404 error is returned. Static content files in the directory are
2635 ** returned if they match comma-separate GLOB pattern specified by --files
2636 ** and do not match "*.fossil*" and have a well-known suffix.
2637 **
2638 ** The --host option can be used to specify the hostname for the server.
2639 ** The --https option indicates that the request came from HTTPS rather
2640 ** than HTTP. If --nossl is given, then SSL connections will not be available,
2641 ** thus also no redirecting from http: to https: will take place.
2642 **
2643 ** If the --localauth option is given, then automatic login is performed
2644 ** for requests coming from localhost, if the "localauth" setting is not
2645 ** enabled.
2646 **
2647 ** Options:
2648 ** --acme Deliver files from the ".well-known" subdirectory
2649 ** --baseurl URL base URL (useful with reverse proxies)
2650 ** --cert FILE Use TLS (HTTPS) encryption with the certificate (the
2651 ** fullchain.pem) taken from FILE.
2652 ** --chroot DIR Use directory for chroot instead of repository path.
2653 ** --ckout-alias N Treat URIs of the form /doc/N/... as if they were
2654 ** /doc/ckout/...
2655 ** --extroot DIR document root for the /ext extension mechanism
2656 ** --files GLOB comma-separate glob patterns for static file to serve
2657 ** --host NAME specify hostname of the server
2658 ** --https signal a request coming in via https
 
 
2659 ** --in FILE Take input from FILE instead of standard input
2660 ** --ipaddr ADDR Assume the request comes from the given IP address
2661 ** --jsmode MODE Determine how JavaScript is delivered with pages.
2662 ** Mode can be one of:
2663 ** inline All JavaScript is inserted inline at
@@ -2669,25 +2668,28 @@
2669 ** concatenate scripts together.
2670 ** Depending on the needs of any given page, inline
2671 ** and bundled modes might result in a single
2672 ** amalgamated script or several, but both approaches
2673 ** result in fewer HTTP requests than the separate mode.
2674 ** --localauth enable automatic login for local connections
 
2675 ** --mainmenu FILE Override the mainmenu config setting with the contents
2676 ** of the given file.
2677 ** --nocompress do not compress HTTP replies
2678 ** --nodelay omit backoffice processing if it would delay
2679 ** process exit
2680 ** --nojail drop root privilege but do not enter the chroot jail
2681 ** --nossl signal that no SSL connections are available
2682 ** --notfound URL use URL as "HTTP 404, object not found" page.
2683 ** --out FILE write results to FILE instead of to standard output
 
 
2684 ** --pkey FILE Read the private key used for TLS from FILE.
2685 ** --repolist If REPOSITORY is directory, URL "/" lists all repos
2686 ** --scgi Interpret input as SCGI rather than HTTP
2687 ** --skin LABEL Use override skin LABEL
2688 ** --th-trace trace TH1 execution (for debugging purposes)
2689 ** --usepidkey Use saved encryption key from parent process. This is
2690 ** only necessary when using SEE on Windows.
2691 **
2692 ** See also: [[cgi]], [[server]], [[winsrv]]
2693 */
@@ -2734,17 +2736,23 @@
2734 backoffice_disable();
2735 g.httpIn = fossil_fopen(zInFile, "rb");
2736 if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
2737 }else{
2738 g.httpIn = stdin;
 
 
 
2739 }
2740 zOutFile = find_option("out",0,1);
2741 if( zOutFile ){
2742 g.httpOut = fossil_fopen(zOutFile, "wb");
2743 if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
2744 }else{
2745 g.httpOut = stdout;
 
 
 
2746 }
2747 zIpAddr = find_option("ipaddr",0,1);
2748 useSCGI = find_option("scgi", 0, 0)!=0;
2749 zAltBase = find_option("baseurl", 0, 1);
2750 if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
2751
--- src/main.c
+++ src/main.c
@@ -206,11 +206,11 @@
206 int markPrivate; /* All new artifacts are private if true */
207 char *ckinLockFail; /* Check-in lock failure received from server */
208 int clockSkewSeen; /* True if clocks on client and server out of sync */
209 int wikiFlags; /* Wiki conversion flags applied to %W */
210 char isHTTP; /* True if server/CGI modes, else assume CLI. */
211 char jsHref; /* If true, set href= using javascript, not HTML */
212 Blob httpHeader; /* Complete text of the HTTP request header */
213 UrlData url; /* Information about current URL */
214 const char *zLogin; /* Login name. NULL or "" if not logged in. */
215 const char *zCkoutAlias; /* doc/ uses this branch as an alias for "ckout" */
216 const char *zMainMenuFile; /* --mainmenu FILE from server/ui/cgi */
@@ -421,28 +421,20 @@
421 unsigned int nArg; /* Number of new arguments */
422 char *z; /* General use string pointer */
423 char **newArgv; /* New expanded g.argv under construction */
424 const char *zFileName; /* input file name */
425 FILE *inFile; /* input FILE */
 
 
 
426
427 g.argc = argc;
428 g.argv = argv;
429 sqlite3_initialize();
430 #if defined(_WIN32) && defined(BROKEN_MINGW_CMDLINE)
431 for(i=0; i<g.argc; i++) g.argv[i] = fossil_mbcs_to_utf8(g.argv[i]);
432 #else
433 for(i=0; i<g.argc; i++) g.argv[i] = fossil_path_to_utf8(g.argv[i]);
434 #endif
435 g.nameOfExe = file_fullexename(g.argv[0]);
 
 
 
 
 
436 for(i=1; i<g.argc-1; i++){
437 z = g.argv[i];
438 if( z[0]!='-' ) continue;
439 z++;
440 if( z[0]=='-' ) z++;
@@ -920,11 +912,11 @@
912 fossil_exit(0);
913 #endif
914 }else if( rc==2 ){
915 Blob couldbe;
916 blob_init(&couldbe,0,0);
917 dispatch_matching_names(zCmdName, CMDFLAG_COMMAND, &couldbe);
918 fossil_print("%s: ambiguous command prefix: %s\n"
919 "%s: could be any of:%s\n"
920 "%s: use \"help\" for more information\n",
921 g.argv[0], zCmdName, g.argv[0], blob_str(&couldbe), g.argv[0]);
922 fossil_exit(1);
@@ -1597,10 +1589,30 @@
1589 cgi_redirect_with_status(zURL, 301, "Moved Permanently");
1590 return 1;
1591 }
1592 return 0;
1593 }
1594
1595 /*
1596 ** Send a 404 Not Found reply
1597 */
1598 void fossil_not_found_page(void){
1599 #ifdef FOSSIL_ENABLE_JSON
1600 if(g.json.isJsonMode){
1601 json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
1602 return;
1603 }
1604 #endif
1605 @ <html><head>
1606 @ <meta name="viewport" \
1607 @ content="width=device-width, initial-scale=1.0">
1608 @ </head><body>
1609 @ <h1>Not Found</h1>
1610 @ </body>
1611 cgi_set_status(404, "Not Found");
1612 cgi_reply();
1613 }
1614
1615 /*
1616 ** Preconditions:
1617 **
1618 ** * Environment variables are set up according to the CGI standard.
@@ -1820,24 +1832,11 @@
1832 && repo_list_page() ){
1833 /* Will return a list of repositories */
1834 }else if( zNotFound ){
1835 cgi_redirect(zNotFound);
1836 }else{
1837 fossil_not_found_page();
 
 
 
 
 
 
 
 
 
 
 
 
 
1838 }
1839 return;
1840 }
1841 break;
1842 }
@@ -1875,11 +1874,10 @@
1874
1875 /* At this point, the appropriate repository database file will have
1876 ** been opened.
1877 */
1878
 
1879 /*
1880 ** Check to see if the first term of PATH_INFO specifies an
1881 ** alternative skin. This will be the case if the first term of
1882 ** PATH_INFO begins with "draftN/" where N is an integer between 1
1883 ** and 9. If so, activate the skin associated with that draft.
@@ -1888,10 +1886,15 @@
1886 && zPathInfo[6]>='1' && zPathInfo[6]<='9'
1887 && (zPathInfo[7]=='/' || zPathInfo[7]==0)
1888 ){
1889 int iSkin = zPathInfo[6] - '0';
1890 char *zNewScript;
1891 if( db_int(0,"SELECT count(*) FROM config WHERE name GLOB 'draft%d-*'",
1892 iSkin)<5 ){
1893 fossil_not_found_page();
1894 fossil_exit(0);
1895 }
1896 skin_use_draft(iSkin);
1897 zNewScript = mprintf("%T/draft%d", P("SCRIPT_NAME"), iSkin);
1898 if( g.zTop ) g.zTop = mprintf("%R/draft%d", iSkin);
1899 if( g.zBaseURL ) g.zBaseURL = mprintf("%s/draft%d", g.zBaseURL, iSkin);
1900 zPathInfo += 7;
@@ -2013,10 +2016,13 @@
2016 @ <h1>Server Configuration Error</h1>
2017 @ <p>The database schema on the server is out-of-date. Please ask
2018 @ the administrator to run <b>fossil rebuild</b>.</p>
2019 }
2020 }else{
2021 if(0==(CMDFLAG_LDAVG_EXEMPT & pCmd->eCmdFlags)){
2022 load_control();
2023 }
2024 #ifdef FOSSIL_ENABLE_JSON
2025 static int jsonOnce = 0;
2026 if( jsonOnce==0 && g.json.isJsonMode!=0 ){
2027 assert(json_is_bootstrapped_early());
2028 json_bootstrap_late();
@@ -2617,12 +2623,12 @@
2623 **
2624 ** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
2625 **
2626 ** Handle a single HTTP request appearing on stdin. The resulting webpage
2627 ** is delivered on stdout. This method is used to launch an HTTP request
2628 ** handler from inetd, for example. The REPOSITORY argument is the name of
2629 ** the repository.
2630 **
2631 ** If REPOSITORY is a directory that contains one or more repositories,
2632 ** either directly in REPOSITORY itself or in subdirectories, and
2633 ** with names of the form "*.fossil" then a prefix of the URL pathname
2634 ** selects from among the various repositories. If the pathname does
@@ -2633,31 +2639,24 @@
2639 ** and every "." must be surrounded on both sides by alphanumerics or else
2640 ** a 404 error is returned. Static content files in the directory are
2641 ** returned if they match comma-separate GLOB pattern specified by --files
2642 ** and do not match "*.fossil*" and have a well-known suffix.
2643 **
 
 
 
 
 
 
 
 
 
2644 ** Options:
2645 ** --acme Deliver files from the ".well-known" subdirectory
2646 ** --baseurl URL base URL (useful with reverse proxies)
2647 ** --cert FILE Use TLS (HTTPS) encryption with the certificate (the
2648 ** fullchain.pem) taken from FILE.
2649 ** --chroot DIR Use directory for chroot instead of repository path.
2650 ** --ckout-alias N Treat URIs of the form /doc/N/... as if they were
2651 ** /doc/ckout/...
2652 ** --extroot DIR Document root for the /ext extension mechanism
2653 ** --files GLOB Comma-separate glob patterns for static file to serve
2654 ** --host NAME DNS Hostname of the server
2655 ** --https The HTTP request originated from https but has already
2656 ** been decoded by a reverse proxy. Hence, URLs created
2657 ** by Fossil should use "https:" rather than "http:".
2658 ** --in FILE Take input from FILE instead of standard input
2659 ** --ipaddr ADDR Assume the request comes from the given IP address
2660 ** --jsmode MODE Determine how JavaScript is delivered with pages.
2661 ** Mode can be one of:
2662 ** inline All JavaScript is inserted inline at
@@ -2669,25 +2668,28 @@
2668 ** concatenate scripts together.
2669 ** Depending on the needs of any given page, inline
2670 ** and bundled modes might result in a single
2671 ** amalgamated script or several, but both approaches
2672 ** result in fewer HTTP requests than the separate mode.
2673 ** --localauth Connections from localhost are given "setup"
2674 ** privileges without having to log in.
2675 ** --mainmenu FILE Override the mainmenu config setting with the contents
2676 ** of the given file.
2677 ** --nocompress Do not compress HTTP replies
2678 ** --nodelay Omit backoffice processing if it would delay
2679 ** process exit
2680 ** --nojail Drop root privilege but do not enter the chroot jail
2681 ** --nossl Do not do http: to https: redirects, regardless of
2682 ** the redirect-to-https setting.
2683 ** --notfound URL Use URL as the "HTTP 404, object not found" page.
2684 ** --out FILE Write the HTTP reply to FILE instead of to
2685 ** standard output
2686 ** --pkey FILE Read the private key used for TLS from FILE.
2687 ** --repolist If REPOSITORY is directory, URL "/" lists all repos
2688 ** --scgi Interpret input as SCGI rather than HTTP
2689 ** --skin LABEL Use override skin LABEL
2690 ** --th-trace Trace TH1 execution (for debugging purposes)
2691 ** --usepidkey Use saved encryption key from parent process. This is
2692 ** only necessary when using SEE on Windows.
2693 **
2694 ** See also: [[cgi]], [[server]], [[winsrv]]
2695 */
@@ -2734,17 +2736,23 @@
2736 backoffice_disable();
2737 g.httpIn = fossil_fopen(zInFile, "rb");
2738 if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
2739 }else{
2740 g.httpIn = stdin;
2741 #if defined(_WIN32)
2742 _setmode(_fileno(stdin), _O_BINARY);
2743 #endif
2744 }
2745 zOutFile = find_option("out",0,1);
2746 if( zOutFile ){
2747 g.httpOut = fossil_fopen(zOutFile, "wb");
2748 if( g.httpOut==0 ) fossil_fatal("cannot open \"%s\" for writing", zOutFile);
2749 }else{
2750 g.httpOut = stdout;
2751 #if defined(_WIN32)
2752 _setmode(_fileno(stdout), _O_BINARY);
2753 #endif
2754 }
2755 zIpAddr = find_option("ipaddr",0,1);
2756 useSCGI = find_option("scgi", 0, 0)!=0;
2757 zAltBase = find_option("baseurl", 0, 1);
2758 if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
2759
+4 -1
--- src/main.mk
+++ src/main.mk
@@ -675,10 +675,13 @@
675675
-DSQLITE_SHELL_IS_UTF8=1 \
676676
-DSQLITE_OMIT_LOAD_EXTENSION=1 \
677677
-DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \
678678
-DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname \
679679
-DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc
680
+
681
+# Setup the options used to compile the included Pikchr formatter.
682
+PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000
680683
681684
# The USE_SYSTEM_SQLITE variable may be undefined, set to 0 or 1.
682685
# If it is set to 1, then there is no need to build or link
683686
# the sqlite3.o object. Instead, the system SQLite will be linked
684687
# using -lsqlite3.
@@ -2101,11 +2104,11 @@
21012104
$(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
21022105
$(XTCC) -c $(SRCDIR)/th_tcl.c -o $@
21032106
21042107
21052108
$(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
2106
- $(XTCC) -c $(SRCDIR_extsrc)/pikchr.c -o $@
2109
+ $(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
21072110
21082111
$(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
21092112
$(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
21102113
21112114
#
21122115
--- src/main.mk
+++ src/main.mk
@@ -675,10 +675,13 @@
675 -DSQLITE_SHELL_IS_UTF8=1 \
676 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
677 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \
678 -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname \
679 -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc
 
 
 
680
681 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0 or 1.
682 # If it is set to 1, then there is no need to build or link
683 # the sqlite3.o object. Instead, the system SQLite will be linked
684 # using -lsqlite3.
@@ -2101,11 +2104,11 @@
2101 $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
2102 $(XTCC) -c $(SRCDIR)/th_tcl.c -o $@
2103
2104
2105 $(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
2106 $(XTCC) -c $(SRCDIR_extsrc)/pikchr.c -o $@
2107
2108 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
2109 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
2110
2111 #
2112
--- src/main.mk
+++ src/main.mk
@@ -675,10 +675,13 @@
675 -DSQLITE_SHELL_IS_UTF8=1 \
676 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
677 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \
678 -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname \
679 -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc
680
681 # Setup the options used to compile the included Pikchr formatter.
682 PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000
683
684 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0 or 1.
685 # If it is set to 1, then there is no need to build or link
686 # the sqlite3.o object. Instead, the system SQLite will be linked
687 # using -lsqlite3.
@@ -2101,11 +2104,11 @@
2104 $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
2105 $(XTCC) -c $(SRCDIR)/th_tcl.c -o $@
2106
2107
2108 $(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
2109 $(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
2110
2111 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
2112 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
2113
2114 #
2115
+14 -11
--- src/markdown.md
+++ src/markdown.md
@@ -54,11 +54,11 @@
5454
> <li> An [interwiki link](#intermap) of the form "<i>Tag</i><b>:</b><i>PageName</i>"</ul>
5555
5656
> In format 8, then the URL becomes the display text. This is useful for
5757
> hyperlinks that refer to wiki pages and check-in and ticket hashes.
5858
59
-## Fonts ##
59
+## Text Style ##
6060
6161
> * _\*italic\*_
6262
> * *\_italic\_*
6363
> * __\*\*bold\*\*__
6464
> * **\_\_bold\_\_**
@@ -69,23 +69,25 @@
6969
> The **\`code\`** construct disables HTML markup, so one can write, for
7070
> example, **\`\<html\>\`** to yield **`<html>`**.
7171
7272
## Lists ##
7373
74
->
75
- * bullet item
76
- + bullet item
77
- - bullet item
78
- 1. numbered item
79
- 2) numbered item
74
+> ~~~
75
+ * bullet item
76
+ + bullet item
77
+ - bullet item
78
+ 1. numbered item
79
+ 2) numbered item
80
+~~~
8081
8182
> A two-level list is created by placing additional whitespace before the
8283
> **\***/**+**/**-**/**1.** of the secondary items.
8384
84
->
85
- * top-level item
86
- * secondary item
85
+> ~~~
86
+ * top-level item
87
+ * second-level item
88
+~~~
8789
8890
## Block Quotes ##
8991
9092
> Begin each line of a paragraph with **>** to block quote that paragraph.
9193
@@ -191,12 +193,13 @@
191193
> * **\<!--** HTML-style comments **-->** are supported.
192194
> * Escape special characters (ex: **\[** **\(** **\|** **\***)
193195
> using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
194196
> * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
195197
> rule. Spaces and extra **-**/**\***/**_** are allowed.
198
+> * Paragraphs enclosed in **\<html\>...\</html\>** is passed through unchanged.
196199
> * See [daringfireball.net][] for additional information.
197
-> * See this page's [Markdown source](/md_rules?txt=1) for complex examples.
200
+> * See this page's [Markdown source](/md_rules?txt=1) for more examples.
198201
199202
## Special Features For Fossil ##
200203
201204
> * In hyperlinks, if the URL begins with **/** then the root of the Fossil
202205
> repository is prepended. This allows for repository-relative hyperlinks.
203206
--- src/markdown.md
+++ src/markdown.md
@@ -54,11 +54,11 @@
54 > <li> An [interwiki link](#intermap) of the form "<i>Tag</i><b>:</b><i>PageName</i>"</ul>
55
56 > In format 8, then the URL becomes the display text. This is useful for
57 > hyperlinks that refer to wiki pages and check-in and ticket hashes.
58
59 ## Fonts ##
60
61 > * _\*italic\*_
62 > * *\_italic\_*
63 > * __\*\*bold\*\*__
64 > * **\_\_bold\_\_**
@@ -69,23 +69,25 @@
69 > The **\`code\`** construct disables HTML markup, so one can write, for
70 > example, **\`\<html\>\`** to yield **`<html>`**.
71
72 ## Lists ##
73
74 >
75 * bullet item
76 + bullet item
77 - bullet item
78 1. numbered item
79 2) numbered item
 
80
81 > A two-level list is created by placing additional whitespace before the
82 > **\***/**+**/**-**/**1.** of the secondary items.
83
84 >
85 * top-level item
86 * secondary item
 
87
88 ## Block Quotes ##
89
90 > Begin each line of a paragraph with **>** to block quote that paragraph.
91
@@ -191,12 +193,13 @@
191 > * **\<!--** HTML-style comments **-->** are supported.
192 > * Escape special characters (ex: **\[** **\(** **\|** **\***)
193 > using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
194 > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
195 > rule. Spaces and extra **-**/**\***/**_** are allowed.
 
196 > * See [daringfireball.net][] for additional information.
197 > * See this page's [Markdown source](/md_rules?txt=1) for complex examples.
198
199 ## Special Features For Fossil ##
200
201 > * In hyperlinks, if the URL begins with **/** then the root of the Fossil
202 > repository is prepended. This allows for repository-relative hyperlinks.
203
--- src/markdown.md
+++ src/markdown.md
@@ -54,11 +54,11 @@
54 > <li> An [interwiki link](#intermap) of the form "<i>Tag</i><b>:</b><i>PageName</i>"</ul>
55
56 > In format 8, then the URL becomes the display text. This is useful for
57 > hyperlinks that refer to wiki pages and check-in and ticket hashes.
58
59 ## Text Style ##
60
61 > * _\*italic\*_
62 > * *\_italic\_*
63 > * __\*\*bold\*\*__
64 > * **\_\_bold\_\_**
@@ -69,23 +69,25 @@
69 > The **\`code\`** construct disables HTML markup, so one can write, for
70 > example, **\`\<html\>\`** to yield **`<html>`**.
71
72 ## Lists ##
73
74 > ~~~
75 * bullet item
76 + bullet item
77 - bullet item
78 1. numbered item
79 2) numbered item
80 ~~~
81
82 > A two-level list is created by placing additional whitespace before the
83 > **\***/**+**/**-**/**1.** of the secondary items.
84
85 > ~~~
86 * top-level item
87 * second-level item
88 ~~~
89
90 ## Block Quotes ##
91
92 > Begin each line of a paragraph with **>** to block quote that paragraph.
93
@@ -191,12 +193,13 @@
193 > * **\<!--** HTML-style comments **-->** are supported.
194 > * Escape special characters (ex: **\[** **\(** **\|** **\***)
195 > using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
196 > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
197 > rule. Spaces and extra **-**/**\***/**_** are allowed.
198 > * Paragraphs enclosed in **\<html\>...\</html\>** is passed through unchanged.
199 > * See [daringfireball.net][] for additional information.
200 > * See this page's [Markdown source](/md_rules?txt=1) for more examples.
201
202 ## Special Features For Fossil ##
203
204 > * In hyperlinks, if the URL begins with **/** then the root of the Fossil
205 > repository is prepended. This allows for repository-relative hyperlinks.
206
+14 -11
--- src/markdown.md
+++ src/markdown.md
@@ -54,11 +54,11 @@
5454
> <li> An [interwiki link](#intermap) of the form "<i>Tag</i><b>:</b><i>PageName</i>"</ul>
5555
5656
> In format 8, then the URL becomes the display text. This is useful for
5757
> hyperlinks that refer to wiki pages and check-in and ticket hashes.
5858
59
-## Fonts ##
59
+## Text Style ##
6060
6161
> * _\*italic\*_
6262
> * *\_italic\_*
6363
> * __\*\*bold\*\*__
6464
> * **\_\_bold\_\_**
@@ -69,23 +69,25 @@
6969
> The **\`code\`** construct disables HTML markup, so one can write, for
7070
> example, **\`\<html\>\`** to yield **`<html>`**.
7171
7272
## Lists ##
7373
74
->
75
- * bullet item
76
- + bullet item
77
- - bullet item
78
- 1. numbered item
79
- 2) numbered item
74
+> ~~~
75
+ * bullet item
76
+ + bullet item
77
+ - bullet item
78
+ 1. numbered item
79
+ 2) numbered item
80
+~~~
8081
8182
> A two-level list is created by placing additional whitespace before the
8283
> **\***/**+**/**-**/**1.** of the secondary items.
8384
84
->
85
- * top-level item
86
- * secondary item
85
+> ~~~
86
+ * top-level item
87
+ * second-level item
88
+~~~
8789
8890
## Block Quotes ##
8991
9092
> Begin each line of a paragraph with **>** to block quote that paragraph.
9193
@@ -191,12 +193,13 @@
191193
> * **\<!--** HTML-style comments **-->** are supported.
192194
> * Escape special characters (ex: **\[** **\(** **\|** **\***)
193195
> using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
194196
> * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
195197
> rule. Spaces and extra **-**/**\***/**_** are allowed.
198
+> * Paragraphs enclosed in **\<html\>...\</html\>** is passed through unchanged.
196199
> * See [daringfireball.net][] for additional information.
197
-> * See this page's [Markdown source](/md_rules?txt=1) for complex examples.
200
+> * See this page's [Markdown source](/md_rules?txt=1) for more examples.
198201
199202
## Special Features For Fossil ##
200203
201204
> * In hyperlinks, if the URL begins with **/** then the root of the Fossil
202205
> repository is prepended. This allows for repository-relative hyperlinks.
203206
--- src/markdown.md
+++ src/markdown.md
@@ -54,11 +54,11 @@
54 > <li> An [interwiki link](#intermap) of the form "<i>Tag</i><b>:</b><i>PageName</i>"</ul>
55
56 > In format 8, then the URL becomes the display text. This is useful for
57 > hyperlinks that refer to wiki pages and check-in and ticket hashes.
58
59 ## Fonts ##
60
61 > * _\*italic\*_
62 > * *\_italic\_*
63 > * __\*\*bold\*\*__
64 > * **\_\_bold\_\_**
@@ -69,23 +69,25 @@
69 > The **\`code\`** construct disables HTML markup, so one can write, for
70 > example, **\`\<html\>\`** to yield **`<html>`**.
71
72 ## Lists ##
73
74 >
75 * bullet item
76 + bullet item
77 - bullet item
78 1. numbered item
79 2) numbered item
 
80
81 > A two-level list is created by placing additional whitespace before the
82 > **\***/**+**/**-**/**1.** of the secondary items.
83
84 >
85 * top-level item
86 * secondary item
 
87
88 ## Block Quotes ##
89
90 > Begin each line of a paragraph with **>** to block quote that paragraph.
91
@@ -191,12 +193,13 @@
191 > * **\<!--** HTML-style comments **-->** are supported.
192 > * Escape special characters (ex: **\[** **\(** **\|** **\***)
193 > using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
194 > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
195 > rule. Spaces and extra **-**/**\***/**_** are allowed.
 
196 > * See [daringfireball.net][] for additional information.
197 > * See this page's [Markdown source](/md_rules?txt=1) for complex examples.
198
199 ## Special Features For Fossil ##
200
201 > * In hyperlinks, if the URL begins with **/** then the root of the Fossil
202 > repository is prepended. This allows for repository-relative hyperlinks.
203
--- src/markdown.md
+++ src/markdown.md
@@ -54,11 +54,11 @@
54 > <li> An [interwiki link](#intermap) of the form "<i>Tag</i><b>:</b><i>PageName</i>"</ul>
55
56 > In format 8, then the URL becomes the display text. This is useful for
57 > hyperlinks that refer to wiki pages and check-in and ticket hashes.
58
59 ## Text Style ##
60
61 > * _\*italic\*_
62 > * *\_italic\_*
63 > * __\*\*bold\*\*__
64 > * **\_\_bold\_\_**
@@ -69,23 +69,25 @@
69 > The **\`code\`** construct disables HTML markup, so one can write, for
70 > example, **\`\<html\>\`** to yield **`<html>`**.
71
72 ## Lists ##
73
74 > ~~~
75 * bullet item
76 + bullet item
77 - bullet item
78 1. numbered item
79 2) numbered item
80 ~~~
81
82 > A two-level list is created by placing additional whitespace before the
83 > **\***/**+**/**-**/**1.** of the secondary items.
84
85 > ~~~
86 * top-level item
87 * second-level item
88 ~~~
89
90 ## Block Quotes ##
91
92 > Begin each line of a paragraph with **>** to block quote that paragraph.
93
@@ -191,12 +193,13 @@
193 > * **\<!--** HTML-style comments **-->** are supported.
194 > * Escape special characters (ex: **\[** **\(** **\|** **\***)
195 > using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***).
196 > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal
197 > rule. Spaces and extra **-**/**\***/**_** are allowed.
198 > * Paragraphs enclosed in **\<html\>...\</html\>** is passed through unchanged.
199 > * See [daringfireball.net][] for additional information.
200 > * See this page's [Markdown source](/md_rules?txt=1) for more examples.
201
202 ## Special Features For Fossil ##
203
204 > * In hyperlinks, if the URL begins with **/** then the root of the Fossil
205 > repository is prepended. This allows for repository-relative hyperlinks.
206
+1 -2
--- src/merge.c
+++ src/merge.c
@@ -407,12 +407,11 @@
407407
}
408408
if( forceFlag==0 && leaf_is_closed(vid) ){
409409
fossil_fatal("cannot merge into a closed leaf. Use --force to override");
410410
}
411411
if( !dryRunFlag ){
412
- if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag,
413
- db_get_int("autosync-tries", 1), 1) ){
412
+ if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "merge") ){
414413
fossil_fatal("merge abandoned due to sync failure");
415414
}
416415
}
417416
418417
/* Find mid, the artifactID of the version to be merged into the current
419418
--- src/merge.c
+++ src/merge.c
@@ -407,12 +407,11 @@
407 }
408 if( forceFlag==0 && leaf_is_closed(vid) ){
409 fossil_fatal("cannot merge into a closed leaf. Use --force to override");
410 }
411 if( !dryRunFlag ){
412 if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag,
413 db_get_int("autosync-tries", 1), 1) ){
414 fossil_fatal("merge abandoned due to sync failure");
415 }
416 }
417
418 /* Find mid, the artifactID of the version to be merged into the current
419
--- src/merge.c
+++ src/merge.c
@@ -407,12 +407,11 @@
407 }
408 if( forceFlag==0 && leaf_is_closed(vid) ){
409 fossil_fatal("cannot merge into a closed leaf. Use --force to override");
410 }
411 if( !dryRunFlag ){
412 if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "merge") ){
 
413 fossil_fatal("merge abandoned due to sync failure");
414 }
415 }
416
417 /* Find mid, the artifactID of the version to be merged into the current
418
+20 -13
--- src/name.c
+++ src/name.c
@@ -157,26 +157,33 @@
157157
Stmt q;
158158
int rc;
159159
int ans = rid;
160160
char *zBr = branch_of_rid(rid);
161161
db_prepare(&q,
162
- "SELECT pid, EXISTS(SELECT 1 FROM tagxref"
163
- " WHERE tagid=%d AND tagtype>0"
164
- " AND value=%Q AND rid=plink.pid)"
165
- " FROM plink"
166
- " WHERE cid=:cid AND isprim",
167
- TAG_BRANCH, zBr
162
+ "WITH RECURSIVE"
163
+ " par(pid, ex, cnt) as ("
164
+ " SELECT pid, EXISTS(SELECT 1 FROM tagxref"
165
+ " WHERE tagid=%d AND tagtype>0"
166
+ " AND value=%Q AND rid=plink.pid), 1"
167
+ " FROM plink WHERE cid=%d AND isprim"
168
+ " UNION ALL "
169
+ " SELECT plink.pid, EXISTS(SELECT 1 FROM tagxref "
170
+ " WHERE tagid=%d AND tagtype>0"
171
+ " AND value=%Q AND rid=plink.pid),"
172
+ " 1+par.cnt"
173
+ " FROM plink, par"
174
+ " WHERE cid=par.pid AND isprim AND par.ex "
175
+ " LIMIT 100000 "
176
+ " )"
177
+ " SELECT pid FROM par WHERE ex>=%d ORDER BY cnt DESC LIMIT 1",
178
+ TAG_BRANCH, zBr, ans, TAG_BRANCH, zBr, eType%2
168179
);
169180
fossil_free(zBr);
170
- do{
171
- db_reset(&q);
172
- db_bind_int(&q, ":cid", ans);
173
- rc = db_step(&q);
174
- if( rc!=SQLITE_ROW ) break;
175
- if( eType==1 && db_column_int(&q,1)==0 ) break;
181
+ rc = db_step(&q);
182
+ if( rc==SQLITE_ROW ){
176183
ans = db_column_int(&q, 0);
177
- }while( db_column_int(&q, 1)==1 && ans>0 );
184
+ }
178185
db_finalize(&q);
179186
if( eType==2 && ans>0 ){
180187
zBr = branch_of_rid(ans);
181188
ans = compute_youngest_ancestor_in_branch(rid, zBr);
182189
fossil_free(zBr);
183190
--- src/name.c
+++ src/name.c
@@ -157,26 +157,33 @@
157 Stmt q;
158 int rc;
159 int ans = rid;
160 char *zBr = branch_of_rid(rid);
161 db_prepare(&q,
162 "SELECT pid, EXISTS(SELECT 1 FROM tagxref"
163 " WHERE tagid=%d AND tagtype>0"
164 " AND value=%Q AND rid=plink.pid)"
165 " FROM plink"
166 " WHERE cid=:cid AND isprim",
167 TAG_BRANCH, zBr
 
 
 
 
 
 
 
 
 
 
 
168 );
169 fossil_free(zBr);
170 do{
171 db_reset(&q);
172 db_bind_int(&q, ":cid", ans);
173 rc = db_step(&q);
174 if( rc!=SQLITE_ROW ) break;
175 if( eType==1 && db_column_int(&q,1)==0 ) break;
176 ans = db_column_int(&q, 0);
177 }while( db_column_int(&q, 1)==1 && ans>0 );
178 db_finalize(&q);
179 if( eType==2 && ans>0 ){
180 zBr = branch_of_rid(ans);
181 ans = compute_youngest_ancestor_in_branch(rid, zBr);
182 fossil_free(zBr);
183
--- src/name.c
+++ src/name.c
@@ -157,26 +157,33 @@
157 Stmt q;
158 int rc;
159 int ans = rid;
160 char *zBr = branch_of_rid(rid);
161 db_prepare(&q,
162 "WITH RECURSIVE"
163 " par(pid, ex, cnt) as ("
164 " SELECT pid, EXISTS(SELECT 1 FROM tagxref"
165 " WHERE tagid=%d AND tagtype>0"
166 " AND value=%Q AND rid=plink.pid), 1"
167 " FROM plink WHERE cid=%d AND isprim"
168 " UNION ALL "
169 " SELECT plink.pid, EXISTS(SELECT 1 FROM tagxref "
170 " WHERE tagid=%d AND tagtype>0"
171 " AND value=%Q AND rid=plink.pid),"
172 " 1+par.cnt"
173 " FROM plink, par"
174 " WHERE cid=par.pid AND isprim AND par.ex "
175 " LIMIT 100000 "
176 " )"
177 " SELECT pid FROM par WHERE ex>=%d ORDER BY cnt DESC LIMIT 1",
178 TAG_BRANCH, zBr, ans, TAG_BRANCH, zBr, eType%2
179 );
180 fossil_free(zBr);
181 rc = db_step(&q);
182 if( rc==SQLITE_ROW ){
 
 
 
 
183 ans = db_column_int(&q, 0);
184 }
185 db_finalize(&q);
186 if( eType==2 && ans>0 ){
187 zBr = branch_of_rid(ans);
188 ans = compute_youngest_ancestor_in_branch(rid, zBr);
189 fossil_free(zBr);
190
+12 -3
--- src/repolist.c
+++ src/repolist.c
@@ -174,11 +174,11 @@
174174
int nName = (int)strlen(zName);
175175
char *zUrl;
176176
char *zAge;
177177
char *zFull;
178178
RepoInfo x;
179
- int iAge;
179
+ sqlite3_int64 iAge;
180180
if( nName<7 ) continue;
181181
zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
182182
if( zName[0]=='/'
183183
#ifdef _WIN32
184184
|| sqlite3_strglob("[a-zA-Z]:/*", zName)==0
@@ -205,13 +205,22 @@
205205
if( x.isRepolistSkin==2 && !allRepo ){
206206
/* Repositories with repolist-skin==2 are omitted from directory
207207
** scan lists, but included in "fossil all ui" lists */
208208
continue;
209209
}
210
- iAge = (rNow - x.rMTime)*86400;
211
- if( iAge<0 ) x.rMTime = rNow;
210
+ if( rNow <= x.rMTime ){
211
+ x.rMTime = rNow;
212
+ }else if( x.rMTime<0.0 ){
213
+ x.rMTime = rNow;
214
+ }
215
+ iAge = (int)(rNow - x.rMTime)*86400;
212216
zAge = human_readable_age(rNow - x.rMTime);
217
+ if( x.rMTime==0.0 ){
218
+ /* This repository has no entry in the "event" table.
219
+ ** Its age will still be maximum, so data-sortkey will work. */
220
+ zAge = mprintf("unknown");
221
+ }
213222
blob_append_sql(&html, "<tr><td valign='top'>");
214223
if( sqlite3_strglob("*.fossil", zName)!=0 ){
215224
/* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
216225
** do not work for repositories whose names do not end in ".fossil".
217226
** So do not hyperlink those cases. */
218227
--- src/repolist.c
+++ src/repolist.c
@@ -174,11 +174,11 @@
174 int nName = (int)strlen(zName);
175 char *zUrl;
176 char *zAge;
177 char *zFull;
178 RepoInfo x;
179 int iAge;
180 if( nName<7 ) continue;
181 zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
182 if( zName[0]=='/'
183 #ifdef _WIN32
184 || sqlite3_strglob("[a-zA-Z]:/*", zName)==0
@@ -205,13 +205,22 @@
205 if( x.isRepolistSkin==2 && !allRepo ){
206 /* Repositories with repolist-skin==2 are omitted from directory
207 ** scan lists, but included in "fossil all ui" lists */
208 continue;
209 }
210 iAge = (rNow - x.rMTime)*86400;
211 if( iAge<0 ) x.rMTime = rNow;
 
 
 
 
212 zAge = human_readable_age(rNow - x.rMTime);
 
 
 
 
 
213 blob_append_sql(&html, "<tr><td valign='top'>");
214 if( sqlite3_strglob("*.fossil", zName)!=0 ){
215 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
216 ** do not work for repositories whose names do not end in ".fossil".
217 ** So do not hyperlink those cases. */
218
--- src/repolist.c
+++ src/repolist.c
@@ -174,11 +174,11 @@
174 int nName = (int)strlen(zName);
175 char *zUrl;
176 char *zAge;
177 char *zFull;
178 RepoInfo x;
179 sqlite3_int64 iAge;
180 if( nName<7 ) continue;
181 zUrl = sqlite3_mprintf("%.*s", nName-7, zName);
182 if( zName[0]=='/'
183 #ifdef _WIN32
184 || sqlite3_strglob("[a-zA-Z]:/*", zName)==0
@@ -205,13 +205,22 @@
205 if( x.isRepolistSkin==2 && !allRepo ){
206 /* Repositories with repolist-skin==2 are omitted from directory
207 ** scan lists, but included in "fossil all ui" lists */
208 continue;
209 }
210 if( rNow <= x.rMTime ){
211 x.rMTime = rNow;
212 }else if( x.rMTime<0.0 ){
213 x.rMTime = rNow;
214 }
215 iAge = (int)(rNow - x.rMTime)*86400;
216 zAge = human_readable_age(rNow - x.rMTime);
217 if( x.rMTime==0.0 ){
218 /* This repository has no entry in the "event" table.
219 ** Its age will still be maximum, so data-sortkey will work. */
220 zAge = mprintf("unknown");
221 }
222 blob_append_sql(&html, "<tr><td valign='top'>");
223 if( sqlite3_strglob("*.fossil", zName)!=0 ){
224 /* The "fossil server DIRECTORY" and "fossil ui DIRECTORY" commands
225 ** do not work for repositories whose names do not end in ".fossil".
226 ** So do not hyperlink those cases. */
227
--- src/security_audit.c
+++ src/security_audit.c
@@ -144,17 +144,17 @@
144144
@ immediately! Or, at least remove the Setup and Admin privileges
145145
@ from the default permissions for new users.
146146
}else if( hasAnyCap(zAnonCap,"y") ){
147147
@ <li><p>This repository is <big><b>INSECURE</b></big> because
148148
@ it allows anonymous users to push unversioned files.
149
- @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
149
+ @ Fix this by <a href="takeitprivate">taking the repository private</a>
150150
@ or by removing the "y" permission from users "anonymous" and
151151
@ "nobody" on the <a href="setup_ulist">User Configuration</a> page.
152152
}else if( hasAnyCap(zSelfCap,"y") ){
153153
@ <li><p>This repository is <big><b>INSECURE</b></big> because
154154
@ it allows self-registered users to push unversioned files.
155
- @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
155
+ @ Fix this by <a href="takeitprivate">taking the repository private</a>
156156
@ or by removing the "y" permission from the default permissions or
157157
@ by disabling self-registration.
158158
}else if( hasAnyCap(zAnonCap,"goz") ){
159159
@ <li><p>This repository is <big><b>PUBLIC</b></big>. All
160160
@ checked-in content can be accessed by anonymous users.
@@ -240,11 +240,11 @@
240240
*/
241241
if( db_get_int("redirect-to-https",0)==0 ){
242242
@ <li><p><b>WARNING:</b>
243243
@ Sensitive material such as login passwords can be sent over an
244244
@ unencrypted connection.
245
- @ <p>Fix this by changing the "Redirect to HTTPS" setting on the
245
+ @ Fix this by changing the "Redirect to HTTPS" setting on the
246246
@ <a href="setup_access">Access Control</a> page. If you were using
247247
@ the old "Redirect to HTTPS on Login Page" setting, switch to the
248248
@ new setting: it has a more secure implementation.
249249
}
250250
@@ -282,11 +282,11 @@
282282
*/
283283
if( hasAnyCap(zAnonCap, "e") ){
284284
@ <li><p><b>WARNING:</b>
285285
@ Anonymous users can view email addresses and other personally
286286
@ identifiable information on tickets.
287
- @ <p>Fix this by removing the "Email" privilege
287
+ @ Fix this by removing the "Email" privilege
288288
@ (<a href="setup_ucap_list">capability "e"</a>) from users
289289
@ "anonymous" and "nobody" on the
290290
@ <a href="setup_ulist">User Configuration</a> page.
291291
}
292292
@@ -294,11 +294,11 @@
294294
** to the repository.
295295
*/
296296
if( hasAnyCap(zAnonCap, "i") ){
297297
@ <li><p><b>WARNING:</b>
298298
@ Anonymous users can push new check-ins into the repository.
299
- @ <p>Fix this by removing the "Check-in" privilege
299
+ @ Fix this by removing the "Check-in" privilege
300300
@ (<a href="setup_ucap_list">capability</a> "i") from users
301301
@ "anonymous" and "nobody" on the
302302
@ <a href="setup_ulist">User Configuration</a> page.
303303
}
304304
@@ -307,11 +307,11 @@
307307
*/
308308
if( hasAnyCap(zAnonCap, "lq5") ){
309309
@ <li><p><b>WARNING:</b>
310310
@ Anonymous users can act as moderators for wiki, tickets, or
311311
@ forum posts. This defeats the whole purpose of moderation.
312
- @ <p>Fix this by removing the "Mod-Wiki", "Mod-Tkt", and "Mod-Forum"
312
+ @ Fix this by removing the "Mod-Wiki", "Mod-Tkt", and "Mod-Forum"
313313
@ privileges (<a href="%R/setup_ucap_list">capabilities</a> "fq5")
314314
@ from users "anonymous" and "nobody"
315315
@ on the <a href="setup_ulist">User Configuration</a> page.
316316
}
317317
@@ -470,37 +470,66 @@
470470
@ number of users (%d(n)).
471471
@ Ideally, the Write-Unver privilege should only
472472
@ be granted to one or two users.
473473
}
474474
}
475
+
476
+ /* Providing hyperlink capability to user "nobody" can lead to robots
477
+ ** making excessive requests resulting in DoS
478
+ */
479
+ if( db_exists("SELECT 1 FROM user WHERE login='nobody' AND cap GLOB '*h*'") ){
480
+ int nobodyId = db_int(0,"SELECT uid FROM user WHERE login='nobody'");
481
+ int anonId = db_int(0,
482
+ "SELECT uid FROM user WHERE login='anonymous' AND cap NOT GLOB '*h*'");
483
+ @ <li><p>
484
+ @ User "nobody" has "Hyperlink" privilege ('h') which can lead to
485
+ @ robots walking a nearly endless progression of pages on public-facing
486
+ @ repositories, causing excessive server load and possible DoS.
487
+ @ Suggested remediation:
488
+ @ <ol type="a">
489
+ @ <li>Remove the 'h' privilege from the
490
+ @ <a href="%R/setup_uedit?id=%d(nobodyId)">'nobody' user</a> so that
491
+ @ robots cannot see hyperlinks.
492
+ @ <li>Activate <a href="%R/setup_robot">autohyperlink</a> so that
493
+ @ human readers can still see hyperlinks even if they are not logged in.
494
+ @ Set the delay to at least 50 milliseconds and require a mouse
495
+ @ event for maximum robot defense.
496
+ if( anonId>0 ){
497
+ @ <li>Perhaps set the 'h' privilege on the
498
+ @ <a href="%R/setup_uedit?id=%d(anonId)">'anonymous' user</a> so
499
+ @ that humans that have javascript disabled in their browsers can
500
+ @ still see hyperlinks if they will log in as "anonymous".
501
+ }
502
+ @ </ol>
503
+ }
475504
476505
/* Notify if REMOTE_USER or HTTP_AUTHENTICATION is used for login.
477506
*/
478507
if( db_get_boolean("remote_user_ok", 0) ){
479
- @ <li><p>
508
+ @ <li><p><b>Caution:</b>
480509
@ This repository trusts that the REMOTE_USER environment variable set
481510
@ up by the webserver contains the name of an authenticated user.
482511
@ Fossil's built-in authentication mechanism is bypassed.
483
- @ <p>Fix this by deactivating the "Allow REMOTE_USER authentication"
512
+ @ Fix this by deactivating the "Allow REMOTE_USER authentication"
484513
@ checkbox on the <a href="setup_access">Access Control</a> page.
485514
}
486515
if( db_get_boolean("http_authentication_ok", 0) ){
487
- @ <li><p>
516
+ @ <li><p><b>Caution:</b>
488517
@ This repository trusts that the HTTP_AUTHENITICATION environment
489518
@ variable set up by the webserver contains the name of an
490519
@ authenticated user.
491520
@ Fossil's built-in authentication mechanism is bypassed.
492
- @ <p>Fix this by deactivating the "Allow HTTP_AUTHENTICATION authentication"
521
+ @ Fix this by deactivating the "Allow HTTP_AUTHENTICATION authentication"
493522
@ checkbox on the <a href="setup_access">Access Control</a> page.
494523
}
495524
496525
/* Logging should be turned on
497526
*/
498527
if( db_get_boolean("access-log",0)==0 ){
499528
@ <li><p>
500529
@ The <a href="access_log">User Log</a> is disabled. The user log
501
- @ keeps a record of successful and unsucessful login attempts and is
530
+ @ keeps a record of successful and unsuccessful login attempts and is
502531
@ useful for security monitoring.
503532
}
504533
if( db_get_boolean("admin-log",0)==0 ){
505534
@ <li><p>
506535
@ The <a href="admin_log">Administrative Log</a> is disabled.
@@ -512,28 +541,29 @@
512541
/* Make sure that the load-average limiter is armed and working */
513542
if( load_average()==0.0 ){
514543
@ <li><p>
515544
@ Unable to get the system load average. This can prevent Fossil
516545
@ from throttling expensive operations during peak demand.
517
- @ <p>If running in a chroot jail on Linux, verify that the /proc
546
+ @ If running in a chroot jail on Linux, verify that the /proc
518547
@ filesystem is mounted within the jail, so that the load average
519548
@ can be obtained from the /proc/loadavg file.
520549
}else {
521550
double r = atof(db_get("max-loadavg", 0));
522551
if( r<=0.0 ){
523552
@ <li><p>
524553
@ Load average limiting is turned off. This can cause the server
525554
@ to bog down if many requests for expensive services (such as
526555
@ large diffs or tarballs) arrive at about the same time.
527
- @ <p>To fix this, set the "Server Load Average Limit" on the
528
- @ <a href="setup_access">Access Control</a> page to approximately
556
+ @ To fix this, set the
557
+ @ <a href='%R/setup_access#slal'>"Server Load Average Limit"</a> on the
558
+ @ <a href='%R/setup_access'>Access Control</a> page to the approximate
529559
@ the number of available cores on your server, or maybe just a little
530560
@ less.
531561
}else if( r>=8.0 ){
532562
@ <li><p>
533
- @ The "Server Load Average Limit" on the
534
- @ <a href="setup_access">Access Control</a> page is set to %g(r),
563
+ @ The <a href='%R/setup_access#slal'>"Server Load Average Limit"</a> on
564
+ @ the <a href="setup_access">Access Control</a> page is set to %g(r),
535565
@ which seems high. Is this server really a %d((int)r)-core machine?
536566
}
537567
}
538568
#endif
539569
540570
--- src/security_audit.c
+++ src/security_audit.c
@@ -144,17 +144,17 @@
144 @ immediately! Or, at least remove the Setup and Admin privileges
145 @ from the default permissions for new users.
146 }else if( hasAnyCap(zAnonCap,"y") ){
147 @ <li><p>This repository is <big><b>INSECURE</b></big> because
148 @ it allows anonymous users to push unversioned files.
149 @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
150 @ or by removing the "y" permission from users "anonymous" and
151 @ "nobody" on the <a href="setup_ulist">User Configuration</a> page.
152 }else if( hasAnyCap(zSelfCap,"y") ){
153 @ <li><p>This repository is <big><b>INSECURE</b></big> because
154 @ it allows self-registered users to push unversioned files.
155 @ <p>Fix this by <a href="takeitprivate">taking the repository private</a>
156 @ or by removing the "y" permission from the default permissions or
157 @ by disabling self-registration.
158 }else if( hasAnyCap(zAnonCap,"goz") ){
159 @ <li><p>This repository is <big><b>PUBLIC</b></big>. All
160 @ checked-in content can be accessed by anonymous users.
@@ -240,11 +240,11 @@
240 */
241 if( db_get_int("redirect-to-https",0)==0 ){
242 @ <li><p><b>WARNING:</b>
243 @ Sensitive material such as login passwords can be sent over an
244 @ unencrypted connection.
245 @ <p>Fix this by changing the "Redirect to HTTPS" setting on the
246 @ <a href="setup_access">Access Control</a> page. If you were using
247 @ the old "Redirect to HTTPS on Login Page" setting, switch to the
248 @ new setting: it has a more secure implementation.
249 }
250
@@ -282,11 +282,11 @@
282 */
283 if( hasAnyCap(zAnonCap, "e") ){
284 @ <li><p><b>WARNING:</b>
285 @ Anonymous users can view email addresses and other personally
286 @ identifiable information on tickets.
287 @ <p>Fix this by removing the "Email" privilege
288 @ (<a href="setup_ucap_list">capability "e"</a>) from users
289 @ "anonymous" and "nobody" on the
290 @ <a href="setup_ulist">User Configuration</a> page.
291 }
292
@@ -294,11 +294,11 @@
294 ** to the repository.
295 */
296 if( hasAnyCap(zAnonCap, "i") ){
297 @ <li><p><b>WARNING:</b>
298 @ Anonymous users can push new check-ins into the repository.
299 @ <p>Fix this by removing the "Check-in" privilege
300 @ (<a href="setup_ucap_list">capability</a> "i") from users
301 @ "anonymous" and "nobody" on the
302 @ <a href="setup_ulist">User Configuration</a> page.
303 }
304
@@ -307,11 +307,11 @@
307 */
308 if( hasAnyCap(zAnonCap, "lq5") ){
309 @ <li><p><b>WARNING:</b>
310 @ Anonymous users can act as moderators for wiki, tickets, or
311 @ forum posts. This defeats the whole purpose of moderation.
312 @ <p>Fix this by removing the "Mod-Wiki", "Mod-Tkt", and "Mod-Forum"
313 @ privileges (<a href="%R/setup_ucap_list">capabilities</a> "fq5")
314 @ from users "anonymous" and "nobody"
315 @ on the <a href="setup_ulist">User Configuration</a> page.
316 }
317
@@ -470,37 +470,66 @@
470 @ number of users (%d(n)).
471 @ Ideally, the Write-Unver privilege should only
472 @ be granted to one or two users.
473 }
474 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
476 /* Notify if REMOTE_USER or HTTP_AUTHENTICATION is used for login.
477 */
478 if( db_get_boolean("remote_user_ok", 0) ){
479 @ <li><p>
480 @ This repository trusts that the REMOTE_USER environment variable set
481 @ up by the webserver contains the name of an authenticated user.
482 @ Fossil's built-in authentication mechanism is bypassed.
483 @ <p>Fix this by deactivating the "Allow REMOTE_USER authentication"
484 @ checkbox on the <a href="setup_access">Access Control</a> page.
485 }
486 if( db_get_boolean("http_authentication_ok", 0) ){
487 @ <li><p>
488 @ This repository trusts that the HTTP_AUTHENITICATION environment
489 @ variable set up by the webserver contains the name of an
490 @ authenticated user.
491 @ Fossil's built-in authentication mechanism is bypassed.
492 @ <p>Fix this by deactivating the "Allow HTTP_AUTHENTICATION authentication"
493 @ checkbox on the <a href="setup_access">Access Control</a> page.
494 }
495
496 /* Logging should be turned on
497 */
498 if( db_get_boolean("access-log",0)==0 ){
499 @ <li><p>
500 @ The <a href="access_log">User Log</a> is disabled. The user log
501 @ keeps a record of successful and unsucessful login attempts and is
502 @ useful for security monitoring.
503 }
504 if( db_get_boolean("admin-log",0)==0 ){
505 @ <li><p>
506 @ The <a href="admin_log">Administrative Log</a> is disabled.
@@ -512,28 +541,29 @@
512 /* Make sure that the load-average limiter is armed and working */
513 if( load_average()==0.0 ){
514 @ <li><p>
515 @ Unable to get the system load average. This can prevent Fossil
516 @ from throttling expensive operations during peak demand.
517 @ <p>If running in a chroot jail on Linux, verify that the /proc
518 @ filesystem is mounted within the jail, so that the load average
519 @ can be obtained from the /proc/loadavg file.
520 }else {
521 double r = atof(db_get("max-loadavg", 0));
522 if( r<=0.0 ){
523 @ <li><p>
524 @ Load average limiting is turned off. This can cause the server
525 @ to bog down if many requests for expensive services (such as
526 @ large diffs or tarballs) arrive at about the same time.
527 @ <p>To fix this, set the "Server Load Average Limit" on the
528 @ <a href="setup_access">Access Control</a> page to approximately
 
529 @ the number of available cores on your server, or maybe just a little
530 @ less.
531 }else if( r>=8.0 ){
532 @ <li><p>
533 @ The "Server Load Average Limit" on the
534 @ <a href="setup_access">Access Control</a> page is set to %g(r),
535 @ which seems high. Is this server really a %d((int)r)-core machine?
536 }
537 }
538 #endif
539
540
--- src/security_audit.c
+++ src/security_audit.c
@@ -144,17 +144,17 @@
144 @ immediately! Or, at least remove the Setup and Admin privileges
145 @ from the default permissions for new users.
146 }else if( hasAnyCap(zAnonCap,"y") ){
147 @ <li><p>This repository is <big><b>INSECURE</b></big> because
148 @ it allows anonymous users to push unversioned files.
149 @ Fix this by <a href="takeitprivate">taking the repository private</a>
150 @ or by removing the "y" permission from users "anonymous" and
151 @ "nobody" on the <a href="setup_ulist">User Configuration</a> page.
152 }else if( hasAnyCap(zSelfCap,"y") ){
153 @ <li><p>This repository is <big><b>INSECURE</b></big> because
154 @ it allows self-registered users to push unversioned files.
155 @ Fix this by <a href="takeitprivate">taking the repository private</a>
156 @ or by removing the "y" permission from the default permissions or
157 @ by disabling self-registration.
158 }else if( hasAnyCap(zAnonCap,"goz") ){
159 @ <li><p>This repository is <big><b>PUBLIC</b></big>. All
160 @ checked-in content can be accessed by anonymous users.
@@ -240,11 +240,11 @@
240 */
241 if( db_get_int("redirect-to-https",0)==0 ){
242 @ <li><p><b>WARNING:</b>
243 @ Sensitive material such as login passwords can be sent over an
244 @ unencrypted connection.
245 @ Fix this by changing the "Redirect to HTTPS" setting on the
246 @ <a href="setup_access">Access Control</a> page. If you were using
247 @ the old "Redirect to HTTPS on Login Page" setting, switch to the
248 @ new setting: it has a more secure implementation.
249 }
250
@@ -282,11 +282,11 @@
282 */
283 if( hasAnyCap(zAnonCap, "e") ){
284 @ <li><p><b>WARNING:</b>
285 @ Anonymous users can view email addresses and other personally
286 @ identifiable information on tickets.
287 @ Fix this by removing the "Email" privilege
288 @ (<a href="setup_ucap_list">capability "e"</a>) from users
289 @ "anonymous" and "nobody" on the
290 @ <a href="setup_ulist">User Configuration</a> page.
291 }
292
@@ -294,11 +294,11 @@
294 ** to the repository.
295 */
296 if( hasAnyCap(zAnonCap, "i") ){
297 @ <li><p><b>WARNING:</b>
298 @ Anonymous users can push new check-ins into the repository.
299 @ Fix this by removing the "Check-in" privilege
300 @ (<a href="setup_ucap_list">capability</a> "i") from users
301 @ "anonymous" and "nobody" on the
302 @ <a href="setup_ulist">User Configuration</a> page.
303 }
304
@@ -307,11 +307,11 @@
307 */
308 if( hasAnyCap(zAnonCap, "lq5") ){
309 @ <li><p><b>WARNING:</b>
310 @ Anonymous users can act as moderators for wiki, tickets, or
311 @ forum posts. This defeats the whole purpose of moderation.
312 @ Fix this by removing the "Mod-Wiki", "Mod-Tkt", and "Mod-Forum"
313 @ privileges (<a href="%R/setup_ucap_list">capabilities</a> "fq5")
314 @ from users "anonymous" and "nobody"
315 @ on the <a href="setup_ulist">User Configuration</a> page.
316 }
317
@@ -470,37 +470,66 @@
470 @ number of users (%d(n)).
471 @ Ideally, the Write-Unver privilege should only
472 @ be granted to one or two users.
473 }
474 }
475
476 /* Providing hyperlink capability to user "nobody" can lead to robots
477 ** making excessive requests resulting in DoS
478 */
479 if( db_exists("SELECT 1 FROM user WHERE login='nobody' AND cap GLOB '*h*'") ){
480 int nobodyId = db_int(0,"SELECT uid FROM user WHERE login='nobody'");
481 int anonId = db_int(0,
482 "SELECT uid FROM user WHERE login='anonymous' AND cap NOT GLOB '*h*'");
483 @ <li><p>
484 @ User "nobody" has "Hyperlink" privilege ('h') which can lead to
485 @ robots walking a nearly endless progression of pages on public-facing
486 @ repositories, causing excessive server load and possible DoS.
487 @ Suggested remediation:
488 @ <ol type="a">
489 @ <li>Remove the 'h' privilege from the
490 @ <a href="%R/setup_uedit?id=%d(nobodyId)">'nobody' user</a> so that
491 @ robots cannot see hyperlinks.
492 @ <li>Activate <a href="%R/setup_robot">autohyperlink</a> so that
493 @ human readers can still see hyperlinks even if they are not logged in.
494 @ Set the delay to at least 50 milliseconds and require a mouse
495 @ event for maximum robot defense.
496 if( anonId>0 ){
497 @ <li>Perhaps set the 'h' privilege on the
498 @ <a href="%R/setup_uedit?id=%d(anonId)">'anonymous' user</a> so
499 @ that humans that have javascript disabled in their browsers can
500 @ still see hyperlinks if they will log in as "anonymous".
501 }
502 @ </ol>
503 }
504
505 /* Notify if REMOTE_USER or HTTP_AUTHENTICATION is used for login.
506 */
507 if( db_get_boolean("remote_user_ok", 0) ){
508 @ <li><p><b>Caution:</b>
509 @ This repository trusts that the REMOTE_USER environment variable set
510 @ up by the webserver contains the name of an authenticated user.
511 @ Fossil's built-in authentication mechanism is bypassed.
512 @ Fix this by deactivating the "Allow REMOTE_USER authentication"
513 @ checkbox on the <a href="setup_access">Access Control</a> page.
514 }
515 if( db_get_boolean("http_authentication_ok", 0) ){
516 @ <li><p><b>Caution:</b>
517 @ This repository trusts that the HTTP_AUTHENITICATION environment
518 @ variable set up by the webserver contains the name of an
519 @ authenticated user.
520 @ Fossil's built-in authentication mechanism is bypassed.
521 @ Fix this by deactivating the "Allow HTTP_AUTHENTICATION authentication"
522 @ checkbox on the <a href="setup_access">Access Control</a> page.
523 }
524
525 /* Logging should be turned on
526 */
527 if( db_get_boolean("access-log",0)==0 ){
528 @ <li><p>
529 @ The <a href="access_log">User Log</a> is disabled. The user log
530 @ keeps a record of successful and unsuccessful login attempts and is
531 @ useful for security monitoring.
532 }
533 if( db_get_boolean("admin-log",0)==0 ){
534 @ <li><p>
535 @ The <a href="admin_log">Administrative Log</a> is disabled.
@@ -512,28 +541,29 @@
541 /* Make sure that the load-average limiter is armed and working */
542 if( load_average()==0.0 ){
543 @ <li><p>
544 @ Unable to get the system load average. This can prevent Fossil
545 @ from throttling expensive operations during peak demand.
546 @ If running in a chroot jail on Linux, verify that the /proc
547 @ filesystem is mounted within the jail, so that the load average
548 @ can be obtained from the /proc/loadavg file.
549 }else {
550 double r = atof(db_get("max-loadavg", 0));
551 if( r<=0.0 ){
552 @ <li><p>
553 @ Load average limiting is turned off. This can cause the server
554 @ to bog down if many requests for expensive services (such as
555 @ large diffs or tarballs) arrive at about the same time.
556 @ To fix this, set the
557 @ <a href='%R/setup_access#slal'>"Server Load Average Limit"</a> on the
558 @ <a href='%R/setup_access'>Access Control</a> page to the approximate
559 @ the number of available cores on your server, or maybe just a little
560 @ less.
561 }else if( r>=8.0 ){
562 @ <li><p>
563 @ The <a href='%R/setup_access#slal'>"Server Load Average Limit"</a> on
564 @ the <a href="setup_access">Access Control</a> page is set to %g(r),
565 @ which seems high. Is this server really a %d((int)r)-core machine?
566 }
567 }
568 #endif
569
570
+110 -42
--- src/setup.c
+++ src/setup.c
@@ -111,10 +111,12 @@
111111
"Configure the WWW components of the repository");
112112
}
113113
setup_menu_entry("Security-Audit", "secaudit0",
114114
"Analyze the current configuration for security problems");
115115
if( setup_user ){
116
+ setup_menu_entry("Robot-Defense", "setup_robot",
117
+ "Settings for configure defense against robots");
116118
setup_menu_entry("Settings", "setup_settings",
117119
"Web interface to the \"fossil settings\" command");
118120
}
119121
setup_menu_entry("Timeline", "setup_timeline",
120122
"Timeline display preferences");
@@ -208,11 +210,11 @@
208210
zVar, iQ ? "on" : "off");
209211
iVal = iQ;
210212
}
211213
}
212214
@ <label><input type="checkbox" name="%s(zQParm)" \
213
- @ aria-label="%s(zLabel[0]?zLabel:zQParm)" \
215
+ @ aria-label="%h(zLabel[0]?zLabel:zQParm)" \
214216
if( iVal ){
215217
@ checked="checked" \
216218
}
217219
if( disabled ){
218220
@ disabled="disabled" \
@@ -322,10 +324,105 @@
322324
@ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option>
323325
}
324326
@ </select> <b>%h(zLabel)</b>
325327
}
326328
329
+/*
330
+** Insert code into the current page that allows the user to configure
331
+** auto-hyperlink related robot defense settings.
332
+*/
333
+static void addAutoHyperlinkSettings(void){
334
+ static const char *const azDefenseOpts[] = {
335
+ "0", "Off",
336
+ "2", "UserAgent only",
337
+ "1", "UserAgent and Javascript",
338
+ };
339
+ multiple_choice_attribute(
340
+ "Enable hyperlinks base on User-Agent and/or Javascript",
341
+ "auto-hyperlink", "autohyperlink", "1",
342
+ count(azDefenseOpts)/2, azDefenseOpts);
343
+ @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users,
344
+ @ including user "nobody", as long as the User-Agent string in the
345
+ @ HTTP header indicates that the request is coming from an actual human
346
+ @ being. If this setting is "UserAgent only" (2) then the
347
+ @ UserAgent string is the only factor considered. If the value of this
348
+ @ setting is "UserAgent And Javascript" (1) then Javascript is added that
349
+ @ runs after the page loads and fills in the href= values of &lt;a&gt;
350
+ @ elements. In either case, &lt;a&gt; tags are only generated if the
351
+ @ UserAgent string indicates that the request is coming from a human and
352
+ @ not a robot.
353
+ @
354
+ @ <p>This setting is designed to give easy access to humans while
355
+ @ keeping out robots.
356
+ @ You do not normally want a robot to walk your entire repository because
357
+ @ if it does, your server will end up computing diffs and annotations for
358
+ @ every historical version of every file and creating ZIPs and tarballs of
359
+ @ every historical check-in, which can use a lot of CPU and bandwidth
360
+ @ even for relatively small projects.</p>
361
+ @
362
+ @ <p>The "UserAgent and Javascript" value for this setting provides
363
+ @ superior protection from robots. However, that setting also prevents
364
+ @ the visited/unvisited colors on hyperlinks from displaying correctly
365
+ @ on Safari-derived browsers. (Chrome and Firefox work fine.) Since
366
+ @ Safari is the underlying rendering engine on all iPhones and iPads,
367
+ @ this means that hyperlink visited/unvisited colors will not operate
368
+ @ on those platforms when "UserAgent and Javascript" is selected.</p>
369
+ @
370
+ @ <p>Additional parameters that control the behavior of Javascript:</p>
371
+ @ <blockquote>
372
+ entry_attribute("Delay in milliseconds before enabling hyperlinks", 5,
373
+ "auto-hyperlink-delay", "ah-delay", "50", 0);
374
+ @ <br />
375
+ onoff_attribute("Also require a mouse event before enabling hyperlinks",
376
+ "auto-hyperlink-mouseover", "ahmo", 0, 0);
377
+ @ </blockquote>
378
+ @ <p>For maximum robot defense, "Delay" should be at least 50 milliseconds
379
+ @ and "require a mouse event" should be turned on. These values only come
380
+ @ into play when the main auto-hyperlink settings is 2 ("UserAgent and
381
+ @ Javascript").</p>
382
+ @
383
+ @ <p>To see if Javascript-base hyperlink enabling mechanism is working,
384
+ @ visit the <a href="%R/test_env">/test_env</a> page (from a separate
385
+ @ web browser that is not logged in, even as "anonymous") and verify
386
+ @ that the "g.jsHref" value is "1".</p>
387
+ @ <p>(Properties: "auto-hyperlink", "auto-hyperlink-delay", and
388
+ @ "auto-hyperlink-mouseover"")</p>
389
+}
390
+
391
+/*
392
+** WEBPAGE: setup_robot
393
+**
394
+** Settings associated with defense against robots. Requires setup privilege.
395
+*/
396
+void setup_robots(void){
397
+ login_check_credentials();
398
+ if( !g.perm.Setup ){
399
+ login_needed(0);
400
+ return;
401
+ }
402
+ style_set_current_feature("setup");
403
+ style_header("Robot Defense Settings");
404
+ db_begin_transaction();
405
+ @ <p>A Fossil website can have billions of pages in its tree, even for a
406
+ @ modest project. Many of those pages (examples: diffs and tarballs)
407
+ @ might be expensive to compute. A robot that tries to walk the entire
408
+ @ website can present a crippling CPU and bandwidth load.
409
+ @
410
+ @ <p>The settings on this page are intended to help site administrators
411
+ @ defend the site against robots.
412
+ @
413
+ @ <form action="%R/setup_robot" method="post"><div>
414
+ login_insert_csrf_secret();
415
+ @ <input type="submit" name="submit" value="Apply Changes" /></p>
416
+ @ <hr />
417
+ addAutoHyperlinkSettings();
418
+ @ <hr />
419
+ @ <p><input type="submit" name="submit" value="Apply Changes" /></p>
420
+ @ </div></form>
421
+ db_end_transaction(0);
422
+ style_finish_page();
423
+}
327424
328425
/*
329426
** WEBPAGE: setup_access
330427
**
331428
** The access-control settings page. Requires Setup privileges.
@@ -447,10 +544,11 @@
447544
@ the out-bound data of sync, clone, and pull packets.
448545
@ If the client request takes longer, a partial reply is given similar
449546
@ to the download packet limit. 30s is a reasonable default.
450547
@ (Property: "max-download-time")</p>
451548
549
+ @ <a id="slal"></a>
452550
@ <hr />
453551
entry_attribute("Server Load Average Limit", 11, "max-loadavg", "mxldavg",
454552
"0.0", 0);
455553
@ <p>Some expensive operations (such as computing tarballs, zip archives,
456554
@ or annotation/blame pages) are prohibited if the load average on the host
@@ -459,44 +557,15 @@
459557
@ This limit is only enforced on Unix servers. On Linux systems,
460558
@ access to the /proc virtual filesystem is required, which means this limit
461559
@ might not work inside a chroot() jail.
462560
@ (Property: "max-loadavg")</p>
463561
562
+ /* Add the auto-hyperlink settings controls. These same controls
563
+ ** are also accessible from the /setup_robot page.
564
+ */
464565
@ <hr />
465
- onoff_attribute(
466
- "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
467
- "auto-hyperlink", "autohyperlink", 1, 0);
468
- @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users,
469
- @ including user "nobody", as long as
470
- @ <ol><li>the User-Agent string in the
471
- @ HTTP header indicates that the request is coming from an actual human
472
- @ being, and
473
- @ <li>the user agent is able to
474
- @ run Javascript in order to set the href= attribute of hyperlinks, and
475
- @ <li>mouse movement is detected (optional - see the checkbox below), and
476
- @ <li>a number of milliseconds have passed since the page loaded.</ol>
477
- @
478
- @ <p>This setting is designed to give easy access to humans while
479
- @ keeping out robots and spiders.
480
- @ You do not normally want a robot to walk your entire repository because
481
- @ if it does, your server will end up computing diffs and annotations for
482
- @ every historical version of every file and creating ZIPs and tarballs of
483
- @ every historical check-in, which can use a lot of CPU and bandwidth
484
- @ even for relatively small projects.</p>
485
- @
486
- @ <p>Additional parameters that control this behavior:</p>
487
- @ <blockquote>
488
- onoff_attribute("Require mouse movement before enabling hyperlinks",
489
- "auto-hyperlink-mouseover", "ahmo", 0, 0);
490
- @ <br />
491
- entry_attribute("Delay in milliseconds before enabling hyperlinks", 5,
492
- "auto-hyperlink-delay", "ah-delay", "50", 0);
493
- @ </blockquote>
494
- @ <p>For maximum robot defense, the "require mouse movement" should
495
- @ be turned on and the "Delay" should be at least 50 milliseconds.</p>
496
- @ (Properties: "auto-hyperlink",
497
- @ "auto-hyperlink-mouseover", and "auto-hyperlink-delay")</p>
566
+ addAutoHyperlinkSettings();
498567
499568
@ <hr />
500569
onoff_attribute("Require a CAPTCHA if not logged in",
501570
"require-captcha", "reqcapt", 1, 0);
502571
@ <p>Require a CAPTCHA for edit operations (appending, creating, or
@@ -962,11 +1031,11 @@
9621031
** * The second term is a hyperlink to take when a user clicks on the
9631032
** entry. Hyperlinks that start with "/" are relative to the
9641033
** repository root.
9651034
**
9661035
** * The third term is an argument to the TH1 "capexpr" command.
967
-** If capexpr evalutes to true, then the entry is shown. If not,
1036
+** If capexpr evaluates to true, then the entry is shown. If not,
9681037
** the entry is omitted. "*" is always true. "{}" is never true.
9691038
**
9701039
** * The fourth term is a list of extra class names to apply to the
9711040
** new menu entry. Some skins use classes "desktoponly" and
9721041
** "wideonly" to only show the entries when the web browser
@@ -993,11 +1062,11 @@
9931062
** * The second term is a hyperlink to take when a user clicks on the
9941063
** entry. Hyperlinks that start with "/" are relative to the
9951064
** repository root.
9961065
**
9971066
** * The third term is an argument to the TH1 "capexpr" command.
998
-** If capexpr evalutes to true, then the entry is shown. If not,
1067
+** If capexpr evaluates to true, then the entry is shown. If not,
9991068
** the entry is omitted. "*" is always true.
10001069
**
10011070
** The default value is blank, meaning no added entries.
10021071
*/
10031072
@@ -1093,11 +1162,11 @@
10931162
@ <li> The first term is text that appears on the menu.
10941163
@ <li> The second term is a hyperlink to take when a user clicks on the
10951164
@ entry. Hyperlinks that start with "/" are relative to the
10961165
@ repository root.
10971166
@ <li> The third term is an argument to the TH1 "capexpr" command.
1098
- @ If capexpr evalutes to true, then the entry is shown. If not,
1167
+ @ If capexpr evaluates to true, then the entry is shown. If not,
10991168
@ the entry is omitted. "*" is always true. "{}" is never true.
11001169
@ <li> The fourth term is a list of extra class names to apply to the new
11011170
@ menu entry. Some skins use classes "desktoponly" and "wideonly"
11021171
@ to only show the entries when the web browser screen is wide or
11031172
@ very wide, respectively.
@@ -1131,11 +1200,11 @@
11311200
@ <li> The first term is the display name of the /sitemap entry
11321201
@ <li> The second term is a hyperlink to take when a user clicks on the
11331202
@ entry. Hyperlinks that start with "/" are relative to the
11341203
@ repository root.
11351204
@ <li> The third term is an argument to the TH1 "capexpr" command.
1136
- @ If capexpr evalutes to true, then the entry is shown. If not,
1205
+ @ If capexpr evaluates to true, then the entry is shown. If not,
11371206
@ the entry is omitted. "*" is always true.
11381207
@ </ol>
11391208
@
11401209
@ <p>The default value is blank, meaning no added entries.
11411210
@ (Property: sitemap-extra)
@@ -1729,13 +1798,11 @@
17291798
zQ = sqlite3_mprintf(
17301799
"SELECT sql FROM repository.sqlite_schema"
17311800
" WHERE sql IS NOT NULL ORDER BY name");
17321801
go = 1;
17331802
}else if( P("tablelist") ){
1734
- zQ = sqlite3_mprintf(
1735
- "SELECT name FROM repository.sqlite_schema WHERE type='table'"
1736
- " ORDER BY name");
1803
+ zQ = sqlite3_mprintf("SELECT*FROM pragma_table_list ORDER BY schema, name");
17371804
go = 1;
17381805
}
17391806
if( go ){
17401807
sqlite3_stmt *pStmt;
17411808
int rc;
@@ -1744,10 +1811,11 @@
17441811
int nRow = 0;
17451812
int i;
17461813
@ <hr />
17471814
login_verify_csrf_secret();
17481815
sqlite3_set_authorizer(g.db, raw_sql_query_authorizer, 0);
1816
+ search_sql_setup(g.db);
17491817
rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail);
17501818
if( rc!=SQLITE_OK ){
17511819
@ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
17521820
sqlite3_finalize(pStmt);
17531821
}else if( pStmt==0 ){
@@ -1757,11 +1825,11 @@
17571825
rc = sqlite3_finalize(pStmt);
17581826
if( rc ){
17591827
@ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
17601828
}
17611829
}else{
1762
- @ <table border=1>
1830
+ @ <table border="1" cellpadding="4" cellspacing="0">
17631831
while( sqlite3_step(pStmt)==SQLITE_ROW ){
17641832
if( nRow==0 ){
17651833
@ <tr>
17661834
for(i=0; i<nCol; i++){
17671835
@ <th>%h(sqlite3_column_name(pStmt, i))</th>
17681836
--- src/setup.c
+++ src/setup.c
@@ -111,10 +111,12 @@
111 "Configure the WWW components of the repository");
112 }
113 setup_menu_entry("Security-Audit", "secaudit0",
114 "Analyze the current configuration for security problems");
115 if( setup_user ){
 
 
116 setup_menu_entry("Settings", "setup_settings",
117 "Web interface to the \"fossil settings\" command");
118 }
119 setup_menu_entry("Timeline", "setup_timeline",
120 "Timeline display preferences");
@@ -208,11 +210,11 @@
208 zVar, iQ ? "on" : "off");
209 iVal = iQ;
210 }
211 }
212 @ <label><input type="checkbox" name="%s(zQParm)" \
213 @ aria-label="%s(zLabel[0]?zLabel:zQParm)" \
214 if( iVal ){
215 @ checked="checked" \
216 }
217 if( disabled ){
218 @ disabled="disabled" \
@@ -322,10 +324,105 @@
322 @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option>
323 }
324 @ </select> <b>%h(zLabel)</b>
325 }
326
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
328 /*
329 ** WEBPAGE: setup_access
330 **
331 ** The access-control settings page. Requires Setup privileges.
@@ -447,10 +544,11 @@
447 @ the out-bound data of sync, clone, and pull packets.
448 @ If the client request takes longer, a partial reply is given similar
449 @ to the download packet limit. 30s is a reasonable default.
450 @ (Property: "max-download-time")</p>
451
 
452 @ <hr />
453 entry_attribute("Server Load Average Limit", 11, "max-loadavg", "mxldavg",
454 "0.0", 0);
455 @ <p>Some expensive operations (such as computing tarballs, zip archives,
456 @ or annotation/blame pages) are prohibited if the load average on the host
@@ -459,44 +557,15 @@
459 @ This limit is only enforced on Unix servers. On Linux systems,
460 @ access to the /proc virtual filesystem is required, which means this limit
461 @ might not work inside a chroot() jail.
462 @ (Property: "max-loadavg")</p>
463
 
 
 
464 @ <hr />
465 onoff_attribute(
466 "Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
467 "auto-hyperlink", "autohyperlink", 1, 0);
468 @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users,
469 @ including user "nobody", as long as
470 @ <ol><li>the User-Agent string in the
471 @ HTTP header indicates that the request is coming from an actual human
472 @ being, and
473 @ <li>the user agent is able to
474 @ run Javascript in order to set the href= attribute of hyperlinks, and
475 @ <li>mouse movement is detected (optional - see the checkbox below), and
476 @ <li>a number of milliseconds have passed since the page loaded.</ol>
477 @
478 @ <p>This setting is designed to give easy access to humans while
479 @ keeping out robots and spiders.
480 @ You do not normally want a robot to walk your entire repository because
481 @ if it does, your server will end up computing diffs and annotations for
482 @ every historical version of every file and creating ZIPs and tarballs of
483 @ every historical check-in, which can use a lot of CPU and bandwidth
484 @ even for relatively small projects.</p>
485 @
486 @ <p>Additional parameters that control this behavior:</p>
487 @ <blockquote>
488 onoff_attribute("Require mouse movement before enabling hyperlinks",
489 "auto-hyperlink-mouseover", "ahmo", 0, 0);
490 @ <br />
491 entry_attribute("Delay in milliseconds before enabling hyperlinks", 5,
492 "auto-hyperlink-delay", "ah-delay", "50", 0);
493 @ </blockquote>
494 @ <p>For maximum robot defense, the "require mouse movement" should
495 @ be turned on and the "Delay" should be at least 50 milliseconds.</p>
496 @ (Properties: "auto-hyperlink",
497 @ "auto-hyperlink-mouseover", and "auto-hyperlink-delay")</p>
498
499 @ <hr />
500 onoff_attribute("Require a CAPTCHA if not logged in",
501 "require-captcha", "reqcapt", 1, 0);
502 @ <p>Require a CAPTCHA for edit operations (appending, creating, or
@@ -962,11 +1031,11 @@
962 ** * The second term is a hyperlink to take when a user clicks on the
963 ** entry. Hyperlinks that start with "/" are relative to the
964 ** repository root.
965 **
966 ** * The third term is an argument to the TH1 "capexpr" command.
967 ** If capexpr evalutes to true, then the entry is shown. If not,
968 ** the entry is omitted. "*" is always true. "{}" is never true.
969 **
970 ** * The fourth term is a list of extra class names to apply to the
971 ** new menu entry. Some skins use classes "desktoponly" and
972 ** "wideonly" to only show the entries when the web browser
@@ -993,11 +1062,11 @@
993 ** * The second term is a hyperlink to take when a user clicks on the
994 ** entry. Hyperlinks that start with "/" are relative to the
995 ** repository root.
996 **
997 ** * The third term is an argument to the TH1 "capexpr" command.
998 ** If capexpr evalutes to true, then the entry is shown. If not,
999 ** the entry is omitted. "*" is always true.
1000 **
1001 ** The default value is blank, meaning no added entries.
1002 */
1003
@@ -1093,11 +1162,11 @@
1093 @ <li> The first term is text that appears on the menu.
1094 @ <li> The second term is a hyperlink to take when a user clicks on the
1095 @ entry. Hyperlinks that start with "/" are relative to the
1096 @ repository root.
1097 @ <li> The third term is an argument to the TH1 "capexpr" command.
1098 @ If capexpr evalutes to true, then the entry is shown. If not,
1099 @ the entry is omitted. "*" is always true. "{}" is never true.
1100 @ <li> The fourth term is a list of extra class names to apply to the new
1101 @ menu entry. Some skins use classes "desktoponly" and "wideonly"
1102 @ to only show the entries when the web browser screen is wide or
1103 @ very wide, respectively.
@@ -1131,11 +1200,11 @@
1131 @ <li> The first term is the display name of the /sitemap entry
1132 @ <li> The second term is a hyperlink to take when a user clicks on the
1133 @ entry. Hyperlinks that start with "/" are relative to the
1134 @ repository root.
1135 @ <li> The third term is an argument to the TH1 "capexpr" command.
1136 @ If capexpr evalutes to true, then the entry is shown. If not,
1137 @ the entry is omitted. "*" is always true.
1138 @ </ol>
1139 @
1140 @ <p>The default value is blank, meaning no added entries.
1141 @ (Property: sitemap-extra)
@@ -1729,13 +1798,11 @@
1729 zQ = sqlite3_mprintf(
1730 "SELECT sql FROM repository.sqlite_schema"
1731 " WHERE sql IS NOT NULL ORDER BY name");
1732 go = 1;
1733 }else if( P("tablelist") ){
1734 zQ = sqlite3_mprintf(
1735 "SELECT name FROM repository.sqlite_schema WHERE type='table'"
1736 " ORDER BY name");
1737 go = 1;
1738 }
1739 if( go ){
1740 sqlite3_stmt *pStmt;
1741 int rc;
@@ -1744,10 +1811,11 @@
1744 int nRow = 0;
1745 int i;
1746 @ <hr />
1747 login_verify_csrf_secret();
1748 sqlite3_set_authorizer(g.db, raw_sql_query_authorizer, 0);
 
1749 rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail);
1750 if( rc!=SQLITE_OK ){
1751 @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
1752 sqlite3_finalize(pStmt);
1753 }else if( pStmt==0 ){
@@ -1757,11 +1825,11 @@
1757 rc = sqlite3_finalize(pStmt);
1758 if( rc ){
1759 @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
1760 }
1761 }else{
1762 @ <table border=1>
1763 while( sqlite3_step(pStmt)==SQLITE_ROW ){
1764 if( nRow==0 ){
1765 @ <tr>
1766 for(i=0; i<nCol; i++){
1767 @ <th>%h(sqlite3_column_name(pStmt, i))</th>
1768
--- src/setup.c
+++ src/setup.c
@@ -111,10 +111,12 @@
111 "Configure the WWW components of the repository");
112 }
113 setup_menu_entry("Security-Audit", "secaudit0",
114 "Analyze the current configuration for security problems");
115 if( setup_user ){
116 setup_menu_entry("Robot-Defense", "setup_robot",
117 "Settings for configure defense against robots");
118 setup_menu_entry("Settings", "setup_settings",
119 "Web interface to the \"fossil settings\" command");
120 }
121 setup_menu_entry("Timeline", "setup_timeline",
122 "Timeline display preferences");
@@ -208,11 +210,11 @@
210 zVar, iQ ? "on" : "off");
211 iVal = iQ;
212 }
213 }
214 @ <label><input type="checkbox" name="%s(zQParm)" \
215 @ aria-label="%h(zLabel[0]?zLabel:zQParm)" \
216 if( iVal ){
217 @ checked="checked" \
218 }
219 if( disabled ){
220 @ disabled="disabled" \
@@ -322,10 +324,105 @@
324 @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option>
325 }
326 @ </select> <b>%h(zLabel)</b>
327 }
328
329 /*
330 ** Insert code into the current page that allows the user to configure
331 ** auto-hyperlink related robot defense settings.
332 */
333 static void addAutoHyperlinkSettings(void){
334 static const char *const azDefenseOpts[] = {
335 "0", "Off",
336 "2", "UserAgent only",
337 "1", "UserAgent and Javascript",
338 };
339 multiple_choice_attribute(
340 "Enable hyperlinks base on User-Agent and/or Javascript",
341 "auto-hyperlink", "autohyperlink", "1",
342 count(azDefenseOpts)/2, azDefenseOpts);
343 @ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users,
344 @ including user "nobody", as long as the User-Agent string in the
345 @ HTTP header indicates that the request is coming from an actual human
346 @ being. If this setting is "UserAgent only" (2) then the
347 @ UserAgent string is the only factor considered. If the value of this
348 @ setting is "UserAgent And Javascript" (1) then Javascript is added that
349 @ runs after the page loads and fills in the href= values of &lt;a&gt;
350 @ elements. In either case, &lt;a&gt; tags are only generated if the
351 @ UserAgent string indicates that the request is coming from a human and
352 @ not a robot.
353 @
354 @ <p>This setting is designed to give easy access to humans while
355 @ keeping out robots.
356 @ You do not normally want a robot to walk your entire repository because
357 @ if it does, your server will end up computing diffs and annotations for
358 @ every historical version of every file and creating ZIPs and tarballs of
359 @ every historical check-in, which can use a lot of CPU and bandwidth
360 @ even for relatively small projects.</p>
361 @
362 @ <p>The "UserAgent and Javascript" value for this setting provides
363 @ superior protection from robots. However, that setting also prevents
364 @ the visited/unvisited colors on hyperlinks from displaying correctly
365 @ on Safari-derived browsers. (Chrome and Firefox work fine.) Since
366 @ Safari is the underlying rendering engine on all iPhones and iPads,
367 @ this means that hyperlink visited/unvisited colors will not operate
368 @ on those platforms when "UserAgent and Javascript" is selected.</p>
369 @
370 @ <p>Additional parameters that control the behavior of Javascript:</p>
371 @ <blockquote>
372 entry_attribute("Delay in milliseconds before enabling hyperlinks", 5,
373 "auto-hyperlink-delay", "ah-delay", "50", 0);
374 @ <br />
375 onoff_attribute("Also require a mouse event before enabling hyperlinks",
376 "auto-hyperlink-mouseover", "ahmo", 0, 0);
377 @ </blockquote>
378 @ <p>For maximum robot defense, "Delay" should be at least 50 milliseconds
379 @ and "require a mouse event" should be turned on. These values only come
380 @ into play when the main auto-hyperlink settings is 2 ("UserAgent and
381 @ Javascript").</p>
382 @
383 @ <p>To see if Javascript-base hyperlink enabling mechanism is working,
384 @ visit the <a href="%R/test_env">/test_env</a> page (from a separate
385 @ web browser that is not logged in, even as "anonymous") and verify
386 @ that the "g.jsHref" value is "1".</p>
387 @ <p>(Properties: "auto-hyperlink", "auto-hyperlink-delay", and
388 @ "auto-hyperlink-mouseover"")</p>
389 }
390
391 /*
392 ** WEBPAGE: setup_robot
393 **
394 ** Settings associated with defense against robots. Requires setup privilege.
395 */
396 void setup_robots(void){
397 login_check_credentials();
398 if( !g.perm.Setup ){
399 login_needed(0);
400 return;
401 }
402 style_set_current_feature("setup");
403 style_header("Robot Defense Settings");
404 db_begin_transaction();
405 @ <p>A Fossil website can have billions of pages in its tree, even for a
406 @ modest project. Many of those pages (examples: diffs and tarballs)
407 @ might be expensive to compute. A robot that tries to walk the entire
408 @ website can present a crippling CPU and bandwidth load.
409 @
410 @ <p>The settings on this page are intended to help site administrators
411 @ defend the site against robots.
412 @
413 @ <form action="%R/setup_robot" method="post"><div>
414 login_insert_csrf_secret();
415 @ <input type="submit" name="submit" value="Apply Changes" /></p>
416 @ <hr />
417 addAutoHyperlinkSettings();
418 @ <hr />
419 @ <p><input type="submit" name="submit" value="Apply Changes" /></p>
420 @ </div></form>
421 db_end_transaction(0);
422 style_finish_page();
423 }
424
425 /*
426 ** WEBPAGE: setup_access
427 **
428 ** The access-control settings page. Requires Setup privileges.
@@ -447,10 +544,11 @@
544 @ the out-bound data of sync, clone, and pull packets.
545 @ If the client request takes longer, a partial reply is given similar
546 @ to the download packet limit. 30s is a reasonable default.
547 @ (Property: "max-download-time")</p>
548
549 @ <a id="slal"></a>
550 @ <hr />
551 entry_attribute("Server Load Average Limit", 11, "max-loadavg", "mxldavg",
552 "0.0", 0);
553 @ <p>Some expensive operations (such as computing tarballs, zip archives,
554 @ or annotation/blame pages) are prohibited if the load average on the host
@@ -459,44 +557,15 @@
557 @ This limit is only enforced on Unix servers. On Linux systems,
558 @ access to the /proc virtual filesystem is required, which means this limit
559 @ might not work inside a chroot() jail.
560 @ (Property: "max-loadavg")</p>
561
562 /* Add the auto-hyperlink settings controls. These same controls
563 ** are also accessible from the /setup_robot page.
564 */
565 @ <hr />
566 addAutoHyperlinkSettings();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
567
568 @ <hr />
569 onoff_attribute("Require a CAPTCHA if not logged in",
570 "require-captcha", "reqcapt", 1, 0);
571 @ <p>Require a CAPTCHA for edit operations (appending, creating, or
@@ -962,11 +1031,11 @@
1031 ** * The second term is a hyperlink to take when a user clicks on the
1032 ** entry. Hyperlinks that start with "/" are relative to the
1033 ** repository root.
1034 **
1035 ** * The third term is an argument to the TH1 "capexpr" command.
1036 ** If capexpr evaluates to true, then the entry is shown. If not,
1037 ** the entry is omitted. "*" is always true. "{}" is never true.
1038 **
1039 ** * The fourth term is a list of extra class names to apply to the
1040 ** new menu entry. Some skins use classes "desktoponly" and
1041 ** "wideonly" to only show the entries when the web browser
@@ -993,11 +1062,11 @@
1062 ** * The second term is a hyperlink to take when a user clicks on the
1063 ** entry. Hyperlinks that start with "/" are relative to the
1064 ** repository root.
1065 **
1066 ** * The third term is an argument to the TH1 "capexpr" command.
1067 ** If capexpr evaluates to true, then the entry is shown. If not,
1068 ** the entry is omitted. "*" is always true.
1069 **
1070 ** The default value is blank, meaning no added entries.
1071 */
1072
@@ -1093,11 +1162,11 @@
1162 @ <li> The first term is text that appears on the menu.
1163 @ <li> The second term is a hyperlink to take when a user clicks on the
1164 @ entry. Hyperlinks that start with "/" are relative to the
1165 @ repository root.
1166 @ <li> The third term is an argument to the TH1 "capexpr" command.
1167 @ If capexpr evaluates to true, then the entry is shown. If not,
1168 @ the entry is omitted. "*" is always true. "{}" is never true.
1169 @ <li> The fourth term is a list of extra class names to apply to the new
1170 @ menu entry. Some skins use classes "desktoponly" and "wideonly"
1171 @ to only show the entries when the web browser screen is wide or
1172 @ very wide, respectively.
@@ -1131,11 +1200,11 @@
1200 @ <li> The first term is the display name of the /sitemap entry
1201 @ <li> The second term is a hyperlink to take when a user clicks on the
1202 @ entry. Hyperlinks that start with "/" are relative to the
1203 @ repository root.
1204 @ <li> The third term is an argument to the TH1 "capexpr" command.
1205 @ If capexpr evaluates to true, then the entry is shown. If not,
1206 @ the entry is omitted. "*" is always true.
1207 @ </ol>
1208 @
1209 @ <p>The default value is blank, meaning no added entries.
1210 @ (Property: sitemap-extra)
@@ -1729,13 +1798,11 @@
1798 zQ = sqlite3_mprintf(
1799 "SELECT sql FROM repository.sqlite_schema"
1800 " WHERE sql IS NOT NULL ORDER BY name");
1801 go = 1;
1802 }else if( P("tablelist") ){
1803 zQ = sqlite3_mprintf("SELECT*FROM pragma_table_list ORDER BY schema, name");
 
 
1804 go = 1;
1805 }
1806 if( go ){
1807 sqlite3_stmt *pStmt;
1808 int rc;
@@ -1744,10 +1811,11 @@
1811 int nRow = 0;
1812 int i;
1813 @ <hr />
1814 login_verify_csrf_secret();
1815 sqlite3_set_authorizer(g.db, raw_sql_query_authorizer, 0);
1816 search_sql_setup(g.db);
1817 rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail);
1818 if( rc!=SQLITE_OK ){
1819 @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
1820 sqlite3_finalize(pStmt);
1821 }else if( pStmt==0 ){
@@ -1757,11 +1825,11 @@
1825 rc = sqlite3_finalize(pStmt);
1826 if( rc ){
1827 @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div>
1828 }
1829 }else{
1830 @ <table border="1" cellpadding="4" cellspacing="0">
1831 while( sqlite3_step(pStmt)==SQLITE_ROW ){
1832 if( nRow==0 ){
1833 @ <tr>
1834 for(i=0; i<nCol; i++){
1835 @ <th>%h(sqlite3_column_name(pStmt, i))</th>
1836
+3 -3
--- src/sitemap.c
+++ src/sitemap.c
@@ -74,11 +74,11 @@
7474
if( P("popup")!=0 ){
7575
/* The "popup" query parameter
7676
** then disable anti-robot defenses */
7777
isPopup = 1;
7878
g.perm.Hyperlink = 1;
79
- g.javascriptHyperlink = 0;
79
+ g.jsHref = 0;
8080
}
8181
srchFlags = search_restrict(SRCH_ALL);
8282
if( !isPopup ){
8383
style_header("Site Map");
8484
style_adunit_config(ADUNIT_RIGHT_OK);
@@ -312,11 +312,11 @@
312312
if( P("popup")!=0 && cgi_csrf_safe(0) ){
313313
/* If this is a POST from the same origin with the popup=1 parameter,
314314
** then disable anti-robot defenses */
315315
isPopup = 1;
316316
g.perm.Hyperlink = 1;
317
- g.javascriptHyperlink = 0;
317
+ g.jsHref = 0;
318318
}
319319
if( !isPopup ){
320320
style_header("Test Page Map");
321321
style_adunit_config(ADUNIT_RIGHT_OK);
322322
}
@@ -364,11 +364,11 @@
364364
if( P("popup")!=0 && cgi_csrf_safe(0) ){
365365
/* If this is a POST from the same origin with the popup=1 parameter,
366366
** then disable anti-robot defenses */
367367
isPopup = 1;
368368
g.perm.Hyperlink = 1;
369
- g.javascriptHyperlink = 0;
369
+ g.jsHref = 0;
370370
}
371371
if( !isPopup ){
372372
style_header("Timeline Examples");
373373
style_adunit_config(ADUNIT_RIGHT_OK);
374374
}
375375
--- src/sitemap.c
+++ src/sitemap.c
@@ -74,11 +74,11 @@
74 if( P("popup")!=0 ){
75 /* The "popup" query parameter
76 ** then disable anti-robot defenses */
77 isPopup = 1;
78 g.perm.Hyperlink = 1;
79 g.javascriptHyperlink = 0;
80 }
81 srchFlags = search_restrict(SRCH_ALL);
82 if( !isPopup ){
83 style_header("Site Map");
84 style_adunit_config(ADUNIT_RIGHT_OK);
@@ -312,11 +312,11 @@
312 if( P("popup")!=0 && cgi_csrf_safe(0) ){
313 /* If this is a POST from the same origin with the popup=1 parameter,
314 ** then disable anti-robot defenses */
315 isPopup = 1;
316 g.perm.Hyperlink = 1;
317 g.javascriptHyperlink = 0;
318 }
319 if( !isPopup ){
320 style_header("Test Page Map");
321 style_adunit_config(ADUNIT_RIGHT_OK);
322 }
@@ -364,11 +364,11 @@
364 if( P("popup")!=0 && cgi_csrf_safe(0) ){
365 /* If this is a POST from the same origin with the popup=1 parameter,
366 ** then disable anti-robot defenses */
367 isPopup = 1;
368 g.perm.Hyperlink = 1;
369 g.javascriptHyperlink = 0;
370 }
371 if( !isPopup ){
372 style_header("Timeline Examples");
373 style_adunit_config(ADUNIT_RIGHT_OK);
374 }
375
--- src/sitemap.c
+++ src/sitemap.c
@@ -74,11 +74,11 @@
74 if( P("popup")!=0 ){
75 /* The "popup" query parameter
76 ** then disable anti-robot defenses */
77 isPopup = 1;
78 g.perm.Hyperlink = 1;
79 g.jsHref = 0;
80 }
81 srchFlags = search_restrict(SRCH_ALL);
82 if( !isPopup ){
83 style_header("Site Map");
84 style_adunit_config(ADUNIT_RIGHT_OK);
@@ -312,11 +312,11 @@
312 if( P("popup")!=0 && cgi_csrf_safe(0) ){
313 /* If this is a POST from the same origin with the popup=1 parameter,
314 ** then disable anti-robot defenses */
315 isPopup = 1;
316 g.perm.Hyperlink = 1;
317 g.jsHref = 0;
318 }
319 if( !isPopup ){
320 style_header("Test Page Map");
321 style_adunit_config(ADUNIT_RIGHT_OK);
322 }
@@ -364,11 +364,11 @@
364 if( P("popup")!=0 && cgi_csrf_safe(0) ){
365 /* If this is a POST from the same origin with the popup=1 parameter,
366 ** then disable anti-robot defenses */
367 isPopup = 1;
368 g.perm.Hyperlink = 1;
369 g.jsHref = 0;
370 }
371 if( !isPopup ){
372 style_header("Timeline Examples");
373 style_adunit_config(ADUNIT_RIGHT_OK);
374 }
375
+8 -5
--- src/stat.c
+++ src/stat.c
@@ -963,11 +963,11 @@
963963
*/
964964
if( !g.perm.Write && !db_get_boolean("artifact_stats_enable",0) ){
965965
login_needed(g.anon.Write);
966966
return;
967967
}
968
- load_control();
968
+ fossil_nice_default();
969969
970970
style_set_current_feature("stat");
971971
style_header("Artifact Statistics");
972972
style_submenu_element("Repository Stats", "stat");
973973
style_submenu_element("Artifact List", "bloblist");
@@ -999,14 +999,17 @@
999999
r = 0;
10001000
n = 0;
10011001
while( db_step(&q)==SQLITE_ROW ){
10021002
r += db_column_int(&q, 0);
10031003
if( n50pct==0 && r>=sumCmpr/2 ) n50pct = n;
1004
- if( n==(nTotal+99)/100 ) sz1pct = r;
1005
- if( n==(nTotal+9)/10 ) sz10pct = r;
1006
- if( n==(nTotal+4)/5 ) sz25pct = r;
1007
- if( n==(nTotal+1)/2 ){ sz50pct = r; medCmpr = db_column_int(&q,0); }
1004
+ if( n==(nTotal+99)/100 ) sz1pct = (sqlite3_int64)r;
1005
+ if( n==(nTotal+9)/10 ) sz10pct = (sqlite3_int64)r;
1006
+ if( n==(nTotal+4)/5 ) sz25pct = (sqlite3_int64)r;
1007
+ if( n==(nTotal+1)/2 ){
1008
+ sz50pct = (sqlite3_int64)r;
1009
+ medCmpr = db_column_int(&q,0);
1010
+ }
10081011
n++;
10091012
}
10101013
db_finalize(&q);
10111014
10121015
@ <h1>Overall Artifact Size Statistics:</h1>
10131016
--- src/stat.c
+++ src/stat.c
@@ -963,11 +963,11 @@
963 */
964 if( !g.perm.Write && !db_get_boolean("artifact_stats_enable",0) ){
965 login_needed(g.anon.Write);
966 return;
967 }
968 load_control();
969
970 style_set_current_feature("stat");
971 style_header("Artifact Statistics");
972 style_submenu_element("Repository Stats", "stat");
973 style_submenu_element("Artifact List", "bloblist");
@@ -999,14 +999,17 @@
999 r = 0;
1000 n = 0;
1001 while( db_step(&q)==SQLITE_ROW ){
1002 r += db_column_int(&q, 0);
1003 if( n50pct==0 && r>=sumCmpr/2 ) n50pct = n;
1004 if( n==(nTotal+99)/100 ) sz1pct = r;
1005 if( n==(nTotal+9)/10 ) sz10pct = r;
1006 if( n==(nTotal+4)/5 ) sz25pct = r;
1007 if( n==(nTotal+1)/2 ){ sz50pct = r; medCmpr = db_column_int(&q,0); }
 
 
 
1008 n++;
1009 }
1010 db_finalize(&q);
1011
1012 @ <h1>Overall Artifact Size Statistics:</h1>
1013
--- src/stat.c
+++ src/stat.c
@@ -963,11 +963,11 @@
963 */
964 if( !g.perm.Write && !db_get_boolean("artifact_stats_enable",0) ){
965 login_needed(g.anon.Write);
966 return;
967 }
968 fossil_nice_default();
969
970 style_set_current_feature("stat");
971 style_header("Artifact Statistics");
972 style_submenu_element("Repository Stats", "stat");
973 style_submenu_element("Artifact List", "bloblist");
@@ -999,14 +999,17 @@
999 r = 0;
1000 n = 0;
1001 while( db_step(&q)==SQLITE_ROW ){
1002 r += db_column_int(&q, 0);
1003 if( n50pct==0 && r>=sumCmpr/2 ) n50pct = n;
1004 if( n==(nTotal+99)/100 ) sz1pct = (sqlite3_int64)r;
1005 if( n==(nTotal+9)/10 ) sz10pct = (sqlite3_int64)r;
1006 if( n==(nTotal+4)/5 ) sz25pct = (sqlite3_int64)r;
1007 if( n==(nTotal+1)/2 ){
1008 sz50pct = (sqlite3_int64)r;
1009 medCmpr = db_column_int(&q,0);
1010 }
1011 n++;
1012 }
1013 db_finalize(&q);
1014
1015 @ <h1>Overall Artifact Size Statistics:</h1>
1016
+43 -29
--- src/style.c
+++ src/style.c
@@ -106,34 +106,35 @@
106106
** Generate and return a anchor tag like this:
107107
**
108108
** <a href="URL">
109109
** or <a id="ID">
110110
**
111
-** The form of the anchor tag is determined by the g.javascriptHyperlink
111
+** The form of the anchor tag is determined by the g.jsHref
112112
** and g.perm.Hyperlink variables.
113113
**
114
-** g.perm.Hyperlink g.javascriptHyperlink Returned anchor format
115
-** ---------------- --------------------- ------------------------
116
-** 0 0 (empty string)
117
-** 0 1 (empty string)
118
-** 1 0 <a href="URL">
119
-** 1 1 <a id="ID">
114
+** g.perm.Hyperlink g.jsHref Returned anchor format
115
+** ---------------- -------- ------------------------
116
+** 0 0 (empty string)
117
+** 0 1 (empty string)
118
+** 1 0 <a href="URL">
119
+** 1 1 <a data-href="URL">
120120
**
121121
** No anchor tag is generated if g.perm.Hyperlink is false.
122
-** The href="URL" form is used if g.javascriptHyperlink is false.
123
-** If g.javascriptHyperlink is true then the id="ID" form is used and
124
-** javascript is generated in the footer to cause href values to be
125
-** inserted after the page has loaded. The use of the id="ID" form
122
+** The href="URL" form is used if g.jsHref is false.
123
+** If g.jsHref is true then the data-href="URL" and
124
+** href="/honeypot" is generated and javascript is added to the footer
125
+** to cause data-href values to be inserted into href
126
+** after the page has loaded. The use of the data-href="URL" form
126127
** instead of href="URL" is a defense against bots.
127128
**
128129
** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
129130
** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
130
-** g.javascriptHyperlink is set to 1 by login_check_credentials(). Thus
131
+** g.jsHref is set to 1 by login_check_credentials(). Thus
131132
** the g.perm.Hyperlink property will be true even if the user does not
132133
** have the "h" privilege if the "auto-hyperlink" setting is true.
133134
**
134
-** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
135
+** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
135136
** ------------ -------------- ---------------- ---------------------
136137
** 0 0 0 0
137138
** 1 0 1 0
138139
** 0 1 1 1
139140
** 1 1 1 0
@@ -142,12 +143,12 @@
142143
**
143144
** User has "h" auto-hyperlink Returned anchor format
144145
** ------------ -------------- ----------------------
145146
** 0 0 (empty string)
146147
** 1 0 <a href="URL">
147
-** 0 1 <a id="ID">
148
-** 1 1 (can't happen)
148
+** 0 1 <a data-href="URL">
149
+** 1 1 <a href="URL">
149150
**
150151
** The name of these routines are deliberately kept short so that can be
151152
** easily used within @-lines. Example:
152153
**
153154
** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
@@ -172,11 +173,11 @@
172173
va_list ap;
173174
if( !g.perm.Hyperlink ) return fossil_strdup("");
174175
va_start(ap, zFormat);
175176
zUrl = vmprintf(zFormat, ap);
176177
va_end(ap);
177
- if( !g.javascriptHyperlink ){
178
+ if( !g.jsHref ){
178179
char *zHUrl;
179180
if( zExtra ){
180181
zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
181182
}else{
182183
zHUrl = mprintf("<a href=\"%h\">", zUrl);
@@ -197,11 +198,11 @@
197198
va_list ap;
198199
if( !g.perm.Hyperlink ) return fossil_strdup("");
199200
va_start(ap, zFormat);
200201
zUrl = vmprintf(zFormat, ap);
201202
va_end(ap);
202
- if( !g.javascriptHyperlink ){
203
+ if( !g.jsHref ){
203204
char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
204205
fossil_free(zUrl);
205206
return zHUrl;
206207
}
207208
needHrefJs = 1;
@@ -213,11 +214,11 @@
213214
va_list ap;
214215
if( !g.perm.Hyperlink ) return fossil_strdup("");
215216
va_start(ap, zFormat);
216217
zUrl = vmprintf(zFormat, ap);
217218
va_end(ap);
218
- if( !g.javascriptHyperlink ){
219
+ if( !g.jsHref ){
219220
char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
220221
fossil_free(zUrl);
221222
return zHUrl;
222223
}
223224
needHrefJs = 1;
@@ -232,18 +233,18 @@
232233
** As a defense against robots, the action=ARG might instead by data-action=ARG
233234
** and javascript (href.js) added to the page so that the data-action= is
234235
** changed into action= after the page loads. Whether or not this happens
235236
** depends on if the user has the "h" privilege and whether or not the
236237
** auto-hyperlink setting is on. These setings determine the values of
237
-** variables g.perm.Hyperlink and g.javascriptHyperlink.
238
+** variables g.perm.Hyperlink and g.jsHref.
238239
**
239
-** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
240
-** ------------ -------------- ---------------- ---------------------
241
-** 1: 0 0 0 0
242
-** 2: 1 0 1 0
243
-** 3: 0 1 1 1
244
-** 4: 1 1 1 0
240
+** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
241
+** ------------ -------------- ---------------- --------
242
+** 1: 0 0 0 0
243
+** 2: 1 0 1 0
244
+** 3: 0 1 1 1
245
+** 4: 1 1 1 0
245246
**
246247
** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js
247248
** javascript is omitted and so the form is effectively disabled.
248249
*/
249250
void form_begin(const char *zOtherArgs, const char *zAction, ...){
@@ -889,11 +890,12 @@
889890
** Generate code to load all required javascript files.
890891
*/
891892
static void style_load_all_js_files(void){
892893
if( needHrefJs && g.perm.Hyperlink ){
893894
int nDelay = db_get_int("auto-hyperlink-delay",0);
894
- int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
895
+ int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
896
+ && sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
895897
@ <script id='href-data' type='application/json'>\
896898
@ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
897899
}
898900
@ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
899901
@ function debugMsg(msg){
@@ -1215,11 +1217,11 @@
12151217
** default.css. */
12161218
fossil_free(zFile);
12171219
}
12181220
12191221
/*
1220
-** WEBPAGE: style.css
1222
+** WEBPAGE: style.css loadavg-exempt
12211223
**
12221224
** Return the style sheet. The style sheet is assemblied from
12231225
** multiple sources, in order:
12241226
**
12251227
** (1) The built-in "default.css" style sheet containing basic defaults.
@@ -1325,12 +1327,23 @@
13251327
/*
13261328
** WEBPAGE: honeypot
13271329
** This page is a honeypot for spiders and bots.
13281330
*/
13291331
void honeypot_page(void){
1330
- cgi_set_status(403, "Forbidden");
1331
- @ <p>Please enable javascript or log in to see this content</p>
1332
+ style_header("I think you are a robot");
1333
+ @ <p>You seem like a robot.</p>
1334
+ @
1335
+ @ <p>Is this wrong? Are you really a human? If so, please prove it
1336
+ @ by <a href="%R/login">logging in</a>.
1337
+ if( g.anon.Hyperlink ){
1338
+ @ You can <a href="%R/login?anon=1">log in anonymously</a> if you
1339
+ @ prefer.
1340
+ }
1341
+ @ <p>Sorry for the inconvenience. The point of this is to prevent
1342
+ @ robots from following the countless of hyperlinks in this site and
1343
+ @ soaking up all the available CPU time and network bandwidth.
1344
+ style_finish_page();
13321345
}
13331346
13341347
/*
13351348
** Webpages that encounter an error due to missing or incorrect
13361349
** query parameters can jump to this routine to render an error
@@ -1382,10 +1395,11 @@
13821395
@ g.zTop = %h(g.zTop)<br />
13831396
@ g.zPath = %h(g.zPath)<br />
13841397
@ g.userUid = %d(g.userUid)<br />
13851398
@ g.zLogin = %h(g.zLogin)<br />
13861399
@ g.isHuman = %d(g.isHuman)<br />
1400
+ @ g.jsHref = %d(g.jsHref)<br />
13871401
if( g.nRequest ){
13881402
@ g.nRequest = %d(g.nRequest)<br />
13891403
}
13901404
if( g.nPendingRequest>1 ){
13911405
@ g.nPendingRequest = %d(g.nPendingRequest)<br />
13921406
--- src/style.c
+++ src/style.c
@@ -106,34 +106,35 @@
106 ** Generate and return a anchor tag like this:
107 **
108 ** <a href="URL">
109 ** or <a id="ID">
110 **
111 ** The form of the anchor tag is determined by the g.javascriptHyperlink
112 ** and g.perm.Hyperlink variables.
113 **
114 ** g.perm.Hyperlink g.javascriptHyperlink Returned anchor format
115 ** ---------------- --------------------- ------------------------
116 ** 0 0 (empty string)
117 ** 0 1 (empty string)
118 ** 1 0 <a href="URL">
119 ** 1 1 <a id="ID">
120 **
121 ** No anchor tag is generated if g.perm.Hyperlink is false.
122 ** The href="URL" form is used if g.javascriptHyperlink is false.
123 ** If g.javascriptHyperlink is true then the id="ID" form is used and
124 ** javascript is generated in the footer to cause href values to be
125 ** inserted after the page has loaded. The use of the id="ID" form
 
126 ** instead of href="URL" is a defense against bots.
127 **
128 ** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
129 ** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
130 ** g.javascriptHyperlink is set to 1 by login_check_credentials(). Thus
131 ** the g.perm.Hyperlink property will be true even if the user does not
132 ** have the "h" privilege if the "auto-hyperlink" setting is true.
133 **
134 ** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
135 ** ------------ -------------- ---------------- ---------------------
136 ** 0 0 0 0
137 ** 1 0 1 0
138 ** 0 1 1 1
139 ** 1 1 1 0
@@ -142,12 +143,12 @@
142 **
143 ** User has "h" auto-hyperlink Returned anchor format
144 ** ------------ -------------- ----------------------
145 ** 0 0 (empty string)
146 ** 1 0 <a href="URL">
147 ** 0 1 <a id="ID">
148 ** 1 1 (can't happen)
149 **
150 ** The name of these routines are deliberately kept short so that can be
151 ** easily used within @-lines. Example:
152 **
153 ** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
@@ -172,11 +173,11 @@
172 va_list ap;
173 if( !g.perm.Hyperlink ) return fossil_strdup("");
174 va_start(ap, zFormat);
175 zUrl = vmprintf(zFormat, ap);
176 va_end(ap);
177 if( !g.javascriptHyperlink ){
178 char *zHUrl;
179 if( zExtra ){
180 zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
181 }else{
182 zHUrl = mprintf("<a href=\"%h\">", zUrl);
@@ -197,11 +198,11 @@
197 va_list ap;
198 if( !g.perm.Hyperlink ) return fossil_strdup("");
199 va_start(ap, zFormat);
200 zUrl = vmprintf(zFormat, ap);
201 va_end(ap);
202 if( !g.javascriptHyperlink ){
203 char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
204 fossil_free(zUrl);
205 return zHUrl;
206 }
207 needHrefJs = 1;
@@ -213,11 +214,11 @@
213 va_list ap;
214 if( !g.perm.Hyperlink ) return fossil_strdup("");
215 va_start(ap, zFormat);
216 zUrl = vmprintf(zFormat, ap);
217 va_end(ap);
218 if( !g.javascriptHyperlink ){
219 char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
220 fossil_free(zUrl);
221 return zHUrl;
222 }
223 needHrefJs = 1;
@@ -232,18 +233,18 @@
232 ** As a defense against robots, the action=ARG might instead by data-action=ARG
233 ** and javascript (href.js) added to the page so that the data-action= is
234 ** changed into action= after the page loads. Whether or not this happens
235 ** depends on if the user has the "h" privilege and whether or not the
236 ** auto-hyperlink setting is on. These setings determine the values of
237 ** variables g.perm.Hyperlink and g.javascriptHyperlink.
238 **
239 ** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
240 ** ------------ -------------- ---------------- ---------------------
241 ** 1: 0 0 0 0
242 ** 2: 1 0 1 0
243 ** 3: 0 1 1 1
244 ** 4: 1 1 1 0
245 **
246 ** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js
247 ** javascript is omitted and so the form is effectively disabled.
248 */
249 void form_begin(const char *zOtherArgs, const char *zAction, ...){
@@ -889,11 +890,12 @@
889 ** Generate code to load all required javascript files.
890 */
891 static void style_load_all_js_files(void){
892 if( needHrefJs && g.perm.Hyperlink ){
893 int nDelay = db_get_int("auto-hyperlink-delay",0);
894 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
 
895 @ <script id='href-data' type='application/json'>\
896 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
897 }
898 @ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
899 @ function debugMsg(msg){
@@ -1215,11 +1217,11 @@
1215 ** default.css. */
1216 fossil_free(zFile);
1217 }
1218
1219 /*
1220 ** WEBPAGE: style.css
1221 **
1222 ** Return the style sheet. The style sheet is assemblied from
1223 ** multiple sources, in order:
1224 **
1225 ** (1) The built-in "default.css" style sheet containing basic defaults.
@@ -1325,12 +1327,23 @@
1325 /*
1326 ** WEBPAGE: honeypot
1327 ** This page is a honeypot for spiders and bots.
1328 */
1329 void honeypot_page(void){
1330 cgi_set_status(403, "Forbidden");
1331 @ <p>Please enable javascript or log in to see this content</p>
 
 
 
 
 
 
 
 
 
 
 
1332 }
1333
1334 /*
1335 ** Webpages that encounter an error due to missing or incorrect
1336 ** query parameters can jump to this routine to render an error
@@ -1382,10 +1395,11 @@
1382 @ g.zTop = %h(g.zTop)<br />
1383 @ g.zPath = %h(g.zPath)<br />
1384 @ g.userUid = %d(g.userUid)<br />
1385 @ g.zLogin = %h(g.zLogin)<br />
1386 @ g.isHuman = %d(g.isHuman)<br />
 
1387 if( g.nRequest ){
1388 @ g.nRequest = %d(g.nRequest)<br />
1389 }
1390 if( g.nPendingRequest>1 ){
1391 @ g.nPendingRequest = %d(g.nPendingRequest)<br />
1392
--- src/style.c
+++ src/style.c
@@ -106,34 +106,35 @@
106 ** Generate and return a anchor tag like this:
107 **
108 ** <a href="URL">
109 ** or <a id="ID">
110 **
111 ** The form of the anchor tag is determined by the g.jsHref
112 ** and g.perm.Hyperlink variables.
113 **
114 ** g.perm.Hyperlink g.jsHref Returned anchor format
115 ** ---------------- -------- ------------------------
116 ** 0 0 (empty string)
117 ** 0 1 (empty string)
118 ** 1 0 <a href="URL">
119 ** 1 1 <a data-href="URL">
120 **
121 ** No anchor tag is generated if g.perm.Hyperlink is false.
122 ** The href="URL" form is used if g.jsHref is false.
123 ** If g.jsHref is true then the data-href="URL" and
124 ** href="/honeypot" is generated and javascript is added to the footer
125 ** to cause data-href values to be inserted into href
126 ** after the page has loaded. The use of the data-href="URL" form
127 ** instead of href="URL" is a defense against bots.
128 **
129 ** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
130 ** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
131 ** g.jsHref is set to 1 by login_check_credentials(). Thus
132 ** the g.perm.Hyperlink property will be true even if the user does not
133 ** have the "h" privilege if the "auto-hyperlink" setting is true.
134 **
135 ** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
136 ** ------------ -------------- ---------------- ---------------------
137 ** 0 0 0 0
138 ** 1 0 1 0
139 ** 0 1 1 1
140 ** 1 1 1 0
@@ -142,12 +143,12 @@
143 **
144 ** User has "h" auto-hyperlink Returned anchor format
145 ** ------------ -------------- ----------------------
146 ** 0 0 (empty string)
147 ** 1 0 <a href="URL">
148 ** 0 1 <a data-href="URL">
149 ** 1 1 <a href="URL">
150 **
151 ** The name of these routines are deliberately kept short so that can be
152 ** easily used within @-lines. Example:
153 **
154 ** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
@@ -172,11 +173,11 @@
173 va_list ap;
174 if( !g.perm.Hyperlink ) return fossil_strdup("");
175 va_start(ap, zFormat);
176 zUrl = vmprintf(zFormat, ap);
177 va_end(ap);
178 if( !g.jsHref ){
179 char *zHUrl;
180 if( zExtra ){
181 zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
182 }else{
183 zHUrl = mprintf("<a href=\"%h\">", zUrl);
@@ -197,11 +198,11 @@
198 va_list ap;
199 if( !g.perm.Hyperlink ) return fossil_strdup("");
200 va_start(ap, zFormat);
201 zUrl = vmprintf(zFormat, ap);
202 va_end(ap);
203 if( !g.jsHref ){
204 char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
205 fossil_free(zUrl);
206 return zHUrl;
207 }
208 needHrefJs = 1;
@@ -213,11 +214,11 @@
214 va_list ap;
215 if( !g.perm.Hyperlink ) return fossil_strdup("");
216 va_start(ap, zFormat);
217 zUrl = vmprintf(zFormat, ap);
218 va_end(ap);
219 if( !g.jsHref ){
220 char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
221 fossil_free(zUrl);
222 return zHUrl;
223 }
224 needHrefJs = 1;
@@ -232,18 +233,18 @@
233 ** As a defense against robots, the action=ARG might instead by data-action=ARG
234 ** and javascript (href.js) added to the page so that the data-action= is
235 ** changed into action= after the page loads. Whether or not this happens
236 ** depends on if the user has the "h" privilege and whether or not the
237 ** auto-hyperlink setting is on. These setings determine the values of
238 ** variables g.perm.Hyperlink and g.jsHref.
239 **
240 ** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
241 ** ------------ -------------- ---------------- --------
242 ** 1: 0 0 0 0
243 ** 2: 1 0 1 0
244 ** 3: 0 1 1 1
245 ** 4: 1 1 1 0
246 **
247 ** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js
248 ** javascript is omitted and so the form is effectively disabled.
249 */
250 void form_begin(const char *zOtherArgs, const char *zAction, ...){
@@ -889,11 +890,12 @@
890 ** Generate code to load all required javascript files.
891 */
892 static void style_load_all_js_files(void){
893 if( needHrefJs && g.perm.Hyperlink ){
894 int nDelay = db_get_int("auto-hyperlink-delay",0);
895 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
896 && sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
897 @ <script id='href-data' type='application/json'>\
898 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
899 }
900 @ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
901 @ function debugMsg(msg){
@@ -1215,11 +1217,11 @@
1217 ** default.css. */
1218 fossil_free(zFile);
1219 }
1220
1221 /*
1222 ** WEBPAGE: style.css loadavg-exempt
1223 **
1224 ** Return the style sheet. The style sheet is assemblied from
1225 ** multiple sources, in order:
1226 **
1227 ** (1) The built-in "default.css" style sheet containing basic defaults.
@@ -1325,12 +1327,23 @@
1327 /*
1328 ** WEBPAGE: honeypot
1329 ** This page is a honeypot for spiders and bots.
1330 */
1331 void honeypot_page(void){
1332 style_header("I think you are a robot");
1333 @ <p>You seem like a robot.</p>
1334 @
1335 @ <p>Is this wrong? Are you really a human? If so, please prove it
1336 @ by <a href="%R/login">logging in</a>.
1337 if( g.anon.Hyperlink ){
1338 @ You can <a href="%R/login?anon=1">log in anonymously</a> if you
1339 @ prefer.
1340 }
1341 @ <p>Sorry for the inconvenience. The point of this is to prevent
1342 @ robots from following the countless of hyperlinks in this site and
1343 @ soaking up all the available CPU time and network bandwidth.
1344 style_finish_page();
1345 }
1346
1347 /*
1348 ** Webpages that encounter an error due to missing or incorrect
1349 ** query parameters can jump to this routine to render an error
@@ -1382,10 +1395,11 @@
1395 @ g.zTop = %h(g.zTop)<br />
1396 @ g.zPath = %h(g.zPath)<br />
1397 @ g.userUid = %d(g.userUid)<br />
1398 @ g.zLogin = %h(g.zLogin)<br />
1399 @ g.isHuman = %d(g.isHuman)<br />
1400 @ g.jsHref = %d(g.jsHref)<br />
1401 if( g.nRequest ){
1402 @ g.nRequest = %d(g.nRequest)<br />
1403 }
1404 if( g.nPendingRequest>1 ){
1405 @ g.nPendingRequest = %d(g.nPendingRequest)<br />
1406
+43 -29
--- src/style.c
+++ src/style.c
@@ -106,34 +106,35 @@
106106
** Generate and return a anchor tag like this:
107107
**
108108
** <a href="URL">
109109
** or <a id="ID">
110110
**
111
-** The form of the anchor tag is determined by the g.javascriptHyperlink
111
+** The form of the anchor tag is determined by the g.jsHref
112112
** and g.perm.Hyperlink variables.
113113
**
114
-** g.perm.Hyperlink g.javascriptHyperlink Returned anchor format
115
-** ---------------- --------------------- ------------------------
116
-** 0 0 (empty string)
117
-** 0 1 (empty string)
118
-** 1 0 <a href="URL">
119
-** 1 1 <a id="ID">
114
+** g.perm.Hyperlink g.jsHref Returned anchor format
115
+** ---------------- -------- ------------------------
116
+** 0 0 (empty string)
117
+** 0 1 (empty string)
118
+** 1 0 <a href="URL">
119
+** 1 1 <a data-href="URL">
120120
**
121121
** No anchor tag is generated if g.perm.Hyperlink is false.
122
-** The href="URL" form is used if g.javascriptHyperlink is false.
123
-** If g.javascriptHyperlink is true then the id="ID" form is used and
124
-** javascript is generated in the footer to cause href values to be
125
-** inserted after the page has loaded. The use of the id="ID" form
122
+** The href="URL" form is used if g.jsHref is false.
123
+** If g.jsHref is true then the data-href="URL" and
124
+** href="/honeypot" is generated and javascript is added to the footer
125
+** to cause data-href values to be inserted into href
126
+** after the page has loaded. The use of the data-href="URL" form
126127
** instead of href="URL" is a defense against bots.
127128
**
128129
** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
129130
** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
130
-** g.javascriptHyperlink is set to 1 by login_check_credentials(). Thus
131
+** g.jsHref is set to 1 by login_check_credentials(). Thus
131132
** the g.perm.Hyperlink property will be true even if the user does not
132133
** have the "h" privilege if the "auto-hyperlink" setting is true.
133134
**
134
-** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
135
+** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
135136
** ------------ -------------- ---------------- ---------------------
136137
** 0 0 0 0
137138
** 1 0 1 0
138139
** 0 1 1 1
139140
** 1 1 1 0
@@ -142,12 +143,12 @@
142143
**
143144
** User has "h" auto-hyperlink Returned anchor format
144145
** ------------ -------------- ----------------------
145146
** 0 0 (empty string)
146147
** 1 0 <a href="URL">
147
-** 0 1 <a id="ID">
148
-** 1 1 (can't happen)
148
+** 0 1 <a data-href="URL">
149
+** 1 1 <a href="URL">
149150
**
150151
** The name of these routines are deliberately kept short so that can be
151152
** easily used within @-lines. Example:
152153
**
153154
** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
@@ -172,11 +173,11 @@
172173
va_list ap;
173174
if( !g.perm.Hyperlink ) return fossil_strdup("");
174175
va_start(ap, zFormat);
175176
zUrl = vmprintf(zFormat, ap);
176177
va_end(ap);
177
- if( !g.javascriptHyperlink ){
178
+ if( !g.jsHref ){
178179
char *zHUrl;
179180
if( zExtra ){
180181
zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
181182
}else{
182183
zHUrl = mprintf("<a href=\"%h\">", zUrl);
@@ -197,11 +198,11 @@
197198
va_list ap;
198199
if( !g.perm.Hyperlink ) return fossil_strdup("");
199200
va_start(ap, zFormat);
200201
zUrl = vmprintf(zFormat, ap);
201202
va_end(ap);
202
- if( !g.javascriptHyperlink ){
203
+ if( !g.jsHref ){
203204
char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
204205
fossil_free(zUrl);
205206
return zHUrl;
206207
}
207208
needHrefJs = 1;
@@ -213,11 +214,11 @@
213214
va_list ap;
214215
if( !g.perm.Hyperlink ) return fossil_strdup("");
215216
va_start(ap, zFormat);
216217
zUrl = vmprintf(zFormat, ap);
217218
va_end(ap);
218
- if( !g.javascriptHyperlink ){
219
+ if( !g.jsHref ){
219220
char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
220221
fossil_free(zUrl);
221222
return zHUrl;
222223
}
223224
needHrefJs = 1;
@@ -232,18 +233,18 @@
232233
** As a defense against robots, the action=ARG might instead by data-action=ARG
233234
** and javascript (href.js) added to the page so that the data-action= is
234235
** changed into action= after the page loads. Whether or not this happens
235236
** depends on if the user has the "h" privilege and whether or not the
236237
** auto-hyperlink setting is on. These setings determine the values of
237
-** variables g.perm.Hyperlink and g.javascriptHyperlink.
238
+** variables g.perm.Hyperlink and g.jsHref.
238239
**
239
-** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
240
-** ------------ -------------- ---------------- ---------------------
241
-** 1: 0 0 0 0
242
-** 2: 1 0 1 0
243
-** 3: 0 1 1 1
244
-** 4: 1 1 1 0
240
+** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
241
+** ------------ -------------- ---------------- --------
242
+** 1: 0 0 0 0
243
+** 2: 1 0 1 0
244
+** 3: 0 1 1 1
245
+** 4: 1 1 1 0
245246
**
246247
** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js
247248
** javascript is omitted and so the form is effectively disabled.
248249
*/
249250
void form_begin(const char *zOtherArgs, const char *zAction, ...){
@@ -889,11 +890,12 @@
889890
** Generate code to load all required javascript files.
890891
*/
891892
static void style_load_all_js_files(void){
892893
if( needHrefJs && g.perm.Hyperlink ){
893894
int nDelay = db_get_int("auto-hyperlink-delay",0);
894
- int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
895
+ int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
896
+ && sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
895897
@ <script id='href-data' type='application/json'>\
896898
@ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
897899
}
898900
@ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
899901
@ function debugMsg(msg){
@@ -1215,11 +1217,11 @@
12151217
** default.css. */
12161218
fossil_free(zFile);
12171219
}
12181220
12191221
/*
1220
-** WEBPAGE: style.css
1222
+** WEBPAGE: style.css loadavg-exempt
12211223
**
12221224
** Return the style sheet. The style sheet is assemblied from
12231225
** multiple sources, in order:
12241226
**
12251227
** (1) The built-in "default.css" style sheet containing basic defaults.
@@ -1325,12 +1327,23 @@
13251327
/*
13261328
** WEBPAGE: honeypot
13271329
** This page is a honeypot for spiders and bots.
13281330
*/
13291331
void honeypot_page(void){
1330
- cgi_set_status(403, "Forbidden");
1331
- @ <p>Please enable javascript or log in to see this content</p>
1332
+ style_header("I think you are a robot");
1333
+ @ <p>You seem like a robot.</p>
1334
+ @
1335
+ @ <p>Is this wrong? Are you really a human? If so, please prove it
1336
+ @ by <a href="%R/login">logging in</a>.
1337
+ if( g.anon.Hyperlink ){
1338
+ @ You can <a href="%R/login?anon=1">log in anonymously</a> if you
1339
+ @ prefer.
1340
+ }
1341
+ @ <p>Sorry for the inconvenience. The point of this is to prevent
1342
+ @ robots from following the countless of hyperlinks in this site and
1343
+ @ soaking up all the available CPU time and network bandwidth.
1344
+ style_finish_page();
13321345
}
13331346
13341347
/*
13351348
** Webpages that encounter an error due to missing or incorrect
13361349
** query parameters can jump to this routine to render an error
@@ -1382,10 +1395,11 @@
13821395
@ g.zTop = %h(g.zTop)<br />
13831396
@ g.zPath = %h(g.zPath)<br />
13841397
@ g.userUid = %d(g.userUid)<br />
13851398
@ g.zLogin = %h(g.zLogin)<br />
13861399
@ g.isHuman = %d(g.isHuman)<br />
1400
+ @ g.jsHref = %d(g.jsHref)<br />
13871401
if( g.nRequest ){
13881402
@ g.nRequest = %d(g.nRequest)<br />
13891403
}
13901404
if( g.nPendingRequest>1 ){
13911405
@ g.nPendingRequest = %d(g.nPendingRequest)<br />
13921406
--- src/style.c
+++ src/style.c
@@ -106,34 +106,35 @@
106 ** Generate and return a anchor tag like this:
107 **
108 ** <a href="URL">
109 ** or <a id="ID">
110 **
111 ** The form of the anchor tag is determined by the g.javascriptHyperlink
112 ** and g.perm.Hyperlink variables.
113 **
114 ** g.perm.Hyperlink g.javascriptHyperlink Returned anchor format
115 ** ---------------- --------------------- ------------------------
116 ** 0 0 (empty string)
117 ** 0 1 (empty string)
118 ** 1 0 <a href="URL">
119 ** 1 1 <a id="ID">
120 **
121 ** No anchor tag is generated if g.perm.Hyperlink is false.
122 ** The href="URL" form is used if g.javascriptHyperlink is false.
123 ** If g.javascriptHyperlink is true then the id="ID" form is used and
124 ** javascript is generated in the footer to cause href values to be
125 ** inserted after the page has loaded. The use of the id="ID" form
 
126 ** instead of href="URL" is a defense against bots.
127 **
128 ** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
129 ** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
130 ** g.javascriptHyperlink is set to 1 by login_check_credentials(). Thus
131 ** the g.perm.Hyperlink property will be true even if the user does not
132 ** have the "h" privilege if the "auto-hyperlink" setting is true.
133 **
134 ** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
135 ** ------------ -------------- ---------------- ---------------------
136 ** 0 0 0 0
137 ** 1 0 1 0
138 ** 0 1 1 1
139 ** 1 1 1 0
@@ -142,12 +143,12 @@
142 **
143 ** User has "h" auto-hyperlink Returned anchor format
144 ** ------------ -------------- ----------------------
145 ** 0 0 (empty string)
146 ** 1 0 <a href="URL">
147 ** 0 1 <a id="ID">
148 ** 1 1 (can't happen)
149 **
150 ** The name of these routines are deliberately kept short so that can be
151 ** easily used within @-lines. Example:
152 **
153 ** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
@@ -172,11 +173,11 @@
172 va_list ap;
173 if( !g.perm.Hyperlink ) return fossil_strdup("");
174 va_start(ap, zFormat);
175 zUrl = vmprintf(zFormat, ap);
176 va_end(ap);
177 if( !g.javascriptHyperlink ){
178 char *zHUrl;
179 if( zExtra ){
180 zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
181 }else{
182 zHUrl = mprintf("<a href=\"%h\">", zUrl);
@@ -197,11 +198,11 @@
197 va_list ap;
198 if( !g.perm.Hyperlink ) return fossil_strdup("");
199 va_start(ap, zFormat);
200 zUrl = vmprintf(zFormat, ap);
201 va_end(ap);
202 if( !g.javascriptHyperlink ){
203 char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
204 fossil_free(zUrl);
205 return zHUrl;
206 }
207 needHrefJs = 1;
@@ -213,11 +214,11 @@
213 va_list ap;
214 if( !g.perm.Hyperlink ) return fossil_strdup("");
215 va_start(ap, zFormat);
216 zUrl = vmprintf(zFormat, ap);
217 va_end(ap);
218 if( !g.javascriptHyperlink ){
219 char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
220 fossil_free(zUrl);
221 return zHUrl;
222 }
223 needHrefJs = 1;
@@ -232,18 +233,18 @@
232 ** As a defense against robots, the action=ARG might instead by data-action=ARG
233 ** and javascript (href.js) added to the page so that the data-action= is
234 ** changed into action= after the page loads. Whether or not this happens
235 ** depends on if the user has the "h" privilege and whether or not the
236 ** auto-hyperlink setting is on. These setings determine the values of
237 ** variables g.perm.Hyperlink and g.javascriptHyperlink.
238 **
239 ** User has "h" auto-hyperlink g.perm.Hyperlink g.javascriptHyperlink
240 ** ------------ -------------- ---------------- ---------------------
241 ** 1: 0 0 0 0
242 ** 2: 1 0 1 0
243 ** 3: 0 1 1 1
244 ** 4: 1 1 1 0
245 **
246 ** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js
247 ** javascript is omitted and so the form is effectively disabled.
248 */
249 void form_begin(const char *zOtherArgs, const char *zAction, ...){
@@ -889,11 +890,12 @@
889 ** Generate code to load all required javascript files.
890 */
891 static void style_load_all_js_files(void){
892 if( needHrefJs && g.perm.Hyperlink ){
893 int nDelay = db_get_int("auto-hyperlink-delay",0);
894 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0);
 
895 @ <script id='href-data' type='application/json'>\
896 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
897 }
898 @ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
899 @ function debugMsg(msg){
@@ -1215,11 +1217,11 @@
1215 ** default.css. */
1216 fossil_free(zFile);
1217 }
1218
1219 /*
1220 ** WEBPAGE: style.css
1221 **
1222 ** Return the style sheet. The style sheet is assemblied from
1223 ** multiple sources, in order:
1224 **
1225 ** (1) The built-in "default.css" style sheet containing basic defaults.
@@ -1325,12 +1327,23 @@
1325 /*
1326 ** WEBPAGE: honeypot
1327 ** This page is a honeypot for spiders and bots.
1328 */
1329 void honeypot_page(void){
1330 cgi_set_status(403, "Forbidden");
1331 @ <p>Please enable javascript or log in to see this content</p>
 
 
 
 
 
 
 
 
 
 
 
1332 }
1333
1334 /*
1335 ** Webpages that encounter an error due to missing or incorrect
1336 ** query parameters can jump to this routine to render an error
@@ -1382,10 +1395,11 @@
1382 @ g.zTop = %h(g.zTop)<br />
1383 @ g.zPath = %h(g.zPath)<br />
1384 @ g.userUid = %d(g.userUid)<br />
1385 @ g.zLogin = %h(g.zLogin)<br />
1386 @ g.isHuman = %d(g.isHuman)<br />
 
1387 if( g.nRequest ){
1388 @ g.nRequest = %d(g.nRequest)<br />
1389 }
1390 if( g.nPendingRequest>1 ){
1391 @ g.nPendingRequest = %d(g.nPendingRequest)<br />
1392
--- src/style.c
+++ src/style.c
@@ -106,34 +106,35 @@
106 ** Generate and return a anchor tag like this:
107 **
108 ** <a href="URL">
109 ** or <a id="ID">
110 **
111 ** The form of the anchor tag is determined by the g.jsHref
112 ** and g.perm.Hyperlink variables.
113 **
114 ** g.perm.Hyperlink g.jsHref Returned anchor format
115 ** ---------------- -------- ------------------------
116 ** 0 0 (empty string)
117 ** 0 1 (empty string)
118 ** 1 0 <a href="URL">
119 ** 1 1 <a data-href="URL">
120 **
121 ** No anchor tag is generated if g.perm.Hyperlink is false.
122 ** The href="URL" form is used if g.jsHref is false.
123 ** If g.jsHref is true then the data-href="URL" and
124 ** href="/honeypot" is generated and javascript is added to the footer
125 ** to cause data-href values to be inserted into href
126 ** after the page has loaded. The use of the data-href="URL" form
127 ** instead of href="URL" is a defense against bots.
128 **
129 ** If the user lacks the Hyperlink (h) property and the "auto-hyperlink"
130 ** setting is true, then g.perm.Hyperlink is changed from 0 to 1 and
131 ** g.jsHref is set to 1 by login_check_credentials(). Thus
132 ** the g.perm.Hyperlink property will be true even if the user does not
133 ** have the "h" privilege if the "auto-hyperlink" setting is true.
134 **
135 ** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
136 ** ------------ -------------- ---------------- ---------------------
137 ** 0 0 0 0
138 ** 1 0 1 0
139 ** 0 1 1 1
140 ** 1 1 1 0
@@ -142,12 +143,12 @@
143 **
144 ** User has "h" auto-hyperlink Returned anchor format
145 ** ------------ -------------- ----------------------
146 ** 0 0 (empty string)
147 ** 1 0 <a href="URL">
148 ** 0 1 <a data-href="URL">
149 ** 1 1 <a href="URL">
150 **
151 ** The name of these routines are deliberately kept short so that can be
152 ** easily used within @-lines. Example:
153 **
154 ** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
@@ -172,11 +173,11 @@
173 va_list ap;
174 if( !g.perm.Hyperlink ) return fossil_strdup("");
175 va_start(ap, zFormat);
176 zUrl = vmprintf(zFormat, ap);
177 va_end(ap);
178 if( !g.jsHref ){
179 char *zHUrl;
180 if( zExtra ){
181 zHUrl = mprintf("<a %s href=\"%h\">", zExtra, zUrl);
182 }else{
183 zHUrl = mprintf("<a href=\"%h\">", zUrl);
@@ -197,11 +198,11 @@
198 va_list ap;
199 if( !g.perm.Hyperlink ) return fossil_strdup("");
200 va_start(ap, zFormat);
201 zUrl = vmprintf(zFormat, ap);
202 va_end(ap);
203 if( !g.jsHref ){
204 char *zHUrl = mprintf("<a class=\"%s\" href=\"%h\">", zExtra, zUrl);
205 fossil_free(zUrl);
206 return zHUrl;
207 }
208 needHrefJs = 1;
@@ -213,11 +214,11 @@
214 va_list ap;
215 if( !g.perm.Hyperlink ) return fossil_strdup("");
216 va_start(ap, zFormat);
217 zUrl = vmprintf(zFormat, ap);
218 va_end(ap);
219 if( !g.jsHref ){
220 char *zHUrl = mprintf("<a href=\"%h\">", zUrl);
221 fossil_free(zUrl);
222 return zHUrl;
223 }
224 needHrefJs = 1;
@@ -232,18 +233,18 @@
233 ** As a defense against robots, the action=ARG might instead by data-action=ARG
234 ** and javascript (href.js) added to the page so that the data-action= is
235 ** changed into action= after the page loads. Whether or not this happens
236 ** depends on if the user has the "h" privilege and whether or not the
237 ** auto-hyperlink setting is on. These setings determine the values of
238 ** variables g.perm.Hyperlink and g.jsHref.
239 **
240 ** User has "h" auto-hyperlink g.perm.Hyperlink g.jsHref
241 ** ------------ -------------- ---------------- --------
242 ** 1: 0 0 0 0
243 ** 2: 1 0 1 0
244 ** 3: 0 1 1 1
245 ** 4: 1 1 1 0
246 **
247 ** The data-action=ARG form is used for cases 1 and 3. In case 1, the href.js
248 ** javascript is omitted and so the form is effectively disabled.
249 */
250 void form_begin(const char *zOtherArgs, const char *zAction, ...){
@@ -889,11 +890,12 @@
890 ** Generate code to load all required javascript files.
891 */
892 static void style_load_all_js_files(void){
893 if( needHrefJs && g.perm.Hyperlink ){
894 int nDelay = db_get_int("auto-hyperlink-delay",0);
895 int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
896 && sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
897 @ <script id='href-data' type='application/json'>\
898 @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
899 }
900 @ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
901 @ function debugMsg(msg){
@@ -1215,11 +1217,11 @@
1217 ** default.css. */
1218 fossil_free(zFile);
1219 }
1220
1221 /*
1222 ** WEBPAGE: style.css loadavg-exempt
1223 **
1224 ** Return the style sheet. The style sheet is assemblied from
1225 ** multiple sources, in order:
1226 **
1227 ** (1) The built-in "default.css" style sheet containing basic defaults.
@@ -1325,12 +1327,23 @@
1327 /*
1328 ** WEBPAGE: honeypot
1329 ** This page is a honeypot for spiders and bots.
1330 */
1331 void honeypot_page(void){
1332 style_header("I think you are a robot");
1333 @ <p>You seem like a robot.</p>
1334 @
1335 @ <p>Is this wrong? Are you really a human? If so, please prove it
1336 @ by <a href="%R/login">logging in</a>.
1337 if( g.anon.Hyperlink ){
1338 @ You can <a href="%R/login?anon=1">log in anonymously</a> if you
1339 @ prefer.
1340 }
1341 @ <p>Sorry for the inconvenience. The point of this is to prevent
1342 @ robots from following the countless of hyperlinks in this site and
1343 @ soaking up all the available CPU time and network bandwidth.
1344 style_finish_page();
1345 }
1346
1347 /*
1348 ** Webpages that encounter an error due to missing or incorrect
1349 ** query parameters can jump to this routine to render an error
@@ -1382,10 +1395,11 @@
1395 @ g.zTop = %h(g.zTop)<br />
1396 @ g.zPath = %h(g.zPath)<br />
1397 @ g.userUid = %d(g.userUid)<br />
1398 @ g.zLogin = %h(g.zLogin)<br />
1399 @ g.isHuman = %d(g.isHuman)<br />
1400 @ g.jsHref = %d(g.jsHref)<br />
1401 if( g.nRequest ){
1402 @ g.nRequest = %d(g.nRequest)<br />
1403 }
1404 if( g.nPendingRequest>1 ){
1405 @ g.nPendingRequest = %d(g.nPendingRequest)<br />
1406
--- src/style.chat.css
+++ src/style.chat.css
@@ -175,11 +175,13 @@
175175
body.chat #load-msg-toolbar > div > button {
176176
flex: 1 1 auto;
177177
}
178178
/* "Chat-only mode" hides the site header/footer, showing only
179179
the chat app. */
180
-body.chat.chat-only-mode{}
180
+body.chat.chat-only-mode{
181
+ padding: 0;
182
+}
181183
body.chat #chat-button-settings {}
182184
/** Popup widget for the /chat settings. */
183185
body.chat .chat-settings-popup {
184186
font-size: 0.8em;
185187
text-align: left;
@@ -271,10 +273,14 @@
271273
display: flex;
272274
flex-direction: row;
273275
align-items: stretch;
274276
flex-wrap: nowrap;
275277
}
278
+body.chat.chat-only-mode #chat-input-line-wrapper {
279
+ padding: 0 0.25em;
280
+}
281
+
276282
/*body.chat #chat-input-line-wrapper:not(.compact) {
277283
flex-wrap: nowrap;
278284
}*/
279285
body.chat #chat-input-line-wrapper.compact {
280286
/* "The problem" with wrapping, together with a contenteditable input
281287
--- src/style.chat.css
+++ src/style.chat.css
@@ -175,11 +175,13 @@
175 body.chat #load-msg-toolbar > div > button {
176 flex: 1 1 auto;
177 }
178 /* "Chat-only mode" hides the site header/footer, showing only
179 the chat app. */
180 body.chat.chat-only-mode{}
 
 
181 body.chat #chat-button-settings {}
182 /** Popup widget for the /chat settings. */
183 body.chat .chat-settings-popup {
184 font-size: 0.8em;
185 text-align: left;
@@ -271,10 +273,14 @@
271 display: flex;
272 flex-direction: row;
273 align-items: stretch;
274 flex-wrap: nowrap;
275 }
 
 
 
 
276 /*body.chat #chat-input-line-wrapper:not(.compact) {
277 flex-wrap: nowrap;
278 }*/
279 body.chat #chat-input-line-wrapper.compact {
280 /* "The problem" with wrapping, together with a contenteditable input
281
--- src/style.chat.css
+++ src/style.chat.css
@@ -175,11 +175,13 @@
175 body.chat #load-msg-toolbar > div > button {
176 flex: 1 1 auto;
177 }
178 /* "Chat-only mode" hides the site header/footer, showing only
179 the chat app. */
180 body.chat.chat-only-mode{
181 padding: 0;
182 }
183 body.chat #chat-button-settings {}
184 /** Popup widget for the /chat settings. */
185 body.chat .chat-settings-popup {
186 font-size: 0.8em;
187 text-align: left;
@@ -271,10 +273,14 @@
273 display: flex;
274 flex-direction: row;
275 align-items: stretch;
276 flex-wrap: nowrap;
277 }
278 body.chat.chat-only-mode #chat-input-line-wrapper {
279 padding: 0 0.25em;
280 }
281
282 /*body.chat #chat-input-line-wrapper:not(.compact) {
283 flex-wrap: nowrap;
284 }*/
285 body.chat #chat-input-line-wrapper.compact {
286 /* "The problem" with wrapping, together with a contenteditable input
287
+13 -9
--- src/sync.c
+++ src/sync.c
@@ -112,18 +112,18 @@
112112
** not acquired unless autosync is set to "on".
113113
**
114114
** If dont-push setting is true, that is the same as having autosync
115115
** set to pullonly.
116116
*/
117
-int autosync(int flags){
117
+static int autosync(int flags, const char *zSubsys){
118118
const char *zAutosync;
119119
int rc;
120120
int configSync = 0; /* configuration changes transferred */
121121
if( g.fNoSync ){
122122
return 0;
123123
}
124
- zAutosync = db_get("autosync", 0);
124
+ zAutosync = db_get_for_subsystem("autosync", zSubsys);
125125
if( zAutosync==0 ) zAutosync = "on"; /* defend against misconfig */
126126
if( is_false(zAutosync) ) return 0;
127127
if( db_get_boolean("dont-push",0)
128128
|| sqlite3_strglob("*pull*", zAutosync)==0
129129
){
@@ -150,25 +150,28 @@
150150
return rc;
151151
}
152152
153153
/*
154154
** This routine will try a number of times to perform autosync with a
155
-** 0.5 second sleep between attempts.
155
+** 0.5 second sleep between attempts. The number of attempts is determined
156
+** by the "autosync-tries" setting, which defaults to 1.
156157
**
157158
** Return zero on success and non-zero on a failure. If failure occurs
158159
** and doPrompt flag is true, ask the user if they want to continue, and
159160
** if they answer "yes" then return zero in spite of the failure.
160161
*/
161
-int autosync_loop(int flags, int nTries, int doPrompt){
162
+int autosync_loop(int flags, int doPrompt, const char *zSubsystem){
162163
int n = 0;
163164
int rc = 0;
165
+ int nTries = db_get_int("autosync-tries", 1);
164166
if( (flags & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL)
165167
&& db_get_boolean("uv-sync",0)
166168
){
167169
flags |= SYNC_UNVERSIONED;
168170
}
169
- while( (n==0 || n<nTries) && (rc=autosync(flags)) ){
171
+ if( nTries<1 ) nTries = 1;
172
+ while( (n==0 || n<nTries) && (rc=autosync(flags, zSubsystem)) ){
170173
if( rc ){
171174
if( ++n<nTries ){
172175
fossil_warning("Autosync failed, making another attempt.");
173176
sqlite3_sleep(500);
174177
}else{
@@ -232,10 +235,13 @@
232235
*pSyncFlags |= SYNC_NOHTTPCOMPRESS;
233236
}
234237
if( find_option("all",0,0)!=0 ){
235238
*pSyncFlags |= SYNC_ALLURL;
236239
}
240
+
241
+ /* Undocumented option to cause links transitive links to other
242
+ ** repositories to be shared */
237243
if( ((*pSyncFlags) & SYNC_PULL)!=0
238244
&& find_option("share-links",0,0)!=0
239245
){
240246
*pSyncFlags |= SYNC_SHARE_LINKS;
241247
}
@@ -319,11 +325,10 @@
319325
** --once Do not remember URL for subsequent syncs
320326
** --private Pull private branches too
321327
** --project-code CODE Use CODE as the project code
322328
** --proxy PROXY Use the specified HTTP proxy
323329
** -R|--repository REPO Local repository to pull into
324
-** --share-links Share links to mirror repos
325330
** --ssl-identity FILE Local SSL credentials, if requested by remote
326331
** --ssh-command SSH Use SSH as the "ssh" command
327332
** --transport-command CMD Use external command CMD to move messages
328333
** between client and server
329334
** -v|--verbose Additional (debugging) output
@@ -422,11 +427,10 @@
422427
** --no-http-compression Do not compress HTTP traffic
423428
** --once Do not remember URL for subsequent syncs
424429
** --proxy PROXY Use the specified HTTP proxy
425430
** --private Sync private branches too
426431
** -R|--repository REPO Local repository to sync with
427
-** --share-links Share links to mirror repos
428432
** --ssl-identity FILE Local SSL credentials, if requested by remote
429433
** --ssh-command SSH Use SSH as the "ssh" command
430434
** --transport-command CMD Use external command CMD to move message
431435
** between the client and the server
432436
** -u|--unversioned Also sync unversioned content
@@ -487,11 +491,11 @@
487491
** Add a new named URL. Afterwards, NAME can be used as a short
488492
** symbolic name for URL in contexts where a URL is required. The
489493
** URL argument can be "default" or a prior symbolic name, to make
490494
** a copy of an existing URL under a new name.
491495
**
492
-** > fossil config-data
496
+** > fossil remote config-data
493497
**
494498
** DEBUG USE ONLY - Show the name and value of every CONFIG table
495499
** entry in the repository that is associated with the remote URL store.
496500
** Passwords are obscured in the output.
497501
**
@@ -612,11 +616,11 @@
612616
db_begin_write();
613617
if( fossil_strcmp(zUrl,"default")==0 ){
614618
x.canonical = db_get("last-sync-url",0);
615619
x.passwd = unobscure(db_get("last-sync-pw",0));
616620
}else{
617
- url_parse_local(zUrl, URL_PROMPT_PW, &x);
621
+ url_parse_local(zUrl, URL_PROMPT_PW|URL_USE_CONFIG, &x);
618622
}
619623
db_unprotect(PROTECT_CONFIG);
620624
db_multi_exec(
621625
"REPLACE INTO config(name, value, mtime)"
622626
" VALUES('sync-url:%q',%Q,now())",
623627
--- src/sync.c
+++ src/sync.c
@@ -112,18 +112,18 @@
112 ** not acquired unless autosync is set to "on".
113 **
114 ** If dont-push setting is true, that is the same as having autosync
115 ** set to pullonly.
116 */
117 int autosync(int flags){
118 const char *zAutosync;
119 int rc;
120 int configSync = 0; /* configuration changes transferred */
121 if( g.fNoSync ){
122 return 0;
123 }
124 zAutosync = db_get("autosync", 0);
125 if( zAutosync==0 ) zAutosync = "on"; /* defend against misconfig */
126 if( is_false(zAutosync) ) return 0;
127 if( db_get_boolean("dont-push",0)
128 || sqlite3_strglob("*pull*", zAutosync)==0
129 ){
@@ -150,25 +150,28 @@
150 return rc;
151 }
152
153 /*
154 ** This routine will try a number of times to perform autosync with a
155 ** 0.5 second sleep between attempts.
 
156 **
157 ** Return zero on success and non-zero on a failure. If failure occurs
158 ** and doPrompt flag is true, ask the user if they want to continue, and
159 ** if they answer "yes" then return zero in spite of the failure.
160 */
161 int autosync_loop(int flags, int nTries, int doPrompt){
162 int n = 0;
163 int rc = 0;
 
164 if( (flags & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL)
165 && db_get_boolean("uv-sync",0)
166 ){
167 flags |= SYNC_UNVERSIONED;
168 }
169 while( (n==0 || n<nTries) && (rc=autosync(flags)) ){
 
170 if( rc ){
171 if( ++n<nTries ){
172 fossil_warning("Autosync failed, making another attempt.");
173 sqlite3_sleep(500);
174 }else{
@@ -232,10 +235,13 @@
232 *pSyncFlags |= SYNC_NOHTTPCOMPRESS;
233 }
234 if( find_option("all",0,0)!=0 ){
235 *pSyncFlags |= SYNC_ALLURL;
236 }
 
 
 
237 if( ((*pSyncFlags) & SYNC_PULL)!=0
238 && find_option("share-links",0,0)!=0
239 ){
240 *pSyncFlags |= SYNC_SHARE_LINKS;
241 }
@@ -319,11 +325,10 @@
319 ** --once Do not remember URL for subsequent syncs
320 ** --private Pull private branches too
321 ** --project-code CODE Use CODE as the project code
322 ** --proxy PROXY Use the specified HTTP proxy
323 ** -R|--repository REPO Local repository to pull into
324 ** --share-links Share links to mirror repos
325 ** --ssl-identity FILE Local SSL credentials, if requested by remote
326 ** --ssh-command SSH Use SSH as the "ssh" command
327 ** --transport-command CMD Use external command CMD to move messages
328 ** between client and server
329 ** -v|--verbose Additional (debugging) output
@@ -422,11 +427,10 @@
422 ** --no-http-compression Do not compress HTTP traffic
423 ** --once Do not remember URL for subsequent syncs
424 ** --proxy PROXY Use the specified HTTP proxy
425 ** --private Sync private branches too
426 ** -R|--repository REPO Local repository to sync with
427 ** --share-links Share links to mirror repos
428 ** --ssl-identity FILE Local SSL credentials, if requested by remote
429 ** --ssh-command SSH Use SSH as the "ssh" command
430 ** --transport-command CMD Use external command CMD to move message
431 ** between the client and the server
432 ** -u|--unversioned Also sync unversioned content
@@ -487,11 +491,11 @@
487 ** Add a new named URL. Afterwards, NAME can be used as a short
488 ** symbolic name for URL in contexts where a URL is required. The
489 ** URL argument can be "default" or a prior symbolic name, to make
490 ** a copy of an existing URL under a new name.
491 **
492 ** > fossil config-data
493 **
494 ** DEBUG USE ONLY - Show the name and value of every CONFIG table
495 ** entry in the repository that is associated with the remote URL store.
496 ** Passwords are obscured in the output.
497 **
@@ -612,11 +616,11 @@
612 db_begin_write();
613 if( fossil_strcmp(zUrl,"default")==0 ){
614 x.canonical = db_get("last-sync-url",0);
615 x.passwd = unobscure(db_get("last-sync-pw",0));
616 }else{
617 url_parse_local(zUrl, URL_PROMPT_PW, &x);
618 }
619 db_unprotect(PROTECT_CONFIG);
620 db_multi_exec(
621 "REPLACE INTO config(name, value, mtime)"
622 " VALUES('sync-url:%q',%Q,now())",
623
--- src/sync.c
+++ src/sync.c
@@ -112,18 +112,18 @@
112 ** not acquired unless autosync is set to "on".
113 **
114 ** If dont-push setting is true, that is the same as having autosync
115 ** set to pullonly.
116 */
117 static int autosync(int flags, const char *zSubsys){
118 const char *zAutosync;
119 int rc;
120 int configSync = 0; /* configuration changes transferred */
121 if( g.fNoSync ){
122 return 0;
123 }
124 zAutosync = db_get_for_subsystem("autosync", zSubsys);
125 if( zAutosync==0 ) zAutosync = "on"; /* defend against misconfig */
126 if( is_false(zAutosync) ) return 0;
127 if( db_get_boolean("dont-push",0)
128 || sqlite3_strglob("*pull*", zAutosync)==0
129 ){
@@ -150,25 +150,28 @@
150 return rc;
151 }
152
153 /*
154 ** This routine will try a number of times to perform autosync with a
155 ** 0.5 second sleep between attempts. The number of attempts is determined
156 ** by the "autosync-tries" setting, which defaults to 1.
157 **
158 ** Return zero on success and non-zero on a failure. If failure occurs
159 ** and doPrompt flag is true, ask the user if they want to continue, and
160 ** if they answer "yes" then return zero in spite of the failure.
161 */
162 int autosync_loop(int flags, int doPrompt, const char *zSubsystem){
163 int n = 0;
164 int rc = 0;
165 int nTries = db_get_int("autosync-tries", 1);
166 if( (flags & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL)
167 && db_get_boolean("uv-sync",0)
168 ){
169 flags |= SYNC_UNVERSIONED;
170 }
171 if( nTries<1 ) nTries = 1;
172 while( (n==0 || n<nTries) && (rc=autosync(flags, zSubsystem)) ){
173 if( rc ){
174 if( ++n<nTries ){
175 fossil_warning("Autosync failed, making another attempt.");
176 sqlite3_sleep(500);
177 }else{
@@ -232,10 +235,13 @@
235 *pSyncFlags |= SYNC_NOHTTPCOMPRESS;
236 }
237 if( find_option("all",0,0)!=0 ){
238 *pSyncFlags |= SYNC_ALLURL;
239 }
240
241 /* Undocumented option to cause links transitive links to other
242 ** repositories to be shared */
243 if( ((*pSyncFlags) & SYNC_PULL)!=0
244 && find_option("share-links",0,0)!=0
245 ){
246 *pSyncFlags |= SYNC_SHARE_LINKS;
247 }
@@ -319,11 +325,10 @@
325 ** --once Do not remember URL for subsequent syncs
326 ** --private Pull private branches too
327 ** --project-code CODE Use CODE as the project code
328 ** --proxy PROXY Use the specified HTTP proxy
329 ** -R|--repository REPO Local repository to pull into
 
330 ** --ssl-identity FILE Local SSL credentials, if requested by remote
331 ** --ssh-command SSH Use SSH as the "ssh" command
332 ** --transport-command CMD Use external command CMD to move messages
333 ** between client and server
334 ** -v|--verbose Additional (debugging) output
@@ -422,11 +427,10 @@
427 ** --no-http-compression Do not compress HTTP traffic
428 ** --once Do not remember URL for subsequent syncs
429 ** --proxy PROXY Use the specified HTTP proxy
430 ** --private Sync private branches too
431 ** -R|--repository REPO Local repository to sync with
 
432 ** --ssl-identity FILE Local SSL credentials, if requested by remote
433 ** --ssh-command SSH Use SSH as the "ssh" command
434 ** --transport-command CMD Use external command CMD to move message
435 ** between the client and the server
436 ** -u|--unversioned Also sync unversioned content
@@ -487,11 +491,11 @@
491 ** Add a new named URL. Afterwards, NAME can be used as a short
492 ** symbolic name for URL in contexts where a URL is required. The
493 ** URL argument can be "default" or a prior symbolic name, to make
494 ** a copy of an existing URL under a new name.
495 **
496 ** > fossil remote config-data
497 **
498 ** DEBUG USE ONLY - Show the name and value of every CONFIG table
499 ** entry in the repository that is associated with the remote URL store.
500 ** Passwords are obscured in the output.
501 **
@@ -612,11 +616,11 @@
616 db_begin_write();
617 if( fossil_strcmp(zUrl,"default")==0 ){
618 x.canonical = db_get("last-sync-url",0);
619 x.passwd = unobscure(db_get("last-sync-pw",0));
620 }else{
621 url_parse_local(zUrl, URL_PROMPT_PW|URL_USE_CONFIG, &x);
622 }
623 db_unprotect(PROTECT_CONFIG);
624 db_multi_exec(
625 "REPLACE INTO config(name, value, mtime)"
626 " VALUES('sync-url:%q',%Q,now())",
627
+3 -3
--- src/tag.c
+++ src/tag.c
@@ -656,11 +656,11 @@
656656
"SELECT tagname FROM tag"
657657
" WHERE EXISTS(SELECT 1 FROM tagxref"
658658
" WHERE tagid=tag.tagid"
659659
" AND tagtype%s%d)"
660660
" AND CASE WHEN %Q IS NULL THEN 1 ELSE tagname GLOB %Q||'*' "
661
- " END ORDER BY tagname",
661
+ " END ORDER BY tagname COLLATE uintnocase",
662662
zTagType!=0 ? (fInverse!=0?"<>":"=") : ">"/*safe-for-%s*/,
663663
nTagType, zTagPrefix, zTagPrefix
664664
);
665665
while( db_step(&q)==SQLITE_ROW ){
666666
const char *zName = db_column_text(&q, 0);
@@ -698,11 +698,11 @@
698698
}
699699
db_prepare(&q,
700700
"SELECT tagname, value FROM tagxref, tag"
701701
" WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
702702
" AND tagtype%s%d"
703
- " ORDER BY tagname",
703
+ " ORDER BY tagname COLLATE uintnocase",
704704
rid,
705705
zTagType!=0 ? (fInverse!=0?"<>":"=") : ">"/*safe-for-%s*/,
706706
nTagType
707707
);
708708
while( db_step(&q)==SQLITE_ROW ){
@@ -817,11 +817,11 @@
817817
" FROM tag"
818818
" WHERE EXISTS(SELECT 1 FROM tagxref"
819819
" WHERE tagid=tag.tagid"
820820
" AND tagtype=1)"
821821
" AND tagname GLOB 'sym-*'"
822
- " ORDER BY tagname"
822
+ " ORDER BY tagname COLLATE uintnocase"
823823
);
824824
@ <ul>
825825
while( db_step(&q)==SQLITE_ROW ){
826826
const char *zName = db_column_text(&q, 0);
827827
if( g.perm.Hyperlink ){
828828
--- src/tag.c
+++ src/tag.c
@@ -656,11 +656,11 @@
656 "SELECT tagname FROM tag"
657 " WHERE EXISTS(SELECT 1 FROM tagxref"
658 " WHERE tagid=tag.tagid"
659 " AND tagtype%s%d)"
660 " AND CASE WHEN %Q IS NULL THEN 1 ELSE tagname GLOB %Q||'*' "
661 " END ORDER BY tagname",
662 zTagType!=0 ? (fInverse!=0?"<>":"=") : ">"/*safe-for-%s*/,
663 nTagType, zTagPrefix, zTagPrefix
664 );
665 while( db_step(&q)==SQLITE_ROW ){
666 const char *zName = db_column_text(&q, 0);
@@ -698,11 +698,11 @@
698 }
699 db_prepare(&q,
700 "SELECT tagname, value FROM tagxref, tag"
701 " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
702 " AND tagtype%s%d"
703 " ORDER BY tagname",
704 rid,
705 zTagType!=0 ? (fInverse!=0?"<>":"=") : ">"/*safe-for-%s*/,
706 nTagType
707 );
708 while( db_step(&q)==SQLITE_ROW ){
@@ -817,11 +817,11 @@
817 " FROM tag"
818 " WHERE EXISTS(SELECT 1 FROM tagxref"
819 " WHERE tagid=tag.tagid"
820 " AND tagtype=1)"
821 " AND tagname GLOB 'sym-*'"
822 " ORDER BY tagname"
823 );
824 @ <ul>
825 while( db_step(&q)==SQLITE_ROW ){
826 const char *zName = db_column_text(&q, 0);
827 if( g.perm.Hyperlink ){
828
--- src/tag.c
+++ src/tag.c
@@ -656,11 +656,11 @@
656 "SELECT tagname FROM tag"
657 " WHERE EXISTS(SELECT 1 FROM tagxref"
658 " WHERE tagid=tag.tagid"
659 " AND tagtype%s%d)"
660 " AND CASE WHEN %Q IS NULL THEN 1 ELSE tagname GLOB %Q||'*' "
661 " END ORDER BY tagname COLLATE uintnocase",
662 zTagType!=0 ? (fInverse!=0?"<>":"=") : ">"/*safe-for-%s*/,
663 nTagType, zTagPrefix, zTagPrefix
664 );
665 while( db_step(&q)==SQLITE_ROW ){
666 const char *zName = db_column_text(&q, 0);
@@ -698,11 +698,11 @@
698 }
699 db_prepare(&q,
700 "SELECT tagname, value FROM tagxref, tag"
701 " WHERE tagxref.rid=%d AND tagxref.tagid=tag.tagid"
702 " AND tagtype%s%d"
703 " ORDER BY tagname COLLATE uintnocase",
704 rid,
705 zTagType!=0 ? (fInverse!=0?"<>":"=") : ">"/*safe-for-%s*/,
706 nTagType
707 );
708 while( db_step(&q)==SQLITE_ROW ){
@@ -817,11 +817,11 @@
817 " FROM tag"
818 " WHERE EXISTS(SELECT 1 FROM tagxref"
819 " WHERE tagid=tag.tagid"
820 " AND tagtype=1)"
821 " AND tagname GLOB 'sym-*'"
822 " ORDER BY tagname COLLATE uintnocase"
823 );
824 @ <ul>
825 while( db_step(&q)==SQLITE_ROW ){
826 const char *zName = db_column_text(&q, 0);
827 if( g.perm.Hyperlink ){
828
+2 -2
--- src/tar.c
+++ src/tar.c
@@ -496,11 +496,11 @@
496496
nPrefix = blob_size(&filename);
497497
498498
pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
499499
if( pManifest ){
500500
int flg, eflg = 0;
501
- mTime = (pManifest->rDate - 2440587.5)*86400.0;
501
+ mTime = (unsigned)((pManifest->rDate - 2440587.5)*86400.0);
502502
if( pTar ) tar_begin(mTime);
503503
flg = db_get_manifest_setting();
504504
if( flg ){
505505
/* eflg is the effective flags, taking include/exclude into account */
506506
if( (pInclude==0 || glob_match(pInclude, "manifest"))
@@ -756,11 +756,11 @@
756756
Blob tarball; /* Tarball accumulated here */
757757
const char *z;
758758
759759
login_check_credentials();
760760
if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
761
- load_control();
761
+ fossil_nice_default();
762762
zName = fossil_strdup(PD("name",""));
763763
z = P("r");
764764
if( z==0 ) z = P("uuid");
765765
if( z==0 ) z = tar_uuid_from_name(&zName);
766766
if( z==0 ) z = "trunk";
767767
--- src/tar.c
+++ src/tar.c
@@ -496,11 +496,11 @@
496 nPrefix = blob_size(&filename);
497
498 pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
499 if( pManifest ){
500 int flg, eflg = 0;
501 mTime = (pManifest->rDate - 2440587.5)*86400.0;
502 if( pTar ) tar_begin(mTime);
503 flg = db_get_manifest_setting();
504 if( flg ){
505 /* eflg is the effective flags, taking include/exclude into account */
506 if( (pInclude==0 || glob_match(pInclude, "manifest"))
@@ -756,11 +756,11 @@
756 Blob tarball; /* Tarball accumulated here */
757 const char *z;
758
759 login_check_credentials();
760 if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
761 load_control();
762 zName = fossil_strdup(PD("name",""));
763 z = P("r");
764 if( z==0 ) z = P("uuid");
765 if( z==0 ) z = tar_uuid_from_name(&zName);
766 if( z==0 ) z = "trunk";
767
--- src/tar.c
+++ src/tar.c
@@ -496,11 +496,11 @@
496 nPrefix = blob_size(&filename);
497
498 pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
499 if( pManifest ){
500 int flg, eflg = 0;
501 mTime = (unsigned)((pManifest->rDate - 2440587.5)*86400.0);
502 if( pTar ) tar_begin(mTime);
503 flg = db_get_manifest_setting();
504 if( flg ){
505 /* eflg is the effective flags, taking include/exclude into account */
506 if( (pInclude==0 || glob_match(pInclude, "manifest"))
@@ -756,11 +756,11 @@
756 Blob tarball; /* Tarball accumulated here */
757 const char *z;
758
759 login_check_credentials();
760 if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
761 fossil_nice_default();
762 zName = fossil_strdup(PD("name",""));
763 z = P("r");
764 if( z==0 ) z = P("uuid");
765 if( z==0 ) z = tar_uuid_from_name(&zName);
766 if( z==0 ) z = "trunk";
767
+5 -6
--- src/timeline.c
+++ src/timeline.c
@@ -911,11 +911,11 @@
911911
** Only exists if "mo" exists.
912912
** cu: Extend the mu merge arrow up to this row as a cherrypick
913913
** merge line, if this value exists.
914914
** u: Draw a thick child-line out of the top of this node and up to
915915
** the node with an id equal to this value. 0 if it is straight to
916
- ** the top of the page or just up a little wasy, -1 if there is
916
+ ** the top of the page or just up a little ways, -1 if there is
917917
** no thick-line riser (if the node is a leaf).
918918
** sb: Draw a dotted child-line out of the top of this node up to the
919919
** node with the id equal to the value. This is like "u" except
920920
** that the line is dotted instead of solid and has no arrow.
921921
** Mnemonic: "Same Branch".
@@ -925,14 +925,13 @@
925925
** is the rail on which the riser should run and the second integer
926926
** is the id of the node upto which the riser should run. If there
927927
** are no risers, this array does not exist.
928928
** mi: "merge-in". An array of integer rail positions from which
929929
** merge arrows should be drawn into this node. If the value is
930
- ** negative, then the rail position is the absolute value of mi[]
931
- ** and a thin merge-arrow descender is drawn to the bottom of
932
- ** the screen. This array is omitted if there are no inbound
933
- ** merges.
930
+ ** negative, then the rail position is -1-mi[] and a thin merge-arrow
931
+ ** descender is drawn to the bottom of the screen. This array is
932
+ ** omitted if there are no inbound merges.
934933
** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
935934
** omitted if there are no cherrypick merges.
936935
** h: The artifact hash of the object being graphed
937936
* br: The branch to which the artifact belongs
938937
*/
@@ -981,11 +980,11 @@
981980
}
982981
/* mi */
983982
for(i=k=0; i<GR_MAX_RAIL; i++){
984983
if( pRow->mergeIn[i]==1 ){
985984
int mi = aiMap[i];
986
- if( (pRow->mergeDown >> i) & 1 ) mi = -mi;
985
+ if( (pRow->mergeDown >> i) & 1 ) mi = -1-mi;
987986
if( k==0 ){
988987
cgi_printf("\"mi\":");
989988
cSep = '[';
990989
}
991990
k++;
992991
--- src/timeline.c
+++ src/timeline.c
@@ -911,11 +911,11 @@
911 ** Only exists if "mo" exists.
912 ** cu: Extend the mu merge arrow up to this row as a cherrypick
913 ** merge line, if this value exists.
914 ** u: Draw a thick child-line out of the top of this node and up to
915 ** the node with an id equal to this value. 0 if it is straight to
916 ** the top of the page or just up a little wasy, -1 if there is
917 ** no thick-line riser (if the node is a leaf).
918 ** sb: Draw a dotted child-line out of the top of this node up to the
919 ** node with the id equal to the value. This is like "u" except
920 ** that the line is dotted instead of solid and has no arrow.
921 ** Mnemonic: "Same Branch".
@@ -925,14 +925,13 @@
925 ** is the rail on which the riser should run and the second integer
926 ** is the id of the node upto which the riser should run. If there
927 ** are no risers, this array does not exist.
928 ** mi: "merge-in". An array of integer rail positions from which
929 ** merge arrows should be drawn into this node. If the value is
930 ** negative, then the rail position is the absolute value of mi[]
931 ** and a thin merge-arrow descender is drawn to the bottom of
932 ** the screen. This array is omitted if there are no inbound
933 ** merges.
934 ** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
935 ** omitted if there are no cherrypick merges.
936 ** h: The artifact hash of the object being graphed
937 * br: The branch to which the artifact belongs
938 */
@@ -981,11 +980,11 @@
981 }
982 /* mi */
983 for(i=k=0; i<GR_MAX_RAIL; i++){
984 if( pRow->mergeIn[i]==1 ){
985 int mi = aiMap[i];
986 if( (pRow->mergeDown >> i) & 1 ) mi = -mi;
987 if( k==0 ){
988 cgi_printf("\"mi\":");
989 cSep = '[';
990 }
991 k++;
992
--- src/timeline.c
+++ src/timeline.c
@@ -911,11 +911,11 @@
911 ** Only exists if "mo" exists.
912 ** cu: Extend the mu merge arrow up to this row as a cherrypick
913 ** merge line, if this value exists.
914 ** u: Draw a thick child-line out of the top of this node and up to
915 ** the node with an id equal to this value. 0 if it is straight to
916 ** the top of the page or just up a little ways, -1 if there is
917 ** no thick-line riser (if the node is a leaf).
918 ** sb: Draw a dotted child-line out of the top of this node up to the
919 ** node with the id equal to the value. This is like "u" except
920 ** that the line is dotted instead of solid and has no arrow.
921 ** Mnemonic: "Same Branch".
@@ -925,14 +925,13 @@
925 ** is the rail on which the riser should run and the second integer
926 ** is the id of the node upto which the riser should run. If there
927 ** are no risers, this array does not exist.
928 ** mi: "merge-in". An array of integer rail positions from which
929 ** merge arrows should be drawn into this node. If the value is
930 ** negative, then the rail position is -1-mi[] and a thin merge-arrow
931 ** descender is drawn to the bottom of the screen. This array is
932 ** omitted if there are no inbound merges.
 
933 ** ci: "cherrypick-in". Like "mi" except for cherrypick merges.
934 ** omitted if there are no cherrypick merges.
935 ** h: The artifact hash of the object being graphed
936 * br: The branch to which the artifact belongs
937 */
@@ -981,11 +980,11 @@
980 }
981 /* mi */
982 for(i=k=0; i<GR_MAX_RAIL; i++){
983 if( pRow->mergeIn[i]==1 ){
984 int mi = aiMap[i];
985 if( (pRow->mergeDown >> i) & 1 ) mi = -1-mi;
986 if( k==0 ){
987 cgi_printf("\"mi\":");
988 cSep = '[';
989 }
990 k++;
991
+4 -2
--- src/update.c
+++ src/update.c
@@ -165,12 +165,11 @@
165165
166166
db_must_be_within_tree();
167167
vid = db_lget_int("checkout", 0);
168168
user_select();
169169
if( !dryRunFlag && !internalUpdate && !bNosync ){
170
- if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag,
171
- db_get_int("autosync-tries", 1), 1) ){
170
+ if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "update") ){
172171
fossil_fatal("update abandoned due to sync failure");
173172
}
174173
}
175174
176175
/* Create any empty directories now, as well as after the update,
@@ -561,10 +560,13 @@
561560
fossil_print("%.79c\n",'-');
562561
if( nUpdate==0 ){
563562
show_common_info(tid, "checkout:", 1, 0);
564563
fossil_print("%-13s None. Already up-to-date\n", "changes:");
565564
}else{
565
+ fossil_print("%-13s %.40s %s\n", "updated-from:", rid_to_uuid(vid),
566
+ db_text("", "SELECT datetime(mtime) || ' UTC' FROM event "
567
+ " WHERE objid=%d", vid));
566568
show_common_info(tid, "updated-to:", 1, 0);
567569
fossil_print("%-13s %d file%s modified.\n", "changes:",
568570
nUpdate, nUpdate>1 ? "s" : "");
569571
}
570572
571573
--- src/update.c
+++ src/update.c
@@ -165,12 +165,11 @@
165
166 db_must_be_within_tree();
167 vid = db_lget_int("checkout", 0);
168 user_select();
169 if( !dryRunFlag && !internalUpdate && !bNosync ){
170 if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag,
171 db_get_int("autosync-tries", 1), 1) ){
172 fossil_fatal("update abandoned due to sync failure");
173 }
174 }
175
176 /* Create any empty directories now, as well as after the update,
@@ -561,10 +560,13 @@
561 fossil_print("%.79c\n",'-');
562 if( nUpdate==0 ){
563 show_common_info(tid, "checkout:", 1, 0);
564 fossil_print("%-13s None. Already up-to-date\n", "changes:");
565 }else{
 
 
 
566 show_common_info(tid, "updated-to:", 1, 0);
567 fossil_print("%-13s %d file%s modified.\n", "changes:",
568 nUpdate, nUpdate>1 ? "s" : "");
569 }
570
571
--- src/update.c
+++ src/update.c
@@ -165,12 +165,11 @@
165
166 db_must_be_within_tree();
167 vid = db_lget_int("checkout", 0);
168 user_select();
169 if( !dryRunFlag && !internalUpdate && !bNosync ){
170 if( autosync_loop(SYNC_PULL + SYNC_VERBOSE*verboseFlag, 1, "update") ){
 
171 fossil_fatal("update abandoned due to sync failure");
172 }
173 }
174
175 /* Create any empty directories now, as well as after the update,
@@ -561,10 +560,13 @@
560 fossil_print("%.79c\n",'-');
561 if( nUpdate==0 ){
562 show_common_info(tid, "checkout:", 1, 0);
563 fossil_print("%-13s None. Already up-to-date\n", "changes:");
564 }else{
565 fossil_print("%-13s %.40s %s\n", "updated-from:", rid_to_uuid(vid),
566 db_text("", "SELECT datetime(mtime) || ' UTC' FROM event "
567 " WHERE objid=%d", vid));
568 show_common_info(tid, "updated-to:", 1, 0);
569 fossil_print("%-13s %d file%s modified.\n", "changes:",
570 nUpdate, nUpdate>1 ? "s" : "");
571 }
572
573
+19
--- src/util.c
+++ src/util.c
@@ -896,5 +896,24 @@
896896
}
897897
}
898898
#endif
899899
return zBrowser;
900900
}
901
+
902
+/*
903
+** On non-Windows systems, calls nice(2) with the given level. Errors
904
+** are ignored. On Windows this is a no-op.
905
+*/
906
+void fossil_nice(int level){
907
+#ifndef _WIN32
908
+ nice(level);
909
+#else
910
+ (void)level;
911
+#endif
912
+}
913
+
914
+/*
915
+** Calls fossil_nice() with a default level.
916
+*/
917
+void fossil_nice_default(void){
918
+ fossil_nice(20);
919
+}
901920
--- src/util.c
+++ src/util.c
@@ -896,5 +896,24 @@
896 }
897 }
898 #endif
899 return zBrowser;
900 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
901
--- src/util.c
+++ src/util.c
@@ -896,5 +896,24 @@
896 }
897 }
898 #endif
899 return zBrowser;
900 }
901
902 /*
903 ** On non-Windows systems, calls nice(2) with the given level. Errors
904 ** are ignored. On Windows this is a no-op.
905 */
906 void fossil_nice(int level){
907 #ifndef _WIN32
908 nice(level);
909 #else
910 (void)level;
911 #endif
912 }
913
914 /*
915 ** Calls fossil_nice() with a default level.
916 */
917 void fossil_nice_default(void){
918 fossil_nice(20);
919 }
920
+17 -8
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,14 +363,14 @@
363363
#endif
364364
}
365365
while( amt<szHdr ){
366366
if( sslConn ){
367367
#ifdef FOSSIL_ENABLE_SSL
368
- got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt);
368
+ got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 0);
369369
#endif
370370
}else{
371
- got = recv(p->s, &zBuf[amt], szHdr-amt, 0);
371
+ got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
372372
if( got==SOCKET_ERROR ) goto end_request;
373373
}
374374
if( got==0 ){
375375
wanted = 0;
376376
break;
@@ -394,11 +394,11 @@
394394
if( out==0 ) goto end_request;
395395
fwrite(zBuf, 1, amt, out);
396396
while( wanted>0 ){
397397
if( sslConn ){
398398
#ifdef FOSSIL_ENABLE_SSL
399
- got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
399
+ got = ssl_read_server(sslConn, zBuf, min(wanted, sizeof(zBuf)), 1);
400400
#endif
401401
}else{
402402
got = recv(p->s, zBuf, sizeof(zBuf), 0);
403403
if( got==SOCKET_ERROR ) goto end_request;
404404
}
@@ -437,10 +437,13 @@
437437
g.httpUseSSL ? "" : " --nossl", p->zOptions
438438
);
439439
in = fossil_fopen(zReplyFName, "w+b");
440440
fflush(out);
441441
fflush(aux);
442
+ if( g.fHttpTrace ){
443
+ fossil_print("%s\n", zCmd);
444
+ }
442445
fossil_system(zCmd);
443446
if( in ){
444447
while( (got = fread(zBuf, 1, sizeof(zBuf), in))>0 ){
445448
if( sslConn ){
446449
#ifdef FOSSIL_ENABLE_SSL
@@ -465,13 +468,15 @@
465468
if( shutdown(p->s,1)==0 ) shutdown(p->s,0);
466469
closesocket(p->s);
467470
/* Make multiple attempts to delete the temporary files. Sometimes AV
468471
** software keeps the files open for a few seconds, preventing the file
469472
** from being deleted on the first try. */
470
- for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
471
- for(i=1; i<=10 && file_delete(zCmdFName); i++){ Sleep(1000*i); }
472
- for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
473
+ if( !g.fHttpTrace ){
474
+ for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
475
+ for(i=1; i<=10 && file_delete(zCmdFName); i++){ Sleep(1000*i); }
476
+ for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
477
+ }
473478
fossil_free(p);
474479
}
475480
476481
/*
477482
** Process a single incoming SCGI request.
@@ -652,12 +657,16 @@
652657
}
653658
}
654659
if( !GetTempPathW(MAX_PATH, zTmpPath) ){
655660
fossil_panic("unable to get path to the temporary directory.");
656661
}
657
- zTempPrefix = mprintf("%sfossil_server_P%d",
658
- fossil_unicode_to_utf8(zTmpPath), iPort);
662
+ if( g.fHttpTrace ){
663
+ zTempPrefix = mprintf("httptrace");
664
+ }else{
665
+ zTempPrefix = mprintf("%sfossil_server_P%d",
666
+ fossil_unicode_to_utf8(zTmpPath), iPort);
667
+ }
659668
fossil_print("Temporary files: %s*\n", zTempPrefix);
660669
fossil_print("Listening for %s requests on TCP port %d\n",
661670
(flags&HTTP_SERVER_SCGI)!=0 ? "SCGI" :
662671
g.httpUseSSL ? "TLS-encrypted HTTPS" : "HTTP", iPort);
663672
if( zBrowser ){
664673
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,14 +363,14 @@
363 #endif
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt);
369 #endif
370 }else{
371 got = recv(p->s, &zBuf[amt], szHdr-amt, 0);
372 if( got==SOCKET_ERROR ) goto end_request;
373 }
374 if( got==0 ){
375 wanted = 0;
376 break;
@@ -394,11 +394,11 @@
394 if( out==0 ) goto end_request;
395 fwrite(zBuf, 1, amt, out);
396 while( wanted>0 ){
397 if( sslConn ){
398 #ifdef FOSSIL_ENABLE_SSL
399 got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
400 #endif
401 }else{
402 got = recv(p->s, zBuf, sizeof(zBuf), 0);
403 if( got==SOCKET_ERROR ) goto end_request;
404 }
@@ -437,10 +437,13 @@
437 g.httpUseSSL ? "" : " --nossl", p->zOptions
438 );
439 in = fossil_fopen(zReplyFName, "w+b");
440 fflush(out);
441 fflush(aux);
 
 
 
442 fossil_system(zCmd);
443 if( in ){
444 while( (got = fread(zBuf, 1, sizeof(zBuf), in))>0 ){
445 if( sslConn ){
446 #ifdef FOSSIL_ENABLE_SSL
@@ -465,13 +468,15 @@
465 if( shutdown(p->s,1)==0 ) shutdown(p->s,0);
466 closesocket(p->s);
467 /* Make multiple attempts to delete the temporary files. Sometimes AV
468 ** software keeps the files open for a few seconds, preventing the file
469 ** from being deleted on the first try. */
470 for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
471 for(i=1; i<=10 && file_delete(zCmdFName); i++){ Sleep(1000*i); }
472 for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
 
 
473 fossil_free(p);
474 }
475
476 /*
477 ** Process a single incoming SCGI request.
@@ -652,12 +657,16 @@
652 }
653 }
654 if( !GetTempPathW(MAX_PATH, zTmpPath) ){
655 fossil_panic("unable to get path to the temporary directory.");
656 }
657 zTempPrefix = mprintf("%sfossil_server_P%d",
658 fossil_unicode_to_utf8(zTmpPath), iPort);
 
 
 
 
659 fossil_print("Temporary files: %s*\n", zTempPrefix);
660 fossil_print("Listening for %s requests on TCP port %d\n",
661 (flags&HTTP_SERVER_SCGI)!=0 ? "SCGI" :
662 g.httpUseSSL ? "TLS-encrypted HTTPS" : "HTTP", iPort);
663 if( zBrowser ){
664
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,14 +363,14 @@
363 #endif
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 0);
369 #endif
370 }else{
371 got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
372 if( got==SOCKET_ERROR ) goto end_request;
373 }
374 if( got==0 ){
375 wanted = 0;
376 break;
@@ -394,11 +394,11 @@
394 if( out==0 ) goto end_request;
395 fwrite(zBuf, 1, amt, out);
396 while( wanted>0 ){
397 if( sslConn ){
398 #ifdef FOSSIL_ENABLE_SSL
399 got = ssl_read_server(sslConn, zBuf, min(wanted, sizeof(zBuf)), 1);
400 #endif
401 }else{
402 got = recv(p->s, zBuf, sizeof(zBuf), 0);
403 if( got==SOCKET_ERROR ) goto end_request;
404 }
@@ -437,10 +437,13 @@
437 g.httpUseSSL ? "" : " --nossl", p->zOptions
438 );
439 in = fossil_fopen(zReplyFName, "w+b");
440 fflush(out);
441 fflush(aux);
442 if( g.fHttpTrace ){
443 fossil_print("%s\n", zCmd);
444 }
445 fossil_system(zCmd);
446 if( in ){
447 while( (got = fread(zBuf, 1, sizeof(zBuf), in))>0 ){
448 if( sslConn ){
449 #ifdef FOSSIL_ENABLE_SSL
@@ -465,13 +468,15 @@
468 if( shutdown(p->s,1)==0 ) shutdown(p->s,0);
469 closesocket(p->s);
470 /* Make multiple attempts to delete the temporary files. Sometimes AV
471 ** software keeps the files open for a few seconds, preventing the file
472 ** from being deleted on the first try. */
473 if( !g.fHttpTrace ){
474 for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
475 for(i=1; i<=10 && file_delete(zCmdFName); i++){ Sleep(1000*i); }
476 for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
477 }
478 fossil_free(p);
479 }
480
481 /*
482 ** Process a single incoming SCGI request.
@@ -652,12 +657,16 @@
657 }
658 }
659 if( !GetTempPathW(MAX_PATH, zTmpPath) ){
660 fossil_panic("unable to get path to the temporary directory.");
661 }
662 if( g.fHttpTrace ){
663 zTempPrefix = mprintf("httptrace");
664 }else{
665 zTempPrefix = mprintf("%sfossil_server_P%d",
666 fossil_unicode_to_utf8(zTmpPath), iPort);
667 }
668 fossil_print("Temporary files: %s*\n", zTempPrefix);
669 fossil_print("Listening for %s requests on TCP port %d\n",
670 (flags&HTTP_SERVER_SCGI)!=0 ? "SCGI" :
671 g.httpUseSSL ? "TLS-encrypted HTTPS" : "HTTP", iPort);
672 if( zBrowser ){
673
+2 -2
--- src/zip.c
+++ src/zip.c
@@ -236,11 +236,11 @@
236236
*/
237237
void zip_set_timedate(double rDate){
238238
char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
239239
zip_set_timedate_from_str(zDate);
240240
fossil_free(zDate);
241
- unixTime = (rDate - 2440587.5)*86400.0;
241
+ unixTime = (int)((rDate - 2440587.5)*86400.0);
242242
}
243243
244244
/*
245245
** Append a single file to a growing ZIP archive.
246246
**
@@ -921,11 +921,11 @@
921921
zType = "SQL";
922922
}else{
923923
eType = ARCHIVE_ZIP;
924924
zType = "ZIP";
925925
}
926
- load_control();
926
+ fossil_nice_default();
927927
zName = fossil_strdup(PD("name",""));
928928
z = P("r");
929929
if( z==0 ) z = P("uuid");
930930
if( z==0 ) z = tar_uuid_from_name(&zName);
931931
if( z==0 ) z = "trunk";
932932
--- src/zip.c
+++ src/zip.c
@@ -236,11 +236,11 @@
236 */
237 void zip_set_timedate(double rDate){
238 char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
239 zip_set_timedate_from_str(zDate);
240 fossil_free(zDate);
241 unixTime = (rDate - 2440587.5)*86400.0;
242 }
243
244 /*
245 ** Append a single file to a growing ZIP archive.
246 **
@@ -921,11 +921,11 @@
921 zType = "SQL";
922 }else{
923 eType = ARCHIVE_ZIP;
924 zType = "ZIP";
925 }
926 load_control();
927 zName = fossil_strdup(PD("name",""));
928 z = P("r");
929 if( z==0 ) z = P("uuid");
930 if( z==0 ) z = tar_uuid_from_name(&zName);
931 if( z==0 ) z = "trunk";
932
--- src/zip.c
+++ src/zip.c
@@ -236,11 +236,11 @@
236 */
237 void zip_set_timedate(double rDate){
238 char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
239 zip_set_timedate_from_str(zDate);
240 fossil_free(zDate);
241 unixTime = (int)((rDate - 2440587.5)*86400.0);
242 }
243
244 /*
245 ** Append a single file to a growing ZIP archive.
246 **
@@ -921,11 +921,11 @@
921 zType = "SQL";
922 }else{
923 eType = ARCHIVE_ZIP;
924 zType = "ZIP";
925 }
926 fossil_nice_default();
927 zName = fossil_strdup(PD("name",""));
928 z = P("r");
929 if( z==0 ) z = P("uuid");
930 if( z==0 ) z = tar_uuid_from_name(&zName);
931 if( z==0 ) z = "trunk";
932
--- tools/makeheaders.c
+++ tools/makeheaders.c
@@ -2207,10 +2207,11 @@
22072207
while( *zArg && isspace(*zArg) && *zArg!='\n' ){
22082208
zArg++;
22092209
}
22102210
if( *zArg==0 || *zArg=='\n' ){ return 0; }
22112211
nArg = pToken->nText + (int)(pToken->zText - zArg);
2212
+ if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
22122213
if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){
22132214
PushIfMacro(0,0,0,pToken->nLine,PS_Interface);
22142215
}else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){
22152216
PushIfMacro(0,0,0,pToken->nLine,PS_Export);
22162217
}else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
@@ -2228,10 +2229,11 @@
22282229
while( *zArg && isspace(*zArg) && *zArg!='\n' ){
22292230
zArg++;
22302231
}
22312232
if( *zArg==0 || *zArg=='\n' ){ return 0; }
22322233
nArg = pToken->nText + (int)(pToken->zText - zArg);
2234
+ if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
22332235
PushIfMacro("defined",zArg,nArg,pToken->nLine,0);
22342236
}else if( nCmd==6 && strncmp(zCmd,"ifndef",6)==0 ){
22352237
/*
22362238
** Push an #ifndef.
22372239
*/
@@ -2239,10 +2241,11 @@
22392241
while( *zArg && isspace(*zArg) && *zArg!='\n' ){
22402242
zArg++;
22412243
}
22422244
if( *zArg==0 || *zArg=='\n' ){ return 0; }
22432245
nArg = pToken->nText + (int)(pToken->zText - zArg);
2246
+ if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
22442247
PushIfMacro("!defined",zArg,nArg,pToken->nLine,0);
22452248
}else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){
22462249
/*
22472250
** Invert the #if on the top of the stack
22482251
*/
22492252
--- tools/makeheaders.c
+++ tools/makeheaders.c
@@ -2207,10 +2207,11 @@
2207 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2208 zArg++;
2209 }
2210 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2211 nArg = pToken->nText + (int)(pToken->zText - zArg);
 
2212 if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){
2213 PushIfMacro(0,0,0,pToken->nLine,PS_Interface);
2214 }else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){
2215 PushIfMacro(0,0,0,pToken->nLine,PS_Export);
2216 }else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
@@ -2228,10 +2229,11 @@
2228 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2229 zArg++;
2230 }
2231 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2232 nArg = pToken->nText + (int)(pToken->zText - zArg);
 
2233 PushIfMacro("defined",zArg,nArg,pToken->nLine,0);
2234 }else if( nCmd==6 && strncmp(zCmd,"ifndef",6)==0 ){
2235 /*
2236 ** Push an #ifndef.
2237 */
@@ -2239,10 +2241,11 @@
2239 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2240 zArg++;
2241 }
2242 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2243 nArg = pToken->nText + (int)(pToken->zText - zArg);
 
2244 PushIfMacro("!defined",zArg,nArg,pToken->nLine,0);
2245 }else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){
2246 /*
2247 ** Invert the #if on the top of the stack
2248 */
2249
--- tools/makeheaders.c
+++ tools/makeheaders.c
@@ -2207,10 +2207,11 @@
2207 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2208 zArg++;
2209 }
2210 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2211 nArg = pToken->nText + (int)(pToken->zText - zArg);
2212 if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
2213 if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){
2214 PushIfMacro(0,0,0,pToken->nLine,PS_Interface);
2215 }else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){
2216 PushIfMacro(0,0,0,pToken->nLine,PS_Export);
2217 }else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
@@ -2228,10 +2229,11 @@
2229 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2230 zArg++;
2231 }
2232 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2233 nArg = pToken->nText + (int)(pToken->zText - zArg);
2234 if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
2235 PushIfMacro("defined",zArg,nArg,pToken->nLine,0);
2236 }else if( nCmd==6 && strncmp(zCmd,"ifndef",6)==0 ){
2237 /*
2238 ** Push an #ifndef.
2239 */
@@ -2239,10 +2241,11 @@
2241 while( *zArg && isspace(*zArg) && *zArg!='\n' ){
2242 zArg++;
2243 }
2244 if( *zArg==0 || *zArg=='\n' ){ return 0; }
2245 nArg = pToken->nText + (int)(pToken->zText - zArg);
2246 if (pToken->zText[pToken->nText-1] == '\r') { nArg--; }
2247 PushIfMacro("!defined",zArg,nArg,pToken->nLine,0);
2248 }else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){
2249 /*
2250 ** Invert the #if on the top of the stack
2251 */
2252
--- tools/makeheaders.html
+++ tools/makeheaders.html
@@ -572,11 +572,11 @@
572572
</p>
573573
574574
<p><li>
575575
Makeheaders generates an error message if it encounters a function or
576576
variable definition within a .h file.
577
-The .h files are suppose to contain only interface, not implementation.
577
+The .h files are supposed to contain only interface, not implementation.
578578
C compilers will not enforce this convention, but makeheaders does.
579579
</ul>
580580
581581
<p>
582582
As a final note, we observe that automatically generated declarations
583583
--- tools/makeheaders.html
+++ tools/makeheaders.html
@@ -572,11 +572,11 @@
572 </p>
573
574 <p><li>
575 Makeheaders generates an error message if it encounters a function or
576 variable definition within a .h file.
577 The .h files are suppose to contain only interface, not implementation.
578 C compilers will not enforce this convention, but makeheaders does.
579 </ul>
580
581 <p>
582 As a final note, we observe that automatically generated declarations
583
--- tools/makeheaders.html
+++ tools/makeheaders.html
@@ -572,11 +572,11 @@
572 </p>
573
574 <p><li>
575 Makeheaders generates an error message if it encounters a function or
576 variable definition within a .h file.
577 The .h files are supposed to contain only interface, not implementation.
578 C compilers will not enforce this convention, but makeheaders does.
579 </ul>
580
581 <p>
582 As a final note, we observe that automatically generated declarations
583
+74 -216
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -249,10 +249,16 @@
249249
}
250250
#lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1
251251
#lappend SQLITE_OPTIONS -DSQLITE_ENABLE_STAT4
252252
#lappend SQLITE_OPTIONS -DSQLITE_WIN32_NO_ANSI
253253
#lappend SQLITE_OPTIONS -DSQLITE_WINNT_MAX_PATH_CHARS=4096
254
+
255
+# Options used to compile the Pikchr library.
256
+#
257
+set PIKCHR_OPTIONS {
258
+ -DPIKCHR_TOKEN_LIMIT=10000
259
+}
254260
255261
# Options used to compile the included SQLite shell.
256262
#
257263
set SHELL_OPTIONS [concat $SQLITE_OPTIONS {
258264
-Dmain=sqlite3_shell
@@ -354,10 +360,11 @@
354360
}
355361
356362
writeln [string map [list \
357363
<<<SQLITE_OPTIONS>>> [join $SQLITE_OPTIONS " \\\n "] \
358364
<<<SHELL_OPTIONS>>> [join $SHELL_OPTIONS " \\\n "] \
365
+ <<<PIKCHR_OPTIONS>>> [join $PIKCHR_OPTIONS " \\\n "] \
359366
<<<NEXT_LINE>>> \\] {
360367
all: $(OBJDIR) $(APPNAME)
361368
362369
install: all
363370
mkdir -p $(INSTALLDIR)
@@ -414,10 +421,13 @@
414421
# Setup the options used to compile the included SQLite library.
415422
SQLITE_OPTIONS = <<<SQLITE_OPTIONS>>>
416423
417424
# Setup the options used to compile the included SQLite shell.
418425
SHELL_OPTIONS = <<<SHELL_OPTIONS>>>
426
+
427
+# Setup the options used to compile the included Pikchr formatter.
428
+PIKCHR_OPTIONS = <<<PIKCHR_OPTIONS>>>
419429
420430
# The USE_SYSTEM_SQLITE variable may be undefined, set to 0 or 1.
421431
# If it is set to 1, then there is no need to build or link
422432
# the sqlite3.o object. Instead, the system SQLite will be linked
423433
# using -lsqlite3.
@@ -544,11 +554,11 @@
544554
writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
545555
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$@\n"
546556
547557
writeln {
548558
$(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
549
- $(XTCC) -c $(SRCDIR_extsrc)/pikchr.c -o $@
559
+ $(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
550560
551561
$(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
552562
$(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
553563
554564
#
@@ -1247,14 +1257,16 @@
12471257
set MINGW_SQLITE_OPTIONS $SQLITE_WIN32_OPTIONS
12481258
lappend MINGW_SQLITE_OPTIONS {$(MINGW_OPTIONS)}
12491259
lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MALLOC_H
12501260
lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MSIZE
12511261
1262
+set MINGW_PIKCHR_OPTIONS $PIKCHR_OPTIONS
1263
+
12521264
set j " \\\n "
12531265
writeln "SQLITE_OPTIONS = [join $MINGW_SQLITE_OPTIONS $j]\n"
1254
-set j " \\\n "
12551266
writeln "SHELL_OPTIONS = [join $SHELL_WIN32_OPTIONS $j]\n"
1267
+writeln "PIKCHR_OPTIONS = [join $MINGW_PIKCHR_OPTIONS $j]\n"
12561268
12571269
writeln "\$(OBJDIR)/sqlite3.o:\t\$(SQLITE3_SRC) \$(SRCDIR)/../win/Makefile.mingw"
12581270
writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) \$(SEE_FLAGS) \\"
12591271
writeln "\t\t-c \$(SQLITE3_SRC) -o \$@\n"
12601272
@@ -1273,11 +1285,11 @@
12731285
12741286
writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
12751287
writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$@\n"
12761288
12771289
writeln "\$(OBJDIR)/pikchr.o:\t\$(SRCDIR_extsrc)/pikchr.c"
1278
-writeln "\t\$(XTCC) -c \$(SRCDIR_extsrc)/pikchr.c -o \$@\n"
1290
+writeln "\t\$(XTCC) \$(PIKCHR_OPTIONS) -c \$(SRCDIR_extsrc)/pikchr.c -o \$@\n"
12791291
12801292
close $output_file
12811293
#
12821294
# End of the win/Makefile.mingw output
12831295
##############################################################################
@@ -1319,10 +1331,11 @@
13191331
TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
13201332
LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
13211333
}
13221334
writeln "SQLITE_OPTIONS = [join $SQLITE_OPTIONS { }]\n"
13231335
writeln "SHELL_OPTIONS = [join $SHELL_WIN32_OPTIONS { }]\n"
1336
+writeln "PIKCHR_OPTIONS = [join $PIKCHR_OPTIONS { }]\n"
13241337
writeln -nonewline "SRC ="
13251338
foreach s [lsort $src] {
13261339
writeln -nonewline " ${s}_.c"
13271340
}
13281341
writeln "\n"
@@ -1436,10 +1449,13 @@
14361449
14371450
writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E "
14381451
foreach s [lsort $src] {
14391452
writeln -nonewline "${s}_.c:$s.h "
14401453
}
1454
+foreach s [lsort $src_ext] {
1455
+ writeln -nonewline "\$(SRCDIR_extsrc)\\${s}.c:$s.h "
1456
+}
14411457
writeln "\$(SRCDIR_extsrc)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR_extsrc)\\cson_amalgamation.h"
14421458
writeln "\t@copy /Y nul: headers"
14431459
14441460
close $output_file
14451461
#
@@ -1571,11 +1587,10 @@
15711587
!if $(FOSSIL_DYNAMIC_BUILD)!=0
15721588
SSLLIBDIR = $(SSLDIR)
15731589
!else
15741590
SSLLIBDIR = $(SSLDIR)
15751591
!endif
1576
-SSLLFLAGS = /nologo /opt:ref /debug
15771592
SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
15781593
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
15791594
!message Using 'x64' platform for OpenSSL...
15801595
SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
15811596
!if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -1628,11 +1643,11 @@
16281643
16291644
!if $(FOSSIL_ENABLE_TCL)!=0
16301645
INCL = $(INCL) /I"$(TCLINCDIR)"
16311646
!endif
16321647
1633
-CFLAGS = /nologo
1648
+CFLAGS = /nologo /W2 /WX /utf-8
16341649
LDFLAGS =
16351650
16361651
CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
16371652
CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
16381653
@@ -1643,16 +1658,27 @@
16431658
!endif
16441659
16451660
!if $(FOSSIL_ENABLE_WINXP)!=0
16461661
XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
16471662
CFLAGS = $(CFLAGS) $(XPCFLAGS)
1663
+#
1664
+# NOTE: For regular builds, /OSVERSION defaults to the /SUBSYSTEM version and
1665
+# explicit initialization is redundant, but is required for post-built edits.
1666
+#
16481667
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1649
-XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
1668
+XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.02 /SUBSYSTEM:CONSOLE,5.02
16501669
!else
1651
-XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
1670
+XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.01 /SUBSYSTEM:CONSOLE,5.01
16521671
!endif
16531672
LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
1673
+#
1674
+# NOTE: Only XPCFLAGS is forwarded to the OpenSSL configuration, and XPLDFLAGS
1675
+# is applied in a separate post-build step, see below for more information.
1676
+#
1677
+!if $(FOSSIL_ENABLE_SSL)!=0
1678
+SSLCONFIG = $(SSLCONFIG) $(XPCFLAGS)
1679
+!endif
16541680
!endif
16551681
16561682
!if $(FOSSIL_DYNAMIC_BUILD)!=0
16571683
!if $(DEBUG)!=0
16581684
CRTFLAGS = /MDd
@@ -1750,19 +1776,28 @@
17501776
17511777
regsub -all {[-]D} [join $SHELL_WIN32_OPTIONS { }] {/D} MSC_SHELL_OPTIONS
17521778
set j " \\\n "
17531779
writeln "SHELL_OPTIONS = [join $MSC_SHELL_OPTIONS $j]\n"
17541780
1781
+regsub -all {[-]D} [join $PIKCHR_OPTIONS { }] {/D} MSC_PIKCHR_OPTIONS
1782
+set j " \\\n "
1783
+writeln "PIKCHR_OPTIONS = [join $MSC_PIKCHR_OPTIONS $j]\n"
1784
+
17551785
writeln -nonewline "SRC = "
17561786
set i 0
17571787
foreach s [lsort $src] {
17581788
if {$i > 0} {
17591789
writeln " \\"
17601790
writeln -nonewline " "
17611791
}
17621792
writeln -nonewline "\"\$(OX)\\${s}_.c\""; incr i
17631793
}
1794
+foreach s [lsort $src_ext] {
1795
+ writeln " \\"
1796
+ writeln -nonewline " "
1797
+ writeln -nonewline "\"\$(SRCDIR_extsrc)\\${s}.c\""; incr i
1798
+}
17641799
writeln "\n"
17651800
writeln -nonewline "EXTRA_FILES = "
17661801
set i 0
17671802
foreach s [lsort $extra_files] {
17681803
if {$i > 0} {
@@ -1823,19 +1858,42 @@
18231858
@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
18241859
18251860
!if $(FOSSIL_ENABLE_SSL)!=0
18261861
openssl:
18271862
@echo Building OpenSSL from "$(SSLDIR)"...
1863
+!if $(FOSSIL_ENABLE_WINXP)!=0
1864
+ @echo Passing XPCFLAGS = [ $(XPCFLAGS) ] to the OpenSSL configuration...
1865
+!endif
18281866
!ifdef PERLDIR
18291867
@pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
18301868
!else
18311869
@pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
18321870
!endif
1833
-!if $(FOSSIL_ENABLE_WINXP)!=0
1834
- @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
1835
-!else
18361871
@pushd "$(SSLDIR)" && $(MAKE) && popd
1872
+!if $(FOSSIL_ENABLE_WINXP)!=0 && $(FOSSIL_DYNAMIC_BUILD)!=0
1873
+#
1874
+# NOTE: Appending custom linker flags to the OpenSSL default linker flags is
1875
+# somewhat difficult, as summarized in this Fossil Forum post:
1876
+#
1877
+# https://fossil-scm.org/forum/forumpost/a9a2d6af28b
1878
+#
1879
+# Therefore the custom linker flags required for Windows XP dynamic builds are
1880
+# applied in a separate post-build step.
1881
+#
1882
+# If the build stops here, or if the custom linker flags are outside the scope
1883
+# of `editbin` or `link /EDIT` (i.e. additional libraries), consider tweaking
1884
+# the OpenSSL makefile by hand.
1885
+#
1886
+# Also note that this step changes the subsystem for the OpenSSL DLLs from
1887
+# WINDOWS to CONSOLE, but which has no effect on DLLs.
1888
+#
1889
+ @echo Applying XPLDFLAGS = [ $(XPLDFLAGS) ] to the OpenSSL DLLs...
1890
+ @for /F "usebackq delims=" %F in (`dir /A:-D/B "$(SSLDIR)\*.dll" 2^>nul`) <<<NEXT_LINE>>>
1891
+ do @( <<<NEXT_LINE>>>
1892
+ echo %F & <<<NEXT_LINE>>>
1893
+ link /EDIT /NOLOGO $(XPLDFLAGS) "$(SSLDIR)\%F" || exit 1 <<<NEXT_LINE>>>
1894
+ )
18371895
!endif
18381896
18391897
clean-openssl:
18401898
@pushd "$(SSLDIR)" && $(MAKE) clean && popd
18411899
!endif
@@ -1907,11 +1965,11 @@
19071965
19081966
"$(OX)\th_tcl$O" : "$(SRCDIR)\th_tcl.c"
19091967
$(TCC) /Fo$@ /Fd$(@D)\ -c $**
19101968
19111969
"$(OX)\pikchr$O" : "$(SRCDIR_extsrc)\pikchr.c"
1912
- $(TCC) /Fo$@ /Fd$(@D)\ -c $**
1970
+ $(TCC) $(PIKCHR_OPTIONS) /Fo$@ /Fd$(@D)\ -c $**
19131971
19141972
"$(OX)\VERSION.h" : "$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" "$(B)\phony.h"
19151973
"$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" > $@
19161974
19171975
"$(B)\phony.h" :
@@ -2002,10 +2060,15 @@
20022060
writeln " \\"
20032061
writeln -nonewline "\t\t\t"
20042062
}
20052063
writeln -nonewline "\"\$(OX)\\${s}_.c\":\"\$(OX)\\$s.h\""; incr i
20062064
}
2065
+foreach s [lsort $src_ext] {
2066
+ writeln " \\"
2067
+ writeln -nonewline "\t\t\t"
2068
+ writeln -nonewline "\"\$(SRCDIR_extsrc)\\${s}.c\":\"\$(OX)\\$s.h\""; incr i
2069
+}
20072070
writeln " \\\n\t\t\t\"\$(SRCDIR_extsrc)\\sqlite3.h\" \\"
20082071
writeln "\t\t\t\"\$(SRCDIR)\\th.h\" \\"
20092072
writeln "\t\t\t\"\$(OX)\\VERSION.h\" \\"
20102073
writeln "\t\t\t\"\$(SRCDIR_extsrc)\\cson_amalgamation.h\""
20112074
writeln "\t@copy /Y nul: $@"
@@ -2014,210 +2077,5 @@
20142077
close $output_file
20152078
#
20162079
# End of the win/Makefile.msc output
20172080
##############################################################################
20182081
##############################################################################
2019
-##############################################################################
2020
-# Begin win/Makefile.PellesCGMake output
2021
-#
2022
-puts "building ../win/Makefile.PellesCGMake"
2023
-set output_file [open ../win/Makefile.PellesCGMake w]
2024
-fconfigure $output_file -translation binary
2025
-
2026
-writeln [string map [list \
2027
- <<<SQLITE_OPTIONS>>> [join $SQLITE_WIN32_OPTIONS { }] \
2028
- <<<SHELL_OPTIONS>>> [join $SHELL_WIN32_OPTIONS { }]] {#
2029
-##############################################################################
2030
-# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "tools/makemake.tcl")
2031
-##############################################################################
2032
-#
2033
-# This file is automatically generated. Instead of editing this
2034
-# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
2035
-# to regenerate this file.
2036
-#
2037
-# HowTo
2038
-# -----
2039
-#
2040
-# This is a Makefile to compile fossil with PellesC from
2041
-# http://www.smorgasbordet.com/pellesc/index.htm
2042
-# In addition to the Compiler envrionment, you need
2043
-# gmake from http://sourceforge.net/projects/unxutils/, Pelles make version
2044
-# couldn't handle the complex dependencies in this build
2045
-# zlib sources
2046
-# Then you do
2047
-# 1. create a directory PellesC in the project root directory
2048
-# 2. Change the variables PellesCDir/ZLIBSRCDIR to the path of your installation
2049
-# 3. open a dos prompt window and change working directory into PellesC (step 1)
2050
-# 4. run gmake -f ..\win\Makefile.PellesCGMake
2051
-#
2052
-# this file is tested with
2053
-# PellesC 5.00.13
2054
-# gmake 3.80
2055
-# zlib sources 1.2.5
2056
-# Windows XP SP 2
2057
-# and
2058
-# PellesC 6.00.4
2059
-# gmake 3.80
2060
-# zlib sources 1.2.5
2061
-# Windows 7 Home Premium
2062
-#
2063
-
2064
-#
2065
-PellesCDir=c:\Programme\PellesC
2066
-
2067
-# Select between 32/64 bit code, default is 32 bit
2068
-#TARGETVERSION=64
2069
-
2070
-ifeq ($(TARGETVERSION),64)
2071
-# 64 bit version
2072
-TARGETMACHINE_CC=amd64
2073
-TARGETMACHINE_LN=amd64
2074
-TARGETEXTEND=64
2075
-else
2076
-# 32 bit version
2077
-TARGETMACHINE_CC=x86
2078
-TARGETMACHINE_LN=ix86
2079
-TARGETEXTEND=
2080
-endif
2081
-
2082
-# define the project directories
2083
-B=..
2084
-SRCDIR=$(B)/src/
2085
-SRCDIR_extsrc=$(B)/extsrc/
2086
-SRCDIR_tools=$(B)/tools/
2087
-WINDIR=$(B)/win/
2088
-ZLIBSRCDIR=../../zlib/
2089
-
2090
-# define linker command and options
2091
-LINK=$(PellesCDir)/bin/polink.exe
2092
-LINKFLAGS=-subsystem:console -machine:$(TARGETMACHINE_LN) /LIBPATH:$(PellesCDir)\lib\win$(TARGETEXTEND) /LIBPATH:$(PellesCDir)\lib kernel32.lib advapi32.lib delayimp$(TARGETEXTEND).lib Wsock32.lib dnsapi.lib Crtmt$(TARGETEXTEND).lib
2093
-
2094
-# define standard C-compiler and flags, used to compile
2095
-# the fossil binary. Some special definitions follow for
2096
-# special files follow
2097
-CC=$(PellesCDir)\bin\pocc.exe
2098
-DEFINES=-D_pgmptr=g.argv[0]
2099
-CCFLAGS=-T$(TARGETMACHINE_CC)-coff -Ot -W2 -Gd -Go -Ze -MT $(DEFINES)
2100
-INCLUDE=/I $(PellesCDir)\Include\Win /I $(PellesCDir)\Include /I $(ZLIBSRCDIR) /I $(SRCDIR) /I $(SRCDIR_extsrc)
2101
-
2102
-# define commands for building the windows resource files
2103
-RESOURCE=fossil.res
2104
-RC=$(PellesCDir)\bin\porc.exe
2105
-RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
2106
-
2107
-# define the special utilities files, needed to generate
2108
-# the automatically generated source files
2109
-UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
2110
-UTILS_OBJ=$(UTILS:.exe=.obj)
2111
-UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR_tools)$(uf:.exe=.c))
2112
-
2113
-# define the SQLite files, which need special flags on compile
2114
-SQLITESRC=sqlite3.c
2115
-ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR_extsrc)$(sf))
2116
-SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
2117
-SQLITEDEFINES=<<<SQLITE_OPTIONS>>>
2118
-
2119
-# define the SQLite shell files, which need special flags on compile
2120
-SQLITESHELLSRC=shell.c
2121
-ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR_extsrc)$(sf))
2122
-SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
2123
-SQLITESHELLDEFINES=<<<SHELL_OPTIONS>>>
2124
-
2125
-# define the th scripting files, which need special flags on compile
2126
-THSRC=th.c th_lang.c
2127
-ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
2128
-THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
2129
-
2130
-# define the zlib files, needed by this compile
2131
-ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
2132
-ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
2133
-ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
2134
-
2135
-# define all fossil sources, using the standard compile and
2136
-# source generation. These are all files in SRCDIR, which are not
2137
-# mentioned as special files above:
2138
-ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC) $(ORIGSQLITESHELLSRC),$(wildcard $(SRCDIR)*.c))
2139
-SRC=$(subst $(SRCDIR),,$(ORIGSRC))
2140
-TRANSLATEDSRC=$(SRC:.c=_.c)
2141
-TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
2142
-
2143
-# main target file is the application
2144
-APPLICATION=fossil.exe
2145
-
2146
-# define the standard make target
2147
-.PHONY: default
2148
-default: page_index.h builtin_data.h headers $(APPLICATION)
2149
-
2150
-# symbolic target to generate the source generate utils
2151
-.PHONY: utils
2152
-utils: $(UTILS)
2153
-
2154
-# link utils
2155
-$(UTILS) version.exe: %.exe: %.obj
2156
- $(LINK) $(LINKFLAGS) -out:"$@" $<
2157
-
2158
-# compiling standard fossil utils
2159
-$(UTILS_OBJ): %.obj: $(SRCDIR)%.c
2160
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2161
-
2162
-# compile special windows utils
2163
-version.obj: $(SRCDIR_tools)mkversion.c
2164
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2165
-
2166
-# generate the translated c-source files
2167
-$(TRANSLATEDSRC): %_.c: $(SRCDIR)%.c translate.exe
2168
- translate.exe $< >$@
2169
-
2170
-# generate the index source, containing all web references,..
2171
-page_index.h: $(TRANSLATEDSRC) mkindex.exe
2172
- mkindex.exe $(TRANSLATEDSRC) >$@
2173
-
2174
-builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
2175
- mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@
2176
-
2177
-# extracting version info from manifest
2178
-VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
2179
- version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@
2180
-
2181
-# generate the simplified headers
2182
-headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/extsrc/sqlite3.h ../src/th.h
2183
- makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/extsrc/sqlite3.h ../src/th.h VERSION.h
2184
- echo Done >$@
2185
-
2186
-# compile C sources with relevant options
2187
-
2188
-$(TRANSLATEDOBJ): %_.obj: %_.c %.h
2189
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2190
-
2191
-$(SQLITEOBJ): %.obj: $(SRCDIR_extsrc)%.c $(SRCDIR_extsrc)%.h
2192
- $(CC) $(CCFLAGS) $(SQLITEDEFINES) $(INCLUDE) "$<" -Fo"$@"
2193
-
2194
-$(SQLITESHELLOBJ): %.obj: $(SRCDIR_extsrc)%.c
2195
- $(CC) $(CCFLAGS) $(SQLITESHELLDEFINES) $(INCLUDE) "$<" -Fo"$@"
2196
-
2197
-$(THOBJ): %.obj: $(SRCDIR)%.c $(SRCDIR)th.h
2198
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2199
-
2200
-$(ZLIBOBJ): %.obj: $(ZLIBSRCDIR)%.c
2201
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2202
-
2203
-# create the windows resource with icon and version info
2204
-$(RESOURCE): %.res: ../win/%.rc ../win/*.ico
2205
- $(RC) $(RCFLAGS) $< -Fo"$@"
2206
-
2207
-# link the application
2208
-$(APPLICATION): $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) headers $(RESOURCE)
2209
- $(LINK) $(LINKFLAGS) -out:"$@" $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) $(RESOURCE)
2210
-
2211
-# cleanup
2212
-
2213
-.PHONY: clean
2214
-clean:
2215
- -del /F $(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) $(UTILS_OBJ) version.obj
2216
- -del /F $(TRANSLATEDSRC)
2217
- -del /F *.h headers
2218
- -del /F $(RESOURCE)
2219
-
2220
-.PHONY: clobber
2221
-clobber: clean
2222
- -del /F *.exe
2223
-}]
22242082
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -249,10 +249,16 @@
249 }
250 #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1
251 #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_STAT4
252 #lappend SQLITE_OPTIONS -DSQLITE_WIN32_NO_ANSI
253 #lappend SQLITE_OPTIONS -DSQLITE_WINNT_MAX_PATH_CHARS=4096
 
 
 
 
 
 
254
255 # Options used to compile the included SQLite shell.
256 #
257 set SHELL_OPTIONS [concat $SQLITE_OPTIONS {
258 -Dmain=sqlite3_shell
@@ -354,10 +360,11 @@
354 }
355
356 writeln [string map [list \
357 <<<SQLITE_OPTIONS>>> [join $SQLITE_OPTIONS " \\\n "] \
358 <<<SHELL_OPTIONS>>> [join $SHELL_OPTIONS " \\\n "] \
 
359 <<<NEXT_LINE>>> \\] {
360 all: $(OBJDIR) $(APPNAME)
361
362 install: all
363 mkdir -p $(INSTALLDIR)
@@ -414,10 +421,13 @@
414 # Setup the options used to compile the included SQLite library.
415 SQLITE_OPTIONS = <<<SQLITE_OPTIONS>>>
416
417 # Setup the options used to compile the included SQLite shell.
418 SHELL_OPTIONS = <<<SHELL_OPTIONS>>>
 
 
 
419
420 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0 or 1.
421 # If it is set to 1, then there is no need to build or link
422 # the sqlite3.o object. Instead, the system SQLite will be linked
423 # using -lsqlite3.
@@ -544,11 +554,11 @@
544 writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
545 writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$@\n"
546
547 writeln {
548 $(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
549 $(XTCC) -c $(SRCDIR_extsrc)/pikchr.c -o $@
550
551 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
552 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
553
554 #
@@ -1247,14 +1257,16 @@
1247 set MINGW_SQLITE_OPTIONS $SQLITE_WIN32_OPTIONS
1248 lappend MINGW_SQLITE_OPTIONS {$(MINGW_OPTIONS)}
1249 lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MALLOC_H
1250 lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MSIZE
1251
 
 
1252 set j " \\\n "
1253 writeln "SQLITE_OPTIONS = [join $MINGW_SQLITE_OPTIONS $j]\n"
1254 set j " \\\n "
1255 writeln "SHELL_OPTIONS = [join $SHELL_WIN32_OPTIONS $j]\n"
 
1256
1257 writeln "\$(OBJDIR)/sqlite3.o:\t\$(SQLITE3_SRC) \$(SRCDIR)/../win/Makefile.mingw"
1258 writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) \$(SEE_FLAGS) \\"
1259 writeln "\t\t-c \$(SQLITE3_SRC) -o \$@\n"
1260
@@ -1273,11 +1285,11 @@
1273
1274 writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
1275 writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$@\n"
1276
1277 writeln "\$(OBJDIR)/pikchr.o:\t\$(SRCDIR_extsrc)/pikchr.c"
1278 writeln "\t\$(XTCC) -c \$(SRCDIR_extsrc)/pikchr.c -o \$@\n"
1279
1280 close $output_file
1281 #
1282 # End of the win/Makefile.mingw output
1283 ##############################################################################
@@ -1319,10 +1331,11 @@
1319 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
1320 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
1321 }
1322 writeln "SQLITE_OPTIONS = [join $SQLITE_OPTIONS { }]\n"
1323 writeln "SHELL_OPTIONS = [join $SHELL_WIN32_OPTIONS { }]\n"
 
1324 writeln -nonewline "SRC ="
1325 foreach s [lsort $src] {
1326 writeln -nonewline " ${s}_.c"
1327 }
1328 writeln "\n"
@@ -1436,10 +1449,13 @@
1436
1437 writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E "
1438 foreach s [lsort $src] {
1439 writeln -nonewline "${s}_.c:$s.h "
1440 }
 
 
 
1441 writeln "\$(SRCDIR_extsrc)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR_extsrc)\\cson_amalgamation.h"
1442 writeln "\t@copy /Y nul: headers"
1443
1444 close $output_file
1445 #
@@ -1571,11 +1587,10 @@
1571 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1572 SSLLIBDIR = $(SSLDIR)
1573 !else
1574 SSLLIBDIR = $(SSLDIR)
1575 !endif
1576 SSLLFLAGS = /nologo /opt:ref /debug
1577 SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
1578 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1579 !message Using 'x64' platform for OpenSSL...
1580 SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
1581 !if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -1628,11 +1643,11 @@
1628
1629 !if $(FOSSIL_ENABLE_TCL)!=0
1630 INCL = $(INCL) /I"$(TCLINCDIR)"
1631 !endif
1632
1633 CFLAGS = /nologo
1634 LDFLAGS =
1635
1636 CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
1637 CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
1638
@@ -1643,16 +1658,27 @@
1643 !endif
1644
1645 !if $(FOSSIL_ENABLE_WINXP)!=0
1646 XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
1647 CFLAGS = $(CFLAGS) $(XPCFLAGS)
 
 
 
 
1648 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1649 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
1650 !else
1651 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
1652 !endif
1653 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
 
 
 
 
 
 
 
1654 !endif
1655
1656 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1657 !if $(DEBUG)!=0
1658 CRTFLAGS = /MDd
@@ -1750,19 +1776,28 @@
1750
1751 regsub -all {[-]D} [join $SHELL_WIN32_OPTIONS { }] {/D} MSC_SHELL_OPTIONS
1752 set j " \\\n "
1753 writeln "SHELL_OPTIONS = [join $MSC_SHELL_OPTIONS $j]\n"
1754
 
 
 
 
1755 writeln -nonewline "SRC = "
1756 set i 0
1757 foreach s [lsort $src] {
1758 if {$i > 0} {
1759 writeln " \\"
1760 writeln -nonewline " "
1761 }
1762 writeln -nonewline "\"\$(OX)\\${s}_.c\""; incr i
1763 }
 
 
 
 
 
1764 writeln "\n"
1765 writeln -nonewline "EXTRA_FILES = "
1766 set i 0
1767 foreach s [lsort $extra_files] {
1768 if {$i > 0} {
@@ -1823,19 +1858,42 @@
1823 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
1824
1825 !if $(FOSSIL_ENABLE_SSL)!=0
1826 openssl:
1827 @echo Building OpenSSL from "$(SSLDIR)"...
 
 
 
1828 !ifdef PERLDIR
1829 @pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
1830 !else
1831 @pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
1832 !endif
1833 !if $(FOSSIL_ENABLE_WINXP)!=0
1834 @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
1835 !else
1836 @pushd "$(SSLDIR)" && $(MAKE) && popd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1837 !endif
1838
1839 clean-openssl:
1840 @pushd "$(SSLDIR)" && $(MAKE) clean && popd
1841 !endif
@@ -1907,11 +1965,11 @@
1907
1908 "$(OX)\th_tcl$O" : "$(SRCDIR)\th_tcl.c"
1909 $(TCC) /Fo$@ /Fd$(@D)\ -c $**
1910
1911 "$(OX)\pikchr$O" : "$(SRCDIR_extsrc)\pikchr.c"
1912 $(TCC) /Fo$@ /Fd$(@D)\ -c $**
1913
1914 "$(OX)\VERSION.h" : "$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" "$(B)\phony.h"
1915 "$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" > $@
1916
1917 "$(B)\phony.h" :
@@ -2002,10 +2060,15 @@
2002 writeln " \\"
2003 writeln -nonewline "\t\t\t"
2004 }
2005 writeln -nonewline "\"\$(OX)\\${s}_.c\":\"\$(OX)\\$s.h\""; incr i
2006 }
 
 
 
 
 
2007 writeln " \\\n\t\t\t\"\$(SRCDIR_extsrc)\\sqlite3.h\" \\"
2008 writeln "\t\t\t\"\$(SRCDIR)\\th.h\" \\"
2009 writeln "\t\t\t\"\$(OX)\\VERSION.h\" \\"
2010 writeln "\t\t\t\"\$(SRCDIR_extsrc)\\cson_amalgamation.h\""
2011 writeln "\t@copy /Y nul: $@"
@@ -2014,210 +2077,5 @@
2014 close $output_file
2015 #
2016 # End of the win/Makefile.msc output
2017 ##############################################################################
2018 ##############################################################################
2019 ##############################################################################
2020 # Begin win/Makefile.PellesCGMake output
2021 #
2022 puts "building ../win/Makefile.PellesCGMake"
2023 set output_file [open ../win/Makefile.PellesCGMake w]
2024 fconfigure $output_file -translation binary
2025
2026 writeln [string map [list \
2027 <<<SQLITE_OPTIONS>>> [join $SQLITE_WIN32_OPTIONS { }] \
2028 <<<SHELL_OPTIONS>>> [join $SHELL_WIN32_OPTIONS { }]] {#
2029 ##############################################################################
2030 # WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "tools/makemake.tcl")
2031 ##############################################################################
2032 #
2033 # This file is automatically generated. Instead of editing this
2034 # file, edit "makemake.tcl" then run "tclsh makemake.tcl"
2035 # to regenerate this file.
2036 #
2037 # HowTo
2038 # -----
2039 #
2040 # This is a Makefile to compile fossil with PellesC from
2041 # http://www.smorgasbordet.com/pellesc/index.htm
2042 # In addition to the Compiler envrionment, you need
2043 # gmake from http://sourceforge.net/projects/unxutils/, Pelles make version
2044 # couldn't handle the complex dependencies in this build
2045 # zlib sources
2046 # Then you do
2047 # 1. create a directory PellesC in the project root directory
2048 # 2. Change the variables PellesCDir/ZLIBSRCDIR to the path of your installation
2049 # 3. open a dos prompt window and change working directory into PellesC (step 1)
2050 # 4. run gmake -f ..\win\Makefile.PellesCGMake
2051 #
2052 # this file is tested with
2053 # PellesC 5.00.13
2054 # gmake 3.80
2055 # zlib sources 1.2.5
2056 # Windows XP SP 2
2057 # and
2058 # PellesC 6.00.4
2059 # gmake 3.80
2060 # zlib sources 1.2.5
2061 # Windows 7 Home Premium
2062 #
2063
2064 #
2065 PellesCDir=c:\Programme\PellesC
2066
2067 # Select between 32/64 bit code, default is 32 bit
2068 #TARGETVERSION=64
2069
2070 ifeq ($(TARGETVERSION),64)
2071 # 64 bit version
2072 TARGETMACHINE_CC=amd64
2073 TARGETMACHINE_LN=amd64
2074 TARGETEXTEND=64
2075 else
2076 # 32 bit version
2077 TARGETMACHINE_CC=x86
2078 TARGETMACHINE_LN=ix86
2079 TARGETEXTEND=
2080 endif
2081
2082 # define the project directories
2083 B=..
2084 SRCDIR=$(B)/src/
2085 SRCDIR_extsrc=$(B)/extsrc/
2086 SRCDIR_tools=$(B)/tools/
2087 WINDIR=$(B)/win/
2088 ZLIBSRCDIR=../../zlib/
2089
2090 # define linker command and options
2091 LINK=$(PellesCDir)/bin/polink.exe
2092 LINKFLAGS=-subsystem:console -machine:$(TARGETMACHINE_LN) /LIBPATH:$(PellesCDir)\lib\win$(TARGETEXTEND) /LIBPATH:$(PellesCDir)\lib kernel32.lib advapi32.lib delayimp$(TARGETEXTEND).lib Wsock32.lib dnsapi.lib Crtmt$(TARGETEXTEND).lib
2093
2094 # define standard C-compiler and flags, used to compile
2095 # the fossil binary. Some special definitions follow for
2096 # special files follow
2097 CC=$(PellesCDir)\bin\pocc.exe
2098 DEFINES=-D_pgmptr=g.argv[0]
2099 CCFLAGS=-T$(TARGETMACHINE_CC)-coff -Ot -W2 -Gd -Go -Ze -MT $(DEFINES)
2100 INCLUDE=/I $(PellesCDir)\Include\Win /I $(PellesCDir)\Include /I $(ZLIBSRCDIR) /I $(SRCDIR) /I $(SRCDIR_extsrc)
2101
2102 # define commands for building the windows resource files
2103 RESOURCE=fossil.res
2104 RC=$(PellesCDir)\bin\porc.exe
2105 RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
2106
2107 # define the special utilities files, needed to generate
2108 # the automatically generated source files
2109 UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
2110 UTILS_OBJ=$(UTILS:.exe=.obj)
2111 UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR_tools)$(uf:.exe=.c))
2112
2113 # define the SQLite files, which need special flags on compile
2114 SQLITESRC=sqlite3.c
2115 ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR_extsrc)$(sf))
2116 SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
2117 SQLITEDEFINES=<<<SQLITE_OPTIONS>>>
2118
2119 # define the SQLite shell files, which need special flags on compile
2120 SQLITESHELLSRC=shell.c
2121 ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR_extsrc)$(sf))
2122 SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
2123 SQLITESHELLDEFINES=<<<SHELL_OPTIONS>>>
2124
2125 # define the th scripting files, which need special flags on compile
2126 THSRC=th.c th_lang.c
2127 ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
2128 THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
2129
2130 # define the zlib files, needed by this compile
2131 ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
2132 ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
2133 ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
2134
2135 # define all fossil sources, using the standard compile and
2136 # source generation. These are all files in SRCDIR, which are not
2137 # mentioned as special files above:
2138 ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC) $(ORIGSQLITESHELLSRC),$(wildcard $(SRCDIR)*.c))
2139 SRC=$(subst $(SRCDIR),,$(ORIGSRC))
2140 TRANSLATEDSRC=$(SRC:.c=_.c)
2141 TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
2142
2143 # main target file is the application
2144 APPLICATION=fossil.exe
2145
2146 # define the standard make target
2147 .PHONY: default
2148 default: page_index.h builtin_data.h headers $(APPLICATION)
2149
2150 # symbolic target to generate the source generate utils
2151 .PHONY: utils
2152 utils: $(UTILS)
2153
2154 # link utils
2155 $(UTILS) version.exe: %.exe: %.obj
2156 $(LINK) $(LINKFLAGS) -out:"$@" $<
2157
2158 # compiling standard fossil utils
2159 $(UTILS_OBJ): %.obj: $(SRCDIR)%.c
2160 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2161
2162 # compile special windows utils
2163 version.obj: $(SRCDIR_tools)mkversion.c
2164 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2165
2166 # generate the translated c-source files
2167 $(TRANSLATEDSRC): %_.c: $(SRCDIR)%.c translate.exe
2168 translate.exe $< >$@
2169
2170 # generate the index source, containing all web references,..
2171 page_index.h: $(TRANSLATEDSRC) mkindex.exe
2172 mkindex.exe $(TRANSLATEDSRC) >$@
2173
2174 builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
2175 mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@
2176
2177 # extracting version info from manifest
2178 VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
2179 version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@
2180
2181 # generate the simplified headers
2182 headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/extsrc/sqlite3.h ../src/th.h
2183 makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/extsrc/sqlite3.h ../src/th.h VERSION.h
2184 echo Done >$@
2185
2186 # compile C sources with relevant options
2187
2188 $(TRANSLATEDOBJ): %_.obj: %_.c %.h
2189 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2190
2191 $(SQLITEOBJ): %.obj: $(SRCDIR_extsrc)%.c $(SRCDIR_extsrc)%.h
2192 $(CC) $(CCFLAGS) $(SQLITEDEFINES) $(INCLUDE) "$<" -Fo"$@"
2193
2194 $(SQLITESHELLOBJ): %.obj: $(SRCDIR_extsrc)%.c
2195 $(CC) $(CCFLAGS) $(SQLITESHELLDEFINES) $(INCLUDE) "$<" -Fo"$@"
2196
2197 $(THOBJ): %.obj: $(SRCDIR)%.c $(SRCDIR)th.h
2198 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2199
2200 $(ZLIBOBJ): %.obj: $(ZLIBSRCDIR)%.c
2201 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
2202
2203 # create the windows resource with icon and version info
2204 $(RESOURCE): %.res: ../win/%.rc ../win/*.ico
2205 $(RC) $(RCFLAGS) $< -Fo"$@"
2206
2207 # link the application
2208 $(APPLICATION): $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) headers $(RESOURCE)
2209 $(LINK) $(LINKFLAGS) -out:"$@" $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) $(RESOURCE)
2210
2211 # cleanup
2212
2213 .PHONY: clean
2214 clean:
2215 -del /F $(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) $(UTILS_OBJ) version.obj
2216 -del /F $(TRANSLATEDSRC)
2217 -del /F *.h headers
2218 -del /F $(RESOURCE)
2219
2220 .PHONY: clobber
2221 clobber: clean
2222 -del /F *.exe
2223 }]
2224
--- tools/makemake.tcl
+++ tools/makemake.tcl
@@ -249,10 +249,16 @@
249 }
250 #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1
251 #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_STAT4
252 #lappend SQLITE_OPTIONS -DSQLITE_WIN32_NO_ANSI
253 #lappend SQLITE_OPTIONS -DSQLITE_WINNT_MAX_PATH_CHARS=4096
254
255 # Options used to compile the Pikchr library.
256 #
257 set PIKCHR_OPTIONS {
258 -DPIKCHR_TOKEN_LIMIT=10000
259 }
260
261 # Options used to compile the included SQLite shell.
262 #
263 set SHELL_OPTIONS [concat $SQLITE_OPTIONS {
264 -Dmain=sqlite3_shell
@@ -354,10 +360,11 @@
360 }
361
362 writeln [string map [list \
363 <<<SQLITE_OPTIONS>>> [join $SQLITE_OPTIONS " \\\n "] \
364 <<<SHELL_OPTIONS>>> [join $SHELL_OPTIONS " \\\n "] \
365 <<<PIKCHR_OPTIONS>>> [join $PIKCHR_OPTIONS " \\\n "] \
366 <<<NEXT_LINE>>> \\] {
367 all: $(OBJDIR) $(APPNAME)
368
369 install: all
370 mkdir -p $(INSTALLDIR)
@@ -414,10 +421,13 @@
421 # Setup the options used to compile the included SQLite library.
422 SQLITE_OPTIONS = <<<SQLITE_OPTIONS>>>
423
424 # Setup the options used to compile the included SQLite shell.
425 SHELL_OPTIONS = <<<SHELL_OPTIONS>>>
426
427 # Setup the options used to compile the included Pikchr formatter.
428 PIKCHR_OPTIONS = <<<PIKCHR_OPTIONS>>>
429
430 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0 or 1.
431 # If it is set to 1, then there is no need to build or link
432 # the sqlite3.o object. Instead, the system SQLite will be linked
433 # using -lsqlite3.
@@ -544,11 +554,11 @@
554 writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
555 writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$@\n"
556
557 writeln {
558 $(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
559 $(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
560
561 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
562 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
563
564 #
@@ -1247,14 +1257,16 @@
1257 set MINGW_SQLITE_OPTIONS $SQLITE_WIN32_OPTIONS
1258 lappend MINGW_SQLITE_OPTIONS {$(MINGW_OPTIONS)}
1259 lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MALLOC_H
1260 lappend MINGW_SQLITE_OPTIONS -DSQLITE_USE_MSIZE
1261
1262 set MINGW_PIKCHR_OPTIONS $PIKCHR_OPTIONS
1263
1264 set j " \\\n "
1265 writeln "SQLITE_OPTIONS = [join $MINGW_SQLITE_OPTIONS $j]\n"
 
1266 writeln "SHELL_OPTIONS = [join $SHELL_WIN32_OPTIONS $j]\n"
1267 writeln "PIKCHR_OPTIONS = [join $MINGW_PIKCHR_OPTIONS $j]\n"
1268
1269 writeln "\$(OBJDIR)/sqlite3.o:\t\$(SQLITE3_SRC) \$(SRCDIR)/../win/Makefile.mingw"
1270 writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) \$(SEE_FLAGS) \\"
1271 writeln "\t\t-c \$(SQLITE3_SRC) -o \$@\n"
1272
@@ -1273,11 +1285,11 @@
1285
1286 writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
1287 writeln "\t\$(XTCC) -c \$(SRCDIR)/th_tcl.c -o \$@\n"
1288
1289 writeln "\$(OBJDIR)/pikchr.o:\t\$(SRCDIR_extsrc)/pikchr.c"
1290 writeln "\t\$(XTCC) \$(PIKCHR_OPTIONS) -c \$(SRCDIR_extsrc)/pikchr.c -o \$@\n"
1291
1292 close $output_file
1293 #
1294 # End of the win/Makefile.mingw output
1295 ##############################################################################
@@ -1319,10 +1331,11 @@
1331 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
1332 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
1333 }
1334 writeln "SQLITE_OPTIONS = [join $SQLITE_OPTIONS { }]\n"
1335 writeln "SHELL_OPTIONS = [join $SHELL_WIN32_OPTIONS { }]\n"
1336 writeln "PIKCHR_OPTIONS = [join $PIKCHR_OPTIONS { }]\n"
1337 writeln -nonewline "SRC ="
1338 foreach s [lsort $src] {
1339 writeln -nonewline " ${s}_.c"
1340 }
1341 writeln "\n"
@@ -1436,10 +1449,13 @@
1449
1450 writeln -nonewline "headers: makeheaders\$E page_index.h builtin_data.h VERSION.h\n\t +makeheaders\$E "
1451 foreach s [lsort $src] {
1452 writeln -nonewline "${s}_.c:$s.h "
1453 }
1454 foreach s [lsort $src_ext] {
1455 writeln -nonewline "\$(SRCDIR_extsrc)\\${s}.c:$s.h "
1456 }
1457 writeln "\$(SRCDIR_extsrc)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR_extsrc)\\cson_amalgamation.h"
1458 writeln "\t@copy /Y nul: headers"
1459
1460 close $output_file
1461 #
@@ -1571,11 +1587,10 @@
1587 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1588 SSLLIBDIR = $(SSLDIR)
1589 !else
1590 SSLLIBDIR = $(SSLDIR)
1591 !endif
 
1592 SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
1593 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1594 !message Using 'x64' platform for OpenSSL...
1595 SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
1596 !if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -1628,11 +1643,11 @@
1643
1644 !if $(FOSSIL_ENABLE_TCL)!=0
1645 INCL = $(INCL) /I"$(TCLINCDIR)"
1646 !endif
1647
1648 CFLAGS = /nologo /W2 /WX /utf-8
1649 LDFLAGS =
1650
1651 CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
1652 CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
1653
@@ -1643,16 +1658,27 @@
1658 !endif
1659
1660 !if $(FOSSIL_ENABLE_WINXP)!=0
1661 XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
1662 CFLAGS = $(CFLAGS) $(XPCFLAGS)
1663 #
1664 # NOTE: For regular builds, /OSVERSION defaults to the /SUBSYSTEM version and
1665 # explicit initialization is redundant, but is required for post-built edits.
1666 #
1667 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1668 XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.02 /SUBSYSTEM:CONSOLE,5.02
1669 !else
1670 XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.01 /SUBSYSTEM:CONSOLE,5.01
1671 !endif
1672 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
1673 #
1674 # NOTE: Only XPCFLAGS is forwarded to the OpenSSL configuration, and XPLDFLAGS
1675 # is applied in a separate post-build step, see below for more information.
1676 #
1677 !if $(FOSSIL_ENABLE_SSL)!=0
1678 SSLCONFIG = $(SSLCONFIG) $(XPCFLAGS)
1679 !endif
1680 !endif
1681
1682 !if $(FOSSIL_DYNAMIC_BUILD)!=0
1683 !if $(DEBUG)!=0
1684 CRTFLAGS = /MDd
@@ -1750,19 +1776,28 @@
1776
1777 regsub -all {[-]D} [join $SHELL_WIN32_OPTIONS { }] {/D} MSC_SHELL_OPTIONS
1778 set j " \\\n "
1779 writeln "SHELL_OPTIONS = [join $MSC_SHELL_OPTIONS $j]\n"
1780
1781 regsub -all {[-]D} [join $PIKCHR_OPTIONS { }] {/D} MSC_PIKCHR_OPTIONS
1782 set j " \\\n "
1783 writeln "PIKCHR_OPTIONS = [join $MSC_PIKCHR_OPTIONS $j]\n"
1784
1785 writeln -nonewline "SRC = "
1786 set i 0
1787 foreach s [lsort $src] {
1788 if {$i > 0} {
1789 writeln " \\"
1790 writeln -nonewline " "
1791 }
1792 writeln -nonewline "\"\$(OX)\\${s}_.c\""; incr i
1793 }
1794 foreach s [lsort $src_ext] {
1795 writeln " \\"
1796 writeln -nonewline " "
1797 writeln -nonewline "\"\$(SRCDIR_extsrc)\\${s}.c\""; incr i
1798 }
1799 writeln "\n"
1800 writeln -nonewline "EXTRA_FILES = "
1801 set i 0
1802 foreach s [lsort $extra_files] {
1803 if {$i > 0} {
@@ -1823,19 +1858,42 @@
1858 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
1859
1860 !if $(FOSSIL_ENABLE_SSL)!=0
1861 openssl:
1862 @echo Building OpenSSL from "$(SSLDIR)"...
1863 !if $(FOSSIL_ENABLE_WINXP)!=0
1864 @echo Passing XPCFLAGS = [ $(XPCFLAGS) ] to the OpenSSL configuration...
1865 !endif
1866 !ifdef PERLDIR
1867 @pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
1868 !else
1869 @pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
1870 !endif
 
 
 
1871 @pushd "$(SSLDIR)" && $(MAKE) && popd
1872 !if $(FOSSIL_ENABLE_WINXP)!=0 && $(FOSSIL_DYNAMIC_BUILD)!=0
1873 #
1874 # NOTE: Appending custom linker flags to the OpenSSL default linker flags is
1875 # somewhat difficult, as summarized in this Fossil Forum post:
1876 #
1877 # https://fossil-scm.org/forum/forumpost/a9a2d6af28b
1878 #
1879 # Therefore the custom linker flags required for Windows XP dynamic builds are
1880 # applied in a separate post-build step.
1881 #
1882 # If the build stops here, or if the custom linker flags are outside the scope
1883 # of `editbin` or `link /EDIT` (i.e. additional libraries), consider tweaking
1884 # the OpenSSL makefile by hand.
1885 #
1886 # Also note that this step changes the subsystem for the OpenSSL DLLs from
1887 # WINDOWS to CONSOLE, but which has no effect on DLLs.
1888 #
1889 @echo Applying XPLDFLAGS = [ $(XPLDFLAGS) ] to the OpenSSL DLLs...
1890 @for /F "usebackq delims=" %F in (`dir /A:-D/B "$(SSLDIR)\*.dll" 2^>nul`) <<<NEXT_LINE>>>
1891 do @( <<<NEXT_LINE>>>
1892 echo %F & <<<NEXT_LINE>>>
1893 link /EDIT /NOLOGO $(XPLDFLAGS) "$(SSLDIR)\%F" || exit 1 <<<NEXT_LINE>>>
1894 )
1895 !endif
1896
1897 clean-openssl:
1898 @pushd "$(SSLDIR)" && $(MAKE) clean && popd
1899 !endif
@@ -1907,11 +1965,11 @@
1965
1966 "$(OX)\th_tcl$O" : "$(SRCDIR)\th_tcl.c"
1967 $(TCC) /Fo$@ /Fd$(@D)\ -c $**
1968
1969 "$(OX)\pikchr$O" : "$(SRCDIR_extsrc)\pikchr.c"
1970 $(TCC) $(PIKCHR_OPTIONS) /Fo$@ /Fd$(@D)\ -c $**
1971
1972 "$(OX)\VERSION.h" : "$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" "$(B)\phony.h"
1973 "$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" > $@
1974
1975 "$(B)\phony.h" :
@@ -2002,10 +2060,15 @@
2060 writeln " \\"
2061 writeln -nonewline "\t\t\t"
2062 }
2063 writeln -nonewline "\"\$(OX)\\${s}_.c\":\"\$(OX)\\$s.h\""; incr i
2064 }
2065 foreach s [lsort $src_ext] {
2066 writeln " \\"
2067 writeln -nonewline "\t\t\t"
2068 writeln -nonewline "\"\$(SRCDIR_extsrc)\\${s}.c\":\"\$(OX)\\$s.h\""; incr i
2069 }
2070 writeln " \\\n\t\t\t\"\$(SRCDIR_extsrc)\\sqlite3.h\" \\"
2071 writeln "\t\t\t\"\$(SRCDIR)\\th.h\" \\"
2072 writeln "\t\t\t\"\$(OX)\\VERSION.h\" \\"
2073 writeln "\t\t\t\"\$(SRCDIR_extsrc)\\cson_amalgamation.h\""
2074 writeln "\t@copy /Y nul: $@"
@@ -2014,210 +2077,5 @@
2077 close $output_file
2078 #
2079 # End of the win/Makefile.msc output
2080 ##############################################################################
2081 ##############################################################################
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2082
+15 -12
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -80,22 +80,23 @@
8080
8181
/***************************************************************************
8282
** These macros must match similar macros in dispatch.c.
8383
**
8484
** Allowed values for CmdOrPage.eCmdFlags. */
85
-#define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
86
-#define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
87
-#define CMDFLAG_TEST 0x0004 /* Commands for testing only */
88
-#define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
89
-#define CMDFLAG_COMMAND 0x0010 /* A command */
90
-#define CMDFLAG_SETTING 0x0020 /* A setting */
91
-#define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
92
-#define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
93
-#define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
94
-#define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret webpage content */
95
-#define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
96
-#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
85
+#define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
86
+#define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
87
+#define CMDFLAG_TEST 0x0004 /* Commands for testing only */
88
+#define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
89
+#define CMDFLAG_COMMAND 0x0010 /* A command */
90
+#define CMDFLAG_SETTING 0x0020 /* A setting */
91
+#define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
92
+#define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
93
+#define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
94
+#define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret webpage content */
95
+#define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
96
+#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
97
+#define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
9798
/**************************************************************************/
9899
99100
/*
100101
** Each entry looks like this:
101102
*/
@@ -260,10 +261,12 @@
260261
aEntry[nUsed].zDflt = string_dup(&zLine[i+8], j-8);
261262
}else if( j>9 && strncmp(&zLine[i], "variable=", 9)==0 ){
262263
aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
263264
}else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
264265
aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
266
+ }else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){
267
+ aEntry[nUsed].eType |= CMDFLAG_LDAVG_EXEMPT;
265268
}else{
266269
fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
267270
zFile, nLine, j, &zLine[i]);
268271
nErr++;
269272
}
270273
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -80,22 +80,23 @@
80
81 /***************************************************************************
82 ** These macros must match similar macros in dispatch.c.
83 **
84 ** Allowed values for CmdOrPage.eCmdFlags. */
85 #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
86 #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
87 #define CMDFLAG_TEST 0x0004 /* Commands for testing only */
88 #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
89 #define CMDFLAG_COMMAND 0x0010 /* A command */
90 #define CMDFLAG_SETTING 0x0020 /* A setting */
91 #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
92 #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
93 #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
94 #define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret webpage content */
95 #define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
96 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
 
97 /**************************************************************************/
98
99 /*
100 ** Each entry looks like this:
101 */
@@ -260,10 +261,12 @@
260 aEntry[nUsed].zDflt = string_dup(&zLine[i+8], j-8);
261 }else if( j>9 && strncmp(&zLine[i], "variable=", 9)==0 ){
262 aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
263 }else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
264 aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
 
 
265 }else{
266 fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
267 zFile, nLine, j, &zLine[i]);
268 nErr++;
269 }
270
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -80,22 +80,23 @@
80
81 /***************************************************************************
82 ** These macros must match similar macros in dispatch.c.
83 **
84 ** Allowed values for CmdOrPage.eCmdFlags. */
85 #define CMDFLAG_1ST_TIER 0x0001 /* Most important commands */
86 #define CMDFLAG_2ND_TIER 0x0002 /* Obscure and seldom used commands */
87 #define CMDFLAG_TEST 0x0004 /* Commands for testing only */
88 #define CMDFLAG_WEBPAGE 0x0008 /* Web pages */
89 #define CMDFLAG_COMMAND 0x0010 /* A command */
90 #define CMDFLAG_SETTING 0x0020 /* A setting */
91 #define CMDFLAG_VERSIONABLE 0x0040 /* A versionable setting */
92 #define CMDFLAG_BLOCKTEXT 0x0080 /* Multi-line text setting */
93 #define CMDFLAG_BOOLEAN 0x0100 /* A boolean setting */
94 #define CMDFLAG_RAWCONTENT 0x0200 /* Do not interpret webpage content */
95 #define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
96 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
97 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
98 /**************************************************************************/
99
100 /*
101 ** Each entry looks like this:
102 */
@@ -260,10 +261,12 @@
261 aEntry[nUsed].zDflt = string_dup(&zLine[i+8], j-8);
262 }else if( j>9 && strncmp(&zLine[i], "variable=", 9)==0 ){
263 aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
264 }else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
265 aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
266 }else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){
267 aEntry[nUsed].eType |= CMDFLAG_LDAVG_EXEMPT;
268 }else{
269 fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
270 zFile, nLine, j, &zLine[i]);
271 nErr++;
272 }
273
--- tools/mkversion.c
+++ tools/mkversion.c
@@ -200,11 +200,13 @@
200200
#elif defined(__POCC__) /* e.g. 700 */
201201
d = (__POCC__ / 100); /* major */
202202
x = (__POCC__ % 100); /* minor */
203203
printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
204204
#elif defined(_MSC_VER) /* e.g. 1800 */
205
+ /* _MSC_FULL_VER also defined, e.g. 193030709 */
205206
d = (_MSC_VER / 100); /* major */
206207
x = (_MSC_VER % 100); /* minor */
207
- printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
208
+ printf("#define COMPILER_VERSION \"%d.%02d.", d, x);
209
+ printf("%05d\"\n",(int)(_MSC_FULL_VER % 100000)); /* build (patch) */
208210
#endif
209211
return 0;
210212
}
211213
--- tools/mkversion.c
+++ tools/mkversion.c
@@ -200,11 +200,13 @@
200 #elif defined(__POCC__) /* e.g. 700 */
201 d = (__POCC__ / 100); /* major */
202 x = (__POCC__ % 100); /* minor */
203 printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
204 #elif defined(_MSC_VER) /* e.g. 1800 */
 
205 d = (_MSC_VER / 100); /* major */
206 x = (_MSC_VER % 100); /* minor */
207 printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
 
208 #endif
209 return 0;
210 }
211
--- tools/mkversion.c
+++ tools/mkversion.c
@@ -200,11 +200,13 @@
200 #elif defined(__POCC__) /* e.g. 700 */
201 d = (__POCC__ / 100); /* major */
202 x = (__POCC__ % 100); /* minor */
203 printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
204 #elif defined(_MSC_VER) /* e.g. 1800 */
205 /* _MSC_FULL_VER also defined, e.g. 193030709 */
206 d = (_MSC_VER / 100); /* major */
207 x = (_MSC_VER % 100); /* minor */
208 printf("#define COMPILER_VERSION \"%d.%02d.", d, x);
209 printf("%05d\"\n",(int)(_MSC_FULL_VER % 100000)); /* build (patch) */
210 #endif
211 return 0;
212 }
213
--- tools/sqlcompattest.c
+++ tools/sqlcompattest.c
@@ -62,11 +62,10 @@
6262
version=(major*1000000)+(minor*1000)+release;
6363
6464
int i;
6565
static const char *zRequiredOpts[] = {
6666
"ENABLE_FTS4", /* Required for repository search */
67
- "ENABLE_JSON1", /* Required for the check-in locking protocol */
6867
"ENABLE_DBSTAT_VTAB", /* Required by /repo-tabsize page */
6968
};
7069
7170
/* Check minimum SQLite version number */
7271
if( sqlite3_libversion_number()<version ){
7372
7473
DELETED win/Makefile.PellesCGMake
--- tools/sqlcompattest.c
+++ tools/sqlcompattest.c
@@ -62,11 +62,10 @@
62 version=(major*1000000)+(minor*1000)+release;
63
64 int i;
65 static const char *zRequiredOpts[] = {
66 "ENABLE_FTS4", /* Required for repository search */
67 "ENABLE_JSON1", /* Required for the check-in locking protocol */
68 "ENABLE_DBSTAT_VTAB", /* Required by /repo-tabsize page */
69 };
70
71 /* Check minimum SQLite version number */
72 if( sqlite3_libversion_number()<version ){
73
74 ELETED win/Makefile.PellesCGMake
--- tools/sqlcompattest.c
+++ tools/sqlcompattest.c
@@ -62,11 +62,10 @@
62 version=(major*1000000)+(minor*1000)+release;
63
64 int i;
65 static const char *zRequiredOpts[] = {
66 "ENABLE_FTS4", /* Required for repository search */
 
67 "ENABLE_DBSTAT_VTAB", /* Required by /repo-tabsize page */
68 };
69
70 /* Check minimum SQLite version number */
71 if( sqlite3_libversion_number()<version ){
72
73 ELETED win/Makefile.PellesCGMake
D win/Makefile.PellesCGMake
-196
--- a/win/Makefile.PellesCGMake
+++ b/win/Makefile.PellesCGMake
@@ -1,196 +0,0 @@
1
-#
2
-##############################################################################
3
-# WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "tools/makemake.tcl")
4
-##############################################################################
5
-#
6
-# This file is automatically generated. Instead of editing this
7
-# file, edit "makemake.tcl" then run "tclsh makemake.tcl"
8
-# to regenerate this file.
9
-#
10
-# HowTo
11
-# -----
12
-#
13
-# This is a Makefile to compile fossil with PellesC from
14
-# http://www.smorgasbordet.com/pellesc/index.htm
15
-# In addition to the Compiler envrionment, you need
16
-# gmake from http://sourceforge.net/projects/unxutils/, Pelles make version
17
-# couldn't handle the complex dependencies in this build
18
-# zlib sources
19
-# Then you do
20
-# 1. create a directory PellesC in the project root directory
21
-# 2. Change the variables PellesCDir/ZLIBSRCDIR to the path of your installation
22
-# 3. open a dos prompt window and change working directory into PellesC (step 1)
23
-# 4. run gmake -f ..\win\Makefile.PellesCGMake
24
-#
25
-# this file is tested with
26
-# PellesC 5.00.13
27
-# gmake 3.80
28
-# zlib sources 1.2.5
29
-# Windows XP SP 2
30
-# and
31
-# PellesC 6.00.4
32
-# gmake 3.80
33
-# zlib sources 1.2.5
34
-# Windows 7 Home Premium
35
-#
36
-
37
-#
38
-PellesCDir=c:\Programme\PellesC
39
-
40
-# Select between 32/64 bit code, default is 32 bit
41
-#TARGETVERSION=64
42
-
43
-ifeq ($(TARGETVERSION),64)
44
-# 64 bit version
45
-TARGETMACHINE_CC=amd64
46
-TARGETMACHINE_LN=amd64
47
-TARGETEXTEND=64
48
-else
49
-# 32 bit version
50
-TARGETMACHINE_CC=x86
51
-TARGETMACHINE_LN=ix86
52
-TARGETEXTEND=
53
-endif
54
-
55
-# define the project directories
56
-B=..
57
-SRCDIR=$(B)/src/
58
-SRCDIR_extsrc=$(B)/extsrc/
59
-SRCDIR_tools=$(B)/tools/
60
-WINDIR=$(B)/win/
61
-ZLIBSRCDIR=../../zlib/
62
-
63
-# define linker command and options
64
-LINK=$(PellesCDir)/bin/polink.exe
65
-LINKFLAGS=-subsystem:console -machine:$(TARGETMACHINE_LN) /LIBPATH:$(PellesCDir)\lib\win$(TARGETEXTEND) /LIBPATH:$(PellesCDir)\lib kernel32.lib advapi32.lib delayimp$(TARGETEXTEND).lib Wsock32.lib dnsapi.lib Crtmt$(TARGETEXTEND).lib
66
-
67
-# define standard C-compiler and flags, used to compile
68
-# the fossil binary. Some special definitions follow for
69
-# special files follow
70
-CC=$(PellesCDir)\bin\pocc.exe
71
-DEFINES=-D_pgmptr=g.argv[0]
72
-CCFLAGS=-T$(TARGETMACHINE_CC)-coff -Ot -W2 -Gd -Go -Ze -MT $(DEFINES)
73
-INCLUDE=/I $(PellesCDir)\Include\Win /I $(PellesCDir)\Include /I $(ZLIBSRCDIR) /I $(SRCDIR) /I $(SRCDIR_extsrc)
74
-
75
-# define commands for building the windows resource files
76
-RESOURCE=fossil.res
77
-RC=$(PellesCDir)\bin\porc.exe
78
-RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
79
-
80
-# define the special utilities files, needed to generate
81
-# the automatically generated source files
82
-UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
83
-UTILS_OBJ=$(UTILS:.exe=.obj)
84
-UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR_tools)$(uf:.exe=.c))
85
-
86
-# define the SQLite files, which need special flags on compile
87
-SQLITESRC=sqlite3.c
88
-ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR_extsrc)$(sf))
89
-SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
90
-SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DSQLITE_WIN32_NO_ANSI
91
-
92
-# define the SQLite shell files, which need special flags on compile
93
-SQLITESHELLSRC=shell.c
94
-ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR_extsrc)$(sf))
95
-SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
96
-SQLITESHELLDEFINES=-DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
97
-
98
-# define the th scripting files, which need special flags on compile
99
-THSRC=th.c th_lang.c
100
-ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
101
-THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
102
-
103
-# define the zlib files, needed by this compile
104
-ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
105
-ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
106
-ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
107
-
108
-# define all fossil sources, using the standard compile and
109
-# source generation. These are all files in SRCDIR, which are not
110
-# mentioned as special files above:
111
-ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC) $(ORIGSQLITESHELLSRC),$(wildcard $(SRCDIR)*.c))
112
-SRC=$(subst $(SRCDIR),,$(ORIGSRC))
113
-TRANSLATEDSRC=$(SRC:.c=_.c)
114
-TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
115
-
116
-# main target file is the application
117
-APPLICATION=fossil.exe
118
-
119
-# define the standard make target
120
-.PHONY: default
121
-default: page_index.h builtin_data.h headers $(APPLICATION)
122
-
123
-# symbolic target to generate the source generate utils
124
-.PHONY: utils
125
-utils: $(UTILS)
126
-
127
-# link utils
128
-$(UTILS) version.exe: %.exe: %.obj
129
- $(LINK) $(LINKFLAGS) -out:"$@" $<
130
-
131
-# compiling standard fossil utils
132
-$(UTILS_OBJ): %.obj: $(SRCDIR)%.c
133
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
134
-
135
-# compile special windows utils
136
-version.obj: $(SRCDIR_tools)mkversion.c
137
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
138
-
139
-# generate the translated c-source files
140
-$(TRANSLATEDSRC): %_.c: $(SRCDIR)%.c translate.exe
141
- translate.exe $< >$@
142
-
143
-# generate the index source, containing all web references,..
144
-page_index.h: $(TRANSLATEDSRC) mkindex.exe
145
- mkindex.exe $(TRANSLATEDSRC) >$@
146
-
147
-builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
148
- mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@
149
-
150
-# extracting version info from manifest
151
-VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
152
- version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@
153
-
154
-# generate the simplified headers
155
-headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/extsrc/sqlite3.h ../src/th.h
156
- makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/extsrc/sqlite3.h ../src/th.h VERSION.h
157
- echo Done >$@
158
-
159
-# compile C sources with relevant options
160
-
161
-$(TRANSLATEDOBJ): %_.obj: %_.c %.h
162
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
163
-
164
-$(SQLITEOBJ): %.obj: $(SRCDIR_extsrc)%.c $(SRCDIR_extsrc)%.h
165
- $(CC) $(CCFLAGS) $(SQLITEDEFINES) $(INCLUDE) "$<" -Fo"$@"
166
-
167
-$(SQLITESHELLOBJ): %.obj: $(SRCDIR_extsrc)%.c
168
- $(CC) $(CCFLAGS) $(SQLITESHELLDEFINES) $(INCLUDE) "$<" -Fo"$@"
169
-
170
-$(THOBJ): %.obj: $(SRCDIR)%.c $(SRCDIR)th.h
171
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
172
-
173
-$(ZLIBOBJ): %.obj: $(ZLIBSRCDIR)%.c
174
- $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
175
-
176
-# create the windows resource with icon and version info
177
-$(RESOURCE): %.res: ../win/%.rc ../win/*.ico
178
- $(RC) $(RCFLAGS) $< -Fo"$@"
179
-
180
-# link the application
181
-$(APPLICATION): $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) headers $(RESOURCE)
182
- $(LINK) $(LINKFLAGS) -out:"$@" $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) $(RESOURCE)
183
-
184
-# cleanup
185
-
186
-.PHONY: clean
187
-clean:
188
- -del /F $(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) $(UTILS_OBJ) version.obj
189
- -del /F $(TRANSLATEDSRC)
190
- -del /F *.h headers
191
- -del /F $(RESOURCE)
192
-
193
-.PHONY: clobber
194
-clobber: clean
195
- -del /F *.exe
196
-
--- a/win/Makefile.PellesCGMake
+++ b/win/Makefile.PellesCGMake
@@ -1,196 +0,0 @@
1 #
2 ##############################################################################
3 # WARNING: DO NOT EDIT, AUTOMATICALLY GENERATED FILE (SEE "tools/makemake.tcl")
4 ##############################################################################
5 #
6 # This file is automatically generated. Instead of editing this
7 # file, edit "makemake.tcl" then run "tclsh makemake.tcl"
8 # to regenerate this file.
9 #
10 # HowTo
11 # -----
12 #
13 # This is a Makefile to compile fossil with PellesC from
14 # http://www.smorgasbordet.com/pellesc/index.htm
15 # In addition to the Compiler envrionment, you need
16 # gmake from http://sourceforge.net/projects/unxutils/, Pelles make version
17 # couldn't handle the complex dependencies in this build
18 # zlib sources
19 # Then you do
20 # 1. create a directory PellesC in the project root directory
21 # 2. Change the variables PellesCDir/ZLIBSRCDIR to the path of your installation
22 # 3. open a dos prompt window and change working directory into PellesC (step 1)
23 # 4. run gmake -f ..\win\Makefile.PellesCGMake
24 #
25 # this file is tested with
26 # PellesC 5.00.13
27 # gmake 3.80
28 # zlib sources 1.2.5
29 # Windows XP SP 2
30 # and
31 # PellesC 6.00.4
32 # gmake 3.80
33 # zlib sources 1.2.5
34 # Windows 7 Home Premium
35 #
36
37 #
38 PellesCDir=c:\Programme\PellesC
39
40 # Select between 32/64 bit code, default is 32 bit
41 #TARGETVERSION=64
42
43 ifeq ($(TARGETVERSION),64)
44 # 64 bit version
45 TARGETMACHINE_CC=amd64
46 TARGETMACHINE_LN=amd64
47 TARGETEXTEND=64
48 else
49 # 32 bit version
50 TARGETMACHINE_CC=x86
51 TARGETMACHINE_LN=ix86
52 TARGETEXTEND=
53 endif
54
55 # define the project directories
56 B=..
57 SRCDIR=$(B)/src/
58 SRCDIR_extsrc=$(B)/extsrc/
59 SRCDIR_tools=$(B)/tools/
60 WINDIR=$(B)/win/
61 ZLIBSRCDIR=../../zlib/
62
63 # define linker command and options
64 LINK=$(PellesCDir)/bin/polink.exe
65 LINKFLAGS=-subsystem:console -machine:$(TARGETMACHINE_LN) /LIBPATH:$(PellesCDir)\lib\win$(TARGETEXTEND) /LIBPATH:$(PellesCDir)\lib kernel32.lib advapi32.lib delayimp$(TARGETEXTEND).lib Wsock32.lib dnsapi.lib Crtmt$(TARGETEXTEND).lib
66
67 # define standard C-compiler and flags, used to compile
68 # the fossil binary. Some special definitions follow for
69 # special files follow
70 CC=$(PellesCDir)\bin\pocc.exe
71 DEFINES=-D_pgmptr=g.argv[0]
72 CCFLAGS=-T$(TARGETMACHINE_CC)-coff -Ot -W2 -Gd -Go -Ze -MT $(DEFINES)
73 INCLUDE=/I $(PellesCDir)\Include\Win /I $(PellesCDir)\Include /I $(ZLIBSRCDIR) /I $(SRCDIR) /I $(SRCDIR_extsrc)
74
75 # define commands for building the windows resource files
76 RESOURCE=fossil.res
77 RC=$(PellesCDir)\bin\porc.exe
78 RCFLAGS=$(INCLUDE) -D__POCC__=1 -D_M_X$(TARGETVERSION)
79
80 # define the special utilities files, needed to generate
81 # the automatically generated source files
82 UTILS=translate.exe mkindex.exe makeheaders.exe mkbuiltin.exe
83 UTILS_OBJ=$(UTILS:.exe=.obj)
84 UTILS_SRC=$(foreach uf,$(UTILS),$(SRCDIR_tools)$(uf:.exe=.c))
85
86 # define the SQLite files, which need special flags on compile
87 SQLITESRC=sqlite3.c
88 ORIGSQLITESRC=$(foreach sf,$(SQLITESRC),$(SRCDIR_extsrc)$(sf))
89 SQLITEOBJ=$(foreach sf,$(SQLITESRC),$(sf:.c=.obj))
90 SQLITEDEFINES=-DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DSQLITE_WIN32_NO_ANSI
91
92 # define the SQLite shell files, which need special flags on compile
93 SQLITESHELLSRC=shell.c
94 ORIGSQLITESHELLSRC=$(foreach sf,$(SQLITESHELLSRC),$(SRCDIR_extsrc)$(sf))
95 SQLITESHELLOBJ=$(foreach sf,$(SQLITESHELLSRC),$(sf:.c=.obj))
96 SQLITESHELLDEFINES=-DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
97
98 # define the th scripting files, which need special flags on compile
99 THSRC=th.c th_lang.c
100 ORIGTHSRC=$(foreach sf,$(THSRC),$(SRCDIR)$(sf))
101 THOBJ=$(foreach sf,$(THSRC),$(sf:.c=.obj))
102
103 # define the zlib files, needed by this compile
104 ZLIBSRC=adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
105 ORIGZLIBSRC=$(foreach sf,$(ZLIBSRC),$(ZLIBSRCDIR)$(sf))
106 ZLIBOBJ=$(foreach sf,$(ZLIBSRC),$(sf:.c=.obj))
107
108 # define all fossil sources, using the standard compile and
109 # source generation. These are all files in SRCDIR, which are not
110 # mentioned as special files above:
111 ORIGSRC=$(filter-out $(UTILS_SRC) $(ORIGTHSRC) $(ORIGSQLITESRC) $(ORIGSQLITESHELLSRC),$(wildcard $(SRCDIR)*.c))
112 SRC=$(subst $(SRCDIR),,$(ORIGSRC))
113 TRANSLATEDSRC=$(SRC:.c=_.c)
114 TRANSLATEDOBJ=$(TRANSLATEDSRC:.c=.obj)
115
116 # main target file is the application
117 APPLICATION=fossil.exe
118
119 # define the standard make target
120 .PHONY: default
121 default: page_index.h builtin_data.h headers $(APPLICATION)
122
123 # symbolic target to generate the source generate utils
124 .PHONY: utils
125 utils: $(UTILS)
126
127 # link utils
128 $(UTILS) version.exe: %.exe: %.obj
129 $(LINK) $(LINKFLAGS) -out:"$@" $<
130
131 # compiling standard fossil utils
132 $(UTILS_OBJ): %.obj: $(SRCDIR)%.c
133 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
134
135 # compile special windows utils
136 version.obj: $(SRCDIR_tools)mkversion.c
137 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
138
139 # generate the translated c-source files
140 $(TRANSLATEDSRC): %_.c: $(SRCDIR)%.c translate.exe
141 translate.exe $< >$@
142
143 # generate the index source, containing all web references,..
144 page_index.h: $(TRANSLATEDSRC) mkindex.exe
145 mkindex.exe $(TRANSLATEDSRC) >$@
146
147 builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe
148 mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@
149
150 # extracting version info from manifest
151 VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION
152 version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@
153
154 # generate the simplified headers
155 headers: makeheaders.exe page_index.h builtin_data.h VERSION.h ../src/extsrc/sqlite3.h ../src/th.h
156 makeheaders.exe $(foreach ts,$(TRANSLATEDSRC),$(ts):$(ts:_.c=.h)) ../src/extsrc/sqlite3.h ../src/th.h VERSION.h
157 echo Done >$@
158
159 # compile C sources with relevant options
160
161 $(TRANSLATEDOBJ): %_.obj: %_.c %.h
162 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
163
164 $(SQLITEOBJ): %.obj: $(SRCDIR_extsrc)%.c $(SRCDIR_extsrc)%.h
165 $(CC) $(CCFLAGS) $(SQLITEDEFINES) $(INCLUDE) "$<" -Fo"$@"
166
167 $(SQLITESHELLOBJ): %.obj: $(SRCDIR_extsrc)%.c
168 $(CC) $(CCFLAGS) $(SQLITESHELLDEFINES) $(INCLUDE) "$<" -Fo"$@"
169
170 $(THOBJ): %.obj: $(SRCDIR)%.c $(SRCDIR)th.h
171 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
172
173 $(ZLIBOBJ): %.obj: $(ZLIBSRCDIR)%.c
174 $(CC) $(CCFLAGS) $(INCLUDE) "$<" -Fo"$@"
175
176 # create the windows resource with icon and version info
177 $(RESOURCE): %.res: ../win/%.rc ../win/*.ico
178 $(RC) $(RCFLAGS) $< -Fo"$@"
179
180 # link the application
181 $(APPLICATION): $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) headers $(RESOURCE)
182 $(LINK) $(LINKFLAGS) -out:"$@" $(TRANSLATEDOBJ) $(SQLITEOBJ) $(SQLITESHELLOBJ) $(THOBJ) $(ZLIBOBJ) $(RESOURCE)
183
184 # cleanup
185
186 .PHONY: clean
187 clean:
188 -del /F $(TRANSLATEDOBJ) $(SQLITEOBJ) $(THOBJ) $(ZLIBOBJ) $(UTILS_OBJ) version.obj
189 -del /F $(TRANSLATEDSRC)
190 -del /F *.h headers
191 -del /F $(RESOURCE)
192
193 .PHONY: clobber
194 clobber: clean
195 -del /F *.exe
196
--- a/win/Makefile.PellesCGMake
+++ b/win/Makefile.PellesCGMake
@@ -1,196 +0,0 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -29,10 +29,12 @@
2929
LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
3030
3131
SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0
3232
3333
SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
34
+
35
+PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000
3436
3537
SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c chat_.c checkin_.c checkout_.c clearsign_.c clone_.c color_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c interwiki_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c patch_.c path_.c piechart_.c pikchrshow_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c
3638
3739
OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\chat$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\color$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\interwiki$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\patch$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pikchrshow$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
3840
@@ -1007,7 +1009,7 @@
10071009
10081010
zip_.c : $(SRCDIR)\zip.c
10091011
+translate$E $** > $@
10101012
10111013
headers: makeheaders$E page_index.h builtin_data.h VERSION.h
1012
- +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h chat_.c:chat.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h color_.c:color.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h interwiki_.c:interwiki.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h patch_.c:patch.h path_.c:path.h piechart_.c:piechart.h pikchrshow_.c:pikchrshow.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR_extsrc)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR_extsrc)\cson_amalgamation.h
1014
+ +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h chat_.c:chat.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h color_.c:color.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h interwiki_.c:interwiki.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h patch_.c:patch.h path_.c:path.h piechart_.c:piechart.h pikchrshow_.c:pikchrshow.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR_extsrc)\pikchr.c:pikchr.h $(SRCDIR_extsrc)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR_extsrc)\cson_amalgamation.h
10131015
@copy /Y nul: headers
10141016
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -29,10 +29,12 @@
29 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
30
31 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0
32
33 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
 
 
34
35 SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c chat_.c checkin_.c checkout_.c clearsign_.c clone_.c color_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c interwiki_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c patch_.c path_.c piechart_.c pikchrshow_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c
36
37 OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\chat$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\color$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\interwiki$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\patch$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pikchrshow$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
38
@@ -1007,7 +1009,7 @@
1007
1008 zip_.c : $(SRCDIR)\zip.c
1009 +translate$E $** > $@
1010
1011 headers: makeheaders$E page_index.h builtin_data.h VERSION.h
1012 +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h chat_.c:chat.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h color_.c:color.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h interwiki_.c:interwiki.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h patch_.c:patch.h path_.c:path.h piechart_.c:piechart.h pikchrshow_.c:pikchrshow.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR_extsrc)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR_extsrc)\cson_amalgamation.h
1013 @copy /Y nul: headers
1014
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -29,10 +29,12 @@
29 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi
30
31 SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0
32
33 SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen
34
35 PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000
36
37 SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c chat_.c checkin_.c checkout_.c clearsign_.c clone_.c color_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c interwiki_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c patch_.c path_.c piechart_.c pikchrshow_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c
38
39 OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\chat$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\color$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\interwiki$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\patch$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pikchrshow$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
40
@@ -1007,7 +1009,7 @@
1009
1010 zip_.c : $(SRCDIR)\zip.c
1011 +translate$E $** > $@
1012
1013 headers: makeheaders$E page_index.h builtin_data.h VERSION.h
1014 +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h chat_.c:chat.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h color_.c:color.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h interwiki_.c:interwiki.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h patch_.c:patch.h path_.c:path.h piechart_.c:piechart.h pikchrshow_.c:pikchrshow.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR_extsrc)\pikchr.c:pikchr.h $(SRCDIR_extsrc)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR_extsrc)\cson_amalgamation.h
1015 @copy /Y nul: headers
1016
+34 -32
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2528,41 +2528,43 @@
25282528
$(MINGW_OPTIONS) \
25292529
-DSQLITE_USE_MALLOC_H \
25302530
-DSQLITE_USE_MSIZE
25312531
25322532
SHELL_OPTIONS = -DNDEBUG=1 \
2533
- -DSQLITE_DQS=0 \
2534
- -DSQLITE_THREADSAFE=0 \
2535
- -DSQLITE_DEFAULT_MEMSTATUS=0 \
2536
- -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
2537
- -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
2538
- -DSQLITE_OMIT_DECLTYPE \
2539
- -DSQLITE_OMIT_DEPRECATED \
2540
- -DSQLITE_OMIT_PROGRESS_CALLBACK \
2541
- -DSQLITE_OMIT_SHARED_CACHE \
2542
- -DSQLITE_OMIT_LOAD_EXTENSION \
2543
- -DSQLITE_MAX_EXPR_DEPTH=0 \
2544
- -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2545
- -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2546
- -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2547
- -DSQLITE_ENABLE_FTS4 \
2548
- -DSQLITE_ENABLE_DBSTAT_VTAB \
2549
- -DSQLITE_ENABLE_FTS5 \
2550
- -DSQLITE_ENABLE_STMTVTAB \
2551
- -DSQLITE_HAVE_ZLIB \
2552
- -DSQLITE_ENABLE_DBPAGE_VTAB \
2553
- -DSQLITE_TRUSTED_SCHEMA=0 \
2554
- -Dmain=sqlite3_shell \
2555
- -DSQLITE_SHELL_IS_UTF8=1 \
2556
- -DSQLITE_OMIT_LOAD_EXTENSION=1 \
2557
- -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \
2558
- -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname \
2559
- -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc \
2560
- -Daccess=file_access \
2561
- -Dsystem=fossil_system \
2562
- -Dgetenv=fossil_getenv \
2563
- -Dfopen=fossil_fopen
2533
+ -DSQLITE_DQS=0 \
2534
+ -DSQLITE_THREADSAFE=0 \
2535
+ -DSQLITE_DEFAULT_MEMSTATUS=0 \
2536
+ -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
2537
+ -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
2538
+ -DSQLITE_OMIT_DECLTYPE \
2539
+ -DSQLITE_OMIT_DEPRECATED \
2540
+ -DSQLITE_OMIT_PROGRESS_CALLBACK \
2541
+ -DSQLITE_OMIT_SHARED_CACHE \
2542
+ -DSQLITE_OMIT_LOAD_EXTENSION \
2543
+ -DSQLITE_MAX_EXPR_DEPTH=0 \
2544
+ -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2545
+ -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2546
+ -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2547
+ -DSQLITE_ENABLE_FTS4 \
2548
+ -DSQLITE_ENABLE_DBSTAT_VTAB \
2549
+ -DSQLITE_ENABLE_FTS5 \
2550
+ -DSQLITE_ENABLE_STMTVTAB \
2551
+ -DSQLITE_HAVE_ZLIB \
2552
+ -DSQLITE_ENABLE_DBPAGE_VTAB \
2553
+ -DSQLITE_TRUSTED_SCHEMA=0 \
2554
+ -Dmain=sqlite3_shell \
2555
+ -DSQLITE_SHELL_IS_UTF8=1 \
2556
+ -DSQLITE_OMIT_LOAD_EXTENSION=1 \
2557
+ -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \
2558
+ -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname \
2559
+ -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc \
2560
+ -Daccess=file_access \
2561
+ -Dsystem=fossil_system \
2562
+ -Dgetenv=fossil_getenv \
2563
+ -Dfopen=fossil_fopen
2564
+
2565
+PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000
25642566
25652567
$(OBJDIR)/sqlite3.o: $(SQLITE3_SRC) $(SRCDIR)/../win/Makefile.mingw
25662568
$(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $(SEE_FLAGS) \
25672569
-c $(SQLITE3_SRC) -o $@
25682570
@@ -2582,7 +2584,7 @@
25822584
25832585
$(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
25842586
$(XTCC) -c $(SRCDIR)/th_tcl.c -o $@
25852587
25862588
$(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
2587
- $(XTCC) -c $(SRCDIR_extsrc)/pikchr.c -o $@
2589
+ $(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
25882590
25892591
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2528,41 +2528,43 @@
2528 $(MINGW_OPTIONS) \
2529 -DSQLITE_USE_MALLOC_H \
2530 -DSQLITE_USE_MSIZE
2531
2532 SHELL_OPTIONS = -DNDEBUG=1 \
2533 -DSQLITE_DQS=0 \
2534 -DSQLITE_THREADSAFE=0 \
2535 -DSQLITE_DEFAULT_MEMSTATUS=0 \
2536 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
2537 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
2538 -DSQLITE_OMIT_DECLTYPE \
2539 -DSQLITE_OMIT_DEPRECATED \
2540 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2541 -DSQLITE_OMIT_SHARED_CACHE \
2542 -DSQLITE_OMIT_LOAD_EXTENSION \
2543 -DSQLITE_MAX_EXPR_DEPTH=0 \
2544 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2545 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2546 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2547 -DSQLITE_ENABLE_FTS4 \
2548 -DSQLITE_ENABLE_DBSTAT_VTAB \
2549 -DSQLITE_ENABLE_FTS5 \
2550 -DSQLITE_ENABLE_STMTVTAB \
2551 -DSQLITE_HAVE_ZLIB \
2552 -DSQLITE_ENABLE_DBPAGE_VTAB \
2553 -DSQLITE_TRUSTED_SCHEMA=0 \
2554 -Dmain=sqlite3_shell \
2555 -DSQLITE_SHELL_IS_UTF8=1 \
2556 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
2557 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \
2558 -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname \
2559 -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc \
2560 -Daccess=file_access \
2561 -Dsystem=fossil_system \
2562 -Dgetenv=fossil_getenv \
2563 -Dfopen=fossil_fopen
 
 
2564
2565 $(OBJDIR)/sqlite3.o: $(SQLITE3_SRC) $(SRCDIR)/../win/Makefile.mingw
2566 $(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $(SEE_FLAGS) \
2567 -c $(SQLITE3_SRC) -o $@
2568
@@ -2582,7 +2584,7 @@
2582
2583 $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
2584 $(XTCC) -c $(SRCDIR)/th_tcl.c -o $@
2585
2586 $(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
2587 $(XTCC) -c $(SRCDIR_extsrc)/pikchr.c -o $@
2588
2589
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -2528,41 +2528,43 @@
2528 $(MINGW_OPTIONS) \
2529 -DSQLITE_USE_MALLOC_H \
2530 -DSQLITE_USE_MSIZE
2531
2532 SHELL_OPTIONS = -DNDEBUG=1 \
2533 -DSQLITE_DQS=0 \
2534 -DSQLITE_THREADSAFE=0 \
2535 -DSQLITE_DEFAULT_MEMSTATUS=0 \
2536 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
2537 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
2538 -DSQLITE_OMIT_DECLTYPE \
2539 -DSQLITE_OMIT_DEPRECATED \
2540 -DSQLITE_OMIT_PROGRESS_CALLBACK \
2541 -DSQLITE_OMIT_SHARED_CACHE \
2542 -DSQLITE_OMIT_LOAD_EXTENSION \
2543 -DSQLITE_MAX_EXPR_DEPTH=0 \
2544 -DSQLITE_ENABLE_LOCKING_STYLE=0 \
2545 -DSQLITE_DEFAULT_FILE_FORMAT=4 \
2546 -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
2547 -DSQLITE_ENABLE_FTS4 \
2548 -DSQLITE_ENABLE_DBSTAT_VTAB \
2549 -DSQLITE_ENABLE_FTS5 \
2550 -DSQLITE_ENABLE_STMTVTAB \
2551 -DSQLITE_HAVE_ZLIB \
2552 -DSQLITE_ENABLE_DBPAGE_VTAB \
2553 -DSQLITE_TRUSTED_SCHEMA=0 \
2554 -Dmain=sqlite3_shell \
2555 -DSQLITE_SHELL_IS_UTF8=1 \
2556 -DSQLITE_OMIT_LOAD_EXTENSION=1 \
2557 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) \
2558 -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname \
2559 -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc \
2560 -Daccess=file_access \
2561 -Dsystem=fossil_system \
2562 -Dgetenv=fossil_getenv \
2563 -Dfopen=fossil_fopen
2564
2565 PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000
2566
2567 $(OBJDIR)/sqlite3.o: $(SQLITE3_SRC) $(SRCDIR)/../win/Makefile.mingw
2568 $(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) $(SEE_FLAGS) \
2569 -c $(SQLITE3_SRC) -o $@
2570
@@ -2582,7 +2584,7 @@
2584
2585 $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
2586 $(XTCC) -c $(SRCDIR)/th_tcl.c -o $@
2587
2588 $(OBJDIR)/pikchr.o: $(SRCDIR_extsrc)/pikchr.c
2589 $(XTCC) $(PIKCHR_OPTIONS) -c $(SRCDIR_extsrc)/pikchr.c -o $@
2590
2591
+46 -9
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,11 +116,10 @@
116116
!if $(FOSSIL_DYNAMIC_BUILD)!=0
117117
SSLLIBDIR = $(SSLDIR)
118118
!else
119119
SSLLIBDIR = $(SSLDIR)
120120
!endif
121
-SSLLFLAGS = /nologo /opt:ref /debug
122121
SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
123122
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
124123
!message Using 'x64' platform for OpenSSL...
125124
SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
126125
!if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -173,11 +172,11 @@
173172
174173
!if $(FOSSIL_ENABLE_TCL)!=0
175174
INCL = $(INCL) /I"$(TCLINCDIR)"
176175
!endif
177176
178
-CFLAGS = /nologo
177
+CFLAGS = /nologo /W2 /WX /utf-8
179178
LDFLAGS =
180179
181180
CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
182181
CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
183182
@@ -188,16 +187,27 @@
188187
!endif
189188
190189
!if $(FOSSIL_ENABLE_WINXP)!=0
191190
XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
192191
CFLAGS = $(CFLAGS) $(XPCFLAGS)
192
+#
193
+# NOTE: For regular builds, /OSVERSION defaults to the /SUBSYSTEM version and
194
+# explicit initialization is redundant, but is required for post-built edits.
195
+#
193196
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
194
-XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
197
+XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.02 /SUBSYSTEM:CONSOLE,5.02
195198
!else
196
-XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
199
+XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.01 /SUBSYSTEM:CONSOLE,5.01
197200
!endif
198201
LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
202
+#
203
+# NOTE: Only XPCFLAGS is forwarded to the OpenSSL configuration, and XPLDFLAGS
204
+# is applied in a separate post-build step, see below for more information.
205
+#
206
+!if $(FOSSIL_ENABLE_SSL)!=0
207
+SSLCONFIG = $(SSLCONFIG) $(XPCFLAGS)
208
+!endif
199209
!endif
200210
201211
!if $(FOSSIL_DYNAMIC_BUILD)!=0
202212
!if $(DEBUG)!=0
203213
CRTFLAGS = /MDd
@@ -344,10 +354,12 @@
344354
/Daccess=file_access \
345355
/Dsystem=fossil_system \
346356
/Dgetenv=fossil_getenv \
347357
/Dfopen=fossil_fopen
348358
359
+PIKCHR_OPTIONS = /DPIKCHR_TOKEN_LIMIT=10000
360
+
349361
SRC = "$(OX)\add_.c" \
350362
"$(OX)\ajax_.c" \
351363
"$(OX)\alerts_.c" \
352364
"$(OX)\allrepo_.c" \
353365
"$(OX)\attach_.c" \
@@ -490,11 +502,12 @@
490502
"$(OX)\wikiformat_.c" \
491503
"$(OX)\winfile_.c" \
492504
"$(OX)\winhttp_.c" \
493505
"$(OX)\xfer_.c" \
494506
"$(OX)\xfersetup_.c" \
495
- "$(OX)\zip_.c"
507
+ "$(OX)\zip_.c" \
508
+ "$(SRCDIR_extsrc)\pikchr.c"
496509
497510
EXTRA_FILES = "$(SRCDIR)\..\skins\ardoise\css.txt" \
498511
"$(SRCDIR)\..\skins\ardoise\details.txt" \
499512
"$(SRCDIR)\..\skins\ardoise\footer.txt" \
500513
"$(SRCDIR)\..\skins\ardoise\header.txt" \
@@ -794,19 +807,42 @@
794807
@pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
795808
796809
!if $(FOSSIL_ENABLE_SSL)!=0
797810
openssl:
798811
@echo Building OpenSSL from "$(SSLDIR)"...
812
+!if $(FOSSIL_ENABLE_WINXP)!=0
813
+ @echo Passing XPCFLAGS = [ $(XPCFLAGS) ] to the OpenSSL configuration...
814
+!endif
799815
!ifdef PERLDIR
800816
@pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
801817
!else
802818
@pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
803819
!endif
804
-!if $(FOSSIL_ENABLE_WINXP)!=0
805
- @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
806
-!else
807820
@pushd "$(SSLDIR)" && $(MAKE) && popd
821
+!if $(FOSSIL_ENABLE_WINXP)!=0 && $(FOSSIL_DYNAMIC_BUILD)!=0
822
+#
823
+# NOTE: Appending custom linker flags to the OpenSSL default linker flags is
824
+# somewhat difficult, as summarized in this Fossil Forum post:
825
+#
826
+# https://fossil-scm.org/forum/forumpost/a9a2d6af28b
827
+#
828
+# Therefore the custom linker flags required for Windows XP dynamic builds are
829
+# applied in a separate post-build step.
830
+#
831
+# If the build stops here, or if the custom linker flags are outside the scope
832
+# of `editbin` or `link /EDIT` (i.e. additional libraries), consider tweaking
833
+# the OpenSSL makefile by hand.
834
+#
835
+# Also note that this step changes the subsystem for the OpenSSL DLLs from
836
+# WINDOWS to CONSOLE, but which has no effect on DLLs.
837
+#
838
+ @echo Applying XPLDFLAGS = [ $(XPLDFLAGS) ] to the OpenSSL DLLs...
839
+ @for /F "usebackq delims=" %F in (`dir /A:-D/B "$(SSLDIR)\*.dll" 2^>nul`) \
840
+ do @( \
841
+ echo %F & \
842
+ link /EDIT /NOLOGO $(XPLDFLAGS) "$(SSLDIR)\%F" || exit 1 \
843
+ )
808844
!endif
809845
810846
clean-openssl:
811847
@pushd "$(SSLDIR)" && $(MAKE) clean && popd
812848
!endif
@@ -1026,11 +1062,11 @@
10261062
10271063
"$(OX)\th_tcl$O" : "$(SRCDIR)\th_tcl.c"
10281064
$(TCC) /Fo$@ /Fd$(@D)\ -c $**
10291065
10301066
"$(OX)\pikchr$O" : "$(SRCDIR_extsrc)\pikchr.c"
1031
- $(TCC) /Fo$@ /Fd$(@D)\ -c $**
1067
+ $(TCC) $(PIKCHR_OPTIONS) /Fo$@ /Fd$(@D)\ -c $**
10321068
10331069
"$(OX)\VERSION.h" : "$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" "$(B)\phony.h"
10341070
"$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" > $@
10351071
10361072
"$(B)\phony.h" :
@@ -2234,10 +2270,11 @@
22342270
"$(OX)\winfile_.c":"$(OX)\winfile.h" \
22352271
"$(OX)\winhttp_.c":"$(OX)\winhttp.h" \
22362272
"$(OX)\xfer_.c":"$(OX)\xfer.h" \
22372273
"$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \
22382274
"$(OX)\zip_.c":"$(OX)\zip.h" \
2275
+ "$(SRCDIR_extsrc)\pikchr.c":"$(OX)\pikchr.h" \
22392276
"$(SRCDIR_extsrc)\sqlite3.h" \
22402277
"$(SRCDIR)\th.h" \
22412278
"$(OX)\VERSION.h" \
22422279
"$(SRCDIR_extsrc)\cson_amalgamation.h"
22432280
@copy /Y nul: $@
22442281
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,11 +116,10 @@
116 !if $(FOSSIL_DYNAMIC_BUILD)!=0
117 SSLLIBDIR = $(SSLDIR)
118 !else
119 SSLLIBDIR = $(SSLDIR)
120 !endif
121 SSLLFLAGS = /nologo /opt:ref /debug
122 SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
123 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
124 !message Using 'x64' platform for OpenSSL...
125 SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
126 !if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -173,11 +172,11 @@
173
174 !if $(FOSSIL_ENABLE_TCL)!=0
175 INCL = $(INCL) /I"$(TCLINCDIR)"
176 !endif
177
178 CFLAGS = /nologo
179 LDFLAGS =
180
181 CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
182 CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
183
@@ -188,16 +187,27 @@
188 !endif
189
190 !if $(FOSSIL_ENABLE_WINXP)!=0
191 XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
192 CFLAGS = $(CFLAGS) $(XPCFLAGS)
 
 
 
 
193 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
194 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.02
195 !else
196 XPLDFLAGS = $(XPLDFLAGS) /SUBSYSTEM:CONSOLE,5.01
197 !endif
198 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
 
 
 
 
 
 
 
199 !endif
200
201 !if $(FOSSIL_DYNAMIC_BUILD)!=0
202 !if $(DEBUG)!=0
203 CRTFLAGS = /MDd
@@ -344,10 +354,12 @@
344 /Daccess=file_access \
345 /Dsystem=fossil_system \
346 /Dgetenv=fossil_getenv \
347 /Dfopen=fossil_fopen
348
 
 
349 SRC = "$(OX)\add_.c" \
350 "$(OX)\ajax_.c" \
351 "$(OX)\alerts_.c" \
352 "$(OX)\allrepo_.c" \
353 "$(OX)\attach_.c" \
@@ -490,11 +502,12 @@
490 "$(OX)\wikiformat_.c" \
491 "$(OX)\winfile_.c" \
492 "$(OX)\winhttp_.c" \
493 "$(OX)\xfer_.c" \
494 "$(OX)\xfersetup_.c" \
495 "$(OX)\zip_.c"
 
496
497 EXTRA_FILES = "$(SRCDIR)\..\skins\ardoise\css.txt" \
498 "$(SRCDIR)\..\skins\ardoise\details.txt" \
499 "$(SRCDIR)\..\skins\ardoise\footer.txt" \
500 "$(SRCDIR)\..\skins\ardoise\header.txt" \
@@ -794,19 +807,42 @@
794 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
795
796 !if $(FOSSIL_ENABLE_SSL)!=0
797 openssl:
798 @echo Building OpenSSL from "$(SSLDIR)"...
 
 
 
799 !ifdef PERLDIR
800 @pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
801 !else
802 @pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
803 !endif
804 !if $(FOSSIL_ENABLE_WINXP)!=0
805 @pushd "$(SSLDIR)" && $(MAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(XPLDFLAGS)" && popd
806 !else
807 @pushd "$(SSLDIR)" && $(MAKE) && popd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
808 !endif
809
810 clean-openssl:
811 @pushd "$(SSLDIR)" && $(MAKE) clean && popd
812 !endif
@@ -1026,11 +1062,11 @@
1026
1027 "$(OX)\th_tcl$O" : "$(SRCDIR)\th_tcl.c"
1028 $(TCC) /Fo$@ /Fd$(@D)\ -c $**
1029
1030 "$(OX)\pikchr$O" : "$(SRCDIR_extsrc)\pikchr.c"
1031 $(TCC) /Fo$@ /Fd$(@D)\ -c $**
1032
1033 "$(OX)\VERSION.h" : "$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" "$(B)\phony.h"
1034 "$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" > $@
1035
1036 "$(B)\phony.h" :
@@ -2234,10 +2270,11 @@
2234 "$(OX)\winfile_.c":"$(OX)\winfile.h" \
2235 "$(OX)\winhttp_.c":"$(OX)\winhttp.h" \
2236 "$(OX)\xfer_.c":"$(OX)\xfer.h" \
2237 "$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \
2238 "$(OX)\zip_.c":"$(OX)\zip.h" \
 
2239 "$(SRCDIR_extsrc)\sqlite3.h" \
2240 "$(SRCDIR)\th.h" \
2241 "$(OX)\VERSION.h" \
2242 "$(SRCDIR_extsrc)\cson_amalgamation.h"
2243 @copy /Y nul: $@
2244
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,11 +116,10 @@
116 !if $(FOSSIL_DYNAMIC_BUILD)!=0
117 SSLLIBDIR = $(SSLDIR)
118 !else
119 SSLLIBDIR = $(SSLDIR)
120 !endif
 
121 SSLLIB = libssl.lib libcrypto.lib user32.lib gdi32.lib crypt32.lib
122 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
123 !message Using 'x64' platform for OpenSSL...
124 SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers
125 !if $(FOSSIL_DYNAMIC_BUILD)!=0
@@ -173,11 +172,11 @@
172
173 !if $(FOSSIL_ENABLE_TCL)!=0
174 INCL = $(INCL) /I"$(TCLINCDIR)"
175 !endif
176
177 CFLAGS = /nologo /W2 /WX /utf-8
178 LDFLAGS =
179
180 CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS
181 CFLAGS = $(CFLAGS) /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_NONSTDC_NO_WARNINGS
182
@@ -188,16 +187,27 @@
187 !endif
188
189 !if $(FOSSIL_ENABLE_WINXP)!=0
190 XPCFLAGS = $(XPCFLAGS) /D_WIN32_WINNT=0x0501 /D_USING_V110_SDK71_=1
191 CFLAGS = $(CFLAGS) $(XPCFLAGS)
192 #
193 # NOTE: For regular builds, /OSVERSION defaults to the /SUBSYSTEM version and
194 # explicit initialization is redundant, but is required for post-built edits.
195 #
196 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
197 XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.02 /SUBSYSTEM:CONSOLE,5.02
198 !else
199 XPLDFLAGS = $(XPLDFLAGS) /OSVERSION:5.01 /SUBSYSTEM:CONSOLE,5.01
200 !endif
201 LDFLAGS = $(LDFLAGS) $(XPLDFLAGS)
202 #
203 # NOTE: Only XPCFLAGS is forwarded to the OpenSSL configuration, and XPLDFLAGS
204 # is applied in a separate post-build step, see below for more information.
205 #
206 !if $(FOSSIL_ENABLE_SSL)!=0
207 SSLCONFIG = $(SSLCONFIG) $(XPCFLAGS)
208 !endif
209 !endif
210
211 !if $(FOSSIL_DYNAMIC_BUILD)!=0
212 !if $(DEBUG)!=0
213 CRTFLAGS = /MDd
@@ -344,10 +354,12 @@
354 /Daccess=file_access \
355 /Dsystem=fossil_system \
356 /Dgetenv=fossil_getenv \
357 /Dfopen=fossil_fopen
358
359 PIKCHR_OPTIONS = /DPIKCHR_TOKEN_LIMIT=10000
360
361 SRC = "$(OX)\add_.c" \
362 "$(OX)\ajax_.c" \
363 "$(OX)\alerts_.c" \
364 "$(OX)\allrepo_.c" \
365 "$(OX)\attach_.c" \
@@ -490,11 +502,12 @@
502 "$(OX)\wikiformat_.c" \
503 "$(OX)\winfile_.c" \
504 "$(OX)\winhttp_.c" \
505 "$(OX)\xfer_.c" \
506 "$(OX)\xfersetup_.c" \
507 "$(OX)\zip_.c" \
508 "$(SRCDIR_extsrc)\pikchr.c"
509
510 EXTRA_FILES = "$(SRCDIR)\..\skins\ardoise\css.txt" \
511 "$(SRCDIR)\..\skins\ardoise\details.txt" \
512 "$(SRCDIR)\..\skins\ardoise\footer.txt" \
513 "$(SRCDIR)\..\skins\ardoise\header.txt" \
@@ -794,19 +807,42 @@
807 @pushd "$(ZLIBDIR)" && $(MAKE) /f win32\Makefile.msc clean && popd
808
809 !if $(FOSSIL_ENABLE_SSL)!=0
810 openssl:
811 @echo Building OpenSSL from "$(SSLDIR)"...
812 !if $(FOSSIL_ENABLE_WINXP)!=0
813 @echo Passing XPCFLAGS = [ $(XPCFLAGS) ] to the OpenSSL configuration...
814 !endif
815 !ifdef PERLDIR
816 @pushd "$(SSLDIR)" && "$(PERLDIR)\$(PERL)" Configure $(SSLCONFIG) && popd
817 !else
818 @pushd "$(SSLDIR)" && "$(PERL)" Configure $(SSLCONFIG) && popd
819 !endif
 
 
 
820 @pushd "$(SSLDIR)" && $(MAKE) && popd
821 !if $(FOSSIL_ENABLE_WINXP)!=0 && $(FOSSIL_DYNAMIC_BUILD)!=0
822 #
823 # NOTE: Appending custom linker flags to the OpenSSL default linker flags is
824 # somewhat difficult, as summarized in this Fossil Forum post:
825 #
826 # https://fossil-scm.org/forum/forumpost/a9a2d6af28b
827 #
828 # Therefore the custom linker flags required for Windows XP dynamic builds are
829 # applied in a separate post-build step.
830 #
831 # If the build stops here, or if the custom linker flags are outside the scope
832 # of `editbin` or `link /EDIT` (i.e. additional libraries), consider tweaking
833 # the OpenSSL makefile by hand.
834 #
835 # Also note that this step changes the subsystem for the OpenSSL DLLs from
836 # WINDOWS to CONSOLE, but which has no effect on DLLs.
837 #
838 @echo Applying XPLDFLAGS = [ $(XPLDFLAGS) ] to the OpenSSL DLLs...
839 @for /F "usebackq delims=" %F in (`dir /A:-D/B "$(SSLDIR)\*.dll" 2^>nul`) \
840 do @( \
841 echo %F & \
842 link /EDIT /NOLOGO $(XPLDFLAGS) "$(SSLDIR)\%F" || exit 1 \
843 )
844 !endif
845
846 clean-openssl:
847 @pushd "$(SSLDIR)" && $(MAKE) clean && popd
848 !endif
@@ -1026,11 +1062,11 @@
1062
1063 "$(OX)\th_tcl$O" : "$(SRCDIR)\th_tcl.c"
1064 $(TCC) /Fo$@ /Fd$(@D)\ -c $**
1065
1066 "$(OX)\pikchr$O" : "$(SRCDIR_extsrc)\pikchr.c"
1067 $(TCC) $(PIKCHR_OPTIONS) /Fo$@ /Fd$(@D)\ -c $**
1068
1069 "$(OX)\VERSION.h" : "$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" "$(B)\phony.h"
1070 "$(OBJDIR)\mkversion$E" "$(B)\manifest.uuid" "$(B)\manifest" "$(B)\VERSION" > $@
1071
1072 "$(B)\phony.h" :
@@ -2234,10 +2270,11 @@
2270 "$(OX)\winfile_.c":"$(OX)\winfile.h" \
2271 "$(OX)\winhttp_.c":"$(OX)\winhttp.h" \
2272 "$(OX)\xfer_.c":"$(OX)\xfer.h" \
2273 "$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \
2274 "$(OX)\zip_.c":"$(OX)\zip.h" \
2275 "$(SRCDIR_extsrc)\pikchr.c":"$(OX)\pikchr.h" \
2276 "$(SRCDIR_extsrc)\sqlite3.h" \
2277 "$(SRCDIR)\th.h" \
2278 "$(OX)\VERSION.h" \
2279 "$(SRCDIR_extsrc)\cson_amalgamation.h"
2280 @copy /Y nul: $@
2281
--- www/aboutcgi.wiki
+++ www/aboutcgi.wiki
@@ -189,13 +189,13 @@
189189
<a id="cgivar"></a>
190190
The web server sets many environment variables in step 2 in addition
191191
to just PATH_INFO. The following diagram shows a few of these variables
192192
and their relationship to the request URL:
193193
<pre>
194
- REQUEST_URI
195
- ______________|___________________
196
- / \
194
+ REQUEST_URI
195
+ ___________________|_______________________
196
+ / \
197197
http://example.com/cgis/example2/subdir/three/timeline?c=55d7e1
198198
\_________/\____________/\____________________/ \______/
199199
| | | |
200200
HTTP_HOST SCRIPT_NAME PATH_INFO QUERY_STRING
201201
</pre>
202202
--- www/aboutcgi.wiki
+++ www/aboutcgi.wiki
@@ -189,13 +189,13 @@
189 <a id="cgivar"></a>
190 The web server sets many environment variables in step 2 in addition
191 to just PATH_INFO. The following diagram shows a few of these variables
192 and their relationship to the request URL:
193 <pre>
194 REQUEST_URI
195 ______________|___________________
196 / \
197 http://example.com/cgis/example2/subdir/three/timeline?c=55d7e1
198 \_________/\____________/\____________________/ \______/
199 | | | |
200 HTTP_HOST SCRIPT_NAME PATH_INFO QUERY_STRING
201 </pre>
202
--- www/aboutcgi.wiki
+++ www/aboutcgi.wiki
@@ -189,13 +189,13 @@
189 <a id="cgivar"></a>
190 The web server sets many environment variables in step 2 in addition
191 to just PATH_INFO. The following diagram shows a few of these variables
192 and their relationship to the request URL:
193 <pre>
194 REQUEST_URI
195 ___________________|_______________________
196 / \
197 http://example.com/cgis/example2/subdir/three/timeline?c=55d7e1
198 \_________/\____________/\____________________/ \______/
199 | | | |
200 HTTP_HOST SCRIPT_NAME PATH_INFO QUERY_STRING
201 </pre>
202
+65 -66
--- www/antibot.wiki
+++ www/antibot.wiki
@@ -1,44 +1,43 @@
1
-<title>Defense Against Spiders</title>
2
-
3
-The website presented by a Fossil server has many hyperlinks.
4
-Even a modest project can have millions of pages in its
5
-tree, and many of those pages (for example diffs and annotations
6
-and ZIP archives of older check-ins) can be expensive to compute.
7
-If a spider or bot tries to walk a website implemented by
8
-Fossil, it can present a crippling bandwidth and CPU load.
9
-
10
-The website presented by a Fossil server is intended to be used
11
-interactively by humans, not walked by spiders. This article
1
+<title>Defense Against Robots</title>
2
+
3
+A typical Fossil website can have millions of pages, and many of
4
+those pages (for example diffs and annotations and tarballs) can
5
+be expensive to compute.
6
+If a robot walks a Fossil-generated website,
7
+it can present a crippling bandwidth and CPU load.
8
+
9
+A Fossil website is intended to be used
10
+interactively by humans, not walked by robots. This article
1211
describes the techniques used by Fossil to try to welcome human
13
-users while keeping out spiders.
12
+users while keeping out robots.
1413
1514
<h2>The Hyperlink User Capability</h2>
1615
1716
Every Fossil web session has a "user". For random passers-by on the internet
18
-(and for spiders) that user is "nobody". The "anonymous" user is also
17
+(and for robots) that user is "nobody". The "anonymous" user is also
1918
available for humans who do not wish to identify themselves. The difference
2019
is that "anonymous" requires a login (using a password supplied via
2120
a CAPTCHA) whereas "nobody" does not require a login.
2221
The site administrator can also create logins with
2322
passwords for specific individuals.
2423
2524
Users without the <b>[./caps/ref.html#h | Hyperlink]</b> capability
2625
do not see most Fossil-generated hyperlinks. This is
27
-a simple defense against spiders, since [./caps/#ucat | the "nobody"
26
+a simple defense against robots, since [./caps/#ucat | the "nobody"
2827
user category] does not have this capability by default.
2928
Users must log in (perhaps as
30
-"anonymous") before they can see any of the hyperlinks. A spider
29
+"anonymous") before they can see any of the hyperlinks. A robot
3130
that cannot log into your Fossil repository will be unable to walk
3231
its historical check-ins, create diffs between versions, pull zip
33
-archives, etc. by visiting links, because they aren't there.
32
+archives, etc. by visiting links, because there are no links.
3433
3534
A text message appears at the top of each page in this situation to
3635
invite humans to log in as anonymous in order to activate hyperlinks.
3736
38
-Because this required login step is annoying to some,
39
-Fossil provides other techniques for blocking spiders which
37
+But requiring a login, even an anonymous login, can be annoying.
38
+Fossil provides other techniques for blocking robots which
4039
are less cumbersome to humans.
4140
4241
<h2>Automatic Hyperlinks Based on UserAgent</h2>
4342
4443
Fossil has the ability to selectively enable hyperlinks for users
@@ -45,11 +44,11 @@
4544
that lack the <b>Hyperlink</b> capability based on their UserAgent string in the
4645
HTTP request header and on the browsers ability to run Javascript.
4746
4847
The UserAgent string is a text identifier that is included in the header
4948
of most HTTP requests that identifies the specific maker and version of
50
-the browser (or spider) that generated the request. Typical UserAgent
49
+the browser (or robot) that generated the request. Typical UserAgent
5150
strings look like this:
5251
5352
<ul>
5453
<li> Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0
5554
<li> Mozilla/4.0 (compatible; MSIE 8.0; Windows_NT 5.1; Trident/4.0)
@@ -57,92 +56,92 @@
5756
<li> Wget/1.12 (openbsd4.9)
5857
</ul>
5958
6059
The first two UserAgent strings above identify Firefox 19 and
6160
Internet Explorer 8.0, both running on Windows NT. The third
62
-example is the spider used by Google to index the internet.
61
+example is the robot used by Google to index the internet.
6362
The fourth example is the "wget" utility running on OpenBSD.
6463
Thus the first two UserAgent strings above identify the requester
65
-as human whereas the second two identify the requester as a spider.
64
+as human whereas the second two identify the requester as a robot.
6665
Note that the UserAgent string is completely under the control
67
-of the requester and so a malicious spider can forge a UserAgent
68
-string that makes it look like a human. But most spiders truly
69
-seem to desire to "play nicely" on the internet and are quite open
70
-about the fact that they are a spider. And so the UserAgent string
66
+of the requester and so a malicious robot can forge a UserAgent
67
+string that makes it look like a human. But most robots want
68
+to "play nicely" on the internet and are quite open
69
+about the fact that they are a robot. And so the UserAgent string
7170
provides a good first-guess about whether or not a request originates
72
-from a human or a spider.
73
-
74
-In Fossil, under the Admin/Access menu, there is a setting entitled
75
-"<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>".
76
-If this setting is enabled, and if the UserAgent string looks like a
77
-human and not a spider, then Fossil will enable hyperlinks even if
78
-the <b>Hyperlink</b> capability is omitted from the user permissions. This setting
79
-gives humans easy access to the hyperlinks while preventing spiders
80
-from walking the millions of pages on a typical Fossil site.
81
-
82
-But the hyperlinks are not enabled directly with the setting above.
71
+from a human or a robot.
72
+
73
+In Fossil, under the Admin/Robot-Defense menu, there is a setting entitled
74
+"<b>Enable hyperlinks based on User-Agent and/or Javascript</b>".
75
+If this setting is set to "UserAgent only" or "UserAgent and Javascript",
76
+and if the UserAgent string looks like a human and not a robot, then
77
+Fossil will enable hyperlinks even if the <b>Hyperlink</b> capability
78
+is omitted from the user permissions. This settingn gives humans easy
79
+access to the hyperlinks while preventing robots
80
+from walking the billions of pages on a typical Fossil site.
81
+
82
+If the setting is "UserAgent only", then the hyperlinks are simply
83
+enabled and that is all. But if the setting is "UserAgent and Javascript",
84
+then the hyperlinks are not enabled directly .
8385
Instead, the HTML code that is generated contains anchor tags ("&lt;a&gt;")
84
-without "href=" attributes. Then, JavaScript code is added to the
85
-end of the page that goes back and fills in the "href=" attributes of
86
-the anchor tags with the hyperlink targets, thus enabling the hyperlinks.
86
+with "href=" attributes that point to [/honeypot] rather than the correct
87
+link. JavaScript code is added to the end of the page that goes back and
88
+fills in the correct "href=" attributes of
89
+the anchor tags with the true hyperlink targets, thus enabling the hyperlinks.
8790
This extra step of using JavaScript to enable the hyperlink targets
88
-is a security measure against spiders that forge a human-looking
89
-UserAgent string. Most spiders do not bother to run JavaScript and
90
-so to the spider the empty anchor tag will be useless. But all modern
91
+is a security measure against robots that forge a human-looking
92
+UserAgent string. Most robots do not bother to run JavaScript and
93
+so to the robot the empty anchor tag will be useless. But all modern
9194
web browsers implement JavaScript, so hyperlinks will show up
9295
normally for human users.
9396
9497
<h2>Further Defenses</h2>
9598
9699
Recently (as of this writing, in the spring of 2013) the Fossil server
97100
on the SQLite website ([http://www.sqlite.org/src/]) has been hit repeatedly
98
-by Chinese spiders that use forged UserAgent strings to make them look
101
+by Chinese robots that use forged UserAgent strings to make them look
99102
like normal web browsers and which interpret JavaScript. We do not
100103
believe these attacks to be nefarious since SQLite is public domain
101104
and the attackers could obtain all information they ever wanted to
102105
know about SQLite simply by cloning the repository. Instead, we
103106
believe these "attacks" are coming from "script kiddies". But regardless
104107
of whether or not malice is involved, these attacks do present
105108
an unnecessary load on the server which reduces the responsiveness of
106109
the SQLite website for well-behaved and socially responsible users.
107110
For this reason, additional defenses against
108
-spiders have been put in place.
111
+robots have been put in place.
109112
110
-On the Admin/Access page of Fossil, just below the
111
-"<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>"
113
+On the Admin/Robot-Defense page of Fossil, just below the
114
+"<b>Enable hyperlinks using User-Agent and/or Javascript</b>"
112115
setting, there are now two additional sub-settings that can be optionally
113116
enabled to control hyperlinks.
114117
115
-The first sub-setting waits to run the
116
-JavaScript that sets the "href=" attributes on anchor tags until after
117
-at least one "mouseover" event has been detected on the &lt;body&gt;
118
-element of the page. The thinking here is that spiders will not be
119
-simulating mouse motion and so no mouseover events will ever occur and
120
-hence the hyperlinks will never become enabled for spiders.
121
-
122
-The second new sub-setting is a delay (in milliseconds) before setting
123
-the "href=" attributes on anchor tags. The default value for this
124
-delay is 10 milliseconds. The idea here is that a spider will try to
125
-render the page immediately, and will not wait for delayed scripts
126
-to be run, thus will never enable the hyperlinks.
127
-
128
-These two sub-settings can be used separately or together. If used together,
129
-then the delay timer does not start until after the first mouse movement
130
-is detected.
118
+The first new sub-setting is a delay (in milliseconds) before setting
119
+the "href=" attributes on anchor tags. The default value for this
120
+delay is 10 milliseconds. The idea here is that a robots will try to
121
+interpret the links on the page immediately, and will not wait for delayed
122
+scripts to be run, and thus will never enable the true links.
123
+
124
+The second sub-setting waits to run the
125
+JavaScript that sets the "href=" attributes on anchor tags until after
126
+at least one "mousedown" or "mousemove" event has been detected on the
127
+&lt;body&gt; element of the page. The thinking here is that robots will not be
128
+simulating mouse motion and so no mouse events will ever occur and
129
+hence the hyperlinks will never become enabled for robots.
131130
132131
See also [./loadmgmt.md|Managing Server Load] for a description
133132
of how expensive pages can be disabled when the server is under heavy
134133
load.
135134
136135
<h2>The Ongoing Struggle</h2>
137136
138137
Fossil currently does a very good job of providing easy access to humans
139
-while keeping out troublesome robots and spiders. However, spiders and
140
-bots continue to grow more sophisticated, requiring ever more advanced
138
+while keeping out troublesome robots. However, robots
139
+continue to grow more sophisticated, requiring ever more advanced
141140
defenses. This "arms race" is unlikely to ever end. The developers of
142
-Fossil will continue to try improve the spider defenses of Fossil so
141
+Fossil will continue to try improve the robot defenses of Fossil so
143142
check back from time to time for the latest releases and updates.
144143
145
-Readers of this page who have suggestions on how to improve the spider
144
+Readers of this page who have suggestions on how to improve the robot
146145
defenses in Fossil are invited to submit your ideas to the Fossil Users
147146
forum:
148147
[https://fossil-scm.org/forum].
149148
--- www/antibot.wiki
+++ www/antibot.wiki
@@ -1,44 +1,43 @@
1 <title>Defense Against Spiders</title>
2
3 The website presented by a Fossil server has many hyperlinks.
4 Even a modest project can have millions of pages in its
5 tree, and many of those pages (for example diffs and annotations
6 and ZIP archives of older check-ins) can be expensive to compute.
7 If a spider or bot tries to walk a website implemented by
8 Fossil, it can present a crippling bandwidth and CPU load.
9
10 The website presented by a Fossil server is intended to be used
11 interactively by humans, not walked by spiders. This article
12 describes the techniques used by Fossil to try to welcome human
13 users while keeping out spiders.
14
15 <h2>The Hyperlink User Capability</h2>
16
17 Every Fossil web session has a "user". For random passers-by on the internet
18 (and for spiders) that user is "nobody". The "anonymous" user is also
19 available for humans who do not wish to identify themselves. The difference
20 is that "anonymous" requires a login (using a password supplied via
21 a CAPTCHA) whereas "nobody" does not require a login.
22 The site administrator can also create logins with
23 passwords for specific individuals.
24
25 Users without the <b>[./caps/ref.html#h | Hyperlink]</b> capability
26 do not see most Fossil-generated hyperlinks. This is
27 a simple defense against spiders, since [./caps/#ucat | the "nobody"
28 user category] does not have this capability by default.
29 Users must log in (perhaps as
30 "anonymous") before they can see any of the hyperlinks. A spider
31 that cannot log into your Fossil repository will be unable to walk
32 its historical check-ins, create diffs between versions, pull zip
33 archives, etc. by visiting links, because they aren't there.
34
35 A text message appears at the top of each page in this situation to
36 invite humans to log in as anonymous in order to activate hyperlinks.
37
38 Because this required login step is annoying to some,
39 Fossil provides other techniques for blocking spiders which
40 are less cumbersome to humans.
41
42 <h2>Automatic Hyperlinks Based on UserAgent</h2>
43
44 Fossil has the ability to selectively enable hyperlinks for users
@@ -45,11 +44,11 @@
45 that lack the <b>Hyperlink</b> capability based on their UserAgent string in the
46 HTTP request header and on the browsers ability to run Javascript.
47
48 The UserAgent string is a text identifier that is included in the header
49 of most HTTP requests that identifies the specific maker and version of
50 the browser (or spider) that generated the request. Typical UserAgent
51 strings look like this:
52
53 <ul>
54 <li> Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0
55 <li> Mozilla/4.0 (compatible; MSIE 8.0; Windows_NT 5.1; Trident/4.0)
@@ -57,92 +56,92 @@
57 <li> Wget/1.12 (openbsd4.9)
58 </ul>
59
60 The first two UserAgent strings above identify Firefox 19 and
61 Internet Explorer 8.0, both running on Windows NT. The third
62 example is the spider used by Google to index the internet.
63 The fourth example is the "wget" utility running on OpenBSD.
64 Thus the first two UserAgent strings above identify the requester
65 as human whereas the second two identify the requester as a spider.
66 Note that the UserAgent string is completely under the control
67 of the requester and so a malicious spider can forge a UserAgent
68 string that makes it look like a human. But most spiders truly
69 seem to desire to "play nicely" on the internet and are quite open
70 about the fact that they are a spider. And so the UserAgent string
71 provides a good first-guess about whether or not a request originates
72 from a human or a spider.
73
74 In Fossil, under the Admin/Access menu, there is a setting entitled
75 "<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>".
76 If this setting is enabled, and if the UserAgent string looks like a
77 human and not a spider, then Fossil will enable hyperlinks even if
78 the <b>Hyperlink</b> capability is omitted from the user permissions. This setting
79 gives humans easy access to the hyperlinks while preventing spiders
80 from walking the millions of pages on a typical Fossil site.
81
82 But the hyperlinks are not enabled directly with the setting above.
 
 
 
83 Instead, the HTML code that is generated contains anchor tags ("&lt;a&gt;")
84 without "href=" attributes. Then, JavaScript code is added to the
85 end of the page that goes back and fills in the "href=" attributes of
86 the anchor tags with the hyperlink targets, thus enabling the hyperlinks.
 
87 This extra step of using JavaScript to enable the hyperlink targets
88 is a security measure against spiders that forge a human-looking
89 UserAgent string. Most spiders do not bother to run JavaScript and
90 so to the spider the empty anchor tag will be useless. But all modern
91 web browsers implement JavaScript, so hyperlinks will show up
92 normally for human users.
93
94 <h2>Further Defenses</h2>
95
96 Recently (as of this writing, in the spring of 2013) the Fossil server
97 on the SQLite website ([http://www.sqlite.org/src/]) has been hit repeatedly
98 by Chinese spiders that use forged UserAgent strings to make them look
99 like normal web browsers and which interpret JavaScript. We do not
100 believe these attacks to be nefarious since SQLite is public domain
101 and the attackers could obtain all information they ever wanted to
102 know about SQLite simply by cloning the repository. Instead, we
103 believe these "attacks" are coming from "script kiddies". But regardless
104 of whether or not malice is involved, these attacks do present
105 an unnecessary load on the server which reduces the responsiveness of
106 the SQLite website for well-behaved and socially responsible users.
107 For this reason, additional defenses against
108 spiders have been put in place.
109
110 On the Admin/Access page of Fossil, just below the
111 "<b>Enable hyperlinks for "nobody" based on User-Agent and Javascript</b>"
112 setting, there are now two additional sub-settings that can be optionally
113 enabled to control hyperlinks.
114
115 The first sub-setting waits to run the
116 JavaScript that sets the "href=" attributes on anchor tags until after
117 at least one "mouseover" event has been detected on the &lt;body&gt;
118 element of the page. The thinking here is that spiders will not be
119 simulating mouse motion and so no mouseover events will ever occur and
120 hence the hyperlinks will never become enabled for spiders.
121
122 The second new sub-setting is a delay (in milliseconds) before setting
123 the "href=" attributes on anchor tags. The default value for this
124 delay is 10 milliseconds. The idea here is that a spider will try to
125 render the page immediately, and will not wait for delayed scripts
126 to be run, thus will never enable the hyperlinks.
127
128 These two sub-settings can be used separately or together. If used together,
129 then the delay timer does not start until after the first mouse movement
130 is detected.
131
132 See also [./loadmgmt.md|Managing Server Load] for a description
133 of how expensive pages can be disabled when the server is under heavy
134 load.
135
136 <h2>The Ongoing Struggle</h2>
137
138 Fossil currently does a very good job of providing easy access to humans
139 while keeping out troublesome robots and spiders. However, spiders and
140 bots continue to grow more sophisticated, requiring ever more advanced
141 defenses. This "arms race" is unlikely to ever end. The developers of
142 Fossil will continue to try improve the spider defenses of Fossil so
143 check back from time to time for the latest releases and updates.
144
145 Readers of this page who have suggestions on how to improve the spider
146 defenses in Fossil are invited to submit your ideas to the Fossil Users
147 forum:
148 [https://fossil-scm.org/forum].
149
--- www/antibot.wiki
+++ www/antibot.wiki
@@ -1,44 +1,43 @@
1 <title>Defense Against Robots</title>
2
3 A typical Fossil website can have millions of pages, and many of
4 those pages (for example diffs and annotations and tarballs) can
5 be expensive to compute.
6 If a robot walks a Fossil-generated website,
7 it can present a crippling bandwidth and CPU load.
8
9 A Fossil website is intended to be used
10 interactively by humans, not walked by robots. This article
 
11 describes the techniques used by Fossil to try to welcome human
12 users while keeping out robots.
13
14 <h2>The Hyperlink User Capability</h2>
15
16 Every Fossil web session has a "user". For random passers-by on the internet
17 (and for robots) that user is "nobody". The "anonymous" user is also
18 available for humans who do not wish to identify themselves. The difference
19 is that "anonymous" requires a login (using a password supplied via
20 a CAPTCHA) whereas "nobody" does not require a login.
21 The site administrator can also create logins with
22 passwords for specific individuals.
23
24 Users without the <b>[./caps/ref.html#h | Hyperlink]</b> capability
25 do not see most Fossil-generated hyperlinks. This is
26 a simple defense against robots, since [./caps/#ucat | the "nobody"
27 user category] does not have this capability by default.
28 Users must log in (perhaps as
29 "anonymous") before they can see any of the hyperlinks. A robot
30 that cannot log into your Fossil repository will be unable to walk
31 its historical check-ins, create diffs between versions, pull zip
32 archives, etc. by visiting links, because there are no links.
33
34 A text message appears at the top of each page in this situation to
35 invite humans to log in as anonymous in order to activate hyperlinks.
36
37 But requiring a login, even an anonymous login, can be annoying.
38 Fossil provides other techniques for blocking robots which
39 are less cumbersome to humans.
40
41 <h2>Automatic Hyperlinks Based on UserAgent</h2>
42
43 Fossil has the ability to selectively enable hyperlinks for users
@@ -45,11 +44,11 @@
44 that lack the <b>Hyperlink</b> capability based on their UserAgent string in the
45 HTTP request header and on the browsers ability to run Javascript.
46
47 The UserAgent string is a text identifier that is included in the header
48 of most HTTP requests that identifies the specific maker and version of
49 the browser (or robot) that generated the request. Typical UserAgent
50 strings look like this:
51
52 <ul>
53 <li> Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0
54 <li> Mozilla/4.0 (compatible; MSIE 8.0; Windows_NT 5.1; Trident/4.0)
@@ -57,92 +56,92 @@
56 <li> Wget/1.12 (openbsd4.9)
57 </ul>
58
59 The first two UserAgent strings above identify Firefox 19 and
60 Internet Explorer 8.0, both running on Windows NT. The third
61 example is the robot used by Google to index the internet.
62 The fourth example is the "wget" utility running on OpenBSD.
63 Thus the first two UserAgent strings above identify the requester
64 as human whereas the second two identify the requester as a robot.
65 Note that the UserAgent string is completely under the control
66 of the requester and so a malicious robot can forge a UserAgent
67 string that makes it look like a human. But most robots want
68 to "play nicely" on the internet and are quite open
69 about the fact that they are a robot. And so the UserAgent string
70 provides a good first-guess about whether or not a request originates
71 from a human or a robot.
72
73 In Fossil, under the Admin/Robot-Defense menu, there is a setting entitled
74 "<b>Enable hyperlinks based on User-Agent and/or Javascript</b>".
75 If this setting is set to "UserAgent only" or "UserAgent and Javascript",
76 and if the UserAgent string looks like a human and not a robot, then
77 Fossil will enable hyperlinks even if the <b>Hyperlink</b> capability
78 is omitted from the user permissions. This settingn gives humans easy
79 access to the hyperlinks while preventing robots
80 from walking the billions of pages on a typical Fossil site.
81
82 If the setting is "UserAgent only", then the hyperlinks are simply
83 enabled and that is all. But if the setting is "UserAgent and Javascript",
84 then the hyperlinks are not enabled directly .
85 Instead, the HTML code that is generated contains anchor tags ("&lt;a&gt;")
86 with "href=" attributes that point to [/honeypot] rather than the correct
87 link. JavaScript code is added to the end of the page that goes back and
88 fills in the correct "href=" attributes of
89 the anchor tags with the true hyperlink targets, thus enabling the hyperlinks.
90 This extra step of using JavaScript to enable the hyperlink targets
91 is a security measure against robots that forge a human-looking
92 UserAgent string. Most robots do not bother to run JavaScript and
93 so to the robot the empty anchor tag will be useless. But all modern
94 web browsers implement JavaScript, so hyperlinks will show up
95 normally for human users.
96
97 <h2>Further Defenses</h2>
98
99 Recently (as of this writing, in the spring of 2013) the Fossil server
100 on the SQLite website ([http://www.sqlite.org/src/]) has been hit repeatedly
101 by Chinese robots that use forged UserAgent strings to make them look
102 like normal web browsers and which interpret JavaScript. We do not
103 believe these attacks to be nefarious since SQLite is public domain
104 and the attackers could obtain all information they ever wanted to
105 know about SQLite simply by cloning the repository. Instead, we
106 believe these "attacks" are coming from "script kiddies". But regardless
107 of whether or not malice is involved, these attacks do present
108 an unnecessary load on the server which reduces the responsiveness of
109 the SQLite website for well-behaved and socially responsible users.
110 For this reason, additional defenses against
111 robots have been put in place.
112
113 On the Admin/Robot-Defense page of Fossil, just below the
114 "<b>Enable hyperlinks using User-Agent and/or Javascript</b>"
115 setting, there are now two additional sub-settings that can be optionally
116 enabled to control hyperlinks.
117
118 The first new sub-setting is a delay (in milliseconds) before setting
119 the "href=" attributes on anchor tags. The default value for this
120 delay is 10 milliseconds. The idea here is that a robots will try to
121 interpret the links on the page immediately, and will not wait for delayed
122 scripts to be run, and thus will never enable the true links.
123
124 The second sub-setting waits to run the
125 JavaScript that sets the "href=" attributes on anchor tags until after
126 at least one "mousedown" or "mousemove" event has been detected on the
127 &lt;body&gt; element of the page. The thinking here is that robots will not be
128 simulating mouse motion and so no mouse events will ever occur and
129 hence the hyperlinks will never become enabled for robots.
 
 
 
 
130
131 See also [./loadmgmt.md|Managing Server Load] for a description
132 of how expensive pages can be disabled when the server is under heavy
133 load.
134
135 <h2>The Ongoing Struggle</h2>
136
137 Fossil currently does a very good job of providing easy access to humans
138 while keeping out troublesome robots. However, robots
139 continue to grow more sophisticated, requiring ever more advanced
140 defenses. This "arms race" is unlikely to ever end. The developers of
141 Fossil will continue to try improve the robot defenses of Fossil so
142 check back from time to time for the latest releases and updates.
143
144 Readers of this page who have suggestions on how to improve the robot
145 defenses in Fossil are invited to submit your ideas to the Fossil Users
146 forum:
147 [https://fossil-scm.org/forum].
148
+1 -1
--- www/backup.md
+++ www/backup.md
@@ -233,11 +233,11 @@
233233
won’t have the `-pbkdf2` and `-iter` options, and you may have to choose
234234
a different cipher algorithm; both changes are likely to weaken the
235235
encryption significantly, so you should install a newer version rather
236236
than work around the lack of these features.
237237
238
-At the time of this writing — 2021.02.26 — macOS 11 (BigSur) ships an
238
+At the time of this writing — 2022.03.28 — macOS 12 (Monterey) still ships an
239239
outdated fork of OpenSSL 1.0 called [LibreSSL][lssl] that lacks this
240240
capability. Until Apple redresses this lack, we recommend use of the
241241
[Homebrew][hb] OpenSSL package rather than give up on the security
242242
afforded by use of configurable-iteration PBKDF2 in OpenSSL 1.1 and up,
243243
later backported to LibreSSL 2.9.1 and up. To avoid a conflict with the
244244
--- www/backup.md
+++ www/backup.md
@@ -233,11 +233,11 @@
233 won’t have the `-pbkdf2` and `-iter` options, and you may have to choose
234 a different cipher algorithm; both changes are likely to weaken the
235 encryption significantly, so you should install a newer version rather
236 than work around the lack of these features.
237
238 At the time of this writing — 2021.02.26 — macOS 11 (BigSur) ships an
239 outdated fork of OpenSSL 1.0 called [LibreSSL][lssl] that lacks this
240 capability. Until Apple redresses this lack, we recommend use of the
241 [Homebrew][hb] OpenSSL package rather than give up on the security
242 afforded by use of configurable-iteration PBKDF2 in OpenSSL 1.1 and up,
243 later backported to LibreSSL 2.9.1 and up. To avoid a conflict with the
244
--- www/backup.md
+++ www/backup.md
@@ -233,11 +233,11 @@
233 won’t have the `-pbkdf2` and `-iter` options, and you may have to choose
234 a different cipher algorithm; both changes are likely to weaken the
235 encryption significantly, so you should install a newer version rather
236 than work around the lack of these features.
237
238 At the time of this writing — 2022.03.28 — macOS 12 (Monterey) still ships an
239 outdated fork of OpenSSL 1.0 called [LibreSSL][lssl] that lacks this
240 capability. Until Apple redresses this lack, we recommend use of the
241 [Homebrew][hb] OpenSSL package rather than give up on the security
242 afforded by use of configurable-iteration PBKDF2 in OpenSSL 1.1 and up,
243 later backported to LibreSSL 2.9.1 and up. To avoid a conflict with the
244
+43 -20
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,34 +1,57 @@
11
<title>Change Log</title>
22
3
-<h2 id='v2_18'>Changes for version 2.18 (pending)</h2>
3
+<h2 id='v2_19'>Changes for version 2.19 (pending)</h2>
4
+ * On file listing pages, sort filenames using the "uintnocase" collating
5
+ sequence, so that filenames that contains embedded integers sort in
6
+ numeric order even if they contain a different number of digits.
7
+ (Example: "fossil_80_..." comes before "fossil_100.png" in the
8
+ [/dir?ci=92fd091703a28c07&name=skins/blitz|/skins/blitz] directory listing.)
9
+ * Enhancements to the graph layout algorithm design to improve readability
10
+ and promote better situational awareness.
11
+ * Performance enhancement for the
12
+ [./checkin_names.wiki#root|"root:BRANCHNAME" style of tag],
13
+ accomplished using a Common Table Expression in the underlying SQL.
14
+ * Add the new "[/help?cmd=describe|fossil describe]" command.
15
+
16
+<h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
417
* Added support for [./ssl-server.md|SSL/TLS server mode] for commands
518
like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
6
- * Added the --share-links option to [/help?cmd=sync|fossil sync] and
7
- [/help?cmd=pull|fossil pull]. Enhance the
8
- [/doc/trunk/www/sync.wiki|sync protocol] so that it is able to support
9
- sharing of links to other clones.
10
- * Added the --transport-command option to [/help?cmd=sync|fossil sync]
11
- and similar.
12
- * [/help?cmd=/chat|The /chat page] input options have been reworked
13
- again for better cross-browser portability.
14
- * Add new setting "[/help?cmd=large-file-size|large-file-size]". If the size
15
- of any file in a commit exceeds this size, a warning is issued.
16
- * When sending a [/help?cmd=/chat|/chat] message fails, it is no longer
17
- immediately lost and sending may optionally be retried.
18
- * [/help?cmd=/chat|/chat] can now optionally embed attachments of certain
19
- types directly into message bodies via an iframe.
2019
* The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
2120
[/help?cmd=merge|merge --cherrypick].
21
+ * Add new setting "[/help?cmd=large-file-size|large-file-size]". If the size
22
+ of any file in a commit exceeds this size, a warning is issued.
23
+ * Query parameter "year=YYYY" is now accepted by [/help?cmd=/timeline|/timeline].
24
+ * The [/help?cmd=tar|tar] and [/help?cmd=zip|zip commands] no longer
25
+ sterilize the manifest file.
26
+ * Futher improvement to diff alignment in cases that involve both
27
+ edits and indentation changes.
28
+ * [/doc/trunk/www/chat.md|Chat] improvements:<ul>
29
+ <li> [/help?cmd=/chat|The /chat page] input options have been reworked
30
+ again for better cross-browser portability.
31
+ <li> When sending a [/help?cmd=/chat|/chat] message fails, it is no longer
32
+ immediately lost and sending may optionally be retried.
33
+ <li> [/help?cmd=/chat|/chat] can now optionally embed attachments of certain
34
+ types directly into message bodies via an iframe.
35
+ <li> Add the "--as FILENAME" option to the "[/help?cmd=chat|fossil chat send]"
36
+ command.
37
+ <li> Added the "[/help?cmd=chat|fossil chat pull]" command, available to
38
+ administrators only, for backing up the chat conversation.
39
+ </ul>
2240
* Promote the test-detach command into the [/help?cmd=detach|detach command].
23
- * For "fossil pull" with the --from-parent-project option, if not URL is
24
- specified used the last URL specified for the --from-parent-project.
41
+ * For "[/help?cmd=pull|fossil pull]" with the --from-parent-project option,
42
+ if no URL is specified then use the last URL from the most recent prior
43
+ "fossil pull --from-parent-project".
2544
* Add options --project-name and --project-desc to the
2645
"[/help?cmd=init|fossil init]" command.
27
- * Query parameter "year=YYYY" is now accepted by [/help?cmd=/timeline|/timeline].
28
- * Add the "--as FILENAME" option to the "[/help?cmd=chat|fossil chat send]"
29
- command.
46
+ * The [/help?cmd=/ext|/ext page] generates the SERVER_SOFTWARE environment
47
+ variable for clients.
48
+ * Fix the REQUEST_URI [/doc/trunk/www/aboutcgi.wiki#cgivar|CGI variable] such
49
+ that it includes the query string. This is how most other systems understand
50
+ REQUEST_URI.
51
+ * Added the --transport-command option to [/help?cmd=sync|fossil sync]
52
+ and similar.
3053
3154
<h2 id='v2_17'>Changes for version 2.17 (2021-10-09)</h2>
3255
3356
* Major improvements to the "diff" subsystem, including: <ul>
3457
<li> Added new [/help?cmd=diff|formatting options]: --by, -b, --webpage, --json, --tcl.
3558
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,34 +1,57 @@
1 <title>Change Log</title>
2
3 <h2 id='v2_18'>Changes for version 2.18 (pending)</h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
4 * Added support for [./ssl-server.md|SSL/TLS server mode] for commands
5 like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
6 * Added the --share-links option to [/help?cmd=sync|fossil sync] and
7 [/help?cmd=pull|fossil pull]. Enhance the
8 [/doc/trunk/www/sync.wiki|sync protocol] so that it is able to support
9 sharing of links to other clones.
10 * Added the --transport-command option to [/help?cmd=sync|fossil sync]
11 and similar.
12 * [/help?cmd=/chat|The /chat page] input options have been reworked
13 again for better cross-browser portability.
14 * Add new setting "[/help?cmd=large-file-size|large-file-size]". If the size
15 of any file in a commit exceeds this size, a warning is issued.
16 * When sending a [/help?cmd=/chat|/chat] message fails, it is no longer
17 immediately lost and sending may optionally be retried.
18 * [/help?cmd=/chat|/chat] can now optionally embed attachments of certain
19 types directly into message bodies via an iframe.
20 * The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
21 [/help?cmd=merge|merge --cherrypick].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22 * Promote the test-detach command into the [/help?cmd=detach|detach command].
23 * For "fossil pull" with the --from-parent-project option, if not URL is
24 specified used the last URL specified for the --from-parent-project.
 
25 * Add options --project-name and --project-desc to the
26 "[/help?cmd=init|fossil init]" command.
27 * Query parameter "year=YYYY" is now accepted by [/help?cmd=/timeline|/timeline].
28 * Add the "--as FILENAME" option to the "[/help?cmd=chat|fossil chat send]"
29 command.
 
 
 
 
30
31 <h2 id='v2_17'>Changes for version 2.17 (2021-10-09)</h2>
32
33 * Major improvements to the "diff" subsystem, including: <ul>
34 <li> Added new [/help?cmd=diff|formatting options]: --by, -b, --webpage, --json, --tcl.
35
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,34 +1,57 @@
1 <title>Change Log</title>
2
3 <h2 id='v2_19'>Changes for version 2.19 (pending)</h2>
4 * On file listing pages, sort filenames using the "uintnocase" collating
5 sequence, so that filenames that contains embedded integers sort in
6 numeric order even if they contain a different number of digits.
7 (Example: "fossil_80_..." comes before "fossil_100.png" in the
8 [/dir?ci=92fd091703a28c07&name=skins/blitz|/skins/blitz] directory listing.)
9 * Enhancements to the graph layout algorithm design to improve readability
10 and promote better situational awareness.
11 * Performance enhancement for the
12 [./checkin_names.wiki#root|"root:BRANCHNAME" style of tag],
13 accomplished using a Common Table Expression in the underlying SQL.
14 * Add the new "[/help?cmd=describe|fossil describe]" command.
15
16 <h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
17 * Added support for [./ssl-server.md|SSL/TLS server mode] for commands
18 like "[/help?cmd=server|fossil server]" and "[/help?cmd=http|fossil http]"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19 * The new [/help?cmd=cherry-pick|cherry-pick command] is an alias for
20 [/help?cmd=merge|merge --cherrypick].
21 * Add new setting "[/help?cmd=large-file-size|large-file-size]". If the size
22 of any file in a commit exceeds this size, a warning is issued.
23 * Query parameter "year=YYYY" is now accepted by [/help?cmd=/timeline|/timeline].
24 * The [/help?cmd=tar|tar] and [/help?cmd=zip|zip commands] no longer
25 sterilize the manifest file.
26 * Futher improvement to diff alignment in cases that involve both
27 edits and indentation changes.
28 * [/doc/trunk/www/chat.md|Chat] improvements:<ul>
29 <li> [/help?cmd=/chat|The /chat page] input options have been reworked
30 again for better cross-browser portability.
31 <li> When sending a [/help?cmd=/chat|/chat] message fails, it is no longer
32 immediately lost and sending may optionally be retried.
33 <li> [/help?cmd=/chat|/chat] can now optionally embed attachments of certain
34 types directly into message bodies via an iframe.
35 <li> Add the "--as FILENAME" option to the "[/help?cmd=chat|fossil chat send]"
36 command.
37 <li> Added the "[/help?cmd=chat|fossil chat pull]" command, available to
38 administrators only, for backing up the chat conversation.
39 </ul>
40 * Promote the test-detach command into the [/help?cmd=detach|detach command].
41 * For "[/help?cmd=pull|fossil pull]" with the --from-parent-project option,
42 if no URL is specified then use the last URL from the most recent prior
43 "fossil pull --from-parent-project".
44 * Add options --project-name and --project-desc to the
45 "[/help?cmd=init|fossil init]" command.
46 * The [/help?cmd=/ext|/ext page] generates the SERVER_SOFTWARE environment
47 variable for clients.
48 * Fix the REQUEST_URI [/doc/trunk/www/aboutcgi.wiki#cgivar|CGI variable] such
49 that it includes the query string. This is how most other systems understand
50 REQUEST_URI.
51 * Added the --transport-command option to [/help?cmd=sync|fossil sync]
52 and similar.
53
54 <h2 id='v2_17'>Changes for version 2.17 (2021-10-09)</h2>
55
56 * Major improvements to the "diff" subsystem, including: <ul>
57 <li> Added new [/help?cmd=diff|formatting options]: --by, -b, --webpage, --json, --tcl.
58
+1 -1
--- www/chat.md
+++ www/chat.md
@@ -136,11 +136,11 @@
136136
The [fossil chat send](/help?cmd=chat) can be used by project-specific
137137
robots to send notifications to the chatroom. For example, on the
138138
[SQLite project](https://sqlite.org/) (for which the Fossil chatroom
139139
feature, and indeed all of Fossil, was invented) there are long-running
140140
fuzz servers that sometimes run across obscure problems. Whenever this
141
-happens, a message is sent to the SQLite developers chatroom altering
141
+happens, a message is sent to the SQLite developers chatroom alerting
142142
them to the problem.
143143
144144
The recommended way to allow robots to send chat messages is to create
145145
a new user on the server for each robot. Give each such robot account
146146
the "C" privilege only. That means that the robot user account will be
147147
--- www/chat.md
+++ www/chat.md
@@ -136,11 +136,11 @@
136 The [fossil chat send](/help?cmd=chat) can be used by project-specific
137 robots to send notifications to the chatroom. For example, on the
138 [SQLite project](https://sqlite.org/) (for which the Fossil chatroom
139 feature, and indeed all of Fossil, was invented) there are long-running
140 fuzz servers that sometimes run across obscure problems. Whenever this
141 happens, a message is sent to the SQLite developers chatroom altering
142 them to the problem.
143
144 The recommended way to allow robots to send chat messages is to create
145 a new user on the server for each robot. Give each such robot account
146 the "C" privilege only. That means that the robot user account will be
147
--- www/chat.md
+++ www/chat.md
@@ -136,11 +136,11 @@
136 The [fossil chat send](/help?cmd=chat) can be used by project-specific
137 robots to send notifications to the chatroom. For example, on the
138 [SQLite project](https://sqlite.org/) (for which the Fossil chatroom
139 feature, and indeed all of Fossil, was invented) there are long-running
140 fuzz servers that sometimes run across obscure problems. Whenever this
141 happens, a message is sent to the SQLite developers chatroom alerting
142 them to the problem.
143
144 The recommended way to allow robots to send chat messages is to create
145 a new user on the server for each robot. Give each such robot account
146 the "C" privilege only. That means that the robot user account will be
147
+1 -1
--- www/defcsp.md
+++ www/defcsp.md
@@ -30,11 +30,11 @@
3030
style-src 'self' 'unsafe-inline';
3131
img-src * data:;
3232
</pre>
3333
3434
The default is recommended for most installations. However,
35
-the site administrators can overwrite this default DSP using the
35
+the site administrators can overwrite this default CSP using the
3636
[default-csp setting](/help?cmd=default-csp). For example,
3737
CSP restrictions can be completely disabled by setting the default-csp to:
3838
3939
<pre>
4040
default-src *;
4141
--- www/defcsp.md
+++ www/defcsp.md
@@ -30,11 +30,11 @@
30 style-src 'self' 'unsafe-inline';
31 img-src * data:;
32 </pre>
33
34 The default is recommended for most installations. However,
35 the site administrators can overwrite this default DSP using the
36 [default-csp setting](/help?cmd=default-csp). For example,
37 CSP restrictions can be completely disabled by setting the default-csp to:
38
39 <pre>
40 default-src *;
41
--- www/defcsp.md
+++ www/defcsp.md
@@ -30,11 +30,11 @@
30 style-src 'self' 'unsafe-inline';
31 img-src * data:;
32 </pre>
33
34 The default is recommended for most installations. However,
35 the site administrators can overwrite this default CSP using the
36 [default-csp setting](/help?cmd=default-csp). For example,
37 CSP restrictions can be completely disabled by setting the default-csp to:
38
39 <pre>
40 default-src *;
41
--- www/env-opts.md
+++ www/env-opts.md
@@ -26,10 +26,12 @@
2626
file names: insensitive on Windows, sensitive on Unix. There are
2727
probably odd interactions possible if you mix case sensitive and case
2828
insensitive file systems on any single platform. This option or the
2929
global setting should be used to force the case sensitivity to the
3030
most sensible condition.
31
+
32
+`--cgitrace`: Active CGI tracing.
3133
3234
`--chdir DIRECTORY`: Change to the named directory before processing
3335
any commands.
3436
3537
3638
--- www/env-opts.md
+++ www/env-opts.md
@@ -26,10 +26,12 @@
26 file names: insensitive on Windows, sensitive on Unix. There are
27 probably odd interactions possible if you mix case sensitive and case
28 insensitive file systems on any single platform. This option or the
29 global setting should be used to force the case sensitivity to the
30 most sensible condition.
 
 
31
32 `--chdir DIRECTORY`: Change to the named directory before processing
33 any commands.
34
35
36
--- www/env-opts.md
+++ www/env-opts.md
@@ -26,10 +26,12 @@
26 file names: insensitive on Windows, sensitive on Unix. There are
27 probably odd interactions possible if you mix case sensitive and case
28 insensitive file systems on any single platform. This option or the
29 global setting should be used to force the case sensitivity to the
30 most sensible condition.
31
32 `--cgitrace`: Active CGI tracing.
33
34 `--chdir DIRECTORY`: Change to the named directory before processing
35 any commands.
36
37
38
--- www/fossil_prompt.sh
+++ www/fossil_prompt.sh
@@ -1,6 +1,5 @@
1
-
21
#-------------------------------------------------------------------------
32
# get_fossil_data()
43
#
54
# If the current directory is part of a fossil checkout, then populate
65
# a series of global variables based on the current state of that
@@ -26,27 +25,20 @@
2625
#-------------------------------------------------------------------------
2726
# set_prompt()
2827
#
2928
# Set the PS1 variable. If the current directory is part of a fossil
3029
# checkout then the prompt contains information relating to the state
31
-# of the checkout.
30
+# of the checkout.
3231
#
3332
# Otherwise, if the current directory is not part of a fossil checkout, it
3433
# is set to a fairly standard bash prompt containing the host name, user
3534
# name and current directory.
3635
#
3736
function set_prompt() {
3837
get_fossil_data
39
- if [ -n "$fossil_info_project_name" ] ; then
40
- project=$fossil_info_project_name
41
- checkout=`echo $fossil_info_checkout | sed 's/^\(........\).*/\1/'`
42
- date=`echo $fossil_info_checkout | sed 's/^[^ ]* *..//' | sed 's/:[^:]*$//'`
43
- tags=$fossil_info_tags
44
- local_root=`echo $fossil_info_local_root | sed 's/\/$//'`
45
- local=`pwd | sed "s*${local_root}**" | sed "s/^$/\//"`
46
-
47
- # Color the first part of the prompt blue if this is a clean checkout.
38
+ if [ -n "$fossil_info_project_name" ] ; then
39
+ # Color the path part of the prompt blue if this is a clean checkout
4840
# Or red if it has been edited in any way at all. Set $c1 to the escape
4941
# sequence required to change the type to the required color. And $c2
5042
# to the sequence that changes it back.
5143
#
5244
if [ -n "`fossil chang`" ] ; then
@@ -53,13 +45,12 @@
5345
c1="\[\033[1;31m\]" # red
5446
else
5547
c1="\[\033[1;34m\]" # blue
5648
fi
5749
c2="\[\033[0m\]"
58
-
59
- PS1="$c1${project}.${tags}$c2 ${checkout} (${date}):${local}$c1\$$c2 "
50
+ PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:$c1\w\$$c2 "
6051
else
61
- PS1="\u@\h:\w\$ "
52
+ PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:\w\$ "
6253
fi
6354
}
6455
6556
PROMPT_COMMAND=set_prompt
6657
--- www/fossil_prompt.sh
+++ www/fossil_prompt.sh
@@ -1,6 +1,5 @@
1
2 #-------------------------------------------------------------------------
3 # get_fossil_data()
4 #
5 # If the current directory is part of a fossil checkout, then populate
6 # a series of global variables based on the current state of that
@@ -26,27 +25,20 @@
26 #-------------------------------------------------------------------------
27 # set_prompt()
28 #
29 # Set the PS1 variable. If the current directory is part of a fossil
30 # checkout then the prompt contains information relating to the state
31 # of the checkout.
32 #
33 # Otherwise, if the current directory is not part of a fossil checkout, it
34 # is set to a fairly standard bash prompt containing the host name, user
35 # name and current directory.
36 #
37 function set_prompt() {
38 get_fossil_data
39 if [ -n "$fossil_info_project_name" ] ; then
40 project=$fossil_info_project_name
41 checkout=`echo $fossil_info_checkout | sed 's/^\(........\).*/\1/'`
42 date=`echo $fossil_info_checkout | sed 's/^[^ ]* *..//' | sed 's/:[^:]*$//'`
43 tags=$fossil_info_tags
44 local_root=`echo $fossil_info_local_root | sed 's/\/$//'`
45 local=`pwd | sed "s*${local_root}**" | sed "s/^$/\//"`
46
47 # Color the first part of the prompt blue if this is a clean checkout.
48 # Or red if it has been edited in any way at all. Set $c1 to the escape
49 # sequence required to change the type to the required color. And $c2
50 # to the sequence that changes it back.
51 #
52 if [ -n "`fossil chang`" ] ; then
@@ -53,13 +45,12 @@
53 c1="\[\033[1;31m\]" # red
54 else
55 c1="\[\033[1;34m\]" # blue
56 fi
57 c2="\[\033[0m\]"
58
59 PS1="$c1${project}.${tags}$c2 ${checkout} (${date}):${local}$c1\$$c2 "
60 else
61 PS1="\u@\h:\w\$ "
62 fi
63 }
64
65 PROMPT_COMMAND=set_prompt
66
--- www/fossil_prompt.sh
+++ www/fossil_prompt.sh
@@ -1,6 +1,5 @@
 
1 #-------------------------------------------------------------------------
2 # get_fossil_data()
3 #
4 # If the current directory is part of a fossil checkout, then populate
5 # a series of global variables based on the current state of that
@@ -26,27 +25,20 @@
25 #-------------------------------------------------------------------------
26 # set_prompt()
27 #
28 # Set the PS1 variable. If the current directory is part of a fossil
29 # checkout then the prompt contains information relating to the state
30 # of the checkout.
31 #
32 # Otherwise, if the current directory is not part of a fossil checkout, it
33 # is set to a fairly standard bash prompt containing the host name, user
34 # name and current directory.
35 #
36 function set_prompt() {
37 get_fossil_data
38 if [ -n "$fossil_info_project_name" ] ; then
39 # Color the path part of the prompt blue if this is a clean checkout
 
 
 
 
 
 
 
40 # Or red if it has been edited in any way at all. Set $c1 to the escape
41 # sequence required to change the type to the required color. And $c2
42 # to the sequence that changes it back.
43 #
44 if [ -n "`fossil chang`" ] ; then
@@ -53,13 +45,12 @@
45 c1="\[\033[1;31m\]" # red
46 else
47 c1="\[\033[1;34m\]" # blue
48 fi
49 c2="\[\033[0m\]"
50 PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:$c1\w\$$c2 "
 
51 else
52 PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:\w\$ "
53 fi
54 }
55
56 PROMPT_COMMAND=set_prompt
57
+6 -1
--- www/globs.md
+++ www/globs.md
@@ -2,11 +2,16 @@
22
33
44
A [glob pattern][glob] is a text expression that matches one or more
55
file names using wild cards familiar to most users of a command line.
66
For example, `*` is a glob that matches any name at all and
7
-`Readme.txt` is a glob that matches exactly one file.
7
+`Readme.txt` is a glob that matches exactly one file. For purposes of
8
+Fossil's globs, a file name with a directory prefix is "just a string"
9
+and the globs do not apply any special meaning to the directory part
10
+of the name. Thus the glob `*` matches any name, including any
11
+directory prefix, and `*/*` matches a name with _one or more_
12
+directory components.
813
914
A glob should not be confused with a [regular expression][regexp] (RE),
1015
even though they use some of the same special characters for similar
1116
purposes, because [they are not fully compatible][greinc] pattern
1217
matching languages. Fossil uses globs when matching file names with the
1318
--- www/globs.md
+++ www/globs.md
@@ -2,11 +2,16 @@
2
3
4 A [glob pattern][glob] is a text expression that matches one or more
5 file names using wild cards familiar to most users of a command line.
6 For example, `*` is a glob that matches any name at all and
7 `Readme.txt` is a glob that matches exactly one file.
 
 
 
 
 
8
9 A glob should not be confused with a [regular expression][regexp] (RE),
10 even though they use some of the same special characters for similar
11 purposes, because [they are not fully compatible][greinc] pattern
12 matching languages. Fossil uses globs when matching file names with the
13
--- www/globs.md
+++ www/globs.md
@@ -2,11 +2,16 @@
2
3
4 A [glob pattern][glob] is a text expression that matches one or more
5 file names using wild cards familiar to most users of a command line.
6 For example, `*` is a glob that matches any name at all and
7 `Readme.txt` is a glob that matches exactly one file. For purposes of
8 Fossil's globs, a file name with a directory prefix is "just a string"
9 and the globs do not apply any special meaning to the directory part
10 of the name. Thus the glob `*` matches any name, including any
11 directory prefix, and `*/*` matches a name with _one or more_
12 directory components.
13
14 A glob should not be confused with a [regular expression][regexp] (RE),
15 even though they use some of the same special characters for similar
16 purposes, because [they are not fully compatible][greinc] pattern
17 matching languages. Fossil uses globs when matching file names with the
18
--- www/glossary.md
+++ www/glossary.md
@@ -298,7 +298,80 @@
298298
[h2cflp]: https://www.sqlite.org/howtocorrupt.html#_file_locking_problems
299299
[fpvsc]: https://marketplace.visualstudio.com/items?itemName=koog1000.fossil
300300
[open]: /help?cmd=open
301301
[mwd]: ./ckout-workflows.md#mcw
302302
[update]: /help?cmd=update
303
+
304
+
305
+## <a id="docs"></a>Embedded Documentation
306
+
307
+Serving as an alternative to Fossil’s built-in [wiki], the [embedded
308
+documentation feature][edoc] stores the same type of marked-up text
309
+files, but under Fossil’s powerful version control features.
310
+
311
+* The simple rule for determining whether to use the wiki or embedded
312
+ docs for any given document is whether the content is considered
313
+ “evergreen,” as with a Wikipedia article.
314
+
315
+ While Fossil’s wiki feature does store the history of each
316
+ document’s changes, Fossil always presents the current version of
317
+ the document unless you manually go out of your way to dig back into
318
+ the history. Then, having done so, links from that historical
319
+ version of the wiki document take you to the current versions of the
320
+ target documents, not to the version contemporaneous with the source
321
+ document.
322
+
323
+ The consequence is that if you say something like…
324
+
325
+ $ fossil up 2020-04-01
326
+ $ fossil ui --page wcontent
327
+
328
+ …you will **not** see the list of wiki articles as of April Fool’s Day in 2020, but
329
+ instead the list of *current* wiki article versions, the same as if you ran it
330
+ from a check-out of the tip-of-trunk.
331
+
332
+ Contrast embedded docs, which are not only version-controlled as
333
+ normal files are in Fossil, they participate in all the tagging,
334
+ branching, and other versioning features. There are several
335
+ consequences of this, such as that Fossil’s [special check-in
336
+ names][ciname] work with embedded doc URLs:
337
+
338
+ * <p>If you visit an embedded doc as `/doc/release/file.md` and
339
+ then click on a relative link from that document, you will remain on
340
+ the release branch. This lets you see not only the release
341
+ version of a software project but also the documentation as of
342
+ that release.</p>
343
+
344
+ * <p>If you visit `/doc/2020-04-01/file.md`, you will not only
345
+ pull up the version of `file.md` as of that date, relative links
346
+ will take you to contemporaneous versions of those embedded docs
347
+ as well.</p>
348
+
349
+ * <p>If you say `fossil up 2020-04-01 && fossil ui` and then visit
350
+ `/doc/ckout/file.md`, you’ll not only see the checked-out
351
+ version of the file as of that date, relative links will show
352
+ you other files within that checkout.</p>
353
+
354
+* Fossil’s wiki presents a flat list of articles, while embedded docs
355
+ are stored in the repository’s file hierarchy, a powerful
356
+ organizational tool well-suited to complicated documentation.
357
+
358
+* Your repository’s Home page is a good candidate for the wiki, as is
359
+ documentation meant for use only with the current version of the
360
+ repository’s contents.
361
+
362
+* If you are at all uncertain whether to use the wiki or the embedded
363
+ documentation feature, prefer the latter, since it is more powerful
364
+ and, with the addition of the [`/fileedit` feature][fef] in Fossil
365
+ 2.12, it’s nearly as easy to use.
366
+
367
+ (This very file is embedded documentation: clone
368
+ [Fossil’s self-hosting repository][fshr] and you will find it as
369
+ `www/glossary.md`.)
370
+
371
+[edoc]: ./embeddeddoc.wiki
372
+[fef]: ./fileedit-page.md
373
+[fshr]: ./selfhost.wiki
374
+[wiki]: ./wikitheory.wiki
375
+
303376
304377
<div style="height:50em" id="this-space-intentionally-left-blank"></div>
305378
--- www/glossary.md
+++ www/glossary.md
@@ -298,7 +298,80 @@
298 [h2cflp]: https://www.sqlite.org/howtocorrupt.html#_file_locking_problems
299 [fpvsc]: https://marketplace.visualstudio.com/items?itemName=koog1000.fossil
300 [open]: /help?cmd=open
301 [mwd]: ./ckout-workflows.md#mcw
302 [update]: /help?cmd=update
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
304 <div style="height:50em" id="this-space-intentionally-left-blank"></div>
305
--- www/glossary.md
+++ www/glossary.md
@@ -298,7 +298,80 @@
298 [h2cflp]: https://www.sqlite.org/howtocorrupt.html#_file_locking_problems
299 [fpvsc]: https://marketplace.visualstudio.com/items?itemName=koog1000.fossil
300 [open]: /help?cmd=open
301 [mwd]: ./ckout-workflows.md#mcw
302 [update]: /help?cmd=update
303
304
305 ## <a id="docs"></a>Embedded Documentation
306
307 Serving as an alternative to Fossil’s built-in [wiki], the [embedded
308 documentation feature][edoc] stores the same type of marked-up text
309 files, but under Fossil’s powerful version control features.
310
311 * The simple rule for determining whether to use the wiki or embedded
312 docs for any given document is whether the content is considered
313 “evergreen,” as with a Wikipedia article.
314
315 While Fossil’s wiki feature does store the history of each
316 document’s changes, Fossil always presents the current version of
317 the document unless you manually go out of your way to dig back into
318 the history. Then, having done so, links from that historical
319 version of the wiki document take you to the current versions of the
320 target documents, not to the version contemporaneous with the source
321 document.
322
323 The consequence is that if you say something like…
324
325 $ fossil up 2020-04-01
326 $ fossil ui --page wcontent
327
328 …you will **not** see the list of wiki articles as of April Fool’s Day in 2020, but
329 instead the list of *current* wiki article versions, the same as if you ran it
330 from a check-out of the tip-of-trunk.
331
332 Contrast embedded docs, which are not only version-controlled as
333 normal files are in Fossil, they participate in all the tagging,
334 branching, and other versioning features. There are several
335 consequences of this, such as that Fossil’s [special check-in
336 names][ciname] work with embedded doc URLs:
337
338 * <p>If you visit an embedded doc as `/doc/release/file.md` and
339 then click on a relative link from that document, you will remain on
340 the release branch. This lets you see not only the release
341 version of a software project but also the documentation as of
342 that release.</p>
343
344 * <p>If you visit `/doc/2020-04-01/file.md`, you will not only
345 pull up the version of `file.md` as of that date, relative links
346 will take you to contemporaneous versions of those embedded docs
347 as well.</p>
348
349 * <p>If you say `fossil up 2020-04-01 && fossil ui` and then visit
350 `/doc/ckout/file.md`, you’ll not only see the checked-out
351 version of the file as of that date, relative links will show
352 you other files within that checkout.</p>
353
354 * Fossil’s wiki presents a flat list of articles, while embedded docs
355 are stored in the repository’s file hierarchy, a powerful
356 organizational tool well-suited to complicated documentation.
357
358 * Your repository’s Home page is a good candidate for the wiki, as is
359 documentation meant for use only with the current version of the
360 repository’s contents.
361
362 * If you are at all uncertain whether to use the wiki or the embedded
363 documentation feature, prefer the latter, since it is more powerful
364 and, with the addition of the [`/fileedit` feature][fef] in Fossil
365 2.12, it’s nearly as easy to use.
366
367 (This very file is embedded documentation: clone
368 [Fossil’s self-hosting repository][fshr] and you will find it as
369 `www/glossary.md`.)
370
371 [edoc]: ./embeddeddoc.wiki
372 [fef]: ./fileedit-page.md
373 [fshr]: ./selfhost.wiki
374 [wiki]: ./wikitheory.wiki
375
376
377 <div style="height:50em" id="this-space-intentionally-left-blank"></div>
378
+34 -25
--- www/grep.md
+++ www/grep.md
@@ -1,58 +1,67 @@
11
# Fossil grep vs POSIX grep
22
33
As of Fossil 2.7, there is a `grep` command which acts roughly like
4
-POSIX's `grep -E` over all historical versions of a single file name.
4
+POSIX's `grep -E` over all historical versions of one or more managed files.
55
This document explains the commonalities and divergences between [POSIX
66
`grep`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html)
77
and Fossil `grep`.
88
99
1010
## Options
1111
12
-Fossil `grep` supports only a small subset of the options specified for
12
+Fossil `grep` implements about half of the options specified for
1313
POSIX `grep`:
1414
1515
| Option | Meaning
1616
|--------|-------------------------------------------------------------
17
+| `-c` | report the count of matches rather than the matched text
1718
| `-i` | ignore case in matches
1819
| `-l` | list a checkin ID prefix for matching historical versions of the file
19
-| `-v` | print each checkin ID considered, regardless of whether it matches
20
-
21
-That leaves many divergences at the option level from POSIX `grep`:
22
-
23
-* There is no built-in way to get a count of matches, as with
24
- `grep -c`.
25
-
26
-* You cannot give more than one pattern, as with `grep -e` or
27
- `grep -f`.
20
+| `-q` | no output; return only a status code indicating the success of the match
21
+| `-s` | suppress error output about missing files
22
+| `-v` | invert the sense of the match
23
+
24
+That leaves several divergences at the option level from POSIX `grep`:
25
+
26
+* You cannot give more than one pattern, as with `grep -e` or
27
+ `grep -f`.
2828
2929
* There is no equivalent of `grep -F` to do literal fixed-string
3030
matches only.
31
+
32
+* There is no `-x` option for doing a whole-line match.
3133
3234
* `fossil grep -l` does not do precisely the same thing as POSIX
3335
`grep -l`: it lists checkin ID prefixes, not file names.
3436
3537
* Fossil always gives the line number in its output, which is to say
3638
that it acts like `grep -n`. There is no way to disable the line
3739
number in `fossil grep` output.
3840
39
-* There is no way to suppress all output, returning only a status code
40
- to indicate whether the pattern matched, as with `grep -q`.
41
-
42
-* There is no way to suppress error output, as with `grep -s`.
43
-
44
-* Fossil `grep` does not accept a directory name for Fossil to
45
- expand to the set of all files under that directory. This means
46
- Fossil `grep` has no equivalent of the common POSIX `grep -R`
47
- extension. (And if it did, it would probably have a different
48
- option letter, since `-R` in Fossil has a different meaning, by
49
- convention.)
50
-
51
-* You cannot invert the match, as with `grep -v`.
52
-
5341
Patches to remove those limitations will be thoughtfully considered.
42
+
43
+Fossil `grep` doesn’t support any of the GNU and BSD `grep` extensions.
44
+For instance, it doesn’t support the common `-R` extension to POSIX,
45
+which would presumably search a subtree of managed files. If Fossil does
46
+one day get this feature, it would have a different option letter, since
47
+`-R` in Fossil has a different meaning, by convention. Until then, you
48
+can get the same effect on systems with a POSIX shell like so:
49
+
50
+ $ fossil grep COMMAND: $(fossil ls src)
51
+
52
+If you run that in a check-out of the [Fossil self-hosting source
53
+repository][fshsr], that returns the first line of the built-in
54
+documentation for each Fossil command, across all historical verisons.
55
+
56
+Fossil `grep` has extensions relative to these other `grep` standards,
57
+such as `--verbose` to print each checkin ID considered, regardless of
58
+whether it matches. This one is noteworthy here because the behavior
59
+used to be under `-v` before we reassigned it to give POSIX-like `grep
60
+-v` behavior.
61
+
62
+[fshsr]: ./selfhost.wiki
5463
5564
5665
## Regular Expression Dialect
5766
5867
Fossil contains a built-in regular expression engine implementing a
5968
--- www/grep.md
+++ www/grep.md
@@ -1,58 +1,67 @@
1 # Fossil grep vs POSIX grep
2
3 As of Fossil 2.7, there is a `grep` command which acts roughly like
4 POSIX's `grep -E` over all historical versions of a single file name.
5 This document explains the commonalities and divergences between [POSIX
6 `grep`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html)
7 and Fossil `grep`.
8
9
10 ## Options
11
12 Fossil `grep` supports only a small subset of the options specified for
13 POSIX `grep`:
14
15 | Option | Meaning
16 |--------|-------------------------------------------------------------
 
17 | `-i` | ignore case in matches
18 | `-l` | list a checkin ID prefix for matching historical versions of the file
19 | `-v` | print each checkin ID considered, regardless of whether it matches
20
21 That leaves many divergences at the option level from POSIX `grep`:
22
23 * There is no built-in way to get a count of matches, as with
24 `grep -c`.
25
26 * You cannot give more than one pattern, as with `grep -e` or
27 `grep -f`.
28
29 * There is no equivalent of `grep -F` to do literal fixed-string
30 matches only.
 
 
31
32 * `fossil grep -l` does not do precisely the same thing as POSIX
33 `grep -l`: it lists checkin ID prefixes, not file names.
34
35 * Fossil always gives the line number in its output, which is to say
36 that it acts like `grep -n`. There is no way to disable the line
37 number in `fossil grep` output.
38
39 * There is no way to suppress all output, returning only a status code
40 to indicate whether the pattern matched, as with `grep -q`.
41
42 * There is no way to suppress error output, as with `grep -s`.
43
44 * Fossil `grep` does not accept a directory name for Fossil to
45 expand to the set of all files under that directory. This means
46 Fossil `grep` has no equivalent of the common POSIX `grep -R`
47 extension. (And if it did, it would probably have a different
48 option letter, since `-R` in Fossil has a different meaning, by
49 convention.)
50
51 * You cannot invert the match, as with `grep -v`.
52
53 Patches to remove those limitations will be thoughtfully considered.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
55
56 ## Regular Expression Dialect
57
58 Fossil contains a built-in regular expression engine implementing a
59
--- www/grep.md
+++ www/grep.md
@@ -1,58 +1,67 @@
1 # Fossil grep vs POSIX grep
2
3 As of Fossil 2.7, there is a `grep` command which acts roughly like
4 POSIX's `grep -E` over all historical versions of one or more managed files.
5 This document explains the commonalities and divergences between [POSIX
6 `grep`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html)
7 and Fossil `grep`.
8
9
10 ## Options
11
12 Fossil `grep` implements about half of the options specified for
13 POSIX `grep`:
14
15 | Option | Meaning
16 |--------|-------------------------------------------------------------
17 | `-c` | report the count of matches rather than the matched text
18 | `-i` | ignore case in matches
19 | `-l` | list a checkin ID prefix for matching historical versions of the file
20 | `-q` | no output; return only a status code indicating the success of the match
21 | `-s` | suppress error output about missing files
22 | `-v` | invert the sense of the match
23
24 That leaves several divergences at the option level from POSIX `grep`:
25
26 * You cannot give more than one pattern, as with `grep -e` or
27 `grep -f`.
 
28
29 * There is no equivalent of `grep -F` to do literal fixed-string
30 matches only.
31
32 * There is no `-x` option for doing a whole-line match.
33
34 * `fossil grep -l` does not do precisely the same thing as POSIX
35 `grep -l`: it lists checkin ID prefixes, not file names.
36
37 * Fossil always gives the line number in its output, which is to say
38 that it acts like `grep -n`. There is no way to disable the line
39 number in `fossil grep` output.
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41 Patches to remove those limitations will be thoughtfully considered.
42
43 Fossil `grep` doesn’t support any of the GNU and BSD `grep` extensions.
44 For instance, it doesn’t support the common `-R` extension to POSIX,
45 which would presumably search a subtree of managed files. If Fossil does
46 one day get this feature, it would have a different option letter, since
47 `-R` in Fossil has a different meaning, by convention. Until then, you
48 can get the same effect on systems with a POSIX shell like so:
49
50 $ fossil grep COMMAND: $(fossil ls src)
51
52 If you run that in a check-out of the [Fossil self-hosting source
53 repository][fshsr], that returns the first line of the built-in
54 documentation for each Fossil command, across all historical verisons.
55
56 Fossil `grep` has extensions relative to these other `grep` standards,
57 such as `--verbose` to print each checkin ID considered, regardless of
58 whether it matches. This one is noteworthy here because the behavior
59 used to be under `-v` before we reassigned it to give POSIX-like `grep
60 -v` behavior.
61
62 [fshsr]: ./selfhost.wiki
63
64
65 ## Regular Expression Dialect
66
67 Fossil contains a built-in regular expression engine implementing a
68
+4 -4
--- www/index.wiki
+++ www/index.wiki
@@ -83,16 +83,16 @@
8383
the repository are consistent prior to each commit.
8484
8585
8. <b>Free and Open-Source</b> - [../COPYRIGHT-BSD2.txt|2-clause BSD license].
8686
8787
<hr>
88
-<h3>Latest Release: 2.17 ([/timeline?c=version-2.17|2021-10-09])</h3>
88
+<h3>Latest Release: 2.18 ([/timeline?c=version-2.18|2022-02-23])</h3>
8989
9090
* [/uv/download.html|Download]
91
- * [./changes.wiki#v2_17|Change Summary]
92
- * [/timeline?p=version-2.17&bt=version-2.16&y=ci|Check-ins in version 2.17]
93
- * [/timeline?df=version-2.17&y=ci|Check-ins derived from the 2.17 release]
91
+ * [./changes.wiki#v2_18|Change Summary]
92
+ * [/timeline?p=version-2.18&bt=version-2.17&y=ci|Check-ins in version 2.18]
93
+ * [/timeline?df=version-2.18&y=ci|Check-ins derived from the 2.18 release]
9494
* [/timeline?t=release|Timeline of all past releases]
9595
9696
<hr>
9797
<h3>Quick Start</h3>
9898
9999
--- www/index.wiki
+++ www/index.wiki
@@ -83,16 +83,16 @@
83 the repository are consistent prior to each commit.
84
85 8. <b>Free and Open-Source</b> - [../COPYRIGHT-BSD2.txt|2-clause BSD license].
86
87 <hr>
88 <h3>Latest Release: 2.17 ([/timeline?c=version-2.17|2021-10-09])</h3>
89
90 * [/uv/download.html|Download]
91 * [./changes.wiki#v2_17|Change Summary]
92 * [/timeline?p=version-2.17&bt=version-2.16&y=ci|Check-ins in version 2.17]
93 * [/timeline?df=version-2.17&y=ci|Check-ins derived from the 2.17 release]
94 * [/timeline?t=release|Timeline of all past releases]
95
96 <hr>
97 <h3>Quick Start</h3>
98
99
--- www/index.wiki
+++ www/index.wiki
@@ -83,16 +83,16 @@
83 the repository are consistent prior to each commit.
84
85 8. <b>Free and Open-Source</b> - [../COPYRIGHT-BSD2.txt|2-clause BSD license].
86
87 <hr>
88 <h3>Latest Release: 2.18 ([/timeline?c=version-2.18|2022-02-23])</h3>
89
90 * [/uv/download.html|Download]
91 * [./changes.wiki#v2_18|Change Summary]
92 * [/timeline?p=version-2.18&bt=version-2.17&y=ci|Check-ins in version 2.18]
93 * [/timeline?df=version-2.18&y=ci|Check-ins derived from the 2.18 release]
94 * [/timeline?t=release|Timeline of all past releases]
95
96 <hr>
97 <h3>Quick Start</h3>
98
99
--- www/json-api/api-wiki.md
+++ www/json-api/api-wiki.md
@@ -166,10 +166,13 @@
166166
- `name=string` specifies the page name.
167167
- `content=string` is the body text.\
168168
Content is required for save (unless `createIfNotExists` is true *and*
169169
the page does not exist), optional for create. It *may* be an empty
170170
string.
171
+- `mimetype=string` specifies the mimetype for the body, noting any any
172
+ unrecognized/unsupported mimetype is silently treated as
173
+ `text/x-fossil-wiki`.
171174
- Save (not create) supports a `createIfNotExists` boolean option which
172175
makes it a functional superset of the create/save features. i.e. it
173176
will create if needed, else it will update. If createIfNotExists is
174177
false (the default) then save will fail if given a page name which
175178
does not refer to an existing page.
@@ -179,10 +182,11 @@
179182
high-priority addition. See:\
180183
[](/doc/trunk/www/fileformat.wiki#wikichng)
181184
- **Potential TODO:** we *could* optionally also support
182185
multi-page saving using an array of pages in the request payload:\
183186
`[… page objects … ]`
187
+
184188
185189
186190
<a id="diffs"></a>
187191
# Wiki Diffs
188192
@@ -238,28 +242,29 @@
238242
239243
This command wiki-processes arbitrary text sent from the client. To help
240244
curb potential abuse, its use is restricted to those with "k" access
241245
rights.
242246
243
-The `POST.payload` property must be a string containing Fossil wiki
244
-markup. The response payload is also a string, but contains the
245
-HTML-processed form of the string. Whether or not "all HTML" is allowed
246
-depends on site-level configuration options, and that changes how the
247
-input is processed.
247
+The `POST.payload` property must be either:
248
+
249
+1) A string containing Fossil wiki markup.
250
+
251
+2) An Object with a `body` property holding the text to render and a
252
+ `mimetype` property describing the wiki format:
253
+ `text/x-fossil-wiki` (the default), `text/x-markdown`, or
254
+ `text/plain`. Any unknown type is treated as `text/x-fossil-wiki`.
255
+
256
+The response payload is a string containing the rendered page. Whether
257
+or not "all HTML" is allowed depends on site-level configuration
258
+options, and that changes how the input is processed.
248259
249260
Note that the links in the generated page are for the HTML interface,
250261
and will not work as-is for arbitrary JSON clients. In order to
251262
integrate the parsed content with JSON-based clients the HTML will
252263
probably need to be post-processed, e.g. using jQuery to fish out the
253264
links and re-map wiki page links to a JSON-capable page handler.
254265
255
-**TODO**: Update this to accept the other two wiki formats (which
256
-didn't exist when this API was implemented): markdown and plain text
257
-(which gets HTML-ized for preview purposes). That requires changing
258
-the payload to an object, perhaps simply submitting the same thing as
259
-`/json/save`. There's no reason we can't support both call forms.
260
-
261266
262267
<a id="todo"></a>
263268
# Notes and TODOs
264269
265270
- When server-parsing the wiki content, the generated
266271
--- www/json-api/api-wiki.md
+++ www/json-api/api-wiki.md
@@ -166,10 +166,13 @@
166 - `name=string` specifies the page name.
167 - `content=string` is the body text.\
168 Content is required for save (unless `createIfNotExists` is true *and*
169 the page does not exist), optional for create. It *may* be an empty
170 string.
 
 
 
171 - Save (not create) supports a `createIfNotExists` boolean option which
172 makes it a functional superset of the create/save features. i.e. it
173 will create if needed, else it will update. If createIfNotExists is
174 false (the default) then save will fail if given a page name which
175 does not refer to an existing page.
@@ -179,10 +182,11 @@
179 high-priority addition. See:\
180 [](/doc/trunk/www/fileformat.wiki#wikichng)
181 - **Potential TODO:** we *could* optionally also support
182 multi-page saving using an array of pages in the request payload:\
183 `[… page objects … ]`
 
184
185
186 <a id="diffs"></a>
187 # Wiki Diffs
188
@@ -238,28 +242,29 @@
238
239 This command wiki-processes arbitrary text sent from the client. To help
240 curb potential abuse, its use is restricted to those with "k" access
241 rights.
242
243 The `POST.payload` property must be a string containing Fossil wiki
244 markup. The response payload is also a string, but contains the
245 HTML-processed form of the string. Whether or not "all HTML" is allowed
246 depends on site-level configuration options, and that changes how the
247 input is processed.
 
 
 
 
 
 
 
248
249 Note that the links in the generated page are for the HTML interface,
250 and will not work as-is for arbitrary JSON clients. In order to
251 integrate the parsed content with JSON-based clients the HTML will
252 probably need to be post-processed, e.g. using jQuery to fish out the
253 links and re-map wiki page links to a JSON-capable page handler.
254
255 **TODO**: Update this to accept the other two wiki formats (which
256 didn't exist when this API was implemented): markdown and plain text
257 (which gets HTML-ized for preview purposes). That requires changing
258 the payload to an object, perhaps simply submitting the same thing as
259 `/json/save`. There's no reason we can't support both call forms.
260
261
262 <a id="todo"></a>
263 # Notes and TODOs
264
265 - When server-parsing the wiki content, the generated
266
--- www/json-api/api-wiki.md
+++ www/json-api/api-wiki.md
@@ -166,10 +166,13 @@
166 - `name=string` specifies the page name.
167 - `content=string` is the body text.\
168 Content is required for save (unless `createIfNotExists` is true *and*
169 the page does not exist), optional for create. It *may* be an empty
170 string.
171 - `mimetype=string` specifies the mimetype for the body, noting any any
172 unrecognized/unsupported mimetype is silently treated as
173 `text/x-fossil-wiki`.
174 - Save (not create) supports a `createIfNotExists` boolean option which
175 makes it a functional superset of the create/save features. i.e. it
176 will create if needed, else it will update. If createIfNotExists is
177 false (the default) then save will fail if given a page name which
178 does not refer to an existing page.
@@ -179,10 +182,11 @@
182 high-priority addition. See:\
183 [](/doc/trunk/www/fileformat.wiki#wikichng)
184 - **Potential TODO:** we *could* optionally also support
185 multi-page saving using an array of pages in the request payload:\
186 `[… page objects … ]`
187
188
189
190 <a id="diffs"></a>
191 # Wiki Diffs
192
@@ -238,28 +242,29 @@
242
243 This command wiki-processes arbitrary text sent from the client. To help
244 curb potential abuse, its use is restricted to those with "k" access
245 rights.
246
247 The `POST.payload` property must be either:
248
249 1) A string containing Fossil wiki markup.
250
251 2) An Object with a `body` property holding the text to render and a
252 `mimetype` property describing the wiki format:
253 `text/x-fossil-wiki` (the default), `text/x-markdown`, or
254 `text/plain`. Any unknown type is treated as `text/x-fossil-wiki`.
255
256 The response payload is a string containing the rendered page. Whether
257 or not "all HTML" is allowed depends on site-level configuration
258 options, and that changes how the input is processed.
259
260 Note that the links in the generated page are for the HTML interface,
261 and will not work as-is for arbitrary JSON clients. In order to
262 integrate the parsed content with JSON-based clients the HTML will
263 probably need to be post-processed, e.g. using jQuery to fish out the
264 links and re-map wiki page links to a JSON-capable page handler.
265
 
 
 
 
 
 
266
267 <a id="todo"></a>
268 # Notes and TODOs
269
270 - When server-parsing the wiki content, the generated
271
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -62,25 +62,25 @@
6262
files.
6363
6464
The VERSION.h header file is generated from other information sources
6565
using a small program called:
6666
67
- 11. [/file/src/mkversion.c | mkversion.c]
67
+ 11. [/file/tools/mkversion.c | mkversion.c]
6868
6969
The builtin_data.h header file contains the definitions of C-language
7070
byte-array constants that contain various resources such as scripts and
7171
images. The builtin_data.h header file is generate from the original
7272
resource files using a small program called:
7373
74
- 12 [/file/src/mkbuiltin.c | mkbuiltin.c]
74
+ 12 [/file/tools/mkbuiltin.c | mkbuiltin.c]
7575
7676
Examples of built-in resources include the [/file/src/diff.tcl | diff.tcl]
7777
script used to implement the --tk option to [/help?cmd=diff| fossil diff],
7878
the [/file/src/markdown.md | markdown documentation], and the various
7979
CSS scripts, headers, and footers used to implement built-in skins. New
8080
resources files are added to the "extra_files" variable in
81
-[/file/src/makemake.tcl | makemake.tcl].
81
+[/file/tools/makemake.tcl | makemake.tcl].
8282
8383
The src/ subdirectory also contains documentation about the
8484
makeheaders preprocessor program:
8585
8686
13. [../tools/makeheaders.html | makeheaders.html]
@@ -91,15 +91,15 @@
9191
14. makemake.tcl
9292
9393
Running this Tcl script will automatically regenerate all makefiles.
9494
In order to add a new source file to the Fossil implementation, simply
9595
edit makemake.tcl to add the new filename, then rerun the script, and
96
-all of the makefiles for all targets will be rebuild.
96
+all of the makefiles for all targets will be rebuilt.
9797
9898
There is an optional code verification step implemented using
9999
100
- 15. [/file/src/codecheck1.c | codecheck1.c]
100
+ 15. [/file/tools/codecheck1.c | codecheck1.c]
101101
102102
This file implements a small utility program ("codecheck1")
103103
that scans other Fossil source files looking for errors in printf-style
104104
format strings.
105105
The codecheck1 utility detects missing or surplus arguments on
@@ -141,12 +141,12 @@
141141
(The "manifest" and "manifest.uuid" files are automatically generated and
142142
updated by Fossil itself. See the [/help/setting | fossil set manifest]
143143
command for additional information.)
144144
145145
The VERSION.h header file is generated by
146
-a C program: src/mkversion.c.
147
-To run the VERSION.h generator, first compile the src/mkversion.c
146
+a C program: tools/mkversion.c.
147
+To run the VERSION.h generator, first compile the tools/mkversion.c
148148
source file into a command-line program (named "mkversion.exe")
149149
then run:
150150
151151
<blockquote><pre>
152152
mkversion.exe manifest.uuid manifest VERSION &gt;VERSION.h
@@ -156,11 +156,11 @@
156156
directories right. The point is that the manifest.uuid, manifest, and
157157
VERSION files
158158
in the root of the source tree are the three arguments and
159159
the generated VERSION.h file appears on standard output.
160160
161
-The builtin_data.h header file is generated by a C program: src/mkbuiltin.c.
161
+The builtin_data.h header file is generated by a C program: tools/mkbuiltin.c.
162162
The builtin_data.h file contains C-language byte-array definitions for
163163
the content of resource files used by Fossil. To generate the
164164
builtin_data.h file, first compile the mkbuiltin.c program, then run:
165165
166166
<blockquote><pre>
167167
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -62,25 +62,25 @@
62 files.
63
64 The VERSION.h header file is generated from other information sources
65 using a small program called:
66
67 11. [/file/src/mkversion.c | mkversion.c]
68
69 The builtin_data.h header file contains the definitions of C-language
70 byte-array constants that contain various resources such as scripts and
71 images. The builtin_data.h header file is generate from the original
72 resource files using a small program called:
73
74 12 [/file/src/mkbuiltin.c | mkbuiltin.c]
75
76 Examples of built-in resources include the [/file/src/diff.tcl | diff.tcl]
77 script used to implement the --tk option to [/help?cmd=diff| fossil diff],
78 the [/file/src/markdown.md | markdown documentation], and the various
79 CSS scripts, headers, and footers used to implement built-in skins. New
80 resources files are added to the "extra_files" variable in
81 [/file/src/makemake.tcl | makemake.tcl].
82
83 The src/ subdirectory also contains documentation about the
84 makeheaders preprocessor program:
85
86 13. [../tools/makeheaders.html | makeheaders.html]
@@ -91,15 +91,15 @@
91 14. makemake.tcl
92
93 Running this Tcl script will automatically regenerate all makefiles.
94 In order to add a new source file to the Fossil implementation, simply
95 edit makemake.tcl to add the new filename, then rerun the script, and
96 all of the makefiles for all targets will be rebuild.
97
98 There is an optional code verification step implemented using
99
100 15. [/file/src/codecheck1.c | codecheck1.c]
101
102 This file implements a small utility program ("codecheck1")
103 that scans other Fossil source files looking for errors in printf-style
104 format strings.
105 The codecheck1 utility detects missing or surplus arguments on
@@ -141,12 +141,12 @@
141 (The "manifest" and "manifest.uuid" files are automatically generated and
142 updated by Fossil itself. See the [/help/setting | fossil set manifest]
143 command for additional information.)
144
145 The VERSION.h header file is generated by
146 a C program: src/mkversion.c.
147 To run the VERSION.h generator, first compile the src/mkversion.c
148 source file into a command-line program (named "mkversion.exe")
149 then run:
150
151 <blockquote><pre>
152 mkversion.exe manifest.uuid manifest VERSION &gt;VERSION.h
@@ -156,11 +156,11 @@
156 directories right. The point is that the manifest.uuid, manifest, and
157 VERSION files
158 in the root of the source tree are the three arguments and
159 the generated VERSION.h file appears on standard output.
160
161 The builtin_data.h header file is generated by a C program: src/mkbuiltin.c.
162 The builtin_data.h file contains C-language byte-array definitions for
163 the content of resource files used by Fossil. To generate the
164 builtin_data.h file, first compile the mkbuiltin.c program, then run:
165
166 <blockquote><pre>
167
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -62,25 +62,25 @@
62 files.
63
64 The VERSION.h header file is generated from other information sources
65 using a small program called:
66
67 11. [/file/tools/mkversion.c | mkversion.c]
68
69 The builtin_data.h header file contains the definitions of C-language
70 byte-array constants that contain various resources such as scripts and
71 images. The builtin_data.h header file is generate from the original
72 resource files using a small program called:
73
74 12 [/file/tools/mkbuiltin.c | mkbuiltin.c]
75
76 Examples of built-in resources include the [/file/src/diff.tcl | diff.tcl]
77 script used to implement the --tk option to [/help?cmd=diff| fossil diff],
78 the [/file/src/markdown.md | markdown documentation], and the various
79 CSS scripts, headers, and footers used to implement built-in skins. New
80 resources files are added to the "extra_files" variable in
81 [/file/tools/makemake.tcl | makemake.tcl].
82
83 The src/ subdirectory also contains documentation about the
84 makeheaders preprocessor program:
85
86 13. [../tools/makeheaders.html | makeheaders.html]
@@ -91,15 +91,15 @@
91 14. makemake.tcl
92
93 Running this Tcl script will automatically regenerate all makefiles.
94 In order to add a new source file to the Fossil implementation, simply
95 edit makemake.tcl to add the new filename, then rerun the script, and
96 all of the makefiles for all targets will be rebuilt.
97
98 There is an optional code verification step implemented using
99
100 15. [/file/tools/codecheck1.c | codecheck1.c]
101
102 This file implements a small utility program ("codecheck1")
103 that scans other Fossil source files looking for errors in printf-style
104 format strings.
105 The codecheck1 utility detects missing or surplus arguments on
@@ -141,12 +141,12 @@
141 (The "manifest" and "manifest.uuid" files are automatically generated and
142 updated by Fossil itself. See the [/help/setting | fossil set manifest]
143 command for additional information.)
144
145 The VERSION.h header file is generated by
146 a C program: tools/mkversion.c.
147 To run the VERSION.h generator, first compile the tools/mkversion.c
148 source file into a command-line program (named "mkversion.exe")
149 then run:
150
151 <blockquote><pre>
152 mkversion.exe manifest.uuid manifest VERSION &gt;VERSION.h
@@ -156,11 +156,11 @@
156 directories right. The point is that the manifest.uuid, manifest, and
157 VERSION files
158 in the root of the source tree are the three arguments and
159 the generated VERSION.h file appears on standard output.
160
161 The builtin_data.h header file is generated by a C program: tools/mkbuiltin.c.
162 The builtin_data.h file contains C-language byte-array definitions for
163 the content of resource files used by Fossil. To generate the
164 builtin_data.h file, first compile the mkbuiltin.c program, then run:
165
166 <blockquote><pre>
167
+1 -1
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -14,11 +14,11 @@
1414
aboutcgi.wiki {How CGI Works In Fossil}
1515
aboutdownload.wiki {How The Download Page Works}
1616
adding_code.wiki {Adding New Features To Fossil}
1717
adding_code.wiki {Hacking Fossil}
1818
alerts.md {Email Alerts And Notifications}
19
- antibot.wiki {Defense against Spiders and Bots}
19
+ antibot.wiki {Defense against Spiders and Robots}
2020
backoffice.md {The "Backoffice" mechanism of Fossil}
2121
backup.md {Backing Up a Remote Fossil Repository}
2222
blame.wiki {The Annotate/Blame Algorithm Of Fossil}
2323
blockchain.md {Is Fossil A Blockchain?}
2424
branching.wiki {Branching, Forking, Merging, and Tagging}
2525
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -14,11 +14,11 @@
14 aboutcgi.wiki {How CGI Works In Fossil}
15 aboutdownload.wiki {How The Download Page Works}
16 adding_code.wiki {Adding New Features To Fossil}
17 adding_code.wiki {Hacking Fossil}
18 alerts.md {Email Alerts And Notifications}
19 antibot.wiki {Defense against Spiders and Bots}
20 backoffice.md {The "Backoffice" mechanism of Fossil}
21 backup.md {Backing Up a Remote Fossil Repository}
22 blame.wiki {The Annotate/Blame Algorithm Of Fossil}
23 blockchain.md {Is Fossil A Blockchain?}
24 branching.wiki {Branching, Forking, Merging, and Tagging}
25
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -14,11 +14,11 @@
14 aboutcgi.wiki {How CGI Works In Fossil}
15 aboutdownload.wiki {How The Download Page Works}
16 adding_code.wiki {Adding New Features To Fossil}
17 adding_code.wiki {Hacking Fossil}
18 alerts.md {Email Alerts And Notifications}
19 antibot.wiki {Defense against Spiders and Robots}
20 backoffice.md {The "Backoffice" mechanism of Fossil}
21 backup.md {Backing Up a Remote Fossil Repository}
22 blame.wiki {The Annotate/Blame Algorithm Of Fossil}
23 blockchain.md {Is Fossil A Blockchain?}
24 branching.wiki {Branching, Forking, Merging, and Tagging}
25
--- www/server/macos/service.md
+++ www/server/macos/service.md
@@ -16,11 +16,11 @@
1616
However, we will still give two different configurations, just as in the
1717
`systemd` article: one for a standalone HTTP server, and one using
1818
socket activation.
1919
2020
For more information on `launchd`, the single best resource we’ve found
21
-is [](launchd.info). The next best is:
21
+is [launchd.info](https://launchd.info). The next best is:
2222
2323
$ man launchd.plist
2424
2525
[la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/
2626
[ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
2727
--- www/server/macos/service.md
+++ www/server/macos/service.md
@@ -16,11 +16,11 @@
16 However, we will still give two different configurations, just as in the
17 `systemd` article: one for a standalone HTTP server, and one using
18 socket activation.
19
20 For more information on `launchd`, the single best resource we’ve found
21 is [](launchd.info). The next best is:
22
23 $ man launchd.plist
24
25 [la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/
26 [ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
27
--- www/server/macos/service.md
+++ www/server/macos/service.md
@@ -16,11 +16,11 @@
16 However, we will still give two different configurations, just as in the
17 `systemd` article: one for a standalone HTTP server, and one using
18 socket activation.
19
20 For more information on `launchd`, the single best resource we’ve found
21 is [launchd.info](https://launchd.info). The next best is:
22
23 $ man launchd.plist
24
25 [la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/
26 [ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
27
+6 -5
--- www/ssl.wiki
+++ www/ssl.wiki
@@ -227,15 +227,16 @@
227227
228228
229229
<h2 id="server">Fossil TLS Configuration: Server Side</h2>
230230
231231
Fossil's built-in HTTP server feature did not add [./ssl-server.md|support HTTP over TLS]
232
-(a.k.a. HTTPS) until version 2.18 (2022). Prior to that, system administrators
233
-that wanted to add HTTPS support to a Fossil server had to put Fossil
234
-behind a web-server or reverse-proxy that would do the HTTPS to HTTP
235
-translation. [./server/ | Instructions for doing so] are found elsewhere
236
-in this documentation. A few of the most useful of these are:
232
+(a.k.a. HTTPS) until version 2.18 (early 2022). Prior to that, system
233
+administrators that wanted to add HTTPS support to a Fossil server had
234
+to put Fossil behind a web-server or reverse-proxy that would do the
235
+HTTPS to HTTP translation. [./server/ | Instructions for doing so]
236
+are found elsewhere in this documentation. A few of the most useful
237
+of these are:
237238
238239
* <a id="stunnel" href="./server/any/stunnel.md">Serving via stunnel</a>
239240
* <a id="althttpd" href="./server/any/althttpd.md">Serving via stunnel + althttpd</a>
240241
* <a id="nginx" href="./server/debian/nginx.md#tls">Serving via SCGI with nginx on Debian</a>
241242
242243
--- www/ssl.wiki
+++ www/ssl.wiki
@@ -227,15 +227,16 @@
227
228
229 <h2 id="server">Fossil TLS Configuration: Server Side</h2>
230
231 Fossil's built-in HTTP server feature did not add [./ssl-server.md|support HTTP over TLS]
232 (a.k.a. HTTPS) until version 2.18 (2022). Prior to that, system administrators
233 that wanted to add HTTPS support to a Fossil server had to put Fossil
234 behind a web-server or reverse-proxy that would do the HTTPS to HTTP
235 translation. [./server/ | Instructions for doing so] are found elsewhere
236 in this documentation. A few of the most useful of these are:
 
237
238 * <a id="stunnel" href="./server/any/stunnel.md">Serving via stunnel</a>
239 * <a id="althttpd" href="./server/any/althttpd.md">Serving via stunnel + althttpd</a>
240 * <a id="nginx" href="./server/debian/nginx.md#tls">Serving via SCGI with nginx on Debian</a>
241
242
--- www/ssl.wiki
+++ www/ssl.wiki
@@ -227,15 +227,16 @@
227
228
229 <h2 id="server">Fossil TLS Configuration: Server Side</h2>
230
231 Fossil's built-in HTTP server feature did not add [./ssl-server.md|support HTTP over TLS]
232 (a.k.a. HTTPS) until version 2.18 (early 2022). Prior to that, system
233 administrators that wanted to add HTTPS support to a Fossil server had
234 to put Fossil behind a web-server or reverse-proxy that would do the
235 HTTPS to HTTP translation. [./server/ | Instructions for doing so]
236 are found elsewhere in this documentation. A few of the most useful
237 of these are:
238
239 * <a id="stunnel" href="./server/any/stunnel.md">Serving via stunnel</a>
240 * <a id="althttpd" href="./server/any/althttpd.md">Serving via stunnel + althttpd</a>
241 * <a id="nginx" href="./server/debian/nginx.md#tls">Serving via SCGI with nginx on Debian</a>
242
243

Keyboard Shortcuts

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