System.Data.SQLite

Check-in Differences
Login

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

Difference From f58ef51a621740f2 To ec237b012300b80f

2006-01-20
16:08
1.0.24.5 check-in: c79755ec5b user: rmsimpson tags: sourceforge
16:08
no message check-in: f58ef51a62 user: rmsimpson tags: sourceforge
15:59
no message check-in: da8e102e28 user: rmsimpson tags: sourceforge
2005-03-01
17:32
Initial revision check-in: 5b6332ffaa user: rmsimpson tags: sourceforge
16:04
Initial checkin Closed-Leaf check-in: 3ca8c53212 user: rmsimpson tags: start, sourceforge
16:04
Initial revision check-in: ec237b0123 user: rmsimpson tags: trunk, sourceforge

Deleted Doc/SQLite.NET.Internal.chm.

cannot compute difference between binary files

Deleted Doc/SQLite.NET.Internal.ndoc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<project SchemaVersion="1.3">
    <assemblies>
        <assembly location="..\bin\System.Data.SQLite.dll" documentation=".\System.Data.SQLite.XML" />
    </assemblies>
    <documenters>
        <documenter name="JavaDoc">
            <property name="OutputDirectory" value=".\doc\" />
        </documenter>
        <documenter name="LaTeX">
            <property name="OutputDirectory" value=".\doc\" />
            <property name="TextFileFullName" value="Documentation.tex" />
            <property name="TexFileBaseName" value="Documentation" />
            <property name="LatexCompiler" value="latex" />
            <property name="TexFileFullPath" value=".\doc\Documentation.tex" />
        </documenter>
        <documenter name="LinearHtml">
            <property name="OutputDirectory" value=".\doc\" />
            <property name="Title" value="An NDoc Documented Class Library" />
        </documenter>
        <documenter name="MSDN">
            <property name="OutputDirectory" value="c:\src\SQLite.NET\Doc\" />
            <property name="HtmlHelpName" value="SQLite.NET.Internal" />
            <property name="Title" value="SQLite.NET Internal Class Library" />
            <property name="OutputTarget" value="HtmlHelp" />
            <property name="IncludeFavorites" value="True" />
            <property name="DocumentInternals" value="True" />
            <property name="DocumentSealedProtected" value="True" />
            <property name="DocumentPrivates" value="True" />
            <property name="DocumentProtectedInternalAsProtected" value="True" />
            <property name="AssemblyVersionInfo" value="AssemblyVersion" />
            <property name="FeedbackEmailAddress" value="robert@blackcastlesoft.com" />
            <property name="Preliminary" value="True" />
            <property name="DocumentAttributes" value="True" />
            <property name="IncludeDefaultThreadSafety" value="False" />
            <property name="CleanIntermediates" value="True" />
        </documenter>
        <documenter name="MSDN 2003">
            <property name="OutputDirectory" value=".\doc\" />
            <property name="Title" value="An NDoc Documented Class Library" />
        </documenter>
        <documenter name="VS.NET 2003">
            <property name="OutputDirectory" value=".\doc\" />
            <property name="HtmlHelpName" value="Documentation" />
            <property name="Title" value="An NDoc documented library" />
        </documenter>
        <documenter name="XML">
            <property name="OutputFile" value=".\doc\doc.xml" />
        </documenter>
    </documenters>
</project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































Changes to Doc/SQLite.NET.chm.

cannot compute difference between binary files

Changes to Doc/SQLite.NET.ndoc.
1
2
3
4
5
6
7
8
9
10
<project SchemaVersion="1.3">
    <assemblies>
        <assembly location="..\bin\System.Data.SQLite.dll" documentation=".\System.Data.SQLite.XML" />
    </assemblies>
    <documenters>
        <documenter name="JavaDoc">
            <property name="OutputDirectory" value=".\doc\" />
        </documenter>
        <documenter name="LaTeX">
            <property name="OutputDirectory" value=".\doc\" />


|







1
2
3
4
5
6
7
8
9
10
<project SchemaVersion="1.3">
    <assemblies>
        <assembly location="..\System.Data.SQLite\bin\Release\System.Data.SQLite.dll" documentation="..\System.Data.SQLite\bin\Release\System.Data.SQLite.xml" />
    </assemblies>
    <documenters>
        <documenter name="JavaDoc">
            <property name="OutputDirectory" value=".\doc\" />
        </documenter>
        <documenter name="LaTeX">
            <property name="OutputDirectory" value=".\doc\" />
Deleted Doc/System.Data.SQLite.XML.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
<?xml version="1.0"?>
<doc>
    <assembly>
        <name>System.Data.SQLite</name>
    </assembly>
    <members>
        <member name="T:System.Data.SQLite.SQLiteFactory">
            <summary>
            SQLite implementation of DbProviderFactory.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteFactory.Instance">
            <summary>
            Static instance member which returns an instanced SQLiteFactory class.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFactory.CreateCommand">
            <summary>
            Returns a new SQLiteCommand object.
            </summary>
            <returns>A SQLiteCommand object.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFactory.CreateCommandBuilder">
            <summary>
            Returns a new SQLiteCommandBuilder object.
            </summary>
            <returns>A SQLiteCommandBuilder object.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFactory.CreateConnection">
            <summary>
            Creates a new SQLiteConnection.
            </summary>
            <returns>A SQLiteConnection object.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFactory.CreateConnectionStringBuilder">
            <summary>
            Creates a new SQLiteConnectionStringBuilder.
            </summary>
            <returns>A SQLiteConnectionStringBuilder object.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFactory.CreateDataAdapter">
            <summary>
            Creates a new SQLiteDataAdapter.
            </summary>
            <returns>A SQLiteDataAdapter object.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFactory.CreateParameter">
            <summary>
            Creates a new SQLiteParameter.
            </summary>
            <returns>A SQLiteParameter object.</returns>
        </member>
        <member name="T:System.Data.SQLite.SQLiteDataReader">
            <summary>
            SQLite implementation of DbDataReader.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteDataReader._command">
            <summary>
            Underlying command this reader is attached to
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteDataReader._activeStatementIndex">
            <summary>
            Index of the current statement in the command being processed
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteDataReader._activeStatement">
            <summary>
            Current statement being Read()
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteDataReader._readingState">
            <summary>
            State of the current statement being processed.
            -1 = First Step() executed, so the first Read() will be ignored
             0 = Actively reading
             1 = Finished reading
             2 = Non-row-returning statement, no records
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteDataReader._rowsAffected">
            <summary>
            Number of records affected by the insert/update statements executed on the command
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteDataReader._fieldCount">
            <summary>
            Count of fields (columns) in the row-returning statement currently being processed
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteDataReader._fieldTypeArray">
            <summary>
            Datatypes of active fields (columns) in the current statement, used for type-restricting data
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteDataReader._commandBehavior">
            <summary>
            The behavior of the datareader
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.#ctor(System.Data.SQLite.SQLiteCommand,System.Data.CommandBehavior)">
            <summary>
            Internal constructor, initializes the datareader and sets up to begin executing statements
            </summary>
            <param name="cmd">The SQLiteCommand this data reader is for</param>
            <param name="behave">The expected behavior of the data reader</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.Initialize">
            <summary>
            Initializes and resets the datareader's member variables
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.Close">
            <summary>
            Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.Dispose(System.Boolean)">
            <summary>
            Disposes the datareader.  Calls Close() to ensure everything is cleaned up.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.CheckClosed">
            <summary>
            Throw an error if the datareader is closed
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.CheckValidRow">
            <summary>
            Throw an error if a row is not loaded
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetEnumerator">
            <summary>
            Enumerator support
            </summary>
            <returns>Returns a DbEnumerator object.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.VerifyType(System.Int32,System.Data.DbType)">
            <summary>
            SQLite is inherently un-typed.  All datatypes in SQLite are natively strings.  The definition of the columns of a table
            and the affinity of returned types are all we have to go on to type-restrict data in the reader.
            
            This function attempts to verify that the type of data being requested of a column matches the datatype of the column.  In
            the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob)
            to a set of known types that closely match that affinity.  It's not an exact science, but its the best we can do.
            </summary>
            <returns>
            This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity.
            </returns>
            <param name="i">The index of the column to type-check</param>
            <param name="typ">The type we want to get out of the column</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetBoolean(System.Int32)">
            <summary>
            Retrieves the column as a boolean value
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>bool</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetByte(System.Int32)">
            <summary>
            Retrieves the column as a single byte value
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>byte</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetBytes(System.Int32,System.Int64,System.Byte[],System.Int32,System.Int32)">
            <summary>
            Retrieves a column as an array of bytes (blob)
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <param name="fieldOffset">The zero-based index of where to begin reading the data</param>
            <param name="buffer">The buffer to write the bytes into</param>
            <param name="bufferoffset">The zero-based index of where to begin writing into the array</param>
            <param name="length">The number of bytes to retrieve</param>
            <returns>The actual number of bytes written into the array</returns>
            <remarks>
            To determine the number of bytes in the column, pass a null value for the buffer.  The total length will be returned.
            </remarks>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetChar(System.Int32)">
            <summary>
            Returns the column as a single character
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>char</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetChars(System.Int32,System.Int64,System.Char[],System.Int32,System.Int32)">
            <summary>
            Retrieves a column as an array of chars (blob)
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <param name="fieldoffset">The zero-based index of where to begin reading the data</param>
            <param name="buffer">The buffer to write the characters into</param>
            <param name="bufferoffset">The zero-based index of where to begin writing into the array</param>
            <param name="length">The number of bytes to retrieve</param>
            <returns>The actual number of characters written into the array</returns>
            <remarks>
            To determine the number of characters in the column, pass a null value for the buffer.  The total length will be returned.
            </remarks>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetDataTypeName(System.Int32)">
            <summary>
            Retrieves the name of the back-end datatype of the column
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>string</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetDateTime(System.Int32)">
            <summary>
            Retrieve the column as a date/time value
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>DateTime</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetDecimal(System.Int32)">
            <summary>
            Retrieve the column as a decimal value
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>decimal</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetDouble(System.Int32)">
            <summary>
            Returns the column as a double
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>double</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetFieldType(System.Int32)">
            <summary>
            Returns the .NET type of a given column
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>Type</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetFloat(System.Int32)">
            <summary>
            Returns a column as a float value
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>float</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetGuid(System.Int32)">
            <summary>
            Returns the column as a Guid
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>Guid</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetInt16(System.Int32)">
            <summary>
            Returns the column as a short
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>Int16</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetInt32(System.Int32)">
            <summary>
            Retrieves the column as an int
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>Int32</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetInt64(System.Int32)">
            <summary>
            Retrieves the column as a long
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>Int64</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetName(System.Int32)">
            <summary>
            Retrieves the name of the column
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>string</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetOrdinal(System.String)">
            <summary>
            Retrieves the i of a column, given its name
            </summary>
            <param name="name">The name of the column to retrieve</param>
            <returns>The int i of the column</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetSchemaTable">
            <summary>
            Schema information in SQLite is an iffy-business.  We've extended the native SQLite3.DLL to include a special pragma called
            PRAGMA real_column_names
            When enabled, the pragma causes all column aliases to be ignored, and the full Database.Table.ColumnName to be returned for
            each column of a SELECT statement.  Using this information it is then possible to query each database and table for the
            matching column, and associate it with the active statement.
            </summary>
            <remarks>
            The current connection is cloned for the sake of executing this statement, so as to avoid any possibility of corrupting the
            original connection's existing statements or state.  Any attached databases are re-attached to the new connection.
            </remarks>
            <returns>Returns a DataTable containing the schema information for the active SELECT statement being processed.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetString(System.Int32)">
            <summary>
            Retrieves the column as a string
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>string</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetValue(System.Int32)">
            <summary>
            Retrieves the column as an object corresponding to the underlying datatype of the column
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>object</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetValues(System.Object[])">
            <summary>
            Retreives the values of multiple columns, up to the size of the supplied array
            </summary>
            <param name="values">The array to fill with values from the columns in the current resultset</param>
            <returns>The number of columns retrieved</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.IsDBNull(System.Int32)">
            <summary>
            Returns True if the specified column is null
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>True or False</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.NextResult">
            <summary>
            Moves to the next resultset in multiple row-returning SQL command.
            </summary>
            <returns>True if the command was successful and a new resultset is available, False otherwise.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.GetSQLiteType(System.Int32)">
            <summary>
            Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls.
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>A SQLiteType structure</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataReader.Read">
            <summary>
            Reads the next row from the resultset
            </summary>
            <returns>True if a new row was successfully loaded and is ready for processing</returns>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataReader.Depth">
            <summary>
            Not implemented.  Returns 0
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataReader.FieldCount">
            <summary>
            Returns the number of columns in the current resultset
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataReader.HasRows">
            <summary>
            Returns True if the resultset has rows that can be fetched
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataReader.IsClosed">
            <summary>
            Returns True if the data reader is closed
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataReader.RecordsAffected">
            <summary>
            Retrieve the count of records affected by an update/insert command.  Only valid once the data reader is closed!
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataReader.Item(System.String)">
            <summary>
            Indexer to retrieve data from a column given its name
            </summary>
            <param name="name">The name of the column to retrieve data for</param>
            <returns>The value contained in the column</returns>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataReader.Item(System.Int32)">
            <summary>
            Indexer to retrieve data from a column given its i
            </summary>
            <param name="i">The index of the column to retrieve</param>
            <returns>The value contained in the column</returns>
        </member>
        <member name="T:System.Data.SQLite.FunctionType">
            <summary>
            The type of user-defined function to declare
            </summary>
        </member>
        <member name="F:System.Data.SQLite.FunctionType.Scalar">
            <summary>
            Scalar functions are designed to be called and return a result immediately.  Examples include ABS(), Upper(), Lower(), etc.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.FunctionType.Aggregate">
            <summary>
            Aggregate functions are designed to accumulate data until the end of a call and then return a result gleaned from the accumulated data.
            Examples include SUM(), COUNT(), AVG(), etc.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.FunctionType.Collation">
            <summary>
            Collation sequences are used to sort textual data in a custom manner, and appear in an ORDER BY clause.  Typically text in an ORDER BY is
            sorted using a straight case-insensitive comparison function.  Custom collating sequences can be used to alter the behavior of text sorting
            in a user-defined manner.
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteCallback">
            <summary>
            An internal callback delegate declaration.
            </summary>
            <param name="context">Raw context pointer for the user function</param>
            <param name="nArgs">Count of arguments to the function</param>
            <param name="argsptr">A pointer to the array of argument pointers</param>
        </member>
        <member name="T:System.Data.SQLite.SQLiteCollation">
            <summary>
            Internal callback delegate for implementing collation sequences
            </summary>
            <param name="len1">Length of the string pv1</param>
            <param name="pv1">Pointer to the first string to compare</param>
            <param name="len2">Length of the string pv2</param>
            <param name="pv2">Pointer to the second string to compare</param>
            <returns>Returns -1 if the first string is less than the second.  0 if they are equal, or 1 if the first string is greater
            than the second.</returns>
        </member>
        <member name="T:System.Data.SQLite.SQLiteFunction">
            <summary>
            This abstract class is designed to handle user-defined functions easily.  An instance of the derived class is made for each
            connection to the database.
            </summary>
            <remarks>
            Although there is one instance of a class derived from SQLiteFunction per database connection, the derived class has no access
            to the underlying connection.  This is necessary to deter implementers from thinking it would be a good idea to make database
            calls during processing.
            
            It is important to distinguish between a per-connection instance, and a per-SQL statement context.  One instance of this class
            services all SQL statements being stepped through on that connection, and there can be many.  One should never store per-statement
            information in member variables of user-defined function classes.
            
            For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step.  This data will
            be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes.
            </remarks>
        </member>
        <member name="F:System.Data.SQLite.SQLiteFunction._base">
            <summary>
            The base connection this function is attached to
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteFunction._interopCookie">
            <summary>
            Used internally to keep track of memory allocated for aggregate functions
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteFunction._contextDataList">
            <summary>
            Internal array used to keep track of aggregate function context data
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteFunction._InvokeFunc">
            <summary>
            Holds a reference to the callback function for user functions
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteFunction._StepFunc">
            <summary>
            Holds a reference to the callbakc function for stepping in an aggregate function
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteFunction._FinalFunc">
            <summary>
            Holds a reference to the callback function for finalizing an aggregate function
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteFunction._CompareFunc">
            <summary>
            Holds a reference to the callback function for collation sequences
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteFunction._registeredFunctions">
            <summary>
            This static list contains all the user-defined functions declared using the proper attributes.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.#ctor">
            <summary>
            Internal constructor, initializes the function's internal variables.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.Invoke(System.Object[])">
            <summary>
            Scalar functions override this method to do their magic.
            </summary>
            <remarks>
            Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available
            to force them into a certain type.  Therefore the only types you will ever see as parameters are
            DBNull.Value, Int64, Double, String or byte[] array.
            </remarks>
            <param name="args">The arguments for the command to process</param>
            <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
            you may return an Exception-derived class if you wish to return an error to SQLite.  Do not actually throw the error,
            just return it!</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.Step(System.Object[],System.Int32,System.Object@)">
            <summary>
            Aggregate functions override this method to do their magic.
            </summary>
            <remarks>
            Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible.
            </remarks>
            <param name="args">The arguments for the command to process</param>
            <param name="stepNumber">The 1-based step number.  This is incrememted each time the step method is called.</param>
            <param name="contextData">A placeholder for implementers to store contextual data pertaining to the current context.</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.Final(System.Object)">
            <summary>
            Aggregate functions override this method to finish their aggregate processing.
            </summary>
            <remarks>
            If you implemented your aggregate function properly,
            you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have
            all the information you need in there to figure out what to return.
            </remarks>
            <param name="contextData">Your own assigned contextData, provided for you so you can return your final results.</param>
            <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
            you may return an Exception-derived class if you wish to return an error to SQLite.  Do not actually throw the error,
            just return it!
            </returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.Compare(System.String,System.String)">
            <summary>
            User-defined collation sequences override this method to provide a custom string sorting algorithm.
            </summary>
            <param name="param1">The first string to compare</param>
            <param name="param2">The second strnig to compare</param>
            <returns>1 if param1 is greater than param2, 0 if they are equal, or -1 if param1 is less than param2</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.ConvertParams(System.Int32,System.IntPtr)">
            <summary>
            Converts an IntPtr array of context arguments to an object array containing the resolved parameters the pointers point to.
            </summary>
            <remarks>
            Parameters passed to functions have only an affinity for a certain data type, there is no underlying schema available
            to force them into a certain type.  Therefore the only types you will ever see as parameters are
            DBNull.Value, Int64, Double, String or byte[] array.
            </remarks>
            <param name="nArgs">The number of arguments</param>
            <param name="argsptr">A pointer to the array of arguments</param>
            <returns>An object array of the arguments once they've been converted to .NET values</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.SetReturnValue(System.Int32,System.Object)">
            <summary>
            Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context.
            </summary>
            <param name="context">The context the return value applies to</param>
            <param name="returnValue">The parameter to return to SQLite</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.ScalarCallback(System.Int32,System.Int32,System.IntPtr)">
            <summary>
            Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method.
            </summary>
            <param name="context">A raw context pointer</param>
            <param name="nArgs">Number of arguments passed in</param>
            <param name="argsptr">A pointer to the array of arguments</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.CompareCallback(System.Int32,System.IntPtr,System.Int32,System.IntPtr)">
            <summary>
            Internal collation sequence function, which wraps up the raw string pointers and executes the Compare() virtual function.
            </summary>
            <param name="len1">Length of the string pv1</param>
            <param name="ptr1">Pointer to the first string to compare</param>
            <param name="len2">Length of the string pv2</param>
            <param name="ptr2">Pointer to the second string to compare</param>
            <returns>Returns -1 if the first string is less than the second.  0 if they are equal, or 1 if the first string is greater
            than the second.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.StepCallback(System.Int32,System.Int32,System.IntPtr)">
            <summary>
            The internal aggregate Step function callback, which wraps the raw context pointer and calls the virtual Step() method.
            </summary>
            <remarks>
            This function takes care of doing the lookups and getting the important information put together to call the Step() function.
            That includes pulling out the user's contextData and updating it after the call is made.  We use a sorted list for this so
            binary searches can be done to find the data.
            </remarks>
            <param name="context">A raw context pointer</param>
            <param name="nArgs">Number of arguments passed in</param>
            <param name="argsptr">A pointer to the array of arguments</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.FinalCallback(System.Int32,System.Int32,System.IntPtr)">
            <summary>
            An internal aggregate Final function callback, which wraps the context pointer and calls the virtual Final() method.
            </summary>
            <param name="context">A raw context pointer</param>
            <param name="nArgs">Not used, always zero</param>
            <param name="argsptr">Not used, always zero</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.Dispose(System.Boolean)">
            <summary>
            Placeholder for a user-defined disposal routine
            </summary>
            <param name="disposing">True if the object is being disposed explicitly</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.Dispose">
            <summary>
            Disposes of any active contextData variables that were not automatically cleaned up.  Sometimes this can happen if
            someone closes the connection while a DataReader is open.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.#cctor">
            <summary>
            Using reflection, enumerate all assemblies in the current appdomain looking for classes that
            have a SQLiteFunctionAttribute attribute, and registering them accordingly.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.BindFunctions(System.Data.SQLite.SQLiteBase)">
            <summary>
            Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection.
            It is done this way so that all user-defined functions will access the database using the same encoding scheme
            as the connection (UTF-8 or UTF-16).
            </summary>
            <remarks>
            The wrapper functions that interop with SQLite will create a unique cooke value, which internally is a pointer to
            all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.
            </remarks>
            <param name="sqlbase">The base object on which the functions are to bind</param>
            <returns>Returns an array of functions which the connection object should retain until the connection is closed.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunction.UnbindFunctions(System.Data.SQLite.SQLiteBase,System.Data.SQLite.SQLiteFunction[])">
            <summary>
            Issued after the base connection is closed, this function cleans up all user-defined functions and disposes of them.
            </summary>
            <remarks>
            Cleaning up here is done mainly because of the interop wrapper.  It allocated memory to hold a reference to all the
            delegates, and now must free that memory.
            Freeing is done after the connection is closed to ensure no callbacks get hit after we've freed the cookie.
            </remarks>
            <param name="sqlbase">The base SQLite connection object</param>
            <param name="ar">An array of user-defined functions for this object</param>
        </member>
        <member name="P:System.Data.SQLite.SQLiteFunction.SQLiteConvert">
            <summary>
            Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert
            strings and DateTime's into the current connection's encoding schema.
            </summary>
        </member>
        <member name="T:System.Data.SQLite.TypeAffinity">
            <summary>
            SQLite has very limited types, and is inherently text-based.  The first 5 types below represent the sum of all types SQLite
            understands.  The DateTime extension to the spec is for internal use only.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.TypeAffinity.Uninitialized">
            <summary>
            Not used
            </summary>
        </member>
        <member name="F:System.Data.SQLite.TypeAffinity.Int64">
            <summary>
            All integers in SQLite default to Int64
            </summary>
        </member>
        <member name="F:System.Data.SQLite.TypeAffinity.Double">
            <summary>
            All floating point numbers in SQLite default to double
            </summary>
        </member>
        <member name="F:System.Data.SQLite.TypeAffinity.Text">
            <summary>
            The default data type of SQLite is text
            </summary>
        </member>
        <member name="F:System.Data.SQLite.TypeAffinity.Blob">
            <summary>
            Typically blob types are only seen when returned from a function
            </summary>
        </member>
        <member name="F:System.Data.SQLite.TypeAffinity.Null">
            <summary>
            Null types can be returned from functions
            </summary>
        </member>
        <member name="F:System.Data.SQLite.TypeAffinity.DateTime">
            <summary>
            Used internally by this provider
            </summary>
        </member>
        <member name="F:System.Data.SQLite.TypeAffinity.None">
            <summary>
            Used internally
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteDateFormats">
            <summary>
            This implementation of SQLite for ADO.NET can process date/time fields in databases in only one of two formats.  Ticks and ISO8601.
            Ticks is inherently more accurate, but less compatible with 3rd party tools that query the database, and renders the DateTime field
            unreadable without post-processing.
            ISO8601 is more compatible, readable, fully-processable, but less accurate as it doesn't provide time down to fractions of a second.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteDateFormats.Ticks">
            <summary>
            Using ticks is more accurate but less compatible with other viewers and utilities that access your database.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteDateFormats.ISO8601">
            <summary>
            The default format for this provider.  More compatible with SQLite's intended usage of datetimes, but overall less accurate than Ticks as it doesn't
            natively support times down to fractions of a second.
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteType">
            <summary>
            Struct used internally to determine the datatype of a column in a resultset
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteType.Type">
            <summary>
            The DbType of the column, or DbType.Object if it cannot be determined
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteType.Affinity">
            <summary>
            The affinity of a column, used for expressions or when Type is DbType.Object
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteConvert">
            <summary>
            This base class provides datatype conversion services for the SQLite provider.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteConvert._datetimeFormats">
            <summary>
            An array of ISO8601 datetime formats we support conversion from
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteConvert._utf8">
            <summary>
            An UTF-8 Encoding instance, so we can convert strings to and from UTF-8
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteConvert._datetimeFormat">
            <summary>
            The default DateTime format for this instance
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.#ctor(System.Data.SQLite.SQLiteDateFormats)">
            <summary>
            Initializes the conversion class
            </summary>
            <param name="fmt">The default date/time format to use for this instance</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.ToUTF8(System.String)">
            <summary>
            Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character.
            </summary>
            <param name="sourceText">The string to convert to UTF-8</param>
            <returns>A byte array containing the converted string plus an extra 0 terminating byte at the end of the array.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.ToUTF8(System.DateTime)">
            <summary>
            Convert a DateTime to a UTF-8 encoded, zero-terminated byte array.
            </summary>
            <remarks>
            This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the
            string result.
            </remarks>
            <param name="dateTimeValue">The DateTime to convert.</param>
            <returns>The UTF-8 encoded string, including a 0 terminating byte at the end of the array.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.ToString(System.IntPtr,System.Int32)">
            <summary>
            Converts a UTF-8 encoded IntPtr of the specified length into a .NET string
            </summary>
            <param name="nativestring">The pointer to the memory where the UTF-8 string is encoded</param>
            <param name="nativestringlen">The number of bytes to decode</param>
            <returns>A string containing the translated character(s)</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.ToDateTime(System.String)">
            <summary>
            Converts a string into a DateTime, using the current DateTimeFormat specified for the connection when it was opened.
            </summary>
            <remarks>
            Acceptable ISO8601 DateTime formats are:
              yyyy-MM-dd HH:mm:ss
              yyyyMMddHHmmss
              yyyyMMddTHHmmssfffffff
              yyyy-MM-dd
              yy-MM-dd
              yyyyMMdd
              HH:mm:ss
              THHmmss
            </remarks>
            <param name="dateText">The string containing either a Tick value or an ISO8601-format string</param>
            <returns>A DateTime value</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.ToString(System.DateTime)">
            <summary>
            Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened.
            </summary>
            <param name="dateValue">The DateTime value to convert</param>
            <returns>Either a string consisting of the tick count for DateTimeFormat.Ticks, or a date/time in ISO8601 format.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.ToDateTime(System.IntPtr,System.Int32)">
            <summary>
            Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime.
            </summary>
            <remarks>
            This is a convenience function, which first calls ToString() on the IntPtr to convert it to a string, then calls
            ToDateTime() on the string to return a DateTime.
            </remarks>
            <param name="ptr">A pointer to the UTF-8 encoded string</param>
            <param name="len">The length in bytes of the string</param>
            <returns>The parsed DateTime value</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.Split(System.String,System.Char)">
            <summary>
            Smart method of splitting a string.  Skips quoted elements, removes the quotes.
            </summary>
            <remarks>
            This split function works somewhat like the String.Split() function in that it breaks apart a string into
            pieces and returns the pieces as an array.  The primary differences are:
            <list type="bullet">
            <item><description>Only one character can be provided as a separator character</description></item>
            <item><description>Quoted text inside the string is skipped over when searching for the separator, and the quotes are removed.</description></item>
            </list>
            Thus, if splitting the following string looking for a comma:<br/>
            One,Two, "Three, Four", Five<br/>
            <br/>
            The resulting array would contain<br/>
            [0] One<br/>
            [1] Two<br/>
            [2] Three, Four<br/>
            [3] Five<br/>
            <br/>
            Note that the leading and trailing spaces were removed from each item during the split.
            </remarks>
            <param name="source">Source string to split apart</param>
            <param name="separator">Separator character</param>
            <returns>A string array of the split up elements</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.ColumnToType(System.Data.SQLite.SQLiteStatement,System.Int32)">
            <summary>
            Determines the data type of a column in a statement
            </summary>
            <param name="stmt">The statement to retrieve information for</param>
            <param name="i">The column to retrieve type information on</param>
            <returns>Returns a SQLiteType struct</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.SQLiteTypeToType(System.Data.SQLite.SQLiteType)">
            <summary>
            Converts a SQLiteType to a .NET Type object
            </summary>
            <param name="t">The SQLiteType to convert</param>
            <returns>Returns a .NET Type object</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.TypeToDbType(System.Type)">
            <summary>
            For a given intrinsic type, return a DbType
            </summary>
            <param name="typ">The native type to convert</param>
            <returns>The corresponding (closest match) DbType</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.DbTypeToType(System.Data.DbType)">
            <summary>
            Convert a DbType to a Type
            </summary>
            <param name="typ">The DbType to convert from</param>
            <returns>The closest-match .NET type</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.TypeToAffinity(System.Type)">
            <summary>
            For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types.
            </summary>
            <param name="typ">The type to evaluate</param>
            <returns>The SQLite type affinity for that type.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConvert.TypeNameToDbType(System.String)">
            <summary>
            For a given type name, return a closest-match .NET type
            </summary>
            <param name="Name">The name of the type to match</param>
            <returns>The .NET DBType the text evaluates to.</returns>
        </member>
        <member name="T:System.Data.SQLite.SR">
            <summary>
              A strongly-typed resource class, for looking up localized strings, etc.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SR.ResourceManager">
            <summary>
              Returns the cached ResourceManager instance used by this class.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SR.Culture">
            <summary>
              Overrides the current thread's CurrentUICulture property for all
              resource lookups using this strongly typed resource class.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SR.DataTypes">
             <summary>
               Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; standalone=&quot;yes&quot;?&gt;
            &lt;DocumentElement&gt;
              &lt;DataTypes&gt;
                &lt;TypeName&gt;System.Int16&lt;/TypeName&gt;
                &lt;ProviderDbType&gt;10&lt;/ProviderDbType&gt;
                &lt;ColumnSize&gt;5&lt;/ColumnSize&gt;
                &lt;DataType&gt;System.Int16&lt;/DataType&gt;
                &lt;IsAutoIncrementable&gt;false&lt;/IsAutoIncrementable&gt;
                &lt;IsCaseSensitive&gt;false&lt;/IsCaseSensitive&gt;
                &lt;IsFixedLength&gt;true&lt;/IsFixedLength&gt;
                &lt;IsFixedPrecisionScale&gt;true&lt;/IsFixedPrecisionScale&gt;
                &lt;IsLong&gt;false&lt;/IsLong&gt;
                &lt;IsNullable&gt;true&lt;/IsNullable&gt;
                &lt;IsSearchable&gt;true&lt;/Is [rest of string was truncated]&quot;;.
             </summary>
        </member>
        <member name="P:System.Data.SQLite.SR.MetaDataCollections">
             <summary>
               Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
            &lt;DocumentElement&gt;
              &lt;MetaDataCollections&gt;
                &lt;CollectionName&gt;MetaDataCollections&lt;/CollectionName&gt;
                &lt;NumberOfRestrictions&gt;0&lt;/NumberOfRestrictions&gt;
                &lt;NumberOfIdentifierParts&gt;0&lt;/NumberOfIdentifierParts&gt;
              &lt;/MetaDataCollections&gt;
              &lt;MetaDataCollections&gt;
                &lt;CollectionName&gt;DataSourceInformation&lt;/CollectionName&gt;
                &lt;NumberOfRestrictions&gt;0&lt;/NumberOfRestrictions&gt;
                &lt;NumberOfIdentifierParts&gt;0&lt;/NumberOfIdentifierParts&gt;
              &lt;/MetaDataCollections&gt;
              &lt;MetaDataC [rest of string was truncated]&quot;;.
             </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteFunctionAttribute">
            <summary>
            A simple custom attribute to enable us to easily find user-defined functions in
            the loaded assemblies and initialize them in SQLite as connections are made.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteFunctionAttribute.#ctor">
            <summary>
            Default constructor, initializes the internal variables for the function.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteFunctionAttribute.Name">
            <summary>
            The function's name as it will be used in SQLite command text.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteFunctionAttribute.Arguments">
            <summary>
            The number of arguments this function expects.  -1 if the number of arguments is variable.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteFunctionAttribute.FuncType">
            <summary>
            The type of function this implementation will be.
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteErrorCode">
            <summary>
            SQLite error codes
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Ok">
            <summary>
            Success
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Error">
            <summary>
            SQL error or missing database
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Internal">
            <summary>
            Internal logic error in SQLite
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Perm">
            <summary>
            Access permission denied
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Abort">
            <summary>
            Callback routine requested an abort
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Busy">
            <summary>
            The database file is locked
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Locked">
            <summary>
            A table in the database is locked
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.NoMem">
            <summary>
            malloc() failed
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.ReadOnly">
            <summary>
            Attempt to write a read-only database
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Interrupt">
            <summary>
            Operation terminated by sqlite3_interrupt()
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.IOErr">
            <summary>
            Some kind of disk I/O error occurred
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Corrupt">
            <summary>
            The database disk image is malformed
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.NotFound">
            <summary>
            Table or record not found
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Full">
            <summary>
            Insertion failed because database is full
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.CantOpen">
            <summary>
            Unable to open the database file
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Protocol">
            <summary>
            Database lock protocol error
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Empty">
            <summary>
            Database is empty
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Schema">
            <summary>
            The database schema changed
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.TooBig">
            <summary>
            Too much data for one row of a table
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Constraint">
            <summary>
            Abort due to constraint violation
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Mismatch">
            <summary>
            Data type mismatch
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Misuse">
            <summary>
            Library used incorrectly
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.NOLFS">
            <summary>
            Uses OS features not supported on host
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Auth">
            <summary>
            Authorization denied
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Format">
            <summary>
            Auxiliary database format error
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Range">
            <summary>
            2nd parameter to sqlite3_bind out of range
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.NotADatabase">
            <summary>
            File opened that is not a database file
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Row">
            <summary>
            sqlite3_step() has another row ready
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteErrorCode.Done">
            <summary>
            sqlite3_step() has finished executing
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteException">
            <summary>
            SQLite exception class.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteException.#ctor(System.Int32,System.String)">
            <summary>
            Public constructor for generating a SQLite error given the base error code
            </summary>
            <param name="errorCode">The SQLite error code to report</param>
            <param name="extendedInformation">Extra text to go along with the error message text</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteException.#ctor(System.String)">
            <summary>
            Various public constructors that just pass along to the base Exception
            </summary>
            <param name="message">Passed verbatim to Exception</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteException.#ctor">
            <summary>
            Various public constructors that just pass along to the base Exception
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteException.#ctor(System.String,System.Exception)">
            <summary>
            Various public constructors that just pass along to the base Exception
            <param name="message">Passed to Exception</param>
            <param name="innerException">Passed to Exception</param>
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteException.GetStockErrorMessage(System.Int32,System.String)">
            <summary>
            Initializes the exception class with the SQLite error code.
            </summary>
            <param name="errorCode">The SQLite error code</param>
            <param name="errorMessage">A detailed error message</param>
            <returns>An error message string</returns>
        </member>
        <member name="P:System.Data.SQLite.SQLiteException.ErrorCode">
            <summary>
            Retrieves the underlying SQLite error code for this exception
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLite3">
            <summary>
            This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteBase">
            <summary>
            This internal class provides the foundation of SQLite support.  It defines all the abstract members needed to implement
            a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.Open(System.String)">
            <summary>
            Opens a database.
            </summary>
            <remarks>
            Implementers should call SQLiteFunction.BindFunctions() and save the array after opening a connection
            to bind all attributed user-defined functions and collating sequences to the new connection.
            </remarks>
            <param name="strFilename">The filename of the database to open.  SQLite automatically creates it if it doesn't exist.</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.Close">
            <summary>
            Closes the currently-open database.
            </summary>
            <remarks>
            After the database has been closed implemeters should call SQLiteFunction.UnbindFunctions() to deallocate all interop allocated
            memory associated with the user-defined functions and collating sequences tied to the closed connection.
            </remarks>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.SetTimeout(System.Int32)">
            <summary>
            Sets the busy timeout on the connection.  SQLiteCommand will call this before executing any command.
            </summary>
            <param name="nTimeoutMS">The number of milliseconds to wait before returning SQLITE_BUSY</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.Execute(System.String)">
            <summary>
            Quick execute of a SQL command.  This is only executed internally, usually by SQLiteConnection when the connection
            is first opened to set the necessary startup pragmas.
            </summary>
            <param name="strSql">The SQL command text to execute</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.SQLiteLastError">
            <summary>
            Returns the text of the last error issued by SQLite
            </summary>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.Prepare(System.String,System.Data.SQLite.SQLiteStatement,System.String@)">
            <summary>
            Prepares a SQL statement for execution.
            </summary>
            <param name="strSql">The SQL command text to prepare</param>
            <param name="previous">The previous statement in a multi-statement command, or null if no previous statement exists</param>
            <param name="strRemain">The remainder of the statement that was not processed.  Each call to prepare parses the
            SQL up to to either the end of the text or to the first semi-colon delimiter.  The remaining text is returned
            here for a subsequent call to Prepare() until all the text has been processed.</param>
            <returns>Returns an initialized SQLiteStatement.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.Step(System.Data.SQLite.SQLiteStatement)">
            <summary>
            Steps through a prepared statement.
            </summary>
            <param name="stmt">The SQLiteStatement to step through</param>
            <returns>True if a row was returned, False if not.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.FinalizeStatement(System.Data.SQLite.SQLiteStatement)">
            <summary>
            Finalizes a prepared statement.
            </summary>
            <param name="stmt">The statement to finalize</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.Reset(System.Data.SQLite.SQLiteStatement)">
            <summary>
            Resets a prepared statement so it can be executed again.  If the error returned is SQLITE_SCHEMA, 
            transparently attempt to rebuild the SQL statement and throw an error if that was not possible.
            </summary>
            <param name="stmt">The statement to reset</param>
            <returns>Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.SetRealColNames(System.Boolean)">
            <summary>
            An interop-specific function, this call sets an internal flag in the sqlite.interop.dll which causes all column names
            of subsequently-prepared statements to return in Database.Table.Column format, ignoring all aliases that may have been applied
            to tables or columns in a resultset.
            </summary>
            <remarks>
            All statements prepared on this connection after this flag is changed are affected.  Existing statements are not.
            </remarks>
            <param name="bOn">Set to True to enable real column names, false to disable them.</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteBase.GetValue(System.Data.SQLite.SQLiteStatement,System.Int32,System.Data.SQLite.SQLiteType@)">
            <summary>
            Helper function to retrieve a column of data from an active statement.
            </summary>
            <param name="stmt">The statement being step()'d through</param>
            <param name="index">The column index to retrieve</param>
            <param name="typ">The type of data contained in the column.  If Uninitialized, this function will retrieve the datatype information.</param>
            <returns>Returns the data in the column</returns>
        </member>
        <member name="P:System.Data.SQLite.SQLiteBase.Version">
            <summary>
            Returns a string representing the active version of SQLite
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteBase.Changes">
            <summary>
            Returns the number of changes the last executing insert/update caused.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLite3._sql">
            <summary>
            The opaque pointer returned to us by the sqlite provider
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLite3._functionsArray">
            <summary>
            The user-defined functions registered on this connection
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteStatement">
            <summary>
            Represents a single SQL statement in SQLite.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteStatement._sql">
            <summary>
            The underlying SQLite object this statement is bound to
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteStatement._sqlStatement">
            <summary>
            The command text of this SQL statement
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteStatement._sqlite_stmt">
            <summary>
            The actual statement pointer
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteStatement._unnamedParameters">
            <summary>
            An index from which unnamed parameters begin
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteStatement._paramNames">
            <summary>
            Names of the parameters as SQLite understands them to be
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteStatement._paramValues">
            <summary>
            Parameters for this statement
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteStatement._command">
            <summary>
            Command this statement belongs to (if any)
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteStatement.#ctor(System.Data.SQLite.SQLiteBase,System.Int32,System.String,System.Data.SQLite.SQLiteStatement)">
            <summary>
            Initializes the statement and attempts to get all information about parameters in the statement
            </summary>
            <param name="sqlbase">The base SQLite object</param>
            <param name="stmt">The statement</param>
            <param name="strCommand">The command text for this statement</param>
            <param name="previous">The previous command in a multi-statement command</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteStatement.MapParameter(System.String,System.Data.SQLite.SQLiteParameter)">
            <summary>
            Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to
            this statement, and if so, keeps a reference to the parameter so it can be bound later.
            </summary>
            <param name="s">The parameter name to map</param>
            <param name="p">The parameter to assign it</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteStatement.Dispose">
            <summary>
            Disposes and finalizes the statement
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteStatement.BindParameters">
            <summary>
             Bind all parameters, making sure the caller didn't miss any
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteStatement.BindParameter(System.Int32,System.Data.SQLite.SQLiteParameter)">
            <summary>
            Perform the bind operation for an individual parameter
            </summary>
            <param name="index">The index of the parameter to bind</param>
            <param name="param">The parameter we're binding</param>
        </member>
        <member name="T:System.Data.SQLite.SQLiteDataAdapter">
            <summary>
            SQLite implementation of DbDataAdapter.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataAdapter.#ctor">
            <overloads>
            This class is just a shell around the DbDataAdapter.  Nothing from DbDataAdapter is overridden here, just a few constructors are defined.
            </overloads>
            <summary>
            Default constructor.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataAdapter.#ctor(System.Data.SQLite.SQLiteCommand)">
            <summary>
            Constructs a data adapter using the specified select command.
            </summary>
            <param name="cmd">The select command to associate with the adapter.</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataAdapter.#ctor(System.String,System.Data.SQLite.SQLiteConnection)">
            <summary>
            Constructs a data adapter with the supplied select command text and associated with the specified connection.
            </summary>
            <param name="commandText">The select command text to associate with the data adapter.</param>
            <param name="cnn">The connection to associate with the select command.</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataAdapter.#ctor(System.String,System.String)">
            <summary>
            Constructs a data adapter with the specified select command text, and using the specified database connection string.
            </summary>
            <param name="commandText">The select command text to use to construct a select command.</param>
            <param name="connectionString">A connection string suitable for passing to a new SQLiteConnection, which is associated with the select command.</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataAdapter.OnRowUpdating(System.Data.Common.RowUpdatingEventArgs)">
            <summary>
            Raised by the underlying DbDataAdapter when a row is being updated
            </summary>
            <param name="value">The event's specifics</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteDataAdapter.OnRowUpdated(System.Data.Common.RowUpdatedEventArgs)">
            <summary>
            Raised by DbDataAdapter after a row is updated
            </summary>
            <param name="value">The event's specifics</param>
        </member>
        <member name="E:System.Data.SQLite.SQLiteDataAdapter.RowUpdating">
            <summary>
            Row updating event handler
            </summary>
        </member>
        <member name="E:System.Data.SQLite.SQLiteDataAdapter.RowUpdated">
            <summary>
            Row updated event handler
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataAdapter.SelectCommand">
            <summary>
            Gets/sets the select command for this DataAdapter
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataAdapter.InsertCommand">
            <summary>
            Gets/sets the insert command for this DataAdapter
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataAdapter.UpdateCommand">
            <summary>
            Gets/sets the update command for this DataAdapter
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteDataAdapter.DeleteCommand">
            <summary>
            Gets/sets the delete command for this DataAdapter
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteCommand">
            <summary>
            SQLite implementation of DbCommand.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteCommand._commandText">
            <summary>
            The command text this command is based on
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteCommand._cnn">
            <summary>
            The connection the command is associated with
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteCommand._isReaderOpen">
            <summary>
            Indicates whether or not a DataReader is active on the command.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteCommand._commandTimeout">
            <summary>
            The timeout for the command, kludged because SQLite doesn't support per-command timeout values
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteCommand._designTimeVisible">
            <summary>
            Designer support
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteCommand._updateRowSource">
            <summary>
            Used by DbDataAdapter to determine updating behavior
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteCommand._parameterCollection">
            <summary>
            The collection of parameters for the command
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteCommand._statementList">
            <summary>
            The SQL command text, broken into individual SQL statements as they are executed
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteCommand._remainingText">
            <summary>
            Unprocessed SQL text that has not been executed
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.#ctor">
            <overloads>
             Constructs a new SQLiteCommand
             </overloads>
             <summary>
             Default constructor
             </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.#ctor(System.String)">
            <summary>
            Initializes the command with the given command text
            </summary>
            <param name="commandText">The SQL command text</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.#ctor(System.String,System.Data.SQLite.SQLiteConnection)">
            <summary>
            Initializes the command with the given SQL command text and attach the command to the specified
            connection.
            </summary>
            <param name="commandText">The SQL command text</param>
            <param name="cnn">The connection to associate with the command</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.#ctor(System.Data.SQLite.SQLiteConnection)">
            <summary>
            Initializes the command and associates it with the specified connection.
            </summary>
            <param name="cnn">The connection to associate with the command</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.#ctor(System.String,System.Data.SQLite.SQLiteConnection,System.Data.SQLite.SQLiteTransaction)">
            <summary>
            Initializes a command with the given SQL, connection and transaction
            </summary>
            <param name="commandText">The SQL command text</param>
            <param name="cnn">The connection to associate with the command</param>
            <param name="trans">The transaction the command should be associated with</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.Initialize(System.String,System.Data.SQLite.SQLiteConnection)">
            <summary>
            Initializes the command class
            </summary>
            <param name="strSql">The SQL command text</param>
            <param name="cnn">A connection to associate with the command</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.Dispose(System.Boolean)">
            <summary>
            Disposes of the command and clears all member variables
            </summary>
            <param name="disposing">Whether or not the class is being explicitly or implicitly disposed</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.ClearCommands">
            <summary>
            Clears and destroys all statements currently prepared
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.BuildNextCommand">
            <summary>
            Builds an array of prepared statements for each complete SQL statement in the command text
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.Cancel">
            <summary>
            Not implemented
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.CreateDbParameter">
            <summary>
            Forwards to the local CreateParameter() function
            </summary>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.CreateParameter">
            <summary>
            Create a new parameter
            </summary>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.InitializeForReader">
            <summary>
            This function ensures there are no active readers, that we have a valid connection,
            that the connection is open, that all statements are prepared and all parameters are assigned
            in preparation for allocating a data reader.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.ExecuteDbDataReader(System.Data.CommandBehavior)">
            <summary>
            Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements
            </summary>
            <param name="behavior">The behavior the data reader should adopt</param>
            <returns>Returns a SQLiteDataReader object</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.ExecuteReader(System.Data.CommandBehavior)">
            <summary>
            Overrides the default behavior to return a SQLiteDataReader specialization class
            </summary>
            <param name="behavior">The flags to be associated with the reader</param>
            <returns>A SQLiteDataReader</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.ExecuteReader">
            <summary>
            Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class
            </summary>
            <returns>A SQLiteDataReader</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.ClearDataReader">
            <summary>
            Called by the SQLiteDataReader when the data reader is closed.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.ExecuteNonQuery">
            <summary>
            Execute the command and return the number of rows inserted/updated affected by it.
            </summary>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.ExecuteScalar">
            <summary>
            Execute the command and return the first column of the first row of the resultset
            (if present), or null if no resultset was returned.
            </summary>
            <returns>The first column of the first row of the first resultset from the query</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.Prepare">
            <summary>
            Does nothing.  Commands are prepared as they are executed the first time, and kept in prepared state afterwards.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommand.Clone">
            <summary>
            Clones a command, including all its parameters
            </summary>
            <returns>A new SQLiteCommand with the same commandtext, connection and parameters</returns>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.CommandText">
            <summary>
            The SQL command text associated with the command
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.CommandTimeout">
            <summary>
            The amount of time to wait for the connection to become available before erroring out
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.CommandType">
            <summary>
            The type of the command.  SQLite only supports CommandType.Text
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.Connection">
            <summary>
            The connection associated with this command
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.DbConnection">
            <summary>
            Forwards to the local Connection property
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.Parameters">
            <summary>
            Returns the SQLiteParameterCollection for the given command
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.DbParameterCollection">
            <summary>
            Forwards to the local Parameters property
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.Transaction">
            <summary>
            The transaction associated with this command.  SQLite only supports one transaction per connection, so this property forwards to the
            command's underlying connection.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.DbTransaction">
            <summary>
            Forwards to the local Transaction property
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.UpdatedRowSource">
            <summary>
            Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommand.DesignTimeVisible">
            <summary>
            Determines if the command is visible at design time.  Defaults to True.
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteTransaction">
            <summary>
            SQLite implementation of DbTransaction.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteTransaction._cnn">
            <summary>
            The connection to which this transaction is bound
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteTransaction.#ctor(System.Data.SQLite.SQLiteConnection,System.Boolean)">
            <summary>
            Constructs the transaction object, binding it to the supplied connection
            </summary>
            <param name="cnn">The connection to open a transaction on</param>
            <param name="deferredLock">TRUE to defer the writelock, or FALSE to lock immediately</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteTransaction.Commit">
            <summary>
            Commits the current transaction.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteTransaction.Dispose(System.Boolean)">
            <summary>
            Disposes the transaction.  If it is currently active, any changes are rolled back.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteTransaction.Rollback">
            <summary>
            Rolls back the active transaction.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteTransaction.Connection">
            <summary>
            Returns the underlying connection to which this transaction applies.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteTransaction.DbConnection">
            <summary>
            Forwards to the local Connection property
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteTransaction.IsolationLevel">
            <summary>
            Gets the isolation level of the transaction.  SQLite does not support isolation levels, so this always returns Unspecified.
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SynchronizationModes">
            <summary>
            The I/O file cache flushing behavior for the connection
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SynchronizationModes.Normal">
            <summary>
            Normal file flushing at critical sections of the code
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SynchronizationModes.Full">
            <summary>
            Full file flushing after every write operation
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SynchronizationModes.Off">
            <summary>
            Use the default operating system's file flushing, SQLite does not explicitly flush the file buffers after writing
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteConnection">
            <summary>
            SQLite implentation of DbConnection.
            </summary>
            <remarks>
            The <see cref="P:System.Data.SQLite.SQLiteConnection.ConnectionString">ConnectionString</see> property of the SQLiteConnection class can contain the following parameter(s), delimited with a semi-colon:
            <list type="table">
            <listheader>
            <term>Parameter</term>
            <term>Values</term>
            <term>Required</term>
            <term>Default</term>
            </listheader>
            <item>
            <description>Data Source</description>
            <description>{filename}</description>
            <description>Y</description>
            <description></description>
            </item>
            <item>
            <description>Version</description>
            <description>3</description>
            <description>N</description>
            <description>3</description>
            </item>
            <item>
            <description>UseUTF16Encoding</description>
            <description><b>True</b><br/><b>False</b></description>
            <description>N</description>
            <description>False</description>
            </item>
            <item>
            <description>DateTimeFormat</description>
            <description><b>Ticks</b> - Use DateTime.Ticks<br/><b>ISO8601</b> - Use ISO8601 DateTime format</description>
            <description>N</description>
            <description>ISO8601</description>
            </item>
            <item>
            <description>Cache Size</description>
            <description>{size in bytes}</description>
            <description>N</description>
            <description>2000</description>
            </item>
            <item>
            <description>Synchronous</description>
            <description><b>Normal</b> - Normal file flushing behavior<br/><b>Full</b> - Full flushing after all writes<br/><b>Off</b> - Underlying OS flushes I/O's</description>
            <description>N</description>
            <description>Normal</description>
            </item>
            <item>
            <description>Page Size</description>
            <description>{size in bytes}</description>
            <description>N</description>
            <description>1024</description>
            </item>
            <item>
            <description>Password</description>
            <description>{password}</description>
            <description>N</description>
            <description></description>
            </item>
            </list>
            </remarks>
        </member>
        <member name="F:System.Data.SQLite.SQLiteConnection._connectionState">
            <summary>
            State of the current connection
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteConnection._connectionString">
            <summary>
            The connection string
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteConnection._activeTransaction">
            <summary>
            One transaction allowed per connection please!
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteConnection._sql">
            <summary>
            The base SQLite object to interop with
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteConnection._commandList">
            <summary>
            Commands associated with this connection
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteConnection._dataSource">
            <summary>
            The database filename minus path and extension
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.#ctor">
            <overloads>
             Constructs a new SQLiteConnection object
             </overloads>
             <summary>
             Default constructor
             </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.#ctor(System.String)">
            <summary>
            Initializes the connection with the specified connection string
            </summary>
            <param name="connectionString">The connection string to use on the connection</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.#ctor(System.Data.SQLite.SQLiteConnection)">
            <summary>
            Clones the settings and connection string from an existing connection.  If the existing connection is already open, this
            function will open its own connection, enumerate any attached databases of the original connection, and automatically
            attach to them.
            </summary>
            <param name="cnn"></param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Clone">
            <summary>
            Creates a clone of the connection.  All attached databases and user-defined functions are cloned.  If the existing connection is open, the cloned connection 
            will also be opened.
            </summary>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Dispose(System.Boolean)">
            <summary>
            Disposes of the SQLiteConnection, closing it if it is active.
            </summary>
            <param name="disposing">True if the connection is being explicitly closed.</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.CreateFile(System.String)">
            <summary>
            Creates a database file.  This just creates a zero-byte file which SQLite
            will turn into a database when the file is opened properly.
            </summary>
            <param name="databaseFileName">The file to create</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.CompressFile(System.String)">
            <summary>
            On NTFS volumes, this function turns on the compression attribute for the given file.
            It must not be open or referenced at the time of the function call.
            </summary>
            <param name="databaseFileName">The file to compress</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.DecompressFile(System.String)">
            <summary>
            On NTFS volumes, this function removes the compression attribute for the given file.
            It must not be open or referenced at the time of the function call.
            </summary>
            <param name="databaseFileName">The file to decompress</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.EncryptFile(System.String)">
            <summary>
            On NTFS volumes, this function turns on the EFS (Encrypted File System) attribute
            for the given file, which causes the file to be encrypted.
            For a full description of EFS, see the MSDN documentation.
            </summary>
            <remarks>
            Requires Win2K and above, plus a valid EFS certificate (which is beyond the scope
            of this function description).
            </remarks>
            <param name="databaseFileName">The file to encrypt</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.DecryptFile(System.String)">
            <summary>
            On NTFS volumes, this function removes the encryption attribute from the file,
            causing the file to be decrypted.  See the MSDN documentation for full details on
            EFS (Encrypted File System).
            </summary>
            <remarks>
            Requires Win2K and above, plus a valid EFS certificate (which is beyond the scope
            of this function description).
            </remarks>
            <param name="databaseFileName">The file to decrypt</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.IsEncrypted(System.String)">
            <summary>
            Returns true if the file is encrypted, or false otherwise.
            </summary>
            <remarks>
            Requires Win2K and above, plus a valid EFS certificate (which is beyond the scope
            of this function description).
            </remarks>
            <param name="databaseFileName">The file to check</param>
            <returns>true if the file is encrypted</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.OnStateChange(System.Data.ConnectionState)">
            <summary>
            Raises the state change event when the state of the connection changes
            </summary>
            <param name="newState">The new state.  If it is different from the previous state, an event is raised.</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.BeginTransaction(System.Data.IsolationLevel,System.Boolean)">
            <summary>
            Creates a new SQLiteTransaction if one isn't already active on the connection.
            </summary>
            <param name="isolationLevel">SQLite doesn't support varying isolation levels, so this parameter is ignored.</param>
            <param name="deferredLock">When TRUE, SQLite defers obtaining a write lock until a write operation is requested.
            When FALSE, a writelock is obtained immediately.  The default is TRUE, but in a multi-threaded multi-writer 
            environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock.</param>
            <returns>Returns a SQLiteTransaction object.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.BeginTransaction(System.Boolean)">
            <summary>
            Creates a new SQLiteTransaction if one isn't already active on the connection.
            </summary>
            <param name="deferredLock">When TRUE, SQLite defers obtaining a write lock until a write operation is requested.
            When FALSE, a writelock is obtained immediately.  The default is TRUE, but in a multi-threaded multi-writer 
            environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock.</param>
            <returns>Returns a SQLiteTransaction object.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.BeginTransaction(System.Data.IsolationLevel)">
            <summary>
            Creates a new SQLiteTransaction if one isn't already active on the connection.
            </summary>
            <param name="isolationLevel">SQLite doesn't support varying isolation levels, so this parameter is ignored.</param>
            <returns>Returns a SQLiteTransaction object.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.BeginTransaction">
            <summary>
            Creates a new SQLiteTransaction if one isn't already active on the connection.
            </summary>
            <returns>Returns a SQLiteTransaction object.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.BeginDbTransaction(System.Data.IsolationLevel)">
            <summary>
            Forwards to the local BeginTransaction() function
            </summary>
            <param name="isolationLevel"></param>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.ChangeDatabase(System.String)">
            <summary>
            Not implemented
            </summary>
            <param name="databaseName"></param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Close">
            <summary>
            When the database connection is closed, all commands linked to this connection are automatically reset.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.CreateCommand">
            <summary>
            Create a new SQLiteCommand and associate it with this connection.
            </summary>
            <returns>Returns an instantiated SQLiteCommand object already assigned to this connection.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.CreateDbCommand">
            <summary>
            Forwards to the local CreateCommand() function
            </summary>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.ParseConnectionString">
            <summary>
            Parses the connection string into component parts
            </summary>
            <returns>An array of key-value pairs representing each parameter of the connection string</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.FindKey(System.Collections.Generic.KeyValuePair{System.String,System.String}[],System.String,System.String)">
            <summary>
            Looks for a key in the array of key/values of the parameter string.  If not found, return the specified default value
            </summary>
            <param name="opts">The Key/Value pair array to look in</param>
            <param name="key">The key to find</param>
            <param name="defValue">The default value to return if the key is not found</param>
            <returns>The value corresponding to the specified key, or the default value if not found.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Open">
            <summary>
            Opens the connection using the parameters found in the <see cref="P:System.Data.SQLite.SQLiteConnection.ConnectionString">ConnectionString</see>
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.ChangePassword(System.String)">
            <summary>
            Change the password (or assign a password) to an open database.
            </summary>
            <remarks>
            No readers or writers may be active for this process.  The database must already be open
            and if it already was password protected, the existing password must already have been supplied.
            </remarks>
            <param name="newPassword">The new password to assign to the database</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.ChangePassword(System.Byte[])">
            <summary>
            Change the password (or assign a password) to an open database.
            </summary>
            <remarks>
            No readers or writers may be active for this process.  The database must already be open
            and if it already was password protected, the existing password must already have been supplied.
            </remarks>
            <param name="newPassword">The new password to assign to the database</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.SetPassword(System.String)">
            <summary>
            Sets the password for a password-protected database.  A password-protected database is
            unusable for any operation until the password has been set.
            </summary>
            <param name="databasePassword">The password for the database</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.SetPassword(System.Byte[])">
            <summary>
            Sets the password for a password-protected database.  A password-protected database is
            unusable for any operation until the password has been set.
            </summary>
            <param name="databasePassword">The password for the database</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.GetSchema">
            <overloads>
             The following commands are used to extract schema information out of the database.  Valid schema types are:
             <list type="bullet">
             <item>
             <description>MetaDataCollections</description>
             </item>
             <item>
             <description>DataSourceInformation</description>
             </item>
             <item>
             <description>Columns</description>
             </item>
             <item>
             <description>Indexes</description>
             </item>
             <item>
             <description>Tables</description>
             </item>
             <item>
             <description>Views</description>
             </item>
             <item>
             <description>Catalogs</description>
             </item>
             </list>
             </overloads>
             <summary>
             Returns the MetaDataCollections schema
             </summary>
             <returns>A DataTable of the MetaDataCollections schema</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.GetSchema(System.String)">
            <summary>
            Returns schema information of the specified collection
            </summary>
            <param name="collectionName">The schema collection to retrieve</param>
            <returns>A DataTable of the specified collection</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.GetSchema(System.String,System.String[])">
            <summary>
            Retrieves schema information using the specified constraint(s) for the specified collection
            </summary>
            <param name="collectionName">The collection to retrieve</param>
            <param name="restrictionValues">The restrictions to impose</param>
            <returns>A DataTable of the specified collection</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Schema_MetaDataCollections">
            <summary>
            Builds a MetaDataCollections schema datatable
            </summary>
            <returns>DataTable</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Schema_DataSourceInformation">
            <summary>
            Builds a DataSourceInformation datatable
            </summary>
            <returns>DataTable</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Schema_Columns(System.String,System.String,System.String)">
            <summary>
            Build a Columns schema
            </summary>
            <param name="strCatalog">The catalog (attached database) to query, can be null</param>
            <param name="strTable">The table to retrieve schema information for, must not be null</param>
            <param name="strColumn">The column to retrieve schema information for, can be null</param>
            <returns>DataTable</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Schema_Indexes(System.String,System.String,System.String)">
            <summary>
            Returns index information for the given database and catalog
            </summary>
            <param name="strCatalog">The catalog (attached database) to query, can be null</param>
            <param name="strIndex">The name of the index to retrieve information for, can be null</param>
            <param name="strTable">The table to retrieve index information for, can be null</param>
            <returns>DataTable</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Schema_Tables(System.String,System.String,System.String)">
            <summary>
            Retrieves table schema information for the database and catalog
            </summary>
            <param name="strCatalog">The catalog (attached database) to retrieve tables on</param>
            <param name="strTable">The table to retrieve, can be null</param>
            <param name="strType">The table type, can be null</param>
            <returns>DataTable</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Schema_Views(System.String,System.String)">
            <summary>
            Retrieves view schema information for the database
            </summary>
            <param name="strCatalog">The catalog (attached database) to retrieve views on</param>
            <param name="strView">The view name, can be null</param>
            <returns>DataTable</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Schema_Catalogs(System.String)">
            <summary>
            Retrieves catalog (attached databases) schema information for the database
            </summary>
            <param name="strCatalog">The catalog to retrieve, can be null</param>
            <returns>DataTable</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Schema_IndexColumns(System.String,System.String,System.String,System.String)">
            <summary>
            Returns the base column information for indexes in a database
            </summary>
            <param name="strCatalog">The catalog to retrieve indexes for (can be null)</param>
            <param name="strTable">The table to restrict index information by (can be null)</param>
            <param name="strIndex">The index to restrict index information by (can be null)</param>
            <param name="strColumn">The source column to restrict index information by (can be null)</param>
            <returns>A DataTable containing the results</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Schema_ViewColumns(System.String,System.String,System.String)">
            <summary>
            Returns detailed column information for a specified view
            </summary>
            <param name="strCatalog">The catalog to retrieve columns for (can be null)</param>
            <param name="strView">The view to restrict column information by (can be null)</param>
            <param name="strColumn">The source column to restrict column information by (can be null)</param>
            <returns>A DataTable containing the results</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnection.Schema_ForeignKeys(System.String,System.String,System.String)">
            <summary>
            Retrieves foreign key information from the specified set of filters
            </summary>
            <param name="strCatalog">An optional catalog to restrict results on</param>
            <param name="strTable">An optional table to restrict results on</param>
            <param name="strKeyName">An optional foreign key name to restrict results on</param>
            <returns>A DataTable with the results of the query</returns>
        </member>
        <member name="E:System.Data.SQLite.SQLiteConnection.StateChange">
            <event/>
            <summary>
            This event is raised whenever the database is opened or closed.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnection.ConnectionString">
            <summary>
            The connection string containing the parameters for the connection
            </summary>
            <remarks>
            <list type="table">
            <listheader>
            <term>Parameter</term>
            <term>Values</term>
            <term>Required</term>
            <term>Default</term>
            </listheader>
            <item>
            <description>Data Source</description>
            <description>{filename}</description>
            <description>Y</description>
            <description></description>
            </item>
            <item>
            <description>Version</description>
            <description>3</description>
            <description>N</description>
            <description>3</description>
            </item>
            <item>
            <description>UseUTF16Encoding</description>
            <description><b>True</b><br/><b>False</b></description>
            <description>N</description>
            <description>False</description>
            </item>
            <item>
            <description>DateTimeFormat</description>
            <description><b>Ticks</b> - Use DateTime.Ticks<br/><b>ISO8601</b> - Use ISO8601 DateTime format</description>
            <description>N</description>
            <description>ISO8601</description>
            </item>
            <item>
            <description>Cache Size</description>
            <description>{size in bytes}</description>
            <description>N</description>
            <description>2000</description>
            </item>
            <item>
            <description>Synchronous</description>
            <description><b>Normal</b> - Normal file flushing behavior<br/><b>Full</b> - Full flushing after all writes<br/><b>Off</b> - Underlying OS flushes I/O's</description>
            <description>N</description>
            <description>Normal</description>
            </item>
            <item>
            <description>Page Size</description>
            <description>{size in bytes}</description>
            <description>N</description>
            <description>1024</description>
            </item>
            <item>
            <description>Password</description>
            <description>{password}</description>
            <description>N</description>
            <description></description>
            </item>
            </list>
            </remarks>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnection.DataSource">
            <summary>
            Returns the filename without extension or path
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnection.Database">
            <summary>
            Returns an empty string
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnection.ServerVersion">
            <summary>
            Returns the version of the underlying SQLite database engine
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnection.State">
            <summary>
            Returns the state of the connection.
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteCommandBuilder">
            <summary>
            SQLite implementation of DbCommandBuilder.
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.#ctor">
            <summary>
            Default constructor
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.#ctor(System.Data.SQLite.SQLiteDataAdapter)">
            <summary>
            Initializes the command builder and associates it with the specified data adapter.
            </summary>
            <param name="adp"></param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.ApplyParameterInfo(System.Data.Common.DbParameter,System.Data.DataRow,System.Data.StatementType,System.Boolean)">
            <summary>
            Not implemented, this function does nothing.
            </summary>
            <param name="parameter">The parameter to use in applying custom behaviors to a row</param>
            <param name="row">The row to apply the parameter to</param>
            <param name="statementType">The type of statement</param>
            <param name="whereClause">Whether the application of the parameter is part of a WHERE clause</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.GetParameterName(System.String)">
            <overloads>
            Not implemented.  Throws a NotImplementedException() if called.
            </overloads>
            <summary>
            Not implemented.
            </summary>
            <param name="parameterName">The name of the parameter</param>
            <returns>Error</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.GetParameterName(System.Int32)">
            <summary>
            Not implemented.
            </summary>
            <param name="parameterOrdinal">The i of the parameter</param>
            <returns>Error</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.GetParameterPlaceholder(System.Int32)">
            <summary>
            Returns a placeholder character for the specified parameter i.
            </summary>
            <param name="parameterOrdinal">The index of the parameter to provide a placeholder for</param>
            <returns>Returns a "?" character, used for all placeholders.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.SetRowUpdatingHandler(System.Data.Common.DbDataAdapter)">
            <summary>
            Sets the handler for receiving row updating events.  Used by the DbCommandBuilder to autogenerate SQL
            statements that may not have previously been generated.
            </summary>
            <param name="adapter">A data adapter to receive events on.</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.GetDeleteCommand">
            <summary>
            Returns the automatically-generated SQLite command to delete rows from the database
            </summary>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.GetDeleteCommand(System.Boolean)">
            <summary>
            Returns the automatically-generated SQLite command to delete rows from the database
            </summary>
            <param name="useColumnsForParameterNames"></param>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.GetUpdateCommand">
            <summary>
            Returns the automatically-generated SQLite command to update rows in the database
            </summary>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.GetUpdateCommand(System.Boolean)">
            <summary>
            Returns the automatically-generated SQLite command to update rows in the database
            </summary>
            <param name="useColumnsForParameterNames"></param>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.GetInsertCommand">
            <summary>
            Returns the automatically-generated SQLite command to insert rows into the database
            </summary>
            <returns></returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteCommandBuilder.GetInsertCommand(System.Boolean)">
            <summary>
            Returns the automatically-generated SQLite command to insert rows into the database
            </summary>
            <param name="useColumnsForParameterNames"></param>
            <returns></returns>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommandBuilder.DataAdapter">
            <summary>
            Gets/sets the DataAdapter for this CommandBuilder
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommandBuilder.CatalogLocation">
            <summary>
            Overridden to hide its property from the designer
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommandBuilder.CatalogSeparator">
            <summary>
            Overridden to hide its property from the designer
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommandBuilder.QuotePrefix">
            <summary>
            Overridden to hide its property from the designer
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommandBuilder.QuoteSuffix">
            <summary>
            Overridden to hide its property from the designer
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteCommandBuilder.SchemaSeparator">
            <summary>
            Overridden to hide its property from the designer
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLite3_UTF16">
            <summary>
            Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode)
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLite3_UTF16.ToString(System.IntPtr,System.Int32)">
            <summary>
            Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8
            </summary>
            <param name="b">A pointer to a UTF-16 string</param>
            <param name="nbytelen">The length (IN BYTES) of the string</param>
            <returns>A .NET string</returns>
        </member>
        <member name="T:System.Data.SQLite.SQLiteParameterCollection">
            <summary>
            SQLite implementation of DbParameterCollection.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteParameterCollection._command">
            <summary>
            The underlying command to which this collection belongs
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteParameterCollection._parameterList">
            <summary>
            The internal array of parameters in this collection
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteParameterCollection._unboundFlag">
            <summary>
            Determines whether or not all parameters have been bound to their statement(s)
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.#ctor(System.Data.SQLite.SQLiteCommand)">
            <summary>
            Initializes the collection
            </summary>
            <param name="cmd">The command to which the collection belongs</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.GetEnumerator">
            <summary>
            Retrieves an enumerator for the collection
            </summary>
            <returns>An enumerator for the underlying array</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Add(System.String,System.Data.DbType,System.Int32,System.String)">
            <summary>
            Adds a parameter to the collection
            </summary>
            <param name="parameterName">The parameter name</param>
            <param name="parameterType">The data type</param>
            <param name="parameterSize">The size of the value</param>
            <param name="sourceColumn">The source column</param>
            <returns>A SQLiteParameter object</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Add(System.String,System.Data.DbType,System.Int32)">
            <summary>
            Adds a parameter to the collection
            </summary>
            <param name="parameterName">The parameter name</param>
            <param name="parameterType">The data type</param>
            <param name="parameterSize">The size of the value</param>
            <returns>A SQLiteParameter object</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Add(System.String,System.Data.DbType)">
            <summary>
            Adds a parameter to the collection
            </summary>
            <param name="parameterName">The parameter name</param>
            <param name="parameterType">The data type</param>
            <returns>A SQLiteParameter object</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Add(System.Data.Common.DbParameter)">
            <summary>
            Adds a parameter to the collection
            </summary>
            <param name="parameter">The parameter to add</param>
            <returns>A zero-based index of where the parameter is located in the array</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Add(System.Object)">
            <summary>
            Adds a parameter to the collection
            </summary>
            <param name="value">The parameter to add</param>
            <returns>A zero-based index of where the parameter is located in the array</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.AddWithValue(System.String,System.Object)">
            <summary>
            Adds a named/unnamed parameter and its value to the parameter collection.
            </summary>
            <param name="parameterName">Name of the parameter, or null to indicate an unnamed parameter</param>
            <param name="value">The initial value of the parameter</param>
            <returns>Returns the SQLiteParameter object created during the call.</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.AddRange(System.Data.Common.DbParameter[])">
            <summary>
            Adds an array of parameters to the collection
            </summary>
            <param name="values">The array of parameters to add</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.AddRange(System.Array)">
            <summary>
            Adds an array of parameters to the collection
            </summary>
            <param name="values">The array of parameters to add</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Clear">
            <summary>
            Clears the array and resets the collection
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Contains(System.String)">
            <summary>
            Determines if the named parameter exists in the collection
            </summary>
            <param name="parameterName">The name of the parameter to check</param>
            <returns>True if the parameter is in the collection</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Contains(System.Object)">
            <summary>
            Determines if the parameter exists in the collection
            </summary>
            <param name="value">The SQLiteParameter to check</param>
            <returns>True if the parameter is in the collection</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.CopyTo(System.Array,System.Int32)">
            <summary>
            Not implemented
            </summary>
            <param name="array"></param>
            <param name="index"></param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.GetParameter(System.String)">
            <summary>
            Retrieve a parameter by name from the collection
            </summary>
            <param name="parameterName">The name of the parameter to fetch</param>
            <returns>A DbParameter object</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.GetParameter(System.Int32)">
            <summary>
            Retrieves a parameter by its index in the collection
            </summary>
            <param name="index">The index of the parameter to retrieve</param>
            <returns>A DbParameter object</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.IndexOf(System.String)">
            <summary>
            Returns the index of a parameter given its name
            </summary>
            <param name="parameterName">The name of the parameter to find</param>
            <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.IndexOf(System.Object)">
            <summary>
            Returns the index of a parameter
            </summary>
            <param name="value">The parameter to find</param>
            <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Insert(System.Int32,System.Object)">
            <summary>
            Inserts a parameter into the array at the specified location
            </summary>
            <param name="index">The zero-based index to insert the parameter at</param>
            <param name="value">The parameter to insert</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Remove(System.Object)">
            <summary>
            Removes a parameter from the collection
            </summary>
            <param name="value">The parameter to remove</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.RemoveAt(System.String)">
            <summary>
            Removes a parameter from the collection given its name
            </summary>
            <param name="parameterName">The name of the parameter to remove</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.RemoveAt(System.Int32)">
            <summary>
            Removes a parameter from the collection given its index
            </summary>
            <param name="index">The zero-based parameter index to remove</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.SetParameter(System.String,System.Data.Common.DbParameter)">
            <summary>
            Re-assign the named parameter to a new parameter object
            </summary>
            <param name="parameterName">The name of the parameter to replace</param>
            <param name="value">The new parameter</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.SetParameter(System.Int32,System.Data.Common.DbParameter)">
            <summary>
            Re-assign a parameter at the specified index
            </summary>
            <param name="index">The zero-based index of the parameter to replace</param>
            <param name="value">The new parameter</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.Unbind">
            <summary>
            Un-binds all parameters from their statements
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameterCollection.MapParameters(System.Data.SQLite.SQLiteStatement)">
            <summary>
            This function attempts to map all parameters in the collection to all statements in a Command.
            Since named parameters may span multiple statements, this function makes sure all statements are bound
            to the same named parameter.  Unnamed parameters are bound in sequence.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameterCollection.IsSynchronized">
            <summary>
            Returns true
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameterCollection.IsFixedSize">
            <summary>
            Returns false
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameterCollection.IsReadOnly">
            <summary>
            Returns false
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameterCollection.SyncRoot">
            <summary>
            Returns null
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameterCollection.Count">
            <summary>
            Returns a count of parameters in the collection
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteParameter">
            <summary>
            SQLite implementation of DbParameter.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteParameter._dbType">
            <summary>
            The data type of the parameter
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteParameter._rowVersion">
            <summary>
            The version information for mapping the parameter
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteParameter._objValue">
            <summary>
            The value of the data in the parameter
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteParameter._sourceColumn">
            <summary>
            The source column for the parameter
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteParameter._columnName">
            <summary>
            The column name
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteParameter._dataSize">
            <summary>
            The data size, unused by SQLite
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor">
            <summary>
            Default constructor
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.String)">
            <summary>
            Constructs a named parameter given the specified parameter name
            </summary>
            <param name="parameterName">The parameter name</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.String,System.Object)">
            <summary>
            Constructs a named parameter given the specified parameter name and initial value
            </summary>
            <param name="parameterName">The parameter name</param>
            <param name="value">The initial value of the parameter</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.String,System.Data.DbType)">
            <summary>
            Constructs a named parameter of the specified type
            </summary>
            <param name="parameterName">The parameter name</param>
            <param name="dbType">The datatype of the parameter</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.String,System.Data.DbType,System.String)">
            <summary>
            Constructs a named parameter of the specified type and source column reference
            </summary>
            <param name="parameterName">The parameter name</param>
            <param name="dbType">The data type</param>
            <param name="sourceColumn">The source column</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.String,System.Data.DbType,System.String,System.Data.DataRowVersion)">
            <summary>
            Constructs a named parameter of the specified type, source column and row version
            </summary>
            <param name="parameterName">The parameter name</param>
            <param name="dbType">The data type</param>
            <param name="sourceColumn">The source column</param>
            <param name="rowVersion">The row version information</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.Data.DbType)">
            <summary>
            Constructs an unnamed parameter of the specified data type
            </summary>
            <param name="dbType">The datatype of the parameter</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.Data.DbType,System.Object)">
            <summary>
            Constructs an unnamed parameter of the specified data type and sets the initial value
            </summary>
            <param name="dbType">The datatype of the parameter</param>
            <param name="value">The initial value of the parameter</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.Data.DbType,System.String)">
            <summary>
            Constructs an unnamed parameter of the specified data type and source column
            </summary>
            <param name="dbType">The datatype of the parameter</param>
            <param name="sourceColumn">The source column</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.Data.DbType,System.String,System.Data.DataRowVersion)">
            <summary>
            Constructs an unnamed parameter of the specified data type, source column and row version
            </summary>
            <param name="dbType">The data type</param>
            <param name="sourceColumn">The source column</param>
            <param name="rowVersion">The row version information</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.String,System.Data.DbType,System.Int32)">
            <summary>
            Constructs a named parameter of the specified type and size
            </summary>
            <param name="parameterName">The parameter name</param>
            <param name="parameterType">The data type</param>
            <param name="parameterSize">The size of the parameter</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.String,System.Data.DbType,System.Int32,System.String)">
            <summary>
            Constructs a named parameter of the specified type, size and source column
            </summary>
            <param name="parameterName">The name of the parameter</param>
            <param name="parameterType">The data type</param>
            <param name="parameterSize">The size of the parameter</param>
            <param name="sourceColumn">The source column</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.String,System.Data.DbType,System.Int32,System.String,System.Data.DataRowVersion)">
            <summary>
            Constructs a named parameter of the specified type, size, source column and row version
            </summary>
            <param name="parameterName">The name of the parameter</param>
            <param name="parameterType">The data type</param>
            <param name="parameterSize">The size of the parameter</param>
            <param name="sourceColumn">The source column</param>
            <param name="rowVersion">The row version information</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.String,System.Data.DbType,System.Int32,System.Data.ParameterDirection,System.Boolean,System.Byte,System.Byte,System.String,System.Data.DataRowVersion,System.Object)">
            <summary>
            Constructs a named parameter of the specified type, size, source column and row version
            </summary>
            <param name="parameterName">The name of the parameter</param>
            <param name="parameterType">The data type</param>
            <param name="parameterSize">The size of the parameter</param>
            <param name="direction">Only input parameters are supported in SQLite</param>
            <param name="isNullable">Ignored</param>
            <param name="precision">Ignored</param>
            <param name="scale">Ignored</param>
            <param name="sourceColumn">The source column</param>
            <param name="rowVersion">The row version information</param>
            <param name="value">The initial value to assign the parameter</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.Data.DbType,System.Int32)">
            <summary>
            Constructs an unnamed parameter of the specified type and size
            </summary>
            <param name="parameterType">The data type</param>
            <param name="parameterSize">The size of the parameter</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.Data.DbType,System.Int32,System.String)">
            <summary>
            Constructs an unnamed parameter of the specified type, size, and source column
            </summary>
            <param name="parameterType">The data type</param>
            <param name="parameterSize">The size of the parameter</param>
            <param name="sourceColumn">The source column</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.#ctor(System.Data.DbType,System.Int32,System.String,System.Data.DataRowVersion)">
            <summary>
            Constructs an unnamed parameter of the specified type, size, source column and row version
            </summary>
            <param name="parameterType">The data type</param>
            <param name="parameterSize">The size of the parameter</param>
            <param name="sourceColumn">The source column</param>
            <param name="rowVersion">The row version information</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.Initialize(System.String,System.Int32,System.Int32,System.String,System.Data.DataRowVersion)">
            <summary>
            Initializes the parameter member variables
            </summary>
            <param name="parameterName">The parameter name</param>
            <param name="paramType">The data type</param>
            <param name="nSize">The size</param>
            <param name="sourceColumn">The source column</param>
            <param name="rowVersion">The row version</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.ResetDbType">
            <summary>
            Not implemented
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteParameter.Clone">
            <summary>
            Clones a parameter
            </summary>
            <returns>A new, unassociated SQLiteParameter</returns>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameter.IsNullable">
            <summary>
            Returns True.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameter.DbType">
            <summary>
            Returns the datatype of the parameter
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameter.Direction">
            <summary>
            Supports only input parameters
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameter.ParameterName">
            <summary>
            Returns the parameter name
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameter.Size">
            <summary>
            Returns the size of the parameter
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameter.SourceColumn">
            <summary>
            Gets/sets the source column
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameter.SourceColumnNullMapping">
            <summary>
            Returns false, ignores any set value
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameter.SourceVersion">
            <summary>
            Gets and sets the row version
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteParameter.Value">
            <summary>
            Gets and sets the parameter value.  If no datatype was specified, the datatype will assume the type from the value given.
            </summary>
        </member>
        <member name="T:System.Data.SQLite.SQLiteConnectionStringBuilder">
            <summary>
            SQLite implementation of DbConnectionStringBuilder.
            </summary>
        </member>
        <member name="F:System.Data.SQLite.SQLiteConnectionStringBuilder._properties">
            <summary>
            Properties of this class
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnectionStringBuilder.#ctor">
            <overloads>
            Constructs a new instance of the class
            </overloads>
            <summary>
            Default constructor
            </summary>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnectionStringBuilder.#ctor(System.String)">
            <summary>
            Constructs a new instance of the class using the specified connection string.
            </summary>
            <param name="connectionString">The connection string to parse</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnectionStringBuilder.Initialize(System.String)">
            <summary>
            Private initializer, which assigns the connection string and resets the builder
            </summary>
            <param name="cnnString">The connection string to assign</param>
        </member>
        <member name="M:System.Data.SQLite.SQLiteConnectionStringBuilder.TryGetValue(System.String,System.Object@)">
            <summary>
            Helper function for retrieving values from the connectionstring
            </summary>
            <param name="keyword">The keyword to retrieve settings for</param>
            <param name="value">The resulting parameter value</param>
            <returns>Returns true if the value was found and returned</returns>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnectionStringBuilder.Version">
            <summary>
            Gets/Sets the default version of the SQLite engine to instantiate.  Currently the only valid value is 3, indicating version 3 of the sqlite library.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnectionStringBuilder.SyncMode">
            <summary>
            Gets/Sets the synchronous mode of the connection string.  Default is "Normal".
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnectionStringBuilder.UseUTF16Encoding">
            <summary>
            Gets/Sets the encoding for the connection string.  The default is "False" which indicates UTF-8 encoding.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnectionStringBuilder.DataSource">
            <summary>
            Gets/Sets the filename to open on the connection string.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnectionStringBuilder.Password">
            <summary>
            Gets/sets the database encryption password
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnectionStringBuilder.PageSize">
            <summary>
            Gets/Sets the page size for the connection.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnectionStringBuilder.CacheSize">
            <summary>
            Gets/Sets the cache size for the connection.
            </summary>
        </member>
        <member name="P:System.Data.SQLite.SQLiteConnectionStringBuilder.DateTimeFormat">
            <summary>
            Gets/Sets the datetime format for the connection.
            </summary>
        </member>
    </members>
</doc>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to Doc/ndoc.log.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
System.Data.SQLite.SQLiteCommand.html
System.Data.SQLite.SQLiteCommandMembers.html
System.Data.SQLite.SQLiteCommandConstructor.html
System.Data.SQLite.SQLiteCommandConstructor1.html
System.Data.SQLite.SQLiteCommandConstructor2.html
System.Data.SQLite.SQLiteCommandConstructor3.html
System.Data.SQLite.SQLiteCommandConstructor4.html
System.Data.SQLite.SQLiteCommandConstructor5.html
System.Data.SQLite.SQLiteCommandProperties.html
System.Data.SQLite.SQLiteCommand.CommandText.html
System.Data.SQLite.SQLiteCommand.CommandTimeout.html
System.Data.SQLite.SQLiteCommand.CommandType.html
System.Data.SQLite.SQLiteCommand.DesignTimeVisible.html
System.Data.SQLite.SQLiteCommand.UpdatedRowSource.html
System.Data.SQLite.SQLiteCommandMethods.html







<







23
24
25
26
27
28
29

30
31
32
33
34
35
36
System.Data.SQLite.SQLiteCommand.html
System.Data.SQLite.SQLiteCommandMembers.html
System.Data.SQLite.SQLiteCommandConstructor.html
System.Data.SQLite.SQLiteCommandConstructor1.html
System.Data.SQLite.SQLiteCommandConstructor2.html
System.Data.SQLite.SQLiteCommandConstructor3.html
System.Data.SQLite.SQLiteCommandConstructor4.html

System.Data.SQLite.SQLiteCommandProperties.html
System.Data.SQLite.SQLiteCommand.CommandText.html
System.Data.SQLite.SQLiteCommand.CommandTimeout.html
System.Data.SQLite.SQLiteCommand.CommandType.html
System.Data.SQLite.SQLiteCommand.DesignTimeVisible.html
System.Data.SQLite.SQLiteCommand.UpdatedRowSource.html
System.Data.SQLite.SQLiteCommandMethods.html
87
88
89
90
91
92
93

94
95
96
97
98
99
100
System.Data.SQLite.SQLiteConvert.ToDateTime.html
System.Data.SQLite.SQLiteConvert.ToString_overloads.html
System.Data.SQLite.SQLiteConvert.ToString_overload_2.html
System.Data.SQLite.SQLiteConvert.ToString_overload_1.html
System.Data.SQLite.SQLiteConvert.ToUTF8_overloads.html
System.Data.SQLite.SQLiteConvert.ToUTF8_overload_2.html
System.Data.SQLite.SQLiteConvert.ToUTF8_overload_1.html

System.Data.SQLite.SQLiteDataAdapter.html
System.Data.SQLite.SQLiteDataAdapterMembers.html
System.Data.SQLite.SQLiteDataAdapterConstructor.html
System.Data.SQLite.SQLiteDataAdapterConstructor1.html
System.Data.SQLite.SQLiteDataAdapterConstructor2.html
System.Data.SQLite.SQLiteDataAdapterConstructor3.html
System.Data.SQLite.SQLiteDataAdapterConstructor4.html







>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
System.Data.SQLite.SQLiteConvert.ToDateTime.html
System.Data.SQLite.SQLiteConvert.ToString_overloads.html
System.Data.SQLite.SQLiteConvert.ToString_overload_2.html
System.Data.SQLite.SQLiteConvert.ToString_overload_1.html
System.Data.SQLite.SQLiteConvert.ToUTF8_overloads.html
System.Data.SQLite.SQLiteConvert.ToUTF8_overload_2.html
System.Data.SQLite.SQLiteConvert.ToUTF8_overload_1.html
System.Data.SQLite.SQLiteConvert.TryToDateTime.html
System.Data.SQLite.SQLiteDataAdapter.html
System.Data.SQLite.SQLiteDataAdapterMembers.html
System.Data.SQLite.SQLiteDataAdapterConstructor.html
System.Data.SQLite.SQLiteDataAdapterConstructor1.html
System.Data.SQLite.SQLiteDataAdapterConstructor2.html
System.Data.SQLite.SQLiteDataAdapterConstructor3.html
System.Data.SQLite.SQLiteDataAdapterConstructor4.html
140
141
142
143
144
145
146


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
System.Data.SQLite.SQLiteException.html
System.Data.SQLite.SQLiteExceptionMembers.html
System.Data.SQLite.SQLiteFactory.html
System.Data.SQLite.SQLiteFactoryMembers.html
System.Data.SQLite.SQLiteFactoryConstructor.html
System.Data.SQLite.SQLiteFactoryFields.html
System.Data.SQLite.SQLiteFactory.Instance.html


System.Data.SQLite.SQLiteFactoryMethods.html
System.Data.SQLite.SQLiteFactory.CreateCommand.html
System.Data.SQLite.SQLiteFactory.CreateCommandBuilder.html
System.Data.SQLite.SQLiteFactory.CreateConnection.html
System.Data.SQLite.SQLiteFactory.CreateConnectionStringBuilder.html
System.Data.SQLite.SQLiteFactory.CreateDataAdapter.html
System.Data.SQLite.SQLiteFactory.CreateParameter.html
System.Data.SQLite.SQLiteFunction.html
System.Data.SQLite.SQLiteFunctionMembers.html
System.Data.SQLite.SQLiteFunctionConstructor.html
System.Data.SQLite.SQLiteFunctionProperties.html
System.Data.SQLite.SQLiteFunction.SQLiteConvert.html
System.Data.SQLite.SQLiteFunctionMethods.html
System.Data.SQLite.SQLiteFunction.Compare.html
System.Data.SQLite.SQLiteFunction.Dispose_overloads.html
System.Data.SQLite.SQLiteFunction.Dispose_overload_2.html
System.Data.SQLite.SQLiteFunction.Dispose_overload_1.html
System.Data.SQLite.SQLiteFunction.Final.html
System.Data.SQLite.SQLiteFunction.Invoke.html

System.Data.SQLite.SQLiteFunction.Step.html
System.Data.SQLite.SQLiteFunctionAttribute.html
System.Data.SQLite.SQLiteFunctionAttributeMembers.html
System.Data.SQLite.SQLiteFunctionAttributeConstructor.html
System.Data.SQLite.SQLiteFunctionAttributeFields.html
System.Data.SQLite.SQLiteFunctionAttribute.Arguments.html
System.Data.SQLite.SQLiteFunctionAttribute.FuncType.html







>
>



















>







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
System.Data.SQLite.SQLiteException.html
System.Data.SQLite.SQLiteExceptionMembers.html
System.Data.SQLite.SQLiteFactory.html
System.Data.SQLite.SQLiteFactoryMembers.html
System.Data.SQLite.SQLiteFactoryConstructor.html
System.Data.SQLite.SQLiteFactoryFields.html
System.Data.SQLite.SQLiteFactory.Instance.html
System.Data.SQLite.SQLiteFactoryProperties.html
System.Data.SQLite.SQLiteFactory.SupportedClasses.html
System.Data.SQLite.SQLiteFactoryMethods.html
System.Data.SQLite.SQLiteFactory.CreateCommand.html
System.Data.SQLite.SQLiteFactory.CreateCommandBuilder.html
System.Data.SQLite.SQLiteFactory.CreateConnection.html
System.Data.SQLite.SQLiteFactory.CreateConnectionStringBuilder.html
System.Data.SQLite.SQLiteFactory.CreateDataAdapter.html
System.Data.SQLite.SQLiteFactory.CreateParameter.html
System.Data.SQLite.SQLiteFunction.html
System.Data.SQLite.SQLiteFunctionMembers.html
System.Data.SQLite.SQLiteFunctionConstructor.html
System.Data.SQLite.SQLiteFunctionProperties.html
System.Data.SQLite.SQLiteFunction.SQLiteConvert.html
System.Data.SQLite.SQLiteFunctionMethods.html
System.Data.SQLite.SQLiteFunction.Compare.html
System.Data.SQLite.SQLiteFunction.Dispose_overloads.html
System.Data.SQLite.SQLiteFunction.Dispose_overload_2.html
System.Data.SQLite.SQLiteFunction.Dispose_overload_1.html
System.Data.SQLite.SQLiteFunction.Final.html
System.Data.SQLite.SQLiteFunction.Invoke.html
System.Data.SQLite.SQLiteFunction.RegisterFunction.html
System.Data.SQLite.SQLiteFunction.Step.html
System.Data.SQLite.SQLiteFunctionAttribute.html
System.Data.SQLite.SQLiteFunctionAttributeMembers.html
System.Data.SQLite.SQLiteFunctionAttributeConstructor.html
System.Data.SQLite.SQLiteFunctionAttributeFields.html
System.Data.SQLite.SQLiteFunctionAttribute.Arguments.html
System.Data.SQLite.SQLiteFunctionAttribute.FuncType.html
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
System.Data.SQLite.SQLiteParameterConstructor8.html
System.Data.SQLite.SQLiteParameterConstructor9.html
System.Data.SQLite.SQLiteParameterConstructor10.html
System.Data.SQLite.SQLiteParameterConstructor11.html
System.Data.SQLite.SQLiteParameterConstructor12.html
System.Data.SQLite.SQLiteParameterConstructor13.html
System.Data.SQLite.SQLiteParameterConstructor14.html
System.Data.SQLite.SQLiteParameterConstructor15.html
System.Data.SQLite.SQLiteParameterConstructor16.html
System.Data.SQLite.SQLiteParameterConstructor17.html
System.Data.SQLite.SQLiteParameterProperties.html
System.Data.SQLite.SQLiteParameter.DbType.html
System.Data.SQLite.SQLiteParameter.Direction.html
System.Data.SQLite.SQLiteParameter.IsNullable.html
System.Data.SQLite.SQLiteParameter.Offset.html
System.Data.SQLite.SQLiteParameter.ParameterName.html
System.Data.SQLite.SQLiteParameter.Size.html
System.Data.SQLite.SQLiteParameter.SourceColumn.html
System.Data.SQLite.SQLiteParameter.SourceColumnNullMapping.html
System.Data.SQLite.SQLiteParameter.SourceVersion.html
System.Data.SQLite.SQLiteParameter.Value.html
System.Data.SQLite.SQLiteParameterMethods.html

System.Data.SQLite.SQLiteParameter.ResetDbType.html
System.Data.SQLite.SQLiteParameterCollection.html
System.Data.SQLite.SQLiteParameterCollectionMembers.html
System.Data.SQLite.SQLiteParameterCollectionProperties.html
System.Data.SQLite.SQLiteParameterCollection.Count.html
System.Data.SQLite.SQLiteParameterCollection.IsFixedSize.html
System.Data.SQLite.SQLiteParameterCollection.IsReadOnly.html







<
<
<












>







187
188
189
190
191
192
193



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
System.Data.SQLite.SQLiteParameterConstructor8.html
System.Data.SQLite.SQLiteParameterConstructor9.html
System.Data.SQLite.SQLiteParameterConstructor10.html
System.Data.SQLite.SQLiteParameterConstructor11.html
System.Data.SQLite.SQLiteParameterConstructor12.html
System.Data.SQLite.SQLiteParameterConstructor13.html
System.Data.SQLite.SQLiteParameterConstructor14.html



System.Data.SQLite.SQLiteParameterProperties.html
System.Data.SQLite.SQLiteParameter.DbType.html
System.Data.SQLite.SQLiteParameter.Direction.html
System.Data.SQLite.SQLiteParameter.IsNullable.html
System.Data.SQLite.SQLiteParameter.Offset.html
System.Data.SQLite.SQLiteParameter.ParameterName.html
System.Data.SQLite.SQLiteParameter.Size.html
System.Data.SQLite.SQLiteParameter.SourceColumn.html
System.Data.SQLite.SQLiteParameter.SourceColumnNullMapping.html
System.Data.SQLite.SQLiteParameter.SourceVersion.html
System.Data.SQLite.SQLiteParameter.Value.html
System.Data.SQLite.SQLiteParameterMethods.html
System.Data.SQLite.SQLiteParameter.CopyTo.html
System.Data.SQLite.SQLiteParameter.ResetDbType.html
System.Data.SQLite.SQLiteParameterCollection.html
System.Data.SQLite.SQLiteParameterCollectionMembers.html
System.Data.SQLite.SQLiteParameterCollectionProperties.html
System.Data.SQLite.SQLiteParameterCollection.Count.html
System.Data.SQLite.SQLiteParameterCollection.IsFixedSize.html
System.Data.SQLite.SQLiteParameterCollection.IsReadOnly.html
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
Compiling Html Help file
Microsoft HTML Help Compiler 4.74.8702

Compiling c:\src\SQLite.NET\Doc\ndoc_msdn_temp\SQLite.NET.chm


Compile time: 0 minutes, 3 seconds
232	Topics
1,341	Local links
0	Internet links
8	Graphics


Created c:\src\SQLite.NET\Doc\ndoc_msdn_temp\SQLite.NET.chm, 142,903 bytes
Compression decreased file by 746,084 bytes.

Html Help compile complete
Done.







|
|




|
|



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
Compiling Html Help file
Microsoft HTML Help Compiler 4.74.8702

Compiling c:\src\SQLite.NET\Doc\ndoc_msdn_temp\SQLite.NET.chm


Compile time: 0 minutes, 3 seconds
233	Topics
1,346	Local links
0	Internet links
8	Graphics


Created c:\src\SQLite.NET\Doc\ndoc_msdn_temp\SQLite.NET.chm, 135,017 bytes
Compression decreased file by 734,402 bytes.

Html Help compile complete
Done.
Deleted SQLite.Designer/AssemblyInfo.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SQLite.Designer")]
[assembly: AssemblyDescription("ADO.NET 2.0 Data Designer for SQLite")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("http://sourceforge.net/projects/sqlite-dotnet2")]
[assembly: AssemblyProduct("SQLite.Designer")]
[assembly: AssemblyCopyright("Public Domain")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM componenets.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
[assembly: ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.24.5")]
[assembly: AssemblyFileVersion("1.0.24.5")]
[assembly:AssemblyDelaySignAttribute(false)]
[assembly:AssemblyKeyFileAttribute("..\\System.Data.SQLite\\System.Data.SQLite.snk")]
[assembly:AssemblyKeyNameAttribute("")]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































Deleted SQLite.Designer/SQLite.Designer.csproj.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.50727</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>SQLite.Designer</RootNamespace>
    <AssemblyName>SQLite.Designer</AssemblyName>
    <SignAssembly>false</SignAssembly>
    <AssemblyOriginatorKeyFile>
    </AssemblyOriginatorKeyFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>..\bin\Designer\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <NoWarn>1701;1702;1699</NoWarn>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>none</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>..\bin\Designer\</OutputPath>
    <DefineConstants>
    </DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <NoWarn>1701;1702;1699</NoWarn>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Microsoft.VisualStudio.Data, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\Microsoft.VisualStudio.Data.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.OLE.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
      <SpecificVersion>False</SpecificVersion>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="SQLiteDataObjectIdentifierResolver.cs" />
    <Compile Include="SQLiteDataSourceInformation.cs" />
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="SR.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>SR.resx</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="SR.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>SR.Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































Deleted SQLite.Designer/SQLiteDataObjectIdentifierResolver.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using Microsoft.VisualStudio.Data;
  using Microsoft.VisualStudio.OLE.Interop;

  internal class SQLiteDataObjectIdentifierResolver : DataObjectIdentifierResolver, IObjectWithSite
  {
    private DataConnection _connection;

    public SQLiteDataObjectIdentifierResolver()
    {
    }

    protected override object[] QuickExpandIdentifier(string typeName, object[] partialIdentifier)
    {
      if (typeName == null)
      {
        throw new ArgumentNullException("typeName");
      }

      // Create an identifier array of the correct full length based on
      // the object type
      object[] identifier = null;
      int length = 0;

      switch (typeName.ToLowerInvariant())
      {
        case "":
          length = 0;
          break;
        case "table":
        case "view":
          length = 3;
          break;
        case "column":
        case "index":
        case "foreignkey":
        case "viewcolumn":
          length = 4;
          break;
        case "indexcolumn":
        case "foreignkeycolumn":
          length = 5;
          break;
        default:
          throw new NotSupportedException();
      }
      identifier = new object[length];

      // If the input identifier is not null, copy it to the full
      // identifier array.  If the input identifier's length is less
      // than the full length we assume the more specific parts are
      // specified and thus copy into the rightmost portion of the
      // full identifier array.
      if (partialIdentifier != null)
      {
        if (partialIdentifier.Length > length)
        {
          throw new InvalidOperationException();
        }
        partialIdentifier.CopyTo(identifier, length - partialIdentifier.Length);
      }

      if (length > 0)
      {
        // Fill in the current database if not specified
        if (!(identifier[0] is string))
        {
          identifier[0] = _connection.SourceInformation[DataSourceInformation.DefaultCatalog] as string;
        }
      }

      if (length > 1)
      {
        identifier[1] = null;
      }

      return identifier;
    }

    protected override object[] QuickContractIdentifier(string typeName, object[] fullIdentifier)
    {
      int length = fullIdentifier.Length;
      object[] identifier = new object[length];

      fullIdentifier.CopyTo(identifier, 0);

      if (length > 0)
      {
        if (!(identifier[0] is string))
          identifier[0] = null;
      }

      if (length > 1)
      {
        identifier[1] = null;
      }

      return identifier;
    }

    /// <summary>
    /// GetSite does not need to be implemented since
    /// DDEX only calls SetSite to site the object.
    /// </summary>
    void IObjectWithSite.GetSite(ref Guid riid, out IntPtr ppvSite)
    {
      ppvSite = IntPtr.Zero;
      throw new NotImplementedException();
    }

    void IObjectWithSite.SetSite(object pUnkSite)
    {
      _connection = (DataConnection)pUnkSite;
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































Deleted SQLite.Designer/SQLiteDataSourceInformation.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace SQLite.Designer
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using Microsoft.VisualStudio.Data;

  internal class SQLiteDataSourceInformation : DataSourceInformation
  {
    public SQLiteDataSourceInformation()
    {
      Initialize();
    }

    public SQLiteDataSourceInformation(DataConnection connection) : base(connection)
    {
      Initialize();
    }

    private void Initialize()
    {
      AddProperty(DefaultSchema);
      AddProperty(DefaultCatalog, "main");
      AddProperty(SupportsAnsi92Sql, true);
      AddProperty(SupportsQuotedIdentifierParts, true);
      AddProperty(IdentifierOpenQuote, "[");
      AddProperty(IdentifierCloseQuote, "]");
      AddProperty(CatalogSeparator, ".");
      AddProperty(CatalogSupported, true);
      AddProperty(CatalogSupportedInDml, true);
      AddProperty(SchemaSupported, false);
      AddProperty(SchemaSupportedInDml, false);
      AddProperty(SchemaSeparator, "");
      AddProperty(ParameterPrefix, "$");
      AddProperty(ParameterPrefixInName, true);
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































Deleted SQLite.Designer/SR.Designer.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50215.44
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

[assembly: global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="SQLite.Designer.SR.get_ResourceManager():System.Resources.ResourceManager")]
[assembly: global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="SQLite.Designer.SR.get_Culture():System.Globalization.CultureInfo")]
[assembly: global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="SQLite.Designer.SR.set_Culture(System.Globalization.CultureInfo):Void")]

namespace SQLite.Designer {
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    internal class SR {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal SR() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if ((resourceMan == null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SQLite.Designer.SR", typeof(SR).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to .NET Data Provider for SQLite.
        /// </summary>
        internal static string DataProvider_SQLite {
            get {
                return ResourceManager.GetString("DataProvider_SQLite", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Description of the SQLite Data Provider goes here.
        /// </summary>
        internal static string DataProvider_SQLite_Description {
            get {
                return ResourceManager.GetString("DataProvider_SQLite_Description", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Service Provider string.
        /// </summary>
        internal static string DataProvider_SQLite_ServiceProvider {
            get {
                return ResourceManager.GetString("DataProvider_SQLite_ServiceProvider", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to SQLite Database File.
        /// </summary>
        internal static string DataProvider_SQLite_Short {
            get {
                return ResourceManager.GetString("DataProvider_SQLite_Short", resourceCulture);
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































Deleted SQLite.Designer/SR.resx.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="DataProvider_SQLite">
    <value xml:space="preserve">.NET Data Provider for SQLite</value>
  </data>
  <data name="DataProvider_SQLite_Description">
    <value xml:space="preserve">Description of the SQLite Data Provider goes here</value>
  </data>
  <data name="DataProvider_SQLite_ServiceProvider">
    <value xml:space="preserve">Service Provider string</value>
  </data>
  <data name="DataProvider_SQLite_Short">
    <value xml:space="preserve">SQLite Database File</value>
  </data>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































Deleted SQLite.Interop/AssemblyInfo.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;

//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute("System.Data.SQLite")];
[assembly:AssemblyDescriptionAttribute("http://sourceforge.net/projects/sqlite-dotnet2")];
[assembly:AssemblyConfigurationAttribute("")];
[assembly:AssemblyCompanyAttribute("")];
[assembly:AssemblyProductAttribute("System.Data.SQLite")];
[assembly:AssemblyCopyrightAttribute("Released to the public domain")];
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];

//
// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:

[assembly:AssemblyVersionAttribute("1.0.17.0")];
[assembly:AssemblyFileVersionAttribute("1.0.17.0")];

//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft CLR Framework documentation for more information on assembly signing.
//
// You can use the attributes below to control which key is used for signing.
// You can also use the project property page for signing under Common Properties
// to set the same information.
//
// Notes:
//   (*) If no key is specified, the assembly is not signed.
//   (*) KeyName refers to a key that has been installed in the Crypto Service
//       Provider (CSP) on your machine. KeyFile refers to a file which contains
//       a key.
//   (*) If the KeyFile and the KeyName values are both specified, the
//       following processing occurs:
//       (1) If the KeyName can be found in the CSP, that key is used.
//       (2) If the KeyName does not exist and the KeyFile does exist, the key
//           in the KeyFile is installed into the CSP and used.
//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
//        When specifying the KeyFile, the location of the KeyFile should be
//        relative to the project directory.
//   (*) Delay Signing is an advanced option - see the Microsoft CLR Framework
//       documentation for more information on this.
//
[assembly:AssemblyDelaySignAttribute(false)];

#ifdef _WIN64
#ifdef _M_IA64 // Itanium
[assembly:AssemblyKeyFileAttribute("..\\System.Data.SQLite\\System.Data.SQLite.IA64.snk")];
#else // AMD64
[assembly:AssemblyKeyFileAttribute("..\\System.Data.SQLite\\System.Data.SQLite.X64.snk")];
#endif
#else
[assembly:AssemblyKeyFileAttribute("..\\System.Data.SQLite\\System.Data.SQLite.snk")];
#endif
[assembly:AssemblyKeyNameAttribute("")];

[assembly:ComVisible(false)];

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































Deleted SQLite.Interop/SQLite.Interop.rc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,24,5
 PRODUCTVERSION 1,0,0,0
 FILEFLAGSMASK 0x17L
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x4L
 FILETYPE 0x2L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "Comments", "http://sourceforge.net/projects/sqlite-dotnet2"
            VALUE "FileDescription", "SQLite.NET Interop Library"
            VALUE "FileVersion", "1.0.24.5"
            VALUE "InternalName", "SQLite.Interop.DLL"
            VALUE "LegalCopyright", "Released to the public domain"
            VALUE "OriginalFilename", "SQLite3.DLL 3.3.1 alpha"
            VALUE "ProductName", "SQLite.NET"
            VALUE "ProductVersion", "1.0"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END

#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































Changes to SQLite.Interop/SQLite.Interop.vcproj.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="8.00"
	Name="SQLite.Interop"
	ProjectGUID="{10B51CE8-A838-44DE-BD82-B658F0296F80}"
	RootNamespace="SQLite.Interop"
	Keyword="Win32Proj"
	>
	<Platforms>
		<Platform
			Name="Win32"
		/>
		<Platform
			Name="Pocket PC 2003 (ARMV4)"
		/>
		<Platform
			Name="Itanium"
		/>
		<Platform
			Name="x64"
		/>
	</Platforms>
	<ToolFiles>
	</ToolFiles>
	<Configurations>
		<Configuration
			Name="Release|Win32"
			OutputDirectory="$(ConfigurationName)"
			IntermediateDirectory="$(ConfigurationName)"
			ConfigurationType="2"
			CharacterSet="2"
			ManagedExtensions="0"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
				Description="Building SQLite netmodule ..."
				CommandLine="CScript //nologo fixsource.vbs&#x0D;&#x0A;cd ..\System.Data.SQLite&#x0D;&#x0A;resgen /compile SR.resx&#x0D;&#x0A;csc /target:module /out:..\SQLite.Interop\SQlite.netmodule /debug- /o+  SQLite3.cs SQLite3_UTF16.cs SQLiteBase.cs SQLiteCommand.cs SQLiteCommandBuilder.cs SQLiteConnection.cs SQLiteConnectionStringBuilder.cs SQLiteConvert.cs SQLiteDataAdapter.cs SQLiteDataReader.cs SQLiteException.cs SQLiteFactory.cs SQLiteFunction.cs SQLiteFunctionAttribute.cs SQLiteParameter.cs SQLiteParameterCollection.cs SQLiteStatement.cs SQLiteTransaction.cs UnsafeNativeMethods.cs AssemblyInfo.cs SR.Designer.cs&#x0D;&#x0A;cd ..\SQLite.Interop&#x0D;&#x0A;"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				AdditionalOptions="/GS-"
				Optimization="3"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NO_TCL;THREADSAFE;SQLITE_HAS_CODEC"
				StringPooling="true"
				ExceptionHandling="0"

				RuntimeLibrary="2"
				BufferSecurityCheck="false"
				EnableFunctionLevelLinking="true"

				FloatingPointModel="2"
				RuntimeTypeInfo="false"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="advapi32.lib SQLite.netmodule $(NOINHERIT)"
				OutputFile="../bin/System.Data.SQLite.DLL"



				ModuleDefinitionFile="src\sqlite3.def"
				EmbedManagedResourceFile="&quot;..\System.Data.SQLite\SR.resources,System.Data.SQLite.SR.resources&quot;"
				DelayLoadDLLs="advapi32.dll"
				ImportLibrary=""
				TargetMachine="1"
				KeyFile="..\System.Data.SQLite\System.Data.SQLite.snk"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				EmbedManifest="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>













<
<
<
<
<
<
<
<
<





|
|
|


<
<



<
<















<
|
<
|


>
|
<

>
|
|












<
|
>
>
>
|
<
|
|

<






<







1
2
3
4
5
6
7
8
9
10
11
12
13









14
15
16
17
18
19
20
21
22
23


24
25
26


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42

43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68

69
70
71

72
73
74
75
76
77

78
79
80
81
82
83
84
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="8.00"
	Name="SQLite.Interop"
	ProjectGUID="{10B51CE8-A838-44DE-BD82-B658F0296F80}"
	RootNamespace="SQLite.Interop"
	Keyword="Win32Proj"
	>
	<Platforms>
		<Platform
			Name="Win32"
		/>









	</Platforms>
	<ToolFiles>
	</ToolFiles>
	<Configurations>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory="Debug"
			IntermediateDirectory="Debug"
			ConfigurationType="2"
			CharacterSet="2"


			>
			<Tool
				Name="VCPreBuildEventTool"


			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"

				Optimization="0"

				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NO_TCL;THREADSAFE"
				StringPooling="true"
				ExceptionHandling="0"
				BasicRuntimeChecks="3"
				RuntimeLibrary="1"

				EnableFunctionLevelLinking="true"
				UsePrecompiledHeader="0"
				WarningLevel="1"
				DebugInformationFormat="3"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"

				OutputFile="$(OutDir)/$(ProjectName).dll"
				LinkIncremental="1"
				GenerateManifest="false"
				GenerateDebugInformation="true"
				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"

				SubSystem="2"
				ImportLibrary="$(OutDir)/$(ProjectName).lib"
				TargetMachine="1"

			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"

			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Release|Pocket PC 2003 (ARMV4)"
			OutputDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"
			IntermediateDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"
			ConfigurationType="2"
			CharacterSet="1"
			WholeProgramOptimization="0"
			>
			<Tool
				Name="VCPreBuildEventTool"
				Description="Preparing build ..."
				CommandLine="CScript //nologo fixsource.vbs&#x0D;&#x0A;"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				ExecutionBucket="7"
				AdditionalOptions="/GS-"
				Optimization="1"
				PreprocessorDefinitions="_WIN32_WCE=$(CEVER);UNDER_CE=$(CEVER);WINCE;$(PLATFORMDEFINES);NDEBUG;_WINDOWS;_USRDLL;CPPSMART_EXPORTS;$(ARCHFAM);$(_ARCHFAM_);UNICODE;_UNICODE;SQLITE_HAS_CODEC"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="2"
				BufferSecurityCheck="false"
				EnableFunctionLevelLinking="true"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_UNICODE;UNICODE;_WIN32_WCE;UNDER_CE"
				Culture="1033"
				AdditionalIncludeDirectories="$(IntDir)"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				IgnoreImportLibrary="true"
				AdditionalOptions=" /subsystem:windowsce,4.20 /machine:ARM /ARMPADCODE"
				OutputFile="../bin/CompactFramework/System.Data.SQLite.DLL"
				AdditionalLibraryDirectories="lib\arm"
				IgnoreDefaultLibraryNames="oldnames.lib"
				ModuleDefinitionFile="src\sqlite3.def"
				AddModuleNamesToAssembly=""
				EmbedManagedResourceFile=""
				TargetMachine="3"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCCodeSignTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				Description="Merging binaries ..."
				CommandLine="..\bin\tools\mergebin.exe /S:.clr ..\System.Data.SQLite\bin\$(TargetFileName) $(TargetPath)&#x0D;&#x0A;sn -Ra $(TargetPath) ..\System.Data.SQLite\System.Data.SQLite.CF.snk&#x0D;&#x0A;"
			/>
			<DeploymentTool
				ForceDirty="-1"
				RemoteDirectory="\Program Files\testce"
				RegisterOutput="0"
				AdditionalFiles=""
			/>
			<DebuggerTool
			/>
		</Configuration>
		<Configuration
			Name="Release|Itanium"
			OutputDirectory="ia64\$(ConfigurationName)"
			IntermediateDirectory="ia64\$(ConfigurationName)"
			ConfigurationType="2"
			CharacterSet="2"
			ManagedExtensions="0"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
				Description="Building SQLite netmodule ..."
				CommandLine="CScript //nologo fixsource.vbs&#x0D;&#x0A;cd ..\System.Data.SQLite&#x0D;&#x0A;resgen /compile SR.resx&#x0D;&#x0A;csc /target:module /out:..\SQLite.Interop\SQlite.netmodule /debug- /o+  SQLite3.cs SQLite3_UTF16.cs SQLiteBase.cs SQLiteCommand.cs SQLiteCommandBuilder.cs SQLiteConnection.cs SQLiteConnectionStringBuilder.cs SQLiteConvert.cs SQLiteDataAdapter.cs SQLiteDataReader.cs SQLiteException.cs SQLiteFactory.cs SQLiteFunction.cs SQLiteFunctionAttribute.cs SQLiteParameter.cs SQLiteParameterCollection.cs SQLiteStatement.cs SQLiteTransaction.cs UnsafeNativeMethods.cs AssemblyInfo.cs SR.Designer.cs&#x0D;&#x0A;cd ..\SQLite.Interop&#x0D;&#x0A;"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="2"
			/>
			<Tool
				Name="VCCLCompilerTool"
				AdditionalOptions="/GS-"
				Optimization="3"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NO_TCL;THREADSAFE;WIN64;SQLITE_HAS_CODEC"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="2"
				BufferSecurityCheck="false"
				EnableFunctionLevelLinking="true"

				FloatingPointModel="2"
				RuntimeTypeInfo="false"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="advapi32.lib SQLite.netmodule $(NOINHERIT)"
				OutputFile="../bin/Itanium/System.Data.SQLite.DLL"

				ModuleDefinitionFile="src\sqlite3.def"
				EmbedManagedResourceFile="&quot;..\System.Data.SQLite\SR.resources,System.Data.SQLite.SR.resources&quot;"
				DelayLoadDLLs="advapi32.dll"

				ImportLibrary=""
				TargetMachine="5"
				KeyFile="..\System.Data.SQLite\System.Data.SQLite.snk"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				EmbedManifest="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Release|x64"
			OutputDirectory="x64\$(ConfigurationName)"
			IntermediateDirectory="x64\$(ConfigurationName)"
			ConfigurationType="2"
			CharacterSet="2"
			ManagedExtensions="0"
			WholeProgramOptimization="1"
			>
			<Tool
				Name="VCPreBuildEventTool"
				Description="Building SQLite netmodule ..."
				CommandLine="CScript //nologo fixsource.vbs&#x0D;&#x0A;cd ..\System.Data.SQLite&#x0D;&#x0A;resgen /compile SR.resx&#x0D;&#x0A;csc /target:module /out:..\SQLite.Interop\SQlite.netmodule /debug- /o+  SQLite3.cs SQLite3_UTF16.cs SQLiteBase.cs SQLiteCommand.cs SQLiteCommandBuilder.cs SQLiteConnection.cs SQLiteConnectionStringBuilder.cs SQLiteConvert.cs SQLiteDataAdapter.cs SQLiteDataReader.cs SQLiteException.cs SQLiteFactory.cs SQLiteFunction.cs SQLiteFunctionAttribute.cs SQLiteParameter.cs SQLiteParameterCollection.cs SQLiteStatement.cs SQLiteTransaction.cs UnsafeNativeMethods.cs AssemblyInfo.cs SR.Designer.cs&#x0D;&#x0A;cd ..\SQLite.Interop&#x0D;&#x0A;"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="3"
			/>
			<Tool
				Name="VCCLCompilerTool"
				AdditionalOptions="/GS-"
				Optimization="3"
				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NO_TCL;THREADSAFE;WIN64;SQLITE_HAS_CODEC"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="2"
				BufferSecurityCheck="false"
				EnableFunctionLevelLinking="true"
				FloatingPointModel="2"
				RuntimeTypeInfo="false"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="advapi32.lib SQLite.netmodule $(NOINHERIT)"
				OutputFile="../bin/x64/System.Data.SQLite.DLL"
				ModuleDefinitionFile="src\sqlite3.def"
				EmbedManagedResourceFile="&quot;..\System.Data.SQLite\SR.resources,System.Data.SQLite.SR.resources&quot;"
				DelayLoadDLLs="advapi32.dll"
				ImportLibrary=""
				TargetMachine="17"
				KeyFile="..\System.Data.SQLite\System.Data.SQLite.snk"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				EmbedManifest="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory="$(ConfigurationName)"
			IntermediateDirectory="$(ConfigurationName)"
			ConfigurationType="2"
			CharacterSet="2"
			ManagedExtensions="0"
			WholeProgramOptimization="0"
			>
			<Tool
				Name="VCPreBuildEventTool"
				Description="Fixing up sources ..."
				CommandLine="CScript //nologo fixsource.vbs"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				AdditionalOptions="/GS-"
				Optimization="0"
				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NO_TCL;THREADSAFE;SQLITE_HAS_CODEC"
				RuntimeLibrary="3"
				RuntimeTypeInfo="false"
				DebugInformationFormat="3"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="advapi32.lib $(NOINHERIT)"
				OutputFile="../bin/$(InputName).DLL"
				ModuleDefinitionFile="src\sqlite3.def"
				EmbedManagedResourceFile=""
				DelayLoadDLLs="advapi32.dll"
				GenerateDebugInformation="true"
				ImportLibrary=""
				TargetMachine="1"
				KeyFile="..\System.Data.SQLite\System.Data.SQLite.snk"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				EmbedManifest="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Debug|Pocket PC 2003 (ARMV4)"
			OutputDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"
			IntermediateDirectory="Pocket PC 2003 (ARMV4)\$(ConfigurationName)"
			ConfigurationType="2"
			CharacterSet="1"
			WholeProgramOptimization="0"
			>
			<Tool
				Name="VCPreBuildEventTool"
				Description="Fixing up sources ..."
				CommandLine="CScript //nologo fixsource.vbs"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="1"
			/>
			<Tool
				Name="VCCLCompilerTool"
				ExecutionBucket="7"
				AdditionalOptions="/GS-"
				Optimization="0"
				FavorSizeOrSpeed="0"
				PreprocessorDefinitions="_WIN32_WCE=$(CEVER);UNDER_CE=$(CEVER);WINCE;$(PLATFORMDEFINES);_DEBUG;_WINDOWS;_USRDLL;CPPSMART_EXPORTS;$(ARCHFAM);$(_ARCHFAM_);UNICODE;_UNICODE;SQLITE_HAS_CODEC"
				RuntimeLibrary="3"
				DebugInformationFormat="3"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
				PreprocessorDefinitions="NDEBUG;_UNICODE;UNICODE;_WIN32_WCE;UNDER_CE"
				Culture="1033"
				AdditionalIncludeDirectories="$(IntDir)"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				IgnoreImportLibrary="true"
				AdditionalOptions=" /subsystem:windowsce,4.20 /machine:ARM /ARMPADCODE"
				OutputFile="../bin/CompactFramework/$(InputName).DLL"
				AdditionalLibraryDirectories=""
				IgnoreDefaultLibraryNames="oldnames.lib"
				ModuleDefinitionFile="src\sqlite3.def"
				AddModuleNamesToAssembly=""
				EmbedManagedResourceFile=""
				GenerateDebugInformation="true"
				TargetMachine="0"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCCodeSignTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
				CommandLine=""
			/>
			<DeploymentTool
				ForceDirty="-1"
				RemoteDirectory="\Program Files\testce"
				RegisterOutput="0"
				AdditionalFiles=""
			/>
			<DebuggerTool
			/>
		</Configuration>
		<Configuration
			Name="Debug|Itanium"
			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			CharacterSet="2"
			ManagedExtensions="0"
			WholeProgramOptimization="0"
			>
			<Tool
				Name="VCPreBuildEventTool"
				Description="Fixing up sources ..."
				CommandLine="CScript //nologo fixsource.vbs"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="2"
			/>
			<Tool
				Name="VCCLCompilerTool"
				AdditionalOptions="/GS-"
				Optimization="0"
				PreprocessorDefinitions="_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NO_TCL;THREADSAFE;WIN64;SQLITE_HAS_CODEC"
				RuntimeLibrary="3"
				RuntimeTypeInfo="false"
				DebugInformationFormat="3"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="advapi32.lib $(NOINHERIT)"
				OutputFile="../bin/Itanium/$(InputName).DLL"
				ModuleDefinitionFile="src\sqlite3.def"
				EmbedManagedResourceFile=""
				DelayLoadDLLs="advapi32.dll"
				GenerateDebugInformation="true"
				ImportLibrary=""
				TargetMachine="5"
				KeyFile="..\System.Data.SQLite\System.Data.SQLite.snk"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				EmbedManifest="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Debug|x64"
			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
			ConfigurationType="2"
			CharacterSet="2"
			ManagedExtensions="0"
			WholeProgramOptimization="0"
			>
			<Tool
				Name="VCPreBuildEventTool"
				Description="Fixing up sources ..."
				CommandLine="CScript //nologo fixsource.vbs"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
				TargetEnvironment="3"
			/>
			<Tool
				Name="VCCLCompilerTool"
				AdditionalOptions="/GS-"
				Optimization="0"
				PreprocessorDefinitions="_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NO_TCL;THREADSAFE;WIN64;SQLITE_HAS_CODEC"
				RuntimeLibrary="3"
				RuntimeTypeInfo="false"
				DebugInformationFormat="3"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				AdditionalDependencies="advapi32.lib $(NOINHERIT)"
				OutputFile="../bin/x64/$(InputName).DLL"
				ModuleDefinitionFile="src\sqlite3.def"
				EmbedManagedResourceFile=""
				DelayLoadDLLs="advapi32.dll"
				GenerateDebugInformation="true"
				ImportLibrary=""
				TargetMachine="17"
				KeyFile="..\System.Data.SQLite\System.Data.SQLite.snk"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
				EmbedManifest="true"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>







|
|
|

|




<
<















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

|


|


>
|
|












<
|
>
|
|
|
>
|
|
<






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122


123
























































































124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153

154
155
156
157
158
159






































































































































































































































































































































































































































160
161
162
163
164
165
166
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Release|Win32"
			OutputDirectory="Release"
			IntermediateDirectory="Release"
			ConfigurationType="2"
			CharacterSet="2"
			WholeProgramOptimization="0"
			>
			<Tool
				Name="VCPreBuildEventTool"


			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"


				Optimization="2"
























































































				FavorSizeOrSpeed="1"
				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;NO_TCL;THREADSAFE"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeLibrary="0"
				BufferSecurityCheck="false"
				EnableFunctionLevelLinking="true"
				UsePrecompiledHeader="0"
				WarningLevel="1"
				DebugInformationFormat="0"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"

				OutputFile="$(OutDir)/$(ProjectName).dll"
				LinkIncremental="1"
				GenerateManifest="false"
				SubSystem="2"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				ImportLibrary="$(OutDir)/$(ProjectName).lib"
				TargetMachine="1"

			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"






































































































































































































































































































































































































































			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
			Name="Source Files"
			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
			>
			<File
				RelativePath=".\src\alter.c"
				>
			</File>
			<File
				RelativePath=".\src\analyze.c"
				>
			</File>
			<File
				RelativePath=".\src\attach.c"
				>
			</File>
			<File
				RelativePath=".\src\auth.c"
				>
			</File>
			<File
				RelativePath=".\src\btree.c"
				>
			</File>
			<File
				RelativePath=".\src\build.c"
				>
			</File>
			<File
				RelativePath=".\src\callback.c"
				>
			</File>
			<File
				RelativePath=".\src\complete.c"
				>
			</File>
			<File
				RelativePath=".\src\date.c"
				>
			</File>
			<File
				RelativePath=".\src\delete.c"







<
<
<
<
















<
<
<
<
<
<
<
<







185
186
187
188
189
190
191




192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207








208
209
210
211
212
213
214
			Name="Source Files"
			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
			>
			<File
				RelativePath=".\src\alter.c"
				>




			</File>
			<File
				RelativePath=".\src\attach.c"
				>
			</File>
			<File
				RelativePath=".\src\auth.c"
				>
			</File>
			<File
				RelativePath=".\src\btree.c"
				>
			</File>
			<File
				RelativePath=".\src\build.c"
				>








			</File>
			<File
				RelativePath=".\src\date.c"
				>
			</File>
			<File
				RelativePath=".\src\delete.c"
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
				>
			</File>
			<File
				RelativePath=".\src\opcodes.c"
				>
			</File>
			<File
				RelativePath=".\src\os.c"
				>
			</File>
			<File
				RelativePath=".\src\os_win.c"
				>
			</File>
			<File
				RelativePath=".\src\pager.c"
				>
				<FileConfiguration
					Name="Release|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Itanium"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Itanium"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\parse.c"
				>
			</File>
			<File
				RelativePath=".\src\pragma.c"
				>
			</File>
			<File
				RelativePath=".\src\prepare.c"
				>
			</File>
			<File
				RelativePath=".\src\printf.c"
				>
			</File>
			<File
				RelativePath=".\src\random.c"
				>
			</File>
			<File
				RelativePath=".\src\select.c"
				>
				<FileConfiguration
					Name="Release|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Itanium"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Win32"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Pocket PC 2003 (ARMV4)"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|Itanium"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Debug|x64"
					ExcludedFromBuild="true"
					>
					<Tool
						Name="VCCLCompilerTool"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\src\table.c"
				>
			</File>
			<File
				RelativePath=".\src\tokenize.c"
				>
			</File>
			<File
				RelativePath=".\src\trigger.c"







|









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








<
<
<
<












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


|








239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
































































256
257
258
259
260
261
262
263




264
265
266
267
268
269
270
271
272
273
274
275







276
277







278


279












































280
281
282
283
284
285
286
287
288
289
290
				>
			</File>
			<File
				RelativePath=".\src\opcodes.c"
				>
			</File>
			<File
				RelativePath=".\src\os_unix.c"
				>
			</File>
			<File
				RelativePath=".\src\os_win.c"
				>
			</File>
			<File
				RelativePath=".\src\pager.c"
				>
































































			</File>
			<File
				RelativePath=".\src\parse.c"
				>
			</File>
			<File
				RelativePath=".\src\pragma.c"
				>




			</File>
			<File
				RelativePath=".\src\printf.c"
				>
			</File>
			<File
				RelativePath=".\src\random.c"
				>
			</File>
			<File
				RelativePath=".\src\select.c"
				>







			</File>
			<File







				RelativePath=".\src\table.c"


				>












































			</File>
			<File
				RelativePath=".\src\tclsqlite.c"
				>
			</File>
			<File
				RelativePath=".\src\tokenize.c"
				>
			</File>
			<File
				RelativePath=".\src\trigger.c"
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008

1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
			<File
				RelativePath=".\src\vdbeapi.c"
				>
			</File>
			<File
				RelativePath=".\src\vdbeaux.c"
				>
			</File>
			<File
				RelativePath=".\src\vdbefifo.c"
				>
			</File>
			<File
				RelativePath=".\src\vdbemem.c"
				>
			</File>
			<File
				RelativePath=".\src\where.c"
				>
			</File>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl;inc;xsd"
			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
			>
			<File
				RelativePath=".\resource.h"

				>
			</File>
			<File
				RelativePath=".\src\sqlite3.h"
				>
			</File>
		</Filter>
		<Filter
			Name="Extras"
			>
			<File
				RelativePath=".\crypt.c"
				>
			</File>
			<File
				RelativePath=".\interop.c"
				>
			</File>
		</Filter>
		<File
			RelativePath=".\SQLite.Interop.rc"
			>
		</File>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>







<
<
<
<
















|
>







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




313
314
315
316
317
318
319




320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
















345
346
347
348
			<File
				RelativePath=".\src\vdbeapi.c"
				>
			</File>
			<File
				RelativePath=".\src\vdbeaux.c"
				>




			</File>
			<File
				RelativePath=".\src\vdbemem.c"
				>
			</File>
			<File
				RelativePath=".\src\where.c"
				>
			</File>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl;inc;xsd"
			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
			>
			<File
				RelativePath=".\interop.h"
				FileType="0"
				>
			</File>
			<File
				RelativePath=".\src\sqlite3.h"
				>
			</File>
		</Filter>
















	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>
Deleted SQLite.Interop/crypt.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
#ifdef SQLITE_HAS_CODEC
  void sqlite3pager_free_codecarg(void *pArg);
#endif

#include "src/pager.c"

#ifndef SQLITE_OMIT_DISKIO
#ifdef SQLITE_HAS_CODEC

#include <windows.h>
#include <wincrypt.h>

typedef struct _CRYPTBLOCK
{
  HCRYPTKEY hReadKey;     // Key used to read from the database and write to the journal
  HCRYPTKEY hWriteKey;    // Key used to write to the database
  DWORD     dwPageSize;   // Size of pages
  LPVOID    pvCrypt;      // A buffer for encrypting/decrypting (if necessary)
  DWORD     dwCryptSize;  // Equal to or greater than dwPageSize.  If larger, pvCrypt is valid and this is its size
} CRYPTBLOCK, *LPCRYPTBLOCK;

HCRYPTPROV g_hProvider = 0; // Global instance of the cryptographic provider

#define SQLITECRYPTERROR_PROVIDER "Cryptographic provider not available"

// Needed for re-keying
static void * sqlite3pager_get_codecarg(Pager *pPager)
{
  return (pPager->xCodec) ? pPager->pCodecArg: NULL;
}

// Create a cryptographic context.  Use the enhanced provider because it is available on
// most platforms
static BOOL InitializeProvider()
{
  if (g_hProvider) return TRUE;

  if (!CryptAcquireContext(&g_hProvider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
  {
    if(!CryptAcquireContext(&g_hProvider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
    {
      return FALSE;
    }
  }
  return TRUE;
}

// Create or update a cryptographic context for a pager.
// This function will automatically determine if the encryption algorithm requires
// extra padding, and if it does, will create a temp buffer big enough to provide
// space to hold it.
static LPCRYPTBLOCK CreateCryptBlock(HCRYPTKEY hKey, Pager *pager, LPCRYPTBLOCK pExisting)
{
  LPCRYPTBLOCK pBlock;

  if (!pExisting) // Creating a new cryptblock
  {
    pBlock = malloc(sizeof(CRYPTBLOCK));
    ZeroMemory(pBlock, sizeof(CRYPTBLOCK));
    pBlock->hReadKey = hKey;
    pBlock->hWriteKey = hKey;
  }
  else // Updating an existing cryptblock
  {
    pBlock = pExisting;
  }

  pBlock->dwPageSize = (DWORD)pager->pageSize;
  pBlock->dwCryptSize = pBlock->dwPageSize;

  // Existing cryptblocks may have a buffer, if so, delete it
  if (pBlock->pvCrypt)
  {
    free(pBlock->pvCrypt);
    pBlock->pvCrypt = NULL;
  }

  // Figure out if this cryptographic key requires extra buffer space, and if so, allocate 
  // enough room for it
  if (CryptEncrypt(hKey, 0, TRUE, 0, NULL, &pBlock->dwCryptSize, pBlock->dwCryptSize * 2))
  {
    if (pBlock->dwCryptSize > pBlock->dwPageSize)
    {
      pBlock->pvCrypt = malloc(pBlock->dwCryptSize);
    }
  }
  return pBlock;
}

// Destroy a cryptographic context and any buffers and keys allocated therein
static void DestroyCryptBlock(LPCRYPTBLOCK pBlock)
{
  // Destroy the read key if there is one
  if (pBlock->hReadKey)
  {
    CryptDestroyKey(pBlock->hReadKey);
  }

  // If there's a writekey and its not equal to the readkey, destroy it
  if (pBlock->hWriteKey && pBlock->hWriteKey != pBlock->hReadKey)
  {
    CryptDestroyKey(pBlock->hWriteKey);
  }

  // If there's extra buffer space allocated, free it as well
  if (pBlock->pvCrypt)
  {
    free(pBlock->pvCrypt);
  }

  // All done with this cryptblock
  free(pBlock);
}

// Encrypt/Decrypt functionality, called by pager.c
void sqlite3Codec(void *pArg, void *data, Pgno nPageNum, int nMode)
{
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)pArg;
  DWORD dwPageSize;
  LPVOID pvTemp;

  if (!pBlock) return;

  // Make sure the page size for the pager is still the same as the page size
  // for the cryptblock.  If the user changed it, we need to adjust!
  if (nMode != 2)
  {
    PgHdr *pageHeader;
    pageHeader = DATA_TO_PGHDR(data);
    if (pageHeader->pPager->pageSize != pBlock->dwPageSize)
    {
      // Update the cryptblock to reflect the new page size
      CreateCryptBlock(0, pageHeader->pPager, pBlock);
    }
  }

  /* Block ciphers often need to write extra padding beyond the 
  data block.  We don't have that luxury for a given page of data so
  we must copy the page data to a buffer that IS large enough to hold
  the padding.  We then encrypt the block and write the buffer back to
  the page without the unnecessary padding.
  We only use the special block of memory if its absolutely necessary. */
  if (pBlock->pvCrypt)
  {
    CopyMemory(pBlock->pvCrypt, data, pBlock->dwPageSize);
    pvTemp = data;
    data = pBlock->pvCrypt;
  }

  switch(nMode)
  {
  case 0: // Undo a "case 7" journal file encryption
  case 2: // Reload a page
  case 3: // Load a page
    if (!pBlock->hReadKey) break;
    dwPageSize = pBlock->dwCryptSize;
    CryptDecrypt(pBlock->hReadKey, 0, TRUE, 0, (LPBYTE)data, &dwPageSize);
    break;
  case 6: // Encrypt a page for the main database file
    if (!pBlock->hWriteKey) break;
    dwPageSize = pBlock->dwPageSize;
    CryptEncrypt(pBlock->hWriteKey, 0, TRUE, 0, (LPBYTE)data, &dwPageSize, pBlock->dwCryptSize);
    break;
  case 7: // Encrypt a page for the journal file
    /* Under normal circumstances, the readkey is the same as the writekey.  However,
    when the database is being rekeyed, the readkey is not the same as the writekey.
    The rollback journal must be written using the original key for the
    database file because it is, by nature, a rollback journal.
    Therefore, for case 7, when the rollback is being written, always encrypt using
    the database's readkey, which is guaranteed to be the same key that was used to
    read the original data.
    */
    if (!pBlock->hReadKey) break;
    dwPageSize = pBlock->dwPageSize;
    CryptEncrypt(pBlock->hReadKey, 0, TRUE, 0, (LPBYTE)data, &dwPageSize, pBlock->dwCryptSize);
    break;
  }

  // If the encryption algorithm required extra padding and we were forced to encrypt or
  // decrypt a copy of the page data to a temp buffer, then write the contents of the temp
  // buffer back to the page data minus any padding applied.
  if (pBlock->pvCrypt)
  {
    CopyMemory(pvTemp, data, pBlock->dwPageSize);
  }
}

// Derive an encryption key from a user-supplied buffer
static HCRYPTKEY DeriveKey(const void *pKey, int nKeyLen)
{
  HCRYPTHASH hHash = 0;
  HCRYPTKEY  hKey;

  if (!pKey || !nKeyLen) return 0;

  if (!InitializeProvider())
  {
    return MAXDWORD;
  }

  if (CryptCreateHash(g_hProvider, CALG_SHA1, 0, 0, &hHash))
  {
    if (CryptHashData(hHash, (LPBYTE)pKey, nKeyLen, 0))
    {
      CryptDeriveKey(g_hProvider, CALG_RC4, hHash, 0, &hKey);
    }
    CryptDestroyHash(hHash);
  }  
  return hKey;
}

// Called by sqlite and sqlite3_key_interop to attach a key to a database.
int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen)
{
  int rc = SQLITE_ERROR;
  HCRYPTKEY hKey = 0;

  // No key specified, could mean either use the main db's encryption or no encryption
  if (!pKey || !nKeyLen)
  {
    if (!nDb)
    {
      return SQLITE_OK; // Main database, no key specified so not encrypted
    }
    else // Attached database, use the main database's key
    {
      // Get the encryption block for the main database and attempt to duplicate the key
      // for use by the attached database
      LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(sqlite3BtreePager(db->aDb[0].pBt));

      if (!pBlock) return SQLITE_OK; // Main database is not encrypted so neither will be any attached database
      if (!pBlock->hReadKey) return SQLITE_OK; // Not encrypted

      if (!CryptDuplicateKey(pBlock->hReadKey, NULL, 0, &hKey))
        return rc; // Unable to duplicate the key
    }
  }
  else // User-supplied passphrase, so create a cryptographic key out of it
  {
    hKey = DeriveKey(pKey, nKeyLen);
    if (hKey == MAXDWORD)
    {
      sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER);
      return rc;
    }
  }

  // Create a new encryption block and assign the codec to the new attached database
  if (hKey)
  {
    LPCRYPTBLOCK pBlock = CreateCryptBlock(hKey, sqlite3BtreePager(db->aDb[nDb].pBt), NULL);
    sqlite3pager_set_codec(sqlite3BtreePager(db->aDb[nDb].pBt), sqlite3Codec, pBlock);
    rc = SQLITE_OK;
  }
  return rc;
}

void sqlite3pager_free_codecarg(void *pArg)
{
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)pArg;

  if (pBlock)
  {
    if (pBlock->hReadKey)
      CryptDestroyKey(pBlock->hReadKey);
    if (pBlock->hWriteKey)
      CryptDestroyKey(pBlock->hWriteKey);

    if (pBlock->pvCrypt)
      free(pBlock->pvCrypt);
  }
  free(pBlock);
}

// Once a password has been supplied and a key created, we don't keep the 
// original password for security purposes.  Therefore return NULL.
void sqlite3CodecGetKey(sqlite3 *db, int nDb, void **ppKey, int *pnKeyLen)
{
  *ppKey = NULL;
  *pnKeyLen = 0;
}

// We do not attach this key to the temp store, only the main database.
__declspec(dllexport) int __stdcall sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize)
{
  return sqlite3CodecAttach(db, 0, pKey, nKeySize);
}

// Changes the encryption key for an existing database.
__declspec(dllexport) int __stdcall sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySize)
{
  Btree *pbt = db->aDb[0].pBt;
  Pager *p = sqlite3BtreePager(pbt);
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(p);
  HCRYPTKEY hKey = DeriveKey(pKey, nKeySize);
  int rc = SQLITE_ERROR;

  if (hKey == MAXDWORD)
  {
    sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER);
    return rc;
  }

  if (!pBlock && !hKey) return SQLITE_OK; // Wasn't encrypted to begin with

  // To rekey a database, we change the writekey for the pager.  The readkey remains
  // the same
  if (!pBlock) // Encrypt an unencrypted database
  {
    pBlock = CreateCryptBlock(hKey, p, NULL);
    pBlock->hReadKey = 0; // Original database is not encrypted
    sqlite3pager_set_codec(sqlite3BtreePager(pbt), sqlite3Codec, pBlock);
  }
  else // Change the writekey for an already-encrypted database
  {
    pBlock->hWriteKey = hKey;
  }

  // Start a transaction
  rc = sqlite3BtreeBeginTrans(pbt, 1);

  if (!rc)
  {
    // Rewrite all the pages in the database using the new encryption key
    int nPage = sqlite3pager_pagecount(p);
    void *pPage;
    int n;

    for(n = 1; rc == SQLITE_OK && n <= nPage; n ++)
    {
      rc = sqlite3pager_get(p, n, &pPage);
      if(!rc)
      {
        rc = sqlite3pager_write(pPage);
        sqlite3pager_unref(pPage);
      }
    }
  }

  // If we succeeded, try and commit the transaction
  if (!rc)
  {
    rc = sqlite3BtreeCommit(pbt);
  }

  // If we failed, rollback
  if (rc)
  {
    sqlite3BtreeRollback(pbt);
  }

  // If we succeeded, destroy any previous read key this database used
  // and make the readkey equal to the writekey
  if (!rc)
  {
    if (pBlock->hReadKey)
    {
      CryptDestroyKey(pBlock->hReadKey);
    }
    pBlock->hReadKey = pBlock->hWriteKey;
  }
  // We failed.  Destroy the new writekey (if there was one) and revert it back to
  // the original readkey
  else
  {
    if (pBlock->hWriteKey)
    {
      CryptDestroyKey(pBlock->hWriteKey);
    }
    pBlock->hWriteKey = pBlock->hReadKey;
  }

  // If the readkey and writekey are both empty, there's no need for a codec on this
  // pager anymore.  Destroy the crypt block and remove the codec from the pager.
  if (!pBlock->hReadKey && !pBlock->hWriteKey)
  {
    sqlite3pager_set_codec(p, NULL, NULL);
    DestroyCryptBlock(pBlock);
  }

  return rc;
}

int sqlite3_key(sqlite3 *db, const void *pKey, int nKey)
{
  return sqlite3_key_interop(db, pKey, nKey);
}

int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey)
{
  return sqlite3_rekey_interop(db, pKey, nKey);
}

#endif // SQLITE_HAS_CODEC

#endif // SQLITE_OMIT_DISKIO
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/fixsource.vbs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
' VBScript source code
Main

Sub Main()
  Dim WshShell
  Set WshShell = WScript.CreateObject("WScript.Shell")
  
  Dim fso
  Set fso = WScript.CreateObject("Scripting.FileSystemObject")
  
  Dim srcFile
  Dim srcFileContents
  dim newFileContents
  
  ' Changes the name of the function so we can get first crack at it in interop.h to provide GetSchemaTable() support
  '
  Set srcFile = fso.OpenTextFile("src\select.c", 1) 
  srcFileContents = srcFile.ReadAll()
  srcFile.Close()  
  newFileContents = Replace(srcFileContents, "static void generateColumnNames(", "static void _generateColumnNames(")
  If (newFileContents <> srcFileContents) Then
    WScript.StdOut.WriteLine "Updating select.c"
    Set srcFile = fso.CreateTextFile("src\select.c", true)
    srcFile.Write(newFileContents)
    srcFile.Close()
  End If

  ' SQLite supports : and $ for named parameters, but we add support for @ as well here
  '  
  Set srcFile = fso.OpenTextFile("src\tokenize.c", 1)  
  srcFileContents = srcFile.ReadAll()
  srcFile.Close()
  If InStr(1, srcFileContents, "    case '@':", 1) = 0 Then
    newFileContents = Replace(srcFileContents, "    case ':': {", "    case '@':" & Chr(10) & "    case ':': {")
    If (newFileContents <> srcFileContents) Then
      WScript.StdOut.WriteLine "Updating tokenize.c"
      Set srcFile = fso.CreateTextFile("src\tokenize.c", true)
      srcFile.Write(newFileContents)
      srcFile.Close()
    End If
  End If

  ' In order to support encryption, we need to know when the pager is being destroyed so we can destroy our encryption
  ' objects.  This modification adds code to support that.
  '
  Set srcFile = fso.OpenTextFile("src\pager.c", 1)  
  srcFileContents = srcFile.ReadAll()
  srcFile.Close()
  If InStr(1, srcFileContents, "sqlite3pager_free_codecarg", 1) = 0 Then
    newFileContents = Replace(srcFileContents, Chr(10) & "  sqliteFree(pPager);", Chr(10) & "#ifdef SQLITE_HAS_CODEC" & Chr(10) & "  sqlite3pager_free_codecarg(pPager->pCodecArg);" & Chr(10) & "#endif" & Chr(10) & "  sqliteFree(pPager);")
    If (newFileContents <> srcFileContents) Then
      WScript.StdOut.WriteLine "Updating pager.c"
      Set srcFile = fso.CreateTextFile("src\pager.c", true)
      srcFile.Write(newFileContents)
      srcFile.Close()
    End If
  End If

End Sub
  
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































Deleted SQLite.Interop/interop.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
/*
   This interop file must be included at or near the top of the select.c file of the SQLite3 source distribution.

   generateColumnNames() in the select.c must be renamed to _generateColumnNames

*/

#include "src/sqliteint.h"
#include "src\os.h"

#if _WIN32_WCE && NDEBUG
#include "merge.h"
#endif

// Forward declare this function, we're implementing it later
static void generateColumnNames(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
);

#include "src\select.c"

/*
** Generate code that will tell the VDBE the names of columns
** in the result set.  This information is used to provide the
** azCol[] values in the callback.
*/
static void generateColumnNames(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
){
  Vdbe *v = pParse->pVdbe;
  int i, j;
  sqlite3 *db = pParse->db;
  int fullNames, shortNames;
  int realNames;                                     /*** ADDED - SQLite.Interop ***/

  realNames = (db->flags & 0x01000000)!=0;           /*** ADDED - SQLite.Interop ***/
  if (!realNames) // Default to normal Sqlite3       /*** ADDED - SQLite.Interop ***/
  {                                                  /*** ADDED - SQLite.Interop ***/
    _generateColumnNames(pParse, pTabList, pEList);  /*** ADDED - SQLite.Interop ***/
    return;                                          /*** ADDED - SQLite.Interop ***/
  }                                                  /*** ADDED - SQLite.Interop ***/

#ifndef SQLITE_OMIT_EXPLAIN
  /* If this is an EXPLAIN, skip this step */
  if( pParse->explain ){
    return;
  }
#endif

  assert( v!=0 );
  if( pParse->colNamesSet || v==0 || sqlite3ThreadData()->mallocFailed ) return;
  pParse->colNamesSet = 1;
  fullNames = (db->flags & SQLITE_FullColNames)!=0;
  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
  if (realNames) fullNames = 1;                      /*** ADDED - SQLite.Interop ***/

  sqlite3VdbeSetNumCols(v, pEList->nExpr);
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    p = pEList->a[i].pExpr;
    if( p==0 ) continue;
    if( pEList->a[i].zName && (realNames == 0 || p->op != TK_COLUMN)){   /*** CHANGED - SQLite.Interop ***/
      char *zName = pEList->a[i].zName;
      sqlite3VdbeSetColName(v, i, zName, strlen(zName));
      continue;
    }
    if( p->op==TK_COLUMN && pTabList ){
      Table *pTab;
      char *zCol;
      int iCol = p->iColumn;
      for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
      assert( j<pTabList->nSrc );
      pTab = pTabList->a[j].pTab;
      if( iCol<0 ) iCol = pTab->iPKey;
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zCol = "rowid";
      }else{
        zCol = pTab->aCol[iCol].zName;
      }
      if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
        sqlite3VdbeSetColName(v, i, (char*)p->span.z, p->span.n);
      }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
        char *zName = 0;
        char *zTab;
        char *zDb = 0;                                                          /*** ADDED - SQLite.Interop ***/
        int iDb;

        iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);

        zTab = pTabList->a[j].zAlias;
        if( fullNames || zTab==0 ){
          if (iDb > 1) zDb = db->aDb[iDb].zName;                    /*** ADDED - SQLite.Interop ***/
          zTab = pTab->zName;
        }
        if (!zDb || !realNames) sqlite3SetString(&zName, zTab, "\x01", zCol, 0);   /*** CHANGED - SQLite.Interop ***/
        else sqlite3SetString(&zName, zDb, "\x01", zTab, "\x01", zCol, 0);            /*** ADDED - SQLite.Interop ***/
        sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
      }else{
        sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
      }
    }else if( p->span.z && p->span.z[0] ){
      sqlite3VdbeSetColName(v, i, (char*)p->span.z, p->span.n);
      /* sqlite3VdbeCompressSpace(v, addr); */
    }else{
      char zName[30];
      assert( p->op!=TK_COLUMN || pTabList==0 );
      sprintf(zName, "column%d", i+1);
      sqlite3VdbeSetColName(v, i, zName, 0);
    }
  }
  generateColumnTypes(pParse, pTabList, pEList);
}

#ifdef OS_WIN

#include <tchar.h>

typedef void (__stdcall *SQLITEUSERFUNC)(void *, int, void **);
typedef int  (__stdcall *SQLITECOLLATION)(int, const void *, int, const void*);

typedef int (__stdcall *ENCRYPTFILEW)(const wchar_t *);
typedef int (__stdcall *ENCRYPTEDSTATUSW)(const wchar_t *, unsigned long *);
typedef int (__stdcall *DECRYPTFILEW)(const wchar_t *, unsigned long);

typedef HANDLE (__stdcall *CREATEFILEW)(
    LPCWSTR,
    DWORD,
    DWORD,
    LPSECURITY_ATTRIBUTES,
    DWORD,
    DWORD,
    HANDLE);

// Callback wrappers
int sqlite3_interop_collationfunc(void *pv, int len1, const void *pv1, int len2, const void *pv2)
{
  SQLITECOLLATION *p = (SQLITECOLLATION *)pv;
  return p[0](len1, pv1, len2, pv2);
}

void sqlite3_interop_func(sqlite3_context *pctx, int n, sqlite3_value **pv)
{
  SQLITEUSERFUNC *pf = (SQLITEUSERFUNC *)sqlite3_user_data(pctx);
  pf[0](pctx, n, (void **)pv);
}

void sqlite3_interop_step(sqlite3_context *pctx, int n, sqlite3_value **pv)
{
  SQLITEUSERFUNC *pf = (SQLITEUSERFUNC *)sqlite3_user_data(pctx);
  pf[1](pctx, n, (void **)pv);
}

void sqlite3_interop_final(sqlite3_context *pctx)
{
  SQLITEUSERFUNC *pf = (SQLITEUSERFUNC *)sqlite3_user_data(pctx);
  pf[2](pctx, 0, 0);
}

__declspec(dllexport) void __stdcall sqlite3_sleep_interop(int milliseconds)
{
  Sleep(milliseconds);
}

__declspec(dllexport) int sqlite3_encryptfile(const wchar_t *pwszFilename)
{
  HMODULE hMod = LoadLibrary(_T("ADVAPI32"));
  ENCRYPTFILEW pfunc;
  int n;

  if (hMod == NULL)
  {
    SetLastError(ERROR_NOT_SUPPORTED);
    return 0;
  }
  
  pfunc = (ENCRYPTFILEW)GetProcAddress(hMod, _T("EncryptFileW"));
  if (pfunc == NULL)
  {
    SetLastError(ERROR_NOT_SUPPORTED);
    return 0;
  }

  n = pfunc(pwszFilename);

  FreeLibrary(hMod);

  return n;
}

__declspec(dllexport) int sqlite3_decryptfile(const wchar_t *pwszFilename)
{
  HMODULE hMod = LoadLibrary(_T("ADVAPI32"));
  DECRYPTFILEW pfunc;
  int n;

  if (hMod == NULL)
  {
    SetLastError(ERROR_NOT_SUPPORTED);
    return 0;
  }

  pfunc = (DECRYPTFILEW)GetProcAddress(hMod, _T("DecryptFileW"));
  if (pfunc == NULL)
  {
    SetLastError(ERROR_NOT_SUPPORTED);
    return 0;
  }

  n = pfunc(pwszFilename, 0);

  FreeLibrary(hMod);

  return n;
}

__declspec(dllexport) unsigned long sqlite3_encryptedstatus(const wchar_t *pwszFilename, unsigned long *pdwStatus)
{
  HMODULE hMod = LoadLibrary(_T("ADVAPI32"));
  ENCRYPTEDSTATUSW pfunc;
  int n;

  if (hMod == NULL)
  {
    SetLastError(ERROR_NOT_SUPPORTED);
    return 0;
  }

  pfunc = (ENCRYPTEDSTATUSW)GetProcAddress(hMod, _T("FileEncryptionStatusW"));
  if (pfunc == NULL)
  {
    SetLastError(ERROR_NOT_SUPPORTED);
    return 0;
  }

  n = pfunc(pwszFilename, pdwStatus);

  FreeLibrary(hMod);

  return n;
}

int SetCompression(const wchar_t *pwszFilename, unsigned short ufLevel)
{
#ifdef FSCTL_SET_COMPRESSION
  HMODULE hMod = GetModuleHandle(_T("KERNEL32"));
  CREATEFILEW pfunc;
  HANDLE hFile;
  unsigned long dw = 0;
  int n;

  if (hMod == NULL)
  {
    SetLastError(ERROR_NOT_SUPPORTED);
    return 0;
  }

  pfunc = (CREATEFILEW)GetProcAddress(hMod, _T("CreateFileW"));
  if (pfunc == NULL)
  {
    SetLastError(ERROR_NOT_SUPPORTED);
    return 0;
  }

  hFile = pfunc(pwszFilename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile == NULL)
    return 0;

  n = DeviceIoControl(hFile, FSCTL_SET_COMPRESSION, &ufLevel, sizeof(ufLevel), NULL, 0, &dw, NULL);

  CloseHandle(hFile);

  return n;
#else
  SetLastError(ERROR_NOT_SUPPORTED);
  return 0;
#endif
}

__declspec(dllexport) int __stdcall sqlite3_compressfile(const wchar_t *pwszFilename)
{
  return SetCompression(pwszFilename, COMPRESSION_FORMAT_DEFAULT);
}

__declspec(dllexport) int __stdcall sqlite3_decompressfile(const wchar_t *pwszFilename)
{
  return SetCompression(pwszFilename, COMPRESSION_FORMAT_NONE);
}

__declspec(dllexport) void __stdcall sqlite3_function_free_callbackcookie(void *pCookie)
{
  if (pCookie)
    free(pCookie);
}

// sqlite3 wrappers
__declspec(dllexport) const char * __stdcall sqlite3_libversion_interop(int *plen)
{
  const char *val = sqlite3_libversion();
  *plen = (val != 0) ? strlen(val) : 0;

  return val;
}

__declspec(dllexport) int __stdcall sqlite3_libversion_number_interop(void)
{
  return sqlite3_libversion_number();
}

__declspec(dllexport) int __stdcall sqlite3_close_interop(sqlite3 *db)
{
  return sqlite3_close(db);
}

__declspec(dllexport) int __stdcall sqlite3_exec_interop(sqlite3 *db, const char *sql, sqlite3_callback cb, void *pv, char **errmsg, int *plen)
{
  int n = sqlite3_exec(db, sql, cb, pv, errmsg);
  *plen = (*errmsg != 0) ? strlen(*errmsg) : 0;
  return n;
}

__declspec(dllexport) sqlite_int64 __stdcall sqlite3_last_insert_rowid_interop(sqlite3 *db)
{
  return sqlite3_last_insert_rowid(db);
}

__declspec(dllexport) int __stdcall sqlite3_changes_interop(sqlite3 *db)
{
  return sqlite3_changes(db);
}

__declspec(dllexport) int __stdcall sqlite3_total_changes_interop(sqlite3 *db)
{
  return sqlite3_total_changes(db);
}

__declspec(dllexport) void __stdcall sqlite3_interrupt_interop(sqlite3 *db)
{
  sqlite3_interrupt(db);
}

__declspec(dllexport) int __stdcall sqlite3_complete_interop(const char *sql)
{
  return sqlite3_complete(sql);
}

__declspec(dllexport) int __stdcall sqlite3_complete16_interop(const void *sql)
{
  return sqlite3_complete16(sql);
}

__declspec(dllexport) int __stdcall sqlite3_busy_handler_interop(sqlite3 *db, int(*cb)(void *, int), void *pv)
{
  return sqlite3_busy_handler(db, cb, pv);
}

__declspec(dllexport) int __stdcall sqlite3_busy_timeout_interop(sqlite3 *db, int ms)
{
  return sqlite3_busy_timeout(db, ms);
}

__declspec(dllexport) int __stdcall sqlite3_get_table_interop(sqlite3 *db, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg, int *plen)
{
  int n = sqlite3_get_table(db, sql, resultp, nrow, ncolumn, errmsg);
  *plen = (*errmsg != 0) ? strlen((char *)*errmsg) : 0;
  return n;
}

__declspec(dllexport) void __stdcall sqlite3_free_table_interop(char **result)
{
  sqlite3_free_table(result);
}

__declspec(dllexport) void __stdcall sqlite3_free_interop(char *z)
{
  sqlite3_free(z);
}

__declspec(dllexport) int __stdcall sqlite3_open_interop(const char*filename, sqlite3 **ppdb)
{
  return sqlite3_open(filename, ppdb);
}

__declspec(dllexport) int __stdcall sqlite3_open16_interop(const void *filename, sqlite3 **ppdb)
{
  return sqlite3_open16(filename, ppdb);
}

__declspec(dllexport) int __stdcall sqlite3_errcode_interop(sqlite3 *db)
{
  return sqlite3_errcode(db);
}

__declspec(dllexport) const char * __stdcall sqlite3_errmsg_interop(sqlite3 *db, int *plen)
{
  const char *pval = sqlite3_errmsg(db);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_errmsg16_interop(sqlite3 *db, int *plen)
{
  const void *pval = sqlite3_errmsg16(db);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t): 0;
  return pval;
}

__declspec(dllexport) int __stdcall sqlite3_prepare_interop(sqlite3 *db, const char *sql, int nbytes, sqlite3_stmt **ppstmt, const char **pztail, int *plen)
{
  int n = sqlite3_prepare(db, sql, nbytes, ppstmt, pztail);
  *plen = (*pztail != 0) ? strlen(*pztail) : 0;
  return n;
}

__declspec(dllexport) int __stdcall sqlite3_prepare16_interop(sqlite3 *db, const void *sql, int nchars, sqlite3_stmt **ppstmt, const void **pztail, int *plen)
{
  int n = sqlite3_prepare16(db, sql, nchars * sizeof(wchar_t), ppstmt, pztail);
  *plen = (*pztail != 0) ? wcslen((wchar_t *)*pztail) * sizeof(wchar_t) : 0;
  return n;
}

__declspec(dllexport) int __stdcall sqlite3_bind_blob_interop(sqlite3_stmt *stmt, int iCol, const void *pv, int n, void(*cb)(void*))
{
  return sqlite3_bind_blob(stmt, iCol, pv, n, cb);
}

__declspec(dllexport) int __stdcall sqlite3_bind_double_interop(sqlite3_stmt *stmt, int iCol, double *val)
{
	return sqlite3_bind_double(stmt,iCol,*val);
}

__declspec(dllexport) int __stdcall sqlite3_bind_int_interop(sqlite3_stmt *stmt, int iCol, int val)
{
  return sqlite3_bind_int(stmt, iCol, val);
}

__declspec(dllexport) int __stdcall sqlite3_bind_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val)
{
	return sqlite3_bind_int64(stmt,iCol,*val);
}

__declspec(dllexport) int __stdcall sqlite3_bind_null_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_bind_null(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_bind_text_interop(sqlite3_stmt *stmt, int iCol, const char *val, int n, void(*cb)(void *))
{
  return sqlite3_bind_text(stmt, iCol, val, n, cb);
}

__declspec(dllexport) int __stdcall sqlite3_bind_text16_interop(sqlite3_stmt *stmt, int iCol, const void *val, int n, void(*cb)(void *))
{
  return sqlite3_bind_text16(stmt, iCol, val, n, cb);
}

__declspec(dllexport) int __stdcall sqlite3_bind_parameter_count_interop(sqlite3_stmt *stmt)
{
  return sqlite3_bind_parameter_count(stmt);
}

__declspec(dllexport) const char * __stdcall sqlite3_bind_parameter_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_bind_parameter_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) int __stdcall sqlite3_bind_parameter_index_interop(sqlite3_stmt *stmt, const char *zName)
{
  return sqlite3_bind_parameter_index(stmt, zName);
}

__declspec(dllexport) int __stdcall sqlite3_column_count_interop(sqlite3_stmt *stmt)
{
  return sqlite3_column_count(stmt);
}

__declspec(dllexport) const char * __stdcall sqlite3_column_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_column_name16_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const void *pval = sqlite3_column_name16(stmt, iCol);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t) : 0;
  return pval;
}

__declspec(dllexport) const char * __stdcall sqlite3_column_decltype_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_decltype(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_column_decltype16_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const void *pval = sqlite3_column_decltype16(stmt, iCol);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t) : 0;
  return pval;
}

__declspec(dllexport) int __stdcall sqlite3_step_interop(sqlite3_stmt *stmt)
{
  return sqlite3_step(stmt);
}

__declspec(dllexport) int __stdcall sqlite3_data_count_interop(sqlite3_stmt *stmt)
{
  return sqlite3_data_count(stmt);
}

__declspec(dllexport) const void * __stdcall sqlite3_column_blob_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_blob(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_bytes_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_bytes(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_bytes16_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_bytes16(stmt, iCol);
}

__declspec(dllexport) void __stdcall sqlite3_column_double_interop(sqlite3_stmt *stmt, int iCol, double *val)
{
	*val = sqlite3_column_double(stmt,iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_int_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_int(stmt, iCol);
}

__declspec(dllexport) void __stdcall sqlite3_column_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val)
{
	*val = sqlite3_column_int64(stmt,iCol);
}

__declspec(dllexport) const unsigned char * __stdcall sqlite3_column_text_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const unsigned char *pval = sqlite3_column_text(stmt, iCol);
  *plen = (pval != 0) ? strlen((char *)pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_column_text16_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const void *pval = sqlite3_column_text16(stmt, iCol);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t): 0;
  return pval;
}

__declspec(dllexport) int __stdcall sqlite3_column_type_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_type(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_finalize_interop(sqlite3_stmt *stmt)
{
  return sqlite3_finalize(stmt);
}

__declspec(dllexport) int __stdcall sqlite3_reset_interop(sqlite3_stmt *stmt)
{
  return sqlite3_reset(stmt);
}

__declspec(dllexport) int __stdcall sqlite3_create_function_interop(sqlite3 *psql, const char *zFunctionName, int nArg, int eTextRep, SQLITEUSERFUNC func, SQLITEUSERFUNC funcstep, SQLITEUSERFUNC funcfinal, void **ppCookie)
{
  int n;
  SQLITEUSERFUNC *p = (SQLITEUSERFUNC *)malloc(sizeof(SQLITEUSERFUNC) * 3);

  p[0] = func;
  p[1] = funcstep;
  p[2] = funcfinal;

  *ppCookie = 0;

  n = sqlite3_create_function(psql, zFunctionName, nArg, eTextRep, p, (func != 0) ? sqlite3_interop_func : 0, (funcstep != 0) ? sqlite3_interop_step : 0, (funcfinal != 0) ? sqlite3_interop_final : 0);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_create_function16_interop(sqlite3 *psql, void *zFunctionName, int nArg, int eTextRep, SQLITEUSERFUNC func, SQLITEUSERFUNC funcstep, SQLITEUSERFUNC funcfinal, void **ppCookie)
{
  int n;
  SQLITEUSERFUNC *p = (SQLITEUSERFUNC *)malloc(sizeof(SQLITEUSERFUNC) * 3);

  p[0] = func;
  p[1] = funcstep;
  p[2] = funcfinal;

  *ppCookie = 0;

  n = sqlite3_create_function16(psql, zFunctionName, nArg, eTextRep, p, (func != 0) ? sqlite3_interop_func : 0, (funcstep != 0) ? sqlite3_interop_step : 0, (funcfinal != 0) ? sqlite3_interop_final : 0);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_create_collation_interop(sqlite3* db, const char *zName, int eTextRep, void* pvUser, SQLITECOLLATION func, void **ppCookie)
{
  int n;
  SQLITECOLLATION *p = (SQLITECOLLATION *)malloc(sizeof(SQLITECOLLATION));
  
  p[0] = func;

  *ppCookie = 0;

  n = sqlite3_create_collation(db, zName, eTextRep, p, sqlite3_interop_collationfunc);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_create_collation16_interop(sqlite3* db, const void *zName, int eTextRep, void* pvUser, SQLITECOLLATION func, void **ppCookie)
{
  int n;
  SQLITECOLLATION *p = (SQLITECOLLATION *)malloc(sizeof(SQLITECOLLATION));
  
  p[0] = func;

  *ppCookie = 0;

  n = sqlite3_create_collation16(db, (const char *)zName, eTextRep, p, sqlite3_interop_collationfunc);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_aggregate_count_interop(sqlite3_context *pctx)
{
  return sqlite3_aggregate_count(pctx);
}

__declspec(dllexport) const void * __stdcall sqlite3_value_blob_interop(sqlite3_value *val)
{
  return sqlite3_value_blob(val);
}

__declspec(dllexport) int __stdcall sqlite3_value_bytes_interop(sqlite3_value *val)
{
  return sqlite3_value_bytes(val);
}

__declspec(dllexport) int __stdcall sqlite3_value_bytes16_interop(sqlite3_value *val)
{
  return sqlite3_value_bytes16(val);
}

__declspec(dllexport) void __stdcall sqlite3_value_double_interop(sqlite3_value *pval, double *val)
{
  *val = sqlite3_value_double(pval);
}

__declspec(dllexport) int __stdcall sqlite3_value_int_interop(sqlite3_value *val)
{
  return sqlite3_value_int(val);
}

__declspec(dllexport) void __stdcall sqlite3_value_int64_interop(sqlite3_value *pval, sqlite_int64 *val)
{
  *val = sqlite3_value_int64(pval);
}

__declspec(dllexport) const unsigned char * __stdcall sqlite3_value_text_interop(sqlite3_value *val, int *plen)
{
  const unsigned char *pval = sqlite3_value_text(val);
  *plen = (pval != 0) ? strlen((char *)pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_value_text16_interop(sqlite3_value *val, int *plen)
{
  const void *pval = sqlite3_value_text16(val);
  *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t) : 0;
  return pval;
}

__declspec(dllexport) int __stdcall sqlite3_value_type_interop(sqlite3_value *val)
{
  return sqlite3_value_type(val);
}

__declspec(dllexport) void * __stdcall sqlite3_aggregate_context_interop(sqlite3_context *pctx, int n)
{
  return sqlite3_aggregate_context(pctx, n);
}

__declspec(dllexport) void __stdcall sqlite3_result_blob_interop(sqlite3_context *ctx, const void *pv, int n, void(*cb)(void *))
{
  sqlite3_result_blob(ctx, pv, n, cb);
}

__declspec(dllexport) void __stdcall sqlite3_result_double_interop(sqlite3_context *pctx, double *val)
{
  sqlite3_result_double(pctx, *val);
}

__declspec(dllexport) void __stdcall sqlite3_result_int_interop(sqlite3_context *pctx, int val)
{
  sqlite3_result_int(pctx, val);
}

__declspec(dllexport) void __stdcall sqlite3_result_int64_interop(sqlite3_context *pctx, sqlite_int64 *val)
{
  sqlite3_result_int64(pctx, *val);
}

__declspec(dllexport) void __stdcall sqlite3_result_null_interop(sqlite3_context *pctx)
{
  sqlite3_result_null(pctx);
}

__declspec(dllexport) void __stdcall sqlite3_result_error_interop(sqlite3_context *ctx, const char *pv, int n)
{
  sqlite3_result_error(ctx, pv, n);
}

__declspec(dllexport) void __stdcall sqlite3_result_error16_interop(sqlite3_context *ctx, const void *pv, int n)
{
  sqlite3_result_error16(ctx, pv, n);
}

__declspec(dllexport) void __stdcall sqlite3_result_text_interop(sqlite3_context *ctx, const char *pv, int n, void(*cb)(void *))
{
  sqlite3_result_text(ctx, pv, n, cb);
}

__declspec(dllexport) void __stdcall sqlite3_result_text16_interop(sqlite3_context *ctx, const void *pv, int n, void(*cb)(void *))
{
  sqlite3_result_text16(ctx, pv, n, cb);
}

__declspec(dllexport) void __stdcall sqlite3_realcolnames(sqlite3 *db, int bOn)
{
  if (bOn)
    db->flags |= 0x01000000;
  else
    db->flags &= (~0x01000000);
}

#endif // OS_WIN
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Added SQLite.Interop/interop.h.




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
/*
   This interop file must be included at or near the top of the select.c file of the SQLite3 source distribution.

   generateColumnNames() in the select.c must be renamed to _generateColumnNames

*/
#include "os.h"
#include "sqliteint.h"

static void generateColumnTypes(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
);

static void _generateColumnNames(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
);

/*
** Generate code that will tell the VDBE the names of columns
** in the result set.  This information is used to provide the
** azCol[] values in the callback.
*/
static void generateColumnNames(
  Parse *pParse,      /* Parser context */
  SrcList *pTabList,  /* List of tables */
  ExprList *pEList    /* Expressions defining the result set */
){
  Vdbe *v = pParse->pVdbe;
  int i, j;
  sqlite3 *db = pParse->db;
  int fullNames, shortNames;
  int realNames;                                     /*** ADDED - SQLite.Interop ***/

  realNames = (db->flags & 0x01000000)!=0;           /*** ADDED - SQLite.Interop ***/
  if (!realNames) // Default to normal Sqlite3       /*** ADDED - SQLite.Interop ***/
  {                                                  /*** ADDED - SQLite.Interop ***/
    _generateColumnNames(pParse, pTabList, pEList);  /*** ADDED - SQLite.Interop ***/
    return;                                          /*** ADDED - SQLite.Interop ***/
  }                                                  /*** ADDED - SQLite.Interop ***/

#ifndef SQLITE_OMIT_EXPLAIN
  /* If this is an EXPLAIN, skip this step */
  if( pParse->explain ){
    return;
  }
#endif

  assert( v!=0 );
  if( pParse->colNamesSet || v==0 || sqlite3_malloc_failed ) return;
  pParse->colNamesSet = 1;
  fullNames = (db->flags & SQLITE_FullColNames)!=0;
  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
  if (realNames) fullNames = 1;                      /*** ADDED - SQLite.Interop ***/

  sqlite3VdbeSetNumCols(v, pEList->nExpr);
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    p = pEList->a[i].pExpr;
    if( p==0 ) continue;
    if( pEList->a[i].zName && (realNames == 0 || p->op != TK_COLUMN)){   /*** CHANGED - SQLite.Interop ***/
      char *zName = pEList->a[i].zName;
      sqlite3VdbeSetColName(v, i, zName, strlen(zName));
      continue;
    }
    if( p->op==TK_COLUMN && pTabList ){
      Table *pTab;
      char *zCol;
      int iCol = p->iColumn;
      for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
      assert( j<pTabList->nSrc );
      pTab = pTabList->a[j].pTab;
      if( iCol<0 ) iCol = pTab->iPKey;
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zCol = "rowid";
      }else{
        zCol = pTab->aCol[iCol].zName;
      }
      if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
        sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
      }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
        char *zName = 0;
        char *zTab;
        char *zDb = 0;                                                          /*** ADDED - SQLite.Interop ***/
 
        zTab = pTabList->a[j].zAlias;
        if( fullNames || zTab==0 ){
          if (pTab->iDb > 1) zDb = db->aDb[pTab->iDb].zName;                    /*** ADDED - SQLite.Interop ***/
          zTab = pTab->zName;
        }
        if (!zDb || !realNames) sqlite3SetString(&zName, zTab, ".", zCol, 0);   /*** CHANGED - SQLite.Interop ***/
        else sqlite3SetString(&zName, zDb, ".", zTab, ".", zCol, 0);            /*** ADDED - SQLite.Interop ***/
        sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
      }else{
        sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
      }
    }else if( p->span.z && p->span.z[0] ){
      sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
      /* sqlite3VdbeCompressSpace(v, addr); */
    }else{
      char zName[30];
      assert( p->op!=TK_COLUMN || pTabList==0 );
      sprintf(zName, "column%d", i+1);
      sqlite3VdbeSetColName(v, i, zName, 0);
    }
  }
  generateColumnTypes(pParse, pTabList, pEList);
}

#ifdef OS_WIN

typedef void (__stdcall *SQLITEUSERFUNC)(void *, int, void **);
typedef int  (__stdcall *SQLITECOLLATION)(int, const void *, int, const void*);

// Callback wrappers
int sqlite3_interop_collationfunc(void *pv, int len1, const void *pv1, int len2, const void *pv2)
{
  SQLITECOLLATION *p = (SQLITECOLLATION *)pv;
  return p[0](len1, pv1, len2, pv2);
}

void sqlite3_interop_func(sqlite3_context *pctx, int n, sqlite3_value **pv)
{
  SQLITEUSERFUNC *pf = (SQLITEUSERFUNC *)sqlite3_user_data(pctx);
  pf[0](pctx, n, pv);
}

void sqlite3_interop_step(sqlite3_context *pctx, int n, sqlite3_value **pv)
{
  SQLITEUSERFUNC *pf = (SQLITEUSERFUNC *)sqlite3_user_data(pctx);
  pf[1](pctx, n, pv);
}

void sqlite3_interop_final(sqlite3_context *pctx)
{
  SQLITEUSERFUNC *pf = (SQLITEUSERFUNC *)sqlite3_user_data(pctx);
  pf[2](pctx, 0, 0);
}

__declspec(dllexport) void __stdcall sqlite3_function_free_callbackcookie(void *pCookie)
{
  if (pCookie)
    free(pCookie);
}

// sqlite3 wrappers
__declspec(dllexport) const char * __stdcall sqlite3_libversion_interop(int *plen)
{
  const char *val = sqlite3_libversion();
  *plen = (val != 0) ? strlen(val) : 0;

  return val;
}

__declspec(dllexport) int __stdcall sqlite3_libversion_number_interop(void)
{
  return sqlite3_libversion_number();
}

__declspec(dllexport) int __stdcall sqlite3_close_interop(sqlite3 *db)
{
  return sqlite3_close(db);
}

__declspec(dllexport) int __stdcall sqlite3_exec_interop(sqlite3 *db, const char *sql, sqlite3_callback cb, void *pv, char **errmsg, int *plen)
{
  int n = sqlite3_exec(db, sql, cb, pv, errmsg);
  *plen = (*errmsg != 0) ? strlen(*errmsg) : 0;
  return n;
}

__declspec(dllexport) sqlite_int64 __stdcall sqlite3_last_insert_rowid_interop(sqlite3 *db)
{
  return sqlite3_last_insert_rowid(db);
}

__declspec(dllexport) int __stdcall sqlite3_changes_interop(sqlite3 *db)
{
  return sqlite3_changes(db);
}

__declspec(dllexport) int __stdcall sqlite3_total_changes_interop(sqlite3 *db)
{
  return sqlite3_total_changes(db);
}

__declspec(dllexport) void __stdcall sqlite3_interrupt_interop(sqlite3 *db)
{
  sqlite3_interrupt(db);
}

__declspec(dllexport) int __stdcall sqlite3_complete_interop(const char *sql)
{
  return sqlite3_complete(sql);
}

__declspec(dllexport) int __stdcall sqlite3_complete16_interop(const void *sql)
{
  return sqlite3_complete16(sql);
}

__declspec(dllexport) int __stdcall sqlite3_busy_handler_interop(sqlite3 *db, int(*cb)(void *, int), void *pv)
{
  return sqlite3_busy_handler(db, cb, pv);
}

__declspec(dllexport) int __stdcall sqlite3_busy_timeout_interop(sqlite3 *db, int ms)
{
  return sqlite3_busy_timeout(db, ms);
}

__declspec(dllexport) int __stdcall sqlite3_get_table_interop(sqlite3 *db, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg, int *plen)
{
  int n = sqlite3_get_table(db, sql, resultp, nrow, ncolumn, errmsg);
  *plen = (*errmsg != 0) ? strlen((char *)*errmsg) : 0;
  return n;
}

__declspec(dllexport) void __stdcall sqlite3_free_table_interop(char **result)
{
  sqlite3_free_table(result);
}

__declspec(dllexport) void __stdcall sqlite3_free_interop(char *z)
{
  sqlite3_free(z);
}

__declspec(dllexport) int __stdcall sqlite3_open_interop(const char*filename, sqlite3 **ppdb)
{
  return sqlite3_open(filename, ppdb);
}

__declspec(dllexport) int __stdcall sqlite3_open16_interop(const void *filename, sqlite3 **ppdb)
{
  return sqlite3_open16(filename, ppdb);
}

__declspec(dllexport) int __stdcall sqlite3_errcode_interop(sqlite3 *db)
{
  return sqlite3_errcode(db);
}

__declspec(dllexport) const char * __stdcall sqlite3_errmsg_interop(sqlite3 *db, int *plen)
{
  const char *pval = sqlite3_errmsg(db);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_errmsg16_interop(sqlite3 *db)
{
  return sqlite3_errmsg16(db);
}

__declspec(dllexport) int __stdcall sqlite3_prepare_interop(sqlite3 *db, const char *sql, int nbytes, sqlite3_stmt **ppstmt, const char **pztail, int *plen)
{
  int n = sqlite3_prepare(db, sql, nbytes, ppstmt, pztail);
  *plen = (*pztail != 0) ? strlen(*pztail) : 0;
  return n;
}

__declspec(dllexport) int __stdcall sqlite3_prepare16_interop(sqlite3 *db, const void *sql, int nbytes, sqlite3_stmt **ppstmt, const void **pztail)
{
  return sqlite3_prepare16(db, sql, nbytes, ppstmt, pztail);
}

__declspec(dllexport) int __stdcall sqlite3_bind_blob_interop(sqlite3_stmt *stmt, int iCol, const void *pv, int n, void(*cb)(void*))
{
  return sqlite3_bind_blob(stmt, iCol, pv, n, cb);
}

__declspec(dllexport) int __stdcall sqlite3_bind_double_interop(sqlite3_stmt *stmt, int iCol, double *val)
{
	return sqlite3_bind_double(stmt,iCol,*val);
}

__declspec(dllexport) int __stdcall sqlite3_bind_int_interop(sqlite3_stmt *stmt, int iCol, int val)
{
  return sqlite3_bind_int(stmt, iCol, val);
}

__declspec(dllexport) int __stdcall sqlite3_bind_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val)
{
	return sqlite3_bind_int64(stmt,iCol,*val);
}

__declspec(dllexport) int __stdcall sqlite3_bind_null_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_bind_null(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_bind_text_interop(sqlite3_stmt *stmt, int iCol, const char *val, int n, void(*cb)(void *))
{
  return sqlite3_bind_text(stmt, iCol, val, n, cb);
}

__declspec(dllexport) int __stdcall sqlite3_bind_text16_interop(sqlite3_stmt *stmt, int iCol, const void *val, int n, void(*cb)(void *))
{
  return sqlite3_bind_text16(stmt, iCol, val, n, cb);
}

__declspec(dllexport) int __stdcall sqlite3_bind_parameter_count_interop(sqlite3_stmt *stmt)
{
  return sqlite3_bind_parameter_count(stmt);
}

__declspec(dllexport) const char * __stdcall sqlite3_bind_parameter_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_bind_parameter_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) int __stdcall sqlite3_bind_parameter_index_interop(sqlite3_stmt *stmt, const char *zName)
{
  return sqlite3_bind_parameter_index(stmt, zName);
}

__declspec(dllexport) int __stdcall sqlite3_column_count_interop(sqlite3_stmt *stmt)
{
  return sqlite3_column_count(stmt);
}

__declspec(dllexport) const char * __stdcall sqlite3_column_name_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_name(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_column_name16_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_name16(stmt, iCol);
}

__declspec(dllexport) const char * __stdcall sqlite3_column_decltype_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const char *pval = sqlite3_column_decltype(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_column_decltype16_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_decltype16(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_step_interop(sqlite3_stmt *stmt)
{
  return sqlite3_step(stmt);
}

__declspec(dllexport) int __stdcall sqlite3_data_count_interop(sqlite3_stmt *stmt)
{
  return sqlite3_data_count(stmt);
}

__declspec(dllexport) const void * __stdcall sqlite3_column_blob_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_blob(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_bytes_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_bytes(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_bytes16_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_bytes16(stmt, iCol);
}

__declspec(dllexport) void __stdcall sqlite3_column_double_interop(sqlite3_stmt *stmt, int iCol, double *val)
{
	*val = sqlite3_column_double(stmt,iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_int_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_int(stmt, iCol);
}

__declspec(dllexport) void __stdcall sqlite3_column_int64_interop(sqlite3_stmt *stmt, int iCol, sqlite_int64 *val)
{
	*val = sqlite3_column_int64(stmt,iCol);
}

__declspec(dllexport) const unsigned char * __stdcall sqlite3_column_text_interop(sqlite3_stmt *stmt, int iCol, int *plen)
{
  const unsigned char *pval = sqlite3_column_text(stmt, iCol);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_column_text16_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_text16(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_column_type_interop(sqlite3_stmt *stmt, int iCol)
{
  return sqlite3_column_type(stmt, iCol);
}

__declspec(dllexport) int __stdcall sqlite3_finalize_interop(sqlite3_stmt *stmt)
{
  return sqlite3_finalize(stmt);
}

__declspec(dllexport) int __stdcall sqlite3_reset_interop(sqlite3_stmt *stmt)
{
  return sqlite3_reset(stmt);
}

__declspec(dllexport) int __stdcall sqlite3_create_function_interop(sqlite3 *psql, const char *zFunctionName, int nArg, int eTextRep, SQLITEUSERFUNC func, SQLITEUSERFUNC funcstep, SQLITEUSERFUNC funcfinal, void **ppCookie)
{
  int n;
  SQLITEUSERFUNC *p = malloc(sizeof(SQLITEUSERFUNC) * 3);

  p[0] = func;
  p[1] = funcstep;
  p[2] = funcfinal;

  *ppCookie = 0;

  n = sqlite3_create_function(psql, zFunctionName, nArg, eTextRep, p, (func != 0) ? sqlite3_interop_func : 0, (funcstep != 0) ? sqlite3_interop_step : 0, (funcfinal != 0) ? sqlite3_interop_final : 0);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_create_function16_interop(sqlite3 *psql, void *zFunctionName, int nArg, int eTextRep, SQLITEUSERFUNC func, SQLITEUSERFUNC funcstep, SQLITEUSERFUNC funcfinal, void **ppCookie)
{
  int n;
  SQLITEUSERFUNC *p = malloc(sizeof(SQLITEUSERFUNC) * 3);

  p[0] = func;
  p[1] = funcstep;
  p[2] = funcfinal;

  *ppCookie = 0;

  n = sqlite3_create_function16(psql, zFunctionName, nArg, eTextRep, p, (func != 0) ? sqlite3_interop_func : 0, (funcstep != 0) ? sqlite3_interop_step : 0, (funcfinal != 0) ? sqlite3_interop_final : 0);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_create_collation_interop(sqlite3* db, const char *zName, int eTextRep, void* pvUser, SQLITECOLLATION func, void **ppCookie)
{
  int n;
  SQLITECOLLATION *p = malloc(sizeof(SQLITECOLLATION));
  
  p[0] = func;

  *ppCookie = 0;

  n = sqlite3_create_collation(db, zName, eTextRep, p, sqlite3_interop_collationfunc);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_create_collation16_interop(sqlite3* db, const void *zName, int eTextRep, void* pvUser, SQLITECOLLATION func, void **ppCookie)
{
  int n;
  SQLITECOLLATION *p = malloc(sizeof(SQLITECOLLATION));
  
  p[0] = func;

  *ppCookie = 0;

  n = sqlite3_create_collation16(db, (const char *)zName, eTextRep, p, sqlite3_interop_collationfunc);
  if (n != 0)
    free(p);
  else
    *ppCookie = p;

  return n;
}

__declspec(dllexport) int __stdcall sqlite3_aggregate_count_interop(sqlite3_context *pctx)
{
  return sqlite3_aggregate_count(pctx);
}

__declspec(dllexport) const void * __stdcall sqlite3_value_blob_interop(sqlite3_value *val)
{
  return sqlite3_value_blob(val);
}

__declspec(dllexport) int __stdcall sqlite3_value_bytes_interop(sqlite3_value *val)
{
  return sqlite3_value_bytes(val);
}

__declspec(dllexport) int __stdcall sqlite3_value_bytes16_interop(sqlite3_value *val)
{
  return sqlite3_value_bytes16(val);
}

__declspec(dllexport) void __stdcall sqlite3_value_double_interop(sqlite3_value *pval, double *val)
{
  *val = sqlite3_value_double(pval);
}

__declspec(dllexport) int __stdcall sqlite3_value_int_interop(sqlite3_value *val)
{
  return sqlite3_value_int(val);
}

__declspec(dllexport) void __stdcall sqlite3_value_int64_interop(sqlite3_value *pval, sqlite_int64 *val)
{
  *val = sqlite3_value_int64(pval);
}

__declspec(dllexport) const unsigned char * __stdcall sqlite3_value_text_interop(sqlite3_value *val, int *plen)
{
  const unsigned char *pval = sqlite3_value_text(val);
  *plen = (pval != 0) ? strlen(pval) : 0;
  return pval;
}

__declspec(dllexport) const void * __stdcall sqlite3_value_text16_interop(sqlite3_value *val)
{
  return sqlite3_value_text16(val);
}

__declspec(dllexport) int __stdcall sqlite3_value_type_interop(sqlite3_value *val)
{
  return sqlite3_value_type(val);
}

__declspec(dllexport) void * __stdcall sqlite3_aggregate_context_interop(sqlite3_context *pctx, int n)
{
  return sqlite3_aggregate_context(pctx, n);
}

__declspec(dllexport) void __stdcall sqlite3_result_blob_interop(sqlite3_context *ctx, const void *pv, int n, void(*cb)(void *))
{
  sqlite3_result_blob(ctx, pv, n, cb);
}

__declspec(dllexport) void __stdcall sqlite3_result_double_interop(sqlite3_context *pctx, double *val)
{
  sqlite3_result_double(pctx, *val);
}

__declspec(dllexport) void __stdcall sqlite3_result_int_interop(sqlite3_context *pctx, int val)
{
  sqlite3_result_int(pctx, val);
}

__declspec(dllexport) void __stdcall sqlite3_result_int64_interop(sqlite3_context *pctx, sqlite_int64 *val)
{
  sqlite3_result_int64(pctx, *val);
}

__declspec(dllexport) void __stdcall sqlite3_result_null_interop(sqlite3_context *pctx)
{
  sqlite3_result_null(pctx);
}

__declspec(dllexport) void __stdcall sqlite3_result_error_interop(sqlite3_context *ctx, const char *pv, int n)
{
  sqlite3_result_error(ctx, pv, n);
}

__declspec(dllexport) void __stdcall sqlite3_result_error16_interop(sqlite3_context *ctx, const void *pv, int n)
{
  sqlite3_result_error16(ctx, pv, n);
}

__declspec(dllexport) void __stdcall sqlite3_result_text_interop(sqlite3_context *ctx, const char *pv, int n, void(*cb)(void *))
{
  sqlite3_result_text(ctx, pv, n, cb);
}

__declspec(dllexport) void __stdcall sqlite3_result_text16_interop(sqlite3_context *ctx, const void *pv, int n, void(*cb)(void *))
{
  sqlite3_result_text16(ctx, pv, n, cb);
}

__declspec(dllexport) void __stdcall sqlite3_realcolnames(sqlite3 *db, int bOn)
{
  if (bOn)
    db->flags |= 0x01000000;
  else
    db->flags &= (~0x01000000);
}

#endif // OS_WIN
Deleted SQLite.Interop/merge.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// This code was automatically generated from assembly
// C:\src\SQLite.NET\System.Data.SQLite\bin\System.Data.SQLite.dll

#include <windef.h>

#pragma data_seg(".clr")
#pragma comment(linker, "/SECTION:.clr,ER")
  char __ph[85184] = {0}; // The number of bytes to reserve
#pragma data_seg()

#pragma comment(lib, "mscoree")

extern BOOL WINAPI _CorDllMain(HANDLE, DWORD, LPVOID);
__declspec(dllexport) BOOL WINAPI _CorDllMainStub(HANDLE hModule, DWORD dwReason, LPVOID pvReserved)
{
  return _CorDllMain(hModule, dwReason, pvReserved);
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































Deleted SQLite.Interop/resource.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by SQLite.Interop.rc

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        101
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Changes to SQLite.Interop/src/alter.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.
*/
#ifndef SQLITE_OMIT_ALTERTABLE








|


<







8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.1 2005/03/01 16:04:26 rmsimpson Exp $
*/
#include "sqliteInt.h"


/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.
*/
#ifndef SQLITE_OMIT_ALTERTABLE

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  sqlite3_value **argv
){
  unsigned char const *zSql = sqlite3_value_text(argv[0]);
  unsigned char const *zTableName = sqlite3_value_text(argv[1]);

  int token;
  Token tname;
  unsigned char const *zCsr = zSql;
  int len = 0;
  char *zRet;

  /* The principle used to locate the table name in the CREATE TABLE 
  ** statement is that the table name is the first token that is immediatedly
  ** followed by a left parenthesis - TK_LP.
  */







|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  sqlite3_value **argv
){
  unsigned char const *zSql = sqlite3_value_text(argv[0]);
  unsigned char const *zTableName = sqlite3_value_text(argv[1]);

  int token;
  Token tname;
  char const *zCsr = zSql;
  int len = 0;
  char *zRet;

  /* The principle used to locate the table name in the CREATE TABLE 
  ** statement is that the table name is the first token that is immediatedly
  ** followed by a left parenthesis - TK_LP.
  */
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
){
  unsigned char const *zSql = sqlite3_value_text(argv[0]);
  unsigned char const *zTableName = sqlite3_value_text(argv[1]);

  int token;
  Token tname;
  int dist = 3;
  unsigned char const *zCsr = zSql;
  int len = 0;
  char *zRet;

  /* The principle used to locate the table name in the CREATE TRIGGER 
  ** statement is that the table name is the first token that is immediatedly
  ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
  ** of TK_WHEN, TK_BEGIN or TK_FOR.







|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
){
  unsigned char const *zSql = sqlite3_value_text(argv[0]);
  unsigned char const *zTableName = sqlite3_value_text(argv[1]);

  int token;
  Token tname;
  int dist = 3;
  char const *zCsr = zSql;
  int len = 0;
  char *zRet;

  /* The principle used to locate the table name in the CREATE TRIGGER 
  ** statement is that the table name is the first token that is immediatedly
  ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
  ** of TK_WHEN, TK_BEGIN or TK_FOR.
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
    sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
        SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
  }
}

/*
** Generate the text of a WHERE expression which can be used to select all
** temporary triggers on table pTab from the sqlite_temp_master table. If
** table pTab has no temporary triggers, or is itself stored in the 
** temporary database, NULL is returned.
*/
static char *whereTempTriggers(Parse *pParse, Table *pTab){
  Trigger *pTrig;
  char *zWhere = 0;
  char *tmp = 0;
  const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */

  /* If the table is not located in the temp-db (in which case NULL is 
  ** returned, loop through the tables list of triggers. For each trigger
  ** that is not part of the temp-db schema, add a clause to the WHERE 
  ** expression being built up in zWhere.
  */
  if( pTab->pSchema!=pTempSchema ){
    for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
      if( pTrig->pSchema==pTempSchema ){
        if( !zWhere ){
          zWhere = sqlite3MPrintf("name=%Q", pTrig->name);
        }else{
          tmp = zWhere;
          zWhere = sqlite3MPrintf("%s OR name=%Q", zWhere, pTrig->name);
          sqliteFree(tmp);
        }
      }
    }
  }
  return zWhere;
}

/*
** Generate code to drop and reload the internal representation of table
** pTab from the database, including triggers and temporary triggers.
** Argument zName is the name of the table in the database schema at
** the time the generated code is executed. This can be different from
** pTab->zName if this function is being called to code part of an 
** "ALTER TABLE RENAME TO" statement.
*/
static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
  Vdbe *v;
  char *zWhere;
  int iDb;                   /* Index of database containing pTab */
#ifndef SQLITE_OMIT_TRIGGER
  Trigger *pTrig;
#endif

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  assert( iDb>=0 );

#ifndef SQLITE_OMIT_TRIGGER
  /* Drop any table triggers from the internal schema. */
  for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){
    int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
    assert( iTrigDb==iDb || iTrigDb==1 );
    sqlite3VdbeOp3(v, OP_DropTrigger, iTrigDb, 0, pTrig->name, 0);
  }
#endif

  /* Drop the table and index from the internal schema */
  sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);

  /* Reload the table, index and permanent trigger schemas. */
  zWhere = sqlite3MPrintf("tbl_name=%Q", zName);
  if( !zWhere ) return;
  sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);

#ifndef SQLITE_OMIT_TRIGGER
  /* Now, if the table is not stored in the temp database, reload any temp 
  ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. 
  */
  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
    sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zWhere, P3_DYNAMIC);
  }
#endif
}

/*
** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
** command. 
*/
void sqlite3AlterRenameTable(
  Parse *pParse,            /* Parser context. */
  SrcList *pSrc,            /* The table to rename. */
  Token *pName              /* The new table name. */
){
  int iDb;                  /* Database that contains the table */
  char *zDb;                /* Name of database iDb */
  Table *pTab;              /* Table being renamed */
  char *zName = 0;          /* NULL-terminated version of pName */ 

  sqlite3 *db = pParse->db; /* Database connection */
  Vdbe *v;
#ifndef SQLITE_OMIT_TRIGGER
  char *zWhere = 0;         /* Where clause to locate temp triggers */
#endif
  
  if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto exit_rename_table;
  assert( pSrc->nSrc==1 );

  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_rename_table;
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  zDb = db->aDb[iDb].zName;

  /* Get a NULL terminated version of the new table name. */
  zName = sqlite3NameFromToken(pName);
  if( !zName ) goto exit_rename_table;

  /* Check that a table or index named 'zName' does not already exist







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













>



|


<




|







162
163
164
165
166
167
168

















































































169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
    sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
        SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
  }
}


















































































/*
** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
** command. 
*/
void sqlite3AlterRenameTable(
  Parse *pParse,            /* Parser context. */
  SrcList *pSrc,            /* The table to rename. */
  Token *pName              /* The new table name. */
){
  int iDb;                  /* Database that contains the table */
  char *zDb;                /* Name of database iDb */
  Table *pTab;              /* Table being renamed */
  char *zName = 0;          /* NULL-terminated version of pName */ 
  char *zWhere = 0;         /* Where clause of schema elements to reparse */
  sqlite3 *db = pParse->db; /* Database connection */
  Vdbe *v;
#ifndef SQLITE_OMIT_TRIGGER
  char *zTempTrig = 0;      /* Where clause to locate temp triggers */
#endif
  

  assert( pSrc->nSrc==1 );

  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_rename_table;
  iDb = pTab->iDb;
  zDb = db->aDb[iDb].zName;

  /* Get a NULL terminated version of the new table name. */
  zName = sqlite3NameFromToken(pName);
  if( !zName ) goto exit_rename_table;

  /* Check that a table or index named 'zName' does not already exist
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360






361












362
363
364
365
366
367
368

369
370

371










372









373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
            "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
              "'sqlite_autoindex_' || %Q || substr(name, %d+18,10) "
            "ELSE name END "
      "WHERE tbl_name=%Q AND "
          "(type='table' OR type='index' OR type='trigger');", 
      zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
#ifndef SQLITE_OMIT_TRIGGER
      zName,
#endif
      zName, strlen(pTab->zName), pTab->zName
  );

#ifndef SQLITE_OMIT_AUTOINCREMENT
  /* If the sqlite_sequence table exists in this database, then update 
  ** it with the new table name.
  */
  if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
    sqlite3NestedParse(pParse,
        "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q",
        zDb, zName, pTab->zName);
  }
#endif

#ifndef SQLITE_OMIT_TRIGGER
  /* If there are TEMP triggers on this table, modify the sqlite_temp_master
  ** table. Don't do this if the table being ALTERed is itself located in
  ** the temp database.
  */






  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){












    sqlite3NestedParse(pParse, 
        "UPDATE sqlite_temp_master SET "
            "sql = sqlite_rename_trigger(sql, %Q), "
            "tbl_name = %Q "
            "WHERE %s;", zName, zName, zWhere);
    sqliteFree(zWhere);
  }

#endif


  /* Drop and reload the internal table schema. */










  reloadTableSchema(pParse, pTab, zName);










exit_rename_table:
  sqlite3SrcListDelete(pSrc);
  sqliteFree(zName);
}


/*
** This function is called after an "ALTER TABLE ... ADD" statement
** has been parsed. Argument pColDef contains the text of the new
** column definition.
**
** The Table structure pParse->pNewTable was extended to include
** the new column during parsing.
*/
void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
  Table *pNew;              /* Copy of pParse->pNewTable */
  Table *pTab;              /* Table being altered */
  int iDb;                  /* Database number */
  const char *zDb;          /* Database name */
  const char *zTab;         /* Table name */
  char *zCol;               /* Null-terminated column definition */
  Column *pCol;             /* The new column */
  Expr *pDflt;              /* Default value for the new column */

  if( pParse->nErr ) return;
  pNew = pParse->pNewTable;
  assert( pNew );

  iDb = sqlite3SchemaToIndex(pParse->db, pNew->pSchema);
  zDb = pParse->db->aDb[iDb].zName;
  zTab = pNew->zName;
  pCol = &pNew->aCol[pNew->nCol-1];
  pDflt = pCol->pDflt;
  pTab = sqlite3FindTable(pParse->db, zTab, zDb);
  assert( pTab );

  /* If the default value for the new column was specified with a 
  ** literal NULL, then set pDflt to 0. This simplifies checking
  ** for an SQL NULL default below.
  */
  if( pDflt && pDflt->op==TK_NULL ){
    pDflt = 0;
  }

  /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
  ** If there is a NOT NULL constraint, then the default value for the
  ** column must not be NULL.
  */
  if( pCol->isPrimKey ){
    sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
    return;
  }
  if( pNew->pIndex ){
    sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
    return;
  }
  if( pCol->notNull && !pDflt ){
    sqlite3ErrorMsg(pParse, 
        "Cannot add a NOT NULL column with default value NULL");
    return;
  }

  /* Ensure the default expression is something that sqlite3ValueFromExpr()
  ** can handle (i.e. not CURRENT_TIME etc.)
  */
  if( pDflt ){
    sqlite3_value *pVal;
    if( sqlite3ValueFromExpr(pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
      /* malloc() has failed */
      return;
    }
    if( !pVal ){
      sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
      return;
    }
    sqlite3ValueFree(pVal);
  }

  /* Modify the CREATE TABLE statement. */
  zCol = sqliteStrNDup((char*)pColDef->z, pColDef->n);
  if( zCol ){
    char *zEnd = &zCol[pColDef->n-1];
    while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){
      *zEnd-- = '\0';
    }
    sqlite3NestedParse(pParse, 
        "UPDATE %Q.%s SET "
          "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d,length(sql)) "
        "WHERE type = 'table' AND name = %Q", 
      zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
      zTab
    );
    sqliteFree(zCol);
  }

  /* If the default value of the new column is NULL, then set the file
  ** format to 2. If the default value of the new column is not NULL,
  ** the file format becomes 3.
  */
  sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);

  /* Reload the schema of the modified table. */
  reloadTableSchema(pParse, pTab, pTab->zName);
}

/*
** This function is called by the parser after the table-name in
** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument 
** pSrc is the full-name of the table being altered.
**
** This routine makes a (partial) copy of the Table structure
** for the table being altered and sets Parse.pNewTable to point
** to it. Routines called by the parser as the column definition
** is parsed (i.e. sqlite3AddColumn()) add the new Column data to 
** the copy. The copy of the Table structure is deleted by tokenize.c 
** after parsing is finished.
**
** Routine sqlite3AlterFinishAddColumn() will be called to complete
** coding the "ALTER TABLE ... ADD" statement.
*/
void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
  Table *pNew;
  Table *pTab;
  Vdbe *v;
  int iDb;
  int i;
  int nAlloc;

  /* Look up the table being altered. */
  assert( pParse->pNewTable==0 );
  if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto exit_begin_add_column;
  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  if( !pTab ) goto exit_begin_add_column;

  /* Make sure this is not an attempt to ALTER a view. */
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
    goto exit_begin_add_column;
  }

  assert( pTab->addColOffset>0 );
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);

  /* Put a copy of the Table struct in Parse.pNewTable for the
  ** sqlite3AddColumn() function and friends to modify.
  */
  pNew = (Table *)sqliteMalloc(sizeof(Table));
  if( !pNew ) goto exit_begin_add_column;
  pParse->pNewTable = pNew;
  pNew->nRef = 1;
  pNew->nCol = pTab->nCol;
  assert( pNew->nCol>0 );
  nAlloc = (((pNew->nCol-1)/8)*8)+8;
  assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
  pNew->aCol = (Column *)sqliteMalloc(sizeof(Column)*nAlloc);
  pNew->zName = sqliteStrDup(pTab->zName);
  if( !pNew->aCol || !pNew->zName ){
    goto exit_begin_add_column;
  }
  memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
  for(i=0; i<pNew->nCol; i++){
    Column *pCol = &pNew->aCol[i];
    pCol->zName = sqliteStrDup(pCol->zName);
    pCol->zType = 0;
    pCol->pDflt = 0;
  }
  pNew->pSchema = pParse->db->aDb[iDb].pSchema;
  pNew->addColOffset = pTab->addColOffset;
  pNew->nRef = 1;

  /* Begin a transaction and increment the schema cookie.  */
  sqlite3BeginWriteOperation(pParse, 0, iDb);
  v = sqlite3GetVdbe(pParse);
  if( !v ) goto exit_begin_add_column;
  sqlite3ChangeCookie(pParse->db, v, iDb);

exit_begin_add_column:
  sqlite3SrcListDelete(pSrc);
  return;
}
#endif  /* SQLITE_ALTER_TABLE */







|




















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


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





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
















































































































































































334
            "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
              "'sqlite_autoindex_' || %Q || substr(name, %d+18,10) "
            "ELSE name END "
      "WHERE tbl_name=%Q AND "
          "(type='table' OR type='index' OR type='trigger');", 
      zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
#ifndef SQLITE_OMIT_TRIGGER
zName,
#endif
      zName, strlen(pTab->zName), pTab->zName
  );

#ifndef SQLITE_OMIT_AUTOINCREMENT
  /* If the sqlite_sequence table exists in this database, then update 
  ** it with the new table name.
  */
  if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
    sqlite3NestedParse(pParse,
        "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q",
        zDb, zName, pTab->zName);
  }
#endif

#ifndef SQLITE_OMIT_TRIGGER
  /* If there are TEMP triggers on this table, modify the sqlite_temp_master
  ** table. Don't do this if the table being ALTERed is itself located in
  ** the temp database.
  */
  if( iDb!=1 ){
    Trigger *pTrig;
    char *tmp = 0;
    for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
      if( pTrig->iDb==1 ){
        if( !zTempTrig ){
          zTempTrig = 
              sqlite3MPrintf("type = 'trigger' AND (name=%Q", pTrig->name);
        }else{
          tmp = zTempTrig;
          zTempTrig = sqlite3MPrintf("%s OR name=%Q", zTempTrig, pTrig->name);
          sqliteFree(tmp);
        }
      }
    }
    if( zTempTrig ){
      tmp = zTempTrig;
      zTempTrig = sqlite3MPrintf("%s)", zTempTrig);
      sqliteFree(tmp);
      sqlite3NestedParse(pParse, 
          "UPDATE sqlite_temp_master SET "
              "sql = sqlite_rename_trigger(sql, %Q), "
              "tbl_name = %Q "
              "WHERE %s;", zName, zName, zTempTrig);

    }
  }
#endif

  /* Drop the elements of the in-memory schema that refered to the table
  ** renamed and load the new versions from the database.
  */
  if( pParse->nErr==0 ){
#ifndef SQLITE_OMIT_TRIGGER
    Trigger *pTrig;
    for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
      assert( pTrig->iDb==iDb || pTrig->iDb==1 );
      sqlite3VdbeOp3(v, OP_DropTrigger, pTrig->iDb, 0, pTrig->name, 0);
    }
#endif
    sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
    zWhere = sqlite3MPrintf("tbl_name=%Q", zName);
    sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);
#ifndef SQLITE_OMIT_TRIGGER
    if( zTempTrig ){
      sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zTempTrig, P3_DYNAMIC);
    }
  }else{
    sqliteFree(zTempTrig);
#endif
  }

exit_rename_table:
  sqlite3SrcListDelete(pSrc);
  sqliteFree(zName);
}
















































































































































































#endif  /* SQLITE_ALTER_TABLE */
Deleted SQLite.Interop/src/analyze.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
/*
** 2005 July 8
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** @(#) $Id: analyze.c,v 1.9 2006/01/16 15:51:47 rmsimpson Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"

/*
** This routine generates code that opens the sqlite_stat1 table on cursor
** iStatCur.
**
** If the sqlite_stat1 tables does not previously exist, it is created.
** If it does previously exist, all entires associated with table zWhere
** are removed.  If zWhere==0 then all entries are removed.
*/
static void openStatTable(
  Parse *pParse,          /* Parsing context */
  int iDb,                /* The database we are looking in */
  int iStatCur,           /* Open the sqlite_stat1 table on this cursor */
  const char *zWhere      /* Delete entries associated with this table */
){
  sqlite3 *db = pParse->db;
  Db *pDb;
  int iRootPage;
  Table *pStat;
  Vdbe *v = sqlite3GetVdbe(pParse);

  pDb = &db->aDb[iDb];
  if( (pStat = sqlite3FindTable(db, "sqlite_stat1", pDb->zName))==0 ){
    /* The sqlite_stat1 tables does not exist.  Create it.  
    ** Note that a side-effect of the CREATE TABLE statement is to leave
    ** the rootpage of the new table on the top of the stack.  This is
    ** important because the OpenWrite opcode below will be needing it. */
    sqlite3NestedParse(pParse,
      "CREATE TABLE %Q.sqlite_stat1(tbl,idx,stat)",
      pDb->zName
    );
    iRootPage = 0;  /* Cause rootpage to be taken from top of stack */
  }else if( zWhere ){
    /* The sqlite_stat1 table exists.  Delete all entries associated with
    ** the table zWhere. */
    sqlite3NestedParse(pParse,
       "DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q",
       pDb->zName, zWhere
    );
    iRootPage = pStat->tnum;
  }else{
    /* The sqlite_stat1 table already exists.  Delete all rows. */
    iRootPage = pStat->tnum;
    sqlite3VdbeAddOp(v, OP_Clear, pStat->tnum, iDb);
  }

  /* Open the sqlite_stat1 table for writing. Unless it was created
  ** by this vdbe program, lock it for writing at the shared-cache level. 
  ** If this vdbe did create the sqlite_stat1 table, then it must have 
  ** already obtained a schema-lock, making the write-lock redundant.
  */
  if( iRootPage>0 ){
    sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
  }
  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
  sqlite3VdbeAddOp(v, OP_OpenWrite, iStatCur, iRootPage);
  sqlite3VdbeAddOp(v, OP_SetNumColumns, iStatCur, 3);
}

/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
static void analyzeOneTable(
  Parse *pParse,   /* Parser context */
  Table *pTab,     /* Table whose indices are to be analyzed */
  int iStatCur,    /* Cursor that writes to the sqlite_stat1 table */
  int iMem         /* Available memory locations begin here */
){
  Index *pIdx;     /* An index to being analyzed */
  int iIdxCur;     /* Cursor number for index being analyzed */
  int nCol;        /* Number of columns in the index */
  Vdbe *v;         /* The virtual machine being built up */
  int i;           /* Loop counter */
  int topOfLoop;   /* The top of the loop */
  int endOfLoop;   /* The end of the loop */
  int addr;        /* The address of an instruction */
  int iDb;         /* Index of database containing pTab */

  v = sqlite3GetVdbe(pParse);
  if( pTab==0 || pTab->pIndex==0 ){
    /* Do no analysis for tables that have no indices */
    return;
  }

  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  assert( iDb>=0 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
      pParse->db->aDb[iDb].zName ) ){
    return;
  }
#endif

  /* Establish a read-lock on the table at the shared-cache level. */
  sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);

  iIdxCur = pParse->nTab;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);

    /* Open a cursor to the index to be analyzed
    */
    assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) );
    sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
    VdbeComment((v, "# %s", pIdx->zName));
    sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum,
        (char *)pKey, P3_KEYINFO_HANDOFF);
    nCol = pIdx->nColumn;
    if( iMem+nCol*2>=pParse->nMem ){
      pParse->nMem = iMem+nCol*2+1;
    }
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, nCol+1);

    /* Memory cells are used as follows:
    **
    **    mem[iMem]:             The total number of rows in the table.
    **    mem[iMem+1]:           Number of distinct values in column 1
    **    ...
    **    mem[iMem+nCol]:        Number of distinct values in column N
    **    mem[iMem+nCol+1]       Last observed value of column 1
    **    ...
    **    mem[iMem+nCol+nCol]:   Last observed value of column N
    **
    ** Cells iMem through iMem+nCol are initialized to 0.  The others
    ** are initialized to NULL.
    */
    for(i=0; i<=nCol; i++){
      sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem+i);
    }
    for(i=0; i<nCol; i++){
      sqlite3VdbeAddOp(v, OP_MemNull, iMem+nCol+i+1, 0);
    }

    /* Do the analysis.
    */
    endOfLoop = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, endOfLoop);
    topOfLoop = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp(v, OP_MemIncr, 1, iMem);
    for(i=0; i<nCol; i++){
      sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
      sqlite3VdbeAddOp(v, OP_MemLoad, iMem+nCol+i+1, 0);
      sqlite3VdbeAddOp(v, OP_Ne, 0x100, 0);
    }
    sqlite3VdbeAddOp(v, OP_Goto, 0, endOfLoop);
    for(i=0; i<nCol; i++){
      addr = sqlite3VdbeAddOp(v, OP_MemIncr, 1, iMem+i+1);
      sqlite3VdbeChangeP2(v, topOfLoop + 3*i + 3, addr);
      sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
      sqlite3VdbeAddOp(v, OP_MemStore, iMem+nCol+i+1, 1);
    }
    sqlite3VdbeResolveLabel(v, endOfLoop);
    sqlite3VdbeAddOp(v, OP_Next, iIdxCur, topOfLoop);
    sqlite3VdbeAddOp(v, OP_Close, iIdxCur, 0);

    /* Store the results.  
    **
    ** The result is a single row of the sqlite_stmt1 table.  The first
    ** two columns are the names of the table and index.  The third column
    ** is a string composed of a list of integer statistics about the
    ** index.  The first integer in the list is the total number of entires
    ** in the index.  There is one additional integer in the list for each
    ** column of the table.  This additional integer is a guess of how many
    ** rows of the table the index will select.  If D is the count of distinct
    ** values and K is the total number of rows, then the integer is computed
    ** as:
    **
    **        I = (K+D-1)/D
    **
    ** If K==0 then no entry is made into the sqlite_stat1 table.  
    ** If K>0 then it is always the case the D>0 so division by zero
    ** is never possible.
    */
    sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
    addr = sqlite3VdbeAddOp(v, OP_IfNot, 0, 0);
    sqlite3VdbeAddOp(v, OP_NewRowid, iStatCur, 0);
    sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
    sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
    sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
    sqlite3VdbeOp3(v, OP_String8, 0, 0, " ", 0);
    for(i=0; i<nCol; i++){
      sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
      sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
      sqlite3VdbeAddOp(v, OP_Add, 0, 0);
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
      sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
      sqlite3VdbeAddOp(v, OP_Divide, 0, 0);
      sqlite3VdbeAddOp(v, OP_ToInt, 0, 0);
      if( i==nCol-1 ){
        sqlite3VdbeAddOp(v, OP_Concat, nCol*2-1, 0);
      }else{
        sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
      }
    }
    sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "aaa", 0);
    sqlite3VdbeAddOp(v, OP_Insert, iStatCur, 0);
    sqlite3VdbeJumpHere(v, addr);
  }
}

/*
** Generate code that will cause the most recent index analysis to
** be laoded into internal hash tables where is can be used.
*/
static void loadAnalysis(Parse *pParse, int iDb){
  Vdbe *v = sqlite3GetVdbe(pParse);
  sqlite3VdbeAddOp(v, OP_LoadAnalysis, iDb, 0);
}

/*
** Generate code that will do an analysis of an entire database
*/
static void analyzeDatabase(Parse *pParse, int iDb){
  sqlite3 *db = pParse->db;
  Schema *pSchema = db->aDb[iDb].pSchema;    /* Schema of database iDb */
  HashElem *k;
  int iStatCur;
  int iMem;

  sqlite3BeginWriteOperation(pParse, 0, iDb);
  iStatCur = pParse->nTab++;
  openStatTable(pParse, iDb, iStatCur, 0);
  iMem = pParse->nMem;
  for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
    Table *pTab = (Table*)sqliteHashData(k);
    analyzeOneTable(pParse, pTab, iStatCur, iMem);
  }
  loadAnalysis(pParse, iDb);
}

/*
** Generate code that will do an analysis of a single table in
** a database.
*/
static void analyzeTable(Parse *pParse, Table *pTab){
  int iDb;
  int iStatCur;

  assert( pTab!=0 );
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  sqlite3BeginWriteOperation(pParse, 0, iDb);
  iStatCur = pParse->nTab++;
  openStatTable(pParse, iDb, iStatCur, pTab->zName);
  analyzeOneTable(pParse, pTab, iStatCur, pParse->nMem);
  loadAnalysis(pParse, iDb);
}

/*
** Generate code for the ANALYZE command.  The parser calls this routine
** when it recognizes an ANALYZE command.
**
**        ANALYZE                            -- 1
**        ANALYZE  <database>                -- 2
**        ANALYZE  ?<database>.?<tablename>  -- 3
**
** Form 1 causes all indices in all attached databases to be analyzed.
** Form 2 analyzes all indices the single database named.
** Form 3 analyzes all indices associated with the named table.
*/
void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
  sqlite3 *db = pParse->db;
  int iDb;
  int i;
  char *z, *zDb;
  Table *pTab;
  Token *pTableName;

  /* Read the database schema. If an error occurs, leave an error message
  ** and code in pParse and return NULL. */
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    return;
  }

  if( pName1==0 ){
    /* Form 1:  Analyze everything */
    for(i=0; i<db->nDb; i++){
      if( i==1 ) continue;  /* Do not analyze the TEMP database */
      analyzeDatabase(pParse, i);
    }
  }else if( pName2==0 || pName2->n==0 ){
    /* Form 2:  Analyze the database or table named */
    iDb = sqlite3FindDb(db, pName1);
    if( iDb>=0 ){
      analyzeDatabase(pParse, iDb);
    }else{
      z = sqlite3NameFromToken(pName1);
      pTab = sqlite3LocateTable(pParse, z, 0);
      sqliteFree(z);
      if( pTab ){
        analyzeTable(pParse, pTab);
      }
    }
  }else{
    /* Form 3: Analyze the fully qualified table name */
    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
    if( iDb>=0 ){
      zDb = db->aDb[iDb].zName;
      z = sqlite3NameFromToken(pTableName);
      pTab = sqlite3LocateTable(pParse, z, zDb);
      sqliteFree(z);
      if( pTab ){
        analyzeTable(pParse, pTab);
      }
    }   
  }
}

/*
** Used to pass information from the analyzer reader through to the
** callback routine.
*/
typedef struct analysisInfo analysisInfo;
struct analysisInfo {
  sqlite3 *db;
  const char *zDatabase;
};

/*
** This callback is invoked once for each index when reading the
** sqlite_stat1 table.  
**
**     argv[0] = name of the index
**     argv[1] = results of analysis - on integer for each column
*/
static int analysisLoader(void *pData, int argc, char **argv, char **azNotUsed){
  analysisInfo *pInfo = (analysisInfo*)pData;
  Index *pIndex;
  int i, c;
  unsigned int v;
  const char *z;

  assert( argc==2 );
  if( argv==0 || argv[0]==0 || argv[1]==0 ){
    return 0;
  }
  pIndex = sqlite3FindIndex(pInfo->db, argv[0], pInfo->zDatabase);
  if( pIndex==0 ){
    return 0;
  }
  z = argv[1];
  for(i=0; *z && i<=pIndex->nColumn; i++){
    v = 0;
    while( (c=z[0])>='0' && c<='9' ){
      v = v*10 + c - '0';
      z++;
    }
    pIndex->aiRowEst[i] = v;
    if( *z==' ' ) z++;
  }
  return 0;
}

/*
** Load the content of the sqlite_stat1 table into the index hash tables.
*/
void sqlite3AnalysisLoad(sqlite3 *db, int iDb){
  analysisInfo sInfo;
  HashElem *i;
  char *zSql;

  /* Clear any prior statistics */
  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
    Index *pIdx = sqliteHashData(i);
    sqlite3DefaultRowEst(pIdx);
  }

  /* Check to make sure the sqlite_stat1 table existss */
  sInfo.db = db;
  sInfo.zDatabase = db->aDb[iDb].zName;
  if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
     return;
  }


  /* Load new statistics out of the sqlite_stat1 table */
  zSql = sqlite3MPrintf("SELECT idx, stat FROM %Q.sqlite_stat1",
                        sInfo.zDatabase);
  sqlite3SafetyOff(db);
  sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
  sqlite3SafetyOn(db);
  sqliteFree(zSql);
}


#endif /* SQLITE_OMIT_ANALYZE */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































Changes to SQLite.Interop/src/attach.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61


62
63

64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82

83
84
85
86

87
88

89
90



91






92




93
94
95
96
97


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136



137
138
139
140




141




142


143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339
340

341



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
/*
** 2003 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** Resolve an expression that was part of an ATTACH or DETACH statement. This
** is slightly different from resolving a normal SQL expression, because simple
** identifiers are treated as strings, not possible column names or aliases.
**
** i.e. if the parser sees:
**
**     ATTACH DATABASE abc AS def
**
** it treats the two expressions as literal strings 'abc' and 'def' instead of
** looking for columns of the same name.
**
** This only applies to the root node of pExpr, so the statement:
**
**     ATTACH DATABASE abc||def AS 'db2'
**
** will fail because neither abc or def can be resolved.
*/
int resolveAttachExpr(NameContext *pName, Expr *pExpr)
{
  int rc = SQLITE_OK;
  if( pExpr ){
    if( pExpr->op!=TK_ID ){
      rc = sqlite3ExprResolveNames(pName, pExpr);
    }else{
      pExpr->op = TK_STRING;
    }
  }
  return rc;
}

/*
** An SQL user-function registered to do the work of an ATTACH statement. The
** three arguments to the function come directly from an attach statement:
**
**     ATTACH DATABASE x AS y KEY z
**
**     SELECT sqlite_attach(x, y, z)
**
** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
** third argument.

*/
static void attachFunc(
  sqlite3_context *context,


  int argc,
  sqlite3_value **argv

){
  int i;
  int rc = 0;
  sqlite3 *db = sqlite3_user_data(context);
  const char *zName;
  const char *zFile;
  Db *aNew;
  char zErr[128];
  char *zErrDyn = 0;

  zFile = (const char *)sqlite3_value_text(argv[0]);

  zName = (const char *)sqlite3_value_text(argv[1]);

  /* Check for the following errors:
  **
  **     * Too many attached databases,
  **     * Transaction currently open
  **     * Specified database name already being used.
  */

  if( db->nDb>=MAX_ATTACHED+2 ){
    sqlite3_snprintf(
      127, zErr, "too many attached databases - max %d", MAX_ATTACHED
    );

    goto attach_error;
  }

  if( !db->autoCommit ){
    strcpy(zErr, "cannot ATTACH database within transaction");



    goto attach_error;






  }




  for(i=0; i<db->nDb; i++){
    char *z = db->aDb[i].zName;
    if( z && sqlite3StrICmp(z, zName)==0 ){
      sqlite3_snprintf(127, zErr, "database %s is already in use", zName);
      goto attach_error;


    }
  }

  /* Allocate the new entry in the db->aDb[] array and initialise the schema
  ** hash tables.
  */
  if( db->aDb==db->aDbStatic ){
    aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
    if( aNew==0 ){
      return;
    }
    memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
  }else{
    aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
    if( aNew==0 ){
      return;
    } 
  }
  db->aDb = aNew;
  aNew = &db->aDb[db->nDb++];
  memset(aNew, 0, sizeof(*aNew));

  /* Open the database file. If the btree is successfully opened, use
  ** it to obtain the database schema. At this point the schema may
  ** or may not be initialised.
  */
  rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
  if( rc==SQLITE_OK ){
    aNew->pSchema = sqlite3SchemaGet(aNew->pBt);
    if( !aNew->pSchema ){
      rc = SQLITE_NOMEM;
    }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
      strcpy(zErr, 
        "attached databases must use the same text encoding as main database");
      goto attach_error;
    }
  }
  aNew->zName = sqliteStrDup(zName);
  aNew->safety_level = 3;




#if SQLITE_HAS_CODEC
  {
    extern int sqlite3CodecAttach(sqlite3*, int, void*, int);




    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);




    int nKey;


    char *zKey;
    int t = sqlite3_value_type(argv[2]);
    switch( t ){
      case SQLITE_INTEGER:
      case SQLITE_FLOAT:
        zErrDyn = sqliteStrDup("Invalid key value");
        rc = SQLITE_ERROR;
        break;
        
      case SQLITE_TEXT:
      case SQLITE_BLOB:
        nKey = sqlite3_value_bytes(argv[2]);
        zKey = (char *)sqlite3_value_blob(argv[2]);
        sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
        break;

      case SQLITE_NULL:
        /* No key specified.  Use the key from the main database */
        sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
        sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);

        break;
    }
  }
#endif

  /* If the file was opened successfully, read the schema for the new database.
  ** If this fails, or if opening the file failed, then close the file and 
  ** remove the entry from the db->aDb[] array. i.e. put everything back the way
  ** we found it.
  */
  if( rc==SQLITE_OK ){
    sqlite3SafetyOn(db);
    rc = sqlite3Init(db, &zErrDyn);
    sqlite3SafetyOff(db);
  }
  if( rc ){
    int i = db->nDb - 1;
    assert( i>=2 );
    if( db->aDb[i].pBt ){
      sqlite3BtreeClose(db->aDb[i].pBt);
      db->aDb[i].pBt = 0;
      db->aDb[i].pSchema = 0;
    }
    sqlite3ResetInternalSchema(db, 0);
    db->nDb = i;
    sqlite3_snprintf(127, zErr, "unable to open database: %s", zFile);
    goto attach_error;
  }
  
  return;

attach_error:
  /* Return an error if we get here */
  if( zErrDyn ){
    sqlite3_result_error(context, zErrDyn, -1);
    sqliteFree(zErrDyn);
  }else{
    zErr[sizeof(zErr)-1] = 0;
    sqlite3_result_error(context, zErr, -1);
  }
}

/*
** An SQL user-function registered to do the work of an DETACH statement. The
** three arguments to the function come directly from a detach statement:
**
**     DETACH DATABASE x
**
**     SELECT sqlite_detach(x)
*/
static void detachFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zName = (const char *)sqlite3_value_text(argv[0]);
  sqlite3 *db = sqlite3_user_data(context);
  int i;
  Db *pDb = 0;
  char zErr[128];

  assert(zName);
  for(i=0; i<db->nDb; i++){
    pDb = &db->aDb[i];
    if( pDb->pBt==0 ) continue;
    if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
  }

  if( i>=db->nDb ){
    sqlite3_snprintf(sizeof(zErr), zErr, "no such database: %s", zName);
    goto detach_error;
  }
  if( i<2 ){
    sqlite3_snprintf(sizeof(zErr), zErr, "cannot detach database %s", zName);
    goto detach_error;
  }
  if( !db->autoCommit ){
    strcpy(zErr, "cannot DETACH database within transaction");
    goto detach_error;
  }

  sqlite3BtreeClose(pDb->pBt);
  pDb->pBt = 0;
  pDb->pSchema = 0;
  sqlite3ResetInternalSchema(db, 0);
  return;

detach_error:
  sqlite3_result_error(context, zErr, -1);
}

/*
** This procedure generates VDBE code for a single invocation of either the
** sqlite_detach() or sqlite_attach() SQL user functions.

*/
static void codeAttach(
  Parse *pParse,       /* The parser context */
  int type,            /* Either SQLITE_ATTACH or SQLITE_DETACH */
  const char *zFunc,   /* Either "sqlite_attach" or "sqlite_detach */
  int nFunc,           /* Number of args to pass to zFunc */
  Expr *pAuthArg,      /* Expression to pass to authorization callback */
  Expr *pFilename,     /* Name of database file */
  Expr *pDbname,       /* Name of the database to use internally */
  Expr *pKey           /* Database key for encryption extension */
){
  int rc;
  NameContext sName;
  Vdbe *v;
  FuncDef *pFunc;
  sqlite3* db = pParse->db;

#ifndef SQLITE_OMIT_AUTHORIZATION
  assert( sqlite3ThreadDataReadOnly()->mallocFailed || pAuthArg );
  if( pAuthArg ){
    char *zAuthArg = sqlite3NameFromToken(&pAuthArg->span);
    if( !zAuthArg ){
      goto attach_end;
    }
    rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
    sqliteFree(zAuthArg);
    if(rc!=SQLITE_OK ){
      goto attach_end;
    }
  }
#endif /* SQLITE_OMIT_AUTHORIZATION */

  memset(&sName, 0, sizeof(NameContext));
  sName.pParse = pParse;

  if( 
      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
  ){
    pParse->nErr++;
    goto attach_end;
  }

  v = sqlite3GetVdbe(pParse);
  sqlite3ExprCode(pParse, pFilename);
  sqlite3ExprCode(pParse, pDbname);
  sqlite3ExprCode(pParse, pKey);

  assert(v || sqlite3ThreadDataReadOnly()->mallocFailed);
  if( v ){
    sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
    pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
    sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF);

    /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
    ** statement only). For DETACH, set it to false (expire all existing
    ** statements).
    */
    sqlite3VdbeAddOp(v, OP_Expire, (type==SQLITE_ATTACH), 0);
  }
  
attach_end:
  sqlite3ExprDelete(pFilename);
  sqlite3ExprDelete(pDbname);
  sqlite3ExprDelete(pKey);
}

/*
** Called by the parser to compile a DETACH statement.
**
**     DETACH pDbname
*/
void sqlite3Detach(Parse *pParse, Expr *pDbname){
  codeAttach(pParse, SQLITE_DETACH, "sqlite_detach", 1, pDbname, 0, 0, pDbname);

}

/*
** Called by the parser to compile an ATTACH statement.
**
**     ATTACH p AS pDbname KEY pKey
*/
void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
  codeAttach(pParse, SQLITE_ATTACH, "sqlite_attach", 3, p, p, pDbname, pKey);

}




/*
** Register the functions sqlite_attach and sqlite_detach.
*/
void sqlite3AttachFunctions(sqlite3 *db){
  static const int enc = SQLITE_UTF8;
  sqlite3_create_function(db, "sqlite_attach", 3, enc, db, attachFunc, 0, 0);
  sqlite3_create_function(db, "sqlite_detach", 1, enc, db, detachFunc, 0, 0);
}

/*
** Initialize a DbFixer structure.  This routine must be called prior
** to passing the structure to one of the sqliteFixAAAA() routines below.
**
** The return value indicates whether or not fixation is required.  TRUE













|




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

|
<
<

<
|
>

|
|
>
>
|
<
>

|
|
<
<
|
|
<
|

|
>
|
|
|
<
<
<
<
<
>

<
|
|
>
|

>

|
>
>
>
|
>
>
>
>
>
>

>
>
>
>



|
|
>
>



<
<
<


|
<
<



|
<
<




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

>
>
>
|



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



|
|
<
<
<
<
|
<
|
<







<


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

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

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

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

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







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18





























19



20
21


22

23
24
25
26
27
28
29
30

31
32
33
34


35
36

37
38
39
40
41
42
43





44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78



79
80
81


82
83
84
85


86
87
88
89
90





91

92
93






94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116




117
118


119
120
121

122



123
124
125
126
127
128
129
130




131

132

133
134
135
136
137
138
139

140
141
142



143

144








145
146
147
























148
149












150





151



152
153


154
155

156
157
158


159
160







161



























162



163
164

165
166
167
168
169
170
171

172
173
174


175
176
177
178



179



180
181
182





183
184
185
186
187
188
189
190
191


192
193
194

195
196
197
198
199
200
201
/*
** 2003 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.1 2005/03/01 16:04:26 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*





























** This routine is called by the parser to process an ATTACH statement:



**
**     ATTACH DATABASE filename AS dbname


**

** The pFilename and pDbname arguments are the tokens that define the
** filename and dbname in the ATTACH statement.
*/
void sqlite3Attach(
  Parse *pParse,       /* The parser context */
  Token *pFilename,    /* Name of database file */
  Token *pDbname,      /* Name of the database to use internally */
  int keyType,         /* 0: no key.  1: TEXT,  2: BLOB */

  Token *pKey          /* Text of the key for keytype 1 and 2 */
){
  Db *aNew;
  int rc, i;


  char *zFile, *zName;
  sqlite3 *db;

  Vdbe *v;

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
  sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
  if( pParse->explain ) return;





  db = pParse->db;
  if( db->nDb>=MAX_ATTACHED+2 ){

    sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 
       MAX_ATTACHED);
    pParse->rc = SQLITE_ERROR;
    return;
  }

  if( !db->autoCommit ){
    sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction");
    pParse->rc = SQLITE_ERROR;
    return;
  }

  zFile = sqlite3NameFromToken(pFilename);;
  if( zFile==0 ) return;
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
    sqliteFree(zFile);
    return;
  }
#endif /* SQLITE_OMIT_AUTHORIZATION */

  zName = sqlite3NameFromToken(pDbname);
  if( zName==0 ) return;
  for(i=0; i<db->nDb; i++){
    char *z = db->aDb[i].zName;
    if( z && sqlite3StrICmp(z, zName)==0 ){
      sqlite3ErrorMsg(pParse, "database %z is already in use", zName);
      pParse->rc = SQLITE_ERROR;
      sqliteFree(zFile);
      return;
    }
  }




  if( db->aDb==db->aDbStatic ){
    aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
    if( aNew==0 ) return;


    memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
  }else{
    aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
    if( aNew==0 ) return;


  }
  db->aDb = aNew;
  aNew = &db->aDb[db->nDb++];
  memset(aNew, 0, sizeof(*aNew));
  sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);





  sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);

  sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);






  aNew->zName = zName;
  aNew->safety_level = 3;
  rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
  if( rc ){
    sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
  }
#if SQLITE_HAS_CODEC
  {
    extern int sqlite3CodecAttach(sqlite3*, int, void*, int);
    char *zKey;
    int nKey;
    if( keyType==0 ){
      /* No key specified.  Use the key from the main database */
      extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
      sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
    }else if( keyType==1 ){
      /* Key specified as text */
      zKey = sqlite3NameFromToken(pKey);
      nKey = strlen(zKey);
    }else{
      /* Key specified as a BLOB */
      char *zTemp;

      assert( keyType==2 );




      pKey->z++;
      pKey->n--;


      zTemp = sqlite3NameFromToken(pKey);
      zKey = sqlite3HexToBlob(zTemp);
      sqliteFree(zTemp);

    }



    sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
    if( keyType ){
      sqliteFree(zKey);
    }
  }
#endif
  sqliteFree(zFile);
  db->flags &= ~SQLITE_Initialized;




  if( pParse->nErr==0 && rc==SQLITE_OK ){

    rc = sqlite3ReadSchema(pParse);

  }
  if( rc ){
    int i = db->nDb - 1;
    assert( i>=2 );
    if( db->aDb[i].pBt ){
      sqlite3BtreeClose(db->aDb[i].pBt);
      db->aDb[i].pBt = 0;

    }
    sqlite3ResetInternalSchema(db, 0);
    if( 0==pParse->nErr ){



      pParse->nErr++;

      pParse->rc = SQLITE_ERROR;








    }
  }
}

























/*












** This routine is called by the parser to process a DETACH statement:





**



**    DETACH DATABASE dbname
**


** The pDbname argument is the name of the database in the DETACH statement.
*/

void sqlite3Detach(Parse *pParse, Token *pDbname){
  int i;
  sqlite3 *db;


  Vdbe *v;
  Db *pDb = 0;



































  v = sqlite3GetVdbe(pParse);



  if( !v ) return;
  sqlite3VdbeAddOp(v, OP_Expire, 0, 0);

  sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
  if( pParse->explain ) return;
  db = pParse->db;
  for(i=0; i<db->nDb; i++){
    pDb = &db->aDb[i];
    if( pDb->pBt==0 || pDb->zName==0 ) continue;
    if( strlen(pDb->zName)!=pDbname->n ) continue;

    if( sqlite3StrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break;
  }
  if( i>=db->nDb ){


    sqlite3ErrorMsg(pParse, "no such database: %T", pDbname);
    return;
  }
  if( i<2 ){



    sqlite3ErrorMsg(pParse, "cannot detach database %T", pDbname);



    return;
  }
  if( !db->autoCommit ){





    sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction");
    pParse->rc = SQLITE_ERROR;
    return;
  }
#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
    return;
  }
#endif /* SQLITE_OMIT_AUTHORIZATION */


  sqlite3BtreeClose(pDb->pBt);
  pDb->pBt = 0;
  sqlite3ResetInternalSchema(db, 0);

}

/*
** Initialize a DbFixer structure.  This routine must be called prior
** to passing the structure to one of the sqliteFixAAAA() routines below.
**
** The return value indicates whether or not fixation is required.  TRUE
Changes to SQLite.Interop/src/auth.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** This file contains code used to implement the sqlite3_set_authorizer()
** API.  This facility is an optional feature of the library.  Embedded
** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
**
** $Id: auth.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** All of the code in this file may be omitted by defining a single
** macro.
*/







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** This file contains code used to implement the sqlite3_set_authorizer()
** API.  This facility is an optional feature of the library.  Embedded
** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1
**
** $Id: auth.c,v 1.1 2005/03/01 16:04:26 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** All of the code in this file may be omitted by defining a single
** macro.
*/
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  sqlite3 *db = pParse->db;
  int rc;
  Table *pTab;          /* The table being read */
  const char *zCol;     /* Name of the column of the table */
  int iSrc;             /* Index in pTabList->a[] of table being read */
  const char *zDBase;   /* Name of database being accessed */
  TriggerStack *pStack; /* The stack of current triggers */
  int iDb;              /* The index of the database the expression refers to */

  if( db->xAuth==0 ) return;
  if( pExpr->op==TK_AS ) return;
  assert( pExpr->op==TK_COLUMN );
  iDb = sqlite3SchemaToIndex(pParse->db, pExpr->pSchema);
  if( iDb<0 ){
    /* An attempt to read a column out of a subquery or other
    ** temporary table. */
    return;
  }
  for(iSrc=0; pTabList && iSrc<pTabList->nSrc; iSrc++){
    if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
  }
  if( iSrc>=0 && pTabList && iSrc<pTabList->nSrc ){
    pTab = pTabList->a[iSrc].pTab;
  }else if( (pStack = pParse->trigStack)!=0 ){
    /* This must be an attempt to read the NEW or OLD pseudo-tables







<


<

<
<
<
<
<
<







108
109
110
111
112
113
114

115
116

117






118
119
120
121
122
123
124
  sqlite3 *db = pParse->db;
  int rc;
  Table *pTab;          /* The table being read */
  const char *zCol;     /* Name of the column of the table */
  int iSrc;             /* Index in pTabList->a[] of table being read */
  const char *zDBase;   /* Name of database being accessed */
  TriggerStack *pStack; /* The stack of current triggers */


  if( db->xAuth==0 ) return;

  assert( pExpr->op==TK_COLUMN );






  for(iSrc=0; pTabList && iSrc<pTabList->nSrc; iSrc++){
    if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
  }
  if( iSrc>=0 && pTabList && iSrc<pTabList->nSrc ){
    pTab = pTabList->a[iSrc].pTab;
  }else if( (pStack = pParse->trigStack)!=0 ){
    /* This must be an attempt to read the NEW or OLD pseudo-tables
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    zCol = pTab->aCol[pExpr->iColumn].zName;
  }else if( pTab->iPKey>=0 ){
    assert( pTab->iPKey<pTab->nCol );
    zCol = pTab->aCol[pTab->iPKey].zName;
  }else{
    zCol = "ROWID";
  }
  assert( iDb>=0 && iDb<db->nDb );
  zDBase = db->aDb[iDb].zName;
  rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, 
                 pParse->zAuthContext);
  if( rc==SQLITE_IGNORE ){
    pExpr->op = TK_NULL;
  }else if( rc==SQLITE_DENY ){
    if( db->nDb>2 || iDb!=0 ){
      sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited", 
         zDBase, pTab->zName, zCol);
    }else{
      sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited",pTab->zName,zCol);
    }
    pParse->rc = SQLITE_AUTH;
  }else if( rc!=SQLITE_OK ){







|
|





|







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    zCol = pTab->aCol[pExpr->iColumn].zName;
  }else if( pTab->iPKey>=0 ){
    assert( pTab->iPKey<pTab->nCol );
    zCol = pTab->aCol[pTab->iPKey].zName;
  }else{
    zCol = "ROWID";
  }
  assert( pExpr->iDb<db->nDb );
  zDBase = db->aDb[pExpr->iDb].zName;
  rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, 
                 pParse->zAuthContext);
  if( rc==SQLITE_IGNORE ){
    pExpr->op = TK_NULL;
  }else if( rc==SQLITE_DENY ){
    if( db->nDb>2 || pExpr->iDb!=0 ){
      sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited", 
         zDBase, pTab->zName, zCol);
    }else{
      sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited",pTab->zName,zCol);
    }
    pParse->rc = SQLITE_AUTH;
  }else if( rc!=SQLITE_OK ){
Changes to SQLite.Interop/src/btree.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.17 2006/01/16 15:51:47 rmsimpson Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.1 2005/03/01 16:04:27 rmsimpson Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
*/
#include "sqliteInt.h"
#include "pager.h"
#include "btree.h"
#include "os.h"
#include <assert.h>

/* Round up a number to the next larger multiple of 8.  This is used

** to force 8-byte alignment on 64-bit architectures.
*/
#define ROUND8(x)   ((x+7)&~7)


/* The following value is the maximum cell size assuming a maximum page
** size give above.
*/
#define MX_CELL_SIZE(pBt)  (pBt->pageSize-8)

/* The maximum number of cells on a single page of the database.  This
** assumes a minimum cell size of 3 bytes.  Such small cells will be
** exceedingly rare, but they are possible.
*/
#define MX_CELL(pBt) ((pBt->pageSize-8)/3)

/* Forward declarations */
typedef struct MemPage MemPage;
typedef struct BtLock BtLock;

/*
** This is a magic string that appears at the beginning of every
** SQLite database in order to identify the file as a real database.
**
** You can change this value at compile-time by specifying a
** -DSQLITE_FILE_HEADER="..." on the compiler command-line.  The
** header must be exactly 16 bytes including the zero-terminator so
** the string itself should be 15 characters long.  If you change
** the header, then your custom library will not be able to read 
** databases generated by the standard tools and the standard tools
** will not be able to read databases created by your custom library.
*/
#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */
#  define SQLITE_FILE_HEADER "SQLite format 3"
#endif
static const char zMagicHeader[] = SQLITE_FILE_HEADER;

/*
** Page type flags.  An ORed combination of these flags appear as the
** first byte of every BTree page.
*/
#define PTF_INTKEY    0x01
#define PTF_ZERODATA  0x02







|
>
|

<
|














<




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







207
208
209
210
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236









237


238
239
240
241
242
243
244
245
*/
#include "sqliteInt.h"
#include "pager.h"
#include "btree.h"
#include "os.h"
#include <assert.h>

/*
** This macro rounds values up so that if the value is an address it
** is guaranteed to be an address that is aligned to an 8-byte boundary.
*/

#define FORCE_ALIGNMENT(X)   (((X)+7)&~7)

/* The following value is the maximum cell size assuming a maximum page
** size give above.
*/
#define MX_CELL_SIZE(pBt)  (pBt->pageSize-8)

/* The maximum number of cells on a single page of the database.  This
** assumes a minimum cell size of 3 bytes.  Such small cells will be
** exceedingly rare, but they are possible.
*/
#define MX_CELL(pBt) ((pBt->pageSize-8)/3)

/* Forward declarations */
typedef struct MemPage MemPage;


/*
** This is a magic string that appears at the beginning of every
** SQLite database in order to identify the file as a real database.









**                                  123456789 123456 */


static const char zMagicHeader[] = "SQLite format 3";

/*
** Page type flags.  An ORed combination of these flags appear as the
** first byte of every BTree page.
*/
#define PTF_INTKEY    0x01
#define PTF_ZERODATA  0x02
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356








357
358
359
360
361
362
363
  u16 maxLocal;        /* Copy of Btree.maxLocal or Btree.maxLeaf */
  u16 minLocal;        /* Copy of Btree.minLocal or Btree.minLeaf */
  u16 cellOffset;      /* Index in aData of first cell pointer */
  u16 idxParent;       /* Index in parent of this node */
  u16 nFree;           /* Number of free bytes on the page */
  u16 nCell;           /* Number of cells on this page, local and ovfl */
  struct _OvflCell {   /* Cells that will not fit on aData[] */
    u8 *pCell;          /* Pointers to the body of the overflow cell */
    u16 idx;            /* Insert this cell before idx-th non-overflow cell */
  } aOvfl[5];
  BtShared *pBt;       /* Pointer back to BTree structure */
  u8 *aData;           /* Pointer back to the start of the page */
  Pgno pgno;           /* Page number for this page */
  MemPage *pParent;    /* The parent of this page.  NULL for root */
};

/*
** The in-memory image of a disk page has the auxiliary information appended
** to the end.  EXTRA_SIZE is the number of bytes of space needed to hold
** that extra information.
*/
#define EXTRA_SIZE sizeof(MemPage)

/* Btree handle */
struct Btree {
  sqlite3 *pSqlite;
  BtShared *pBt;
  u8 inTrans;            /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
};

/*
** Btree.inTrans may take one of the following values.
**
** If the shared-data extension is enabled, there may be multiple users
** of the Btree structure. At most one of these may open a write transaction,
** but any number may have active read transactions. Variable Btree.pDb 
** points to the handle that owns any current write-transaction.
*/
#define TRANS_NONE  0
#define TRANS_READ  1
#define TRANS_WRITE 2

/*
** Everything we need to know about an open database
*/
struct BtShared {
  Pager *pPager;        /* The page cache */
  BtCursor *pCursor;    /* A list of all open cursors */
  MemPage *pPage1;      /* First page of the database */

  u8 inStmt;            /* True if we are in a statement subtransaction */
  u8 readOnly;          /* True if the underlying file is readonly */
  u8 maxEmbedFrac;      /* Maximum payload as % of total page size */
  u8 minEmbedFrac;      /* Minimum payload as % of total page size */
  u8 minLeafFrac;       /* Minimum leaf payload as % of total page size */
  u8 pageSizeFixed;     /* True if the page size can no longer be changed */
#ifndef SQLITE_OMIT_AUTOVACUUM
  u8 autoVacuum;        /* True if database supports auto-vacuum */
#endif
  u16 pageSize;         /* Total number of bytes on a page */

  u16 usableSize;       /* Number of usable bytes on each page */
  int maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
  int minLocal;         /* Minimum local payload in non-LEAFDATA tables */
  int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
  int minLeaf;          /* Minimum local payload in a LEAFDATA table */
  BusyHandler *pBusyHandler;   /* Callback for when there is lock contention */
  u8 inTransaction;     /* Transaction state */
  int nRef;             /* Number of references to this structure */
  int nTransaction;     /* Number of open transactions (read + write) */
  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
#ifndef SQLITE_OMIT_SHARED_CACHE
  BtLock *pLock;        /* List of locks held on this shared-btree struct */
  BtShared *pNext;      /* Next in ThreadData.pBtree linked list */
#endif
};









/*
** An instance of the following structure is used to hold information
** about a cell.  The parseCellPtr() function fills in this structure
** based on information extract from the raw disk page.
*/
typedef struct CellInfo CellInfo;







|
|

|












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|



>










>





<
<
<
<
<
<
<
<
<
<

>
>
>
>
>
>
>
>







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292



















293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316










317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
  u16 maxLocal;        /* Copy of Btree.maxLocal or Btree.maxLeaf */
  u16 minLocal;        /* Copy of Btree.minLocal or Btree.minLeaf */
  u16 cellOffset;      /* Index in aData of first cell pointer */
  u16 idxParent;       /* Index in parent of this node */
  u16 nFree;           /* Number of free bytes on the page */
  u16 nCell;           /* Number of cells on this page, local and ovfl */
  struct _OvflCell {   /* Cells that will not fit on aData[] */
    u8 *pCell;           /* Pointers to the body of the overflow cell */
    u16 idx;             /* Insert this cell before idx-th non-overflow cell */
  } aOvfl[5];
  struct Btree *pBt;   /* Pointer back to BTree structure */
  u8 *aData;           /* Pointer back to the start of the page */
  Pgno pgno;           /* Page number for this page */
  MemPage *pParent;    /* The parent of this page.  NULL for root */
};

/*
** The in-memory image of a disk page has the auxiliary information appended
** to the end.  EXTRA_SIZE is the number of bytes of space needed to hold
** that extra information.
*/
#define EXTRA_SIZE sizeof(MemPage)




















/*
** Everything we need to know about an open database
*/
struct Btree {
  Pager *pPager;        /* The page cache */
  BtCursor *pCursor;    /* A list of all open cursors */
  MemPage *pPage1;      /* First page of the database */
  u8 inTrans;           /* True if a transaction is in progress */
  u8 inStmt;            /* True if we are in a statement subtransaction */
  u8 readOnly;          /* True if the underlying file is readonly */
  u8 maxEmbedFrac;      /* Maximum payload as % of total page size */
  u8 minEmbedFrac;      /* Minimum payload as % of total page size */
  u8 minLeafFrac;       /* Minimum leaf payload as % of total page size */
  u8 pageSizeFixed;     /* True if the page size can no longer be changed */
#ifndef SQLITE_OMIT_AUTOVACUUM
  u8 autoVacuum;        /* True if database supports auto-vacuum */
#endif
  u16 pageSize;         /* Total number of bytes on a page */
  u16 psAligned;        /* pageSize rounded up to a multiple of 8 */
  u16 usableSize;       /* Number of usable bytes on each page */
  int maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
  int minLocal;         /* Minimum local payload in non-LEAFDATA tables */
  int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
  int minLeaf;          /* Minimum local payload in a LEAFDATA table */










};
typedef Btree Bt;

/*
** Btree.inTrans may take one of the following values.
*/
#define TRANS_NONE  0
#define TRANS_READ  1
#define TRANS_WRITE 2

/*
** An instance of the following structure is used to hold information
** about a cell.  The parseCellPtr() function fills in this structure
** based on information extract from the raw disk page.
*/
typedef struct CellInfo CellInfo;
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444

/*
** A cursor is a pointer to a particular entry in the BTree.
** The entry is identified by its MemPage and the index in
** MemPage.aCell[] of the entry.
*/
struct BtCursor {
  Btree *pBtree;            /* The Btree to which this cursor belongs */
  BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
  int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */
  void *pArg;               /* First arg to xCompare() */
  Pgno pgnoRoot;            /* The root page of this tree */
  MemPage *pPage;           /* Page that contains the entry */
  int idx;                  /* Index of the entry in pPage->aCell[] */
  CellInfo info;            /* A parse of the cell we are pointing at */
  u8 wrFlag;                /* True if writable */
  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
#ifndef SQLITE_OMIT_SHARED_CACHE
  void *pKey;
  i64 nKey;
  int skip;        /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */
#endif
};

/*
** Potential values for BtCursor.eState. The first two values (VALID and 
** INVALID) may occur in any build. The third (REQUIRESEEK) may only occur 
** if sqlite was compiled without the OMIT_SHARED_CACHE symbol defined.
**
** CURSOR_VALID:
**   Cursor points to a valid entry. getPayload() etc. may be called.
**
** CURSOR_INVALID:
**   Cursor does not point to a valid entry. This can happen (for example) 
**   because the table is empty or because BtreeCursorFirst() has not been
**   called.
**
** CURSOR_REQUIRESEEK:
**   The table that this cursor was opened on still exists, but has been 
**   modified since the cursor was last used. The cursor position is saved
**   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
**   this state, restoreOrClearCursorPosition() can be called to attempt to seek 
**   the cursor to the saved position.
*/
#define CURSOR_INVALID           0
#define CURSOR_VALID             1
#define CURSOR_REQUIRESEEK       2

/*
** The TRACE macro will print high-level status information about the
** btree operation when the global variable sqlite3_btree_trace is
** enabled.
*/
#if SQLITE_TEST
# define TRACE(X)   if( sqlite3_btree_trace )\
                        { sqlite3DebugPrintf X; fflush(stdout); }
#else
# define TRACE(X)
#endif
int sqlite3_btree_trace=0;  /* True to enable tracing */

/*
** Forward declaration
*/
static int checkReadLocks(BtShared*,Pgno,BtCursor*);

/*
** Read or write a two- and four-byte big-endian integer values.
*/
static u32 get2byte(unsigned char *p){
  return (p[0]<<8) | p[1];
}







|








|
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















|







342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358





359
360
























361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

/*
** A cursor is a pointer to a particular entry in the BTree.
** The entry is identified by its MemPage and the index in
** MemPage.aCell[] of the entry.
*/
struct BtCursor {
  Btree *pBt;               /* The Btree to which this cursor belongs */
  BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
  int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */
  void *pArg;               /* First arg to xCompare() */
  Pgno pgnoRoot;            /* The root page of this tree */
  MemPage *pPage;           /* Page that contains the entry */
  int idx;                  /* Index of the entry in pPage->aCell[] */
  CellInfo info;            /* A parse of the cell we are pointing at */
  u8 wrFlag;                /* True if writable */
  u8 isValid;               /* TRUE if points to a valid entry */





};

























/*
** The TRACE macro will print high-level status information about the
** btree operation when the global variable sqlite3_btree_trace is
** enabled.
*/
#if SQLITE_TEST
# define TRACE(X)   if( sqlite3_btree_trace )\
                        { sqlite3DebugPrintf X; fflush(stdout); }
#else
# define TRACE(X)
#endif
int sqlite3_btree_trace=0;  /* True to enable tracing */

/*
** Forward declaration
*/
static int checkReadLocks(Btree*,Pgno,BtCursor*);

/*
** Read or write a two- and four-byte big-endian integer values.
*/
static u32 get2byte(unsigned char *p){
  return (p[0]<<8) | p[1];
}
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

/* The database page the PENDING_BYTE occupies. This page is never used.
** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They
** should possibly be consolidated (presumably in pager.h).
*/
#define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1)

/*
** A linked list of the following structures is stored at BtShared.pLock.
** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor 
** is opened on the table with root page BtShared.iTable. Locks are removed
** from this list when a transaction is committed or rolled back, or when
** a btree handle is closed.
*/
struct BtLock {
  Btree *pBtree;        /* Btree handle holding this lock */
  Pgno iTable;          /* Root page of table */
  u8 eLock;             /* READ_LOCK or WRITE_LOCK */
  BtLock *pNext;        /* Next in BtShared.pLock list */
};

/* Candidate values for BtLock.eLock */
#define READ_LOCK     1
#define WRITE_LOCK    2

#ifdef SQLITE_OMIT_SHARED_CACHE
  /*
  ** The functions queryTableLock(), lockTable() and unlockAllTables()
  ** manipulate entries in the BtShared.pLock linked list used to store
  ** shared-cache table level locks. If the library is compiled with the
  ** shared-cache feature disabled, then there is only ever one user
  ** of each BtShared structure and so this locking is not necessary. 
  ** So define the lock related functions as no-ops.
  */
  #define queryTableLock(a,b,c) SQLITE_OK
  #define lockTable(a,b,c) SQLITE_OK
  #define unlockAllTables(a)
  #define restoreOrClearCursorPosition(a,b) SQLITE_OK
  #define saveAllCursors(a,b,c) SQLITE_OK

#else

/*
** Save the current cursor position in the variables BtCursor.nKey 
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
*/
static int saveCursorPosition(BtCursor *pCur){
  int rc = SQLITE_OK;

  assert( CURSOR_VALID==pCur->eState|| CURSOR_INVALID==pCur->eState );
  assert( 0==pCur->pKey );

  if( pCur->eState==CURSOR_VALID ){
    rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);

    /* If this is an intKey table, then the above call to BtreeKeySize()
    ** stores the integer key in pCur->nKey. In this case this value is
    ** all that is required. Otherwise, if pCur is not open on an intKey
    ** table, then malloc space for and store the pCur->nKey bytes of key 
    ** data.
    */
    if( rc==SQLITE_OK && 0==pCur->pPage->intKey){
      void *pKey = sqliteMalloc(pCur->nKey);
      if( pKey ){
        rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
        if( rc==SQLITE_OK ){
          pCur->pKey = pKey;
        }else{
          sqliteFree(pKey);
        }
      }else{
        rc = SQLITE_NOMEM;
      }
    }
    assert( !pCur->pPage->intKey || !pCur->pKey );

    /* Todo: Should we drop the reference to pCur->pPage here? */

    if( rc==SQLITE_OK ){
      pCur->eState = CURSOR_REQUIRESEEK;
    }
  }

  return rc;
}

/*
** Save the positions of all cursors except pExcept open on the table 
** with root-page iRoot. Usually, this is called just before cursor
** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
*/
static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
  BtCursor *p;
  if( sqlite3ThreadDataReadOnly()->useSharedData ){
    for(p=pBt->pCursor; p; p=p->pNext){
      if( p!=pExcept && p->pgnoRoot==iRoot && p->eState==CURSOR_VALID ){
        int rc = saveCursorPosition(p);
        if( SQLITE_OK!=rc ){
          return rc;
        }
      }
    }
  }
  return SQLITE_OK;
}

/*
** Restore the cursor to the position it was in (or as close to as possible)
** when saveCursorPosition() was called. Note that this call deletes the 
** saved position info stored by saveCursorPosition(), so there can be
** at most one effective restoreOrClearCursorPosition() call after each 
** saveCursorPosition().
**
** If the second argument argument - doSeek - is false, then instead of 
** returning the cursor to it's saved position, any saved position is deleted
** and the cursor state set to CURSOR_INVALID.
*/
static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){
  int rc = SQLITE_OK;
  assert( sqlite3ThreadDataReadOnly()->useSharedData );
  assert( pCur->eState==CURSOR_REQUIRESEEK );
  if( doSeek ){
    rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
  }else{
    pCur->eState = CURSOR_INVALID;
  }
  if( rc==SQLITE_OK ){
    sqliteFree(pCur->pKey);
    pCur->pKey = 0;
    assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState );
  }
  return rc;
}

#define restoreOrClearCursorPosition(p,x) \
  (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK)

/*
** Query to see if btree handle p may obtain a lock of type eLock 
** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
** SQLITE_OK if the lock may be obtained (by calling lockTable()), or
** SQLITE_LOCKED if not.
*/
static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
  BtShared *pBt = p->pBt;
  BtLock *pIter;

  /* This is a no-op if the shared-cache is not enabled */
  if( 0==sqlite3ThreadDataReadOnly()->useSharedData ){
    return SQLITE_OK;
  }

  /* This (along with lockTable()) is where the ReadUncommitted flag is
  ** dealt with. If the caller is querying for a read-lock and the flag is
  ** set, it is unconditionally granted - even if there are write-locks
  ** on the table. If a write-lock is requested, the ReadUncommitted flag
  ** is not considered.
  **
  ** In function lockTable(), if a read-lock is demanded and the 
  ** ReadUncommitted flag is set, no entry is added to the locks list 
  ** (BtShared.pLock).
  **
  ** To summarize: If the ReadUncommitted flag is set, then read cursors do
  ** not create or respect table locks. The locking procedure for a 
  ** write-cursor does not change.
  */
  if( 
    !p->pSqlite || 
    0==(p->pSqlite->flags&SQLITE_ReadUncommitted) || 
    eLock==WRITE_LOCK ||
    iTab==MASTER_ROOT
  ){
    for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
      if( pIter->pBtree!=p && pIter->iTable==iTab && 
          (pIter->eLock!=eLock || eLock!=READ_LOCK) ){
        return SQLITE_LOCKED;
      }
    }
  }
  return SQLITE_OK;
}

/*
** Add a lock on the table with root-page iTable to the shared-btree used
** by Btree handle p. Parameter eLock must be either READ_LOCK or 
** WRITE_LOCK.
**
** SQLITE_OK is returned if the lock is added successfully. SQLITE_BUSY and
** SQLITE_NOMEM may also be returned.
*/
static int lockTable(Btree *p, Pgno iTable, u8 eLock){
  BtShared *pBt = p->pBt;
  BtLock *pLock = 0;
  BtLock *pIter;

  /* This is a no-op if the shared-cache is not enabled */
  if( 0==sqlite3ThreadDataReadOnly()->useSharedData ){
    return SQLITE_OK;
  }

  assert( SQLITE_OK==queryTableLock(p, iTable, eLock) );

  /* If the read-uncommitted flag is set and a read-lock is requested,
  ** return early without adding an entry to the BtShared.pLock list. See
  ** comment in function queryTableLock() for more info on handling 
  ** the ReadUncommitted flag.
  */
  if( 
    (p->pSqlite) && 
    (p->pSqlite->flags&SQLITE_ReadUncommitted) && 
    (eLock==READ_LOCK) &&
    iTable!=MASTER_ROOT
  ){
    return SQLITE_OK;
  }

  /* First search the list for an existing lock on this table. */
  for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
    if( pIter->iTable==iTable && pIter->pBtree==p ){
      pLock = pIter;
      break;
    }
  }

  /* If the above search did not find a BtLock struct associating Btree p
  ** with table iTable, allocate one and link it into the list.
  */
  if( !pLock ){
    pLock = (BtLock *)sqliteMalloc(sizeof(BtLock));
    if( !pLock ){
      return SQLITE_NOMEM;
    }
    pLock->iTable = iTable;
    pLock->pBtree = p;
    pLock->pNext = pBt->pLock;
    pBt->pLock = pLock;
  }

  /* Set the BtLock.eLock variable to the maximum of the current lock
  ** and the requested lock. This means if a write-lock was already held
  ** and a read-lock requested, we don't incorrectly downgrade the lock.
  */
  assert( WRITE_LOCK>READ_LOCK );
  if( eLock>pLock->eLock ){
    pLock->eLock = eLock;
  }

  return SQLITE_OK;
}

/*
** Release all the table locks (locks obtained via calls to the lockTable()
** procedure) held by Btree handle p.
*/
static void unlockAllTables(Btree *p){
  BtLock **ppIter = &p->pBt->pLock;

  /* If the shared-cache extension is not enabled, there should be no
  ** locks in the BtShared.pLock list, making this procedure a no-op. Assert
  ** that this is the case.
  */
  assert( sqlite3ThreadDataReadOnly()->useSharedData || 0==*ppIter );

  while( *ppIter ){
    BtLock *pLock = *ppIter;
    if( pLock->pBtree==p ){
      *ppIter = pLock->pNext;
      sqliteFree(pLock);
    }else{
      ppIter = &pLock->pNext;
    }
  }
}
#endif /* SQLITE_OMIT_SHARED_CACHE */

#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** These macros define the location of the pointer-map entry for a 
** database page. The first argument to each is the number of usable
** bytes on each page of the database (often 1024). The second is the
** page number to look up in the pointer map.
**







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







407
408
409
410
411
412
413












































































































































































































































































414
415
416
417
418
419
420

/* The database page the PENDING_BYTE occupies. This page is never used.
** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They
** should possibly be consolidated (presumably in pager.h).
*/
#define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1)













































































































































































































































































#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** These macros define the location of the pointer-map entry for a 
** database page. The first argument to each is the number of usable
** bytes on each page of the database (often 1024). The second is the
** page number to look up in the pointer map.
**
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
/*
** Write an entry into the pointer map.
**
** This routine updates the pointer map entry for page number 'key'
** so that it maps to type 'eType' and parent page number 'pgno'.
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
*/
static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
  u8 *pPtrmap;    /* The pointer map page */
  Pgno iPtrmap;   /* The pointer map page number */
  int offset;     /* Offset in pointer map page */
  int rc;

  assert( pBt->autoVacuum );
  if( key==0 ){
    return SQLITE_CORRUPT_BKPT;
  }
  iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
  rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  offset = PTRMAP_PTROFFSET(pBt->usableSize, key);







|







|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
/*
** Write an entry into the pointer map.
**
** This routine updates the pointer map entry for page number 'key'
** so that it maps to type 'eType' and parent page number 'pgno'.
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
*/
static int ptrmapPut(Btree *pBt, Pgno key, u8 eType, Pgno parent){
  u8 *pPtrmap;    /* The pointer map page */
  Pgno iPtrmap;   /* The pointer map page number */
  int offset;     /* Offset in pointer map page */
  int rc;

  assert( pBt->autoVacuum );
  if( key==0 ){
    return SQLITE_CORRUPT;
  }
  iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
  rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
/*
** Read an entry from the pointer map.
**
** This routine retrieves the pointer map entry for page 'key', writing
** the type and parent page number to *pEType and *pPgno respectively.
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
*/
static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
  int iPtrmap;       /* Pointer map page index */
  u8 *pPtrmap;       /* Pointer map page data */
  int offset;        /* Offset of entry in pointer map */
  int rc;

  iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
  rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
  if( rc!=0 ){
    return rc;
  }

  offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
  if( pEType ) *pEType = pPtrmap[offset];
  if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);

  sqlite3pager_unref(pPtrmap);
  if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT;
  return SQLITE_OK;
}

#endif /* SQLITE_OMIT_AUTOVACUUM */

/*
** Given a btree page and a cell index (0 means the first cell on







|
















|







508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
/*
** Read an entry from the pointer map.
**
** This routine retrieves the pointer map entry for page 'key', writing
** the type and parent page number to *pEType and *pPgno respectively.
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
*/
static int ptrmapGet(Btree *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
  int iPtrmap;       /* Pointer map page index */
  u8 *pPtrmap;       /* Pointer map page data */
  int offset;        /* Offset of entry in pointer map */
  int rc;

  iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key);
  rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap);
  if( rc!=0 ){
    return rc;
  }

  offset = PTRMAP_PTROFFSET(pBt->usableSize, key);
  if( pEType ) *pEType = pPtrmap[offset];
  if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);

  sqlite3pager_unref(pPtrmap);
  if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT;
  return SQLITE_OK;
}

#endif /* SQLITE_OMIT_AUTOVACUUM */

/*
** Given a btree page and a cell index (0 means the first cell on
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
  int cellOffset;
  int nCell, cellLimit;
  u8 *used;

  used = sqliteMallocRaw( pPage->pBt->pageSize );
  if( used==0 ) return;
  usableSize = pPage->pBt->usableSize;
  assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] );
  hdr = pPage->hdrOffset;
  assert( hdr==(pPage->pgno==1 ? 100 : 0) );
  assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
  c = pPage->aData[hdr];
  if( pPage->isInit ){
    assert( pPage->leaf == ((c & PTF_LEAF)!=0) );
    assert( pPage->zeroData == ((c & PTF_ZERODATA)!=0) );







|







709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
  int cellOffset;
  int nCell, cellLimit;
  u8 *used;

  used = sqliteMallocRaw( pPage->pBt->pageSize );
  if( used==0 ) return;
  usableSize = pPage->pBt->usableSize;
  assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->psAligned] );
  hdr = pPage->hdrOffset;
  assert( hdr==(pPage->pgno==1 ? 100 : 0) );
  assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
  c = pPage->aData[hdr];
  if( pPage->isInit ){
    assert( pPage->leaf == ((c & PTF_LEAF)!=0) );
    assert( pPage->zeroData == ((c & PTF_ZERODATA)!=0) );
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
  sqliteFree(used);
}
#define pageIntegrity(X) _pageIntegrity(X)
#else
# define pageIntegrity(X)
#endif

/* A bunch of assert() statements to check the transaction state variables
** of handle p (type Btree*) are internally consistent.
*/
#define btreeIntegrity(p) \
  assert( p->inTrans!=TRANS_NONE || p->pBt->nTransaction<p->pBt->nRef ); \
  assert( p->pBt->nTransaction<=p->pBt->nRef ); \
  assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
  assert( p->pBt->inTransaction>=p->inTrans ); 

/*
** Defragment the page given.  All Cells are moved to the
** end of the page and all free space is collected into one
** big FreeBlk that occurs in between the header and cell
** pointer array and the cell content area.
*/
static int defragmentPage(MemPage *pPage){
  int i;                     /* Loop counter */
  int pc;                    /* Address of a i-th cell */
  int addr;                  /* Offset of first byte after cell pointer array */
  int hdr;                   /* Offset to the page header */
  int size;                  /* Size of a cell */







<
<
<
<
<
<
<
<
<


|
|
<







775
776
777
778
779
780
781









782
783
784
785

786
787
788
789
790
791
792
  sqliteFree(used);
}
#define pageIntegrity(X) _pageIntegrity(X)
#else
# define pageIntegrity(X)
#endif










/*
** Defragment the page given.  All Cells are moved to the
** beginning of the page and all free space is collected 
** into one big FreeBlk at the end of the page.

*/
static int defragmentPage(MemPage *pPage){
  int i;                     /* Loop counter */
  int pc;                    /* Address of a i-th cell */
  int addr;                  /* Offset of first byte after cell pointer array */
  int hdr;                   /* Offset to the page header */
  int size;                  /* Size of a cell */
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
}

/*
** Decode the flags byte (the first byte of the header) for a page
** and initialize fields of the MemPage structure accordingly.
*/
static void decodeFlags(MemPage *pPage, int flagByte){
  BtShared *pBt;     /* A copy of pPage->pBt */

  assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
  pPage->intKey = (flagByte & (PTF_INTKEY|PTF_LEAFDATA))!=0;
  pPage->zeroData = (flagByte & PTF_ZERODATA)!=0;
  pPage->leaf = (flagByte & PTF_LEAF)!=0;
  pPage->childPtrSize = 4*(pPage->leaf==0);
  pBt = pPage->pBt;







|







962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
}

/*
** Decode the flags byte (the first byte of the header) for a page
** and initialize fields of the MemPage structure accordingly.
*/
static void decodeFlags(MemPage *pPage, int flagByte){
  Btree *pBt;     /* A copy of pPage->pBt */

  assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
  pPage->intKey = (flagByte & (PTF_INTKEY|PTF_LEAFDATA))!=0;
  pPage->zeroData = (flagByte & PTF_ZERODATA)!=0;
  pPage->leaf = (flagByte & PTF_LEAF)!=0;
  pPage->childPtrSize = 4*(pPage->leaf==0);
  pBt = pPage->pBt;
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
static int initPage(
  MemPage *pPage,        /* The page to be initialized */
  MemPage *pParent       /* The parent.  Might be NULL */
){
  int pc;            /* Address of a freeblock within pPage->aData[] */
  int hdr;           /* Offset to beginning of page header */
  u8 *data;          /* Equal to pPage->aData */
  BtShared *pBt;        /* The main btree structure */
  int usableSize;    /* Amount of usable space on each page */
  int cellOffset;    /* Offset from start of page to first cell pointer */
  int nFree;         /* Number of unused bytes on the page */
  int top;           /* First byte of the cell content area */

  pBt = pPage->pBt;
  assert( pBt!=0 );
  assert( pParent==0 || pParent->pBt==pBt );
  assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
  assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] );
  if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){
    /* The parent page should never change unless the file is corrupt */
    return SQLITE_CORRUPT_BKPT;
  }
  if( pPage->isInit ) return SQLITE_OK;
  if( pPage->pParent==0 && pParent!=0 ){
    pPage->pParent = pParent;
    sqlite3pager_ref(pParent->aData);
  }
  hdr = pPage->hdrOffset;
  data = pPage->aData;
  decodeFlags(pPage, data[hdr]);
  pPage->nOverflow = 0;
  pPage->idxShift = 0;
  usableSize = pBt->usableSize;
  pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
  top = get2byte(&data[hdr+5]);
  pPage->nCell = get2byte(&data[hdr+3]);
  if( pPage->nCell>MX_CELL(pBt) ){
    /* To many cells for a single page.  The page must be corrupt */
    return SQLITE_CORRUPT_BKPT;
  }
  if( pPage->nCell==0 && pParent!=0 && pParent->pgno!=1 ){
    /* All pages must have at least one cell, except for root pages */
    return SQLITE_CORRUPT_BKPT;
  }

  /* Compute the total free space on the page */
  pc = get2byte(&data[hdr+1]);
  nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
  while( pc>0 ){
    int next, size;
    if( pc>usableSize-4 ){
      /* Free block is off the page */
      return SQLITE_CORRUPT_BKPT; 
    }
    next = get2byte(&data[pc]);
    size = get2byte(&data[pc+2]);
    if( next>0 && next<=pc+size+3 ){
      /* Free blocks must be in accending order */
      return SQLITE_CORRUPT_BKPT; 
    }
    nFree += size;
    pc = next;
  }
  pPage->nFree = nFree;
  if( nFree>=usableSize ){
    /* Free space cannot exceed total page size */
    return SQLITE_CORRUPT_BKPT; 
  }

  pPage->isInit = 1;
  pageIntegrity(pPage);
  return SQLITE_OK;
}

/*
** Set up a raw page so that it looks like a database page holding
** no entries.
*/
static void zeroPage(MemPage *pPage, int flags){
  unsigned char *data = pPage->aData;
  BtShared *pBt = pPage->pBt;
  int hdr = pPage->hdrOffset;
  int first;

  assert( sqlite3pager_pagenumber(data)==pPage->pgno );
  assert( &data[pBt->pageSize] == (unsigned char*)pPage );
  assert( sqlite3pager_iswriteable(data) );
  memset(&data[hdr], 0, pBt->usableSize - hdr);
  data[hdr] = flags;
  first = hdr + 8 + 4*((flags&PTF_LEAF)==0);
  memset(&data[hdr+1], 0, 4);
  data[hdr+7] = 0;
  put2byte(&data[hdr+5], pBt->usableSize);







|









|


|

















|



|









|





|







|













|




|







1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
static int initPage(
  MemPage *pPage,        /* The page to be initialized */
  MemPage *pParent       /* The parent.  Might be NULL */
){
  int pc;            /* Address of a freeblock within pPage->aData[] */
  int hdr;           /* Offset to beginning of page header */
  u8 *data;          /* Equal to pPage->aData */
  Btree *pBt;        /* The main btree structure */
  int usableSize;    /* Amount of usable space on each page */
  int cellOffset;    /* Offset from start of page to first cell pointer */
  int nFree;         /* Number of unused bytes on the page */
  int top;           /* First byte of the cell content area */

  pBt = pPage->pBt;
  assert( pBt!=0 );
  assert( pParent==0 || pParent->pBt==pBt );
  assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
  assert( pPage->aData == &((unsigned char*)pPage)[-pBt->psAligned] );
  if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){
    /* The parent page should never change unless the file is corrupt */
    return SQLITE_CORRUPT; /* bkpt-CORRUPT */
  }
  if( pPage->isInit ) return SQLITE_OK;
  if( pPage->pParent==0 && pParent!=0 ){
    pPage->pParent = pParent;
    sqlite3pager_ref(pParent->aData);
  }
  hdr = pPage->hdrOffset;
  data = pPage->aData;
  decodeFlags(pPage, data[hdr]);
  pPage->nOverflow = 0;
  pPage->idxShift = 0;
  usableSize = pBt->usableSize;
  pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
  top = get2byte(&data[hdr+5]);
  pPage->nCell = get2byte(&data[hdr+3]);
  if( pPage->nCell>MX_CELL(pBt) ){
    /* To many cells for a single page.  The page must be corrupt */
    return SQLITE_CORRUPT; /* bkpt-CORRUPT */
  }
  if( pPage->nCell==0 && pParent!=0 && pParent->pgno!=1 ){
    /* All pages must have at least one cell, except for root pages */
    return SQLITE_CORRUPT; /* bkpt-CORRUPT */
  }

  /* Compute the total free space on the page */
  pc = get2byte(&data[hdr+1]);
  nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
  while( pc>0 ){
    int next, size;
    if( pc>usableSize-4 ){
      /* Free block is off the page */
      return SQLITE_CORRUPT;  /* bkpt-CORRUPT */
    }
    next = get2byte(&data[pc]);
    size = get2byte(&data[pc+2]);
    if( next>0 && next<=pc+size+3 ){
      /* Free blocks must be in accending order */
      return SQLITE_CORRUPT;  /* bkpt-CORRUPT */
    }
    nFree += size;
    pc = next;
  }
  pPage->nFree = nFree;
  if( nFree>=usableSize ){
    /* Free space cannot exceed total page size */
    return SQLITE_CORRUPT;  /* bkpt-CORRUPT */
  }

  pPage->isInit = 1;
  pageIntegrity(pPage);
  return SQLITE_OK;
}

/*
** Set up a raw page so that it looks like a database page holding
** no entries.
*/
static void zeroPage(MemPage *pPage, int flags){
  unsigned char *data = pPage->aData;
  Btree *pBt = pPage->pBt;
  int hdr = pPage->hdrOffset;
  int first;

  assert( sqlite3pager_pagenumber(data)==pPage->pgno );
  assert( &data[pBt->psAligned] == (unsigned char*)pPage );
  assert( sqlite3pager_iswriteable(data) );
  memset(&data[hdr], 0, pBt->usableSize - hdr);
  data[hdr] = flags;
  first = hdr + 8 + 4*((flags&PTF_LEAF)==0);
  memset(&data[hdr+1], 0, 4);
  data[hdr+7] = 0;
  put2byte(&data[hdr+5], pBt->usableSize);
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607


1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644



1645

1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912

1913
1914
1915
1916
1917
1918
1919
  pageIntegrity(pPage);
}

/*
** Get a page from the pager.  Initialize the MemPage.pBt and
** MemPage.aData elements if needed.
*/
static int getPage(BtShared *pBt, Pgno pgno, MemPage **ppPage){
  int rc;
  unsigned char *aData;
  MemPage *pPage;
  rc = sqlite3pager_get(pBt->pPager, pgno, (void**)&aData);
  if( rc ) return rc;
  pPage = (MemPage*)&aData[pBt->pageSize];
  pPage->aData = aData;
  pPage->pBt = pBt;
  pPage->pgno = pgno;
  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
  *ppPage = pPage;
  return SQLITE_OK;
}

/*
** Get a page from the pager and initialize it.  This routine
** is just a convenience wrapper around separate calls to
** getPage() and initPage().
*/
static int getAndInitPage(
  BtShared *pBt,          /* The database file */
  Pgno pgno,           /* Number of the page to get */
  MemPage **ppPage,    /* Write the page pointer here */
  MemPage *pParent     /* Parent of the page */
){
  int rc;
  if( pgno==0 ){
    return SQLITE_CORRUPT_BKPT; 
  }
  rc = getPage(pBt, pgno, ppPage);
  if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
    rc = initPage(*ppPage, pParent);
  }
  return rc;
}

/*
** Release a MemPage.  This should be called once for each prior
** call to getPage.
*/
static void releasePage(MemPage *pPage){
  if( pPage ){
    assert( pPage->aData );
    assert( pPage->pBt );
    assert( &pPage->aData[pPage->pBt->pageSize]==(unsigned char*)pPage );
    sqlite3pager_unref(pPage->aData);
  }
}

/*
** This routine is called when the reference count for a page
** reaches zero.  We need to unref the pParent pointer when that
** happens.
*/
static void pageDestructor(void *pData, int pageSize){
  MemPage *pPage;
  assert( (pageSize & 7)==0 );
  pPage = (MemPage*)&((char*)pData)[pageSize];
  if( pPage->pParent ){
    MemPage *pParent = pPage->pParent;
    pPage->pParent = 0;
    releasePage(pParent);
  }
  pPage->isInit = 0;
}

/*
** During a rollback, when the pager reloads information into the cache
** so that the cache is restored to its original state at the start of
** the transaction, for each page restored this routine is called.
**
** This routine needs to reset the extra data section at the end of the
** page to agree with the restored data.
*/
static void pageReinit(void *pData, int pageSize){
  MemPage *pPage;
  assert( (pageSize & 7)==0 );
  pPage = (MemPage*)&((char*)pData)[pageSize];
  if( pPage->isInit ){
    pPage->isInit = 0;
    initPage(pPage, pPage->pParent);
  }
}

/*
** Open a database file.
** 
** zFilename is the name of the database file.  If zFilename is NULL
** a new database with a random name is created.  This randomly named
** database file will be deleted when sqlite3BtreeClose() is called.
*/
int sqlite3BtreeOpen(
  const char *zFilename,  /* Name of the file containing the BTree database */
  sqlite3 *pSqlite,       /* Associated database handle */
  Btree **ppBtree,        /* Pointer to new Btree object written here */
  int flags               /* Options */
){
  BtShared *pBt;          /* Shared part of btree structure */
  Btree *p;               /* Handle to return */
  int rc;
  int nReserve;
  unsigned char zDbHeader[100];
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  const ThreadData *pTsdro;
#endif

  /* Set the variable isMemdb to true for an in-memory database, or 
  ** false for a file-based database. This symbol is only required if
  ** either of the shared-data or autovacuum features are compiled 
  ** into the library.
  */
#if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM)
  #ifdef SQLITE_OMIT_MEMORYDB
  const int isMemdb = !zFilename;
  #else
  const int isMemdb = !zFilename || (strcmp(zFilename, ":memory:")?0:1);
  #endif
#endif

  p = sqliteMalloc(sizeof(Btree));
  if( !p ){
    return SQLITE_NOMEM;
  }
  p->inTrans = TRANS_NONE;
  p->pSqlite = pSqlite;

  /* Try to find an existing Btree structure opened on zFilename. */
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  pTsdro = sqlite3ThreadDataReadOnly();
  if( pTsdro->useSharedData && zFilename && !isMemdb ){
    char *zFullPathname = sqlite3OsFullPathname(zFilename);
    if( !zFullPathname ){
      sqliteFree(p);
      return SQLITE_NOMEM;
    }
    for(pBt=pTsdro->pBtree; pBt; pBt=pBt->pNext){
      assert( pBt->nRef>0 );
      if( 0==strcmp(zFullPathname, sqlite3pager_filename(pBt->pPager)) ){
        p->pBt = pBt;
        *ppBtree = p;
        pBt->nRef++;
        sqliteFree(zFullPathname);
        return SQLITE_OK;
      }
    }
    sqliteFree(zFullPathname);
  }
#endif

  /*
  ** The following asserts make sure that structures used by the btree are
  ** the right size.  This is to guard against size changes that result
  ** when compiling on a different architecture.
  */
  assert( sizeof(i64)==8 );
  assert( sizeof(u64)==8 );
  assert( sizeof(u32)==4 );
  assert( sizeof(u16)==2 );
  assert( sizeof(Pgno)==4 );



  pBt = sqliteMalloc( sizeof(*pBt) );
  if( pBt==0 ){
    *ppBtree = 0;
    sqliteFree(p);
    return SQLITE_NOMEM;
  }
  rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
  if( rc!=SQLITE_OK ){
    if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
    sqliteFree(pBt);
    sqliteFree(p);
    *ppBtree = 0;
    return rc;
  }
  p->pBt = pBt;

  sqlite3pager_set_destructor(pBt->pPager, pageDestructor);
  sqlite3pager_set_reiniter(pBt->pPager, pageReinit);
  pBt->pCursor = 0;
  pBt->pPage1 = 0;
  pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager);
  sqlite3pager_read_fileheader(pBt->pPager, sizeof(zDbHeader), zDbHeader);
  pBt->pageSize = get2byte(&zDbHeader[16]);
  if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
       || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
    pBt->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
    pBt->maxEmbedFrac = 64;   /* 25% */
    pBt->minEmbedFrac = 32;   /* 12.5% */
    pBt->minLeafFrac = 32;    /* 12.5% */
#ifndef SQLITE_OMIT_AUTOVACUUM
    /* If the magic name ":memory:" will create an in-memory database, then
    ** do not set the auto-vacuum flag, even if SQLITE_DEFAULT_AUTOVACUUM
    ** is true. On the other hand, if SQLITE_OMIT_MEMORYDB has been defined,
    ** then ":memory:" is just a regular file-name. Respect the auto-vacuum
    ** default in this case.
    */



    if( zFilename && !isMemdb ){

      pBt->autoVacuum = SQLITE_DEFAULT_AUTOVACUUM;
    }
#endif
    nReserve = 0;
  }else{
    nReserve = zDbHeader[20];
    pBt->maxEmbedFrac = zDbHeader[21];
    pBt->minEmbedFrac = zDbHeader[22];
    pBt->minLeafFrac = zDbHeader[23];
    pBt->pageSizeFixed = 1;
#ifndef SQLITE_OMIT_AUTOVACUUM
    pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
#endif
  }
  pBt->usableSize = pBt->pageSize - nReserve;
  assert( (pBt->pageSize & 7)==0 );  /* 8-byte alignment of pageSize */
  sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);

#ifndef SQLITE_OMIT_SHARED_CACHE
  /* Add the new btree to the linked list starting at ThreadData.pBtree */
  if( pTsdro->useSharedData && zFilename && !isMemdb ){
    pBt->pNext = pTsdro->pBtree;
    sqlite3ThreadData()->pBtree = pBt;
  }
#endif
  pBt->nRef = 1;
  *ppBtree = p;
  return SQLITE_OK;
}

/*
** Close an open database and invalidate all cursors.
*/
int sqlite3BtreeClose(Btree *p){
  BtShared *pBt = p->pBt;
  BtCursor *pCur;

#ifndef SQLITE_OMIT_SHARED_CACHE
  ThreadData *pTsd;
#endif

  /* Drop any table-locks */
  unlockAllTables(p);

  /* Close all cursors opened via this handle.  */
  pCur = pBt->pCursor;
  while( pCur ){
    BtCursor *pTmp = pCur;
    pCur = pCur->pNext;
    if( pTmp->pBtree==p ){
      sqlite3BtreeCloseCursor(pTmp);
    }
  }

  /* Rollback any active transaction and free the handle structure */
  sqlite3BtreeRollback(p);
  sqliteFree(p);

#ifndef SQLITE_OMIT_SHARED_CACHE
  /* If there are still other outstanding references to the shared-btree
  ** structure, return now. The remainder of this procedure cleans 
  ** up the shared-btree.
  */
  assert( pBt->nRef>0 );
  pBt->nRef--;
  if( pBt->nRef ){
    return SQLITE_OK;
  }

  /* Remove the shared-btree from the thread wide list */
  pTsd = sqlite3ThreadData();
  if( pTsd->pBtree==pBt ){
    pTsd->pBtree = pBt->pNext;
  }else{
    BtShared *pPrev;
    for(pPrev=pTsd->pBtree; pPrev && pPrev->pNext!=pBt; pPrev=pPrev->pNext);
    if( pPrev ){
      pPrev->pNext = pBt->pNext;
    }
  }
#endif

  /* Close the pager and free the shared-btree structure */
  assert( !pBt->pCursor );
  sqlite3pager_close(pBt->pPager);
  if( pBt->xFreeSchema && pBt->pSchema ){
    pBt->xFreeSchema(pBt->pSchema);
  }
  sqliteFree(pBt->pSchema);
  sqliteFree(pBt);
  return SQLITE_OK;
}

/*
** Change the busy handler callback function.
*/
int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){
  BtShared *pBt = p->pBt;
  pBt->pBusyHandler = pHandler;
  sqlite3pager_set_busyhandler(pBt->pPager, pHandler);
  return SQLITE_OK;
}

/*
** Change the limit on the number of pages allowed in the cache.
**
** The maximum number of cache pages is set to the absolute
** value of mxPage.  If mxPage is negative, the pager will
** operate asynchronously - it will not stop to do fsync()s
** to insure data is written to the disk surface before
** continuing.  Transactions still work if synchronous is off,
** and the database cannot be corrupted if this program
** crashes.  But if the operating system crashes or there is
** an abrupt power failure when synchronous is off, the database
** could be left in an inconsistent and unrecoverable state.
** Synchronous is on by default so database corruption is not
** normally a worry.
*/
int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
  BtShared *pBt = p->pBt;
  sqlite3pager_set_cachesize(pBt->pPager, mxPage);
  return SQLITE_OK;
}

/*
** Change the way data is synced to disk in order to increase or decrease
** how well the database resists damage due to OS crashes and power
** failures.  Level 1 is the same as asynchronous (no syncs() occur and
** there is a high probability of damage)  Level 2 is the default.  There
** is a very low but non-zero probability of damage.  Level 3 reduces the
** probability of damage to near zero but with a write performance reduction.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
int sqlite3BtreeSetSafetyLevel(Btree *p, int level){
  BtShared *pBt = p->pBt;
  sqlite3pager_set_safety_level(pBt->pPager, level);
  return SQLITE_OK;
}
#endif

/*
** Return TRUE if the given btree is set to safety level 1.  In other
** words, return TRUE if no sync() occurs on the disk files.
*/
int sqlite3BtreeSyncDisabled(Btree *p){
  BtShared *pBt = p->pBt;
  assert( pBt && pBt->pPager );
  return sqlite3pager_nosync(pBt->pPager);
}

#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
/*
** Change the default pages size and the number of reserved bytes per page.
**
** The page size must be a power of 2 between 512 and 65536.  If the page
** size supplied does not meet this constraint then the page size is not
** changed.
**
** Page sizes are constrained to be a power of two so that the region
** of the database file used for locking (beginning at PENDING_BYTE,
** the first byte past the 1GB boundary, 0x40000000) needs to occur
** at the beginning of a page.
**
** If parameter nReserve is less than zero, then the number of reserved
** bytes per page is left unchanged.
*/
int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve){
  BtShared *pBt = p->pBt;
  if( pBt->pageSizeFixed ){
    return SQLITE_READONLY;
  }
  if( nReserve<0 ){
    nReserve = pBt->pageSize - pBt->usableSize;
  }
  if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
        ((pageSize-1)&pageSize)==0 ){
    assert( (pageSize & 7)==0 );
    assert( !pBt->pPage1 && !pBt->pCursor );
    pBt->pageSize = sqlite3pager_set_pagesize(pBt->pPager, pageSize);
  }
  pBt->usableSize = pBt->pageSize - nReserve;
  return SQLITE_OK;
}

/*
** Return the currently defined page size
*/
int sqlite3BtreeGetPageSize(Btree *p){
  return p->pBt->pageSize;
}
int sqlite3BtreeGetReserve(Btree *p){
  return p->pBt->pageSize - p->pBt->usableSize;
}
#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */

/*
** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
** is disabled. The default value for the auto-vacuum property is 
** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
*/
int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){
  BtShared *pBt = p->pBt;;
#ifdef SQLITE_OMIT_AUTOVACUUM
  return SQLITE_READONLY;
#else
  if( pBt->pageSizeFixed ){
    return SQLITE_READONLY;
  }
  pBt->autoVacuum = (autoVacuum?1:0);
  return SQLITE_OK;
#endif
}

/*
** Return the value of the 'auto-vacuum' property. If auto-vacuum is 
** enabled 1 is returned. Otherwise 0.
*/
int sqlite3BtreeGetAutoVacuum(Btree *p){
#ifdef SQLITE_OMIT_AUTOVACUUM
  return 0;
#else
  return p->pBt->autoVacuum;
#endif
}


/*
** Get a reference to pPage1 of the database file.  This will
** also acquire a readlock on that file.
**
** SQLITE_OK is returned on success.  If the file is not a
** well-formed database file, then SQLITE_CORRUPT is returned.
** SQLITE_BUSY is returned if the database is locked.  SQLITE_NOMEM
** is returned if we run out of memory.  SQLITE_PROTOCOL is returned
** if there is a locking protocol violation.
*/
static int lockBtree(BtShared *pBt){
  int rc, pageSize;
  MemPage *pPage1;
  if( pBt->pPage1 ) return SQLITE_OK;
  rc = getPage(pBt, 1, &pPage1);
  if( rc!=SQLITE_OK ) return rc;
  

  /* Do some checking to help insure the file we opened really is
  ** a valid database file. 
  */
  rc = SQLITE_NOTADB;
  if( sqlite3pager_pagecount(pBt->pPager)>0 ){
    u8 *page1 = pPage1->aData;
    if( memcmp(page1, zMagicHeader, 16)!=0 ){
      goto page1_init_failed;
    }
    if( page1[18]>1 || page1[19]>1 ){
      goto page1_init_failed;
    }
    pageSize = get2byte(&page1[16]);
    if( ((pageSize-1)&pageSize)!=0 ){
      goto page1_init_failed;
    }
    assert( (pageSize & 7)==0 );
    pBt->pageSize = pageSize;
    pBt->usableSize = pageSize - page1[20];
    if( pBt->usableSize<500 ){
      goto page1_init_failed;
    }

    pBt->maxEmbedFrac = page1[21];
    pBt->minEmbedFrac = page1[22];
    pBt->minLeafFrac = page1[23];
#ifndef SQLITE_OMIT_AUTOVACUUM
    pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
#endif
  }







|





|














|






|
















|










<
<
|

















<
<
|















<



<
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











>
>




<






<



<
<







|
<











>
>
>
|
>















|

<
<
<
<
<
<
<
<
<
|






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

<
<
<
<







|
<
<



















|
<













|
<





<
<
<
<
<
<
<
<
<
<
















|
<








|
|
|








|
|

|
|









|
<















|



|














|
|


















|
<
<
<
<
<
|



>







1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165


1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183


1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199

1200
1201
1202

1203
1204
1205
1206














































1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223

1224
1225
1226
1227
1228
1229

1230
1231
1232


1233
1234
1235
1236
1237
1238
1239
1240

1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273









1274
1275
1276
1277
1278
1279
1280
1281












1282



1283
1284
































1285




1286
1287
1288
1289
1290
1291
1292
1293


1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313

1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327

1328
1329
1330
1331
1332










1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349

1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438





1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
  pageIntegrity(pPage);
}

/*
** Get a page from the pager.  Initialize the MemPage.pBt and
** MemPage.aData elements if needed.
*/
static int getPage(Btree *pBt, Pgno pgno, MemPage **ppPage){
  int rc;
  unsigned char *aData;
  MemPage *pPage;
  rc = sqlite3pager_get(pBt->pPager, pgno, (void**)&aData);
  if( rc ) return rc;
  pPage = (MemPage*)&aData[pBt->psAligned];
  pPage->aData = aData;
  pPage->pBt = pBt;
  pPage->pgno = pgno;
  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
  *ppPage = pPage;
  return SQLITE_OK;
}

/*
** Get a page from the pager and initialize it.  This routine
** is just a convenience wrapper around separate calls to
** getPage() and initPage().
*/
static int getAndInitPage(
  Btree *pBt,          /* The database file */
  Pgno pgno,           /* Number of the page to get */
  MemPage **ppPage,    /* Write the page pointer here */
  MemPage *pParent     /* Parent of the page */
){
  int rc;
  if( pgno==0 ){
    return SQLITE_CORRUPT;  /* bkpt-CORRUPT */
  }
  rc = getPage(pBt, pgno, ppPage);
  if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
    rc = initPage(*ppPage, pParent);
  }
  return rc;
}

/*
** Release a MemPage.  This should be called once for each prior
** call to getPage.
*/
static void releasePage(MemPage *pPage){
  if( pPage ){
    assert( pPage->aData );
    assert( pPage->pBt );
    assert( &pPage->aData[pPage->pBt->psAligned]==(unsigned char*)pPage );
    sqlite3pager_unref(pPage->aData);
  }
}

/*
** This routine is called when the reference count for a page
** reaches zero.  We need to unref the pParent pointer when that
** happens.
*/
static void pageDestructor(void *pData, int pageSize){


  MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)];
  if( pPage->pParent ){
    MemPage *pParent = pPage->pParent;
    pPage->pParent = 0;
    releasePage(pParent);
  }
  pPage->isInit = 0;
}

/*
** During a rollback, when the pager reloads information into the cache
** so that the cache is restored to its original state at the start of
** the transaction, for each page restored this routine is called.
**
** This routine needs to reset the extra data section at the end of the
** page to agree with the restored data.
*/
static void pageReinit(void *pData, int pageSize){


  MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)];
  if( pPage->isInit ){
    pPage->isInit = 0;
    initPage(pPage, pPage->pParent);
  }
}

/*
** Open a database file.
** 
** zFilename is the name of the database file.  If zFilename is NULL
** a new database with a random name is created.  This randomly named
** database file will be deleted when sqlite3BtreeClose() is called.
*/
int sqlite3BtreeOpen(
  const char *zFilename,  /* Name of the file containing the BTree database */

  Btree **ppBtree,        /* Pointer to new Btree object written here */
  int flags               /* Options */
){

  Btree *pBt;
  int rc;
  int nReserve;
  unsigned char zDbHeader[100];















































  /*
  ** The following asserts make sure that structures used by the btree are
  ** the right size.  This is to guard against size changes that result
  ** when compiling on a different architecture.
  */
  assert( sizeof(i64)==8 );
  assert( sizeof(u64)==8 );
  assert( sizeof(u32)==4 );
  assert( sizeof(u16)==2 );
  assert( sizeof(Pgno)==4 );
  assert( sizeof(ptr)==sizeof(char*) );
  assert( sizeof(uptr)==sizeof(ptr) );

  pBt = sqliteMalloc( sizeof(*pBt) );
  if( pBt==0 ){
    *ppBtree = 0;

    return SQLITE_NOMEM;
  }
  rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
  if( rc!=SQLITE_OK ){
    if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
    sqliteFree(pBt);

    *ppBtree = 0;
    return rc;
  }


  sqlite3pager_set_destructor(pBt->pPager, pageDestructor);
  sqlite3pager_set_reiniter(pBt->pPager, pageReinit);
  pBt->pCursor = 0;
  pBt->pPage1 = 0;
  pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager);
  sqlite3pager_read_fileheader(pBt->pPager, sizeof(zDbHeader), zDbHeader);
  pBt->pageSize = get2byte(&zDbHeader[16]);
  if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE ){

    pBt->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
    pBt->maxEmbedFrac = 64;   /* 25% */
    pBt->minEmbedFrac = 32;   /* 12.5% */
    pBt->minLeafFrac = 32;    /* 12.5% */
#ifndef SQLITE_OMIT_AUTOVACUUM
    /* If the magic name ":memory:" will create an in-memory database, then
    ** do not set the auto-vacuum flag, even if SQLITE_DEFAULT_AUTOVACUUM
    ** is true. On the other hand, if SQLITE_OMIT_MEMORYDB has been defined,
    ** then ":memory:" is just a regular file-name. Respect the auto-vacuum
    ** default in this case.
    */
#ifndef SQLITE_OMIT_MEMORYDB
    if( zFilename && strcmp(zFilename,":memory:") ){
#else
    if( zFilename ){
#endif
      pBt->autoVacuum = SQLITE_DEFAULT_AUTOVACUUM;
    }
#endif
    nReserve = 0;
  }else{
    nReserve = zDbHeader[20];
    pBt->maxEmbedFrac = zDbHeader[21];
    pBt->minEmbedFrac = zDbHeader[22];
    pBt->minLeafFrac = zDbHeader[23];
    pBt->pageSizeFixed = 1;
#ifndef SQLITE_OMIT_AUTOVACUUM
    pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
#endif
  }
  pBt->usableSize = pBt->pageSize - nReserve;
  pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize);
  sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);









  *ppBtree = pBt;
  return SQLITE_OK;
}

/*
** Close an open database and invalidate all cursors.
*/
int sqlite3BtreeClose(Btree *pBt){












  while( pBt->pCursor ){



    sqlite3BtreeCloseCursor(pBt->pCursor);
  }
































  sqlite3pager_close(pBt->pPager);




  sqliteFree(pBt);
  return SQLITE_OK;
}

/*
** Change the busy handler callback function.
*/
int sqlite3BtreeSetBusyHandler(Btree *pBt, BusyHandler *pHandler){


  sqlite3pager_set_busyhandler(pBt->pPager, pHandler);
  return SQLITE_OK;
}

/*
** Change the limit on the number of pages allowed in the cache.
**
** The maximum number of cache pages is set to the absolute
** value of mxPage.  If mxPage is negative, the pager will
** operate asynchronously - it will not stop to do fsync()s
** to insure data is written to the disk surface before
** continuing.  Transactions still work if synchronous is off,
** and the database cannot be corrupted if this program
** crashes.  But if the operating system crashes or there is
** an abrupt power failure when synchronous is off, the database
** could be left in an inconsistent and unrecoverable state.
** Synchronous is on by default so database corruption is not
** normally a worry.
*/
int sqlite3BtreeSetCacheSize(Btree *pBt, int mxPage){

  sqlite3pager_set_cachesize(pBt->pPager, mxPage);
  return SQLITE_OK;
}

/*
** Change the way data is synced to disk in order to increase or decrease
** how well the database resists damage due to OS crashes and power
** failures.  Level 1 is the same as asynchronous (no syncs() occur and
** there is a high probability of damage)  Level 2 is the default.  There
** is a very low but non-zero probability of damage.  Level 3 reduces the
** probability of damage to near zero but with a write performance reduction.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){

  sqlite3pager_set_safety_level(pBt->pPager, level);
  return SQLITE_OK;
}
#endif











#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
/*
** Change the default pages size and the number of reserved bytes per page.
**
** The page size must be a power of 2 between 512 and 65536.  If the page
** size supplied does not meet this constraint then the page size is not
** changed.
**
** Page sizes are constrained to be a power of two so that the region
** of the database file used for locking (beginning at PENDING_BYTE,
** the first byte past the 1GB boundary, 0x40000000) needs to occur
** at the beginning of a page.
**
** If parameter nReserve is less than zero, then the number of reserved
** bytes per page is left unchanged.
*/
int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){

  if( pBt->pageSizeFixed ){
    return SQLITE_READONLY;
  }
  if( nReserve<0 ){
    nReserve = pBt->pageSize - pBt->usableSize;
  }
  if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
        ((pageSize-1)&pageSize)==0 ){
    pBt->pageSize = pageSize;
    pBt->psAligned = FORCE_ALIGNMENT(pageSize);
    sqlite3pager_set_pagesize(pBt->pPager, pageSize);
  }
  pBt->usableSize = pBt->pageSize - nReserve;
  return SQLITE_OK;
}

/*
** Return the currently defined page size
*/
int sqlite3BtreeGetPageSize(Btree *pBt){
  return pBt->pageSize;
}
int sqlite3BtreeGetReserve(Btree *pBt){
  return pBt->pageSize - pBt->usableSize;
}
#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */

/*
** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
** is disabled. The default value for the auto-vacuum property is 
** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
*/
int sqlite3BtreeSetAutoVacuum(Btree *pBt, int autoVacuum){

#ifdef SQLITE_OMIT_AUTOVACUUM
  return SQLITE_READONLY;
#else
  if( pBt->pageSizeFixed ){
    return SQLITE_READONLY;
  }
  pBt->autoVacuum = (autoVacuum?1:0);
  return SQLITE_OK;
#endif
}

/*
** Return the value of the 'auto-vacuum' property. If auto-vacuum is 
** enabled 1 is returned. Otherwise 0.
*/
int sqlite3BtreeGetAutoVacuum(Btree *pBt){
#ifdef SQLITE_OMIT_AUTOVACUUM
  return 0;
#else
  return pBt->autoVacuum;
#endif
}


/*
** Get a reference to pPage1 of the database file.  This will
** also acquire a readlock on that file.
**
** SQLITE_OK is returned on success.  If the file is not a
** well-formed database file, then SQLITE_CORRUPT is returned.
** SQLITE_BUSY is returned if the database is locked.  SQLITE_NOMEM
** is returned if we run out of memory.  SQLITE_PROTOCOL is returned
** if there is a locking protocol violation.
*/
static int lockBtree(Btree *pBt){
  int rc;
  MemPage *pPage1;
  if( pBt->pPage1 ) return SQLITE_OK;
  rc = getPage(pBt, 1, &pPage1);
  if( rc!=SQLITE_OK ) return rc;
  

  /* Do some checking to help insure the file we opened really is
  ** a valid database file. 
  */
  rc = SQLITE_NOTADB;
  if( sqlite3pager_pagecount(pBt->pPager)>0 ){
    u8 *page1 = pPage1->aData;
    if( memcmp(page1, zMagicHeader, 16)!=0 ){
      goto page1_init_failed;
    }
    if( page1[18]>1 || page1[19]>1 ){
      goto page1_init_failed;
    }
    pBt->pageSize = get2byte(&page1[16]);





    pBt->usableSize = pBt->pageSize - page1[20];
    if( pBt->usableSize<500 ){
      goto page1_init_failed;
    }
    pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize);
    pBt->maxEmbedFrac = page1[21];
    pBt->minEmbedFrac = page1[22];
    pBt->minLeafFrac = page1[23];
#ifndef SQLITE_OMIT_AUTOVACUUM
    pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
#endif
  }
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007

page1_init_failed:
  releasePage(pPage1);
  pBt->pPage1 = 0;
  return rc;
}

/*
** This routine works like lockBtree() except that it also invokes the
** busy callback if there is lock contention.
*/
static int lockBtreeWithRetry(Btree *pRef){
  int rc = SQLITE_OK;
  if( pRef->inTrans==TRANS_NONE ){
    u8 inTransaction = pRef->pBt->inTransaction;
    btreeIntegrity(pRef);
    rc = sqlite3BtreeBeginTrans(pRef, 0);
    pRef->pBt->inTransaction = inTransaction;
    pRef->inTrans = TRANS_NONE;
    if( rc==SQLITE_OK ){
      pRef->pBt->nTransaction--;
    }
    btreeIntegrity(pRef);
  }
  return rc;
}
       

/*
** If there are no outstanding cursors and we are not in the middle
** of a transaction but there is a read lock on the database, then
** this routine unrefs the first page of the database file which 
** has the effect of releasing the read lock.
**
** If there are any outstanding cursors, this routine is a no-op.
**
** If there is a transaction in progress, this routine is a no-op.
*/
static void unlockBtreeIfUnused(BtShared *pBt){
  if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
    if( pBt->pPage1->aData==0 ){
      MemPage *pPage = pBt->pPage1;
      pPage->aData = &((u8*)pPage)[-pBt->pageSize];
      pPage->pBt = pBt;
      pPage->pgno = 1;
    }
    releasePage(pBt->pPage1);
    pBt->pPage1 = 0;
    pBt->inStmt = 0;
  }
}

/*
** Create a new database by initializing the first page of the
** file.
*/
static int newDatabase(BtShared *pBt){
  MemPage *pP1;
  unsigned char *data;
  int rc;
  if( sqlite3pager_pagecount(pBt->pPager)>0 ) return SQLITE_OK;
  pP1 = pBt->pPage1;
  assert( pP1!=0 );
  data = pP1->aData;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










|
|


|













|







1475
1476
1477
1478
1479
1480
1481





















1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517

page1_init_failed:
  releasePage(pPage1);
  pBt->pPage1 = 0;
  return rc;
}






















/*
** If there are no outstanding cursors and we are not in the middle
** of a transaction but there is a read lock on the database, then
** this routine unrefs the first page of the database file which 
** has the effect of releasing the read lock.
**
** If there are any outstanding cursors, this routine is a no-op.
**
** If there is a transaction in progress, this routine is a no-op.
*/
static void unlockBtreeIfUnused(Btree *pBt){
  if( pBt->inTrans==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){
    if( pBt->pPage1->aData==0 ){
      MemPage *pPage = pBt->pPage1;
      pPage->aData = &((char*)pPage)[-pBt->psAligned];
      pPage->pBt = pBt;
      pPage->pgno = 1;
    }
    releasePage(pBt->pPage1);
    pBt->pPage1 = 0;
    pBt->inStmt = 0;
  }
}

/*
** Create a new database by initializing the first page of the
** file.
*/
static int newDatabase(Btree *pBt){
  MemPage *pP1;
  unsigned char *data;
  int rc;
  if( sqlite3pager_pagecount(pBt->pPager)>0 ) return SQLITE_OK;
  pP1 = pBt->pPage1;
  assert( pP1!=0 );
  data = pP1->aData;
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074

2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104

2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144

/*
** Attempt to start a new transaction. A write-transaction
** is started if the second argument is nonzero, otherwise a read-
** transaction.  If the second argument is 2 or more and exclusive
** transaction is started, meaning that no other process is allowed
** to access the database.  A preexisting transaction may not be
** upgraded to exclusive by calling this routine a second time - the
** exclusivity flag only works for a new transaction.
**
** A write-transaction must be started before attempting any 
** changes to the database.  None of the following routines 
** will work unless a transaction is started first:
**
**      sqlite3BtreeCreateTable()
**      sqlite3BtreeCreateIndex()
**      sqlite3BtreeClearTable()
**      sqlite3BtreeDropTable()
**      sqlite3BtreeInsert()
**      sqlite3BtreeDelete()
**      sqlite3BtreeUpdateMeta()
**
** If an initial attempt to acquire the lock fails because of lock contention
** and the database was previously unlocked, then invoke the busy handler
** if there is one.  But if there was previously a read-lock, do not
** invoke the busy handler - just return SQLITE_BUSY.  SQLITE_BUSY is 
** returned when there is already a read-lock in order to avoid a deadlock.
**
** Suppose there are two processes A and B.  A has a read lock and B has
** a reserved lock.  B tries to promote to exclusive but is blocked because
** of A's read lock.  A tries to promote to reserved but is blocked by B.
** One or the other of the two processes must give way or there can be
** no progress.  By returning SQLITE_BUSY and not invoking the busy callback
** when A already has a read lock, we encourage A to give up and let B
** proceed.
*/
int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
  BtShared *pBt = p->pBt;
  int rc = SQLITE_OK;

  btreeIntegrity(p);

  /* If the btree is already in a write-transaction, or it
  ** is already in a read-transaction and a read-transaction
  ** is requested, this is a no-op.
  */

  if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
    return SQLITE_OK;
  }

  /* Write transactions are not possible on a read-only database */
  if( pBt->readOnly && wrflag ){
    return SQLITE_READONLY;
  }

  /* If another database handle has already opened a write transaction 
  ** on this shared-btree structure and a second write transaction is
  ** requested, return SQLITE_BUSY.
  */
  if( pBt->inTransaction==TRANS_WRITE && wrflag ){
    return SQLITE_BUSY;
  }

  do {
    if( pBt->pPage1==0 ){
      rc = lockBtree(pBt);
    }
  
    if( rc==SQLITE_OK && wrflag ){
      rc = sqlite3pager_begin(pBt->pPage1->aData, wrflag>1);
      if( rc==SQLITE_OK ){
        rc = newDatabase(pBt);
      }
    }
  
    if( rc==SQLITE_OK ){

      if( wrflag ) pBt->inStmt = 0;
    }else{
      unlockBtreeIfUnused(pBt);
    }
  }while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
          sqlite3InvokeBusyHandler(pBt->pBusyHandler) );

  if( rc==SQLITE_OK ){
    if( p->inTrans==TRANS_NONE ){
      pBt->nTransaction++;
    }
    p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
    if( p->inTrans>pBt->inTransaction ){
      pBt->inTransaction = p->inTrans;
    }
  }

  btreeIntegrity(p);
  return rc;
}

#ifndef SQLITE_OMIT_AUTOVACUUM

/*
** Set the pointer-map entries for all children of page pPage. Also, if
** pPage contains cells that point to overflow pages, set the pointer
** map entries for the overflow pages as well.
*/
static int setChildPtrmaps(MemPage *pPage){
  int i;                             /* Counter variable */
  int nCell;                         /* Number of cells in page pPage */
  int rc = SQLITE_OK;                /* Return code */
  BtShared *pBt = pPage->pBt;
  int isInitOrig = pPage->isInit;
  Pgno pgno = pPage->pgno;

  initPage(pPage, 0);
  nCell = pPage->nCell;

  for(i=0; i<nCell; i++){







|














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

|
<


<
<




>
|


<
<




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














|







1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563








1564

1565
1566

1567
1568


1569
1570
1571
1572
1573
1574
1575
1576


1577
1578
1579
1580









1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597














1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619

/*
** Attempt to start a new transaction. A write-transaction
** is started if the second argument is nonzero, otherwise a read-
** transaction.  If the second argument is 2 or more and exclusive
** transaction is started, meaning that no other process is allowed
** to access the database.  A preexisting transaction may not be
** upgrade to exclusive by calling this routine a second time - the
** exclusivity flag only works for a new transaction.
**
** A write-transaction must be started before attempting any 
** changes to the database.  None of the following routines 
** will work unless a transaction is started first:
**
**      sqlite3BtreeCreateTable()
**      sqlite3BtreeCreateIndex()
**      sqlite3BtreeClearTable()
**      sqlite3BtreeDropTable()
**      sqlite3BtreeInsert()
**      sqlite3BtreeDelete()
**      sqlite3BtreeUpdateMeta()
**
** If wrflag is true, then nMaster specifies the maximum length of
** a master journal file name supplied later via sqlite3BtreeSync().
** This is so that appropriate space can be allocated in the journal file








** when it is created..

*/
int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){

  int rc = SQLITE_OK;



  /* If the btree is already in a write-transaction, or it
  ** is already in a read-transaction and a read-transaction
  ** is requested, this is a no-op.
  */
  if( pBt->inTrans==TRANS_WRITE || 
      (pBt->inTrans==TRANS_READ && !wrflag) ){
    return SQLITE_OK;
  }


  if( pBt->readOnly && wrflag ){
    return SQLITE_READONLY;
  }










  if( pBt->pPage1==0 ){
    rc = lockBtree(pBt);
  }

  if( rc==SQLITE_OK && wrflag ){
    rc = sqlite3pager_begin(pBt->pPage1->aData, wrflag>1);
    if( rc==SQLITE_OK ){
      rc = newDatabase(pBt);
    }
  }

  if( rc==SQLITE_OK ){
    pBt->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
    if( wrflag ) pBt->inStmt = 0;
  }else{
    unlockBtreeIfUnused(pBt);
  }














  return rc;
}

#ifndef SQLITE_OMIT_AUTOVACUUM

/*
** Set the pointer-map entries for all children of page pPage. Also, if
** pPage contains cells that point to overflow pages, set the pointer
** map entries for the overflow pages as well.
*/
static int setChildPtrmaps(MemPage *pPage){
  int i;                             /* Counter variable */
  int nCell;                         /* Number of cells in page pPage */
  int rc = SQLITE_OK;                /* Return code */
  Btree *pBt = pPage->pBt;
  int isInitOrig = pPage->isInit;
  Pgno pgno = pPage->pgno;

  initPage(pPage, 0);
  nCell = pPage->nCell;

  for(i=0; i<nCell; i++){
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
**                   overflow page in the list.
*/
static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
  if( eType==PTRMAP_OVERFLOW2 ){
    /* The pointer is always the first 4 bytes of the page in this case.  */
    if( get4byte(pPage->aData)!=iFrom ){
      return SQLITE_CORRUPT_BKPT;
    }
    put4byte(pPage->aData, iTo);
  }else{
    int isInitOrig = pPage->isInit;
    int i;
    int nCell;








|







1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
**                   overflow page in the list.
*/
static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
  if( eType==PTRMAP_OVERFLOW2 ){
    /* The pointer is always the first 4 bytes of the page in this case.  */
    if( get4byte(pPage->aData)!=iFrom ){
      return SQLITE_CORRUPT;
    }
    put4byte(pPage->aData, iTo);
  }else{
    int isInitOrig = pPage->isInit;
    int i;
    int nCell;

2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
        }
      }
    }
  
    if( i==nCell ){
      if( eType!=PTRMAP_BTREE || 
          get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
        return SQLITE_CORRUPT_BKPT;
      }
      put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
    }

    pPage->isInit = isInitOrig;
  }
  return SQLITE_OK;
}


/*
** Move the open database page pDbPage to location iFreePage in the 
** database. The pDbPage reference remains valid.
*/
static int relocatePage(
  BtShared *pBt,           /* Btree */
  MemPage *pDbPage,        /* Open page to move */
  u8 eType,                /* Pointer map 'type' entry for pDbPage */
  Pgno iPtrPage,           /* Pointer map 'page-no' entry for pDbPage */
  Pgno iFreePage           /* The location to move pDbPage to */
){
  MemPage *pPtrPage;   /* The page that contains a pointer to pDbPage */
  Pgno iDbPage = pDbPage->pgno;







|















|







1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
        }
      }
    }
  
    if( i==nCell ){
      if( eType!=PTRMAP_BTREE || 
          get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
        return SQLITE_CORRUPT;
      }
      put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
    }

    pPage->isInit = isInitOrig;
  }
  return SQLITE_OK;
}


/*
** Move the open database page pDbPage to location iFreePage in the 
** database. The pDbPage reference remains valid.
*/
static int relocatePage(
  Btree *pBt,              /* Btree */
  MemPage *pDbPage,        /* Open page to move */
  u8 eType,                /* Pointer map 'type' entry for pDbPage */
  Pgno iPtrPage,           /* Pointer map 'page-no' entry for pDbPage */
  Pgno iFreePage           /* The location to move pDbPage to */
){
  MemPage *pPtrPage;   /* The page that contains a pointer to pDbPage */
  Pgno iDbPage = pDbPage->pgno;
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
      rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage);
    }
  }
  return rc;
}

/* Forward declaration required by autoVacuumCommit(). */
static int allocatePage(BtShared *, MemPage **, Pgno *, Pgno, u8);

/*
** This routine is called prior to sqlite3pager_commit when a transaction
** is commited for an auto-vacuum database.
*/
static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){
  Pager *pPager = pBt->pPager;
  Pgno nFreeList;            /* Number of pages remaining on the free-list. */
  int nPtrMap;               /* Number of pointer-map pages deallocated */
  Pgno origSize;             /* Pages in the database file */
  Pgno finSize;              /* Pages in the database file after truncation */
  int rc;                    /* Return code */
  u8 eType;
  int pgsz = pBt->pageSize;  /* Page size for this database */
  Pgno iDbPage;              /* The database page to move */
  MemPage *pDbMemPage = 0;   /* "" */
  Pgno iPtrPage;             /* The page that contains a pointer to iDbPage */
  Pgno iFreePage;            /* The free-list page to move iDbPage to */
  MemPage *pFreeMemPage = 0; /* "" */

#ifndef NDEBUG
  int nRef = *sqlite3pager_stats(pPager);
#endif

  assert( pBt->autoVacuum );
  if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){
    return SQLITE_CORRUPT_BKPT;
  }

  /* Figure out how many free-pages are in the database. If there are no
  ** free pages, then auto-vacuum is a no-op.
  */
  nFreeList = get4byte(&pBt->pPage1->aData[36]);
  if( nFreeList==0 ){
    *nTrunc = 0;
    return SQLITE_OK;
  }

  origSize = sqlite3pager_pagecount(pPager);
  nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5);
  finSize = origSize - nFreeList - nPtrMap;
  if( origSize>=PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
    finSize--;
    if( PTRMAP_ISPAGE(pBt->usableSize, finSize) ){
      finSize--;
    }
  }
  TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize));








|





|

|
|
|
|
|














|














|







1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
      rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage);
    }
  }
  return rc;
}

/* Forward declaration required by autoVacuumCommit(). */
static int allocatePage(Btree *, MemPage **, Pgno *, Pgno, u8);

/*
** This routine is called prior to sqlite3pager_commit when a transaction
** is commited for an auto-vacuum database.
*/
static int autoVacuumCommit(Btree *pBt, Pgno *nTrunc){
  Pager *pPager = pBt->pPager;
  Pgno nFreeList;   /* Number of pages remaining on the free-list. */
  int nPtrMap;      /* Number of pointer-map pages deallocated */
  Pgno origSize;  /* Pages in the database file */
  Pgno finSize;   /* Pages in the database file after truncation */
  int rc;           /* Return code */
  u8 eType;
  int pgsz = pBt->pageSize;  /* Page size for this database */
  Pgno iDbPage;              /* The database page to move */
  MemPage *pDbMemPage = 0;   /* "" */
  Pgno iPtrPage;             /* The page that contains a pointer to iDbPage */
  Pgno iFreePage;            /* The free-list page to move iDbPage to */
  MemPage *pFreeMemPage = 0; /* "" */

#ifndef NDEBUG
  int nRef = *sqlite3pager_stats(pPager);
#endif

  assert( pBt->autoVacuum );
  if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){
    return SQLITE_CORRUPT;
  }

  /* Figure out how many free-pages are in the database. If there are no
  ** free pages, then auto-vacuum is a no-op.
  */
  nFreeList = get4byte(&pBt->pPage1->aData[36]);
  if( nFreeList==0 ){
    *nTrunc = 0;
    return SQLITE_OK;
  }

  origSize = sqlite3pager_pagecount(pPager);
  nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5);
  finSize = origSize - nFreeList - nPtrMap;
  if( origSize>PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){
    finSize--;
    if( PTRMAP_ISPAGE(pBt->usableSize, finSize) ){
      finSize--;
    }
  }
  TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize));

2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
    /* If iDbPage is a pointer map page, or the pending-byte page, skip it. */
    if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
      continue;
    }

    rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
    if( eType==PTRMAP_ROOTPAGE ){
      rc = SQLITE_CORRUPT_BKPT;
      goto autovacuum_out;
    }

    /* If iDbPage is free, do not swap it.  */
    if( eType==PTRMAP_FREEPAGE ){
      continue;
    }
    rc = getPage(pBt, iDbPage, &pDbMemPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;







|
<
<
<







1839
1840
1841
1842
1843
1844
1845
1846



1847
1848
1849
1850
1851
1852
1853
    /* If iDbPage is a pointer map page, or the pending-byte page, skip it. */
    if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){
      continue;
    }

    rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
    assert( eType!=PTRMAP_ROOTPAGE );




    /* If iDbPage is free, do not swap it.  */
    if( eType==PTRMAP_FREEPAGE ){
      continue;
    }
    rc = getPage(pBt, iDbPage, &pDbMemPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
        goto autovacuum_out;
      }
      assert( iFreePage<=origSize );
    }while( iFreePage>finSize );
    releasePage(pFreeMemPage);
    pFreeMemPage = 0;

    /* Relocate the page into the body of the file. Note that although the 
    ** page has moved within the database file, the pDbMemPage pointer 
    ** remains valid. This means that this function can run without
    ** invalidating cursors open on the btree. This is important in 
    ** shared-cache mode.
    */
    rc = relocatePage(pBt, pDbMemPage, eType, iPtrPage, iFreePage);
    releasePage(pDbMemPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
  }

  /* The entire free-list has been swapped to the end of the file. So
  ** truncate the database file to finSize pages and consider the







<
<
<
<
<
<







1867
1868
1869
1870
1871
1872
1873






1874
1875
1876
1877
1878
1879
1880
        goto autovacuum_out;
      }
      assert( iFreePage<=origSize );
    }while( iFreePage>finSize );
    releasePage(pFreeMemPage);
    pFreeMemPage = 0;







    rc = relocatePage(pBt, pDbMemPage, eType, iPtrPage, iFreePage);
    releasePage(pDbMemPage);
    if( rc!=SQLITE_OK ) goto autovacuum_out;
  }

  /* The entire free-list has been swapped to the end of the file. So
  ** truncate the database file to finSize pages and consider the
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472

2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622

/*
** Commit the transaction currently in progress.
**
** This will release the write lock on the database file.  If there
** are no active cursors, it also releases the read lock.
*/
int sqlite3BtreeCommit(Btree *p){
  int rc = SQLITE_OK;
  BtShared *pBt = p->pBt;

  btreeIntegrity(p);
  unlockAllTables(p);

  /* If the handle has a write-transaction open, commit the shared-btrees 
  ** transaction and set the shared state to TRANS_READ.
  */
  if( p->inTrans==TRANS_WRITE ){
    assert( pBt->inTransaction==TRANS_WRITE );
    assert( pBt->nTransaction>0 );
    rc = sqlite3pager_commit(pBt->pPager);
    pBt->inTransaction = TRANS_READ;
    pBt->inStmt = 0;
  }

  /* If the handle has any kind of transaction open, decrement the transaction
  ** count of the shared btree. If the transaction count reaches 0, set
  ** the shared state to TRANS_NONE. The unlockBtreeIfUnused() call below
  ** will unlock the pager.
  */
  if( p->inTrans!=TRANS_NONE ){
    pBt->nTransaction--;
    if( 0==pBt->nTransaction ){
      pBt->inTransaction = TRANS_NONE;
    }
  }

  /* Set the handles current transaction state to TRANS_NONE and unlock
  ** the pager if this call closed the only read or write transaction.
  */
  p->inTrans = TRANS_NONE;

  unlockBtreeIfUnused(pBt);

  btreeIntegrity(p);
  return rc;
}

#ifndef NDEBUG
/*
** Return the number of write-cursors open on this handle. This is for use
** in assert() expressions, so it is only compiled if NDEBUG is not
** defined.
*/
static int countWriteCursors(BtShared *pBt){
  BtCursor *pCur;
  int r = 0;
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    if( pCur->wrFlag ) r++; 
  }
  return r;
}
#endif

#ifdef SQLITE_TEST
/*
** Print debugging information about all cursors to standard output.
*/
void sqlite3BtreeCursorList(Btree *p){
  BtCursor *pCur;
  BtShared *pBt = p->pBt;
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    MemPage *pPage = pCur->pPage;
    char *zMode = pCur->wrFlag ? "rw" : "ro";
    sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
       pCur, pCur->pgnoRoot, zMode,
       pPage ? pPage->pgno : 0, pCur->idx,
       (pCur->eState==CURSOR_VALID) ? "" : " eof"
    );
  }
}
#endif

/*
** Rollback the transaction in progress.  All cursors will be
** invalided by this operation.  Any attempt to use a cursor
** that was open at the beginning of this operation will result
** in an error.
**
** This will release the write lock on the database file.  If there
** are no active cursors, it also releases the read lock.
*/
int sqlite3BtreeRollback(Btree *p){
  int rc = SQLITE_OK;
  BtShared *pBt = p->pBt;
  MemPage *pPage1;

  btreeIntegrity(p);
  unlockAllTables(p);

  if( p->inTrans==TRANS_WRITE ){
    assert( TRANS_WRITE==pBt->inTransaction );

    rc = sqlite3pager_rollback(pBt->pPager);
    /* The rollback may have destroyed the pPage1->aData value.  So
    ** call getPage() on page 1 again to make sure pPage1->aData is
    ** set correctly. */
    if( getPage(pBt, 1, &pPage1)==SQLITE_OK ){
      releasePage(pPage1);
    }
    assert( countWriteCursors(pBt)==0 );
    pBt->inTransaction = TRANS_READ;
  }

  if( p->inTrans!=TRANS_NONE ){
    assert( pBt->nTransaction>0 );
    pBt->nTransaction--;
    if( 0==pBt->nTransaction ){
      pBt->inTransaction = TRANS_NONE;
    }
  }

  p->inTrans = TRANS_NONE;
  pBt->inStmt = 0;
  unlockBtreeIfUnused(pBt);

  btreeIntegrity(p);
  return rc;
}

/*
** Start a statement subtransaction.  The subtransaction can
** can be rolled back independently of the main transaction.
** You must start a transaction before starting a subtransaction.
** The subtransaction is ended automatically if the main transaction
** commits or rolls back.
**
** Only one subtransaction may be active at a time.  It is an error to try
** to start a new subtransaction if another subtransaction is already active.
**
** Statement subtransactions are used around individual SQL statements
** that are contained within a BEGIN...COMMIT block.  If a constraint
** error occurs within the statement, the effect of that one statement
** can be rolled back without having to rollback the entire transaction.
*/
int sqlite3BtreeBeginStmt(Btree *p){
  int rc;
  BtShared *pBt = p->pBt;
  if( (p->inTrans!=TRANS_WRITE) || pBt->inStmt ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( pBt->inTransaction==TRANS_WRITE );
  rc = pBt->readOnly ? SQLITE_OK : sqlite3pager_stmt_begin(pBt->pPager);
  pBt->inStmt = 1;
  return rc;
}


/*
** Commit the statment subtransaction currently in progress.  If no
** subtransaction is active, this is a no-op.
*/
int sqlite3BtreeCommitStmt(Btree *p){
  int rc;
  BtShared *pBt = p->pBt;
  if( pBt->inStmt && !pBt->readOnly ){
    rc = sqlite3pager_stmt_commit(pBt->pPager);
  }else{
    rc = SQLITE_OK;
  }
  pBt->inStmt = 0;
  return rc;
}

/*
** Rollback the active statement subtransaction.  If no subtransaction
** is active this routine is a no-op.
**
** All cursors will be invalidated by this operation.  Any attempt
** to use a cursor that was open at the beginning of this operation
** will result in an error.
*/
int sqlite3BtreeRollbackStmt(Btree *p){
  int rc;
  BtShared *pBt = p->pBt;
  if( pBt->inStmt==0 || pBt->readOnly ) return SQLITE_OK;
  rc = sqlite3pager_stmt_rollback(pBt->pPager);
  assert( countWriteCursors(pBt)==0 );
  pBt->inStmt = 0;
  return rc;
}








|

<
<
<
<
<
<
<
<
|
<
<

<
<

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

<
<









|



|









|

<






|














|

<

<
<
<
<
|
<
<








<

<
<
<
<
<
<
<
<
<
|


<
<


















|

<
|


<










|

<

















|

<







1898
1899
1900
1901
1902
1903
1904
1905
1906








1907


1908


1909
















1910
1911
1912


1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937

1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960

1961




1962


1963
1964
1965
1966
1967
1968
1969
1970

1971









1972
1973
1974


1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994

1995
1996
1997

1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009

2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028

2029
2030
2031
2032
2033
2034
2035

/*
** Commit the transaction currently in progress.
**
** This will release the write lock on the database file.  If there
** are no active cursors, it also releases the read lock.
*/
int sqlite3BtreeCommit(Btree *pBt){
  int rc = SQLITE_OK;








  if( pBt->inTrans==TRANS_WRITE ){


    rc = sqlite3pager_commit(pBt->pPager);


  }
















  pBt->inTrans = TRANS_NONE;
  pBt->inStmt = 0;
  unlockBtreeIfUnused(pBt);


  return rc;
}

#ifndef NDEBUG
/*
** Return the number of write-cursors open on this handle. This is for use
** in assert() expressions, so it is only compiled if NDEBUG is not
** defined.
*/
static int countWriteCursors(Btree *pBt){
  BtCursor *pCur;
  int r = 0;
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    if( pCur->wrFlag ) r++;
  }
  return r;
}
#endif

#ifdef SQLITE_TEST
/*
** Print debugging information about all cursors to standard output.
*/
void sqlite3BtreeCursorList(Btree *pBt){
  BtCursor *pCur;

  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    MemPage *pPage = pCur->pPage;
    char *zMode = pCur->wrFlag ? "rw" : "ro";
    sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
       pCur, pCur->pgnoRoot, zMode,
       pPage ? pPage->pgno : 0, pCur->idx,
       pCur->isValid ? "" : " eof"
    );
  }
}
#endif

/*
** Rollback the transaction in progress.  All cursors will be
** invalided by this operation.  Any attempt to use a cursor
** that was open at the beginning of this operation will result
** in an error.
**
** This will release the write lock on the database file.  If there
** are no active cursors, it also releases the read lock.
*/
int sqlite3BtreeRollback(Btree *pBt){
  int rc = SQLITE_OK;

  MemPage *pPage1;




  if( pBt->inTrans==TRANS_WRITE ){


    rc = sqlite3pager_rollback(pBt->pPager);
    /* The rollback may have destroyed the pPage1->aData value.  So
    ** call getPage() on page 1 again to make sure pPage1->aData is
    ** set correctly. */
    if( getPage(pBt, 1, &pPage1)==SQLITE_OK ){
      releasePage(pPage1);
    }
    assert( countWriteCursors(pBt)==0 );

  }









  pBt->inTrans = TRANS_NONE;
  pBt->inStmt = 0;
  unlockBtreeIfUnused(pBt);


  return rc;
}

/*
** Start a statement subtransaction.  The subtransaction can
** can be rolled back independently of the main transaction.
** You must start a transaction before starting a subtransaction.
** The subtransaction is ended automatically if the main transaction
** commits or rolls back.
**
** Only one subtransaction may be active at a time.  It is an error to try
** to start a new subtransaction if another subtransaction is already active.
**
** Statement subtransactions are used around individual SQL statements
** that are contained within a BEGIN...COMMIT block.  If a constraint
** error occurs within the statement, the effect of that one statement
** can be rolled back without having to rollback the entire transaction.
*/
int sqlite3BtreeBeginStmt(Btree *pBt){
  int rc;

  if( (pBt->inTrans!=TRANS_WRITE) || pBt->inStmt ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }

  rc = pBt->readOnly ? SQLITE_OK : sqlite3pager_stmt_begin(pBt->pPager);
  pBt->inStmt = 1;
  return rc;
}


/*
** Commit the statment subtransaction currently in progress.  If no
** subtransaction is active, this is a no-op.
*/
int sqlite3BtreeCommitStmt(Btree *pBt){
  int rc;

  if( pBt->inStmt && !pBt->readOnly ){
    rc = sqlite3pager_stmt_commit(pBt->pPager);
  }else{
    rc = SQLITE_OK;
  }
  pBt->inStmt = 0;
  return rc;
}

/*
** Rollback the active statement subtransaction.  If no subtransaction
** is active this routine is a no-op.
**
** All cursors will be invalidated by this operation.  Any attempt
** to use a cursor that was open at the beginning of this operation
** will result in an error.
*/
int sqlite3BtreeRollbackStmt(Btree *pBt){
  int rc;

  if( pBt->inStmt==0 || pBt->readOnly ) return SQLITE_OK;
  rc = sqlite3pager_stmt_rollback(pBt->pPager);
  assert( countWriteCursors(pBt)==0 );
  pBt->inStmt = 0;
  return rc;
}

2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717

2718
2719

2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732


2733
2734
2735
2736

2737
2738
2739
2740
2741

2742
2743
2744
2745
2746
2747
2748
** The comparison function must be logically the same for every cursor
** on a particular table.  Changing the comparison function will result
** in incorrect operations.  If the comparison function is NULL, a
** default comparison function is used.  The comparison function is
** always ignored for INTKEY tables.
*/
int sqlite3BtreeCursor(
  Btree *p,                                   /* The btree */
  int iTable,                                 /* Root page of table to open */
  int wrFlag,                                 /* 1 to write. 0 read-only */
  int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
  void *pArg,                                 /* First arg to xCompare() */
  BtCursor **ppCur                            /* Write new cursor here */
){
  int rc;
  BtCursor *pCur;
  BtShared *pBt = p->pBt;

  *ppCur = 0;
  if( wrFlag ){
    if( pBt->readOnly ){
      return SQLITE_READONLY;
    }
    if( checkReadLocks(pBt, iTable, 0) ){
      return SQLITE_LOCKED;
    }
  }

  if( pBt->pPage1==0 ){
    rc = lockBtreeWithRetry(p);
    if( rc!=SQLITE_OK ){
      return rc;
    }
  }
  pCur = sqliteMalloc( sizeof(*pCur) );
  if( pCur==0 ){
    rc = SQLITE_NOMEM;
    goto create_cursor_exception;
  }
  pCur->pgnoRoot = (Pgno)iTable;
  if( iTable==1 && sqlite3pager_pagecount(pBt->pPager)==0 ){
    rc = SQLITE_EMPTY;

    goto create_cursor_exception;
  }

  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->pPage, 0);
  if( rc!=SQLITE_OK ){
    goto create_cursor_exception;
  }

  /* Now that no other errors can occur, finish filling in the BtCursor
  ** variables, link the cursor into the BtShared list and set *ppCur (the
  ** output argument to this function).
  */
  pCur->xCompare = xCmp ? xCmp : dfltCompare;
  pCur->pArg = pArg;
  pCur->pBtree = p;
  pCur->wrFlag = wrFlag;


  pCur->pNext = pBt->pCursor;
  if( pCur->pNext ){
    pCur->pNext->pPrev = pCur;
  }

  pBt->pCursor = pCur;
  pCur->eState = CURSOR_INVALID;
  *ppCur = pCur;

  return SQLITE_OK;

create_cursor_exception:
  if( pCur ){
    releasePage(pCur->pPage);
    sqliteFree(pCur);
  }
  unlockBtreeIfUnused(pBt);
  return rc;







|








<










<

|




|







>


>




<
<
<
<
<


|

>
>




>

|

<

>







2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104

2105
2106
2107
2108
2109
2110
2111
2112
2113
2114

2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136





2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150

2151
2152
2153
2154
2155
2156
2157
2158
2159
** The comparison function must be logically the same for every cursor
** on a particular table.  Changing the comparison function will result
** in incorrect operations.  If the comparison function is NULL, a
** default comparison function is used.  The comparison function is
** always ignored for INTKEY tables.
*/
int sqlite3BtreeCursor(
  Btree *pBt,                                 /* The btree */
  int iTable,                                 /* Root page of table to open */
  int wrFlag,                                 /* 1 to write. 0 read-only */
  int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
  void *pArg,                                 /* First arg to xCompare() */
  BtCursor **ppCur                            /* Write new cursor here */
){
  int rc;
  BtCursor *pCur;


  *ppCur = 0;
  if( wrFlag ){
    if( pBt->readOnly ){
      return SQLITE_READONLY;
    }
    if( checkReadLocks(pBt, iTable, 0) ){
      return SQLITE_LOCKED;
    }
  }

  if( pBt->pPage1==0 ){
    rc = lockBtree(pBt);
    if( rc!=SQLITE_OK ){
      return rc;
    }
  }
  pCur = sqliteMallocRaw( sizeof(*pCur) );
  if( pCur==0 ){
    rc = SQLITE_NOMEM;
    goto create_cursor_exception;
  }
  pCur->pgnoRoot = (Pgno)iTable;
  if( iTable==1 && sqlite3pager_pagecount(pBt->pPager)==0 ){
    rc = SQLITE_EMPTY;
    pCur->pPage = 0;
    goto create_cursor_exception;
  }
  pCur->pPage = 0;  /* For exit-handler, in case getAndInitPage() fails. */
  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->pPage, 0);
  if( rc!=SQLITE_OK ){
    goto create_cursor_exception;
  }





  pCur->xCompare = xCmp ? xCmp : dfltCompare;
  pCur->pArg = pArg;
  pCur->pBt = pBt;
  pCur->wrFlag = wrFlag;
  pCur->idx = 0;
  memset(&pCur->info, 0, sizeof(pCur->info));
  pCur->pNext = pBt->pCursor;
  if( pCur->pNext ){
    pCur->pNext->pPrev = pCur;
  }
  pCur->pPrev = 0;
  pBt->pCursor = pCur;
  pCur->isValid = 0;
  *ppCur = pCur;

  return SQLITE_OK;

create_cursor_exception:
  if( pCur ){
    releasePage(pCur->pPage);
    sqliteFree(pCur);
  }
  unlockBtreeIfUnused(pBt);
  return rc;
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
#endif

/*
** Close a cursor.  The read lock on the database file is released
** when the last cursor is closed.
*/
int sqlite3BtreeCloseCursor(BtCursor *pCur){
  BtShared *pBt = pCur->pBtree->pBt;
  restoreOrClearCursorPosition(pCur, 0);
  if( pCur->pPrev ){
    pCur->pPrev->pNext = pCur->pNext;
  }else{
    pBt->pCursor = pCur->pNext;
  }
  if( pCur->pNext ){
    pCur->pNext->pPrev = pCur->pPrev;







|
<







2174
2175
2176
2177
2178
2179
2180
2181

2182
2183
2184
2185
2186
2187
2188
#endif

/*
** Close a cursor.  The read lock on the database file is released
** when the last cursor is closed.
*/
int sqlite3BtreeCloseCursor(BtCursor *pCur){
  Btree *pBt = pCur->pBt;

  if( pCur->pPrev ){
    pCur->pPrev->pNext = pCur->pNext;
  }else{
    pBt->pCursor = pCur->pNext;
  }
  if( pCur->pNext ){
    pCur->pNext->pPrev = pCur->pPrev;
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
** the key for the current entry.  If the cursor is not pointing
** to a valid entry, *pSize is set to 0. 
**
** For a table with the INTKEY flag set, this routine returns the key
** itself, not the number of bytes in the key.
*/
int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
  int rc = restoreOrClearCursorPosition(pCur, 1);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
    if( pCur->eState==CURSOR_INVALID ){
      *pSize = 0;
    }else{
      getCellInfo(pCur);
      *pSize = pCur->info.nKey;
    }
  }
  return rc;
}

/*
** Set *pSize to the number of bytes of data in the entry the
** cursor currently points to.  Always return SQLITE_OK.
** Failure is not possible.  If the cursor is not currently
** pointing to an entry (which can happen, for example, if
** the database is empty) then *pSize is set to 0.
*/
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
  int rc = restoreOrClearCursorPosition(pCur, 1);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
    if( pCur->eState==CURSOR_INVALID ){
      /* Not pointing at a valid entry - set *pSize to 0. */
      *pSize = 0;
    }else{
      getCellInfo(pCur);
      *pSize = pCur->info.nData;
    }
  }
  return rc;
}

/*
** Read payload information from the entry that the pCur cursor is
** pointing to.  Begin reading the payload at "offset" and read
** a total of "amt" bytes.  Put the result in zBuf.
**







<
<
<
|
|
|
|
|
|
<
|










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







2241
2242
2243
2244
2245
2246
2247



2248
2249
2250
2251
2252
2253

2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264



2265
2266
2267
2268
2269
2270
2271

2272
2273
2274
2275
2276
2277
2278
2279
** the key for the current entry.  If the cursor is not pointing
** to a valid entry, *pSize is set to 0. 
**
** For a table with the INTKEY flag set, this routine returns the key
** itself, not the number of bytes in the key.
*/
int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){



  if( !pCur->isValid ){
    *pSize = 0;
  }else{
    getCellInfo(pCur);
    *pSize = pCur->info.nKey;
  }

  return SQLITE_OK;
}

/*
** Set *pSize to the number of bytes of data in the entry the
** cursor currently points to.  Always return SQLITE_OK.
** Failure is not possible.  If the cursor is not currently
** pointing to an entry (which can happen, for example, if
** the database is empty) then *pSize is set to 0.
*/
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){



  if( !pCur->isValid ){
    /* Not pointing at a valid entry - set *pSize to 0. */
    *pSize = 0;
  }else{
    getCellInfo(pCur);
    *pSize = pCur->info.nData;
  }

  return SQLITE_OK;
}

/*
** Read payload information from the entry that the pCur cursor is
** pointing to.  Begin reading the payload at "offset" and read
** a total of "amt" bytes.  Put the result in zBuf.
**
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904

2905
2906
2907
2908
2909
2910
2911
  unsigned char *pBuf, /* Write the bytes into this buffer */ 
  int skipKey          /* offset begins at data if this is true */
){
  unsigned char *aPayload;
  Pgno nextPage;
  int rc;
  MemPage *pPage;
  BtShared *pBt;
  int ovflSize;
  u32 nKey;

  assert( pCur!=0 && pCur->pPage!=0 );
  assert( pCur->eState==CURSOR_VALID );
  pBt = pCur->pBtree->pBt;
  pPage = pCur->pPage;
  pageIntegrity(pPage);
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  getCellInfo(pCur);
  aPayload = pCur->info.pCell + pCur->info.nHeader;

  if( pPage->intKey ){
    nKey = 0;
  }else{
    nKey = pCur->info.nKey;
  }
  assert( offset>=0 );
  if( skipKey ){







|




|
|




|
>







2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
  unsigned char *pBuf, /* Write the bytes into this buffer */ 
  int skipKey          /* offset begins at data if this is true */
){
  unsigned char *aPayload;
  Pgno nextPage;
  int rc;
  MemPage *pPage;
  Btree *pBt;
  int ovflSize;
  u32 nKey;

  assert( pCur!=0 && pCur->pPage!=0 );
  assert( pCur->isValid );
  pBt = pCur->pBt;
  pPage = pCur->pPage;
  pageIntegrity(pPage);
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  getCellInfo(pCur);
  aPayload = pCur->info.pCell;
  aPayload += pCur->info.nHeader;
  if( pPage->intKey ){
    nKey = 0;
  }else{
    nKey = pCur->info.nKey;
  }
  assert( offset>=0 );
  if( skipKey ){
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
        offset -= ovflSize;
      }
      sqlite3pager_unref(aPayload);
    }
  }

  if( amt>0 ){
    return SQLITE_CORRUPT_BKPT;
  }
  return SQLITE_OK;
}

/*
** Read part of the key associated with cursor pCur.  Exactly
** "amt" bytes will be transfered into pBuf[].  The transfer
** begins at "offset".
**
** Return SQLITE_OK on success or an error code if anything goes
** wrong.  An error is returned if "offset+amt" is larger than
** the available payload.
*/
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
  int rc = restoreOrClearCursorPosition(pCur, 1);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_VALID );
    assert( pCur->pPage!=0 );
    if( pCur->pPage->intKey ){
      return SQLITE_CORRUPT_BKPT;
    }
    assert( pCur->pPage->intKey==0 );
    assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
    rc = getPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
  }
  return rc;
}

/*
** Read part of the data associated with cursor pCur.  Exactly
** "amt" bytes will be transfered into pBuf[].  The transfer
** begins at "offset".
**
** Return SQLITE_OK on success or an error code if anything goes
** wrong.  An error is returned if "offset+amt" is larger than
** the available payload.
*/
int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
  int rc = restoreOrClearCursorPosition(pCur, 1);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_VALID );
    assert( pCur->pPage!=0 );
    assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
    rc = getPayload(pCur, offset, amt, pBuf, 1);
  }
  return rc;
}

/*
** Return a pointer to payload information from the entry that the 
** pCur cursor is pointing to.  The pointer is to the beginning of
** the key if skipKey==0 and it points to the beginning of data if
** skipKey==1.  The number of bytes of available key/data is written







|














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












<
<
|
|
|
|
<
<







2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375


2376
2377



2378
2379
2380


2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392


2393
2394
2395
2396


2397
2398
2399
2400
2401
2402
2403
        offset -= ovflSize;
      }
      sqlite3pager_unref(aPayload);
    }
  }

  if( amt>0 ){
    return SQLITE_CORRUPT; /* bkpt-CORRUPT */
  }
  return SQLITE_OK;
}

/*
** Read part of the key associated with cursor pCur.  Exactly
** "amt" bytes will be transfered into pBuf[].  The transfer
** begins at "offset".
**
** Return SQLITE_OK on success or an error code if anything goes
** wrong.  An error is returned if "offset+amt" is larger than
** the available payload.
*/
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){


  assert( pCur->isValid );
  assert( pCur->pPage!=0 );



  assert( pCur->pPage->intKey==0 );
  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  return getPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);


}

/*
** Read part of the data associated with cursor pCur.  Exactly
** "amt" bytes will be transfered into pBuf[].  The transfer
** begins at "offset".
**
** Return SQLITE_OK on success or an error code if anything goes
** wrong.  An error is returned if "offset+amt" is larger than
** the available payload.
*/
int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){


  assert( pCur->isValid );
  assert( pCur->pPage!=0 );
  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  return getPayload(pCur, offset, amt, pBuf, 1);


}

/*
** Return a pointer to payload information from the entry that the 
** pCur cursor is pointing to.  The pointer is to the beginning of
** the key if skipKey==0 and it points to the beginning of data if
** skipKey==1.  The number of bytes of available key/data is written
3026
3027
3028
3029
3030
3031
3032

3033
3034
3035
3036
3037

3038
3039
3040
3041
3042
3043
3044
static const unsigned char *fetchPayload(
  BtCursor *pCur,      /* Cursor pointing to entry to read from */
  int *pAmt,           /* Write the number of available bytes here */
  int skipKey          /* read beginning at data if this is true */
){
  unsigned char *aPayload;
  MemPage *pPage;

  u32 nKey;
  int nLocal;

  assert( pCur!=0 && pCur->pPage!=0 );
  assert( pCur->eState==CURSOR_VALID );

  pPage = pCur->pPage;
  pageIntegrity(pPage);
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  getCellInfo(pCur);
  aPayload = pCur->info.pCell;
  aPayload += pCur->info.nHeader;
  if( pPage->intKey ){







>




|
>







2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
static const unsigned char *fetchPayload(
  BtCursor *pCur,      /* Cursor pointing to entry to read from */
  int *pAmt,           /* Write the number of available bytes here */
  int skipKey          /* read beginning at data if this is true */
){
  unsigned char *aPayload;
  MemPage *pPage;
  Btree *pBt;
  u32 nKey;
  int nLocal;

  assert( pCur!=0 && pCur->pPage!=0 );
  assert( pCur->isValid );
  pBt = pCur->pBt;
  pPage = pCur->pPage;
  pageIntegrity(pPage);
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  getCellInfo(pCur);
  aPayload = pCur->info.pCell;
  aPayload += pCur->info.nHeader;
  if( pPage->intKey ){
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
** The pointer returned is ephemeral.  The key/data may move
** or be destroyed on the next call to any Btree routine.
**
** These routines is used to get quick access to key and data
** in the common case where no overflow pages are used.
*/
const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
  if( pCur->eState==CURSOR_VALID ){
    return (const void*)fetchPayload(pCur, pAmt, 0);
  }
  return 0;
}
const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
  if( pCur->eState==CURSOR_VALID ){
    return (const void*)fetchPayload(pCur, pAmt, 1);
  }
  return 0;
}


/*
** Move the cursor down to a new child page.  The newPgno argument is the
** page number of the child page to move to.
*/
static int moveToChild(BtCursor *pCur, u32 newPgno){
  int rc;
  MemPage *pNewPage;
  MemPage *pOldPage;
  BtShared *pBt = pCur->pBtree->pBt;

  assert( pCur->eState==CURSOR_VALID );
  rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage);
  if( rc ) return rc;
  pageIntegrity(pNewPage);
  pNewPage->idxParent = pCur->idx;
  pOldPage = pCur->pPage;
  pOldPage->idxShift = 0;
  releasePage(pOldPage);
  pCur->pPage = pNewPage;
  pCur->idx = 0;
  pCur->info.nSize = 0;
  if( pNewPage->nCell<1 ){
    return SQLITE_CORRUPT_BKPT;
  }
  return SQLITE_OK;
}

/*
** Return true if the page is the virtual root of its table.
**







<
|
|
<
<

<
|
<
<











|

|











|







2462
2463
2464
2465
2466
2467
2468

2469
2470


2471

2472


2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
** The pointer returned is ephemeral.  The key/data may move
** or be destroyed on the next call to any Btree routine.
**
** These routines is used to get quick access to key and data
** in the common case where no overflow pages are used.
*/
const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){

  return (const void*)fetchPayload(pCur, pAmt, 0);
}


const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){

  return (const void*)fetchPayload(pCur, pAmt, 1);


}


/*
** Move the cursor down to a new child page.  The newPgno argument is the
** page number of the child page to move to.
*/
static int moveToChild(BtCursor *pCur, u32 newPgno){
  int rc;
  MemPage *pNewPage;
  MemPage *pOldPage;
  Btree *pBt = pCur->pBt;

  assert( pCur->isValid );
  rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage);
  if( rc ) return rc;
  pageIntegrity(pNewPage);
  pNewPage->idxParent = pCur->idx;
  pOldPage = pCur->pPage;
  pOldPage->idxShift = 0;
  releasePage(pOldPage);
  pCur->pPage = pNewPage;
  pCur->idx = 0;
  pCur->info.nSize = 0;
  if( pNewPage->nCell<1 ){
    return SQLITE_CORRUPT; /* bkpt-CORRUPT */
  }
  return SQLITE_OK;
}

/*
** Return true if the page is the virtual root of its table.
**
3134
3135
3136
3137
3138
3139
3140

3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154

3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
**
** pCur->idx is set to the cell index that contains the pointer
** to the page we are coming from.  If we are coming from the
** right-most child page then pCur->idx is set to one more than
** the largest cell index.
*/
static void moveToParent(BtCursor *pCur){

  MemPage *pParent;
  MemPage *pPage;
  int idxParent;

  assert( pCur->eState==CURSOR_VALID );
  pPage = pCur->pPage;
  assert( pPage!=0 );
  assert( !isRootPage(pPage) );
  pageIntegrity(pPage);
  pParent = pPage->pParent;
  assert( pParent!=0 );
  pageIntegrity(pParent);
  idxParent = pPage->idxParent;
  sqlite3pager_ref(pParent->aData);

  releasePage(pPage);
  pCur->pPage = pParent;
  pCur->info.nSize = 0;
  assert( pParent->idxShift==0 );
  pCur->idx = idxParent;
}

/*
** Move the cursor to the root page
*/
static int moveToRoot(BtCursor *pCur){
  MemPage *pRoot;
  int rc = SQLITE_OK;
  BtShared *pBt = pCur->pBtree->pBt;

  restoreOrClearCursorPosition(pCur, 0);
  assert( pCur->pPage );
  pRoot = pCur->pPage;
  if( pRoot->pgno==pCur->pgnoRoot ){
    assert( pRoot->isInit );
  }else{
    if( 
      SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0))
    ){
      pCur->eState = CURSOR_INVALID;
      return rc;
    }
    releasePage(pCur->pPage);
    pageIntegrity(pRoot);
    pCur->pPage = pRoot;
  }
  pCur->idx = 0;
  pCur->info.nSize = 0;
  if( pRoot->nCell==0 && !pRoot->leaf ){
    Pgno subpage;
    assert( pRoot->pgno==1 );
    subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
    assert( subpage>0 );
    pCur->eState = CURSOR_VALID;
    rc = moveToChild(pCur, subpage);
  }
  pCur->eState = ((pCur->pPage->nCell>0)?CURSOR_VALID:CURSOR_INVALID);
  return rc;
}

/*
** Move the cursor down to the left-most leaf entry beneath the
** entry to which it is currently pointing.
**
** The left-most leaf is the one with the smallest key - the first
** in ascending order.
*/
static int moveToLeftmost(BtCursor *pCur){
  Pgno pgno;
  int rc;
  MemPage *pPage;

  assert( pCur->eState==CURSOR_VALID );
  while( !(pPage = pCur->pPage)->leaf ){
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
    pgno = get4byte(findCell(pPage, pCur->idx));
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
  }
  return SQLITE_OK;
}

/*
** Move the cursor down to the right-most leaf entry beneath the
** page to which it is currently pointing.  Notice the difference
** between moveToLeftmost() and moveToRightmost().  moveToLeftmost()
** finds the left-most entry beneath the *entry* whereas moveToRightmost()
** finds the right-most entry beneath the *page*.
**
** The right-most entry is the one with the largest key - the last
** key in ascending order.
*/
static int moveToRightmost(BtCursor *pCur){
  Pgno pgno;
  int rc;
  MemPage *pPage;

  assert( pCur->eState==CURSOR_VALID );
  while( !(pPage = pCur->pPage)->leaf ){
    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    pCur->idx = pPage->nCell;
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
  }
  pCur->idx = pPage->nCell - 1;
  pCur->info.nSize = 0;
  return SQLITE_OK;
}

/* Move the cursor to the first entry in the table.  Return SQLITE_OK
** on success.  Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
*/
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
  int rc;
  rc = moveToRoot(pCur);
  if( rc ) return rc;
  if( pCur->eState==CURSOR_INVALID ){
    assert( pCur->pPage->nCell==0 );
    *pRes = 1;
    return SQLITE_OK;
  }
  assert( pCur->pPage->nCell>0 );
  *pRes = 0;
  rc = moveToLeftmost(pCur);
  return rc;
}

/* Move the cursor to the last entry in the table.  Return SQLITE_OK
** on success.  Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
*/
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  int rc;
  rc = moveToRoot(pCur);
  if( rc ) return rc;
  if( CURSOR_INVALID==pCur->eState ){
    assert( pCur->pPage->nCell==0 );
    *pRes = 1;
    return SQLITE_OK;
  }
  assert( pCur->eState==CURSOR_VALID );
  *pRes = 0;
  rc = moveToRightmost(pCur);
  return rc;
}

/* Move the cursor so that it points to an entry near pKey/nKey.
** Return a success code.
**
** For INTKEY tables, only the nKey parameter is used.  pKey is
** ignored.  For other tables, nKey is the number of bytes of data
** in pKey.  The comparison function specified when the cursor was
** created is used to compare keys.
**
** If an exact match is not found, then the cursor is always
** left pointing at a leaf page which would hold the entry if it
** were present.  The cursor might point to an entry that comes
** before or after the key.
**







>




|









>












|
|

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







|


|






<
<
<






|















<
<
<






|



















|


















|




|










|







2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559







2560
2561
2562
2563
2564
2565
2566
2567

2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584



2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606



2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
**
** pCur->idx is set to the cell index that contains the pointer
** to the page we are coming from.  If we are coming from the
** right-most child page then pCur->idx is set to one more than
** the largest cell index.
*/
static void moveToParent(BtCursor *pCur){
  Pgno oldPgno;
  MemPage *pParent;
  MemPage *pPage;
  int idxParent;

  assert( pCur->isValid );
  pPage = pCur->pPage;
  assert( pPage!=0 );
  assert( !isRootPage(pPage) );
  pageIntegrity(pPage);
  pParent = pPage->pParent;
  assert( pParent!=0 );
  pageIntegrity(pParent);
  idxParent = pPage->idxParent;
  sqlite3pager_ref(pParent->aData);
  oldPgno = pPage->pgno;
  releasePage(pPage);
  pCur->pPage = pParent;
  pCur->info.nSize = 0;
  assert( pParent->idxShift==0 );
  pCur->idx = idxParent;
}

/*
** Move the cursor to the root page
*/
static int moveToRoot(BtCursor *pCur){
  MemPage *pRoot;
  int rc;
  Btree *pBt = pCur->pBt;








  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0);
  if( rc ){
    pCur->isValid = 0;
    return rc;
  }
  releasePage(pCur->pPage);
  pageIntegrity(pRoot);
  pCur->pPage = pRoot;

  pCur->idx = 0;
  pCur->info.nSize = 0;
  if( pRoot->nCell==0 && !pRoot->leaf ){
    Pgno subpage;
    assert( pRoot->pgno==1 );
    subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
    assert( subpage>0 );
    pCur->isValid = 1;
    rc = moveToChild(pCur, subpage);
  }
  pCur->isValid = pCur->pPage->nCell>0;
  return rc;
}

/*
** Move the cursor down to the left-most leaf entry beneath the
** entry to which it is currently pointing.



*/
static int moveToLeftmost(BtCursor *pCur){
  Pgno pgno;
  int rc;
  MemPage *pPage;

  assert( pCur->isValid );
  while( !(pPage = pCur->pPage)->leaf ){
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
    pgno = get4byte(findCell(pPage, pCur->idx));
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
  }
  return SQLITE_OK;
}

/*
** Move the cursor down to the right-most leaf entry beneath the
** page to which it is currently pointing.  Notice the difference
** between moveToLeftmost() and moveToRightmost().  moveToLeftmost()
** finds the left-most entry beneath the *entry* whereas moveToRightmost()
** finds the right-most entry beneath the *page*.



*/
static int moveToRightmost(BtCursor *pCur){
  Pgno pgno;
  int rc;
  MemPage *pPage;

  assert( pCur->isValid );
  while( !(pPage = pCur->pPage)->leaf ){
    pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    pCur->idx = pPage->nCell;
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
  }
  pCur->idx = pPage->nCell - 1;
  pCur->info.nSize = 0;
  return SQLITE_OK;
}

/* Move the cursor to the first entry in the table.  Return SQLITE_OK
** on success.  Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
*/
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
  int rc;
  rc = moveToRoot(pCur);
  if( rc ) return rc;
  if( pCur->isValid==0 ){
    assert( pCur->pPage->nCell==0 );
    *pRes = 1;
    return SQLITE_OK;
  }
  assert( pCur->pPage->nCell>0 );
  *pRes = 0;
  rc = moveToLeftmost(pCur);
  return rc;
}

/* Move the cursor to the last entry in the table.  Return SQLITE_OK
** on success.  Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
*/
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  int rc;
  rc = moveToRoot(pCur);
  if( rc ) return rc;
  if( pCur->isValid==0 ){
    assert( pCur->pPage->nCell==0 );
    *pRes = 1;
    return SQLITE_OK;
  }
  assert( pCur->isValid );
  *pRes = 0;
  rc = moveToRightmost(pCur);
  return rc;
}

/* Move the cursor so that it points to an entry near pKey/nKey.
** Return a success code.
**
** For INTKEY tables, only the nKey parameter is used.  pKey is
** ignored.  For other tables, nKey is the number of bytes of data
** in nKey.  The comparison function specified when the cursor was
** created is used to compare keys.
**
** If an exact match is not found, then the cursor is always
** left pointing at a leaf page which would hold the entry if it
** were present.  The cursor might point to an entry that comes
** before or after the key.
**
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342

3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
**                  exactly matches pKey.
**
**     *pRes>0      The cursor is left pointing at an entry that
**                  is larger than pKey.
*/
int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
  int rc;
  int tryRightmost;
  rc = moveToRoot(pCur);
  if( rc ) return rc;
  assert( pCur->pPage );
  assert( pCur->pPage->isInit );
  tryRightmost = pCur->pPage->intKey;
  if( pCur->eState==CURSOR_INVALID ){
    *pRes = -1;
    assert( pCur->pPage->nCell==0 );
    return SQLITE_OK;
  }
   for(;;){
    int lwr, upr;
    Pgno chldPg;
    MemPage *pPage = pCur->pPage;
    int c = -1;  /* pRes return if table is empty must be -1 */
    lwr = 0;
    upr = pPage->nCell-1;
    if( !pPage->intKey && pKey==0 ){
      return SQLITE_CORRUPT_BKPT;
    }
    pageIntegrity(pPage);
    while( lwr<=upr ){
      void *pCellKey;
      i64 nCellKey;
      pCur->idx = (lwr+upr)/2;
      pCur->info.nSize = 0;

      if( pPage->intKey ){
        u8 *pCell;
        if( tryRightmost ){
          pCur->idx = upr;
        }
        pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize;
        if( pPage->hasData ){
          int dummy;
          pCell += getVarint32(pCell, &dummy);
        }
        getVarint(pCell, &nCellKey);
        if( nCellKey<nKey ){
          c = -1;
        }else if( nCellKey>nKey ){
          c = +1;
          tryRightmost = 0;
        }else{
          c = 0;
        }
      }else{
        int available;
        pCellKey = (void *)fetchPayload(pCur, &available, 0);
        nCellKey = pCur->info.nKey;
        if( available>=nCellKey ){
          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
        }else{
          pCellKey = sqliteMallocRaw( nCellKey );
          if( pCellKey==0 ) return SQLITE_NOMEM;
          rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey);
          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);







<




<
|












|







>

<
<
<
<
<
<
<
<
<
<




<






<







2685
2686
2687
2688
2689
2690
2691

2692
2693
2694
2695

2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718










2719
2720
2721
2722

2723
2724
2725
2726
2727
2728

2729
2730
2731
2732
2733
2734
2735
**                  exactly matches pKey.
**
**     *pRes>0      The cursor is left pointing at an entry that
**                  is larger than pKey.
*/
int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
  int rc;

  rc = moveToRoot(pCur);
  if( rc ) return rc;
  assert( pCur->pPage );
  assert( pCur->pPage->isInit );

  if( pCur->isValid==0 ){
    *pRes = -1;
    assert( pCur->pPage->nCell==0 );
    return SQLITE_OK;
  }
   for(;;){
    int lwr, upr;
    Pgno chldPg;
    MemPage *pPage = pCur->pPage;
    int c = -1;  /* pRes return if table is empty must be -1 */
    lwr = 0;
    upr = pPage->nCell-1;
    if( !pPage->intKey && pKey==0 ){
      return SQLITE_CORRUPT;
    }
    pageIntegrity(pPage);
    while( lwr<=upr ){
      void *pCellKey;
      i64 nCellKey;
      pCur->idx = (lwr+upr)/2;
      pCur->info.nSize = 0;
      sqlite3BtreeKeySize(pCur, &nCellKey);
      if( pPage->intKey ){










        if( nCellKey<nKey ){
          c = -1;
        }else if( nCellKey>nKey ){
          c = +1;

        }else{
          c = 0;
        }
      }else{
        int available;
        pCellKey = (void *)fetchPayload(pCur, &available, 0);

        if( available>=nCellKey ){
          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
        }else{
          pCellKey = sqliteMallocRaw( nCellKey );
          if( pCellKey==0 ) return SQLITE_NOMEM;
          rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey);
          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
** Return TRUE if the cursor is not pointing at an entry of the table.
**
** TRUE will be returned after a call to sqlite3BtreeNext() moves
** past the last entry in the table or sqlite3BtreePrev() moves past
** the first entry.  TRUE is also returned if the table is empty.
*/
int sqlite3BtreeEof(BtCursor *pCur){
  /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries
  ** have been deleted? This API will need to change to return an error code
  ** as well as the boolean result value.
  */
  return (CURSOR_VALID!=pCur->eState);
}

/*
** Advance the cursor to the next entry in the database.  If
** successful then set *pRes=0.  If the cursor
** was already pointing to the last entry in the database before
** this routine was called, then set *pRes=1.
*/
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
  int rc;
  MemPage *pPage = pCur->pPage;

#ifndef SQLITE_OMIT_SHARED_CACHE
  rc = restoreOrClearCursorPosition(pCur, 1);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  if( pCur->skip>0 ){
    pCur->skip = 0;
    *pRes = 0;
    return SQLITE_OK;
  }
  pCur->skip = 0;
#endif

  assert( pRes!=0 );
  if( CURSOR_INVALID==pCur->eState ){
    *pRes = 1;
    return SQLITE_OK;
  }
  assert( pPage->isInit );
  assert( pCur->idx<pPage->nCell );

  pCur->idx++;
  pCur->info.nSize = 0;
  if( pCur->idx>=pPage->nCell ){
    if( !pPage->leaf ){
      rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
      if( rc ) return rc;
      rc = moveToLeftmost(pCur);
      *pRes = 0;
      return rc;
    }
    do{
      if( isRootPage(pPage) ){
        *pRes = 1;
        pCur->eState = CURSOR_INVALID;
        return SQLITE_OK;
      }
      moveToParent(pCur);
      pPage = pCur->pPage;
    }while( pCur->idx>=pPage->nCell );
    *pRes = 0;
    if( pPage->leafData ){







<
<
<
<
|












<
<
<
<
<
<
<
<
<
<
<
<
<

|



















|







2781
2782
2783
2784
2785
2786
2787




2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800













2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
** Return TRUE if the cursor is not pointing at an entry of the table.
**
** TRUE will be returned after a call to sqlite3BtreeNext() moves
** past the last entry in the table or sqlite3BtreePrev() moves past
** the first entry.  TRUE is also returned if the table is empty.
*/
int sqlite3BtreeEof(BtCursor *pCur){




  return pCur->isValid==0;
}

/*
** Advance the cursor to the next entry in the database.  If
** successful then set *pRes=0.  If the cursor
** was already pointing to the last entry in the database before
** this routine was called, then set *pRes=1.
*/
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
  int rc;
  MemPage *pPage = pCur->pPage;














  assert( pRes!=0 );
  if( pCur->isValid==0 ){
    *pRes = 1;
    return SQLITE_OK;
  }
  assert( pPage->isInit );
  assert( pCur->idx<pPage->nCell );

  pCur->idx++;
  pCur->info.nSize = 0;
  if( pCur->idx>=pPage->nCell ){
    if( !pPage->leaf ){
      rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
      if( rc ) return rc;
      rc = moveToLeftmost(pCur);
      *pRes = 0;
      return rc;
    }
    do{
      if( isRootPage(pPage) ){
        *pRes = 1;
        pCur->isValid = 0;
        return SQLITE_OK;
      }
      moveToParent(pCur);
      pPage = pCur->pPage;
    }while( pCur->idx>=pPage->nCell );
    *pRes = 0;
    if( pPage->leafData ){
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
** was already pointing to the first entry in the database before
** this routine was called, then set *pRes=1.
*/
int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
  int rc;
  Pgno pgno;
  MemPage *pPage;

#ifndef SQLITE_OMIT_SHARED_CACHE
  rc = restoreOrClearCursorPosition(pCur, 1);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  if( pCur->skip<0 ){
    pCur->skip = 0;
    *pRes = 0;
    return SQLITE_OK;
  }
  pCur->skip = 0;
#endif

  if( CURSOR_INVALID==pCur->eState ){
    *pRes = 1;
    return SQLITE_OK;
  }

  pPage = pCur->pPage;
  assert( pPage->isInit );
  assert( pCur->idx>=0 );
  if( !pPage->leaf ){
    pgno = get4byte( findCell(pPage, pCur->idx) );
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
    rc = moveToRightmost(pCur);
  }else{
    while( pCur->idx==0 ){
      if( isRootPage(pPage) ){
        pCur->eState = CURSOR_INVALID;
        *pRes = 1;
        return SQLITE_OK;
      }
      moveToParent(pCur);
      pPage = pCur->pPage;
    }
    pCur->idx--;







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















|







2847
2848
2849
2850
2851
2852
2853






2854








2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
** was already pointing to the first entry in the database before
** this routine was called, then set *pRes=1.
*/
int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
  int rc;
  Pgno pgno;
  MemPage *pPage;






  if( pCur->isValid==0 ){








    *pRes = 1;
    return SQLITE_OK;
  }

  pPage = pCur->pPage;
  assert( pPage->isInit );
  assert( pCur->idx>=0 );
  if( !pPage->leaf ){
    pgno = get4byte( findCell(pPage, pCur->idx) );
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
    rc = moveToRightmost(pCur);
  }else{
    while( pCur->idx==0 ){
      if( isRootPage(pPage) ){
        pCur->isValid = 0;
        *pRes = 1;
        return SQLITE_OK;
      }
      moveToParent(pCur);
      pPage = pCur->pPage;
    }
    pCur->idx--;
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
** which in turn can make database access faster.
**
** If the "exact" parameter is not 0, and the page-number nearby exists 
** anywhere on the free-list, then it is guarenteed to be returned. This
** is only used by auto-vacuum databases when allocating a new table.
*/
static int allocatePage(
  BtShared *pBt, 
  MemPage **ppPage, 
  Pgno *pPgno, 
  Pgno nearby,
  u8 exact
){
  MemPage *pPage1;
  int rc;







|







2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
** which in turn can make database access faster.
**
** If the "exact" parameter is not 0, and the page-number nearby exists 
** anywhere on the free-list, then it is guarenteed to be returned. This
** is only used by auto-vacuum databases when allocating a new table.
*/
static int allocatePage(
  Btree *pBt, 
  MemPage **ppPage, 
  Pgno *pPgno, 
  Pgno nearby,
  u8 exact
){
  MemPage *pPage1;
  int rc;
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
        *pPgno = iTrunk;
        memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
        *ppPage = pTrunk;
        pTrunk = 0;
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
      }else if( k>pBt->usableSize/4 - 8 ){
        /* Value of k is out of range.  Database corruption */
        return SQLITE_CORRUPT_BKPT;
#ifndef SQLITE_OMIT_AUTOVACUUM
      }else if( searchList && nearby==iTrunk ){
        /* The list is being searched and this trunk page is the page
        ** to allocate, regardless of whether it has leaves.
        */
        assert( *pPgno==iTrunk );
        *ppPage = pTrunk;







|







2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
        *pPgno = iTrunk;
        memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
        *ppPage = pTrunk;
        pTrunk = 0;
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
      }else if( k>pBt->usableSize/4 - 8 ){
        /* Value of k is out of range.  Database corruption */
        return SQLITE_CORRUPT; /* bkpt-CORRUPT */
#ifndef SQLITE_OMIT_AUTOVACUUM
      }else if( searchList && nearby==iTrunk ){
        /* The list is being searched and this trunk page is the page
        ** to allocate, regardless of whether it has leaves.
        */
        assert( *pPgno==iTrunk );
        *ppPage = pTrunk;
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
        }

        iPage = get4byte(&aData[8+closest*4]);
        if( !searchList || iPage==nearby ){
          *pPgno = iPage;
          if( *pPgno>sqlite3pager_pagecount(pBt->pPager) ){
            /* Free page off the end of the file */
            return SQLITE_CORRUPT_BKPT;
          }
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
                 ": %d more free pages\n",
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }







|







3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
        }

        iPage = get4byte(&aData[8+closest*4]);
        if( !searchList || iPage==nearby ){
          *pPgno = iPage;
          if( *pPgno>sqlite3pager_pagecount(pBt->pPager) ){
            /* Free page off the end of the file */
            return SQLITE_CORRUPT; /* bkpt-CORRUPT */
          }
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
                 ": %d more free pages\n",
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          if( closest<k-1 ){
            memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
          }
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804

/*
** Add a page of the database file to the freelist.
**
** sqlite3pager_unref() is NOT called for pPage.
*/
static int freePage(MemPage *pPage){
  BtShared *pBt = pPage->pBt;
  MemPage *pPage1 = pBt->pPage1;
  int rc, n, k;

  /* Prepare the page for freeing */
  assert( pPage->pgno>1 );
  pPage->isInit = 0;
  releasePage(pPage->pParent);







|







3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136

/*
** Add a page of the database file to the freelist.
**
** sqlite3pager_unref() is NOT called for pPage.
*/
static int freePage(MemPage *pPage){
  Btree *pBt = pPage->pBt;
  MemPage *pPage1 = pBt->pPage1;
  int rc, n, k;

  /* Prepare the page for freeing */
  assert( pPage->pgno>1 );
  pPage->isInit = 0;
  releasePage(pPage->pParent);
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885

3886
3887
3888
3889
3890
3891
3892
  return rc;
}

/*
** Free any overflow pages associated with the given Cell.
*/
static int clearCell(MemPage *pPage, unsigned char *pCell){
  BtShared *pBt = pPage->pBt;
  CellInfo info;
  Pgno ovflPgno;
  int rc;

  parseCellPtr(pPage, pCell, &info);
  if( info.iOverflow==0 ){
    return SQLITE_OK;  /* No overflow pages. Return without doing anything */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);
  while( ovflPgno!=0 ){
    MemPage *pOvfl;
    if( ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){
      return SQLITE_CORRUPT_BKPT;
    }
    rc = getPage(pBt, ovflPgno, &pOvfl);
    if( rc ) return rc;
    ovflPgno = get4byte(pOvfl->aData);
    rc = freePage(pOvfl);
    sqlite3pager_unref(pOvfl->aData);
    if( rc ) return rc;

  }
  return SQLITE_OK;
}

/*
** Create the byte sequence used to represent a cell on page pPage
** and write that byte sequence into pCell[].  Overflow pages are







|












|





<

>







3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215

3216
3217
3218
3219
3220
3221
3222
3223
3224
  return rc;
}

/*
** Free any overflow pages associated with the given Cell.
*/
static int clearCell(MemPage *pPage, unsigned char *pCell){
  Btree *pBt = pPage->pBt;
  CellInfo info;
  Pgno ovflPgno;
  int rc;

  parseCellPtr(pPage, pCell, &info);
  if( info.iOverflow==0 ){
    return SQLITE_OK;  /* No overflow pages. Return without doing anything */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);
  while( ovflPgno!=0 ){
    MemPage *pOvfl;
    if( ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){
      return SQLITE_CORRUPT;
    }
    rc = getPage(pBt, ovflPgno, &pOvfl);
    if( rc ) return rc;
    ovflPgno = get4byte(pOvfl->aData);
    rc = freePage(pOvfl);

    if( rc ) return rc;
    sqlite3pager_unref(pOvfl->aData);
  }
  return SQLITE_OK;
}

/*
** Create the byte sequence used to represent a cell on page pPage
** and write that byte sequence into pCell[].  Overflow pages are
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
  const u8 *pSrc;
  int nSrc, n, rc;
  int spaceLeft;
  MemPage *pOvfl = 0;
  MemPage *pToRelease = 0;
  unsigned char *pPrior;
  unsigned char *pPayload;
  BtShared *pBt = pPage->pBt;
  Pgno pgnoOvfl = 0;
  int nHeader;
  CellInfo info;

  /* Fill in the header. */
  nHeader = 0;
  if( !pPage->leaf ){







|







3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
  const u8 *pSrc;
  int nSrc, n, rc;
  int spaceLeft;
  MemPage *pOvfl = 0;
  MemPage *pToRelease = 0;
  unsigned char *pPrior;
  unsigned char *pPayload;
  Btree *pBt = pPage->pBt;
  Pgno pgnoOvfl = 0;
  int nHeader;
  CellInfo info;

  /* Fill in the header. */
  nHeader = 0;
  if( !pPage->leaf ){
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
}

/*
** Change the MemPage.pParent pointer on the page whose number is
** given in the second argument so that MemPage.pParent holds the
** pointer in the third argument.
*/
static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){
  MemPage *pThis;
  unsigned char *aData;

  if( pgno==0 ) return SQLITE_OK;
  assert( pBt->pPager!=0 );
  aData = sqlite3pager_lookup(pBt->pPager, pgno);
  if( aData ){
    pThis = (MemPage*)&aData[pBt->pageSize];
    assert( pThis->aData==aData );
    if( pThis->isInit ){
      if( pThis->pParent!=pNewParent ){
        if( pThis->pParent ) sqlite3pager_unref(pThis->pParent->aData);
        pThis->pParent = pNewParent;
        if( pNewParent ) sqlite3pager_ref(pNewParent->aData);
      }







|







|







3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
}

/*
** Change the MemPage.pParent pointer on the page whose number is
** given in the second argument so that MemPage.pParent holds the
** pointer in the third argument.
*/
static int reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){
  MemPage *pThis;
  unsigned char *aData;

  if( pgno==0 ) return SQLITE_OK;
  assert( pBt->pPager!=0 );
  aData = sqlite3pager_lookup(pBt->pPager, pgno);
  if( aData ){
    pThis = (MemPage*)&aData[pBt->psAligned];
    assert( pThis->aData==aData );
    if( pThis->isInit ){
      if( pThis->pParent!=pNewParent ){
        if( pThis->pParent ) sqlite3pager_unref(pThis->pParent->aData);
        pThis->pParent = pNewParent;
        if( pNewParent ) sqlite3pager_ref(pNewParent->aData);
      }
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
** to make sure that each child knows that pPage is its parent.
**
** This routine gets called after you memcpy() one page into
** another.
*/
static int reparentChildPages(MemPage *pPage){
  int i;
  BtShared *pBt = pPage->pBt;
  int rc = SQLITE_OK;

  if( pPage->leaf ) return SQLITE_OK;

  for(i=0; i<pPage->nCell; i++){
    u8 *pCell = findCell(pPage, i);
    if( !pPage->leaf ){







|







3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
** to make sure that each child knows that pPage is its parent.
**
** This routine gets called after you memcpy() one page into
** another.
*/
static int reparentChildPages(MemPage *pPage){
  int i;
  Btree *pBt = pPage->pBt;
  int rc = SQLITE_OK;

  if( pPage->leaf ) return SQLITE_OK;

  for(i=0; i<pPage->nCell; i++){
    u8 *pCell = findCell(pPage, i);
    if( !pPage->leaf ){
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
    data = pPage->aData;
    hdr = pPage->hdrOffset;
    top = get2byte(&data[hdr+5]);
    cellOffset = pPage->cellOffset;
    end = cellOffset + 2*pPage->nCell + 2;
    ins = cellOffset + 2*i;
    if( end > top - sz ){
      int rc = defragmentPage(pPage);
      if( rc!=SQLITE_OK ) return rc;
      top = get2byte(&data[hdr+5]);
      assert( end + sz <= top );
    }
    idx = allocateSpace(pPage, sz);
    assert( idx>0 );
    assert( end <= get2byte(&data[hdr+5]) );
    pPage->nCell++;







|
<







3482
3483
3484
3485
3486
3487
3488
3489

3490
3491
3492
3493
3494
3495
3496
    data = pPage->aData;
    hdr = pPage->hdrOffset;
    top = get2byte(&data[hdr+5]);
    cellOffset = pPage->cellOffset;
    end = cellOffset + 2*pPage->nCell + 2;
    ins = cellOffset + 2*i;
    if( end > top - sz ){
      defragmentPage(pPage);

      top = get2byte(&data[hdr+5]);
      assert( end + sz <= top );
    }
    idx = allocateSpace(pPage, sz);
    assert( idx>0 );
    assert( end <= get2byte(&data[hdr+5]) );
    pPage->nCell++;
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
  }
  assert( totalSize+2*nCell<=pPage->nFree );
  assert( pPage->nCell==0 );
  cellptr = pPage->cellOffset;
  data = pPage->aData;
  hdr = pPage->hdrOffset;
  put2byte(&data[hdr+3], nCell);
  if( nCell ){
    cellbody = allocateSpace(pPage, totalSize);
    assert( cellbody>0 );
    assert( pPage->nFree >= 2*nCell );
    pPage->nFree -= 2*nCell;
    for(i=0; i<nCell; i++){
      put2byte(&data[cellptr], cellbody);
      memcpy(&data[cellbody], apCell[i], aSize[i]);
      cellptr += 2;
      cellbody += aSize[i];
    }
    assert( cellbody==pPage->pBt->usableSize );
  }
  pPage->nCell = nCell;
}

/*
** The following parameters determine how many adjacent pages get involved
** in a balancing operation.  NN is the number of neighbors on either side
** of the page that participate in the balancing operation.  NB is the







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







3547
3548
3549
3550
3551
3552
3553

3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564

3565
3566
3567
3568
3569
3570
3571
  }
  assert( totalSize+2*nCell<=pPage->nFree );
  assert( pPage->nCell==0 );
  cellptr = pPage->cellOffset;
  data = pPage->aData;
  hdr = pPage->hdrOffset;
  put2byte(&data[hdr+3], nCell);

  cellbody = allocateSpace(pPage, totalSize);
  assert( cellbody>0 );
  assert( pPage->nFree >= 2*nCell );
  pPage->nFree -= 2*nCell;
  for(i=0; i<nCell; i++){
    put2byte(&data[cellptr], cellbody);
    memcpy(&data[cellbody], apCell[i], aSize[i]);
    cellptr += 2;
    cellbody += aSize[i];
  }
  assert( cellbody==pPage->pBt->usableSize );

  pPage->nCell = nCell;
}

/*
** The following parameters determine how many adjacent pages get involved
** in a balancing operation.  NN is the number of neighbors on either side
** of the page that participate in the balancing operation.  NB is the
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
static int balance_quick(MemPage *pPage, MemPage *pParent){
  int rc;
  MemPage *pNew;
  Pgno pgnoNew;
  u8 *pCell;
  int szCell;
  CellInfo info;
  BtShared *pBt = pPage->pBt;
  int parentIdx = pParent->nCell;   /* pParent new divider cell index */
  int parentSize;                   /* Size of new divider cell */
  u8 parentCell[64];                /* Space for the new divider cell */

  /* Allocate a new page. Insert the overflow cell from pPage
  ** into it. Then remove the overflow cell from pPage.
  */







|







3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
static int balance_quick(MemPage *pPage, MemPage *pParent){
  int rc;
  MemPage *pNew;
  Pgno pgnoNew;
  u8 *pCell;
  int szCell;
  CellInfo info;
  Btree *pBt = pPage->pBt;
  int parentIdx = pParent->nCell;   /* pParent new divider cell index */
  int parentSize;                   /* Size of new divider cell */
  u8 parentCell[64];                /* Space for the new divider cell */

  /* Allocate a new page. Insert the overflow cell from pPage
  ** into it. Then remove the overflow cell from pPage.
  */
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406

4407
4408
4409
4410
4411

4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
**
** If this routine fails for any reason, it might leave the database
** in a corrupted state.  So if this routine fails, the database should
** be rolled back.
*/
static int balance_nonroot(MemPage *pPage){
  MemPage *pParent;            /* The parent of pPage */
  BtShared *pBt;                  /* The whole database */
  int nCell = 0;               /* Number of cells in apCell[] */
  int nMaxCells = 0;           /* Allocated size of apCell, szCell, aFrom. */
  int nOld;                    /* Number of pages in apOld[] */
  int nNew;                    /* Number of pages in apNew[] */
  int nDiv;                    /* Number of cells in apDiv[] */
  int i, j, k;                 /* Loop counters */
  int idx;                     /* Index of pPage in pParent->aCell[] */
  int nxDiv;                   /* Next divider slot in pParent->aCell[] */
  int rc;                      /* The return code */
  int leafCorrection;          /* 4 if pPage is a leaf.  0 if not */
  int leafData;                /* True if pPage is a leaf of a LEAFDATA tree */
  int usableSpace;             /* Bytes in pPage beyond the header */
  int pageFlags;               /* Value of pPage->aData[0] */
  int subtotal;                /* Subtotal of bytes in cells on one page */
  int iSpace = 0;              /* First unused byte of aSpace[] */

  MemPage *apOld[NB];          /* pPage and up to two siblings */
  Pgno pgnoOld[NB];            /* Page numbers for each page in apOld[] */
  MemPage *apCopy[NB];         /* Private copies of apOld[] pages */
  MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
  Pgno pgnoNew[NB+2];          /* Page numbers for each page in apNew[] */

  u8 *apDiv[NB];               /* Divider cells in pParent */
  int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
  int szNew[NB+2];             /* Combined size of cells place on i-th page */
  u8 **apCell = 0;             /* All cells begin balanced */
  int *szCell;                 /* Local size of all cells in apCell[] */
  u8 *aCopy[NB];               /* Space for holding data of apCopy[] */
  u8 *aSpace;                  /* Space to hold copies of dividers cells */
#ifndef SQLITE_OMIT_AUTOVACUUM
  u8 *aFrom = 0;
#endif








|
|
<













>





>



|







3713
3714
3715
3716
3717
3718
3719
3720
3721

3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
**
** If this routine fails for any reason, it might leave the database
** in a corrupted state.  So if this routine fails, the database should
** be rolled back.
*/
static int balance_nonroot(MemPage *pPage){
  MemPage *pParent;            /* The parent of pPage */
  Btree *pBt;                  /* The whole database */
  int nCell = 0;               /* Number of cells in aCell[] */

  int nOld;                    /* Number of pages in apOld[] */
  int nNew;                    /* Number of pages in apNew[] */
  int nDiv;                    /* Number of cells in apDiv[] */
  int i, j, k;                 /* Loop counters */
  int idx;                     /* Index of pPage in pParent->aCell[] */
  int nxDiv;                   /* Next divider slot in pParent->aCell[] */
  int rc;                      /* The return code */
  int leafCorrection;          /* 4 if pPage is a leaf.  0 if not */
  int leafData;                /* True if pPage is a leaf of a LEAFDATA tree */
  int usableSpace;             /* Bytes in pPage beyond the header */
  int pageFlags;               /* Value of pPage->aData[0] */
  int subtotal;                /* Subtotal of bytes in cells on one page */
  int iSpace = 0;              /* First unused byte of aSpace[] */
  int mxCellPerPage;           /* Maximum number of cells in one page */
  MemPage *apOld[NB];          /* pPage and up to two siblings */
  Pgno pgnoOld[NB];            /* Page numbers for each page in apOld[] */
  MemPage *apCopy[NB];         /* Private copies of apOld[] pages */
  MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
  Pgno pgnoNew[NB+2];          /* Page numbers for each page in apNew[] */
  int idxDiv[NB];              /* Indices of divider cells in pParent */
  u8 *apDiv[NB];               /* Divider cells in pParent */
  int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
  int szNew[NB+2];             /* Combined size of cells place on i-th page */
  u8 **apCell;                 /* All cells begin balanced */
  int *szCell;                 /* Local size of all cells in apCell[] */
  u8 *aCopy[NB];               /* Space for holding data of apCopy[] */
  u8 *aSpace;                  /* Space to hold copies of dividers cells */
#ifndef SQLITE_OMIT_AUTOVACUUM
  u8 *aFrom = 0;
#endif

4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458

























4459
4460
4461
4462
4463
4464
4465
  assert( pParent );
  TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));

#ifndef SQLITE_OMIT_QUICKBALANCE
  /*
  ** A special case:  If a new entry has just been inserted into a
  ** table (that is, a btree with integer keys and all data at the leaves)
  ** and the new entry is the right-most entry in the tree (it has the
  ** largest key) then use the special balance_quick() routine for
  ** balancing.  balance_quick() is much faster and results in a tighter
  ** packing of data in the common case.
  */
  if( pPage->leaf &&
      pPage->intKey &&
      pPage->leafData &&
      pPage->nOverflow==1 &&
      pPage->aOvfl[0].idx==pPage->nCell &&
      pPage->pParent->pgno!=1 &&
      get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno
  ){
    /*
    ** TODO: Check the siblings to the left of pPage. It may be that
    ** they are not full and no new page is required.
    */
    return balance_quick(pPage, pParent);
  }
#endif


























  /*
  ** Find the cell in the parent page whose left child points back
  ** to pPage.  The "idx" variable is the index of that cell.  If pPage
  ** is the rightmost child of pParent then set idx to pParent->nCell 
  */
  if( pParent->idxShift ){
    Pgno pgno;







|




















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







3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
  assert( pParent );
  TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));

#ifndef SQLITE_OMIT_QUICKBALANCE
  /*
  ** A special case:  If a new entry has just been inserted into a
  ** table (that is, a btree with integer keys and all data at the leaves)
  ** an the new entry is the right-most entry in the tree (it has the
  ** largest key) then use the special balance_quick() routine for
  ** balancing.  balance_quick() is much faster and results in a tighter
  ** packing of data in the common case.
  */
  if( pPage->leaf &&
      pPage->intKey &&
      pPage->leafData &&
      pPage->nOverflow==1 &&
      pPage->aOvfl[0].idx==pPage->nCell &&
      pPage->pParent->pgno!=1 &&
      get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno
  ){
    /*
    ** TODO: Check the siblings to the left of pPage. It may be that
    ** they are not full and no new page is required.
    */
    return balance_quick(pPage, pParent);
  }
#endif

  /*
  ** Allocate space for memory structures
  */
  mxCellPerPage = MX_CELL(pBt);
  apCell = sqliteMallocRaw( 
       (mxCellPerPage+2)*NB*(sizeof(u8*)+sizeof(int))
     + sizeof(MemPage)*NB
     + pBt->psAligned*(5+NB)
     + (ISAUTOVACUUM ? (mxCellPerPage+2)*NN*2 : 0)
  );
  if( apCell==0 ){
    return SQLITE_NOMEM;
  }
  szCell = (int*)&apCell[(mxCellPerPage+2)*NB];
  aCopy[0] = (u8*)&szCell[(mxCellPerPage+2)*NB];
  for(i=1; i<NB; i++){
    aCopy[i] = &aCopy[i-1][pBt->psAligned+sizeof(MemPage)];
  }
  aSpace = &aCopy[NB-1][pBt->psAligned+sizeof(MemPage)];
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( pBt->autoVacuum ){
    aFrom = &aSpace[5*pBt->psAligned];
  }
#endif
  
  /*
  ** Find the cell in the parent page whose left child points back
  ** to pPage.  The "idx" variable is the index of that cell.  If pPage
  ** is the rightmost child of pParent then set idx to pParent->nCell 
  */
  if( pParent->idxShift ){
    Pgno pgno;
4496
4497
4498
4499
4500
4501
4502

4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
  }
  if( nxDiv<0 ){
    nxDiv = 0;
  }
  nDiv = 0;
  for(i=0, k=nxDiv; i<NB; i++, k++){
    if( k<pParent->nCell ){

      apDiv[i] = findCell(pParent, k);
      nDiv++;
      assert( !pParent->leaf );
      pgnoOld[i] = get4byte(apDiv[i]);
    }else if( k==pParent->nCell ){
      pgnoOld[i] = get4byte(&pParent->aData[pParent->hdrOffset+8]);
    }else{
      break;
    }
    rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i], pParent);
    if( rc ) goto balance_cleanup;
    apOld[i]->idxParent = k;
    apCopy[i] = 0;
    assert( i==nOld );
    nOld++;
    nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
  }

  /* Make nMaxCells a multiple of 2 in order to preserve 8-byte
  ** alignment */
  nMaxCells = (nMaxCells + 1)&~1;

  /*
  ** Allocate space for memory structures
  */
  apCell = sqliteMallocRaw( 
       nMaxCells*sizeof(u8*)                           /* apCell */
     + nMaxCells*sizeof(int)                           /* szCell */
     + ROUND8(sizeof(MemPage))*NB                      /* aCopy */
     + pBt->pageSize*(5+NB)                            /* aSpace */
     + (ISAUTOVACUUM ? nMaxCells : 0)                  /* aFrom */
  );
  if( apCell==0 ){
    rc = SQLITE_NOMEM;
    goto balance_cleanup;
  }
  szCell = (int*)&apCell[nMaxCells];
  aCopy[0] = (u8*)&szCell[nMaxCells];
  assert( ((aCopy[0] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
  for(i=1; i<NB; i++){
    aCopy[i] = &aCopy[i-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
    assert( ((aCopy[i] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
  }
  aSpace = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
  assert( ((aSpace - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( pBt->autoVacuum ){
    aFrom = &aSpace[5*pBt->pageSize];
  }
#endif
  
  /*
  ** Make copies of the content of pPage and its siblings into aOld[].
  ** The rest of this function will use data from the copies rather
  ** that the original pages since the original pages will be in the
  ** process of being overwritten.
  */
  for(i=0; i<nOld; i++){
    MemPage *p = apCopy[i] = (MemPage*)&aCopy[i][pBt->pageSize];
    p->aData = &((u8*)p)[-pBt->pageSize];
    memcpy(p->aData, apOld[i]->aData, pBt->pageSize + sizeof(MemPage));
    /* The memcpy() above changes the value of p->aData so we have to
    ** set it again. */
    p->aData = &((u8*)p)[-pBt->pageSize];
  }

  /*
  ** Load pointers to all cells on sibling pages and the divider cells
  ** into the local apCell[] array.  Make copies of the divider cells
  ** into space obtained form aSpace[] and remove the the divider Cells
  ** from pParent.







>















<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
|
|
<
<
|







3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873

3874
3875

































3876
3877
3878
3879
3880
3881
3882
3883
3884
3885


3886
3887
3888
3889
3890
3891
3892
3893
  }
  if( nxDiv<0 ){
    nxDiv = 0;
  }
  nDiv = 0;
  for(i=0, k=nxDiv; i<NB; i++, k++){
    if( k<pParent->nCell ){
      idxDiv[i] = k;
      apDiv[i] = findCell(pParent, k);
      nDiv++;
      assert( !pParent->leaf );
      pgnoOld[i] = get4byte(apDiv[i]);
    }else if( k==pParent->nCell ){
      pgnoOld[i] = get4byte(&pParent->aData[pParent->hdrOffset+8]);
    }else{
      break;
    }
    rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i], pParent);
    if( rc ) goto balance_cleanup;
    apOld[i]->idxParent = k;
    apCopy[i] = 0;
    assert( i==nOld );
    nOld++;

  }


































  /*
  ** Make copies of the content of pPage and its siblings into aOld[].
  ** The rest of this function will use data from the copies rather
  ** that the original pages since the original pages will be in the
  ** process of being overwritten.
  */
  for(i=0; i<nOld; i++){
    MemPage *p = apCopy[i] = (MemPage*)&aCopy[i][pBt->psAligned];
    p->aData = &((u8*)p)[-pBt->psAligned];
    memcpy(p->aData, apOld[i]->aData, pBt->psAligned + sizeof(MemPage));


    p->aData = &((u8*)p)[-pBt->psAligned];
  }

  /*
  ** Load pointers to all cells on sibling pages and the divider cells
  ** into the local apCell[] array.  Make copies of the divider cells
  ** into space obtained form aSpace[] and remove the the divider Cells
  ** from pParent.
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
  nCell = 0;
  leafCorrection = pPage->leaf*4;
  leafData = pPage->leafData && pPage->leaf;
  for(i=0; i<nOld; i++){
    MemPage *pOld = apCopy[i];
    int limit = pOld->nCell+pOld->nOverflow;
    for(j=0; j<limit; j++){
      assert( nCell<nMaxCells );
      apCell[nCell] = findOverflowCell(pOld, j);
      szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pBt->autoVacuum ){
        int a;
        aFrom[nCell] = i;
        for(a=0; a<pOld->nOverflow; a++){







<







3905
3906
3907
3908
3909
3910
3911

3912
3913
3914
3915
3916
3917
3918
  nCell = 0;
  leafCorrection = pPage->leaf*4;
  leafData = pPage->leafData && pPage->leaf;
  for(i=0; i<nOld; i++){
    MemPage *pOld = apCopy[i];
    int limit = pOld->nCell+pOld->nOverflow;
    for(j=0; j<limit; j++){

      apCell[nCell] = findOverflowCell(pOld, j);
      szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
#ifndef SQLITE_OMIT_AUTOVACUUM
      if( pBt->autoVacuum ){
        int a;
        aFrom[nCell] = i;
        for(a=0; a<pOld->nOverflow; a++){
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
        ** are duplicates of keys on the child pages.  We need to remove
        ** the divider cells from pParent, but the dividers cells are not
        ** added to apCell[] because they are duplicates of child cells.
        */
        dropCell(pParent, nxDiv, sz);
      }else{
        u8 *pTemp;
        assert( nCell<nMaxCells );
        szCell[nCell] = sz;
        pTemp = &aSpace[iSpace];
        iSpace += sz;
        assert( iSpace<=pBt->pageSize*5 );
        memcpy(pTemp, apDiv[i], sz);
        apCell[nCell] = pTemp+leafCorrection;
#ifndef SQLITE_OMIT_AUTOVACUUM
        if( pBt->autoVacuum ){
          aFrom[nCell] = 0xFF;
        }
#endif







<



|







3932
3933
3934
3935
3936
3937
3938

3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
        ** are duplicates of keys on the child pages.  We need to remove
        ** the divider cells from pParent, but the dividers cells are not
        ** added to apCell[] because they are duplicates of child cells.
        */
        dropCell(pParent, nxDiv, sz);
      }else{
        u8 *pTemp;

        szCell[nCell] = sz;
        pTemp = &aSpace[iSpace];
        iSpace += sz;
        assert( iSpace<=pBt->psAligned*5 );
        memcpy(pTemp, apDiv[i], sz);
        apCell[nCell] = pTemp+leafCorrection;
#ifndef SQLITE_OMIT_AUTOVACUUM
        if( pBt->autoVacuum ){
          aFrom[nCell] = 0xFF;
        }
#endif
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
  **   cntNew[i]: Index in apCell[] and szCell[] for the first cell to
  **              the right of the i-th sibling page.
  ** usableSpace: Number of bytes of space available on each sibling.
  ** 
  */
  usableSpace = pBt->usableSize - 12 + leafCorrection;
  for(subtotal=k=i=0; i<nCell; i++){
    assert( i<nMaxCells );
    subtotal += szCell[i] + 2;
    if( subtotal > usableSpace ){
      szNew[k] = subtotal - szCell[i];
      cntNew[k] = i;
      if( leafData ){ i--; }
      subtotal = 0;
      k++;







<







3977
3978
3979
3980
3981
3982
3983

3984
3985
3986
3987
3988
3989
3990
  **   cntNew[i]: Index in apCell[] and szCell[] for the first cell to
  **              the right of the i-th sibling page.
  ** usableSpace: Number of bytes of space available on each sibling.
  ** 
  */
  usableSpace = pBt->usableSize - 12 + leafCorrection;
  for(subtotal=k=i=0; i<nCell; i++){

    subtotal += szCell[i] + 2;
    if( subtotal > usableSpace ){
      szNew[k] = subtotal - szCell[i];
      cntNew[k] = i;
      if( leafData ){ i--; }
      subtotal = 0;
      k++;
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
    int szRight = szNew[i];  /* Size of sibling on the right */
    int szLeft = szNew[i-1]; /* Size of sibling on the left */
    int r;              /* Index of right-most cell in left sibling */
    int d;              /* Index of first cell to the left of right sibling */

    r = cntNew[i-1] - 1;
    d = r + 1 - leafData;
    assert( d<nMaxCells );
    assert( r<nMaxCells );
    while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){
      szRight += szCell[d] + 2;
      szLeft -= szCell[r] + 2;
      cntNew[i-1]--;
      r = cntNew[i-1] - 1;
      d = r + 1 - leafData;
    }
    szNew[i] = szRight;
    szNew[i-1] = szLeft;
  }

  /* Either we found one or more cells (cntnew[0])>0) or we are the
  ** a virtual root page.  A virtual root page is when the real root
  ** page is page 1 and we are the only child of that page.
  */
  assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) );

  /*
  ** Allocate k new pages.  Reuse old pages where possible.
  */
  assert( pPage->pgno>1 );
  pageFlags = pPage->aData[0];
  for(i=0; i<k; i++){







<
<










<
<
<
<
<
|







4008
4009
4010
4011
4012
4013
4014


4015
4016
4017
4018
4019
4020
4021
4022
4023
4024





4025
4026
4027
4028
4029
4030
4031
4032
    int szRight = szNew[i];  /* Size of sibling on the right */
    int szLeft = szNew[i-1]; /* Size of sibling on the left */
    int r;              /* Index of right-most cell in left sibling */
    int d;              /* Index of first cell to the left of right sibling */

    r = cntNew[i-1] - 1;
    d = r + 1 - leafData;


    while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){
      szRight += szCell[d] + 2;
      szLeft -= szCell[r] + 2;
      cntNew[i-1]--;
      r = cntNew[i-1] - 1;
      d = r + 1 - leafData;
    }
    szNew[i] = szRight;
    szNew[i-1] = szLeft;
  }





  assert( cntNew[0]>0 );

  /*
  ** Allocate k new pages.  Reuse old pages where possible.
  */
  assert( pPage->pgno>1 );
  pageFlags = pPage->aData[0];
  for(i=0; i<k; i++){
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
  ** Evenly distribute the data in apCell[] across the new pages.
  ** Insert divider cells into pParent as necessary.
  */
  j = 0;
  for(i=0; i<nNew; i++){
    /* Assemble the new sibling page. */
    MemPage *pNew = apNew[i];
    assert( j<nMaxCells );
    assert( pNew->pgno==pgnoNew[i] );
    assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
    assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );
    assert( pNew->nOverflow==0 );

#ifndef SQLITE_OMIT_AUTOVACUUM
    /* If this is an auto-vacuum database, update the pointer map entries
    ** that point to the siblings that were rearranged. These can be: left
    ** children of cells, the right-child of the page, or overflow pages
    ** pointed to by cells.
    */
    if( pBt->autoVacuum ){
      for(k=j; k<cntNew[i]; k++){
        assert( k<nMaxCells );
        if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){
          rc = ptrmapPutOvfl(pNew, k-j);
          if( rc!=SQLITE_OK ){
            goto balance_cleanup;
          }
        }
      }
    }
#endif

    j = cntNew[i];

    /* If the sibling page assembled above was not the right-most sibling,
    ** insert a divider cell into the parent page.
    */
    if( i<nNew-1 && j<nCell ){
      u8 *pCell;
      u8 *pTemp;
      int sz;

      assert( j<nMaxCells );
      pCell = apCell[j];
      sz = szCell[j] + leafCorrection;
      if( !pNew->leaf ){
        memcpy(&pNew->aData[8], pCell, 4);
        pTemp = 0;
      }else if( leafData ){
	/* If the tree is a leaf-data tree, and the siblings are leaves, 
        ** then there is no divider cell in apCell[]. Instead, the divider 
        ** cell consists of the integer key for the right-most cell of 
        ** the sibling-page assembled above only.
        */
        CellInfo info;
        j--;
        parseCellPtr(pNew, apCell[j], &info);
        pCell = &aSpace[iSpace];
        fillInCell(pParent, pCell, 0, info.nKey, 0, 0, &sz);
        iSpace += sz;
        assert( iSpace<=pBt->pageSize*5 );
        pTemp = 0;
      }else{
        pCell -= 4;
        pTemp = &aSpace[iSpace];
        iSpace += sz;
        assert( iSpace<=pBt->pageSize*5 );
      }
      rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4);
      if( rc!=SQLITE_OK ) goto balance_cleanup;
      put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno);
#ifndef SQLITE_OMIT_AUTOVACUUM
      /* If this is an auto-vacuum database, and not a leaf-data tree,
      ** then update the pointer map with an entry for the overflow page







<


|










<



















<
<

















|





|







4104
4105
4106
4107
4108
4109
4110

4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123

4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142


4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
  ** Evenly distribute the data in apCell[] across the new pages.
  ** Insert divider cells into pParent as necessary.
  */
  j = 0;
  for(i=0; i<nNew; i++){
    /* Assemble the new sibling page. */
    MemPage *pNew = apNew[i];

    assert( pNew->pgno==pgnoNew[i] );
    assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
    assert( pNew->nCell>0 );
    assert( pNew->nOverflow==0 );

#ifndef SQLITE_OMIT_AUTOVACUUM
    /* If this is an auto-vacuum database, update the pointer map entries
    ** that point to the siblings that were rearranged. These can be: left
    ** children of cells, the right-child of the page, or overflow pages
    ** pointed to by cells.
    */
    if( pBt->autoVacuum ){
      for(k=j; k<cntNew[i]; k++){

        if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){
          rc = ptrmapPutOvfl(pNew, k-j);
          if( rc!=SQLITE_OK ){
            goto balance_cleanup;
          }
        }
      }
    }
#endif

    j = cntNew[i];

    /* If the sibling page assembled above was not the right-most sibling,
    ** insert a divider cell into the parent page.
    */
    if( i<nNew-1 && j<nCell ){
      u8 *pCell;
      u8 *pTemp;
      int sz;


      pCell = apCell[j];
      sz = szCell[j] + leafCorrection;
      if( !pNew->leaf ){
        memcpy(&pNew->aData[8], pCell, 4);
        pTemp = 0;
      }else if( leafData ){
	/* If the tree is a leaf-data tree, and the siblings are leaves, 
        ** then there is no divider cell in apCell[]. Instead, the divider 
        ** cell consists of the integer key for the right-most cell of 
        ** the sibling-page assembled above only.
        */
        CellInfo info;
        j--;
        parseCellPtr(pNew, apCell[j], &info);
        pCell = &aSpace[iSpace];
        fillInCell(pParent, pCell, 0, info.nKey, 0, 0, &sz);
        iSpace += sz;
        assert( iSpace<=pBt->psAligned*5 );
        pTemp = 0;
      }else{
        pCell -= 4;
        pTemp = &aSpace[iSpace];
        iSpace += sz;
        assert( iSpace<=pBt->psAligned*5 );
      }
      rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4);
      if( rc!=SQLITE_OK ) goto balance_cleanup;
      put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno);
#ifndef SQLITE_OMIT_AUTOVACUUM
      /* If this is an auto-vacuum database, and not a leaf-data tree,
      ** then update the pointer map with an entry for the overflow page
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
** page contains no cells.  This is an opportunity to make the tree
** shallower by one level.
*/
static int balance_shallower(MemPage *pPage){
  MemPage *pChild;             /* The only child page of pPage */
  Pgno pgnoChild;              /* Page number for pChild */
  int rc = SQLITE_OK;          /* Return code from subprocedures */
  BtShared *pBt;                  /* The main BTree structure */
  int mxCellPerPage;           /* Maximum number of cells per page */
  u8 **apCell;                 /* All cells from pages being balanced */
  int *szCell;                 /* Local size of all cells */

  assert( pPage->pParent==0 );
  assert( pPage->nCell==0 );
  pBt = pPage->pBt;







|







4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
** page contains no cells.  This is an opportunity to make the tree
** shallower by one level.
*/
static int balance_shallower(MemPage *pPage){
  MemPage *pChild;             /* The only child page of pPage */
  Pgno pgnoChild;              /* Page number for pChild */
  int rc = SQLITE_OK;          /* Return code from subprocedures */
  Btree *pBt;                  /* The main BTree structure */
  int mxCellPerPage;           /* Maximum number of cells per page */
  u8 **apCell;                 /* All cells from pages being balanced */
  int *szCell;                 /* Local size of all cells */

  assert( pPage->pParent==0 );
  assert( pPage->nCell==0 );
  pBt = pPage->pBt;
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
** child.   Finally, call balance_internal() on the new child
** to cause it to split.
*/
static int balance_deeper(MemPage *pPage){
  int rc;             /* Return value from subprocedures */
  MemPage *pChild;    /* Pointer to a new child page */
  Pgno pgnoChild;     /* Page number of the new child page */
  BtShared *pBt;         /* The BTree */
  int usableSize;     /* Total usable size of a page */
  u8 *data;           /* Content of the parent page */
  u8 *cdata;          /* Content of the child page */
  int hdr;            /* Offset to page header in parent */
  int brk;            /* Offset to content of first cell in parent */

  assert( pPage->pParent==0 );







|







4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
** child.   Finally, call balance_internal() on the new child
** to cause it to split.
*/
static int balance_deeper(MemPage *pPage){
  int rc;             /* Return value from subprocedures */
  MemPage *pChild;    /* Pointer to a new child page */
  Pgno pgnoChild;     /* Page number of the new child page */
  Btree *pBt;         /* The BTree */
  int usableSize;     /* Total usable size of a page */
  u8 *data;           /* Content of the parent page */
  u8 *cdata;          /* Content of the child page */
  int hdr;            /* Offset to page header in parent */
  int brk;            /* Offset to content of first cell in parent */

  assert( pPage->pParent==0 );
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
  hdr = pPage->hdrOffset;
  brk = get2byte(&data[hdr+5]);
  cdata = pChild->aData;
  memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr);
  memcpy(&cdata[brk], &data[brk], usableSize-brk);
  assert( pChild->isInit==0 );
  rc = initPage(pChild, pPage);
  if( rc ) goto balancedeeper_out;
  memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0]));
  pChild->nOverflow = pPage->nOverflow;
  if( pChild->nOverflow ){
    pChild->nFree = 0;
  }
  assert( pChild->nCell==pPage->nCell );
  zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF);
  put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild);
  TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno));
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( pBt->autoVacuum ){
    int i;
    rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno);
    if( rc ) goto balancedeeper_out;
    for(i=0; i<pChild->nCell; i++){
      rc = ptrmapPutOvfl(pChild, i);
      if( rc!=SQLITE_OK ){
        return rc;
      }
    }
  }
#endif
  rc = balance_nonroot(pChild);

balancedeeper_out:
  releasePage(pChild);
  return rc;
}

/*
** Decide if the page pPage needs to be balanced.  If balancing is
** required, call the appropriate balancing routine.







|













|









<
<







4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393


4394
4395
4396
4397
4398
4399
4400
  hdr = pPage->hdrOffset;
  brk = get2byte(&data[hdr+5]);
  cdata = pChild->aData;
  memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr);
  memcpy(&cdata[brk], &data[brk], usableSize-brk);
  assert( pChild->isInit==0 );
  rc = initPage(pChild, pPage);
  if( rc ) return rc;
  memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0]));
  pChild->nOverflow = pPage->nOverflow;
  if( pChild->nOverflow ){
    pChild->nFree = 0;
  }
  assert( pChild->nCell==pPage->nCell );
  zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF);
  put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild);
  TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno));
#ifndef SQLITE_OMIT_AUTOVACUUM
  if( pBt->autoVacuum ){
    int i;
    rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno);
    if( rc ) return rc;
    for(i=0; i<pChild->nCell; i++){
      rc = ptrmapPutOvfl(pChild, i);
      if( rc!=SQLITE_OK ){
        return rc;
      }
    }
  }
#endif
  rc = balance_nonroot(pChild);


  releasePage(pChild);
  return rc;
}

/*
** Decide if the page pPage needs to be balanced.  If balancing is
** required, call the appropriate balancing routine.
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
** means a cursor opened with wrFlag==0) this routine also moves
** all cursors other than pExclude so that they are pointing to the 
** first Cell on root page.  This is necessary because an insert 
** or delete might change the number of cells on a page or delete
** a page entirely and we do not want to leave any cursors 
** pointing to non-existant pages or cells.
*/
static int checkReadLocks(BtShared *pBt, Pgno pgnoRoot, BtCursor *pExclude){
  BtCursor *p;
  for(p=pBt->pCursor; p; p=p->pNext){
    u32 flags = (p->pBtree->pSqlite ? p->pBtree->pSqlite->flags : 0);
    if( p->pgnoRoot!=pgnoRoot || p==pExclude ) continue;
    if( p->wrFlag==0 && flags&SQLITE_ReadUncommitted ) continue;
    if( p->wrFlag==0 ) return SQLITE_LOCKED;
    if( p->pPage->pgno!=p->pgnoRoot ){
      moveToRoot(p);
    }
  }
  return SQLITE_OK;
}







|


<

<







4428
4429
4430
4431
4432
4433
4434
4435
4436
4437

4438

4439
4440
4441
4442
4443
4444
4445
** means a cursor opened with wrFlag==0) this routine also moves
** all cursors other than pExclude so that they are pointing to the 
** first Cell on root page.  This is necessary because an insert 
** or delete might change the number of cells on a page or delete
** a page entirely and we do not want to leave any cursors 
** pointing to non-existant pages or cells.
*/
static int checkReadLocks(Btree *pBt, Pgno pgnoRoot, BtCursor *pExclude){
  BtCursor *p;
  for(p=pBt->pCursor; p; p=p->pNext){

    if( p->pgnoRoot!=pgnoRoot || p==pExclude ) continue;

    if( p->wrFlag==0 ) return SQLITE_LOCKED;
    if( p->pPage->pgno!=p->pgnoRoot ){
      moveToRoot(p);
    }
  }
  return SQLITE_OK;
}
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
  const void *pKey, i64 nKey,    /* The key of the new record */
  const void *pData, int nData   /* The data of the new record */
){
  int rc;
  int loc;
  int szNew;
  MemPage *pPage;
  BtShared *pBt = pCur->pBtree->pBt;
  unsigned char *oldCell;
  unsigned char *newCell = 0;

  if( pBt->inTransaction!=TRANS_WRITE ){
    /* Must start a transaction before doing an insert */
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( !pBt->readOnly );
  if( !pCur->wrFlag ){
    return SQLITE_PERM;   /* Cursor not open for writing */
  }
  if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
  }

  /* Save the positions of any other cursors open on this table */
  restoreOrClearCursorPosition(pCur, 0);
  if( 
    SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc))
  ){
    return rc;
  }

  pPage = pCur->pPage;
  assert( pPage->intKey || nKey>=0 );
  assert( pPage->leaf || !pPage->leafData );
  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
          pCur->pgnoRoot, nKey, nData, pPage->pgno,
          loc==0 ? "overwrite" : "new entry"));
  assert( pPage->isInit );
  rc = sqlite3pager_write(pPage->aData);
  if( rc ) return rc;
  newCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
  if( newCell==0 ) return SQLITE_NOMEM;
  rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, &szNew);
  if( rc ) goto end_insert;
  assert( szNew==cellSizePtr(pPage, newCell) );
  assert( szNew<=MX_CELL_SIZE(pBt) );
  if( loc==0 && CURSOR_VALID==pCur->eState ){
    int szOld;
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
    oldCell = findCell(pPage, pCur->idx);
    if( !pPage->leaf ){
      memcpy(newCell, oldCell, 4);
    }
    szOld = cellSizePtr(pPage, oldCell);







|



|










<
<
<
<
<
|
<
|
<
<















|







4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479





4480

4481


4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
  const void *pKey, i64 nKey,    /* The key of the new record */
  const void *pData, int nData   /* The data of the new record */
){
  int rc;
  int loc;
  int szNew;
  MemPage *pPage;
  Btree *pBt = pCur->pBt;
  unsigned char *oldCell;
  unsigned char *newCell = 0;

  if( pBt->inTrans!=TRANS_WRITE ){
    /* Must start a transaction before doing an insert */
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( !pBt->readOnly );
  if( !pCur->wrFlag ){
    return SQLITE_PERM;   /* Cursor not open for writing */
  }
  if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
  }





  rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc);

  if( rc ) return rc;


  pPage = pCur->pPage;
  assert( pPage->intKey || nKey>=0 );
  assert( pPage->leaf || !pPage->leafData );
  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
          pCur->pgnoRoot, nKey, nData, pPage->pgno,
          loc==0 ? "overwrite" : "new entry"));
  assert( pPage->isInit );
  rc = sqlite3pager_write(pPage->aData);
  if( rc ) return rc;
  newCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
  if( newCell==0 ) return SQLITE_NOMEM;
  rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, &szNew);
  if( rc ) goto end_insert;
  assert( szNew==cellSizePtr(pPage, newCell) );
  assert( szNew<=MX_CELL_SIZE(pBt) );
  if( loc==0 && pCur->isValid ){
    int szOld;
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
    oldCell = findCell(pPage, pCur->idx);
    if( !pPage->leaf ){
      memcpy(newCell, oldCell, 4);
    }
    szOld = cellSizePtr(pPage, oldCell);
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
** is left pointing at a random location.
*/
int sqlite3BtreeDelete(BtCursor *pCur){
  MemPage *pPage = pCur->pPage;
  unsigned char *pCell;
  int rc;
  Pgno pgnoChild = 0;
  BtShared *pBt = pCur->pBtree->pBt;

  assert( pPage->isInit );
  if( pBt->inTransaction!=TRANS_WRITE ){
    /* Must start a transaction before doing a delete */
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( !pBt->readOnly );
  if( pCur->idx >= pPage->nCell ){
    return SQLITE_ERROR;  /* The cursor is not pointing to anything */
  }
  if( !pCur->wrFlag ){
    return SQLITE_PERM;   /* Did not open this cursor for writing */
  }
  if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
  }

  /* Restore the current cursor position (a no-op if the cursor is not in 
  ** CURSOR_REQUIRESEEK state) and save the positions of any other cursors 
  ** open on the same table. Then call sqlite3pager_write() on the page
  ** that the entry will be deleted from.
  */
  if( 
    (rc = restoreOrClearCursorPosition(pCur, 1)) ||
    (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
    (rc = sqlite3pager_write(pPage->aData))
  ){
    return rc;
  }

  /* Locate the cell within it's page and leave pCell pointing to the
  ** data. The clearCell() call frees any overflow pages associated with the
  ** cell. The cell itself is still intact.
  */
  pCell = findCell(pPage, pCur->idx);
  if( !pPage->leaf ){







|


|













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







4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553









4554

4555

4556
4557
4558
4559
4560
4561
4562
** is left pointing at a random location.
*/
int sqlite3BtreeDelete(BtCursor *pCur){
  MemPage *pPage = pCur->pPage;
  unsigned char *pCell;
  int rc;
  Pgno pgnoChild = 0;
  Btree *pBt = pCur->pBt;

  assert( pPage->isInit );
  if( pBt->inTrans!=TRANS_WRITE ){
    /* Must start a transaction before doing a delete */
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( !pBt->readOnly );
  if( pCur->idx >= pPage->nCell ){
    return SQLITE_ERROR;  /* The cursor is not pointing to anything */
  }
  if( !pCur->wrFlag ){
    return SQLITE_PERM;   /* Did not open this cursor for writing */
  }
  if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
    return SQLITE_LOCKED; /* The table pCur points to has a read lock */
  }









  rc = sqlite3pager_write(pPage->aData);

  if( rc ) return rc;


  /* Locate the cell within it's page and leave pCell pointing to the
  ** data. The clearCell() call frees any overflow pages associated with the
  ** cell. The cell itself is still intact.
  */
  pCell = findCell(pPage, pCur->idx);
  if( !pPage->leaf ){
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304

5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327

5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
    ** next Cell after the one to be deleted is guaranteed to exist and
    ** to be a leaf so we can use it.
    */
    BtCursor leafCur;
    unsigned char *pNext;
    int szNext;
    int notUsed;
    unsigned char *tempCell = 0;
    assert( !pPage->leafData );
    getTempCursor(pCur, &leafCur);
    rc = sqlite3BtreeNext(&leafCur, &notUsed);
    if( rc!=SQLITE_OK ){
      if( rc!=SQLITE_NOMEM ){
        rc = SQLITE_CORRUPT_BKPT; 
      }

    }
    if( rc==SQLITE_OK ){
      rc = sqlite3pager_write(leafCur.pPage->aData);
    }
    if( rc==SQLITE_OK ){
      TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n",
         pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno));
      dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
      pNext = findCell(leafCur.pPage, leafCur.idx);
      szNext = cellSizePtr(leafCur.pPage, pNext);
      assert( MX_CELL_SIZE(pBt)>=szNext+4 );
      tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
      if( tempCell==0 ){
        rc = SQLITE_NOMEM;
      }
    }
    if( rc==SQLITE_OK ){
      rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0);
    }
    if( rc==SQLITE_OK ){
      put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild);
      rc = balance(pPage, 0);
    }

    if( rc==SQLITE_OK ){
      dropCell(leafCur.pPage, leafCur.idx, szNext);
      rc = balance(leafCur.pPage, 0);
    }
    sqliteFree(tempCell);
    releaseTempCursor(&leafCur);
  }else{
    TRACE(("DELETE: table=%d delete from leaf %d\n",
       pCur->pgnoRoot, pPage->pgno));
    dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
    rc = balance(pPage, 0);
  }
  if( rc==SQLITE_OK ){
    moveToRoot(pCur);
  }
  return rc;
}

/*
** Create a new BTree table.  Write into *piTable the page
** number for the root page of the new table.
**
** The type of type is determined by the flags parameter.  Only the
** following values of flags are currently in use.  Other values for
** flags might not work:
**
**     BTREE_INTKEY|BTREE_LEAFDATA     Used for SQL tables with rowid keys
**     BTREE_ZERODATA                  Used for SQL indices
*/
int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
  BtShared *pBt = p->pBt;
  MemPage *pRoot;
  Pgno pgnoRoot;
  int rc;
  if( pBt->inTransaction!=TRANS_WRITE ){
    /* Must start a transaction first */
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( !pBt->readOnly );

  /* It is illegal to create a table if any cursors are open on the
  ** database. This is because in auto-vacuum mode the backend may







|





|

>

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







<
|
<














|
<



|







4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589

4590

4591
4592
4593
4594
4595
4596
4597
4598
4599




4600

4601
4602
4603

4604
4605
4606
4607


4608
4609
4610
4611
4612
4613
4614

4615

4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630

4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
    ** next Cell after the one to be deleted is guaranteed to exist and
    ** to be a leaf so we can use it.
    */
    BtCursor leafCur;
    unsigned char *pNext;
    int szNext;
    int notUsed;
    unsigned char *tempCell;
    assert( !pPage->leafData );
    getTempCursor(pCur, &leafCur);
    rc = sqlite3BtreeNext(&leafCur, &notUsed);
    if( rc!=SQLITE_OK ){
      if( rc!=SQLITE_NOMEM ){
        rc = SQLITE_CORRUPT;  /* bkpt-CORRUPT */
      }
      return rc;
    }

    rc = sqlite3pager_write(leafCur.pPage->aData);

    if( rc ) return rc;
    TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n",
       pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno));
    dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
    pNext = findCell(leafCur.pPage, leafCur.idx);
    szNext = cellSizePtr(leafCur.pPage, pNext);
    assert( MX_CELL_SIZE(pBt)>=szNext+4 );
    tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
    if( tempCell==0 ) return SQLITE_NOMEM;




    rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0);

    if( rc!=SQLITE_OK ) return rc;
    put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild);
    rc = balance(pPage, 0);

    sqliteFree(tempCell);
    if( rc ) return rc;
    dropCell(leafCur.pPage, leafCur.idx, szNext);
    rc = balance(leafCur.pPage, 0);


    releaseTempCursor(&leafCur);
  }else{
    TRACE(("DELETE: table=%d delete from leaf %d\n",
       pCur->pgnoRoot, pPage->pgno));
    dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
    rc = balance(pPage, 0);
  }

  moveToRoot(pCur);

  return rc;
}

/*
** Create a new BTree table.  Write into *piTable the page
** number for the root page of the new table.
**
** The type of type is determined by the flags parameter.  Only the
** following values of flags are currently in use.  Other values for
** flags might not work:
**
**     BTREE_INTKEY|BTREE_LEAFDATA     Used for SQL tables with rowid keys
**     BTREE_ZERODATA                  Used for SQL indices
*/
int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){

  MemPage *pRoot;
  Pgno pgnoRoot;
  int rc;
  if( pBt->inTrans!=TRANS_WRITE ){
    /* Must start a transaction first */
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( !pBt->readOnly );

  /* It is illegal to create a table if any cursors are open on the
  ** database. This is because in auto-vacuum mode the backend may
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
    Pgno pgnoMove;      /* Move a page here to make room for the root-page */
    MemPage *pPageMove; /* The page to move to. */

    /* Read the value of meta[3] from the database to determine where the
    ** root page of the new table should go. meta[3] is the largest root-page
    ** created so far, so the new root-page is (meta[3]+1).
    */
    rc = sqlite3BtreeGetMeta(p, 4, &pgnoRoot);
    if( rc!=SQLITE_OK ) return rc;
    pgnoRoot++;

    /* The new root-page may not be allocated on a pointer-map page, or the
    ** PENDING_BYTE page.
    */
    if( pgnoRoot==PTRMAP_PAGENO(pBt->usableSize, pgnoRoot) ||







|







4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
    Pgno pgnoMove;      /* Move a page here to make room for the root-page */
    MemPage *pPageMove; /* The page to move to. */

    /* Read the value of meta[3] from the database to determine where the
    ** root page of the new table should go. meta[3] is the largest root-page
    ** created so far, so the new root-page is (meta[3]+1).
    */
    rc = sqlite3BtreeGetMeta(pBt, 4, &pgnoRoot);
    if( rc!=SQLITE_OK ) return rc;
    pgnoRoot++;

    /* The new root-page may not be allocated on a pointer-map page, or the
    ** PENDING_BYTE page.
    */
    if( pgnoRoot==PTRMAP_PAGENO(pBt->usableSize, pgnoRoot) ||
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434

      releasePage(pPageMove);
      rc = getPage(pBt, pgnoRoot, &pRoot);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
      if( rc!=SQLITE_OK || eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
        releasePage(pRoot);
        return rc;
      }
      assert( eType!=PTRMAP_ROOTPAGE );
      assert( eType!=PTRMAP_FREEPAGE );
      rc = sqlite3pager_write(pRoot->aData);
      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;
      }
      rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove);
      releasePage(pRoot);
      if( rc!=SQLITE_OK ){







<
<
<
<


<







4686
4687
4688
4689
4690
4691
4692




4693
4694

4695
4696
4697
4698
4699
4700
4701

      releasePage(pPageMove);
      rc = getPage(pBt, pgnoRoot, &pRoot);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);




      assert( eType!=PTRMAP_ROOTPAGE );
      assert( eType!=PTRMAP_FREEPAGE );

      if( rc!=SQLITE_OK ){
        releasePage(pRoot);
        return rc;
      }
      rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove);
      releasePage(pRoot);
      if( rc!=SQLITE_OK ){
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463

    /* Update the pointer-map and meta-data with the new root-page number. */
    rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0);
    if( rc ){
      releasePage(pRoot);
      return rc;
    }
    rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot);
    if( rc ){
      releasePage(pRoot);
      return rc;
    }

  }else{
    rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0);







|







4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730

    /* Update the pointer-map and meta-data with the new root-page number. */
    rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0);
    if( rc ){
      releasePage(pRoot);
      return rc;
    }
    rc = sqlite3BtreeUpdateMeta(pBt, 4, pgnoRoot);
    if( rc ){
      releasePage(pRoot);
      return rc;
    }

  }else{
    rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0);
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
}

/*
** Erase the given database page and all its children.  Return
** the page to the freelist.
*/
static int clearDatabasePage(
  BtShared *pBt,           /* The BTree that contains the table */
  Pgno pgno,            /* Page number to clear */
  MemPage *pParent,     /* Parent page.  NULL for the root */
  int freePageFlag      /* Deallocate page if true */
){
  MemPage *pPage = 0;
  int rc;
  unsigned char *pCell;
  int i;

  if( pgno>sqlite3pager_pagecount(pBt->pPager) ){
    return SQLITE_CORRUPT_BKPT;
  }

  rc = getAndInitPage(pBt, pgno, &pPage, pParent);
  if( rc ) goto cleardatabasepage_out;
  rc = sqlite3pager_write(pPage->aData);
  if( rc ) goto cleardatabasepage_out;
  for(i=0; i<pPage->nCell; i++){
    pCell = findCell(pPage, i);
    if( !pPage->leaf ){
      rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1);
      if( rc ) goto cleardatabasepage_out;
    }
    rc = clearCell(pPage, pCell);
    if( rc ) goto cleardatabasepage_out;
  }
  if( !pPage->leaf ){
    rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage->pParent, 1);
    if( rc ) goto cleardatabasepage_out;
  }
  if( freePageFlag ){
    rc = freePage(pPage);
  }else{
    zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
  }

cleardatabasepage_out:
  releasePage(pPage);
  return rc;
}

/*
** Delete all information from a single table in the database.  iTable is
** the page number of the root of the table.  After this routine returns,
** the root page is empty, but still exists.
**
** This routine will fail with SQLITE_LOCKED if there are any open
** read cursors on the table.  Open write cursors are moved to the
** root of the table.
*/
int sqlite3BtreeClearTable(Btree *p, int iTable){
  int rc;
  BtCursor *pCur;
  BtShared *pBt = p->pBt;
  if( p->inTrans!=TRANS_WRITE ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    if( pCur->pgnoRoot==(Pgno)iTable ){
      if( pCur->wrFlag==0 ) return SQLITE_LOCKED;
      moveToRoot(pCur);
    }
  }
  rc = clearDatabasePage(pBt, (Pgno)iTable, 0, 0);
#if 0
  if( rc ){
    sqlite3BtreeRollback(pBt);
  }
#endif
  return rc;
}

/*
** Erase all information in a table and add the root of the table to
** the freelist.  Except, the root of the principle table (the one on
** page 1) is never added to the freelist.







|




|





|



|

|




|


|



|






<
<













|


<
|









<



<







4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781


4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797

4798
4799
4800
4801
4802
4803
4804
4805
4806
4807

4808
4809
4810

4811
4812
4813
4814
4815
4816
4817
}

/*
** Erase the given database page and all its children.  Return
** the page to the freelist.
*/
static int clearDatabasePage(
  Btree *pBt,           /* The BTree that contains the table */
  Pgno pgno,            /* Page number to clear */
  MemPage *pParent,     /* Parent page.  NULL for the root */
  int freePageFlag      /* Deallocate page if true */
){
  MemPage *pPage;
  int rc;
  unsigned char *pCell;
  int i;

  if( pgno>sqlite3pager_pagecount(pBt->pPager) ){
    return SQLITE_CORRUPT;
  }

  rc = getAndInitPage(pBt, pgno, &pPage, pParent);
  if( rc ) return rc;
  rc = sqlite3pager_write(pPage->aData);
  if( rc ) return rc;
  for(i=0; i<pPage->nCell; i++){
    pCell = findCell(pPage, i);
    if( !pPage->leaf ){
      rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1);
      if( rc ) return rc;
    }
    rc = clearCell(pPage, pCell);
    if( rc ) return rc;
  }
  if( !pPage->leaf ){
    rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage->pParent, 1);
    if( rc ) return rc;
  }
  if( freePageFlag ){
    rc = freePage(pPage);
  }else{
    zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
  }


  releasePage(pPage);
  return rc;
}

/*
** Delete all information from a single table in the database.  iTable is
** the page number of the root of the table.  After this routine returns,
** the root page is empty, but still exists.
**
** This routine will fail with SQLITE_LOCKED if there are any open
** read cursors on the table.  Open write cursors are moved to the
** root of the table.
*/
int sqlite3BtreeClearTable(Btree *pBt, int iTable){
  int rc;
  BtCursor *pCur;

  if( pBt->inTrans!=TRANS_WRITE ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
    if( pCur->pgnoRoot==(Pgno)iTable ){
      if( pCur->wrFlag==0 ) return SQLITE_LOCKED;
      moveToRoot(pCur);
    }
  }
  rc = clearDatabasePage(pBt, (Pgno)iTable, 0, 0);

  if( rc ){
    sqlite3BtreeRollback(pBt);
  }

  return rc;
}

/*
** Erase all information in a table and add the root of the table to
** the freelist.  Except, the root of the principle table (the one on
** page 1) is never added to the freelist.
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
** root pages are kept at the beginning of the database file, which
** is necessary for AUTOVACUUM to work right.  *piMoved is set to the 
** page number that used to be the last root page in the file before
** the move.  If no page gets moved, *piMoved is set to 0.
** The last root page is recorded in meta[3] and the value of
** meta[3] is updated by this procedure.
*/
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
  int rc;
  MemPage *pPage = 0;
  BtShared *pBt = p->pBt;

  if( p->inTrans!=TRANS_WRITE ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }

  /* It is illegal to drop a table if any cursors are open on the
  ** database. This is because in auto-vacuum mode the backend may
  ** need to move another root-page to fill a gap left by the deleted
  ** root page. If an open cursor was using this page a problem would 
  ** occur.
  */
  if( pBt->pCursor ){
    return SQLITE_LOCKED;
  }

  rc = getPage(pBt, (Pgno)iTable, &pPage);
  if( rc ) return rc;
  rc = sqlite3BtreeClearTable(p, iTable);
  if( rc ){
    releasePage(pPage);
    return rc;
  }

  *piMoved = 0;

  if( iTable>1 ){
#ifdef SQLITE_OMIT_AUTOVACUUM
    rc = freePage(pPage);
    releasePage(pPage);
#else
    if( pBt->autoVacuum ){
      Pgno maxRootPgno;
      rc = sqlite3BtreeGetMeta(p, 4, &maxRootPgno);
      if( rc!=SQLITE_OK ){
        releasePage(pPage);
        return rc;
      }

      if( iTable==maxRootPgno ){
        /* If the table being dropped is the table with the largest root-page







|


<

|















|
|
<
<
<










|







4827
4828
4829
4830
4831
4832
4833
4834
4835
4836

4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855



4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
** root pages are kept at the beginning of the database file, which
** is necessary for AUTOVACUUM to work right.  *piMoved is set to the 
** page number that used to be the last root page in the file before
** the move.  If no page gets moved, *piMoved is set to 0.
** The last root page is recorded in meta[3] and the value of
** meta[3] is updated by this procedure.
*/
int sqlite3BtreeDropTable(Btree *pBt, int iTable, int *piMoved){
  int rc;
  MemPage *pPage = 0;


  if( pBt->inTrans!=TRANS_WRITE ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }

  /* It is illegal to drop a table if any cursors are open on the
  ** database. This is because in auto-vacuum mode the backend may
  ** need to move another root-page to fill a gap left by the deleted
  ** root page. If an open cursor was using this page a problem would 
  ** occur.
  */
  if( pBt->pCursor ){
    return SQLITE_LOCKED;
  }

  rc = getPage(pBt, (Pgno)iTable, &pPage);
  if( rc ) return rc;
  rc = sqlite3BtreeClearTable(pBt, iTable);
  if( rc ) return rc;




  *piMoved = 0;

  if( iTable>1 ){
#ifdef SQLITE_OMIT_AUTOVACUUM
    rc = freePage(pPage);
    releasePage(pPage);
#else
    if( pBt->autoVacuum ){
      Pgno maxRootPgno;
      rc = sqlite3BtreeGetMeta(pBt, 4, &maxRootPgno);
      if( rc!=SQLITE_OK ){
        releasePage(pPage);
        return rc;
      }

      if( iTable==maxRootPgno ){
        /* If the table being dropped is the table with the largest root-page
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
        maxRootPgno--;
      }
      if( maxRootPgno==PTRMAP_PAGENO(pBt->usableSize, maxRootPgno) ){
        maxRootPgno--;
      }
      assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );

      rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
    }else{
      rc = freePage(pPage);
      releasePage(pPage);
    }
#endif
  }else{
    /* If sqlite3BtreeDropTable was called on page 1. */







|







4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
        maxRootPgno--;
      }
      if( maxRootPgno==PTRMAP_PAGENO(pBt->usableSize, maxRootPgno) ){
        maxRootPgno--;
      }
      assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );

      rc = sqlite3BtreeUpdateMeta(pBt, 4, maxRootPgno);
    }else{
      rc = freePage(pPage);
      releasePage(pPage);
    }
#endif
  }else{
    /* If sqlite3BtreeDropTable was called on page 1. */
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
** through meta[15] are available for use by higher layers.  Meta[0]
** is read-only, the others are read/write.
** 
** The schema layer numbers meta values differently.  At the schema
** layer (and the SetCookie and ReadCookie opcodes) the number of
** free pages is not visible.  So Cookie[0] is the same as Meta[1].
*/
int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
  int rc;
  unsigned char *pP1;
  BtShared *pBt = p->pBt;

  /* Reading a meta-data value requires a read-lock on page 1 (and hence
  ** the sqlite_master table. We grab this lock regardless of whether or
  ** not the SQLITE_ReadUncommitted flag is set (the table rooted at page
  ** 1 is treated as a special case by queryTableLock() and lockTable()).
  */
  rc = queryTableLock(p, 1, READ_LOCK);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  assert( idx>=0 && idx<=15 );
  rc = sqlite3pager_get(pBt->pPager, 1, (void**)&pP1);
  if( rc ) return rc;
  *pMeta = get4byte(&pP1[36 + idx*4]);
  sqlite3pager_unref(pP1);

  /* If autovacuumed is disabled in this build but we are trying to 
  ** access an autovacuumed database, then make the database readonly. 
  */
#ifdef SQLITE_OMIT_AUTOVACUUM
  if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
#endif

  /* Grab the read-lock on page 1. */
  rc = lockTable(p, 1, READ_LOCK);
  return rc;
}

/*
** Write meta-information back into the database.  Meta[0] is
** read-only and may not be written.
*/
int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
  BtShared *pBt = p->pBt;
  unsigned char *pP1;
  int rc;
  assert( idx>=1 && idx<=15 );
  if( p->inTrans!=TRANS_WRITE ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( pBt->pPage1!=0 );
  pP1 = pBt->pPage1->aData;
  rc = sqlite3pager_write(pP1);
  if( rc ) return rc;
  put4byte(&pP1[36 + idx*4], iMeta);
  return SQLITE_OK;
}

/*
** Return the flag byte at the beginning of the page that the cursor
** is currently pointing to.
*/
int sqlite3BtreeFlags(BtCursor *pCur){
  /* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call
  ** restoreOrClearCursorPosition() here.
  */
  MemPage *pPage = pCur->pPage;
  return pPage ? pPage->aData[pPage->hdrOffset] : 0;
}

#ifdef SQLITE_DEBUG
/*
** Print a disassembly of the given page on standard output.  This routine
** is used for debugging and testing only.
*/
static int btreePageDump(BtShared *pBt, int pgno, int recursive, MemPage *pParent){
  int rc;
  MemPage *pPage;
  int i, j, c;
  int nFree;
  u16 idx;
  int hdr;
  int nCell;







|


<
<
<
<
<
<
<
<
<
<
<














<
<
|






|
<



|















<
<
<









|







4941
4942
4943
4944
4945
4946
4947
4948
4949
4950











4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964


4965
4966
4967
4968
4969
4970
4971
4972

4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991



4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
** through meta[15] are available for use by higher layers.  Meta[0]
** is read-only, the others are read/write.
** 
** The schema layer numbers meta values differently.  At the schema
** layer (and the SetCookie and ReadCookie opcodes) the number of
** free pages is not visible.  So Cookie[0] is the same as Meta[1].
*/
int sqlite3BtreeGetMeta(Btree *pBt, int idx, u32 *pMeta){
  int rc;
  unsigned char *pP1;












  assert( idx>=0 && idx<=15 );
  rc = sqlite3pager_get(pBt->pPager, 1, (void**)&pP1);
  if( rc ) return rc;
  *pMeta = get4byte(&pP1[36 + idx*4]);
  sqlite3pager_unref(pP1);

  /* If autovacuumed is disabled in this build but we are trying to 
  ** access an autovacuumed database, then make the database readonly. 
  */
#ifdef SQLITE_OMIT_AUTOVACUUM
  if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
#endif



  return SQLITE_OK;
}

/*
** Write meta-information back into the database.  Meta[0] is
** read-only and may not be written.
*/
int sqlite3BtreeUpdateMeta(Btree *pBt, int idx, u32 iMeta){

  unsigned char *pP1;
  int rc;
  assert( idx>=1 && idx<=15 );
  if( pBt->inTrans!=TRANS_WRITE ){
    return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  }
  assert( pBt->pPage1!=0 );
  pP1 = pBt->pPage1->aData;
  rc = sqlite3pager_write(pP1);
  if( rc ) return rc;
  put4byte(&pP1[36 + idx*4], iMeta);
  return SQLITE_OK;
}

/*
** Return the flag byte at the beginning of the page that the cursor
** is currently pointing to.
*/
int sqlite3BtreeFlags(BtCursor *pCur){



  MemPage *pPage = pCur->pPage;
  return pPage ? pPage->aData[pPage->hdrOffset] : 0;
}

#ifdef SQLITE_DEBUG
/*
** Print a disassembly of the given page on standard output.  This routine
** is used for debugging and testing only.
*/
static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){
  int rc;
  MemPage *pPage;
  int i, j, c;
  int nFree;
  u16 idx;
  int hdr;
  int nCell;
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
    btreePageDump(pBt, get4byte(&data[hdr+8]), 1, pPage);
  }
  pPage->isInit = isInit;
  sqlite3pager_unref(data);
  fflush(stdout);
  return SQLITE_OK;
}
int sqlite3BtreePageDump(Btree *p, int pgno, int recursive){
  return btreePageDump(p->pBt, pgno, recursive, 0);
}
#endif

#ifdef SQLITE_TEST
/*
** Fill aResult[] with information about the entry and page that the
** cursor is pointing to.







|
|







5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
    btreePageDump(pBt, get4byte(&data[hdr+8]), 1, pPage);
  }
  pPage->isInit = isInit;
  sqlite3pager_unref(data);
  fflush(stdout);
  return SQLITE_OK;
}
int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){
  return btreePageDump(pBt, pgno, recursive, 0);
}
#endif

#ifdef SQLITE_TEST
/*
** Fill aResult[] with information about the entry and page that the
** cursor is pointing to.
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
** This routine is used for testing and debugging only.
*/
int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
  int cnt, idx;
  MemPage *pPage = pCur->pPage;
  BtCursor tmpCur;

  int rc = restoreOrClearCursorPosition(pCur, 1);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  pageIntegrity(pPage);
  assert( pPage->isInit );
  getTempCursor(pCur, &tmpCur);
  while( upCnt-- ){
    moveToParent(&tmpCur);
  }
  pPage = tmpCur.pPage;







<
<
<
<
<







5118
5119
5120
5121
5122
5123
5124





5125
5126
5127
5128
5129
5130
5131
** This routine is used for testing and debugging only.
*/
int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
  int cnt, idx;
  MemPage *pPage = pCur->pPage;
  BtCursor tmpCur;






  pageIntegrity(pPage);
  assert( pPage->isInit );
  getTempCursor(pCur, &tmpCur);
  while( upCnt-- ){
    moveToParent(&tmpCur);
  }
  pPage = tmpCur.pPage;
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
}
#endif

/*
** Return the pager associated with a BTree.  This routine is used for
** testing and debugging only.
*/
Pager *sqlite3BtreePager(Btree *p){
  return p->pBt->pPager;
}

/*
** This structure is passed around through all the sanity checking routines
** in order to keep track of some global state information.
*/
typedef struct IntegrityCk IntegrityCk;
struct IntegrityCk {
  BtShared *pBt;    /* The tree being checked out */
  Pager *pPager; /* The associated pager.  Also accessible by pBt->pPager */
  int nPage;     /* Number of pages in the database */
  int *anRef;    /* Number of times each page is referenced */
  char *zErrMsg; /* An error message.  NULL of no errors seen. */
};

#ifndef SQLITE_OMIT_INTEGRITY_CHECK







|
|








|







5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
}
#endif

/*
** Return the pager associated with a BTree.  This routine is used for
** testing and debugging only.
*/
Pager *sqlite3BtreePager(Btree *pBt){
  return pBt->pPager;
}

/*
** This structure is passed around through all the sanity checking routines
** in order to keep track of some global state information.
*/
typedef struct IntegrityCk IntegrityCk;
struct IntegrityCk {
  Btree *pBt;    /* The tree being checked out */
  Pager *pPager; /* The associated pager.  Also accessible by pBt->pPager */
  int nPage;     /* Number of pages in the database */
  int *anRef;    /* Number of times each page is referenced */
  char *zErrMsg; /* An error message.  NULL of no errors seen. */
};

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
6129
6130
6131
6132
6133
6134
6135

6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153

6154
6155
6156
6157
6158
6159
6160
6161
6162

6163
6164
6165
6166
6167
6168
6169
  int nUpper            /* Number of characters in zUpperBound */
){
  MemPage *pPage;
  int i, rc, depth, d2, pgno, cnt;
  int hdr, cellStart;
  int nCell;
  u8 *data;

  BtShared *pBt;
  int usableSize;
  char zContext[100];
  char *hit;

  sprintf(zContext, "Page %d: ", iPage);

  /* Check that the page exists
  */
  pBt = pCheck->pBt;
  usableSize = pBt->usableSize;
  if( iPage==0 ) return 0;
  if( checkRef(pCheck, iPage, zParentContext) ) return 0;
  if( (rc = getPage(pBt, (Pgno)iPage, &pPage))!=0 ){
    checkAppendMsg(pCheck, zContext,
       "unable to get the page. error code=%d", rc);
    return 0;
  }

  if( (rc = initPage(pPage, pParent))!=0 ){
    checkAppendMsg(pCheck, zContext, "initPage() returns error code %d", rc);
    releasePage(pPage);
    return 0;
  }

  /* Check out all the cells.
  */
  depth = 0;

  for(i=0; i<pPage->nCell; i++){
    u8 *pCell;
    int sz;
    CellInfo info;

    /* Check payload overflow pages
    */







>
|
|







|








>









>







5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
  int nUpper            /* Number of characters in zUpperBound */
){
  MemPage *pPage;
  int i, rc, depth, d2, pgno, cnt;
  int hdr, cellStart;
  int nCell;
  u8 *data;
  BtCursor cur;
  Btree *pBt;
  int maxLocal, usableSize;
  char zContext[100];
  char *hit;

  sprintf(zContext, "Page %d: ", iPage);

  /* Check that the page exists
  */
  cur.pBt = pBt = pCheck->pBt;
  usableSize = pBt->usableSize;
  if( iPage==0 ) return 0;
  if( checkRef(pCheck, iPage, zParentContext) ) return 0;
  if( (rc = getPage(pBt, (Pgno)iPage, &pPage))!=0 ){
    checkAppendMsg(pCheck, zContext,
       "unable to get the page. error code=%d", rc);
    return 0;
  }
  maxLocal = pPage->leafData ? pBt->maxLeaf : pBt->maxLocal;
  if( (rc = initPage(pPage, pParent))!=0 ){
    checkAppendMsg(pCheck, zContext, "initPage() returns error code %d", rc);
    releasePage(pPage);
    return 0;
  }

  /* Check out all the cells.
  */
  depth = 0;
  cur.pPage = pPage;
  for(i=0; i<pPage->nCell; i++){
    u8 *pCell;
    int sz;
    CellInfo info;

    /* Check payload overflow pages
    */
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
** a table.  nRoot is the number of entries in aRoot.
**
** If everything checks out, this routine returns NULL.  If something is
** amiss, an error message is written into memory obtained from malloc()
** and a pointer to that error message is returned.  The calling function
** is responsible for freeing the error message when it is done.
*/
char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){
  int i;
  int nRef;
  IntegrityCk sCheck;
  BtShared *pBt = p->pBt;

  nRef = *sqlite3pager_stats(pBt->pPager);
  if( lockBtreeWithRetry(p)!=SQLITE_OK ){
    return sqliteStrDup("Unable to acquire a read lock on the database");
  }
  sCheck.pBt = pBt;
  sCheck.pPager = pBt->pPager;
  sCheck.nPage = sqlite3pager_pagecount(sCheck.pPager);
  if( sCheck.nPage==0 ){
    unlockBtreeIfUnused(pBt);







|



<


|







5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520

5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
** a table.  nRoot is the number of entries in aRoot.
**
** If everything checks out, this routine returns NULL.  If something is
** amiss, an error message is written into memory obtained from malloc()
** and a pointer to that error message is returned.  The calling function
** is responsible for freeing the error message when it is done.
*/
char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){
  int i;
  int nRef;
  IntegrityCk sCheck;


  nRef = *sqlite3pager_stats(pBt->pPager);
  if( lockBtree(pBt)!=SQLITE_OK ){
    return sqliteStrDup("Unable to acquire a read lock on the database");
  }
  sCheck.pBt = pBt;
  sCheck.pPager = pBt->pPager;
  sCheck.nPage = sqlite3pager_pagecount(sCheck.pPager);
  if( sCheck.nPage==0 ){
    unlockBtreeIfUnused(pBt);
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
  return sCheck.zErrMsg;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

/*
** Return the full pathname of the underlying database file.
*/
const char *sqlite3BtreeGetFilename(Btree *p){
  assert( p->pBt->pPager!=0 );
  return sqlite3pager_filename(p->pBt->pPager);
}

/*
** Return the pathname of the directory that contains the database file.
*/
const char *sqlite3BtreeGetDirname(Btree *p){
  assert( p->pBt->pPager!=0 );
  return sqlite3pager_dirname(p->pBt->pPager);
}

/*
** Return the pathname of the journal file for this database. The return
** value of this routine is the same regardless of whether the journal file
** has been created or not.
*/
const char *sqlite3BtreeGetJournalname(Btree *p){
  assert( p->pBt->pPager!=0 );
  return sqlite3pager_journalname(p->pBt->pPager);
}

#ifndef SQLITE_OMIT_VACUUM
/*
** Copy the complete content of pBtFrom into pBtTo.  A transaction
** must be active for both files.
**
** The size of file pBtFrom may be reduced by this operation.
** If anything goes wrong, the transaction on pBtFrom is rolled back.
*/
int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
  int rc = SQLITE_OK;
  Pgno i, nPage, nToPage, iSkip;

  BtShared *pBtTo = pTo->pBt;
  BtShared *pBtFrom = pFrom->pBt;

  if( pTo->inTrans!=TRANS_WRITE || pFrom->inTrans!=TRANS_WRITE ){
    return SQLITE_ERROR;
  }
  if( pBtTo->pCursor ) return SQLITE_BUSY;
  nToPage = sqlite3pager_pagecount(pBtTo->pPager);
  nPage = sqlite3pager_pagecount(pBtFrom->pPager);
  iSkip = PENDING_BYTE_PAGE(pBtTo);
  for(i=1; rc==SQLITE_OK && i<=nPage; i++){
    void *pPage;
    if( i==iSkip ) continue;
    rc = sqlite3pager_get(pBtFrom->pPager, i, &pPage);
    if( rc ) break;
    rc = sqlite3pager_overwrite(pBtTo->pPager, i, pPage);
    if( rc ) break;
    sqlite3pager_unref(pPage);
  }
  for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){
    void *pPage;
    if( i==iSkip ) continue;
    rc = sqlite3pager_get(pBtTo->pPager, i, &pPage);
    if( rc ) break;
    rc = sqlite3pager_write(pPage);
    sqlite3pager_unref(pPage);
    sqlite3pager_dont_write(pBtTo->pPager, i);
  }
  if( !rc && nPage<nToPage ){
    rc = sqlite3pager_truncate(pBtTo->pPager, nPage);
  }
  if( rc ){
    sqlite3BtreeRollback(pTo);
  }
  return rc;  
}
#endif /* SQLITE_OMIT_VACUUM */

/*
** Return non-zero if a transaction is active.
*/
int sqlite3BtreeIsInTrans(Btree *p){
  return (p && (p->inTrans==TRANS_WRITE));
}

/*
** Return non-zero if a statement transaction is active.
*/
int sqlite3BtreeIsInStmt(Btree *p){
  return (p->pBt && p->pBt->inStmt);
}

/*
** This call is a no-op if no write-transaction is currently active on pBt.
**
** Otherwise, sync the database file for the btree pBt. zMaster points to
** the name of a master journal file that should be written into the
** individual journal file, or is NULL, indicating no master journal file 
** (single database transaction).
**
** When this is called, the master journal should already have been
** created, populated with this journal pointer and synced to disk.
**
** Once this is routine has returned, the only thing required to commit
** the write-transaction for this database file is to delete the journal.
*/
int sqlite3BtreeSync(Btree *p, const char *zMaster){
  if( p->inTrans==TRANS_WRITE ){
    BtShared *pBt = p->pBt;
#ifndef SQLITE_OMIT_AUTOVACUUM
    Pgno nTrunc = 0;
    if( pBt->autoVacuum ){
      int rc = autoVacuumCommit(pBt, &nTrunc); 
      if( rc!=SQLITE_OK ) return rc;
    }
    return sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
#endif
    return sqlite3pager_sync(pBt->pPager, zMaster, 0);
  }
  return SQLITE_OK;
}

/*
** This function returns a pointer to a blob of memory associated with
** a single shared-btree. The memory is used by client code for it's own
** purposes (for example, to store a high-level schema associated with 
** the shared-btree). The btree layer manages reference counting issues.
**
** The first time this is called on a shared-btree, nBytes bytes of memory
** are allocated, zeroed, and returned to the caller. For each subsequent 
** call the nBytes parameter is ignored and a pointer to the same blob
** of memory returned. 
**
** Just before the shared-btree is closed, the function passed as the 
** xFree argument when the memory allocation was made is invoked on the 
** blob of allocated memory. This function should not call sqliteFree()
** on the memory, the btree layer does that.
*/
void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
  BtShared *pBt = p->pBt;
  if( !pBt->pSchema ){
    pBt->pSchema = sqliteMalloc(nBytes);
    pBt->xFreeSchema = xFree;
  }
  return pBt->pSchema;
}

/*
** Return true if another user of the same shared btree as the argument
** handle holds an exclusive lock on the sqlite_master table.
*/
int sqlite3BtreeSchemaLocked(Btree *p){
  return (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK);
}

int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
  int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_SHARED_CACHE
  u8 lockType = (isWriteLock?WRITE_LOCK:READ_LOCK);
  rc = queryTableLock(p, iTab, lockType);
  if( rc==SQLITE_OK ){
    rc = lockTable(p, iTab, lockType);
  }
#endif
  return rc;
}

/*
** The following debugging interface has to be in this file (rather
** than in, for example, test1.c) so that it can get access to
** the definition of BtShared.
*/
#if defined(SQLITE_TEST) && defined(TCLSH)
#include <tcl.h>
int sqlite3_shared_cache_report(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  const ThreadData *pTd = sqlite3ThreadDataReadOnly();
  if( pTd->useSharedData ){
    BtShared *pBt;
    Tcl_Obj *pRet = Tcl_NewObj();
    for(pBt=pTd->pBtree; pBt; pBt=pBt->pNext){
      const char *zFile = sqlite3pager_filename(pBt->pPager);
      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1));
      Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef));
    }
    Tcl_SetObjResult(interp, pRet);
  }
  return TCL_OK;
}
#endif







|
|
|





|
|
|







|
|
|










|

|

<
<
<
|





<


<








<










|








|
|





|
|
















|
|
<












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639



5640
5641
5642
5643
5644
5645

5646
5647

5648
5649
5650
5651
5652
5653
5654
5655

5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701

5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713









































































  return sCheck.zErrMsg;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

/*
** Return the full pathname of the underlying database file.
*/
const char *sqlite3BtreeGetFilename(Btree *pBt){
  assert( pBt->pPager!=0 );
  return sqlite3pager_filename(pBt->pPager);
}

/*
** Return the pathname of the directory that contains the database file.
*/
const char *sqlite3BtreeGetDirname(Btree *pBt){
  assert( pBt->pPager!=0 );
  return sqlite3pager_dirname(pBt->pPager);
}

/*
** Return the pathname of the journal file for this database. The return
** value of this routine is the same regardless of whether the journal file
** has been created or not.
*/
const char *sqlite3BtreeGetJournalname(Btree *pBt){
  assert( pBt->pPager!=0 );
  return sqlite3pager_journalname(pBt->pPager);
}

#ifndef SQLITE_OMIT_VACUUM
/*
** Copy the complete content of pBtFrom into pBtTo.  A transaction
** must be active for both files.
**
** The size of file pBtFrom may be reduced by this operation.
** If anything goes wrong, the transaction on pBtFrom is rolled back.
*/
int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){
  int rc = SQLITE_OK;
  Pgno i, nPage, nToPage;




  if( pBtTo->inTrans!=TRANS_WRITE || pBtFrom->inTrans!=TRANS_WRITE ){
    return SQLITE_ERROR;
  }
  if( pBtTo->pCursor ) return SQLITE_BUSY;
  nToPage = sqlite3pager_pagecount(pBtTo->pPager);
  nPage = sqlite3pager_pagecount(pBtFrom->pPager);

  for(i=1; rc==SQLITE_OK && i<=nPage; i++){
    void *pPage;

    rc = sqlite3pager_get(pBtFrom->pPager, i, &pPage);
    if( rc ) break;
    rc = sqlite3pager_overwrite(pBtTo->pPager, i, pPage);
    if( rc ) break;
    sqlite3pager_unref(pPage);
  }
  for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){
    void *pPage;

    rc = sqlite3pager_get(pBtTo->pPager, i, &pPage);
    if( rc ) break;
    rc = sqlite3pager_write(pPage);
    sqlite3pager_unref(pPage);
    sqlite3pager_dont_write(pBtTo->pPager, i);
  }
  if( !rc && nPage<nToPage ){
    rc = sqlite3pager_truncate(pBtTo->pPager, nPage);
  }
  if( rc ){
    sqlite3BtreeRollback(pBtTo);
  }
  return rc;  
}
#endif /* SQLITE_OMIT_VACUUM */

/*
** Return non-zero if a transaction is active.
*/
int sqlite3BtreeIsInTrans(Btree *pBt){
  return (pBt && (pBt->inTrans==TRANS_WRITE));
}

/*
** Return non-zero if a statement transaction is active.
*/
int sqlite3BtreeIsInStmt(Btree *pBt){
  return (pBt && pBt->inStmt);
}

/*
** This call is a no-op if no write-transaction is currently active on pBt.
**
** Otherwise, sync the database file for the btree pBt. zMaster points to
** the name of a master journal file that should be written into the
** individual journal file, or is NULL, indicating no master journal file 
** (single database transaction).
**
** When this is called, the master journal should already have been
** created, populated with this journal pointer and synced to disk.
**
** Once this is routine has returned, the only thing required to commit
** the write-transaction for this database file is to delete the journal.
*/
int sqlite3BtreeSync(Btree *pBt, const char *zMaster){
  if( pBt->inTrans==TRANS_WRITE ){

#ifndef SQLITE_OMIT_AUTOVACUUM
    Pgno nTrunc = 0;
    if( pBt->autoVacuum ){
      int rc = autoVacuumCommit(pBt, &nTrunc); 
      if( rc!=SQLITE_OK ) return rc;
    }
    return sqlite3pager_sync(pBt->pPager, zMaster, nTrunc);
#endif
    return sqlite3pager_sync(pBt->pPager, zMaster, 0);
  }
  return SQLITE_OK;
}









































































Changes to SQLite.Interop/src/btree.h.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
** subsystem.  See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.16 2006/01/16 15:51:47 rmsimpson Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
** subsystem.  See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.1 2005/03/01 16:04:27 rmsimpson Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#endif

/*
** Forward declarations of structure
*/
typedef struct Btree Btree;
typedef struct BtCursor BtCursor;
typedef struct BtShared BtShared;


int sqlite3BtreeOpen(
  const char *zFilename,   /* Name of database file to open */
  sqlite3 *db,             /* Associated database connection */
  Btree **,                /* Return open Btree* here */
  int flags                /* Flags */
);

/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
** following values.
**
** NOTE:  These values must match the corresponding PAGER_ values in
** pager.h.
*/
#define BTREE_OMIT_JOURNAL  1  /* Do not use journal.  No argument */
#define BTREE_NO_READLOCK   2  /* Omit readlocks on readonly files */
#define BTREE_MEMORY        4  /* In-memory DB.  No argument */

int sqlite3BtreeClose(Btree*);
int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
int sqlite3BtreeSetCacheSize(Btree*,int);
int sqlite3BtreeSetSafetyLevel(Btree*,int);
int sqlite3BtreeSyncDisabled(Btree*);
int sqlite3BtreeSetPageSize(Btree*,int,int);
int sqlite3BtreeGetPageSize(Btree*);
int sqlite3BtreeGetReserve(Btree*);
int sqlite3BtreeSetAutoVacuum(Btree *, int);
int sqlite3BtreeGetAutoVacuum(Btree *);
int sqlite3BtreeBeginTrans(Btree*,int);
int sqlite3BtreeCommit(Btree*);
int sqlite3BtreeRollback(Btree*);
int sqlite3BtreeBeginStmt(Btree*);
int sqlite3BtreeCommitStmt(Btree*);
int sqlite3BtreeRollbackStmt(Btree*);
int sqlite3BtreeCreateTable(Btree*, int*, int flags);
int sqlite3BtreeIsInTrans(Btree*);
int sqlite3BtreeIsInStmt(Btree*);
int sqlite3BtreeSync(Btree*, const char *zMaster);
void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
int sqlite3BtreeSchemaLocked(Btree *);
int sqlite3BtreeLockTable(Btree *, int, u8);

const char *sqlite3BtreeGetFilename(Btree *);
const char *sqlite3BtreeGetDirname(Btree *);
const char *sqlite3BtreeGetJournalname(Btree *);
int sqlite3BtreeCopyFile(Btree *, Btree *);

/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR







<




<


















<















<
<
<







32
33
34
35
36
37
38

39
40
41
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75



76
77
78
79
80
81
82
#endif

/*
** Forward declarations of structure
*/
typedef struct Btree Btree;
typedef struct BtCursor BtCursor;



int sqlite3BtreeOpen(
  const char *zFilename,   /* Name of database file to open */

  Btree **,                /* Return open Btree* here */
  int flags                /* Flags */
);

/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
** following values.
**
** NOTE:  These values must match the corresponding PAGER_ values in
** pager.h.
*/
#define BTREE_OMIT_JOURNAL  1  /* Do not use journal.  No argument */
#define BTREE_NO_READLOCK   2  /* Omit readlocks on readonly files */
#define BTREE_MEMORY        4  /* In-memory DB.  No argument */

int sqlite3BtreeClose(Btree*);
int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
int sqlite3BtreeSetCacheSize(Btree*,int);
int sqlite3BtreeSetSafetyLevel(Btree*,int);

int sqlite3BtreeSetPageSize(Btree*,int,int);
int sqlite3BtreeGetPageSize(Btree*);
int sqlite3BtreeGetReserve(Btree*);
int sqlite3BtreeSetAutoVacuum(Btree *, int);
int sqlite3BtreeGetAutoVacuum(Btree *);
int sqlite3BtreeBeginTrans(Btree*,int);
int sqlite3BtreeCommit(Btree*);
int sqlite3BtreeRollback(Btree*);
int sqlite3BtreeBeginStmt(Btree*);
int sqlite3BtreeCommitStmt(Btree*);
int sqlite3BtreeRollbackStmt(Btree*);
int sqlite3BtreeCreateTable(Btree*, int*, int flags);
int sqlite3BtreeIsInTrans(Btree*);
int sqlite3BtreeIsInStmt(Btree*);
int sqlite3BtreeSync(Btree*, const char *zMaster);




const char *sqlite3BtreeGetFilename(Btree *);
const char *sqlite3BtreeGetDirname(Btree *);
const char *sqlite3BtreeGetJournalname(Btree *);
int sqlite3BtreeCopyFile(Btree *, Btree *);

/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
Changes to SQLite.Interop/src/build.c.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
*/
void sqlite3BeginParse(Parse *pParse, int explainFlag){
  pParse->explain = explainFlag;
  pParse->nVar = 0;
}

#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** The TableLock structure is only used by the sqlite3TableLock() and
** codeTableLocks() functions.
*/
struct TableLock {
  int iDb;
  int iTab;
  u8 isWriteLock;
  const char *zName;
};

/*
** Have the compiled statement lock the table with rootpage iTab in database
** iDb at the shared-cache level when executed. The isWriteLock argument 
** is zero for a read-lock, or non-zero for a write-lock.
**
** The zName parameter should point to the unqualified table name. This is
** used to provide a more informative error message should the lock fail.
*/
void sqlite3TableLock(
  Parse *pParse, 
  int iDb, 
  int iTab, 
  u8 isWriteLock,  
  const char *zName
){
  int i;
  int nBytes;
  TableLock *p;

  if( 0==sqlite3ThreadDataReadOnly()->useSharedData || iDb<0 ){
    return;
  }

  for(i=0; i<pParse->nTableLock; i++){
    p = &pParse->aTableLock[i];
    if( p->iDb==iDb && p->iTab==iTab ){
      p->isWriteLock = (p->isWriteLock || isWriteLock);
      return;
    }
  }

  nBytes = sizeof(TableLock) * (pParse->nTableLock+1);
  sqliteReallocOrFree((void **)&pParse->aTableLock, nBytes);
  if( pParse->aTableLock ){
    p = &pParse->aTableLock[pParse->nTableLock++];
    p->iDb = iDb;
    p->iTab = iTab;
    p->isWriteLock = isWriteLock;
    p->zName = zName;
  }
}

/*
** Code an OP_TableLock instruction for each table locked by the
** statement (configured by calls to sqlite3TableLock()).
*/
static void codeTableLocks(Parse *pParse){
  int i;
  Vdbe *pVdbe; 
  assert( sqlite3ThreadDataReadOnly()->useSharedData || pParse->nTableLock==0 );

  if( 0==(pVdbe = sqlite3GetVdbe(pParse)) ){
    return;
  }

  for(i=0; i<pParse->nTableLock; i++){
    TableLock *p = &pParse->aTableLock[i];
    int p1 = p->iDb;
    if( p->isWriteLock ){
      p1 = -1*(p1+1);
    }
    sqlite3VdbeOp3(pVdbe, OP_TableLock, p1, p->iTab, p->zName, P3_STATIC);
  }
}
#else
  #define codeTableLocks(x)
#endif

/*
** This routine is called after a single SQL statement has been
** parsed and a VDBE program to execute that statement has been
** prepared.  This routine puts the finishing touches on the
** VDBE program and resets the pParse structure for the next
** parse.
**
** Note that if an error occurred, it might be the case that
** no VDBE code was generated.
*/
void sqlite3FinishCoding(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( sqlite3ThreadDataReadOnly()->mallocFailed ) return;
  if( pParse->nested ) return;
  if( !pParse->pVdbe ){
    if( pParse->rc==SQLITE_OK && pParse->nErr ){
      pParse->rc = SQLITE_ERROR;
    }
    return;
  }







|













<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
















































































39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.1 2005/03/01 16:04:28 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
*/
void sqlite3BeginParse(Parse *pParse, int explainFlag){
  pParse->explain = explainFlag;
  pParse->nVar = 0;
}

















































































/*
** This routine is called after a single SQL statement has been
** parsed and a VDBE program to execute that statement has been
** prepared.  This routine puts the finishing touches on the
** VDBE program and resets the pParse structure for the next
** parse.
**
** Note that if an error occurred, it might be the case that
** no VDBE code was generated.
*/
void sqlite3FinishCoding(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( sqlite3_malloc_failed ) return;
  if( pParse->nested ) return;
  if( !pParse->pVdbe ){
    if( pParse->rc==SQLITE_OK && pParse->nErr ){
      pParse->rc = SQLITE_ERROR;
    }
    return;
  }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
    ** set for each database that is used.  Generate code to start a
    ** transaction on each used database and to verify the schema cookie
    ** on each used database.
    */
    if( pParse->cookieGoto>0 ){
      u32 mask;
      int iDb;
      sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);
      for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
        if( (mask & pParse->cookieMask)==0 ) continue;
        sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
        sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
      }

      /* Once all the cookies have been verified and transactions opened, 
      ** obtain the required table-locks. This is a no-op unless the 
      ** shared-cache feature is enabled.
      */
      codeTableLocks(pParse);
      sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
    }

#ifndef SQLITE_OMIT_TRACE
    /* Add a No-op that contains the complete text of the compiled SQL
    ** statement as its P3 argument.  This does not change the functionality
    ** of the program. 
    **
    ** This is used to implement sqlite3_trace().
    */
    sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql);
#endif /* SQLITE_OMIT_TRACE */
  }


  /* Get the VDBE program ready for execution
  */
  if( v && pParse->nErr==0 ){
    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
    sqlite3VdbeTrace(v, trace);
    sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3,
                         pParse->nTab+3, pParse->explain);
    pParse->rc = SQLITE_DONE;
    pParse->colNamesSet = 0;
  }else if( pParse->rc==SQLITE_OK ){
    pParse->rc = SQLITE_ERROR;
  }
  pParse->nTab = 0;
  pParse->nMem = 0;







|





<
<
<
<
<
<



<







<









|







72
73
74
75
76
77
78
79
80
81
82
83
84






85
86
87

88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    ** set for each database that is used.  Generate code to start a
    ** transaction on each used database and to verify the schema cookie
    ** on each used database.
    */
    if( pParse->cookieGoto>0 ){
      u32 mask;
      int iDb;
      sqlite3VdbeChangeP2(v, pParse->cookieGoto-1, sqlite3VdbeCurrentAddr(v));
      for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
        if( (mask & pParse->cookieMask)==0 ) continue;
        sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
        sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
      }






      sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto);
    }


    /* Add a No-op that contains the complete text of the compiled SQL
    ** statement as its P3 argument.  This does not change the functionality
    ** of the program. 
    **
    ** This is used to implement sqlite3_trace().
    */
    sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql);

  }


  /* Get the VDBE program ready for execution
  */
  if( v && pParse->nErr==0 ){
    FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
    sqlite3VdbeTrace(v, trace);
    sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3,
                         pParse->nTab+3, pParse->nMaxDepth+1, pParse->explain);
    pParse->rc = SQLITE_DONE;
    pParse->colNamesSet = 0;
  }else if( pParse->rc==SQLITE_OK ){
    pParse->rc = SQLITE_ERROR;
  }
  pParse->nTab = 0;
  pParse->nMem = 0;
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
** Not everything is nestable.  This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
** care if you decide to try to use this routine for some other purposes.
*/
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;

# define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
  char saveBuf[SAVE_SZ];

  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(zFormat, ap);
  va_end(ap);
  if( zSql==0 ){
    return;   /* A malloc must have failed */
  }
  pParse->nested++;
  memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
  memset(&pParse->nVar, 0, SAVE_SZ);
  sqlite3RunParser(pParse, zSql, 0);
  sqliteFree(zSql);
  memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
  pParse->nested--;
}

/*
** Locate the in-memory structure that describes a particular database







>














|







126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
** Not everything is nestable.  This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
** care if you decide to try to use this routine for some other purposes.
*/
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;
  int rc;
# define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
  char saveBuf[SAVE_SZ];

  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(zFormat, ap);
  va_end(ap);
  if( zSql==0 ){
    return;   /* A malloc must have failed */
  }
  pParse->nested++;
  memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
  memset(&pParse->nVar, 0, SAVE_SZ);
  rc = sqlite3RunParser(pParse, zSql, 0);
  sqliteFree(zSql);
  memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
  pParse->nested--;
}

/*
** Locate the in-memory structure that describes a particular database
250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
**
** See also sqlite3LocateTable().
*/
Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
  Table *p = 0;
  int i;
  assert( zName!=0 );

  for(i=OMIT_TEMPDB; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
    if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
    p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, strlen(zName)+1);
    if( p ) break;
  }
  return p;
}

/*
** Locate the in-memory structure that describes a particular database







>
|


|







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
**
** See also sqlite3LocateTable().
*/
Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
  Table *p = 0;
  int i;
  assert( zName!=0 );
  assert( (db->flags & SQLITE_Initialized) || db->init.busy );
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
    if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
    p = sqlite3HashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1);
    if( p ) break;
  }
  return p;
}

/*
** Locate the in-memory structure that describes a particular database
282
283
284
285
286
287
288



289
290
291
292
293
294
295
    return 0;
  }

  p = sqlite3FindTable(pParse->db, zName, zDbase);
  if( p==0 ){
    if( zDbase ){
      sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);



    }else{
      sqlite3ErrorMsg(pParse, "no such table: %s", zName);
    }
    pParse->checkSchema = 1;
  }
  return p;
}







>
>
>







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
    return 0;
  }

  p = sqlite3FindTable(pParse->db, zName, zDbase);
  if( p==0 ){
    if( zDbase ){
      sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);
    }else if( sqlite3FindTable(pParse->db, zName, 0)!=0 ){
      sqlite3ErrorMsg(pParse, "table \"%s\" is not in database \"%s\"",
         zName, zDbase);
    }else{
      sqlite3ErrorMsg(pParse, "no such table: %s", zName);
    }
    pParse->checkSchema = 1;
  }
  return p;
}
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
** for duplicate index names is done.)  The search order is
** TEMP first, then MAIN, then any auxiliary databases added
** using the ATTACH command.
*/
Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
  Index *p = 0;
  int i;

  for(i=OMIT_TEMPDB; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    Schema *pSchema = db->aDb[j].pSchema;
    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
    assert( pSchema || (j==1 && !db->aDb[1].pBt) );
    if( pSchema ){
      p = sqlite3HashFind(&pSchema->idxHash, zName, strlen(zName)+1);
    }
    if( p ) break;
  }
  return p;
}

/*
** Reclaim the memory used by an index







>
|

<

<
<
|
<







222
223
224
225
226
227
228
229
230
231

232


233

234
235
236
237
238
239
240
** for duplicate index names is done.)  The search order is
** TEMP first, then MAIN, then any auxiliary databases added
** using the ATTACH command.
*/
Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
  Index *p = 0;
  int i;
  assert( (db->flags & SQLITE_Initialized) || db->init.busy );
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */

    if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;


    p = sqlite3HashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1);

    if( p ) break;
  }
  return p;
}

/*
** Reclaim the memory used by an index
336
337
338
339
340
341
342
343
344

345

346



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
**
** The index is removed from the database hash tables but
** it is not unlinked from the Table that it indexes.
** Unlinking from the Table must be done by the calling function.
*/
static void sqliteDeleteIndex(sqlite3 *db, Index *p){
  Index *pOld;
  const char *zName = p->zName;


  pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName, strlen( zName)+1, 0);

  assert( pOld==0 || pOld==p );



  freeIndex(p);
}

/*
** For the index called zIdxName which is found in the database iDb,
** unlike that index from its Table then remove the index from
** the index hash table and free all memory structures associated
** with the index.
*/
void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
  Index *pIndex;
  int len;
  Hash *pHash = &db->aDb[iDb].pSchema->idxHash;

  len = strlen(zIdxName);
  pIndex = sqlite3HashInsert(pHash, zIdxName, len+1, 0);
  if( pIndex ){
    if( pIndex->pTable->pIndex==pIndex ){
      pIndex->pTable->pIndex = pIndex->pNext;
    }else{
      Index *p;
      for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){}
      if( p && p->pNext==pIndex ){







<

>
|
>
|
>
>
>




<
|
|
|




<


|







250
251
252
253
254
255
256

257
258
259
260
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
**
** The index is removed from the database hash tables but
** it is not unlinked from the Table that it indexes.
** Unlinking from the Table must be done by the calling function.
*/
static void sqliteDeleteIndex(sqlite3 *db, Index *p){
  Index *pOld;


  assert( db!=0 && p->zName!=0 );
  pOld = sqlite3HashInsert(&db->aDb[p->iDb].idxHash, p->zName,
                          strlen(p->zName)+1, 0);
  if( pOld!=0 && pOld!=p ){
    sqlite3HashInsert(&db->aDb[p->iDb].idxHash, pOld->zName,
                     strlen(pOld->zName)+1, pOld);
  }
  freeIndex(p);
}

/*

** Unlink the given index from its table, then remove
** the index from the index hash table and free its memory
** structures.
*/
void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
  Index *pIndex;
  int len;


  len = strlen(zIdxName);
  pIndex = sqlite3HashInsert(&db->aDb[iDb].idxHash, zIdxName, len+1, 0);
  if( pIndex ){
    if( pIndex->pTable->pIndex==pIndex ){
      pIndex->pTable->pIndex = pIndex->pNext;
    }else{
      Index *p;
      for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){}
      if( p && p->pNext==pIndex ){
383
384
385
386
387
388
389



390
391
392

393
394
395







396




397



398
399
400
401
402
403
404
405
406
407
408
409
410
411
** schema-cookie mismatch occurs.
**
** If iDb<=0 then reset the internal schema tables for all database
** files.  If iDb>=2 then reset the internal schema for only the
** single file indicated.
*/
void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){



  int i, j;

  assert( iDb>=0 && iDb<db->nDb );

  for(i=iDb; i<db->nDb; i++){
    Db *pDb = &db->aDb[i];
    if( pDb->pSchema ){







      sqlite3SchemaFree(pDb->pSchema);




    }



    if( iDb>0 ) return;
  }
  assert( iDb==0 );
  db->flags &= ~SQLITE_InternChanges;

  /* If one or more of the auxiliary database files has been closed,
  ** then remove them from the auxiliary database list.  We take the
  ** opportunity to do this here since we have just deleted all of the
  ** schema hash tables and therefore do not have to make any changes
  ** to any of those tables.
  */
  for(i=0; i<db->nDb; i++){
    struct Db *pDb = &db->aDb[i];
    if( pDb->pBt==0 ){







>
>
>



>


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

>
>
>






|







299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
** schema-cookie mismatch occurs.
**
** If iDb<=0 then reset the internal schema tables for all database
** files.  If iDb>=2 then reset the internal schema for only the
** single file indicated.
*/
void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
  HashElem *pElem;
  Hash temp1;
  Hash temp2;
  int i, j;

  assert( iDb>=0 && iDb<db->nDb );
  db->flags &= ~SQLITE_Initialized;
  for(i=iDb; i<db->nDb; i++){
    Db *pDb = &db->aDb[i];
    temp1 = pDb->tblHash;
    temp2 = pDb->trigHash;
    sqlite3HashInit(&pDb->trigHash, SQLITE_HASH_STRING, 0);
    sqlite3HashClear(&pDb->aFKey);
    sqlite3HashClear(&pDb->idxHash);
    for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
      sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
    }
    sqlite3HashClear(&temp2);
    sqlite3HashInit(&pDb->tblHash, SQLITE_HASH_STRING, 0);
    for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
      Table *pTab = sqliteHashData(pElem);
      sqlite3DeleteTable(db, pTab);
    }
    sqlite3HashClear(&temp1);
    pDb->pSeqTab = 0;
    DbClearProperty(db, i, DB_SchemaLoaded);
    if( iDb>0 ) return;
  }
  assert( iDb==0 );
  db->flags &= ~SQLITE_InternChanges;

  /* If one or more of the auxiliary database files has been closed,
  ** then remove then from the auxiliary database list.  We take the
  ** opportunity to do this here since we have just deleted all of the
  ** schema hash tables and therefore do not have to make any changes
  ** to any of those tables.
  */
  for(i=0; i<db->nDb; i++){
    struct Db *pDb = &db->aDb[i];
    if( pDb->pBt==0 ){
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
/*
** Clear the column names from a table or view.
*/
static void sqliteResetColumnNames(Table *pTable){
  int i;
  Column *pCol;
  assert( pTable!=0 );
  if( (pCol = pTable->aCol)!=0 ){
    for(i=0; i<pTable->nCol; i++, pCol++){
      sqliteFree(pCol->zName);
      sqlite3ExprDelete(pCol->pDflt);
      sqliteFree(pCol->zType);
      sqliteFree(pCol->zColl);
    }
    sqliteFree(pTable->aCol);
  }
  pTable->aCol = 0;
  pTable->nCol = 0;
}

/*
** Remove the memory data structures associated with the given
** Table.  No changes are made to disk by this routine.







<
|
|
|
|
<
|
|
<







389
390
391
392
393
394
395

396
397
398
399

400
401

402
403
404
405
406
407
408
/*
** Clear the column names from a table or view.
*/
static void sqliteResetColumnNames(Table *pTable){
  int i;
  Column *pCol;
  assert( pTable!=0 );

  for(i=0, pCol=pTable->aCol; i<pTable->nCol; i++, pCol++){
    sqliteFree(pCol->zName);
    sqlite3ExprDelete(pCol->pDflt);
    sqliteFree(pCol->zType);

  }
  sqliteFree(pTable->aCol);

  pTable->aCol = 0;
  pTable->nCol = 0;
}

/*
** Remove the memory data structures associated with the given
** Table.  No changes are made to disk by this routine.
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
** the table are deleted, but it is assumed they have already been
** unlinked.
*/
void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
  Index *pIndex, *pNext;
  FKey *pFKey, *pNextFKey;

  db = 0;

  if( pTable==0 ) return;

  /* Do not delete the table until the reference count reaches zero. */
  pTable->nRef--;
  if( pTable->nRef>0 ){
    return;
  }
  assert( pTable->nRef==0 );

  /* Delete all indices associated with this table
  */
  for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
    pNext = pIndex->pNext;
    assert( pIndex->pSchema==pTable->pSchema );
    sqliteDeleteIndex(db, pIndex);
  }

#ifndef SQLITE_OMIT_FOREIGN_KEY
  /* Delete all foreign keys associated with this table.  The keys
  ** should have already been unlinked from the db->aFKey hash table 
  */
  for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
    pNextFKey = pFKey->pNextFrom;

    assert( sqlite3HashFind(&pTable->pSchema->aFKey,
                           pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
    sqliteFree(pFKey);
  }
#endif

  /* Delete the Table structure itself.
  */
  sqliteResetColumnNames(pTable);
  sqliteFree(pTable->zName);
  sqliteFree(pTable->zColAff);
  sqlite3SelectDelete(pTable->pSelect);
#ifndef SQLITE_OMIT_CHECK
  sqlite3ExprDelete(pTable->pCheck);
#endif
  sqliteFree(pTable);
}

/*
** Unlink the given table from the hash tables and the delete the
** table structure with all its indices and foreign keys.
*/
void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
  Table *p;
  FKey *pF1, *pF2;
  Db *pDb;

  assert( db!=0 );
  assert( iDb>=0 && iDb<db->nDb );
  assert( zTabName && zTabName[0] );
  pDb = &db->aDb[iDb];
  p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, strlen(zTabName)+1,0);
  if( p ){
#ifndef SQLITE_OMIT_FOREIGN_KEY
    for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){
      int nTo = strlen(pF1->zTo) + 1;
      pF2 = sqlite3HashFind(&pDb->pSchema->aFKey, pF1->zTo, nTo);
      if( pF2==pF1 ){
        sqlite3HashInsert(&pDb->pSchema->aFKey, pF1->zTo, nTo, pF1->pNextTo);
      }else{
        while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; }
        if( pF2 ){
          pF2->pNextTo = pF1->pNextTo;
        }
      }
    }
#endif
    sqlite3DeleteTable(db, p);
  }
  db->flags |= SQLITE_InternChanges;
}

/*
** Given a token, return a string that consists of the text of that
** token with any quotations removed.  Space to hold the returned string
** is obtained from sqliteMalloc() and must be freed by the calling
** function.
**
** Tokens are often just pointers into the original SQL text and so
** are not \000 terminated and are not persistent.  The returned string
** is \000 terminated and is persistent.
*/
char *sqlite3NameFromToken(Token *pName){
  char *zName;
  if( pName ){
    zName = sqliteStrNDup((char*)pName->z, pName->n);
    sqlite3Dequote(zName);
  }else{
    zName = 0;
  }
  return zName;
}

/*
** Open the sqlite_master table stored in database number iDb for
** writing. The table is opened using cursor 0.
*/
void sqlite3OpenMasterTable(Parse *p, int iDb){
  Vdbe *v = sqlite3GetVdbe(p);
  sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
  sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT);
  sqlite3VdbeAddOp(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */
}

/*
** The token *pName contains the name of a database (either "main" or
** "temp" or the name of an attached db). This routine returns the
** index of the named database in db->aDb[], or -1 if the named db 
** does not exist.
*/
int sqlite3FindDb(sqlite3 *db, Token *pName){
  int i = -1;    /* Database number */
  int n;         /* Number of characters in the name */
  Db *pDb;       /* A database whose name space is being searched */
  char *zName;   /* Name we are searching for */

  zName = sqlite3NameFromToken(pName);
  if( zName ){
    n = strlen(zName);
    for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
      if( (!OMIT_TEMPDB || i!=1 ) && n==strlen(pDb->zName) && 
          0==sqlite3StrICmp(pDb->zName, zName) ){
        break;
      }
    }
    sqliteFree(zName);
  }
  return i;
}







<
<


<
<
<
<
<
<
<




|









>
|











<
<
<
















|




|

|



















|






|











|
<
<











|









<
|







418
419
420
421
422
423
424


425
426







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453



454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516


517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545
** the table are deleted, but it is assumed they have already been
** unlinked.
*/
void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
  Index *pIndex, *pNext;
  FKey *pFKey, *pNextFKey;



  if( pTable==0 ) return;








  /* Delete all indices associated with this table
  */
  for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
    pNext = pIndex->pNext;
    assert( pIndex->iDb==pTable->iDb || (pTable->iDb==0 && pIndex->iDb==1) );
    sqliteDeleteIndex(db, pIndex);
  }

#ifndef SQLITE_OMIT_FOREIGN_KEY
  /* Delete all foreign keys associated with this table.  The keys
  ** should have already been unlinked from the db->aFKey hash table 
  */
  for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
    pNextFKey = pFKey->pNextFrom;
    assert( pTable->iDb<db->nDb );
    assert( sqlite3HashFind(&db->aDb[pTable->iDb].aFKey,
                           pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
    sqliteFree(pFKey);
  }
#endif

  /* Delete the Table structure itself.
  */
  sqliteResetColumnNames(pTable);
  sqliteFree(pTable->zName);
  sqliteFree(pTable->zColAff);
  sqlite3SelectDelete(pTable->pSelect);



  sqliteFree(pTable);
}

/*
** Unlink the given table from the hash tables and the delete the
** table structure with all its indices and foreign keys.
*/
void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
  Table *p;
  FKey *pF1, *pF2;
  Db *pDb;

  assert( db!=0 );
  assert( iDb>=0 && iDb<db->nDb );
  assert( zTabName && zTabName[0] );
  pDb = &db->aDb[iDb];
  p = sqlite3HashInsert(&pDb->tblHash, zTabName, strlen(zTabName)+1, 0);
  if( p ){
#ifndef SQLITE_OMIT_FOREIGN_KEY
    for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){
      int nTo = strlen(pF1->zTo) + 1;
      pF2 = sqlite3HashFind(&pDb->aFKey, pF1->zTo, nTo);
      if( pF2==pF1 ){
        sqlite3HashInsert(&pDb->aFKey, pF1->zTo, nTo, pF1->pNextTo);
      }else{
        while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; }
        if( pF2 ){
          pF2->pNextTo = pF1->pNextTo;
        }
      }
    }
#endif
    sqlite3DeleteTable(db, p);
  }
  db->flags |= SQLITE_InternChanges;
}

/*
** Given a token, return a string that consists of the text of that
** token with any quotations removed.  Space to hold the returned string
** is obtained from sqliteMalloc() and must be freed by the calling
** function.
**
** Tokens are really just pointers into the original SQL text and so
** are not \000 terminated and are not persistent.  The returned string
** is \000 terminated and is persistent.
*/
char *sqlite3NameFromToken(Token *pName){
  char *zName;
  if( pName ){
    zName = sqliteStrNDup(pName->z, pName->n);
    sqlite3Dequote(zName);
  }else{
    zName = 0;
  }
  return zName;
}

/*
** Open the sqlite_master table stored in database number iDb for
** writing. The table is opened using cursor 0.
*/
void sqlite3OpenMasterTable(Vdbe *v, int iDb){


  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
  sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT);
  sqlite3VdbeAddOp(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */
}

/*
** The token *pName contains the name of a database (either "main" or
** "temp" or the name of an attached db). This routine returns the
** index of the named database in db->aDb[], or -1 if the named db 
** does not exist.
*/
static int findDb(sqlite3 *db, Token *pName){
  int i = -1;    /* Database number */
  int n;         /* Number of characters in the name */
  Db *pDb;       /* A database whose name space is being searched */
  char *zName;   /* Name we are searching for */

  zName = sqlite3NameFromToken(pName);
  if( zName ){
    n = strlen(zName);
    for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){

      if( n==strlen(pDb->zName) && 0==sqlite3StrICmp(pDb->zName, zName) ){
        break;
      }
    }
    sqliteFree(zName);
  }
  return i;
}
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
){
  int iDb;                    /* Database holding the object */
  sqlite3 *db = pParse->db;

  if( pName2 && pName2->n>0 ){
    assert( !db->init.busy );
    *pUnqual = pName2;
    iDb = sqlite3FindDb(db, pName1);
    if( iDb<0 ){
      sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
      pParse->nErr++;
      return -1;
    }
  }else{
    assert( db->init.iDb==0 || db->init.busy );







|







568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
){
  int iDb;                    /* Database holding the object */
  sqlite3 *db = pParse->db;

  if( pName2 && pName2->n>0 ){
    assert( !db->init.busy );
    *pUnqual = pName2;
    iDb = findDb(db, pName1);
    if( iDb<0 ){
      sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
      pParse->nErr++;
      return -1;
    }
  }else{
    assert( db->init.iDb==0 || db->init.busy );
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
** unqualified name for a new schema object (table, index, view or
** trigger). All names are legal except those that begin with the string
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
** is reserved for internal use.
*/
int sqlite3CheckObjectName(Parse *pParse, const char *zName){
  if( !pParse->db->init.busy && pParse->nested==0 
          && (pParse->db->flags & SQLITE_WriteSchema)==0
          && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
    sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
    return SQLITE_ERROR;
  }
  return SQLITE_OK;
}








<







591
592
593
594
595
596
597

598
599
600
601
602
603
604
** unqualified name for a new schema object (table, index, view or
** trigger). All names are legal except those that begin with the string
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
** is reserved for internal use.
*/
int sqlite3CheckObjectName(Parse *pParse, const char *zName){
  if( !pParse->db->init.busy && pParse->nested==0 

          && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
    sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
    return SQLITE_ERROR;
  }
  return SQLITE_OK;
}

705
706
707
708
709
710
711
712
713
714
715

716
717
718
719
720
721
722
*/
void sqlite3StartTable(
  Parse *pParse,   /* Parser context */
  Token *pStart,   /* The "CREATE" token */
  Token *pName1,   /* First part of the name of the table or view */
  Token *pName2,   /* Second part of the name of the table or view */
  int isTemp,      /* True if this is a TEMP table */
  int isView,      /* True if this is a VIEW */
  int noErr        /* Do nothing if table already exists */
){
  Table *pTable;

  char *zName = 0; /* The name of the new table */
  sqlite3 *db = pParse->db;
  Vdbe *v;
  int iDb;         /* Database number to create the table in */
  Token *pName;    /* Unqualified name of the table to create */

  /* The table or view name to create is passed to this routine via tokens







|
<


>







621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
636
637
638
*/
void sqlite3StartTable(
  Parse *pParse,   /* Parser context */
  Token *pStart,   /* The "CREATE" token */
  Token *pName1,   /* First part of the name of the table or view */
  Token *pName2,   /* Second part of the name of the table or view */
  int isTemp,      /* True if this is a TEMP table */
  int isView       /* True if this is a VIEW */

){
  Table *pTable;
  Index *pIdx;
  char *zName = 0; /* The name of the new table */
  sqlite3 *db = pParse->db;
  Vdbe *v;
  int iDb;         /* Database number to create the table in */
  Token *pName;    /* Unqualified name of the table to create */

  /* The table or view name to create is passed to this routine via tokens
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795

796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
  ** The call below sets the pName pointer to point at the token (pName1 or
  ** pName2) that stores the unqualified table name. The variable iDb is
  ** set to the index of the database that the table or view is to be
  ** created in.
  */
  iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
  if( iDb<0 ) return;
  if( !OMIT_TEMPDB && isTemp && iDb>1 ){
    /* If creating a temp table, the name may not be qualified */
    sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
    return;
  }
  if( !OMIT_TEMPDB && isTemp ) iDb = 1;

  pParse->sNameToken = *pName;
  zName = sqlite3NameFromToken(pName);
  if( zName==0 ) return;
  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
    goto begin_table_error;
  }
  if( db->init.iDb==1 ) isTemp = 1;
#ifndef SQLITE_OMIT_AUTHORIZATION
  assert( (isTemp & 1)==isTemp );
  {
    int code;
    char *zDb = db->aDb[iDb].zName;
    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
      goto begin_table_error;
    }
    if( isView ){
      if( !OMIT_TEMPDB && isTemp ){
        code = SQLITE_CREATE_TEMP_VIEW;
      }else{
        code = SQLITE_CREATE_VIEW;
      }
    }else{
      if( !OMIT_TEMPDB && isTemp ){
        code = SQLITE_CREATE_TEMP_TABLE;
      }else{
        code = SQLITE_CREATE_TABLE;
      }
    }
    if( sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){
      goto begin_table_error;
    }
  }
#endif

  /* Make sure the new table name does not collide with an existing
  ** index or table name in the same database.  Issue an error message if
  ** it does.
  */
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto begin_table_error;
  }
  pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);
  if( pTable ){
    if( !noErr ){
      sqlite3ErrorMsg(pParse, "table %T already exists", pName);
    }
    goto begin_table_error;
  }

  if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){
    sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
    goto begin_table_error;
  }
  pTable = sqliteMalloc( sizeof(Table) );
  if( pTable==0 ){
    pParse->rc = SQLITE_NOMEM;
    pParse->nErr++;
    goto begin_table_error;
  }
  pTable->zName = zName;
  pTable->nCol = 0;
  pTable->aCol = 0;
  pTable->iPKey = -1;
  pTable->pIndex = 0;
  pTable->pSchema = db->aDb[iDb].pSchema;
  pTable->nRef = 1;
  if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable);
  pParse->pNewTable = pTable;

  /* If this is the magic sqlite_sequence table used by autoincrement,
  ** then record a pointer to this table in the main database structure
  ** so that INSERT can find the table easily.
  */
#ifndef SQLITE_OMIT_AUTOINCREMENT
  if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){
    pTable->pSchema->pSeqTab = pTable;
  }
#endif

  /* Begin generating the code that will insert the table record into
  ** the SQLITE_MASTER table.  Note in particular that we must go ahead
  ** and allocate the record number for the table entry now.  Before any
  ** PRIMARY KEY or UNIQUE keywords are parsed.  Those keywords will cause
  ** indices to be created and the table record must come before the 
  ** indices.  Hence, the record number for the table must be allocated
  ** now.
  */
  if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
    int lbl;
    int fileFormat;
    sqlite3BeginWriteOperation(pParse, 0, iDb);

    /* If the file format and encoding in the database have not been set, 
    ** set them now.
    */
    sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);   /* file_format */
    lbl = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_If, 0, lbl);
    fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
                  1 : SQLITE_DEFAULT_FILE_FORMAT;
    sqlite3VdbeAddOp(v, OP_Integer, fileFormat, 0);
    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
    sqlite3VdbeAddOp(v, OP_Integer, ENC(db), 0);
    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
    sqlite3VdbeResolveLabel(v, lbl);

    /* This just creates a place-holder record in the sqlite_master table.
    ** The record created does not contain anything yet.  It will be replaced
    ** by the real entry in code generated at sqlite3EndTable().
    **
    ** The rowid for the new entry is left on the top of the stack.
    ** The rowid value is needed by the code that sqlite3EndTable will
    ** generate.
    */
#ifndef SQLITE_OMIT_VIEW
    if( isView ){
      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
    }else
#endif
    {
      sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0);
    }
    sqlite3OpenMasterTable(pParse, iDb);
    sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0);
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    sqlite3VdbeAddOp(v, OP_Null, 0, 0);
    sqlite3VdbeAddOp(v, OP_Insert, 0, 0);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
  }

  /* Normal (non-error) return. */
  return;








|




|

















|





|




















<
|
<


>
|














<
|








|
|













<








<
<
|

|



















|
|

|
|







650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706

707

708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749

750
751
752
753
754
755
756
757


758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
  ** The call below sets the pName pointer to point at the token (pName1 or
  ** pName2) that stores the unqualified table name. The variable iDb is
  ** set to the index of the database that the table or view is to be
  ** created in.
  */
  iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
  if( iDb<0 ) return;
  if( isTemp && iDb>1 ){
    /* If creating a temp table, the name may not be qualified */
    sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
    return;
  }
  if( isTemp ) iDb = 1;

  pParse->sNameToken = *pName;
  zName = sqlite3NameFromToken(pName);
  if( zName==0 ) return;
  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
    goto begin_table_error;
  }
  if( db->init.iDb==1 ) isTemp = 1;
#ifndef SQLITE_OMIT_AUTHORIZATION
  assert( (isTemp & 1)==isTemp );
  {
    int code;
    char *zDb = db->aDb[iDb].zName;
    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
      goto begin_table_error;
    }
    if( isView ){
      if( isTemp ){
        code = SQLITE_CREATE_TEMP_VIEW;
      }else{
        code = SQLITE_CREATE_VIEW;
      }
    }else{
      if( isTemp ){
        code = SQLITE_CREATE_TEMP_TABLE;
      }else{
        code = SQLITE_CREATE_TABLE;
      }
    }
    if( sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){
      goto begin_table_error;
    }
  }
#endif

  /* Make sure the new table name does not collide with an existing
  ** index or table name in the same database.  Issue an error message if
  ** it does.
  */
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto begin_table_error;
  }
  pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName);
  if( pTable ){

    sqlite3ErrorMsg(pParse, "table %T already exists", pName);

    goto begin_table_error;
  }
  if( (pIdx = sqlite3FindIndex(db, zName, 0))!=0 && 
      ( iDb==0 || !db->init.busy) ){
    sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
    goto begin_table_error;
  }
  pTable = sqliteMalloc( sizeof(Table) );
  if( pTable==0 ){
    pParse->rc = SQLITE_NOMEM;
    pParse->nErr++;
    goto begin_table_error;
  }
  pTable->zName = zName;
  pTable->nCol = 0;
  pTable->aCol = 0;
  pTable->iPKey = -1;
  pTable->pIndex = 0;

  pTable->iDb = iDb;
  if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable);
  pParse->pNewTable = pTable;

  /* If this is the magic sqlite_sequence table used by autoincrement,
  ** then record a pointer to this table in the main database structure
  ** so that INSERT can find the table easily.
  */
#ifndef SQLITE_OMIT_AUTOINCREMENT
  if( strcmp(zName, "sqlite_sequence")==0 ){
    db->aDb[iDb].pSeqTab = pTable;
  }
#endif

  /* Begin generating the code that will insert the table record into
  ** the SQLITE_MASTER table.  Note in particular that we must go ahead
  ** and allocate the record number for the table entry now.  Before any
  ** PRIMARY KEY or UNIQUE keywords are parsed.  Those keywords will cause
  ** indices to be created and the table record must come before the 
  ** indices.  Hence, the record number for the table must be allocated
  ** now.
  */
  if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
    int lbl;

    sqlite3BeginWriteOperation(pParse, 0, iDb);

    /* If the file format and encoding in the database have not been set, 
    ** set them now.
    */
    sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);   /* file_format */
    lbl = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_If, 0, lbl);


    sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0);
    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
    sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
    sqlite3VdbeResolveLabel(v, lbl);

    /* This just creates a place-holder record in the sqlite_master table.
    ** The record created does not contain anything yet.  It will be replaced
    ** by the real entry in code generated at sqlite3EndTable().
    **
    ** The rowid for the new entry is left on the top of the stack.
    ** The rowid value is needed by the code that sqlite3EndTable will
    ** generate.
    */
#ifndef SQLITE_OMIT_VIEW
    if( isView ){
      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
    }else
#endif
    {
      sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0);
    }
    sqlite3OpenMasterTable(v, iDb);
    sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0);
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
  }

  /* Normal (non-error) return. */
  return;

919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940

941
942
943
944
945
946
947
      sqliteFree(z);
      return;
    }
  }
  if( (p->nCol & 0x7)==0 ){
    Column *aNew;
    aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
    if( aNew==0 ){
      sqliteFree(z);
      return;
    }
    p->aCol = aNew;
  }
  pCol = &p->aCol[p->nCol];
  memset(pCol, 0, sizeof(p->aCol[0]));
  pCol->zName = z;
 
  /* If there is no type specified, columns have the default affinity
  ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will
  ** be called next to set pCol->affinity correctly.
  */
  pCol->affinity = SQLITE_AFF_NONE;

  p->nCol++;
}

/*
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.  A "NOT NULL" constraint has
** been seen on a column.  This routine sets the notNull flag on







|
<
<
<











>







830
831
832
833
834
835
836
837



838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
      sqliteFree(z);
      return;
    }
  }
  if( (p->nCol & 0x7)==0 ){
    Column *aNew;
    aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
    if( aNew==0 ) return;



    p->aCol = aNew;
  }
  pCol = &p->aCol[p->nCol];
  memset(pCol, 0, sizeof(p->aCol[0]));
  pCol->zName = z;
 
  /* If there is no type specified, columns have the default affinity
  ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will
  ** be called next to set pCol->affinity correctly.
  */
  pCol->affinity = SQLITE_AFF_NONE;
  pCol->pColl = pParse->db->pDfltColl;
  p->nCol++;
}

/*
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.  A "NOT NULL" constraint has
** been seen on a column.  This routine sets the notNull flag on
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032

1033

1034

1035
1036
1037
1038


1039
1040







1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
** Substring     | Affinity
** --------------------------------
** 'INT'         | SQLITE_AFF_INTEGER
** 'CHAR'        | SQLITE_AFF_TEXT
** 'CLOB'        | SQLITE_AFF_TEXT
** 'TEXT'        | SQLITE_AFF_TEXT
** 'BLOB'        | SQLITE_AFF_NONE
** 'REAL'        | SQLITE_AFF_REAL
** 'FLOA'        | SQLITE_AFF_REAL
** 'DOUB'        | SQLITE_AFF_REAL
**
** If none of the substrings in the above table are found,
** SQLITE_AFF_NUMERIC is returned.
*/
char sqlite3AffinityType(const Token *pType){
  u32 h = 0;
  char aff = SQLITE_AFF_NUMERIC;
  const unsigned char *zIn = pType->z;
  const unsigned char *zEnd = &pType->z[pType->n];

  while( zIn!=zEnd ){
    h = (h<<8) + sqlite3UpperToLower[*zIn];
    zIn++;
    if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){             /* CHAR */
      aff = SQLITE_AFF_TEXT; 
    }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){       /* CLOB */
      aff = SQLITE_AFF_TEXT;
    }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){       /* TEXT */
      aff = SQLITE_AFF_TEXT;
    }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b')          /* BLOB */
        && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){
      aff = SQLITE_AFF_NONE;
#ifndef SQLITE_OMIT_FLOATING_POINT
    }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l')          /* REAL */
        && aff==SQLITE_AFF_NUMERIC ){
      aff = SQLITE_AFF_REAL;
    }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a')          /* FLOA */
        && aff==SQLITE_AFF_NUMERIC ){
      aff = SQLITE_AFF_REAL;
    }else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b')          /* DOUB */
        && aff==SQLITE_AFF_NUMERIC ){
      aff = SQLITE_AFF_REAL;
#endif
    }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){    /* INT */
      aff = SQLITE_AFF_INTEGER;
      break;
    }
  }

  return aff;
}

/*
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.  The pFirst token is the first
** token in the sequence of tokens that describe the type of the
** column currently under construction.   pLast is the last token
** in the sequence.  Use this information to construct a string
** that contains the typename of the column and store that string
** in zType.
*/ 
void sqlite3AddColumnType(Parse *pParse, Token *pType){
  Table *p;
  int i;

  Column *pCol;



  if( (p = pParse->pNewTable)==0 ) return;
  i = p->nCol-1;
  if( i<0 ) return;
  pCol = &p->aCol[i];


  sqliteFree(pCol->zType);
  pCol->zType = sqlite3NameFromToken(pType);







  pCol->affinity = sqlite3AffinityType(pType);
}

/*
** The expression is the default value for the most recently added column
** of the table currently under construction.
**
** Default value expressions must be constant.  Raise an exception if this
** is not the case.
**
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.
*/
void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
  Table *p;
  Column *pCol;
  if( (p = pParse->pNewTable)!=0 ){
    pCol = &(p->aCol[p->nCol-1]);
    if( !sqlite3ExprIsConstantOrFunction(pExpr) ){
      sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
          pCol->zName);
    }else{
      sqlite3ExprDelete(pCol->pDflt);
      pCol->pDflt = sqlite3ExprDup(pExpr);
    }
  }
  sqlite3ExprDelete(pExpr);
}

/*
** Designate the PRIMARY KEY for the table.  pList is a list of names 
** of columns that form the primary key.  If pList is NULL, then the







<
<
<




|


|
|











<
<
<
<

|
<
<
<
<
<
<
<

|
















|

|
>
|
>

>




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















|
|
|
|
|
|
|
|
<







878
879
880
881
882
883
884



885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904




905
906







907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971

972
973
974
975
976
977
978
** Substring     | Affinity
** --------------------------------
** 'INT'         | SQLITE_AFF_INTEGER
** 'CHAR'        | SQLITE_AFF_TEXT
** 'CLOB'        | SQLITE_AFF_TEXT
** 'TEXT'        | SQLITE_AFF_TEXT
** 'BLOB'        | SQLITE_AFF_NONE



**
** If none of the substrings in the above table are found,
** SQLITE_AFF_NUMERIC is returned.
*/
static char sqlite3AffinityType(const char *zType, int nType){
  u32 h = 0;
  char aff = SQLITE_AFF_NUMERIC;
  const unsigned char *zIn = zType;
  const unsigned char *zEnd = (zIn+nType);

  while( zIn!=zEnd ){
    h = (h<<8) + sqlite3UpperToLower[*zIn];
    zIn++;
    if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){             /* CHAR */
      aff = SQLITE_AFF_TEXT; 
    }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){       /* CLOB */
      aff = SQLITE_AFF_TEXT;
    }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){       /* TEXT */
      aff = SQLITE_AFF_TEXT;
    }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b')          /* BLOB */




        && aff==SQLITE_AFF_NUMERIC ){
      aff = SQLITE_AFF_NONE;







    }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){    /* INT */
      aff = SQLITE_AFF_INTEGER; 
      break;
    }
  }

  return aff;
}

/*
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.  The pFirst token is the first
** token in the sequence of tokens that describe the type of the
** column currently under construction.   pLast is the last token
** in the sequence.  Use this information to construct a string
** that contains the typename of the column and store that string
** in zType.
*/ 
void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){
  Table *p;
  int i, j;
  int n;
  char *z;
  const unsigned char *zIn;

  Column *pCol;
  if( (p = pParse->pNewTable)==0 ) return;
  i = p->nCol-1;
  if( i<0 ) return;
  pCol = &p->aCol[i];
  zIn = pFirst->z;
  n = pLast->n + (pLast->z - zIn);
  assert( pCol->zType==0 );
  z = pCol->zType = sqliteMallocRaw(n+1);
  if( z==0 ) return;
  for(i=j=0; i<n; i++){
    int c = zIn[i];
    if( isspace(c) ) continue;
    z[j++] = c;
  }
  z[j] = 0;
  pCol->affinity = sqlite3AffinityType(z, n);
}

/*
** The expression is the default value for the most recently added column
** of the table currently under construction.
**
** Default value expressions must be constant.  Raise an exception if this
** is not the case.
**
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.
*/
void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
  Table *p;
  Column *pCol;
  if( (p = pParse->pNewTable)==0 ) return;
  pCol = &(p->aCol[p->nCol-1]);
  if( !sqlite3ExprIsConstant(pExpr) ){
    sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
        pCol->zName);
  }else{
    sqlite3ExprDelete(pCol->pDflt);
    pCol->pDflt = sqlite3ExprDup(pExpr);

  }
  sqlite3ExprDelete(pExpr);
}

/*
** Designate the PRIMARY KEY for the table.  pList is a list of names 
** of columns that form the primary key.  If pList is NULL, then the
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
** If the key is not an INTEGER PRIMARY KEY, then create a unique
** index for the key.  No index is created for INTEGER PRIMARY KEYs.
*/
void sqlite3AddPrimaryKey(
  Parse *pParse,    /* Parsing context */
  ExprList *pList,  /* List of field names to be indexed */
  int onError,      /* What to do with a uniqueness conflict */
  int autoInc,      /* True if the AUTOINCREMENT keyword is present */
  int sortOrder     /* SQLITE_SO_ASC or SQLITE_SO_DESC */
){
  Table *pTab = pParse->pNewTable;
  char *zType = 0;
  int iCol = -1, i;
  if( pTab==0 ) goto primary_key_exit;
  if( pTab->hasPrimKey ){
    sqlite3ErrorMsg(pParse, 







|
<







991
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
** If the key is not an INTEGER PRIMARY KEY, then create a unique
** index for the key.  No index is created for INTEGER PRIMARY KEYs.
*/
void sqlite3AddPrimaryKey(
  Parse *pParse,    /* Parsing context */
  ExprList *pList,  /* List of field names to be indexed */
  int onError,      /* What to do with a uniqueness conflict */
  int autoInc       /* True if the AUTOINCREMENT keyword is present */

){
  Table *pTab = pParse->pNewTable;
  char *zType = 0;
  int iCol = -1, i;
  if( pTab==0 ) goto primary_key_exit;
  if( pTab->hasPrimKey ){
    sqlite3ErrorMsg(pParse, 
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168


1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180










































































































































1181
1182






1183






1184

1185


1186
1187
1188

1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212



1213

1214



1215
1216

1217
1218
1219
1220
1221
1222







1223
1224
1225
1226
1227
1228
1229
  }else{
    for(i=0; i<pList->nExpr; i++){
      for(iCol=0; iCol<pTab->nCol; iCol++){
        if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
          break;
        }
      }
      if( iCol<pTab->nCol ){
        pTab->aCol[iCol].isPrimKey = 1;
      }
    }
    if( pList->nExpr>1 ) iCol = -1;
  }
  if( iCol>=0 && iCol<pTab->nCol ){
    zType = pTab->aCol[iCol].zType;
  }
  if( zType && sqlite3StrICmp(zType, "INTEGER")==0
        && sortOrder==SQLITE_SO_ASC ){
    pTab->iPKey = iCol;
    pTab->keyConf = onError;
    pTab->autoInc = autoInc;
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else{
    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
    pList = 0;
  }

primary_key_exit:
  sqlite3ExprListDelete(pList);
  return;
}

/*
** Add a new CHECK constraint to the table currently under construction.
*/
void sqlite3AddCheckConstraint(
  Parse *pParse,    /* Parsing context */
  Expr *pCheckExpr  /* The check expression */
){
#ifndef SQLITE_OMIT_CHECK
  Table *pTab = pParse->pNewTable;
  if( pTab ){
    /* The CHECK expression must be duplicated so that tokens refer
    ** to malloced space and not the (ephemeral) text of the CREATE TABLE
    ** statement */
    pTab->pCheck = sqlite3ExprAnd(pTab->pCheck, sqlite3ExprDup(pCheckExpr));
  }
#endif
  sqlite3ExprDelete(pCheckExpr);
}

/*
** Set the collation function of the most recently parsed table column
** to the CollSeq given.
*/
void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){
  Table *p;


  int i;

  if( (p = pParse->pNewTable)==0 ) return;
  i = p->nCol-1;

  if( sqlite3LocateCollSeq(pParse, zType, nType) ){
    Index *pIdx;
    p->aCol[i].zColl = sqliteStrNDup(zType, nType);
  
    /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
    ** then an index may have been created on this column before the
    ** collation type was added. Correct this if it is the case.










































































































































    */
    for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){






      assert( pIdx->nColumn==1 );






      if( pIdx->aiColumn[0]==i ){

        pIdx->azColl[0] = p->aCol[i].zColl;


      }
    }
  }

}

/*
** This function returns the collation sequence for database native text
** encoding identified by the string zName, length nName.
**
** If the requested collation sequence is not available, or not available
** in the database native encoding, the collation factory is invoked to
** request it. If the collation factory does not supply such a sequence,
** and the sequence is available in another text encoding, then that is
** returned instead.
**
** If no versions of the requested collations sequence are available, or
** another error occurs, NULL is returned and an error message written into
** pParse.
*/
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
  sqlite3 *db = pParse->db;
  u8 enc = ENC(db);
  u8 initbusy = db->init.busy;
  CollSeq *pColl;

  pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy);
  if( !initbusy && (!pColl || !pColl->xCmp) ){



    pColl = sqlite3GetCollSeq(db, pColl, zName, nName);

    if( !pColl ){



      if( nName<0 ){
        nName = strlen(zName);

      }
      sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName);
      pColl = 0;
    }
  }








  return pColl;
}


/*
** Generate code that will increment the schema cookie.
**







|
<
<






|
<









|








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






>
>





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

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



>

















<
|
|
|
|
<

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

<
<



>
>
>
>
>
>
>







1013
1014
1015
1016
1017
1018
1019
1020


1021
1022
1023
1024
1025
1026
1027

1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045



















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

1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243

1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258

1259
1260


1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
  }else{
    for(i=0; i<pList->nExpr; i++){
      for(iCol=0; iCol<pTab->nCol; iCol++){
        if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
          break;
        }
      }
      if( iCol<pTab->nCol ) pTab->aCol[iCol].isPrimKey = 1;


    }
    if( pList->nExpr>1 ) iCol = -1;
  }
  if( iCol>=0 && iCol<pTab->nCol ){
    zType = pTab->aCol[iCol].zType;
  }
  if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){

    pTab->iPKey = iCol;
    pTab->keyConf = onError;
    pTab->autoInc = autoInc;
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
    sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
       "INTEGER PRIMARY KEY");
#endif
  }else{
    sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0);
    pList = 0;
  }

primary_key_exit:
  sqlite3ExprListDelete(pList);
  return;
}




















/*
** Set the collation function of the most recently parsed table column
** to the CollSeq given.
*/
void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){
  Table *p;
  Index *pIdx;
  CollSeq *pColl;
  int i;

  if( (p = pParse->pNewTable)==0 ) return;
  i = p->nCol-1;

  pColl = sqlite3LocateCollSeq(pParse, zType, nType);

  p->aCol[i].pColl = pColl;

  /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
  ** then an index may have been created on this column before the
  ** collation type was added. Correct this if it is the case.
  */
  for(pIdx = p->pIndex; pIdx; pIdx=pIdx->pNext){
    assert( pIdx->nColumn==1 );
    if( pIdx->aiColumn[0]==i ) pIdx->keyInfo.aColl[0] = pColl;
  }
}

/*
** Locate and return an entry from the db.aCollSeq hash table. If the entry
** specified by zName and nName is not found and parameter 'create' is
** true, then create a new entry. Otherwise return NULL.
**
** Each pointer stored in the sqlite3.aCollSeq hash table contains an
** array of three CollSeq structures. The first is the collation sequence
** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
**
** Stored immediately after the three collation sequences is a copy of
** the collation sequence name. A pointer to this string is stored in
** each collation sequence structure.
*/
static CollSeq * findCollSeqEntry(
  sqlite3 *db,
  const char *zName,
  int nName,
  int create
){
  CollSeq *pColl;
  if( nName<0 ) nName = strlen(zName);
  pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);

  if( 0==pColl && create ){
    pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );
    if( pColl ){
      pColl[0].zName = (char*)&pColl[3];
      pColl[0].enc = SQLITE_UTF8;
      pColl[1].zName = (char*)&pColl[3];
      pColl[1].enc = SQLITE_UTF16LE;
      pColl[2].zName = (char*)&pColl[3];
      pColl[2].enc = SQLITE_UTF16BE;
      memcpy(pColl[0].zName, zName, nName);
      pColl[0].zName[nName] = 0;
      sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
    }
  }
  return pColl;
}

/*
** Parameter zName points to a UTF-8 encoded string nName bytes long.
** Return the CollSeq* pointer for the collation sequence named zName
** for the encoding 'enc' from the database 'db'.
**
** If the entry specified is not found and 'create' is true, then create a
** new entry.  Otherwise return NULL.
*/
CollSeq *sqlite3FindCollSeq(
  sqlite3 *db,
  u8 enc,
  const char *zName,
  int nName,
  int create
){
  CollSeq *pColl = findCollSeqEntry(db, zName, nName, create);
  assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
  assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
  if( pColl ) pColl += enc-1;
  return pColl;
}

/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
** If the collation sequence
*/
static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
  assert( !db->xCollNeeded || !db->xCollNeeded16 );
  if( nName<0 ) nName = strlen(zName);
  if( db->xCollNeeded ){
    char *zExternal = sqliteStrNDup(zName, nName);
    if( !zExternal ) return;
    db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal);
    sqliteFree(zExternal);
  }
#ifndef SQLITE_OMIT_UTF16
  if( db->xCollNeeded16 ){
    char const *zExternal;
    sqlite3_value *pTmp = sqlite3GetTransientValue(db);
    sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
    zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
    if( !zExternal ) return;
    db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal);
  }
#endif
}

/*
** This routine is called if the collation factory fails to deliver a
** collation function in the best encoding but there may be other versions
** of this collation function (for other text encodings) available. Use one
** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
** possible.
*/
static int synthCollSeq(Parse *pParse, CollSeq *pColl){
  CollSeq *pColl2;
  char *z = pColl->zName;
  int n = strlen(z);
  sqlite3 *db = pParse->db;
  int i;
  static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
  for(i=0; i<3; i++){
    pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
    if( pColl2->xCmp!=0 ){
      memcpy(pColl, pColl2, sizeof(CollSeq));
      return SQLITE_OK;
    }
  }
  if( pParse->nErr==0 ){
    sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", n, z);
  }
  pParse->nErr++;
  return SQLITE_ERROR;
}

/*
** This routine is called on a collation sequence before it is used to
** check that it is defined. An undefined collation sequence exists when
** a database is loaded that contains references to collation sequences
** that have not been defined by sqlite3_create_collation() etc.
**
** If required, this routine calls the 'collation needed' callback to
** request a definition of the collating sequence. If this doesn't work, 
** an equivalent collating sequence that uses a text encoding different
** from the main database is substituted, if one is available.
*/
int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
  if( pColl && !pColl->xCmp ){
    /* No collation sequence of this type for this encoding is registered.
    ** Call the collation factory to see if it can supply us with one.
    */
    callCollNeeded(pParse->db, pColl->zName, strlen(pColl->zName));
    if( !pColl->xCmp && synthCollSeq(pParse, pColl) ){
      return SQLITE_ERROR;
    }
  }
  return SQLITE_OK;
}

/*
** Call sqlite3CheckCollSeq() for all collating sequences in an index,
** in order to verify that all the necessary collating sequences are
** loaded.
*/
int sqlite3CheckIndexCollSeq(Parse *pParse, Index *pIdx){
  if( pIdx ){
    int i;
    for(i=0; i<pIdx->nColumn; i++){
      if( sqlite3CheckCollSeq(pParse, pIdx->keyInfo.aColl[i]) ){
        return SQLITE_ERROR;
      }
    }
  }
  return SQLITE_OK;
}

/*
** This function returns the collation sequence for database native text
** encoding identified by the string zName, length nName.
**
** If the requested collation sequence is not available, or not available
** in the database native encoding, the collation factory is invoked to
** request it. If the collation factory does not supply such a sequence,
** and the sequence is available in another text encoding, then that is
** returned instead.
**
** If no versions of the requested collations sequence are available, or
** another error occurs, NULL is returned and an error message written into
** pParse.
*/
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){

  u8 enc = pParse->db->enc;
  u8 initbusy = pParse->db->init.busy;
  CollSeq *pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, initbusy);
  if( nName<0 ) nName = strlen(zName);

  if( !initbusy && (!pColl || !pColl->xCmp) ){
    /* No collation sequence of this type for this encoding is registered.
    ** Call the collation factory to see if it can supply us with one.
    */
    callCollNeeded(pParse->db, zName, nName);
    pColl = sqlite3FindCollSeq(pParse->db, enc, zName, nName, 0);
    if( pColl && !pColl->xCmp ){
      /* There may be a version of the collation sequence that requires
      ** translation between encodings. Search for it with synthCollSeq().
      */
      if( synthCollSeq(pParse, pColl) ){

        return 0;
      }


    }
  }

  /* If nothing has been found, write the error message into pParse */
  if( !initbusy && (!pColl || !pColl->xCmp) ){
    if( pParse->nErr==0 ){
      sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName);
    }
    pColl = 0;
  }
  return pColl;
}


/*
** Generate code that will increment the schema cookie.
**
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
** This plan is not completely bullet-proof.  It is possible for
** the schema to change multiple times and for the cookie to be
** set back to prior value.  But schema changes are infrequent
** and the probability of hitting the same cookie value is only
** 1 chance in 2^32.  So we're safe enough.
*/
void sqlite3ChangeCookie(sqlite3 *db, Vdbe *v, int iDb){
  sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, 0);
  sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
}

/*
** Measure the number of characters needed to output the given
** identifier.  The number returned includes any quotes used
** but does not include the null terminator.







|







1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
** This plan is not completely bullet-proof.  It is possible for
** the schema to change multiple times and for the cookie to be
** set back to prior value.  But schema changes are infrequent
** and the probability of hitting the same cookie value is only
** 1 chance in 2^32.  So we're safe enough.
*/
void sqlite3ChangeCookie(sqlite3 *db, Vdbe *v, int iDb){
  sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].schema_cookie+1, 0);
  sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0);
}

/*
** Measure the number of characters needed to output the given
** identifier.  The number returned includes any quotes used
** but does not include the null terminator.
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
}

/*
** Generate a CREATE TABLE statement appropriate for the given
** table.  Memory to hold the text of the statement is obtained
** from sqliteMalloc() and must be freed by the calling function.
*/
static char *createTableStmt(Table *p, int isTemp){
  int i, k, n;
  char *zStmt;
  char *zSep, *zSep2, *zEnd, *z;
  Column *pCol;
  n = 0;
  for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
    n += identLength(pCol->zName);







|







1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
}

/*
** Generate a CREATE TABLE statement appropriate for the given
** table.  Memory to hold the text of the statement is obtained
** from sqliteMalloc() and must be freed by the calling function.
*/
static char *createTableStmt(Table *p){
  int i, k, n;
  char *zStmt;
  char *zSep, *zSep2, *zEnd, *z;
  Column *pCol;
  n = 0;
  for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
    n += identLength(pCol->zName);
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
    zSep = "\n  ";
    zSep2 = ",\n  ";
    zEnd = "\n)";
  }
  n += 35 + 6*p->nCol;
  zStmt = sqliteMallocRaw( n );
  if( zStmt==0 ) return 0;
  strcpy(zStmt, !OMIT_TEMPDB&&isTemp ? "CREATE TEMP TABLE ":"CREATE TABLE ");
  k = strlen(zStmt);
  identPut(zStmt, &k, p->zName);
  zStmt[k++] = '(';
  for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
    strcpy(&zStmt[k], zSep);
    k += strlen(&zStmt[k]);
    zSep = zSep2;







|







1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
    zSep = "\n  ";
    zSep2 = ",\n  ";
    zEnd = "\n)";
  }
  n += 35 + 6*p->nCol;
  zStmt = sqliteMallocRaw( n );
  if( zStmt==0 ) return 0;
  strcpy(zStmt, p->iDb==1 ? "CREATE TEMP TABLE " : "CREATE TABLE ");
  k = strlen(zStmt);
  identPut(zStmt, &k, p->zName);
  zStmt[k++] = '(';
  for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
    strcpy(&zStmt[k], zSep);
    k += strlen(&zStmt[k]);
    zSep = zSep2;
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
** is added to the internal hash tables, assuming no errors have
** occurred.
**
** An entry for the table is made in the master table on disk, unless
** this is a temporary table or db->init.busy==1.  When db->init.busy==1
** it means we are reading the sqlite_master table because we just
** connected to the database or because the sqlite_master table has
** recently changed, so the entry for this table already exists in
** the sqlite_master table.  We do not want to create it again.
**
** If the pSelect argument is not NULL, it means that this routine
** was called to create a table generated from a 
** "CREATE TABLE ... AS SELECT ..." statement.  The column names of
** the new table will match the result set of the SELECT.
*/
void sqlite3EndTable(
  Parse *pParse,          /* Parse context */
  Token *pCons,           /* The ',' token after the last column defn. */
  Token *pEnd,            /* The final ')' token in the CREATE TABLE */
  Select *pSelect         /* Select from a "CREATE ... AS SELECT" */
){
  Table *p;
  sqlite3 *db = pParse->db;
  int iDb;

  if( (pEnd==0 && pSelect==0) || 
      pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) {
    return;
  }
  p = pParse->pNewTable;
  if( p==0 ) return;

  assert( !db->init.busy || !pSelect );

  iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);

#ifndef SQLITE_OMIT_CHECK
  /* Resolve names in all CHECK constraint expressions.
  */
  if( p->pCheck ){
    SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
    NameContext sNC;                /* Name context for pParse->pNewTable */

    memset(&sNC, 0, sizeof(sNC));
    memset(&sSrc, 0, sizeof(sSrc));
    sSrc.nSrc = 1;
    sSrc.a[0].zName = p->zName;
    sSrc.a[0].pTab = p;
    sSrc.a[0].iCursor = -1;
    sNC.pParse = pParse;
    sNC.pSrcList = &sSrc;
    sNC.isCheck = 1;
    if( sqlite3ExprResolveNames(&sNC, p->pCheck) ){
      return;
    }
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */

  /* If the db->init.busy is 1 it means we are reading the SQL off the
  ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  ** So do not write to the disk again.  Extract the root page number
  ** for the table from the db->init.newTnum field.  (The page number
  ** should have been put there by the sqliteOpenCb routine.)
  */
  if( db->init.busy ){







|







|
<
<
<
<
<


<

|
<
<
<





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405





1406
1407

1408
1409



1410
1411
1412
1413
1414
























1415
1416
1417
1418
1419
1420
1421
** is added to the internal hash tables, assuming no errors have
** occurred.
**
** An entry for the table is made in the master table on disk, unless
** this is a temporary table or db->init.busy==1.  When db->init.busy==1
** it means we are reading the sqlite_master table because we just
** connected to the database or because the sqlite_master table has
** recently changes, so the entry for this table already exists in
** the sqlite_master table.  We do not want to create it again.
**
** If the pSelect argument is not NULL, it means that this routine
** was called to create a table generated from a 
** "CREATE TABLE ... AS SELECT ..." statement.  The column names of
** the new table will match the result set of the SELECT.
*/
void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){





  Table *p;
  sqlite3 *db = pParse->db;


  if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite3_malloc_failed ) return;



  p = pParse->pNewTable;
  if( p==0 ) return;

  assert( !db->init.busy || !pSelect );

























  /* If the db->init.busy is 1 it means we are reading the SQL off the
  ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  ** So do not write to the disk again.  Extract the root page number
  ** for the table from the db->init.newTnum field.  (The page number
  ** should have been put there by the sqliteOpenCb routine.)
  */
  if( db->init.busy ){
1428
1429
1430
1431
1432
1433
1434

1435
1436
1437
1438
1439

1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562

    /* Create the rootpage for the new table and push it onto the stack.
    ** A view has no rootpage, so just push a zero onto the stack for
    ** views.  Initialize zType at the same time.
    */
    if( p->pSelect==0 ){
      /* A regular table */

      zType = "table";
      zType2 = "TABLE";
#ifndef SQLITE_OMIT_VIEW
    }else{
      /* A view */

      zType = "view";
      zType2 = "VIEW";
#endif
    }

    /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
    ** statement to populate the new table. The root-page number for the
    ** new table is on the top of the vdbe stack.
    **
    ** Once the SELECT has been coded by sqlite3Select(), it is in a
    ** suitable state to query for the column names and types to be used
    ** by the new table.
    **
    ** A shared-cache write-lock is not required to write to the new table,
    ** as a schema-lock must have already been obtained to create it. Since
    ** a schema-lock excludes all other database users, the write-lock would
    ** be redundant.
    */
    if( pSelect ){
      Table *pSelTab;
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
      sqlite3VdbeAddOp(v, OP_OpenWrite, 1, 0);
      pParse->nTab = 2;
      sqlite3Select(pParse, pSelect, SRT_Table, 1, 0, 0, 0, 0);
      sqlite3VdbeAddOp(v, OP_Close, 1, 0);
      if( pParse->nErr==0 ){
        pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect);
        if( pSelTab==0 ) return;
        assert( p->aCol==0 );
        p->nCol = pSelTab->nCol;
        p->aCol = pSelTab->aCol;
        pSelTab->nCol = 0;
        pSelTab->aCol = 0;
        sqlite3DeleteTable(0, pSelTab);
      }
    }

    /* Compute the complete text of the CREATE statement */
    if( pSelect ){
      zStmt = createTableStmt(p, p->pSchema==pParse->db->aDb[1].pSchema);
    }else{
      n = pEnd->z - pParse->sNameToken.z + 1;
      zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z);
    }

    /* A slot for the record has already been allocated in the 
    ** SQLITE_MASTER table.  We just need to update that slot with all
    ** the information we've collected.  The rowid for the preallocated
    ** slot is the 2nd item on the stack.  The top of the stack is the
    ** root page for the new table (or a 0 if this is a view).
    */
    sqlite3NestedParse(pParse,
      "UPDATE %Q.%s "
         "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q "
       "WHERE rowid=#1",
      db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
      zType,
      p->zName,
      p->zName,
      zStmt
    );
    sqliteFree(zStmt);
    sqlite3ChangeCookie(db, v, iDb);

#ifndef SQLITE_OMIT_AUTOINCREMENT
    /* Check to see if we need to create an sqlite_sequence table for
    ** keeping track of autoincrement keys.
    */
    if( p->autoInc ){
      Db *pDb = &db->aDb[iDb];
      if( pDb->pSchema->pSeqTab==0 ){
        sqlite3NestedParse(pParse,
          "CREATE TABLE %Q.sqlite_sequence(name,seq)",
          pDb->zName
        );
      }
    }
#endif

    /* Reparse everything to update our internal data structures */
    sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
        sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
  }


  /* Add the table to the in-memory representation of the database.
  */
  if( db->init.busy && pParse->nErr==0 ){
    Table *pOld;
    FKey *pFKey; 
    Schema *pSchema = p->pSchema;
    pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, strlen(p->zName)+1,p);
    if( pOld ){
      assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
      return;
    }
#ifndef SQLITE_OMIT_FOREIGN_KEY
    for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
      int nTo = strlen(pFKey->zTo) + 1;
      pFKey->pNextTo = sqlite3HashFind(&pSchema->aFKey, pFKey->zTo, nTo);
      sqlite3HashInsert(&pSchema->aFKey, pFKey->zTo, nTo, pFKey);
    }
#endif
    pParse->pNewTable = 0;
    db->nTable++;
    db->flags |= SQLITE_InternChanges;

#ifndef SQLITE_OMIT_ALTERTABLE
    if( !p->pSelect ){
      const unsigned char *zName = pParse->sNameToken.z;
      assert( !pSelect && pCons && pEnd );
      if( pCons->z==0 ) pCons = pEnd;
      p->addColOffset = 13 + sqlite3utf8CharLen(zName, pCons->z - zName);
    }
#endif
  }
}

#ifndef SQLITE_OMIT_VIEW
/*
** The parser calls this routine in order to create a new VIEW
*/







>





>












<
<
<
<
<




|


















|

|













|






|






|
|









|









|
|







|
|





<
<
<
<
<
<
<
<
<







1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468





1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558









1559
1560
1561
1562
1563
1564
1565

    /* Create the rootpage for the new table and push it onto the stack.
    ** A view has no rootpage, so just push a zero onto the stack for
    ** views.  Initialize zType at the same time.
    */
    if( p->pSelect==0 ){
      /* A regular table */
      /* sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); */
      zType = "table";
      zType2 = "TABLE";
#ifndef SQLITE_OMIT_VIEW
    }else{
      /* A view */
    /*  sqlite3VdbeAddOp(v, OP_Integer, 0, 0); */
      zType = "view";
      zType2 = "VIEW";
#endif
    }

    /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
    ** statement to populate the new table. The root-page number for the
    ** new table is on the top of the vdbe stack.
    **
    ** Once the SELECT has been coded by sqlite3Select(), it is in a
    ** suitable state to query for the column names and types to be used
    ** by the new table.





    */
    if( pSelect ){
      Table *pSelTab;
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      sqlite3VdbeAddOp(v, OP_Integer, p->iDb, 0);
      sqlite3VdbeAddOp(v, OP_OpenWrite, 1, 0);
      pParse->nTab = 2;
      sqlite3Select(pParse, pSelect, SRT_Table, 1, 0, 0, 0, 0);
      sqlite3VdbeAddOp(v, OP_Close, 1, 0);
      if( pParse->nErr==0 ){
        pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect);
        if( pSelTab==0 ) return;
        assert( p->aCol==0 );
        p->nCol = pSelTab->nCol;
        p->aCol = pSelTab->aCol;
        pSelTab->nCol = 0;
        pSelTab->aCol = 0;
        sqlite3DeleteTable(0, pSelTab);
      }
    }

    /* Compute the complete text of the CREATE statement */
    if( pSelect ){
      zStmt = createTableStmt(p);
    }else{
      n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1;
      zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z);
    }

    /* A slot for the record has already been allocated in the 
    ** SQLITE_MASTER table.  We just need to update that slot with all
    ** the information we've collected.  The rowid for the preallocated
    ** slot is the 2nd item on the stack.  The top of the stack is the
    ** root page for the new table (or a 0 if this is a view).
    */
    sqlite3NestedParse(pParse,
      "UPDATE %Q.%s "
         "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q "
       "WHERE rowid=#1",
      db->aDb[p->iDb].zName, SCHEMA_TABLE(p->iDb),
      zType,
      p->zName,
      p->zName,
      zStmt
    );
    sqliteFree(zStmt);
    sqlite3ChangeCookie(db, v, p->iDb);

#ifndef SQLITE_OMIT_AUTOINCREMENT
    /* Check to see if we need to create an sqlite_sequence table for
    ** keeping track of autoincrement keys.
    */
    if( p->autoInc ){
      Db *pDb = &db->aDb[p->iDb];
      if( pDb->pSeqTab==0 ){
        sqlite3NestedParse(pParse,
          "CREATE TABLE %Q.sqlite_sequence(name,seq)",
          pDb->zName
        );
      }
    }
#endif

    /* Reparse everything to update our internal data structures */
    sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0,
        sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC);
  }


  /* Add the table to the in-memory representation of the database.
  */
  if( db->init.busy && pParse->nErr==0 ){
    Table *pOld;
    FKey *pFKey; 
    Db *pDb = &db->aDb[p->iDb];
    pOld = sqlite3HashInsert(&pDb->tblHash, p->zName, strlen(p->zName)+1, p);
    if( pOld ){
      assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
      return;
    }
#ifndef SQLITE_OMIT_FOREIGN_KEY
    for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
      int nTo = strlen(pFKey->zTo) + 1;
      pFKey->pNextTo = sqlite3HashFind(&pDb->aFKey, pFKey->zTo, nTo);
      sqlite3HashInsert(&pDb->aFKey, pFKey->zTo, nTo, pFKey);
    }
#endif
    pParse->pNewTable = 0;
    db->nTable++;
    db->flags |= SQLITE_InternChanges;









  }
}

#ifndef SQLITE_OMIT_VIEW
/*
** The parser calls this routine in order to create a new VIEW
*/
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
){
  Table *p;
  int n;
  const unsigned char *z;
  Token sEnd;
  DbFixer sFix;
  Token *pName;
  int iDb;

  if( pParse->nVar>0 ){
    sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
    sqlite3SelectDelete(pSelect);
    return;
  }
  sqlite3StartTable(pParse, pBegin, pName1, pName2, isTemp, 1, 0);
  p = pParse->pNewTable;
  if( p==0 || pParse->nErr ){
    sqlite3SelectDelete(pSelect);
    return;
  }
  sqlite3TwoPartName(pParse, pName1, pName2, &pName);
  iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
  if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
    && sqlite3FixSelect(&sFix, pSelect)
  ){
    sqlite3SelectDelete(pSelect);
    return;
  }

  /* Make a copy of the entire SELECT statement that defines the view.
  ** This will force all the Expr.token.z values to be dynamically
  ** allocated rather than point to the input string - which means that
  ** they will persist after the current sqlite3_exec() call returns.
  */
  p->pSelect = sqlite3SelectDup(pSelect);
  sqlite3SelectDelete(pSelect);
  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    return;
  }
  if( !pParse->db->init.busy ){
    sqlite3ViewGetColumnNames(pParse, p);
  }

  /* Locate the end of the CREATE VIEW statement.  Make sEnd point to
  ** the end.
  */
  sEnd = pParse->sLastToken;
  if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
    sEnd.z += sEnd.n;
  }
  sEnd.n = 0;
  n = sEnd.z - pBegin->z;
  z = (const unsigned char*)pBegin->z;
  while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
  sEnd.z = &z[n-1];
  sEnd.n = 1;

  /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
  sqlite3EndTable(pParse, 0, &sEnd, 0);
  return;
}
#endif /* SQLITE_OMIT_VIEW */

#ifndef SQLITE_OMIT_VIEW
/*
** The Table structure pTable is really a VIEW.  Fill in the names of







<

<
<
<
<
<
|






<
|













<
<
<



















|







1573
1574
1575
1576
1577
1578
1579

1580





1581
1582
1583
1584
1585
1586
1587

1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601



1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
){
  Table *p;
  int n;
  const unsigned char *z;
  Token sEnd;
  DbFixer sFix;
  Token *pName;







  sqlite3StartTable(pParse, pBegin, pName1, pName2, isTemp, 1);
  p = pParse->pNewTable;
  if( p==0 || pParse->nErr ){
    sqlite3SelectDelete(pSelect);
    return;
  }
  sqlite3TwoPartName(pParse, pName1, pName2, &pName);

  if( sqlite3FixInit(&sFix, pParse, p->iDb, "view", pName)
    && sqlite3FixSelect(&sFix, pSelect)
  ){
    sqlite3SelectDelete(pSelect);
    return;
  }

  /* Make a copy of the entire SELECT statement that defines the view.
  ** This will force all the Expr.token.z values to be dynamically
  ** allocated rather than point to the input string - which means that
  ** they will persist after the current sqlite3_exec() call returns.
  */
  p->pSelect = sqlite3SelectDup(pSelect);
  sqlite3SelectDelete(pSelect);



  if( !pParse->db->init.busy ){
    sqlite3ViewGetColumnNames(pParse, p);
  }

  /* Locate the end of the CREATE VIEW statement.  Make sEnd point to
  ** the end.
  */
  sEnd = pParse->sLastToken;
  if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
    sEnd.z += sEnd.n;
  }
  sEnd.n = 0;
  n = sEnd.z - pBegin->z;
  z = (const unsigned char*)pBegin->z;
  while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
  sEnd.z = &z[n-1];
  sEnd.n = 1;

  /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
  sqlite3EndTable(pParse, &sEnd, 0);
  return;
}
#endif /* SQLITE_OMIT_VIEW */

#ifndef SQLITE_OMIT_VIEW
/*
** The Table structure pTable is really a VIEW.  Fill in the names of
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
  **
  **     CREATE VIEW one AS SELECT * FROM two;
  **     CREATE VIEW two AS SELECT * FROM one;
  **
  ** Actually, this error is caught previously and so the following test
  ** should always fail.  But we will leave it in place just to be safe.
  */
#if 0
  if( pTable->nCol<0 ){
    sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
    return 1;
  }
#endif
  assert( pTable->nCol>=0 );

  /* If we get this far, it means we need to compute the table names.
  ** Note that the call to sqlite3ResultSetOfSelect() will expand any
  ** "*" elements in the results set of the view and will assign cursors
  ** to the elements of the FROM clause.  But we do not want these changes
  ** to be permanent.  So the computation is done on a copy of the SELECT
  ** statement that defines the view.
  */
  assert( pTable->pSelect );
  pSel = sqlite3SelectDup(pTable->pSelect);
  if( pSel ){
    n = pParse->nTab;
    sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
    pTable->nCol = -1;
    pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel);
    pParse->nTab = n;
    if( pSelTab ){
      assert( pTable->aCol==0 );
      pTable->nCol = pSelTab->nCol;
      pTable->aCol = pSelTab->aCol;
      pSelTab->nCol = 0;
      pSelTab->aCol = 0;
      sqlite3DeleteTable(0, pSelTab);
      pTable->pSchema->flags |= DB_UnresetViews;
    }else{
      pTable->nCol = 0;
      nErr++;
    }
    sqlite3SelectDelete(pSel);
  } else {
    nErr++;
  }
  return nErr;  
}
#endif /* SQLITE_OMIT_VIEW */

#ifndef SQLITE_OMIT_VIEW
/*
** Clear the column names from every VIEW in database idx.
*/
static void sqliteViewResetAll(sqlite3 *db, int idx){
  HashElem *i;
  if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
  for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){
    Table *pTab = sqliteHashData(i);
    if( pTab->pSelect ){
      sqliteResetColumnNames(pTab);
    }
  }
  DbClearProperty(db, idx, DB_UnresetViews);
}
#else
# define sqliteViewResetAll(A,B)
#endif /* SQLITE_OMIT_VIEW */

/*
** This function is called by the VDBE to adjust the internal schema
** used by SQLite when the btree layer moves a table root page. The
** root-page of a table or index in database iDb has changed from iFrom
** to iTo.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
  HashElem *pElem;
  Hash *pHash;

  pHash = &pDb->pSchema->tblHash;
  for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){
    Table *pTab = sqliteHashData(pElem);
    if( pTab->tnum==iFrom ){
      pTab->tnum = iTo;
      return;
    }
  }
  pHash = &pDb->pSchema->idxHash;
  for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){
    Index *pIdx = sqliteHashData(pElem);
    if( pIdx->tnum==iFrom ){
      pIdx->tnum = iTo;
      return;
    }
  }
  assert(0);







<




<
<










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











|




















<
|
<
|






<
|







1648
1649
1650
1651
1652
1653
1654

1655
1656
1657
1658


1659
1660
1661
1662
1663
1664
1665
1666
1667
1668

1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686



1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718

1719

1720
1721
1722
1723
1724
1725
1726

1727
1728
1729
1730
1731
1732
1733
1734
  **
  **     CREATE VIEW one AS SELECT * FROM two;
  **     CREATE VIEW two AS SELECT * FROM one;
  **
  ** Actually, this error is caught previously and so the following test
  ** should always fail.  But we will leave it in place just to be safe.
  */

  if( pTable->nCol<0 ){
    sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
    return 1;
  }



  /* If we get this far, it means we need to compute the table names.
  ** Note that the call to sqlite3ResultSetOfSelect() will expand any
  ** "*" elements in the results set of the view and will assign cursors
  ** to the elements of the FROM clause.  But we do not want these changes
  ** to be permanent.  So the computation is done on a copy of the SELECT
  ** statement that defines the view.
  */
  assert( pTable->pSelect );
  pSel = sqlite3SelectDup(pTable->pSelect);

  n = pParse->nTab;
  sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
  pTable->nCol = -1;
  pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel);
  pParse->nTab = n;
  if( pSelTab ){
    assert( pTable->aCol==0 );
    pTable->nCol = pSelTab->nCol;
    pTable->aCol = pSelTab->aCol;
    pSelTab->nCol = 0;
    pSelTab->aCol = 0;
    sqlite3DeleteTable(0, pSelTab);
    DbSetProperty(pParse->db, pTable->iDb, DB_UnresetViews);
  }else{
    pTable->nCol = 0;
    nErr++;
  }
  sqlite3SelectDelete(pSel);



  return nErr;  
}
#endif /* SQLITE_OMIT_VIEW */

#ifndef SQLITE_OMIT_VIEW
/*
** Clear the column names from every VIEW in database idx.
*/
static void sqliteViewResetAll(sqlite3 *db, int idx){
  HashElem *i;
  if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
  for(i=sqliteHashFirst(&db->aDb[idx].tblHash); i; i=sqliteHashNext(i)){
    Table *pTab = sqliteHashData(i);
    if( pTab->pSelect ){
      sqliteResetColumnNames(pTab);
    }
  }
  DbClearProperty(db, idx, DB_UnresetViews);
}
#else
# define sqliteViewResetAll(A,B)
#endif /* SQLITE_OMIT_VIEW */

/*
** This function is called by the VDBE to adjust the internal schema
** used by SQLite when the btree layer moves a table root page. The
** root-page of a table or index in database iDb has changed from iFrom
** to iTo.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
  HashElem *pElem;

  

  for(pElem=sqliteHashFirst(&pDb->tblHash); pElem; pElem=sqliteHashNext(pElem)){
    Table *pTab = sqliteHashData(pElem);
    if( pTab->tnum==iFrom ){
      pTab->tnum = iTo;
      return;
    }
  }

  for(pElem=sqliteHashFirst(&pDb->idxHash); pElem; pElem=sqliteHashNext(pElem)){
    Index *pIdx = sqliteHashData(pElem);
    if( pIdx->tnum==iFrom ){
      pIdx->tnum = iTo;
      return;
    }
  }
  assert(0);
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
** Code to update the sqlite_master tables and internal schema definitions
** in case a root-page belonging to another table is moved by the btree layer
** is also added (this can happen with an auto-vacuum database).
*/
static void destroyTable(Parse *pParse, Table *pTab){
#ifdef SQLITE_OMIT_AUTOVACUUM
  Index *pIdx;
  int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  destroyRootPage(pParse, pTab->tnum, iDb);
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    destroyRootPage(pParse, pIdx->tnum, iDb);
  }
#else
  /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
  ** is not defined), then it is important to call OP_Destroy on the
  ** table and index root-pages in order, starting with the numerically 
  ** largest root-page number. This guarantees that none of the root-pages
  ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the







<
|

|







1764
1765
1766
1767
1768
1769
1770

1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
** Code to update the sqlite_master tables and internal schema definitions
** in case a root-page belonging to another table is moved by the btree layer
** is also added (this can happen with an auto-vacuum database).
*/
static void destroyTable(Parse *pParse, Table *pTab){
#ifdef SQLITE_OMIT_AUTOVACUUM
  Index *pIdx;

  destroyRootPage(pParse, pTab->tnum, pTab->iDb);
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    destroyRootPage(pParse, pIdx->tnum, pIdx->iDb);
  }
#else
  /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
  ** is not defined), then it is important to call OP_Destroy on the
  ** table and index root-pages in order, starting with the numerically 
  ** largest root-page number. This guarantees that none of the root-pages
  ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
    int iLargest = 0;

    if( iDestroyed==0 || iTab<iDestroyed ){
      iLargest = iTab;
    }
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      int iIdx = pIdx->tnum;
      assert( pIdx->pSchema==pTab->pSchema );
      if( (iDestroyed==0 || (iIdx<iDestroyed)) && iIdx>iLargest ){
        iLargest = iIdx;
      }
    }
    if( iLargest==0 ){
      return;
    }else{
      int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
      destroyRootPage(pParse, iLargest, iDb);
      iDestroyed = iLargest;
    }
  }
#endif
}

/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
  Table *pTab;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
    goto exit_drop_table;
  }
  assert( pName->nSrc==1 );
  pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase);

  if( pTab==0 ){
    if( noErr ){
      sqlite3ErrorClear(pParse);
    }
    goto exit_drop_table;
  }
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iDb>=0 && iDb<db->nDb );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code;
    const char *zTab = SCHEMA_TABLE(iDb);
    const char *zDb = db->aDb[iDb].zName;
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
      goto exit_drop_table;
    }
    if( isView ){
      if( !OMIT_TEMPDB && iDb==1 ){
        code = SQLITE_DROP_TEMP_VIEW;
      }else{
        code = SQLITE_DROP_VIEW;
      }
    }else{
      if( !OMIT_TEMPDB && iDb==1 ){
        code = SQLITE_DROP_TEMP_TABLE;
      }else{
        code = SQLITE_DROP_TABLE;
      }
    }
    if( sqlite3AuthCheck(pParse, code, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
  }
#endif
  if( pTab->readOnly || pTab==db->aDb[iDb].pSchema->pSeqTab ){
    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.







|




|
<
<
<
|
|
<








|





<
|
<



|
<
<
<
<
<
|




|
|




|





|













|







1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809



1810
1811

1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825

1826

1827
1828
1829
1830





1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
    int iLargest = 0;

    if( iDestroyed==0 || iTab<iDestroyed ){
      iLargest = iTab;
    }
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      int iIdx = pIdx->tnum;
      assert( pIdx->iDb==pTab->iDb );
      if( (iDestroyed==0 || (iIdx<iDestroyed)) && iIdx>iLargest ){
        iLargest = iIdx;
      }
    }
    if( iLargest==0 ) return;



    destroyRootPage(pParse, iLargest, pTab->iDb);
    iDestroyed = iLargest;

  }
#endif
}

/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
*/
void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
  Table *pTab;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;


  if( pParse->nErr || sqlite3_malloc_failed ) goto exit_drop_table;

  assert( pName->nSrc==1 );
  pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase);

  if( pTab==0 ) goto exit_drop_table;





  iDb = pTab->iDb;
  assert( iDb>=0 && iDb<db->nDb );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code;
    const char *zTab = SCHEMA_TABLE(pTab->iDb);
    const char *zDb = db->aDb[pTab->iDb].zName;
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
      goto exit_drop_table;
    }
    if( isView ){
      if( iDb==1 ){
        code = SQLITE_DROP_TEMP_VIEW;
      }else{
        code = SQLITE_DROP_VIEW;
      }
    }else{
      if( iDb==1 ){
        code = SQLITE_DROP_TEMP_TABLE;
      }else{
        code = SQLITE_DROP_TABLE;
      }
    }
    if( sqlite3AuthCheck(pParse, code, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
      goto exit_drop_table;
    }
  }
#endif
  if( pTab->readOnly || pTab==db->aDb[iDb].pSeqTab ){
    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
    goto exit_drop_table;
  }

#ifndef SQLITE_OMIT_VIEW
  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
  ** on a table.
1909
1910
1911
1912
1913
1914
1915

1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933

  /* Generate code to remove the table from the master table
  ** on disk.
  */
  v = sqlite3GetVdbe(pParse);
  if( v ){
    Trigger *pTrigger;

    Db *pDb = &db->aDb[iDb];
    sqlite3BeginWriteOperation(pParse, 0, iDb);

    /* Drop all triggers associated with the table being dropped. Code
    ** is generated to remove entries from sqlite_master and/or
    ** sqlite_temp_master if required.
    */
    pTrigger = pTab->pTrigger;
    while( pTrigger ){
      assert( pTrigger->pSchema==pTab->pSchema || 
          pTrigger->pSchema==db->aDb[1].pSchema );
      sqlite3DropTriggerPtr(pParse, pTrigger, 1);
      pTrigger = pTrigger->pNext;
    }

#ifndef SQLITE_OMIT_AUTOINCREMENT
    /* Remove any entries of the sqlite_sequence table associated with
    ** the table being dropped. This is done before the table is dropped







>









|
<







1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897

1898
1899
1900
1901
1902
1903
1904

  /* Generate code to remove the table from the master table
  ** on disk.
  */
  v = sqlite3GetVdbe(pParse);
  if( v ){
    Trigger *pTrigger;
    int iDb = pTab->iDb;
    Db *pDb = &db->aDb[iDb];
    sqlite3BeginWriteOperation(pParse, 0, iDb);

    /* Drop all triggers associated with the table being dropped. Code
    ** is generated to remove entries from sqlite_master and/or
    ** sqlite_temp_master if required.
    */
    pTrigger = pTab->pTrigger;
    while( pTrigger ){
      assert( pTrigger->iDb==iDb || pTrigger->iDb==1 );

      sqlite3DropTriggerPtr(pParse, pTrigger, 1);
      pTrigger = pTrigger->pNext;
    }

#ifndef SQLITE_OMIT_AUTOINCREMENT
    /* Remove any entries of the sqlite_sequence table associated with
    ** the table being dropped. This is done before the table is dropped
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132



2133


2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146


2147

2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
  Table *pTab = pIndex->pTable;  /* The table that is indexed */
  int iTab = pParse->nTab;       /* Btree cursor used for pTab */
  int iIdx = pParse->nTab+1;     /* Btree cursor used for pIndex */
  int addr1;                     /* Address of top of loop */
  int tnum;                      /* Root page of index */
  Vdbe *v;                       /* Generate code into this virtual machine */
  KeyInfo *pKey;                 /* KeyInfo for index */
  int iDb = sqlite3SchemaToIndex(pParse->db, pIndex->pSchema);

#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
      pParse->db->aDb[iDb].zName ) ){
    return;
  }
#endif

  /* Require a write-lock on the table to perform this operation */



  sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);



  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;
  if( memRootPage>=0 ){
    sqlite3VdbeAddOp(v, OP_MemLoad, memRootPage, 0);
    tnum = 0;
  }else{
    tnum = pIndex->tnum;
    sqlite3VdbeAddOp(v, OP_Clear, tnum, iDb);
  }
  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
  pKey = sqlite3IndexKeyinfo(pParse, pIndex);
  sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum, (char *)pKey, P3_KEYINFO_HANDOFF);


  sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);

  addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
  sqlite3GenerateIndexKey(v, pIndex, iTab);
  if( pIndex->onError!=OE_None ){
    int curaddr = sqlite3VdbeCurrentAddr(v);
    int addr2 = curaddr+4;
    sqlite3VdbeChangeP2(v, curaddr-1, addr2);
    sqlite3VdbeAddOp(v, OP_Rowid, iTab, 0);
    sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
    sqlite3VdbeAddOp(v, OP_IsUnique, iIdx, addr2);
    sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort,
                    "indexed columns are not unique", P3_STATIC);
    assert( addr2==sqlite3VdbeCurrentAddr(v) );
  }
  sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, 0);
  sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1);
  sqlite3VdbeJumpHere(v, addr1);
  sqlite3VdbeAddOp(v, OP_Close, iTab, 0);
  sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
}

/*
** Create a new index for an SQL table.  pName1.pName2 is the name of the index 
** and pTblList is the name of the table that is to be indexed.  Both will 







|
<



|




|
>
>
>
|
>
>








|

|
<
|
>
>
|
>


|
<
<
<
<
|
|
<
|
<

<

|







2086
2087
2088
2089
2090
2091
2092
2093

2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119

2120
2121
2122
2123
2124
2125
2126
2127




2128
2129

2130

2131

2132
2133
2134
2135
2136
2137
2138
2139
2140
static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
  Table *pTab = pIndex->pTable;  /* The table that is indexed */
  int iTab = pParse->nTab;       /* Btree cursor used for pTab */
  int iIdx = pParse->nTab+1;     /* Btree cursor used for pIndex */
  int addr1;                     /* Address of top of loop */
  int tnum;                      /* Root page of index */
  Vdbe *v;                       /* Generate code into this virtual machine */
  int isUnique;                  /* True for a unique index */


#ifndef SQLITE_OMIT_AUTHORIZATION
  if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
      pParse->db->aDb[pIndex->iDb].zName ) ){
    return;
  }
#endif

  /* Ensure all the required collation sequences are available. This
  ** routine will invoke the collation-needed callback if necessary (and
  ** if one has been registered).
  */
  if( sqlite3CheckIndexCollSeq(pParse, pIndex) ){
    return;
  }

  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;
  if( memRootPage>=0 ){
    sqlite3VdbeAddOp(v, OP_MemLoad, memRootPage, 0);
    tnum = 0;
  }else{
    tnum = pIndex->tnum;
    sqlite3VdbeAddOp(v, OP_Clear, tnum, pIndex->iDb);
  }
  sqlite3VdbeAddOp(v, OP_Integer, pIndex->iDb, 0);

  sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum,
                    (char*)&pIndex->keyInfo, P3_KEYINFO);
  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeAddOp(v, OP_OpenRead, iTab, pTab->tnum);
  sqlite3VdbeAddOp(v, OP_SetNumColumns, iTab, pTab->nCol);
  addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
  sqlite3GenerateIndexKey(v, pIndex, iTab);
  isUnique = pIndex->onError!=OE_None;




  sqlite3VdbeAddOp(v, OP_IdxPut, iIdx, isUnique);
  if( isUnique ){

    sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC);

  }

  sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1);
  sqlite3VdbeChangeP2(v, addr1, sqlite3VdbeCurrentAddr(v));
  sqlite3VdbeAddOp(v, OP_Close, iTab, 0);
  sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
}

/*
** Create a new index for an SQL table.  pName1.pName2 is the name of the index 
** and pTblList is the name of the table that is to be indexed.  Both will 
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199

2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265

2266
2267
2268
2269
2270
2271
2272
  Parse *pParse,     /* All information about this parse */
  Token *pName1,     /* First part of index name. May be NULL */
  Token *pName2,     /* Second part of index name. May be NULL */
  SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
  ExprList *pList,   /* A list of columns to be indexed */
  int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  Token *pStart,     /* The CREATE token that begins a CREATE TABLE statement */
  Token *pEnd,       /* The ")" that closes the CREATE INDEX statement */
  int sortOrder,     /* Sort order of primary key when pList==NULL */
  int ifNotExist     /* Omit error if index already exists */
){
  Table *pTab = 0;     /* Table to be indexed */
  Index *pIndex = 0;   /* The index to be created */
  char *zName = 0;     /* Name of the index */
  int nName;           /* Number of characters in zName */
  int i, j;
  Token nullId;        /* Fake token for an empty ID list */
  DbFixer sFix;        /* For assigning database names to pTable */
  int sortOrderMask;   /* 1 to honor DESC in index.  0 to ignore. */

  sqlite3 *db = pParse->db;
  Db *pDb;             /* The specific table containing the indexed database */
  int iDb;             /* Index of the database that is being written */
  Token *pName = 0;    /* Unqualified name of the index to create */
  struct ExprList_item *pListItem; /* For looping over pList */
  int nCol;
  int nExtra = 0;
  char *zExtra;

  if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
    goto exit_create_index;
  }

  /*
  ** Find the table that is to be indexed.  Return early if not found.
  */
  if( pTblName!=0 ){

    /* Use the two-part index name to determine the database 
    ** to search for the table. 'Fix' the table name to this db
    ** before looking up the table.
    */
    assert( pName1 && pName2 );
    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
    if( iDb<0 ) goto exit_create_index;

#ifndef SQLITE_OMIT_TEMPDB
    /* If the index name was unqualified, check if the the table
    ** is a temp table. If so, set the database to 1.
    */
    pTab = sqlite3SrcListLookup(pParse, pTblName);
    if( pName2 && pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
      iDb = 1;
    }
#endif

    if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) &&
        sqlite3FixSrcList(&sFix, pTblName)
    ){
      /* Because the parser constructs pTblName from a single identifier,
      ** sqlite3FixSrcList can never fail. */
      assert(0);
    }
    pTab = sqlite3LocateTable(pParse, pTblName->a[0].zName, 
        pTblName->a[0].zDatabase);
    if( !pTab ) goto exit_create_index;
    assert( db->aDb[iDb].pSchema==pTab->pSchema );
  }else{
    assert( pName==0 );
    pTab = pParse->pNewTable;
    if( !pTab ) goto exit_create_index;
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  }
  pDb = &db->aDb[iDb];

  if( pTab==0 || pParse->nErr ) goto exit_create_index;
  if( pTab->readOnly ){
    sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
    goto exit_create_index;
  }
#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "views may not be indexed");
    goto exit_create_index;
  }
#endif


  /*
  ** Find the name of the index.  Make sure there is not already another
  ** index or table with the same name.  
  **
  ** Exception:  If we are reading the names of permanent indices from the
  ** sqlite_master table (because some other process changed the schema) and







|
<
<

|
|
|
<

|
|
<
>

|
|
|
<
<
<
<

<
|
<














<




|


<




|
<
<




|


|
<
|

<












>







2151
2152
2153
2154
2155
2156
2157
2158


2159
2160
2161
2162

2163
2164
2165

2166
2167
2168
2169
2170




2171

2172

2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186

2187
2188
2189
2190
2191
2192
2193

2194
2195
2196
2197
2198


2199
2200
2201
2202
2203
2204
2205
2206

2207
2208

2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
  Parse *pParse,     /* All information about this parse */
  Token *pName1,     /* First part of index name. May be NULL */
  Token *pName2,     /* Second part of index name. May be NULL */
  SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
  ExprList *pList,   /* A list of columns to be indexed */
  int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  Token *pStart,     /* The CREATE token that begins a CREATE TABLE statement */
  Token *pEnd        /* The ")" that closes the CREATE INDEX statement */


){
  Table *pTab = 0;   /* Table to be indexed */
  Index *pIndex = 0; /* The index to be created */
  char *zName = 0;

  int i, j;
  Token nullId;    /* Fake token for an empty ID list */
  DbFixer sFix;    /* For assigning database names to pTable */

  int isTemp;      /* True for a temporary index */
  sqlite3 *db = pParse->db;

  int iDb;          /* Index of the database that is being written */
  Token *pName = 0; /* Unqualified name of the index to create */






  if( pParse->nErr || sqlite3_malloc_failed ) goto exit_create_index;


  /*
  ** Find the table that is to be indexed.  Return early if not found.
  */
  if( pTblName!=0 ){

    /* Use the two-part index name to determine the database 
    ** to search for the table. 'Fix' the table name to this db
    ** before looking up the table.
    */
    assert( pName1 && pName2 );
    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
    if( iDb<0 ) goto exit_create_index;


    /* If the index name was unqualified, check if the the table
    ** is a temp table. If so, set the database to 1.
    */
    pTab = sqlite3SrcListLookup(pParse, pTblName);
    if( pName2 && pName2->n==0 && pTab && pTab->iDb==1 ){
      iDb = 1;
    }


    if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) &&
        sqlite3FixSrcList(&sFix, pTblName)
    ){
      goto exit_create_index;


    }
    pTab = sqlite3LocateTable(pParse, pTblName->a[0].zName, 
        pTblName->a[0].zDatabase);
    if( !pTab ) goto exit_create_index;
    assert( iDb==pTab->iDb );
  }else{
    assert( pName==0 );
    pTab =  pParse->pNewTable;

    iDb = pTab->iDb;
  }


  if( pTab==0 || pParse->nErr ) goto exit_create_index;
  if( pTab->readOnly ){
    sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
    goto exit_create_index;
  }
#ifndef SQLITE_OMIT_VIEW
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "views may not be indexed");
    goto exit_create_index;
  }
#endif
  isTemp = pTab->iDb==1;

  /*
  ** Find the name of the index.  Make sure there is not already another
  ** index or table with the same name.  
  **
  ** Exception:  If we are reading the names of permanent indices from the
  ** sqlite_master table (because some other process changed the schema) and
2281
2282
2283
2284
2285
2286
2287


2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414

2415


2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
    zName = sqlite3NameFromToken(pName);
    if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
    if( zName==0 ) goto exit_create_index;
    if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
      goto exit_create_index;
    }
    if( !db->init.busy ){


      if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
      if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
        if( !ifNotExist ){
          sqlite3ErrorMsg(pParse, "index %s already exists", zName);
        }
        goto exit_create_index;
      }
      if( sqlite3FindTable(db, zName, 0)!=0 ){
        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
        goto exit_create_index;
      }
    }
  }else{
    char zBuf[30];
    int n;
    Index *pLoop;
    for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
    sprintf(zBuf,"_%d",n);
    zName = 0;
    sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0);
    if( zName==0 ) goto exit_create_index;
  }

  /* Check for authorization to create an index.
  */
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    const char *zDb = pDb->zName;
    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
      goto exit_create_index;
    }
    i = SQLITE_CREATE_INDEX;
    if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX;
    if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
      goto exit_create_index;
    }
  }
#endif

  /* If pList==0, it means this routine was called to make a primary
  ** key out of the last column added to the table under construction.
  ** So create a fake list to simulate this.
  */
  if( pList==0 ){
    nullId.z = (u8*)pTab->aCol[pTab->nCol-1].zName;
    nullId.n = strlen((char*)nullId.z);
    pList = sqlite3ExprListAppend(0, 0, &nullId);
    if( pList==0 ) goto exit_create_index;
    pList->a[0].sortOrder = sortOrder;
  }

  /* Figure out how many bytes of space are required to store explicitly
  ** specified collation sequence names.
  */
  for(i=0; i<pList->nExpr; i++){
    Expr *pExpr = pList->a[i].pExpr;
    if( pExpr ){
      nExtra += (1 + strlen(pExpr->pColl->zName));
    }
  }

  /* 
  ** Allocate the index structure. 
  */
  nName = strlen(zName);
  nCol = pList->nExpr;
  pIndex = sqliteMalloc( 
      sizeof(Index) +              /* Index structure  */
      sizeof(int)*nCol +           /* Index.aiColumn   */
      sizeof(int)*(nCol+1) +       /* Index.aiRowEst   */
      sizeof(char *)*nCol +        /* Index.azColl     */
      sizeof(u8)*nCol +            /* Index.aSortOrder */
      nName + 1 +                  /* Index.zName      */
      nExtra                       /* Collation sequence names */
  );
  if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto exit_create_index;
  pIndex->aiColumn = (int *)(&pIndex[1]);
  pIndex->aiRowEst = (int *)(&pIndex->aiColumn[nCol]);
  pIndex->azColl = (char **)(&pIndex->aiRowEst[nCol+1]);
  pIndex->aSortOrder = (u8 *)(&pIndex->azColl[nCol]);
  pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
  zExtra = (char *)(&pIndex->zName[nName+1]);
  strcpy(pIndex->zName, zName);
  pIndex->pTable = pTab;
  pIndex->nColumn = pList->nExpr;
  pIndex->onError = onError;
  pIndex->autoIndex = pName==0;
  pIndex->pSchema = db->aDb[iDb].pSchema;

  /* Check to see if we should honor DESC requests on index columns
  */
  if( pDb->pSchema->file_format>=4 ){
    sortOrderMask = -1;   /* Honor DESC */
  }else{
    sortOrderMask = 0;    /* Ignore DESC */
  }

  /* Scan the names of the columns of the table to be indexed and
  ** load the column indices into the Index structure.  Report an error
  ** if any column is not found.
  */
  for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
    const char *zColName = pListItem->zName;
    Column *pTabCol;
    int requestedSortOrder;
    char *zColl;                   /* Collation sequence */

    for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
      if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
    }
    if( j>=pTab->nCol ){
      sqlite3ErrorMsg(pParse, "table %s has no column named %s",
        pTab->zName, zColName);
      goto exit_create_index;
    }
    pIndex->aiColumn[i] = j;
    if( pListItem->pExpr ){
      assert( pListItem->pExpr->pColl );
      zColl = zExtra;
      strcpy(zExtra, pListItem->pExpr->pColl->zName);
      zExtra += (strlen(zColl) + 1);
    }else{
      zColl = pTab->aCol[j].zColl;
      if( !zColl ){
        zColl = db->pDfltColl->zName;
      }
    }

    if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl, -1) ){


      goto exit_create_index;
    }
    pIndex->azColl[i] = zColl;
    requestedSortOrder = pListItem->sortOrder & sortOrderMask;
    pIndex->aSortOrder[i] = requestedSortOrder;
  }
  sqlite3DefaultRowEst(pIndex);

  if( pTab==pParse->pNewTable ){
    /* This routine has been called to create an automatic index as a
    ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
    ** a PRIMARY KEY or UNIQUE clause following the column definitions.
    ** i.e. one of:
    **







>
>

|
<
|
<


|



















|
|



|











|
|


<
<
<
<
<
<
<
<
<
<
<





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





<
|
<
<
<
<
<
<
<





|
<
<
<
<
<
|
|



|



|
|
<
|
<

|
<
<
|
<
>
|
>
>


<
<
<

|







2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247

2248

2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291











2292
2293
2294
2295
2296


2297

2298






2299
2300



2301

2302
2303
2304
2305
2306

2307







2308
2309
2310
2311
2312
2313





2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324

2325

2326
2327


2328

2329
2330
2331
2332
2333
2334



2335
2336
2337
2338
2339
2340
2341
2342
2343
    zName = sqlite3NameFromToken(pName);
    if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
    if( zName==0 ) goto exit_create_index;
    if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
      goto exit_create_index;
    }
    if( !db->init.busy ){
      Index *pISameName;    /* Another index with the same name */
      Table *pTSameName;    /* A table with same name as the index */
      if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
      if( (pISameName = sqlite3FindIndex(db, zName, db->aDb[iDb].zName))!=0 ){

        sqlite3ErrorMsg(pParse, "index %s already exists", zName);

        goto exit_create_index;
      }
      if( (pTSameName = sqlite3FindTable(db, zName, 0))!=0 ){
        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
        goto exit_create_index;
      }
    }
  }else{
    char zBuf[30];
    int n;
    Index *pLoop;
    for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
    sprintf(zBuf,"_%d",n);
    zName = 0;
    sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0);
    if( zName==0 ) goto exit_create_index;
  }

  /* Check for authorization to create an index.
  */
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    const char *zDb = db->aDb[pTab->iDb].zName;
    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
      goto exit_create_index;
    }
    i = SQLITE_CREATE_INDEX;
    if( isTemp ) i = SQLITE_CREATE_TEMP_INDEX;
    if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
      goto exit_create_index;
    }
  }
#endif

  /* If pList==0, it means this routine was called to make a primary
  ** key out of the last column added to the table under construction.
  ** So create a fake list to simulate this.
  */
  if( pList==0 ){
    nullId.z = pTab->aCol[pTab->nCol-1].zName;
    nullId.n = strlen(nullId.z);
    pList = sqlite3ExprListAppend(0, 0, &nullId);
    if( pList==0 ) goto exit_create_index;











  }

  /* 
  ** Allocate the index structure. 
  */


  pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 +

                        (sizeof(int) + sizeof(CollSeq*))*pList->nExpr );






  if( pIndex==0 ) goto exit_create_index;
  pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr];



  pIndex->zName = (char*)&pIndex->aiColumn[pList->nExpr];

  strcpy(pIndex->zName, zName);
  pIndex->pTable = pTab;
  pIndex->nColumn = pList->nExpr;
  pIndex->onError = onError;
  pIndex->autoIndex = pName==0;

  pIndex->iDb = iDb;








  /* Scan the names of the columns of the table to be indexed and
  ** load the column indices into the Index structure.  Report an error
  ** if any column is not found.
  */
  for(i=0; i<pList->nExpr; i++){





    for(j=0; j<pTab->nCol; j++){
      if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break;
    }
    if( j>=pTab->nCol ){
      sqlite3ErrorMsg(pParse, "table %s has no column named %s",
        pTab->zName, pList->a[i].zName);
      goto exit_create_index;
    }
    pIndex->aiColumn[i] = j;
    if( pList->a[i].pExpr ){
      assert( pList->a[i].pExpr->pColl );

      pIndex->keyInfo.aColl[i] = pList->a[i].pExpr->pColl;

    }else{
      pIndex->keyInfo.aColl[i] = pTab->aCol[j].pColl;


    }

    assert( pIndex->keyInfo.aColl[i] );
    if( !db->init.busy && 
        sqlite3CheckCollSeq(pParse, pIndex->keyInfo.aColl[i]) 
    ){
      goto exit_create_index;
    }



  }
  pIndex->keyInfo.nField = pList->nExpr;

  if( pTab==pParse->pNewTable ){
    /* This routine has been called to create an automatic index as a
    ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
    ** a PRIMARY KEY or UNIQUE clause following the column definitions.
    ** i.e. one of:
    **
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
      int k;
      assert( pIdx->onError!=OE_None );
      assert( pIdx->autoIndex );
      assert( pIndex->onError!=OE_None );

      if( pIdx->nColumn!=pIndex->nColumn ) continue;
      for(k=0; k<pIdx->nColumn; k++){
        const char *z1 = pIdx->azColl[k];
        const char *z2 = pIndex->azColl[k];
        if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
        if( pIdx->aSortOrder[k]!=pIndex->aSortOrder[k] ) break;
        if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
      }
      if( k==pIdx->nColumn ){
        if( pIdx->onError!=pIndex->onError ){
          /* This constraint creates the same index as a previous
          ** constraint specified somewhere in the CREATE TABLE statement.
          ** However the ON CONFLICT clauses are different. If both this 
          ** constraint and the previous equivalent constraint have explicit







<
<

|
<







2354
2355
2356
2357
2358
2359
2360


2361
2362

2363
2364
2365
2366
2367
2368
2369
      int k;
      assert( pIdx->onError!=OE_None );
      assert( pIdx->autoIndex );
      assert( pIndex->onError!=OE_None );

      if( pIdx->nColumn!=pIndex->nColumn ) continue;
      for(k=0; k<pIdx->nColumn; k++){


        if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
        if( pIdx->keyInfo.aColl[k]!=pIndex->keyInfo.aColl[k] ) break;

      }
      if( k==pIdx->nColumn ){
        if( pIdx->onError!=pIndex->onError ){
          /* This constraint creates the same index as a previous
          ** constraint specified somewhere in the CREATE TABLE statement.
          ** However the ON CONFLICT clauses are different. If both this 
          ** constraint and the previous equivalent constraint have explicit
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
  }

  /* Link the new Index structure to its table and to the other
  ** in-memory database structures. 
  */
  if( db->init.busy ){
    Index *p;
    p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
                         pIndex->zName, strlen(pIndex->zName)+1, pIndex);
    if( p ){
      assert( p==pIndex );  /* Malloc must have failed */
      goto exit_create_index;
    }
    db->flags |= SQLITE_InternChanges;
    if( pTblName!=0 ){







|







2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
  }

  /* Link the new Index structure to its table and to the other
  ** in-memory database structures. 
  */
  if( db->init.busy ){
    Index *p;
    p = sqlite3HashInsert(&db->aDb[pIndex->iDb].idxHash, 
                         pIndex->zName, strlen(pIndex->zName)+1, pIndex);
    if( p ){
      assert( p==pIndex );  /* Malloc must have failed */
      goto exit_create_index;
    }
    db->flags |= SQLITE_InternChanges;
    if( pTblName!=0 ){
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
    Vdbe *v;
    char *zStmt;
    int iMem = pParse->nMem++;

    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto exit_create_index;


    /* Create the rootpage for the index
    */
    sqlite3BeginWriteOperation(pParse, 1, iDb);
    sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);

    /* Gather the complete text of the CREATE INDEX statement into
    ** the zStmt variable
    */
    if( pStart && pEnd ){
      /* A named index with an explicit CREATE INDEX statement */
      zStmt = sqlite3MPrintf("CREATE%s INDEX %.*s",
        onError==OE_None ? "" : " UNIQUE",
        pEnd->z - pName->z + 1,
        pName->z);
    }else{
      /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
      /* zStmt = sqlite3MPrintf(""); */
      zStmt = 0;
    }








<













|







2419
2420
2421
2422
2423
2424
2425

2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
    Vdbe *v;
    char *zStmt;
    int iMem = pParse->nMem++;

    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto exit_create_index;


    /* Create the rootpage for the index
    */
    sqlite3BeginWriteOperation(pParse, 1, iDb);
    sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);

    /* Gather the complete text of the CREATE INDEX statement into
    ** the zStmt variable
    */
    if( pStart && pEnd ){
      /* A named index with an explicit CREATE INDEX statement */
      zStmt = sqlite3MPrintf("CREATE%s INDEX %.*s",
        onError==OE_None ? "" : " UNIQUE",
        Addr(pEnd->z) - Addr(pName->z) + 1,
        pName->z);
    }else{
      /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
      /* zStmt = sqlite3MPrintf(""); */
      zStmt = 0;
    }

2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689

2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757



2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
  }
  sqlite3ExprListDelete(pList);
  sqlite3SrcListDelete(pTblName);
  sqliteFree(zName);
  return;
}

/*
** Generate code to make sure the file format number is at least minFormat.
** The generated code will increase the file format number if necessary.
*/
void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
  Vdbe *v;
  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);
    sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0);
    sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
    sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0);
    sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
  }
}

/*
** Fill the Index.aiRowEst[] array with default information - information
** to be used when we have not run the ANALYZE command.
**
** aiRowEst[0] is suppose to contain the number of elements in the index.
** Since we do not know, guess 1 million.  aiRowEst[1] is an estimate of the
** number of rows in the table that match any particular value of the
** first column of the index.  aiRowEst[2] is an estimate of the number
** of rows that match any particular combiniation of the first 2 columns
** of the index.  And so forth.  It must always be the case that
*
**           aiRowEst[N]<=aiRowEst[N-1]
**           aiRowEst[N]>=1
**
** Apart from that, we have little to go on besides intuition as to
** how aiRowEst[] should be initialized.  The numbers generated here
** are based on typical values found in actual indices.
*/
void sqlite3DefaultRowEst(Index *pIdx){
  unsigned *a = pIdx->aiRowEst;
  int i;
  assert( a!=0 );
  a[0] = 1000000;
  for(i=pIdx->nColumn; i>=1; i--){
    a[i] = 10;
  }
  if( pIdx->onError!=OE_None ){
    a[pIdx->nColumn] = 1;
  }
}

/*
** This routine will drop an existing named index.  This routine
** implements the DROP INDEX statement.
*/
void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
  Index *pIndex;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
    goto exit_drop_index;
  }
  assert( pName->nSrc==1 );
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto exit_drop_index;
  }
  pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
  if( pIndex==0 ){
    if( !ifExists ){
      sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
    }
    pParse->checkSchema = 1;
    goto exit_drop_index;
  }
  if( pIndex->autoIndex ){
    sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
      "or PRIMARY KEY constraint cannot be dropped", 0);
    goto exit_drop_index;
  }
  iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_INDEX;
    Table *pTab = pIndex->pTable;
    const char *zDb = db->aDb[iDb].zName;
    const char *zTab = SCHEMA_TABLE(iDb);
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
      goto exit_drop_index;
    }
    if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX;
    if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
      goto exit_drop_index;
    }
  }
#endif

  /* Generate code to remove the index and from the master table */
  v = sqlite3GetVdbe(pParse);
  if( v ){

    sqlite3NestedParse(pParse,
       "DELETE FROM %Q.%s WHERE name=%Q",
       db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
       pIndex->zName
    );
    sqlite3ChangeCookie(db, v, iDb);
    destroyRootPage(pParse, pIndex->tnum, iDb);
    sqlite3VdbeOp3(v, OP_DropIndex, iDb, 0, pIndex->zName, 0);
  }

exit_drop_index:
  sqlite3SrcListDelete(pName);
}

/*
** ppArray points into a structure where there is an array pointer
** followed by two integers. The first integer is the
** number of elements in the structure array.  The second integer
** is the number of allocated slots in the array.
**
** In other words, the structure looks something like this:
**
**        struct Example1 {
**          struct subElem *aEntry;
**          int nEntry;
**          int nAlloc;
**        }
**
** The pnEntry parameter points to the equivalent of Example1.nEntry.
**
** This routine allocates a new slot in the array, zeros it out,
** and returns its index.  If malloc fails a negative number is returned.
**
** szEntry is the sizeof of a single array entry.  initSize is the 
** number of array entries allocated on the initial allocation.
*/
int sqlite3ArrayAllocate(void **ppArray, int szEntry, int initSize){
  char *p;
  int *an = (int*)&ppArray[1];
  if( an[0]>=an[1] ){
    void *pNew;
    int newSize;
    newSize = an[1]*2 + initSize;
    pNew = sqliteRealloc(*ppArray, newSize*szEntry);
    if( pNew==0 ){
      return -1;
    }
    an[1] = newSize;
    *ppArray = pNew;
  }
  p = *ppArray;
  memset(&p[an[0]*szEntry], 0, szEntry);
  return an[0]++;
}

/*
** Append a new element to the given IdList.  Create a new IdList if
** need be.
**
** A new IdList is returned, or NULL if malloc() fails.
*/
IdList *sqlite3IdListAppend(IdList *pList, Token *pToken){
  int i;
  if( pList==0 ){
    pList = sqliteMalloc( sizeof(IdList) );
    if( pList==0 ) return 0;
    pList->nAlloc = 0;
  }



  i = sqlite3ArrayAllocate((void**)&pList->a, sizeof(pList->a[0]), 5);
  if( i<0 ){
    sqlite3IdListDelete(pList);
    return 0;
  }
  pList->a[i].zName = sqlite3NameFromToken(pToken);
  return pList;
}

/*
** Delete an IdList.
*/
void sqlite3IdListDelete(IdList *pList){
  int i;
  if( pList==0 ) return;
  for(i=0; i<pList->nId; i++){
    sqliteFree(pList->a[i].zName);
  }
  sqliteFree(pList->a);
  sqliteFree(pList);
}

/*
** Return the index in pList of the identifier named zId.  Return -1
** if not found.
*/
int sqlite3IdListIndex(IdList *pList, const char *zName){
  int i;
  if( pList==0 ) return -1;
  for(i=0; i<pList->nId; i++){
    if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
  }
  return -1;
}

/*
** Append a new table name to the given SrcList.  Create a new SrcList if
** need be.  A new entry is created in the SrcList even if pToken is NULL.
**
** A new SrcList is returned, or NULL if malloc() fails.








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|



<

|
<
<

|
<
<


<
|
<








<




|
|



|









>














<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







<





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







2496
2497
2498
2499
2500
2501
2502
2503















































2504
2505
2506
2507
2508
2509
2510

2511
2512


2513
2514


2515
2516

2517

2518
2519
2520
2521
2522
2523
2524
2525

2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559









































2560
2561
2562
2563
2564
2565
2566

2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580

2581
2582












2583







2584


2585
2586
2587
2588
2589
2590
2591
2592
  }
  sqlite3ExprListDelete(pList);
  sqlite3SrcListDelete(pTblName);
  sqliteFree(zName);
  return;
}

/*















































** This routine will drop an existing named index.  This routine
** implements the DROP INDEX statement.
*/
void sqlite3DropIndex(Parse *pParse, SrcList *pName){
  Index *pIndex;
  Vdbe *v;
  sqlite3 *db = pParse->db;


  if( pParse->nErr || sqlite3_malloc_failed ) return;


  assert( pName->nSrc==1 );
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) return;


  pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
  if( pIndex==0 ){

    sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);

    pParse->checkSchema = 1;
    goto exit_drop_index;
  }
  if( pIndex->autoIndex ){
    sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
      "or PRIMARY KEY constraint cannot be dropped", 0);
    goto exit_drop_index;
  }

#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_INDEX;
    Table *pTab = pIndex->pTable;
    const char *zDb = db->aDb[pIndex->iDb].zName;
    const char *zTab = SCHEMA_TABLE(pIndex->iDb);
    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
      goto exit_drop_index;
    }
    if( pIndex->iDb ) code = SQLITE_DROP_TEMP_INDEX;
    if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
      goto exit_drop_index;
    }
  }
#endif

  /* Generate code to remove the index and from the master table */
  v = sqlite3GetVdbe(pParse);
  if( v ){
    int iDb = pIndex->iDb;
    sqlite3NestedParse(pParse,
       "DELETE FROM %Q.%s WHERE name=%Q",
       db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
       pIndex->zName
    );
    sqlite3ChangeCookie(db, v, iDb);
    destroyRootPage(pParse, pIndex->tnum, iDb);
    sqlite3VdbeOp3(v, OP_DropIndex, iDb, 0, pIndex->zName, 0);
  }

exit_drop_index:
  sqlite3SrcListDelete(pName);
}










































/*
** Append a new element to the given IdList.  Create a new IdList if
** need be.
**
** A new IdList is returned, or NULL if malloc() fails.
*/
IdList *sqlite3IdListAppend(IdList *pList, Token *pToken){

  if( pList==0 ){
    pList = sqliteMalloc( sizeof(IdList) );
    if( pList==0 ) return 0;
    pList->nAlloc = 0;
  }
  if( pList->nId>=pList->nAlloc ){
    struct IdList_item *a;
    pList->nAlloc = pList->nAlloc*2 + 5;
    a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]) );
    if( a==0 ){
      sqlite3IdListDelete(pList);
      return 0;
    }
    pList->a = a;

  }
  memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));












  pList->a[pList->nId].zName = sqlite3NameFromToken(pToken);







  pList->nId++;


  return pList;
}

/*
** Append a new table name to the given SrcList.  Create a new SrcList if
** need be.  A new entry is created in the SrcList even if pToken is NULL.
**
** A new SrcList is returned, or NULL if malloc() fails.
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878


























2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890

2891

2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953

/*
** Assign cursors to all tables in a SrcList
*/
void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
  int i;
  struct SrcList_item *pItem;
  assert(pList || sqlite3ThreadDataReadOnly()->mallocFailed);
  if( pList ){
    for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
      if( pItem->iCursor>=0 ) break;
      pItem->iCursor = pParse->nTab++;
      if( pItem->pSelect ){
        sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
      }
    }
  }
}

/*
** Add an alias to the last identifier on the given identifier list.
*/
void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){
  if( pList && pList->nSrc>0 ){
    pList->a[pList->nSrc-1].zAlias = sqlite3NameFromToken(pToken);
  }
}



























/*
** Delete an entire SrcList including all its substructure.
*/
void sqlite3SrcListDelete(SrcList *pList){
  int i;
  struct SrcList_item *pItem;
  if( pList==0 ) return;
  for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
    sqliteFree(pItem->zDatabase);
    sqliteFree(pItem->zName);
    sqliteFree(pItem->zAlias);

    sqlite3DeleteTable(0, pItem->pTab);

    sqlite3SelectDelete(pItem->pSelect);
    sqlite3ExprDelete(pItem->pOn);
    sqlite3IdListDelete(pItem->pUsing);
  }
  sqliteFree(pList);
}

/*
** Begin a transaction
*/
void sqlite3BeginTransaction(Parse *pParse, int type){
  sqlite3 *db;
  Vdbe *v;
  int i;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  if( type!=TK_DEFERRED ){
    for(i=0; i<db->nDb; i++){
      sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
    }
  }
  sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0);
}

/*
** Commit a transaction
*/
void sqlite3CommitTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0);
  }
}

/*
** Rollback a transaction
*/
void sqlite3RollbackTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1);
  }
}







<
<
|
|
|
|
|
<












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












>
|
>
















|




















|
















|







2647
2648
2649
2650
2651
2652
2653


2654
2655
2656
2657
2658

2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773

/*
** Assign cursors to all tables in a SrcList
*/
void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
  int i;
  struct SrcList_item *pItem;


  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
    if( pItem->iCursor>=0 ) break;
    pItem->iCursor = pParse->nTab++;
    if( pItem->pSelect ){
      sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);

    }
  }
}

/*
** Add an alias to the last identifier on the given identifier list.
*/
void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){
  if( pList && pList->nSrc>0 ){
    pList->a[pList->nSrc-1].zAlias = sqlite3NameFromToken(pToken);
  }
}

/*
** Delete an IdList.
*/
void sqlite3IdListDelete(IdList *pList){
  int i;
  if( pList==0 ) return;
  for(i=0; i<pList->nId; i++){
    sqliteFree(pList->a[i].zName);
  }
  sqliteFree(pList->a);
  sqliteFree(pList);
}

/*
** Return the index in pList of the identifier named zId.  Return -1
** if not found.
*/
int sqlite3IdListIndex(IdList *pList, const char *zName){
  int i;
  if( pList==0 ) return -1;
  for(i=0; i<pList->nId; i++){
    if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
  }
  return -1;
}

/*
** Delete an entire SrcList including all its substructure.
*/
void sqlite3SrcListDelete(SrcList *pList){
  int i;
  struct SrcList_item *pItem;
  if( pList==0 ) return;
  for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
    sqliteFree(pItem->zDatabase);
    sqliteFree(pItem->zName);
    sqliteFree(pItem->zAlias);
    if( pItem->pTab && pItem->pTab->isTransient ){
      sqlite3DeleteTable(0, pItem->pTab);
    }
    sqlite3SelectDelete(pItem->pSelect);
    sqlite3ExprDelete(pItem->pOn);
    sqlite3IdListDelete(pItem->pUsing);
  }
  sqliteFree(pList);
}

/*
** Begin a transaction
*/
void sqlite3BeginTransaction(Parse *pParse, int type){
  sqlite3 *db;
  Vdbe *v;
  int i;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3_malloc_failed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  if( type!=TK_DEFERRED ){
    for(i=0; i<db->nDb; i++){
      sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
    }
  }
  sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0);
}

/*
** Commit a transaction
*/
void sqlite3CommitTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3_malloc_failed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0);
  }
}

/*
** Rollback a transaction
*/
void sqlite3RollbackTransaction(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
  if( pParse->nErr || sqlite3_malloc_failed ) return;
  if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;

  v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1);
  }
}
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
      if( rc!=SQLITE_OK ){
        sqlite3ErrorMsg(pParse, "unable to get a write lock on "
          "the temporary database file");
        pParse->rc = rc;
        return 1;
      }
    }
    assert( db->aDb[1].pSchema );
  }
  return 0;
}

/*
** Generate VDBE code that will verify the schema cookie and start
** a read-transaction for all named database files.







<







2791
2792
2793
2794
2795
2796
2797

2798
2799
2800
2801
2802
2803
2804
      if( rc!=SQLITE_OK ){
        sqlite3ErrorMsg(pParse, "unable to get a write lock on "
          "the temporary database file");
        pParse->rc = rc;
        return 1;
      }
    }

  }
  return 0;
}

/*
** Generate VDBE code that will verify the schema cookie and start
** a read-transaction for all named database files.
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
  if( iDb>=0 ){
    assert( iDb<db->nDb );
    assert( db->aDb[iDb].pBt!=0 || iDb==1 );
    assert( iDb<32 );
    mask = 1<<iDb;
    if( (pParse->cookieMask & mask)==0 ){
      pParse->cookieMask |= mask;
      pParse->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
      if( !OMIT_TEMPDB && iDb==1 ){
        sqlite3OpenTempDatabase(pParse);
      }
    }
  }
}

/*







|
|







2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
  if( iDb>=0 ){
    assert( iDb<db->nDb );
    assert( db->aDb[iDb].pBt!=0 || iDb==1 );
    assert( iDb<32 );
    mask = 1<<iDb;
    if( (pParse->cookieMask & mask)==0 ){
      pParse->cookieMask |= mask;
      pParse->cookieValue[iDb] = db->aDb[iDb].schema_cookie;
      if( iDb==1 ){
        sqlite3OpenTempDatabase(pParse);
      }
    }
  }
}

/*
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060













3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071

3072
3073

3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;
  sqlite3CodeVerifySchema(pParse, iDb);
  pParse->writeMask |= 1<<iDb;
  if( setStatement && pParse->nested==0 ){
    sqlite3VdbeAddOp(v, OP_Statement, iDb, 0);
  }
  if( (OMIT_TEMPDB || iDb!=1) && pParse->db->aDb[1].pBt!=0 ){
    sqlite3BeginWriteOperation(pParse, setStatement, 1);
  }
}














/*
** Check to see if pIndex uses the collating sequence pColl.  Return
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(const char *zColl, Index *pIndex){
  int i;
  for(i=0; i<pIndex->nColumn; i++){
    const char *z = pIndex->azColl[i];
    if( z==zColl || (z && zColl && 0==sqlite3StrICmp(z, zColl)) ){

      return 1;
    }

  }
  return 0;
}
#endif

/*
** Recompute all indices of pTab that use the collating sequence pColl.
** If pColl==0 then recompute all indices of pTab.
*/
#ifndef SQLITE_OMIT_REINDEX
static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){
  Index *pIndex;              /* An index associated with pTab */

  for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
    if( zColl==0 || collationMatch(zColl, pIndex) ){
      int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
      sqlite3BeginWriteOperation(pParse, 0, iDb);
      sqlite3RefillIndex(pParse, pIndex, -1);
    }
  }
}
#endif

/*
** Recompute all indices of all tables in all databases where the
** indices use the collating sequence pColl.  If pColl==0 then recompute
** all indices everywhere.
*/
#ifndef SQLITE_OMIT_REINDEX
static void reindexDatabases(Parse *pParse, char const *zColl){
  Db *pDb;                    /* A single database */
  int iDb;                    /* The database index number */
  sqlite3 *db = pParse->db;   /* The database connection */
  HashElem *k;                /* For looping over tables in pDb */
  Table *pTab;                /* A table in the database */

  for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
    if( pDb==0 ) continue;
    for(k=sqliteHashFirst(&pDb->pSchema->tblHash);  k; k=sqliteHashNext(k)){
      pTab = (Table*)sqliteHashData(k);
      reindexTable(pParse, pTab, zColl);
    }
  }
}
#endif

/*
** Generate code for the REINDEX command.







|



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






|
<
|
|
<
>
|
<
>










|



|
<
|












|








|

|







2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899

2900
2901

2902
2903

2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919

2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;
  sqlite3CodeVerifySchema(pParse, iDb);
  pParse->writeMask |= 1<<iDb;
  if( setStatement && pParse->nested==0 ){
    sqlite3VdbeAddOp(v, OP_Statement, iDb, 0);
  }
  if( iDb!=1 && pParse->db->aDb[1].pBt!=0 ){
    sqlite3BeginWriteOperation(pParse, setStatement, 1);
  }
}

#ifndef SQLITE_OMIT_UTF16
/* 
** Return the transient sqlite3_value object used for encoding conversions
** during SQL compilation.
*/
sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){
  if( !db->pValue ){
    db->pValue = sqlite3ValueNew();
  }
  return db->pValue;
}
#endif

/*
** Check to see if pIndex uses the collating sequence pColl.  Return
** true if it does and false if it does not.
*/
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(CollSeq *pColl, Index *pIndex){

  int n = pIndex->keyInfo.nField;
  CollSeq **pp = pIndex->keyInfo.aColl;

  while( n-- ){
    if( *pp==pColl ) return 1;

    pp++;
  }
  return 0;
}
#endif

/*
** Recompute all indices of pTab that use the collating sequence pColl.
** If pColl==0 then recompute all indices of pTab.
*/
#ifndef SQLITE_OMIT_REINDEX
void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){
  Index *pIndex;              /* An index associated with pTab */

  for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
    if( pColl==0 || collationMatch(pColl,pIndex) ){

      sqlite3BeginWriteOperation(pParse, 0, pTab->iDb);
      sqlite3RefillIndex(pParse, pIndex, -1);
    }
  }
}
#endif

/*
** Recompute all indices of all tables in all databases where the
** indices use the collating sequence pColl.  If pColl==0 then recompute
** all indices everywhere.
*/
#ifndef SQLITE_OMIT_REINDEX
void reindexDatabases(Parse *pParse, CollSeq *pColl){
  Db *pDb;                    /* A single database */
  int iDb;                    /* The database index number */
  sqlite3 *db = pParse->db;   /* The database connection */
  HashElem *k;                /* For looping over tables in pDb */
  Table *pTab;                /* A table in the database */

  for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
    if( pDb==0 ) continue;
      for(k=sqliteHashFirst(&pDb->tblHash);  k; k=sqliteHashNext(k)){
      pTab = (Table*)sqliteHashData(k);
      reindexTable(pParse, pTab, pColl);
    }
  }
}
#endif

/*
** Generate code for the REINDEX command.
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
    return;
  }

  if( pName1==0 || pName1->z==0 ){
    reindexDatabases(pParse, 0);
    return;
  }else if( pName2==0 || pName2->z==0 ){
    assert( pName1->z );
    pColl = sqlite3FindCollSeq(db, ENC(db), (char*)pName1->z, pName1->n, 0);
    if( pColl ){
      char *z = sqliteStrNDup(pName1->z, pName1->n);
      if( z ){
        reindexDatabases(pParse, z);
        sqliteFree(z);
      }
      return;
    }
  }
  iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
  if( iDb<0 ) return;
  z = sqlite3NameFromToken(pObjName);
  zDb = db->aDb[iDb].zName;







<
|

<
<
|
<
<







2977
2978
2979
2980
2981
2982
2983

2984
2985


2986


2987
2988
2989
2990
2991
2992
2993
    return;
  }

  if( pName1==0 || pName1->z==0 ){
    reindexDatabases(pParse, 0);
    return;
  }else if( pName2==0 || pName2->z==0 ){

    pColl = sqlite3FindCollSeq(db, db->enc, pName1->z, pName1->n, 0);
    if( pColl ){


      reindexDatabases(pParse, pColl);


      return;
    }
  }
  iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
  if( iDb<0 ) return;
  z = sqlite3NameFromToken(pObjName);
  zDb = db->aDb[iDb].zName;
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3RefillIndex(pParse, pIndex, -1);
    return;
  }
  sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
}
#endif

/*
** Return a dynamicly allocated KeyInfo structure that can be used
** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
**
** If successful, a pointer to the new structure is returned. In this case
** the caller is responsible for calling sqliteFree() on the returned 
** pointer. If an error occurs (out of memory or missing collation 
** sequence), NULL is returned and the state of pParse updated to reflect
** the error.
*/
KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
  int i;
  int nCol = pIdx->nColumn;
  int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
  KeyInfo *pKey = (KeyInfo *)sqliteMalloc(nBytes);

  if( pKey ){
    pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
    assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
    for(i=0; i<nCol; i++){
      char *zColl = pIdx->azColl[i];
      assert( zColl );
      pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl, -1);
      pKey->aSortOrder[i] = pIdx->aSortOrder[i];
    }
    pKey->nField = nCol;
  }

  if( pParse->nErr ){
    sqliteFree(pKey);
    pKey = 0;
  }
  return pKey;
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
3003
3004
3005
3006
3007
3008
3009



































    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3RefillIndex(pParse, pIndex, -1);
    return;
  }
  sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
}
#endif



































Deleted SQLite.Interop/src/callback.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
/*
** 2005 May 23 
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
** $Id: callback.c,v 1.11 2006/01/16 15:51:47 rmsimpson Exp $
*/

#include "sqliteInt.h"

/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
** If the collation sequence
*/
static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
  assert( !db->xCollNeeded || !db->xCollNeeded16 );
  if( nName<0 ) nName = strlen(zName);
  if( db->xCollNeeded ){
    char *zExternal = sqliteStrNDup(zName, nName);
    if( !zExternal ) return;
    db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal);
    sqliteFree(zExternal);
  }
#ifndef SQLITE_OMIT_UTF16
  if( db->xCollNeeded16 ){
    char const *zExternal;
    sqlite3_value *pTmp = sqlite3ValueNew();
    sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC);
    zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
    if( zExternal ){
      db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
    }
    sqlite3ValueFree(pTmp);
  }
#endif
}

/*
** This routine is called if the collation factory fails to deliver a
** collation function in the best encoding but there may be other versions
** of this collation function (for other text encodings) available. Use one
** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
** possible.
*/
static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
  CollSeq *pColl2;
  char *z = pColl->zName;
  int n = strlen(z);
  int i;
  static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
  for(i=0; i<3; i++){
    pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
    if( pColl2->xCmp!=0 ){
      memcpy(pColl, pColl2, sizeof(CollSeq));
      return SQLITE_OK;
    }
  }
  return SQLITE_ERROR;
}

/*
** This function is responsible for invoking the collation factory callback
** or substituting a collation sequence of a different encoding when the
** requested collation sequence is not available in the database native
** encoding.
** 
** If it is not NULL, then pColl must point to the database native encoding 
** collation sequence with name zName, length nName.
**
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.
*/
CollSeq *sqlite3GetCollSeq(
  sqlite3* db, 
  CollSeq *pColl, 
  const char *zName, 
  int nName
){
  CollSeq *p;

  p = pColl;
  if( !p ){
    p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
  }
  if( !p || !p->xCmp ){
    /* No collation sequence of this type for this encoding is registered.
    ** Call the collation factory to see if it can supply us with one.
    */
    callCollNeeded(db, zName, nName);
    p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
  }
  if( p && !p->xCmp && synthCollSeq(db, p) ){
    p = 0;
  }
  assert( !p || p->xCmp );
  return p;
}

/*
** This routine is called on a collation sequence before it is used to
** check that it is defined. An undefined collation sequence exists when
** a database is loaded that contains references to collation sequences
** that have not been defined by sqlite3_create_collation() etc.
**
** If required, this routine calls the 'collation needed' callback to
** request a definition of the collating sequence. If this doesn't work, 
** an equivalent collating sequence that uses a text encoding different
** from the main database is substituted, if one is available.
*/
int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
  if( pColl ){
    const char *zName = pColl->zName;
    CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1);
    if( !p ){
      if( pParse->nErr==0 ){
        sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
      }
      pParse->nErr++;
      return SQLITE_ERROR;
    }
    assert( p==pColl );
  }
  return SQLITE_OK;
}



/*
** Locate and return an entry from the db.aCollSeq hash table. If the entry
** specified by zName and nName is not found and parameter 'create' is
** true, then create a new entry. Otherwise return NULL.
**
** Each pointer stored in the sqlite3.aCollSeq hash table contains an
** array of three CollSeq structures. The first is the collation sequence
** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
**
** Stored immediately after the three collation sequences is a copy of
** the collation sequence name. A pointer to this string is stored in
** each collation sequence structure.
*/
static CollSeq *findCollSeqEntry(
  sqlite3 *db,
  const char *zName,
  int nName,
  int create
){
  CollSeq *pColl;
  if( nName<0 ) nName = strlen(zName);
  pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);

  if( 0==pColl && create ){
    pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 );
    if( pColl ){
      CollSeq *pDel = 0;
      pColl[0].zName = (char*)&pColl[3];
      pColl[0].enc = SQLITE_UTF8;
      pColl[1].zName = (char*)&pColl[3];
      pColl[1].enc = SQLITE_UTF16LE;
      pColl[2].zName = (char*)&pColl[3];
      pColl[2].enc = SQLITE_UTF16BE;
      memcpy(pColl[0].zName, zName, nName);
      pColl[0].zName[nName] = 0;
      pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);

      /* If a malloc() failure occured in sqlite3HashInsert(), it will 
      ** return the pColl pointer to be deleted (because it wasn't added
      ** to the hash table).
      */
      assert( !pDel ||
              (sqlite3ThreadDataReadOnly()->mallocFailed && pDel==pColl) );
      sqliteFree(pDel);
    }
  }
  return pColl;
}

/*
** Parameter zName points to a UTF-8 encoded string nName bytes long.
** Return the CollSeq* pointer for the collation sequence named zName
** for the encoding 'enc' from the database 'db'.
**
** If the entry specified is not found and 'create' is true, then create a
** new entry.  Otherwise return NULL.
*/
CollSeq *sqlite3FindCollSeq(
  sqlite3 *db,
  u8 enc,
  const char *zName,
  int nName,
  int create
){
  CollSeq *pColl;
  if( zName ){
    pColl = findCollSeqEntry(db, zName, nName, create);
  }else{
    pColl = db->pDfltColl;
  }
  assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
  assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
  if( pColl ) pColl += enc-1;
  return pColl;
}

/*
** Locate a user function given a name, a number of arguments and a flag
** indicating whether the function prefers UTF-16 over UTF-8.  Return a
** pointer to the FuncDef structure that defines that function, or return
** NULL if the function does not exist.
**
** If the createFlag argument is true, then a new (blank) FuncDef
** structure is created and liked into the "db" structure if a
** no matching function previously existed.  When createFlag is true
** and the nArg parameter is -1, then only a function that accepts
** any number of arguments will be returned.
**
** If createFlag is false and nArg is -1, then the first valid
** function found is returned.  A function is valid if either xFunc
** or xStep is non-zero.
**
** If createFlag is false, then a function with the required name and
** number of arguments may be returned even if the eTextRep flag does not
** match that requested.
*/
FuncDef *sqlite3FindFunction(
  sqlite3 *db,       /* An open database */
  const char *zName, /* Name of the function.  Not null-terminated */
  int nName,         /* Number of characters in the name */
  int nArg,          /* Number of arguments.  -1 means any number */
  u8 enc,            /* Preferred text encoding */
  int createFlag     /* Create new entry if true and does not otherwise exist */
){
  FuncDef *p;         /* Iterator variable */
  FuncDef *pFirst;    /* First function with this name */
  FuncDef *pBest = 0; /* Best match found so far */
  int bestmatch = 0;  


  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
  if( nArg<-1 ) nArg = -1;

  pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
  for(p=pFirst; p; p=p->pNext){
    /* During the search for the best function definition, bestmatch is set
    ** as follows to indicate the quality of the match with the definition
    ** pointed to by pBest:
    **
    ** 0: pBest is NULL. No match has been found.
    ** 1: A variable arguments function that prefers UTF-8 when a UTF-16
    **    encoding is requested, or vice versa.
    ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
    **    requested, or vice versa.
    ** 3: A variable arguments function using the same text encoding.
    ** 4: A function with the exact number of arguments requested that
    **    prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
    ** 5: A function with the exact number of arguments requested that
    **    prefers UTF-16LE when UTF-16BE is requested, or vice versa.
    ** 6: An exact match.
    **
    ** A larger value of 'matchqual' indicates a more desirable match.
    */
    if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
      int match = 1;          /* Quality of this match */
      if( p->nArg==nArg || nArg==-1 ){
        match = 4;
      }
      if( enc==p->iPrefEnc ){
        match += 2;
      }
      else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
               (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
        match += 1;
      }

      if( match>bestmatch ){
        pBest = p;
        bestmatch = match;
      }
    }
  }

  /* If the createFlag parameter is true, and the seach did not reveal an
  ** exact match for the name, number of arguments and encoding, then add a
  ** new entry to the hash table and return it.
  */
  if( createFlag && bestmatch<6 && 
      (pBest = sqliteMalloc(sizeof(*pBest)+nName))!=0 ){
    pBest->nArg = nArg;
    pBest->pNext = pFirst;
    pBest->iPrefEnc = enc;
    memcpy(pBest->zName, zName, nName);
    pBest->zName[nName] = 0;
    if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
      sqliteFree(pBest);
      return 0;
    }
  }

  if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
    return pBest;
  }
  return 0;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































Deleted SQLite.Interop/src/complete.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that implements the sqlite3_complete() API.
** This code used to be part of the tokenizer.c source file.  But by
** separating it out, the code will be automatically omitted from
** static links that do not use it.
**
** $Id: complete.c,v 1.9 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#ifndef SQLITE_OMIT_COMPLETE

/*
** This is defined in tokenize.c.  We just have to import the definition.
*/
extern const char sqlite3IsIdChar[];
#define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsIdChar[c-0x20]))


/*
** Token types used by the sqlite3_complete() routine.  See the header
** comments on that procedure for additional information.
*/
#define tkSEMI    0
#define tkWS      1
#define tkOTHER   2
#define tkEXPLAIN 3
#define tkCREATE  4
#define tkTEMP    5
#define tkTRIGGER 6
#define tkEND     7

/*
** Return TRUE if the given SQL string ends in a semicolon.
**
** Special handling is require for CREATE TRIGGER statements.
** Whenever the CREATE TRIGGER keywords are seen, the statement
** must end with ";END;".
**
** This implementation uses a state machine with 7 states:
**
**   (0) START     At the beginning or end of an SQL statement.  This routine
**                 returns 1 if it ends in the START state and 0 if it ends
**                 in any other state.
**
**   (1) NORMAL    We are in the middle of statement which ends with a single
**                 semicolon.
**
**   (2) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of 
**                 a statement.
**
**   (3) CREATE    The keyword CREATE has been seen at the beginning of a
**                 statement, possibly preceeded by EXPLAIN and/or followed by
**                 TEMP or TEMPORARY
**
**   (4) TRIGGER   We are in the middle of a trigger definition that must be
**                 ended by a semicolon, the keyword END, and another semicolon.
**
**   (5) SEMI      We've seen the first semicolon in the ";END;" that occurs at
**                 the end of a trigger definition.
**
**   (6) END       We've seen the ";END" of the ";END;" that occurs at the end
**                 of a trigger difinition.
**
** Transitions between states above are determined by tokens extracted
** from the input.  The following tokens are significant:
**
**   (0) tkSEMI      A semicolon.
**   (1) tkWS        Whitespace
**   (2) tkOTHER     Any other SQL token.
**   (3) tkEXPLAIN   The "explain" keyword.
**   (4) tkCREATE    The "create" keyword.
**   (5) tkTEMP      The "temp" or "temporary" keyword.
**   (6) tkTRIGGER   The "trigger" keyword.
**   (7) tkEND       The "end" keyword.
**
** Whitespace never causes a state transition and is always ignored.
**
** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
** to recognize the end of a trigger can be omitted.  All we have to do
** is look for a semicolon that is not part of an string or comment.
*/
int sqlite3_complete(const char *zSql){
  u8 state = 0;   /* Current state, using numbers defined in header comment */
  u8 token;       /* Value of the next token */

#ifndef SQLITE_OMIT_TRIGGER
  /* A complex statement machine used to detect the end of a CREATE TRIGGER
  ** statement.  This is the normal case.
  */
  static const u8 trans[7][8] = {
                     /* Token:                                                */
     /* State:       **  SEMI  WS  OTHER EXPLAIN  CREATE  TEMP  TRIGGER  END  */
     /* 0   START: */ {    0,  0,     1,      2,      3,    1,       1,   1,  },
     /* 1  NORMAL: */ {    0,  1,     1,      1,      1,    1,       1,   1,  },
     /* 2 EXPLAIN: */ {    0,  2,     1,      1,      3,    1,       1,   1,  },
     /* 3  CREATE: */ {    0,  3,     1,      1,      1,    3,       4,   1,  },
     /* 4 TRIGGER: */ {    5,  4,     4,      4,      4,    4,       4,   4,  },
     /* 5    SEMI: */ {    5,  5,     4,      4,      4,    4,       4,   6,  },
     /* 6     END: */ {    0,  6,     4,      4,      4,    4,       4,   4,  },
  };
#else
  /* If triggers are not suppored by this compile then the statement machine
  ** used to detect the end of a statement is much simplier
  */
  static const u8 trans[2][3] = {
                     /* Token:           */
     /* State:       **  SEMI  WS  OTHER */
     /* 0   START: */ {    0,  0,     1, },
     /* 1  NORMAL: */ {    0,  1,     1, },
  };
#endif /* SQLITE_OMIT_TRIGGER */

  while( *zSql ){
    switch( *zSql ){
      case ';': {  /* A semicolon */
        token = tkSEMI;
        break;
      }
      case ' ':
      case '\r':
      case '\t':
      case '\n':
      case '\f': {  /* White space is ignored */
        token = tkWS;
        break;
      }
      case '/': {   /* C-style comments */
        if( zSql[1]!='*' ){
          token = tkOTHER;
          break;
        }
        zSql += 2;
        while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
        if( zSql[0]==0 ) return 0;
        zSql++;
        token = tkWS;
        break;
      }
      case '-': {   /* SQL-style comments from "--" to end of line */
        if( zSql[1]!='-' ){
          token = tkOTHER;
          break;
        }
        while( *zSql && *zSql!='\n' ){ zSql++; }
        if( *zSql==0 ) return state==0;
        token = tkWS;
        break;
      }
      case '[': {   /* Microsoft-style identifiers in [...] */
        zSql++;
        while( *zSql && *zSql!=']' ){ zSql++; }
        if( *zSql==0 ) return 0;
        token = tkOTHER;
        break;
      }
      case '`':     /* Grave-accent quoted symbols used by MySQL */
      case '"':     /* single- and double-quoted strings */
      case '\'': {
        int c = *zSql;
        zSql++;
        while( *zSql && *zSql!=c ){ zSql++; }
        if( *zSql==0 ) return 0;
        token = tkOTHER;
        break;
      }
      default: {
        int c;
        if( IdChar((u8)*zSql) ){
          /* Keywords and unquoted identifiers */
          int nId;
          for(nId=1; IdChar(zSql[nId]); nId++){}
#ifdef SQLITE_OMIT_TRIGGER
          token = tkOTHER;
#else
          switch( *zSql ){
            case 'c': case 'C': {
              if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
                token = tkCREATE;
              }else{
                token = tkOTHER;
              }
              break;
            }
            case 't': case 'T': {
              if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
                token = tkTRIGGER;
              }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
                token = tkTEMP;
              }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
                token = tkTEMP;
              }else{
                token = tkOTHER;
              }
              break;
            }
            case 'e':  case 'E': {
              if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
                token = tkEND;
              }else
#ifndef SQLITE_OMIT_EXPLAIN
              if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
                token = tkEXPLAIN;
              }else
#endif
              {
                token = tkOTHER;
              }
              break;
            }
            default: {
              token = tkOTHER;
              break;
            }
          }
#endif /* SQLITE_OMIT_TRIGGER */
          zSql += nId-1;
        }else{
          /* Operators and special symbols */
          token = tkOTHER;
        }
        break;
      }
    }
    state = trans[state][token];
    zSql++;
  }
  return state==0;
}

#ifndef SQLITE_OMIT_UTF16
/*
** This routine is the same as the sqlite3_complete() routine described
** above, except that the parameter is required to be UTF-16 encoded, not
** UTF-8.
*/
int sqlite3_complete16(const void *zSql){
  sqlite3_value *pVal;
  char const *zSql8;
  int rc = 0;

  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zSql8 ){
    rc = sqlite3_complete(zSql8);
  }else if( zSql ){
    rc = SQLITE_NOMEM;
    sqlite3MallocClearFailed();
  }
  sqlite3ValueFree(pVal);
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_OMIT_COMPLETE */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































Added SQLite.Interop/src/config.h.


>
1
#define SQLITE_PTR_SZ 4
Changes to SQLite.Interop/src/date.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This file contains the C functions that implement date and time
** functions for SQLite.  
**
** There is only one exported symbol in this file - the function
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.16 2006/01/16 15:51:47 rmsimpson Exp $
**
** NOTES:
**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This file contains the C functions that implement date and time
** functions for SQLite.  
**
** There is only one exported symbol in this file - the function
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.1 2005/03/01 16:04:28 rmsimpson Exp $
**
** NOTES:
**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128


129


130
131
132
133
134
135
136
    min = va_arg(ap, int);
    max = va_arg(ap, int);
    nextC = va_arg(ap, int);
    pVal = va_arg(ap, int*);
    val = 0;
    while( N-- ){
      if( !isdigit(*(u8*)zDate) ){
        goto end_getDigits;
      }
      val = val*10 + *zDate - '0';
      zDate++;
    }
    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
      goto end_getDigits;
    }
    *pVal = val;
    zDate++;
    cnt++;
  }while( nextC );
  va_end(ap);
end_getDigits:
  return cnt;
}

/*
** Read text from z[] and convert into a floating point number.  Return
** the number of digits converted.
*/


#define getValue sqlite3AtoF



/*
** Parse a timezone extension on the end of a date-time.
** The extension is of the form:
**
**        (+/-)HH:MM
**







|





|





<
<







>
>
|
>
>







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
    min = va_arg(ap, int);
    max = va_arg(ap, int);
    nextC = va_arg(ap, int);
    pVal = va_arg(ap, int*);
    val = 0;
    while( N-- ){
      if( !isdigit(*(u8*)zDate) ){
        return cnt;
      }
      val = val*10 + *zDate - '0';
      zDate++;
    }
    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
      return cnt;
    }
    *pVal = val;
    zDate++;
    cnt++;
  }while( nextC );


  return cnt;
}

/*
** Read text from z[] and convert into a floating point number.  Return
** the number of digits converted.
*/
static int getValue(const char *z, double *pR){
  const char *zEnd;
  *pR = sqlite3AtoF(z, &zEnd);
  return zEnd - z;
}

/*
** Parse a timezone extension on the end of a date-time.
** The extension is of the form:
**
**        (+/-)HH:MM
**
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  X2 = 30.6001*(M+1);
  p->rJD = X1 + X2 + D + B - 1524.5;
  p->validJD = 1;
  p->validYMD = 0;
  if( p->validHMS ){
    p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
    if( p->validTZ ){
      p->rJD -= p->tz*60/86400.0;
      p->validHMS = 0;
      p->validTZ = 0;
    }
  }
}

/*







|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
  X2 = 30.6001*(M+1);
  p->rJD = X1 + X2 + D + B - 1524.5;
  p->validJD = 1;
  p->validYMD = 0;
  if( p->validHMS ){
    p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
    if( p->validTZ ){
      p->rJD += p->tz*60/86400.0;
      p->validHMS = 0;
      p->validTZ = 0;
    }
  }
}

/*
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  }else{
    neg = 0;
  }
  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
    return 1;
  }
  zDate += 10;
  while( isspace(*(u8*)zDate) || 'T'==*(u8*)zDate ){ zDate++; }
  if( parseHhMmSs(zDate, p)==0 ){
    /* We got the time */
  }else if( *zDate==0 ){
    p->validHMS = 0;
  }else{
    return 1;
  }







|







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
  }else{
    neg = 0;
  }
  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
    return 1;
  }
  zDate += 10;
  while( isspace(*(u8*)zDate) ){ zDate++; }
  if( parseHhMmSs(zDate, p)==0 ){
    /* We got the time */
  }else if( *zDate==0 ){
    p->validHMS = 0;
  }else{
    return 1;
  }
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
  }else if( sqlite3StrICmp(zDate,"now")==0){
    double r;
    sqlite3OsCurrentTime(&r);
    p->rJD = r;
    p->validJD = 1;
    return 0;
  }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){
    getValue(zDate, &p->rJD);
    p->validJD = 1;
    return 0;
  }
  return 1;
}

/*







|







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
  }else if( sqlite3StrICmp(zDate,"now")==0){
    double r;
    sqlite3OsCurrentTime(&r);
    p->rJD = r;
    p->validJD = 1;
    return 0;
  }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){
    p->rJD = sqlite3AtoF(zDate, 0);
    p->validJD = 1;
    return 0;
  }
  return 1;
}

/*
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
** the resulting time into the DateTime structure p.  Return 0
** on success and 1 if there are any errors.
*/
static int isDate(int argc, sqlite3_value **argv, DateTime *p){
  int i;
  if( argc==0 ) return 1;
  if( SQLITE_NULL==sqlite3_value_type(argv[0]) || 
      parseDateOrTime((char*)sqlite3_value_text(argv[0]), p) ) return 1;
  for(i=1; i<argc; i++){
    if( SQLITE_NULL==sqlite3_value_type(argv[i]) || 
        parseModifier((char*)sqlite3_value_text(argv[i]), p) ) return 1;
  }
  return 0;
}


/*
** The following routines implement the various date and time functions







|


|







639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
** the resulting time into the DateTime structure p.  Return 0
** on success and 1 if there are any errors.
*/
static int isDate(int argc, sqlite3_value **argv, DateTime *p){
  int i;
  if( argc==0 ) return 1;
  if( SQLITE_NULL==sqlite3_value_type(argv[0]) || 
      parseDateOrTime(sqlite3_value_text(argv[0]), p) ) return 1;
  for(i=1; i<argc; i++){
    if( SQLITE_NULL==sqlite3_value_type(argv[i]) || 
        parseModifier(sqlite3_value_text(argv[i]), p) ) return 1;
  }
  return 0;
}


/*
** The following routines implement the various date and time functions
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  DateTime x;
  int n, i, j;
  char *z;
  const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
  char zBuf[100];
  if( zFmt==0 || isDate(argc-1, argv+1, &x) ) return;
  for(i=0, n=1; zFmt[i]; i++, n++){
    if( zFmt[i]=='%' ){
      switch( zFmt[i+1] ){
        case 'd':
        case 'H':







|







755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  DateTime x;
  int n, i, j;
  char *z;
  const char *zFmt = sqlite3_value_text(argv[0]);
  char zBuf[100];
  if( zFmt==0 || isDate(argc-1, argv+1, &x) ) return;
  for(i=0, n=1; zFmt[i]; i++, n++){
    if( zFmt[i]=='%' ){
      switch( zFmt[i+1] ){
        case 'd':
        case 'H':
Changes to SQLite.Interop/src/delete.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
*/
Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
  Table *pTab = 0;
  int i;
  struct SrcList_item *pItem;
  for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
    pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);
    sqlite3DeleteTable(pParse->db, pItem->pTab);
    pItem->pTab = pTab;
    if( pTab ){
      pTab->nRef++;
    }
  }
  return pTab;
}

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is







|














<

<
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

30



31
32
33
34
35
36
37
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.1 2005/03/01 16:04:29 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
*/
Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
  Table *pTab = 0;
  int i;
  struct SrcList_item *pItem;
  for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
    pTab = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase);

    pItem->pTab = pTab;



  }
  return pTab;
}

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
#endif
  return 0;
}

/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTable(
  Parse *p,       /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */
  int iDb,        /* The database index in sqlite3.aDb[] */
  Table *pTab,    /* The table to be opened */
  int opcode      /* OP_OpenRead or OP_OpenWrite */
){
  Vdbe *v = sqlite3GetVdbe(p);
  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
  sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);
  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);

  VdbeComment((v, "# %s", pTab->zName));
  sqlite3VdbeAddOp(v, opcode, iCur, pTab->tnum);
  sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
}


/*
** Generate code for a DELETE FROM statement.
**







|
|

<
|
<

<
<
<
|
>

<







51
52
53
54
55
56
57
58
59
60

61

62



63
64
65

66
67
68
69
70
71
72
#endif
  return 0;
}

/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTableForReading(
  Vdbe *v,        /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */

  Table *pTab     /* The table to be opened */

){



  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
  VdbeComment((v, "# %s", pTab->zName));

  sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
}


/*
** Generate code for a DELETE FROM statement.
**
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
  WhereInfo *pWInfo;     /* Information about the WHERE clause */
  Index *pIdx;           /* For looping over indices of the table */
  int iCur;              /* VDBE Cursor number for pTab */
  sqlite3 *db;           /* Main database structure */
  AuthContext sContext;  /* Authorization context */
  int oldIdx = -1;       /* Cursor for the OLD table of AFTER triggers */
  NameContext sNC;       /* Name context to resolve expressions in */
  int iDb;

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* True if attempting to delete from a view */
  int triggers_exist = 0;      /* True if any triggers exist */
#endif

  sContext.pParse = 0;
  if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){

    goto delete_from_cleanup;
  }
  db = pParse->db;
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to delete.  This table has to be
  ** put in an SrcList structure because some of the subroutines we







<







|
>







87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  WhereInfo *pWInfo;     /* Information about the WHERE clause */
  Index *pIdx;           /* For looping over indices of the table */
  int iCur;              /* VDBE Cursor number for pTab */
  sqlite3 *db;           /* Main database structure */
  AuthContext sContext;  /* Authorization context */
  int oldIdx = -1;       /* Cursor for the OLD table of AFTER triggers */
  NameContext sNC;       /* Name context to resolve expressions in */


#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* True if attempting to delete from a view */
  int triggers_exist = 0;      /* True if any triggers exist */
#endif

  sContext.pParse = 0;
  if( pParse->nErr || sqlite3_malloc_failed ){
    pTabList = 0;
    goto delete_from_cleanup;
  }
  db = pParse->db;
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to delete.  This table has to be
  ** put in an SrcList structure because some of the subroutines we
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# undef isView
# define isView 0
#endif

  if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
    goto delete_from_cleanup;
  }
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iDb<db->nDb );
  zDb = db->aDb[iDb].zName;
  if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
    goto delete_from_cleanup;
  }

  /* If pTab is really a view, make sure it has been initialized.
  */
  if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){







<
|
|







127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
# undef isView
# define isView 0
#endif

  if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
    goto delete_from_cleanup;
  }

  assert( pTab->iDb<db->nDb );
  zDb = db->aDb[pTab->iDb].zName;
  if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
    goto delete_from_cleanup;
  }

  /* If pTab is really a view, make sure it has been initialized.
  */
  if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
  /* Begin generating code.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    goto delete_from_cleanup;
  }
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, triggers_exist, iDb);

  /* If we are trying to delete from a view, realize that view into
  ** a ephemeral table.
  */
  if( isView ){
    Select *pView = sqlite3SelectDup(pTab->pSelect);
    sqlite3Select(pParse, pView, SRT_VirtualTab, iCur, 0, 0, 0, 0);
    sqlite3SelectDelete(pView);
  }

  /* Initialize the counter of the number of rows deleted, if
  ** we are counting rows.
  */
  if( db->flags & SQLITE_CountRows ){







|

|
|



|







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  /* Begin generating code.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    goto delete_from_cleanup;
  }
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, triggers_exist, pTab->iDb);

  /* If we are trying to delete from a view, construct that view into
  ** a temporary table.
  */
  if( isView ){
    Select *pView = sqlite3SelectDup(pTab->pSelect);
    sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0, 0);
    sqlite3SelectDelete(pView);
  }

  /* Initialize the counter of the number of rows deleted, if
  ** we are counting rows.
  */
  if( db->flags & SQLITE_CountRows ){
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
  if( pWhere==0 && !triggers_exist ){
    if( db->flags & SQLITE_CountRows ){
      /* If counting rows deleted, just count the total number of
      ** entries in the table. */
      int endOfLoop = sqlite3VdbeMakeLabel(v);
      int addr;
      if( !isView ){
        sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
      }
      sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
      addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
      sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
      sqlite3VdbeResolveLabel(v, endOfLoop);
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, iDb);
      if( !pParse->nested ){
        sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
      }
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
        assert( pIdx->pSchema==pTab->pSchema );
        sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, iDb);
      }
    }
  }

  /* The usual case: There is a WHERE clause so we have to scan through
  ** the table and pick which records to delete.
  */
  else{







    /* Begin the database scan
    */
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
    if( pWInfo==0 ) goto delete_from_cleanup;

    /* Remember the rowid of every item to be deleted.
    */
    sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
    sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);
    if( db->flags & SQLITE_CountRows ){
      sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
    }

    /* End the database scan loop.
    */
    sqlite3WhereEnd(pWInfo);

    /* Open the pseudo-table used to store OLD if there are triggers.
    */
    if( triggers_exist ){
      sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
    }

    /* Delete every item whose key was written to the list during the
    ** database scan.  We have to delete items after the scan is complete
    ** because deleting an item can change the scan order.
    */

    end = sqlite3VdbeMakeLabel(v);

    /* This is the beginning of the delete loop when there are
    ** row triggers.
    */
    if( triggers_exist ){
      addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Dup, 0, 0);

        sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
      }
      sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
      sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
      sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
      }

      (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
          -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
          addr);
    }

    if( !isView ){
      /* Open cursors for the table we are deleting from and all its
      ** indices.  If there are row triggers, this happens inside the
      ** OP_FifoRead loop because the cursor have to all be closed
      ** before the trigger fires.  If there are no row triggers, the
      ** cursors are opened only once on the outside the loop.
      */
      sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);

      /* This is the beginning of the delete loop when there are no
      ** row triggers */
      if( !triggers_exist ){ 
        addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
      }

      /* Delete the row */
      sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0);
    }

    /* If there are row triggers, close all cursors then invoke
    ** the AFTER triggers
    */
    if( triggers_exist ){
      if( !isView ){
        for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
          sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
        }
        sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
      }
      (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
          oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
          addr);
    }

    /* End of the delete loop */
    sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
    sqlite3VdbeResolveLabel(v, end);


    /* Close the cursors after the loop if there are no row triggers */
    if( !triggers_exist ){
      for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
        sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
      }
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);







|








|
<
<
<

<
|








>
>
>
>
>
>
>


|




|
|



















>






|
<
|
>
|


|

|






|





|








|


















|





>







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214



215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
  if( pWhere==0 && !triggers_exist ){
    if( db->flags & SQLITE_CountRows ){
      /* If counting rows deleted, just count the total number of
      ** entries in the table. */
      int endOfLoop = sqlite3VdbeMakeLabel(v);
      int addr;
      if( !isView ){
        sqlite3OpenTableForReading(v, iCur, pTab);
      }
      sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
      addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
      sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
      sqlite3VdbeResolveLabel(v, endOfLoop);
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, pTab->iDb);



      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){

        sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, pIdx->iDb);
      }
    }
  }

  /* The usual case: There is a WHERE clause so we have to scan through
  ** the table and pick which records to delete.
  */
  else{
    /* Ensure all required collation sequences are available. */
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
        goto delete_from_cleanup;
      }
    }

    /* Begin the database scan
    */
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0);
    if( pWInfo==0 ) goto delete_from_cleanup;

    /* Remember the rowid of every item to be deleted.
    */
    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
    if( db->flags & SQLITE_CountRows ){
      sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
    }

    /* End the database scan loop.
    */
    sqlite3WhereEnd(pWInfo);

    /* Open the pseudo-table used to store OLD if there are triggers.
    */
    if( triggers_exist ){
      sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
    }

    /* Delete every item whose key was written to the list during the
    ** database scan.  We have to delete items after the scan is complete
    ** because deleting an item can change the scan order.
    */
    sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
    end = sqlite3VdbeMakeLabel(v);

    /* This is the beginning of the delete loop when there are
    ** row triggers.
    */
    if( triggers_exist ){
      addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);

      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      if( !isView ){
        sqlite3OpenTableForReading(v, iCur, pTab);
      }
      sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
      sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
      sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
      }

      (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab,
          -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
	  addr);
    }

    if( !isView ){
      /* Open cursors for the table we are deleting from and all its
      ** indices.  If there are row triggers, this happens inside the
      ** OP_ListRead loop because the cursor have to all be closed
      ** before the trigger fires.  If there are no row triggers, the
      ** cursors are opened only once on the outside the loop.
      */
      sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);

      /* This is the beginning of the delete loop when there are no
      ** row triggers */
      if( !triggers_exist ){ 
        addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
      }

      /* Delete the row */
      sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0);
    }

    /* If there are row triggers, close all cursors then invoke
    ** the AFTER triggers
    */
    if( triggers_exist ){
      if( !isView ){
        for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
          sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
        }
        sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
      }
      (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1,
          oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
	  addr);
    }

    /* End of the delete loop */
    sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
    sqlite3VdbeResolveLabel(v, end);
    sqlite3VdbeAddOp(v, OP_ListReset, 0, 0);

    /* Close the cursors after the loop if there are no row triggers */
    if( !triggers_exist ){
      for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
        sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
      }
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
  int iCur,          /* Cursor number for the table */
  int count          /* Increment the row change counter */
){
  int addr;
  addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
  sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, 0);
  sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
  if( count ){
    sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
  }
  sqlite3VdbeJumpHere(v, addr);
}

/*
** This routine generates VDBE code that causes the deletion of all
** index entries associated with a single row of a single table.
**
** The VDBE must be in a particular state when this routine is called.







<
|
<
<







375
376
377
378
379
380
381

382


383
384
385
386
387
388
389
  int iCur,          /* Cursor number for the table */
  int count          /* Increment the row change counter */
){
  int addr;
  addr = sqlite3VdbeAddOp(v, OP_NotExists, iCur, 0);
  sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, 0);
  sqlite3VdbeAddOp(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));

  sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));


}

/*
** This routine generates VDBE code that causes the deletion of all
** index entries associated with a single row of a single table.
**
** The VDBE must be in a particular state when this routine is called.
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
  Vdbe *v,           /* Generate code into this VDBE */
  Index *pIdx,       /* The index for which to generate a key */
  int iCur           /* Cursor number for the pIdx->pTable table */
){
  int j;
  Table *pTab = pIdx->pTable;

  sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
  for(j=0; j<pIdx->nColumn; j++){
    int idx = pIdx->aiColumn[j];
    if( idx==pTab->iPKey ){
      sqlite3VdbeAddOp(v, OP_Dup, j, 0);
    }else{
      sqlite3VdbeAddOp(v, OP_Column, iCur, idx);
      sqlite3ColumnDefault(v, pTab, idx);
    }
  }
  sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0);
  sqlite3IndexAffinityStr(v, pIdx);
}







|






<


|


425
426
427
428
429
430
431
432
433
434
435
436
437
438

439
440
441
442
443
  Vdbe *v,           /* Generate code into this VDBE */
  Index *pIdx,       /* The index for which to generate a key */
  int iCur           /* Cursor number for the pIdx->pTable table */
){
  int j;
  Table *pTab = pIdx->pTable;

  sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
  for(j=0; j<pIdx->nColumn; j++){
    int idx = pIdx->aiColumn[j];
    if( idx==pTab->iPKey ){
      sqlite3VdbeAddOp(v, OP_Dup, j, 0);
    }else{
      sqlite3VdbeAddOp(v, OP_Column, iCur, idx);

    }
  }
  sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24));
  sqlite3IndexAffinityStr(v, pIdx);
}
Deleted SQLite.Interop/src/experimental.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
** 2005 January 20
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are not a part of the official
** SQLite API.  These routines are unsupported.
**
** $Id: experimental.c,v 1.5 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** Set all the parameters in the compiled SQL statement to NULL.
*/
int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
  int i;
  int rc = SQLITE_OK;
  for(i=1; rc==SQLITE_OK && i<=sqlite3_bind_parameter_count(pStmt); i++){
    rc = sqlite3_bind_null(pStmt, i);
  }
  return rc;
}

/*
** Sleep for a little while.  Return the amount of time slept.
*/
int sqlite3_sleep(int ms){
  return sqlite3OsSleep(ms);
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































Changes to SQLite.Interop/src/expr.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.22 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.1 2005/03/01 16:04:29 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81


82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
**
** CREATE TABLE t1(a);
** SELECT * FROM t1 WHERE a;
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
char sqlite3ExprAffinity(Expr *pExpr){
  int op = pExpr->op;
  if( op==TK_AS ){
    return sqlite3ExprAffinity(pExpr->pLeft);
  }
  if( op==TK_SELECT ){
    return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr);
  }
#ifndef SQLITE_OMIT_CAST
  if( op==TK_CAST ){
    return sqlite3AffinityType(&pExpr->token);
  }
#endif
  return pExpr->affinity;
}

/*
** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
*/
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
  CollSeq *pColl = 0;
  if( pExpr ){
    pColl = pExpr->pColl;
    if( (pExpr->op==TK_AS || pExpr->op==TK_CAST) && !pColl ){
      return sqlite3ExprCollSeq(pParse, pExpr->pLeft);
    }
  }
  if( sqlite3CheckCollSeq(pParse, pColl) ){ 
    pColl = 0;
  }
  return pColl;
}

/*
** pExpr is an operand of a comparison operator.  aff2 is the
** type affinity of the other operand.  This routine returns the
** type affinity that should be used for the comparison operator.
*/
char sqlite3CompareAffinity(Expr *pExpr, char aff2){
  char aff1 = sqlite3ExprAffinity(pExpr);
  if( aff1 && aff2 ){
    /* Both sides of the comparison are columns. If one has numeric
    ** affinity, use that. Otherwise use no affinity.
    */
    if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){


      return SQLITE_AFF_NUMERIC;
    }else{
      return SQLITE_AFF_NONE;
    }
  }else if( !aff1 && !aff2 ){
    /* Neither side of the comparison is a column.  Compare the
    ** results directly.
    */

    return SQLITE_AFF_NONE;
  }else{
    /* One side is a column, the other is not. Use the columns affinity. */
    assert( aff1==0 || aff2==0 );
    return (aff1 + aff2);
  }
}

/*
** pExpr is a comparison operator.  Return the type affinity that should
** be applied to both operands prior to doing the comparison.







<
|


|


<
<
<
<
<











|

















|
|

|
>
>








>



<







30
31
32
33
34
35
36

37
38
39
40
41
42





43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
**
** CREATE TABLE t1(a);
** SELECT * FROM t1 WHERE a;
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
char sqlite3ExprAffinity(Expr *pExpr){

  if( pExpr->op==TK_AS ){
    return sqlite3ExprAffinity(pExpr->pLeft);
  }
  if( pExpr->op==TK_SELECT ){
    return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr);
  }





  return pExpr->affinity;
}

/*
** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
*/
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
  CollSeq *pColl = 0;
  if( pExpr ){
    pColl = pExpr->pColl;
    if( pExpr->op==TK_AS && !pColl ){
      return sqlite3ExprCollSeq(pParse, pExpr->pLeft);
    }
  }
  if( sqlite3CheckCollSeq(pParse, pColl) ){ 
    pColl = 0;
  }
  return pColl;
}

/*
** pExpr is an operand of a comparison operator.  aff2 is the
** type affinity of the other operand.  This routine returns the
** type affinity that should be used for the comparison operator.
*/
char sqlite3CompareAffinity(Expr *pExpr, char aff2){
  char aff1 = sqlite3ExprAffinity(pExpr);
  if( aff1 && aff2 ){
    /* Both sides of the comparison are columns. If one has numeric or
    ** integer affinity, use that. Otherwise use no affinity.
    */
    if( aff1==SQLITE_AFF_INTEGER || aff2==SQLITE_AFF_INTEGER ){
      return SQLITE_AFF_INTEGER;
    }else if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){
      return SQLITE_AFF_NUMERIC;
    }else{
      return SQLITE_AFF_NONE;
    }
  }else if( !aff1 && !aff2 ){
    /* Neither side of the comparison is a column.  Compare the
    ** results directly.
    */
    /* return SQLITE_AFF_NUMERIC;  // Ticket #805 */
    return SQLITE_AFF_NONE;
  }else{
    /* One side is a column, the other is not. Use the columns affinity. */

    return (aff1 + aff2);
  }
}

/*
** pExpr is a comparison operator.  Return the type affinity that should
** be applied to both operands prior to doing the comparison.
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
** idx_affinity is the affinity of an indexed column. Return true
** if the index with affinity idx_affinity may be used to implement
** the comparison in pExpr.
*/
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
  char aff = comparisonAffinity(pExpr);
  switch( aff ){
    case SQLITE_AFF_NONE:
      return 1;
    case SQLITE_AFF_TEXT:
      return idx_affinity==SQLITE_AFF_TEXT;
    default:

      return sqlite3IsNumericAffinity(idx_affinity);
  }
}

/*
** Return the P1 value that should be used for a binary comparison
** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
** If jumpIfNull is true, then set the low byte of the returned
** P1 value to tell the opcode to jump if either expression
** evaluates to NULL.
*/
static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
  char aff = sqlite3ExprAffinity(pExpr2);
  return ((int)sqlite3CompareAffinity(pExpr1, aff))+(jumpIfNull?0x100:0);
}

/*
** Return a pointer to the collation sequence that should be used by
** a binary comparison operator comparing pLeft and pRight.
**
** If the left hand expression has a collating sequence type, then it is







<
<
|
|
|
<
>
|
<











|







118
119
120
121
122
123
124


125
126
127

128
129

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
** idx_affinity is the affinity of an indexed column. Return true
** if the index with affinity idx_affinity may be used to implement
** the comparison in pExpr.
*/
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
  char aff = comparisonAffinity(pExpr);


  return 
    (aff==SQLITE_AFF_NONE) ||
    (aff==SQLITE_AFF_NUMERIC && idx_affinity==SQLITE_AFF_INTEGER) ||

    (aff==SQLITE_AFF_INTEGER && idx_affinity==SQLITE_AFF_NUMERIC) ||
    (aff==idx_affinity);

}

/*
** Return the P1 value that should be used for a binary comparison
** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
** If jumpIfNull is true, then set the low byte of the returned
** P1 value to tell the opcode to jump if either expression
** evaluates to NULL.
*/
static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
  char aff = sqlite3ExprAffinity(pExpr2);
  return (((int)sqlite3CompareAffinity(pExpr1, aff))<<8)+(jumpIfNull?1:0);
}

/*
** Return a pointer to the collation sequence that should be used by
** a binary comparison operator comparing pLeft and pRight.
**
** If the left hand expression has a collating sequence type, then it is
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
238

239
240
241



242
243
244
245
246
247
248
** for this node is obtained from sqliteMalloc().  The calling function
** is responsible for making sure the node eventually gets freed.
*/
Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){
  Expr *pNew;
  pNew = sqliteMalloc( sizeof(Expr) );
  if( pNew==0 ){
    /* When malloc fails, delete pLeft and pRight. Expressions passed to 
    ** this function must always be allocated with sqlite3Expr() for this 
    ** reason. 
    */
    sqlite3ExprDelete(pLeft);
    sqlite3ExprDelete(pRight);
    return 0;
  }
  pNew->op = op;
  pNew->pLeft = pLeft;
  pNew->pRight = pRight;
  pNew->iAgg = -1;
  if( pToken ){
    assert( pToken->dyn==0 );
    pNew->span = pNew->token = *pToken;
  }else if( pLeft && pRight ){
    sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
  }
  return pNew;
}

/*
** When doing a nested parse, you can include terms in an expression
** that look like this:   #0 #1 #2 ...  These terms refer to elements
** on the stack.  "#0" means the top of the stack.
** "#1" means the next down on the stack.  And so forth.

**
** This routine is called by the parser to deal with on of those terms.
** It immediately generates code to store the value in a memory location.
** The returns an expression that will code to extract the value from
** that memory location as needed.
*/
Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
  Vdbe *v = pParse->pVdbe;
  Expr *p;
  int depth;

  if( pParse->nested==0 ){
    sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken);
    return 0;
  }
  if( v==0 ) return 0;
  p = sqlite3Expr(TK_REGISTER, 0, 0, pToken);
  if( p==0 ){
    return 0;  /* Malloc failed */
  }
  depth = atoi((char*)&pToken->z[1]);

  p->iTable = pParse->nMem++;
  sqlite3VdbeAddOp(v, OP_Dup, depth, 0);
  sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1);



  return p;
}

/*
** Join two expressions using an AND operator.  If either expression is
** NULL, then just return the other expression.
*/







|
<
<
<
<
<


















|
|
>










>




<




|
>
|
|
|
>
>
>







179
180
181
182
183
184
185
186





187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
** for this node is obtained from sqliteMalloc().  The calling function
** is responsible for making sure the node eventually gets freed.
*/
Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){
  Expr *pNew;
  pNew = sqliteMalloc( sizeof(Expr) );
  if( pNew==0 ){
    /* When malloc fails, we leak memory from pLeft and pRight */





    return 0;
  }
  pNew->op = op;
  pNew->pLeft = pLeft;
  pNew->pRight = pRight;
  pNew->iAgg = -1;
  if( pToken ){
    assert( pToken->dyn==0 );
    pNew->span = pNew->token = *pToken;
  }else if( pLeft && pRight ){
    sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
  }
  return pNew;
}

/*
** When doing a nested parse, you can include terms in an expression
** that look like this:   #0 #1 #2 ...  These terms refer to elements
** on the stack.  "#0" (or just "#") means the top of the stack.
** "#1" means the next down on the stack.  And so forth.  #-1 means
** memory location 0.  #-2 means memory location 1.  And so forth.
**
** This routine is called by the parser to deal with on of those terms.
** It immediately generates code to store the value in a memory location.
** The returns an expression that will code to extract the value from
** that memory location as needed.
*/
Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
  Vdbe *v = pParse->pVdbe;
  Expr *p;
  int depth;
  if( v==0 ) return 0;
  if( pParse->nested==0 ){
    sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken);
    return 0;
  }

  p = sqlite3Expr(TK_REGISTER, 0, 0, pToken);
  if( p==0 ){
    return 0;  /* Malloc failed */
  }
  depth = atoi(&pToken->z[1]);
  if( depth>=0 ){
    p->iTable = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_Dup, depth, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1);
  }else{
    p->iTable = -1-depth;
  }
  return p;
}

/*
** Join two expressions using an AND operator.  If either expression is
** NULL, then just return the other expression.
*/
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/*
** Set the Expr.span field of the given expression to span all
** text between the two given tokens.
*/
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
  assert( pRight!=0 );
  assert( pLeft!=0 );
  if( !sqlite3ThreadDataReadOnly()->mallocFailed && pRight->z && pLeft->z ){
    assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
    if( pLeft->dyn==0 && pRight->dyn==0 ){
      pExpr->span.z = pLeft->z;
      pExpr->span.n = pRight->n + (pRight->z - pLeft->z);
    }else{
      pExpr->span.z = 0;
    }
  }
}

/*
** Construct a new expression node for a function with multiple
** arguments.
*/
Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){
  Expr *pNew;
  pNew = sqliteMalloc( sizeof(Expr) );
  if( pNew==0 ){
    sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */
    return 0;
  }
  pNew->op = TK_FUNCTION;
  pNew->pList = pList;
  if( pToken ){
    assert( pToken->dyn==0 );
    pNew->token = *pToken;







|



|














|







252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
/*
** Set the Expr.span field of the given expression to span all
** text between the two given tokens.
*/
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
  assert( pRight!=0 );
  assert( pLeft!=0 );
  if( !sqlite3_malloc_failed && pRight->z && pLeft->z ){
    assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
    if( pLeft->dyn==0 && pRight->dyn==0 ){
      pExpr->span.z = pLeft->z;
      pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z);
    }else{
      pExpr->span.z = 0;
    }
  }
}

/*
** Construct a new expression node for a function with multiple
** arguments.
*/
Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){
  Expr *pNew;
  pNew = sqliteMalloc( sizeof(Expr) );
  if( pNew==0 ){
    /* sqlite3ExprListDelete(pList); // Leak pList when malloc fails */
    return 0;
  }
  pNew->op = TK_FUNCTION;
  pNew->pList = pList;
  if( pToken ){
    assert( pToken->dyn==0 );
    pNew->token = *pToken;
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
  if( pToken->n==1 ){
    /* Wildcard of the form "?".  Assign the next variable number */
    pExpr->iTable = ++pParse->nVar;
  }else if( pToken->z[0]=='?' ){
    /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
    ** use it as the variable number */
    int i;
    pExpr->iTable = i = atoi((char*)&pToken->z[1]);
    if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){
      sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
          SQLITE_MAX_VARIABLE_NUMBER);
    }
    if( i>pParse->nVar ){
      pParse->nVar = i;
    }







|







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
  if( pToken->n==1 ){
    /* Wildcard of the form "?".  Assign the next variable number */
    pExpr->iTable = ++pParse->nVar;
  }else if( pToken->z[0]=='?' ){
    /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
    ** use it as the variable number */
    int i;
    pExpr->iTable = i = atoi(&pToken->z[1]);
    if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){
      sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
          SQLITE_MAX_VARIABLE_NUMBER);
    }
    if( i>pParse->nVar ){
      pParse->nVar = i;
    }
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
        break;
      }
    }
    if( i>=pParse->nVarExpr ){
      pExpr->iTable = ++pParse->nVar;
      if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
        pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
        sqliteReallocOrFree((void**)&pParse->apVarExpr,
                       pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
      }
      if( !sqlite3ThreadDataReadOnly()->mallocFailed ){
        assert( pParse->apVarExpr!=0 );
        pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
      }
    }
  } 
}








|


|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
        break;
      }
    }
    if( i>=pParse->nVarExpr ){
      pExpr->iTable = ++pParse->nVar;
      if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
        pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
        pParse->apVarExpr = sqliteRealloc(pParse->apVarExpr,
                       pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
      }
      if( !sqlite3_malloc_failed ){
        assert( pParse->apVarExpr!=0 );
        pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
      }
    }
  } 
}

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
  sqlite3ExprDelete(p->pLeft);
  sqlite3ExprDelete(p->pRight);
  sqlite3ExprListDelete(p->pList);
  sqlite3SelectDelete(p->pSelect);
  sqliteFree(p);
}

/*
** The Expr.token field might be a string literal that is quoted.
** If so, remove the quotation marks.
*/
void sqlite3DequoteExpr(Expr *p){
  if( ExprHasAnyProperty(p, EP_Dequoted) ){
    return;
  }
  ExprSetProperty(p, EP_Dequoted);
  if( p->token.dyn==0 ){
    sqlite3TokenCopy(&p->token, &p->token);
  }
  sqlite3Dequote((char*)p->token.z);
}


/*
** The following group of routines make deep copies of expressions,
** expression lists, ID lists, and select statements.  The copies can
** be deleted (by being passed to their respective ...Delete() routines)
** without effecting the originals.
**
** The expression list, ID, and source lists return by sqlite3ExprListDup(),
** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded 
** by subsequent calls to sqlite*ListAppend() routines.
**
** Any tables that the SrcList might point to are not duplicated.
*/
Expr *sqlite3ExprDup(Expr *p){
  Expr *pNew;
  if( p==0 ) return 0;
  pNew = sqliteMallocRaw( sizeof(*p) );
  if( pNew==0 ) return 0;
  memcpy(pNew, p, sizeof(*pNew));
  if( p->token.z!=0 ){
    pNew->token.z = (u8*)sqliteStrNDup((char*)p->token.z, p->token.n);
    pNew->token.dyn = 1;
  }else{
    assert( pNew->token.z==0 );
  }
  pNew->span.z = 0;
  pNew->pLeft = sqlite3ExprDup(p->pLeft);
  pNew->pRight = sqlite3ExprDup(p->pRight);
  pNew->pList = sqlite3ExprListDup(p->pList);
  pNew->pSelect = sqlite3SelectDup(p->pSelect);
  pNew->pTab = p->pTab;
  return pNew;
}
void sqlite3TokenCopy(Token *pTo, Token *pFrom){
  if( pTo->dyn ) sqliteFree((char*)pTo->z);
  if( pFrom->z ){
    pTo->n = pFrom->n;
    pTo->z = (u8*)sqliteStrNDup((char*)pFrom->z, pFrom->n);
    pTo->dyn = 1;
  }else{
    pTo->z = 0;
  }
}
ExprList *sqlite3ExprListDup(ExprList *p){
  ExprList *pNew;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















|









<






|







369
370
371
372
373
374
375















376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
  sqlite3ExprDelete(p->pLeft);
  sqlite3ExprDelete(p->pRight);
  sqlite3ExprListDelete(p->pList);
  sqlite3SelectDelete(p->pSelect);
  sqliteFree(p);
}

















/*
** The following group of routines make deep copies of expressions,
** expression lists, ID lists, and select statements.  The copies can
** be deleted (by being passed to their respective ...Delete() routines)
** without effecting the originals.
**
** The expression list, ID, and source lists return by sqlite3ExprListDup(),
** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded 
** by subsequent calls to sqlite*ListAppend() routines.
**
** Any tables that the SrcList might point to are not duplicated.
*/
Expr *sqlite3ExprDup(Expr *p){
  Expr *pNew;
  if( p==0 ) return 0;
  pNew = sqliteMallocRaw( sizeof(*p) );
  if( pNew==0 ) return 0;
  memcpy(pNew, p, sizeof(*pNew));
  if( p->token.z!=0 ){
    pNew->token.z = sqliteStrNDup(p->token.z, p->token.n);
    pNew->token.dyn = 1;
  }else{
    assert( pNew->token.z==0 );
  }
  pNew->span.z = 0;
  pNew->pLeft = sqlite3ExprDup(p->pLeft);
  pNew->pRight = sqlite3ExprDup(p->pRight);
  pNew->pList = sqlite3ExprListDup(p->pList);
  pNew->pSelect = sqlite3SelectDup(p->pSelect);

  return pNew;
}
void sqlite3TokenCopy(Token *pTo, Token *pFrom){
  if( pTo->dyn ) sqliteFree((char*)pTo->z);
  if( pFrom->z ){
    pTo->n = pFrom->n;
    pTo->z = sqliteStrNDup(pFrom->z, pFrom->n);
    pTo->dyn = 1;
  }else{
    pTo->z = 0;
  }
}
ExprList *sqlite3ExprListDup(ExprList *p){
  ExprList *pNew;
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
    if( pOldExpr->span.z!=0 && pNewExpr ){
      /* Always make a copy of the span for top-level expressions in the
      ** expression list.  The logic in SELECT processing that determines
      ** the names of columns in the result set needs this information */
      sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span);
    }
    assert( pNewExpr==0 || pNewExpr->span.z!=0 
            || pOldExpr->span.z==0
            || sqlite3ThreadDataReadOnly()->mallocFailed );
    pItem->zName = sqliteStrDup(pOldItem->zName);
    pItem->sortOrder = pOldItem->sortOrder;
    pItem->isAgg = pOldItem->isAgg;
    pItem->done = 0;
  }
  return pNew;
}







|
<







435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
    if( pOldExpr->span.z!=0 && pNewExpr ){
      /* Always make a copy of the span for top-level expressions in the
      ** expression list.  The logic in SELECT processing that determines
      ** the names of columns in the result set needs this information */
      sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span);
    }
    assert( pNewExpr==0 || pNewExpr->span.z!=0 
            || pOldExpr->span.z==0 || sqlite3_malloc_failed );

    pItem->zName = sqliteStrDup(pOldItem->zName);
    pItem->sortOrder = pOldItem->sortOrder;
    pItem->isAgg = pOldItem->isAgg;
    pItem->done = 0;
  }
  return pNew;
}
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
  nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
  pNew = sqliteMallocRaw( nByte );
  if( pNew==0 ) return 0;
  pNew->nSrc = pNew->nAlloc = p->nSrc;
  for(i=0; i<p->nSrc; i++){
    struct SrcList_item *pNewItem = &pNew->a[i];
    struct SrcList_item *pOldItem = &p->a[i];
    Table *pTab;
    pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
    pNewItem->zName = sqliteStrDup(pOldItem->zName);
    pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
    pNewItem->jointype = pOldItem->jointype;
    pNewItem->iCursor = pOldItem->iCursor;
    pTab = pNewItem->pTab = pOldItem->pTab;
    if( pTab ){
      pTab->nRef++;
    }
    pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect);
    pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn);
    pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing);
    pNewItem->colUsed = pOldItem->colUsed;
  }
  return pNew;
}
IdList *sqlite3IdListDup(IdList *p){
  IdList *pNew;
  int i;
  if( p==0 ) return 0;
  pNew = sqliteMallocRaw( sizeof(*pNew) );
  if( pNew==0 ) return 0;
  pNew->nId = pNew->nAlloc = p->nId;
  pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) );
  if( pNew->a==0 ){
    sqliteFree(pNew);
    return 0;
  }
  for(i=0; i<p->nId; i++){
    struct IdList_item *pNewItem = &pNew->a[i];
    struct IdList_item *pOldItem = &p->a[i];
    pNewItem->zName = sqliteStrDup(pOldItem->zName);
    pNewItem->idx = pOldItem->idx;
  }
  return pNew;







<





|
|
|
















|
<
<
<







464
465
466
467
468
469
470

471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495



496
497
498
499
500
501
502
  nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
  pNew = sqliteMallocRaw( nByte );
  if( pNew==0 ) return 0;
  pNew->nSrc = pNew->nAlloc = p->nSrc;
  for(i=0; i<p->nSrc; i++){
    struct SrcList_item *pNewItem = &pNew->a[i];
    struct SrcList_item *pOldItem = &p->a[i];

    pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
    pNewItem->zName = sqliteStrDup(pOldItem->zName);
    pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
    pNewItem->jointype = pOldItem->jointype;
    pNewItem->iCursor = pOldItem->iCursor;
    pNewItem->pTab = pOldItem->pTab;
    if( pNewItem->pTab ){
      pNewItem->pTab->isTransient = 0;
    }
    pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect);
    pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn);
    pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing);
    pNewItem->colUsed = pOldItem->colUsed;
  }
  return pNew;
}
IdList *sqlite3IdListDup(IdList *p){
  IdList *pNew;
  int i;
  if( p==0 ) return 0;
  pNew = sqliteMallocRaw( sizeof(*pNew) );
  if( pNew==0 ) return 0;
  pNew->nId = pNew->nAlloc = p->nId;
  pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) );
  if( pNew->a==0 ) return 0;



  for(i=0; i<p->nId; i++){
    struct IdList_item *pNewItem = &pNew->a[i];
    struct IdList_item *pOldItem = &p->a[i];
    pNewItem->zName = sqliteStrDup(pOldItem->zName);
    pNewItem->idx = pOldItem->idx;
  }
  return pNew;
543
544
545
546
547
548
549


550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575

576
577
578
579
580
581
582
583
584

585

586
587
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
  pNew->pOrderBy = sqlite3ExprListDup(p->pOrderBy);
  pNew->op = p->op;
  pNew->pPrior = sqlite3SelectDup(p->pPrior);
  pNew->pLimit = sqlite3ExprDup(p->pLimit);
  pNew->pOffset = sqlite3ExprDup(p->pOffset);
  pNew->iLimit = -1;
  pNew->iOffset = -1;


  pNew->isResolved = p->isResolved;
  pNew->isAgg = p->isAgg;
  pNew->usesVirt = 0;
  pNew->disallowOrderBy = 0;
  pNew->pRightmost = 0;
  pNew->addrOpenVirt[0] = -1;
  pNew->addrOpenVirt[1] = -1;
  pNew->addrOpenVirt[2] = -1;
  return pNew;
}
#else
Select *sqlite3SelectDup(Select *p){
  assert( p==0 );
  return 0;
}
#endif


/*
** Add a new element to the end of an expression list.  If pList is
** initially NULL, then create a new expression list.
*/
ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
  if( pList==0 ){
    pList = sqliteMalloc( sizeof(ExprList) );
    if( pList==0 ){

      goto no_mem;
    }
    assert( pList->nAlloc==0 );
  }
  if( pList->nAlloc<=pList->nExpr ){
    struct ExprList_item *a;
    int n = pList->nAlloc*2 + 4;
    a = sqliteRealloc(pList->a, n*sizeof(pList->a[0]));
    if( a==0 ){

      goto no_mem;

    }
    pList->a = a;
    pList->nAlloc = n;
  }
  assert( pList->a!=0 );
  if( pExpr || pName ){
    struct ExprList_item *pItem = &pList->a[pList->nExpr++];
    memset(pItem, 0, sizeof(*pItem));
    pItem->zName = sqlite3NameFromToken(pName);
    pItem->pExpr = pExpr;

  }
  return pList;

no_mem:     
  /* Avoid leaking memory if malloc has failed. */
  sqlite3ExprDelete(pExpr);
  sqlite3ExprListDelete(pList);
  return 0;
}

/*
** Delete an entire expression list.
*/
void sqlite3ExprListDelete(ExprList *pList){
  int i;







>
>


<
<
<
<
<
<


















>
|




<
|
|
|
>
|
>

<
<





<

>


<
<
<
<
<
<







515
516
517
518
519
520
521
522
523
524
525






526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549

550
551
552
553
554
555
556


557
558
559
560
561

562
563
564
565






566
567
568
569
570
571
572
  pNew->pOrderBy = sqlite3ExprListDup(p->pOrderBy);
  pNew->op = p->op;
  pNew->pPrior = sqlite3SelectDup(p->pPrior);
  pNew->pLimit = sqlite3ExprDup(p->pLimit);
  pNew->pOffset = sqlite3ExprDup(p->pOffset);
  pNew->iLimit = -1;
  pNew->iOffset = -1;
  pNew->ppOpenTemp = 0;
  pNew->pFetch = 0;
  pNew->isResolved = p->isResolved;
  pNew->isAgg = p->isAgg;






  return pNew;
}
#else
Select *sqlite3SelectDup(Select *p){
  assert( p==0 );
  return 0;
}
#endif


/*
** Add a new element to the end of an expression list.  If pList is
** initially NULL, then create a new expression list.
*/
ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
  if( pList==0 ){
    pList = sqliteMalloc( sizeof(ExprList) );
    if( pList==0 ){
      /* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */
      return 0;
    }
    assert( pList->nAlloc==0 );
  }
  if( pList->nAlloc<=pList->nExpr ){

    pList->nAlloc = pList->nAlloc*2 + 4;
    pList->a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]));
    if( pList->a==0 ){
      /* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */
      pList->nExpr = pList->nAlloc = 0;
      return pList;
    }


  }
  assert( pList->a!=0 );
  if( pExpr || pName ){
    struct ExprList_item *pItem = &pList->a[pList->nExpr++];
    memset(pItem, 0, sizeof(*pItem));

    pItem->pExpr = pExpr;
    pItem->zName = sqlite3NameFromToken(pName);
  }
  return pList;






}

/*
** Delete an entire expression list.
*/
void sqlite3ExprListDelete(ExprList *pList){
  int i;
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
** The return value from xFunc determines whether the tree walk continues.
** 0 means continue walking the tree.  1 means do not walk children
** of the current node but continue with siblings.  2 means abandon
** the tree walk completely.
**
** The return value from this routine is 1 to abandon the tree walk
** and 0 to continue.
**
** NOTICE:  This routine does *not* descend into subqueries.
*/
static int walkExprList(ExprList *, int (*)(void *, Expr*), void *);
static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){
  int rc;
  if( pExpr==0 ) return 0;
  rc = (*xFunc)(pArg, pExpr);
  if( rc==0 ){







<
<







588
589
590
591
592
593
594


595
596
597
598
599
600
601
** The return value from xFunc determines whether the tree walk continues.
** 0 means continue walking the tree.  1 means do not walk children
** of the current node but continue with siblings.  2 means abandon
** the tree walk completely.
**
** The return value from this routine is 1 to abandon the tree walk
** and 0 to continue.


*/
static int walkExprList(ExprList *, int (*)(void *, Expr*), void *);
static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){
  int rc;
  if( pExpr==0 ) return 0;
  rc = (*xFunc)(pArg, pExpr);
  if( rc==0 ){
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
**
** After walking the whole tree, if no nodes are found that disqualify
** the expression as constant, then we assume the whole expression
** is constant.  See sqlite3ExprIsConstant() for additional information.
*/
static int exprNodeIsConstant(void *pArg, Expr *pExpr){
  switch( pExpr->op ){
    /* Consider functions to be constant if all their arguments are constant
    ** and *pArg==2 */
    case TK_FUNCTION:
      if( *((int*)pArg)==2 ) return 0;
      /* Fall through */
    case TK_ID:
    case TK_COLUMN:
    case TK_DOT:
    case TK_AGG_FUNCTION:
    case TK_AGG_COLUMN:
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_SELECT:
    case TK_EXISTS:
#endif
      *((int*)pArg) = 0;
      return 2;
    case TK_IN:
      if( pExpr->pSelect ){
        *((int*)pArg) = 0;
        return 2;
      }
    default:
      return 0;
  }
}

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables or function calls.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
int sqlite3ExprIsConstant(Expr *p){
  int isConst = 1;
  walkExprTree(p, exprNodeIsConstant, &isConst);
  return isConst;
}

/*
** Walk an expression tree.  Return 1 if the expression is constant
** or a function call with constant arguments.  Return and 0 if there
** are any variables.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
int sqlite3ExprIsConstantOrFunction(Expr *p){
  int isConst = 2;
  walkExprTree(p, exprNodeIsConstant, &isConst);
  return isConst!=0;
}

/*
** If the expression p codes a constant integer that is small enough
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue.  If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
*/
int sqlite3ExprIsInteger(Expr *p, int *pValue){
  switch( p->op ){
    case TK_INTEGER: {
      if( sqlite3GetInt32((char*)p->token.z, pValue) ){
        return 1;
      }
      break;
    }
    case TK_UPLUS: {
      return sqlite3ExprIsInteger(p->pLeft, pValue);
    }







<
<
<
<
<




|






<
<
<
<
<







|











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









|







645
646
647
648
649
650
651





652
653
654
655
656
657
658
659
660
661
662





663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681















682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
**
** After walking the whole tree, if no nodes are found that disqualify
** the expression as constant, then we assume the whole expression
** is constant.  See sqlite3ExprIsConstant() for additional information.
*/
static int exprNodeIsConstant(void *pArg, Expr *pExpr){
  switch( pExpr->op ){





    case TK_ID:
    case TK_COLUMN:
    case TK_DOT:
    case TK_AGG_FUNCTION:
    case TK_FUNCTION:
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_SELECT:
    case TK_EXISTS:
#endif
      *((int*)pArg) = 0;
      return 2;





    default:
      return 0;
  }
}

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
int sqlite3ExprIsConstant(Expr *p){
  int isConst = 1;
  walkExprTree(p, exprNodeIsConstant, &isConst);
  return isConst;
}
















/*
** If the expression p codes a constant integer that is small enough
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue.  If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
*/
int sqlite3ExprIsInteger(Expr *p, int *pValue){
  switch( p->op ){
    case TK_INTEGER: {
      if( sqlite3GetInt32(p->token.z, pValue) ){
        return 1;
      }
      break;
    }
    case TK_UPLUS: {
      return sqlite3ExprIsInteger(p->pLeft, pValue);
    }
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
** means that the form of the name is Z and that columns from any table
** can be used.
**
** If the name cannot be resolved unambiguously, leave an error message
** in pParse and return non-zero.  Return zero on success.
*/
static int lookupName(
  Parse *pParse,       /* The parsing context */
  Token *pDbToken,     /* Name of the database containing table, or NULL */
  Token *pTableToken,  /* Name of table containing column, or NULL */
  Token *pColumnToken, /* Name of the column. */
  NameContext *pNC,    /* The name context used to resolve the name */
  Expr *pExpr          /* Make this EXPR node point to the selected column */
){
  char *zDb = 0;       /* Name of the database.  The "X" in X.Y.Z */







|







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
** means that the form of the name is Z and that columns from any table
** can be used.
**
** If the name cannot be resolved unambiguously, leave an error message
** in pParse and return non-zero.  Return zero on success.
*/
static int lookupName(
  Parse *pParse,      /* The parsing context */
  Token *pDbToken,     /* Name of the database containing table, or NULL */
  Token *pTableToken,  /* Name of table containing column, or NULL */
  Token *pColumnToken, /* Name of the column. */
  NameContext *pNC,    /* The name context used to resolve the name */
  Expr *pExpr          /* Make this EXPR node point to the selected column */
){
  char *zDb = 0;       /* Name of the database.  The "X" in X.Y.Z */
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842

843


844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
  struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
  NameContext *pTopNC = pNC;        /* First namecontext in the list */

  assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
  zDb = sqlite3NameFromToken(pDbToken);
  zTab = sqlite3NameFromToken(pTableToken);
  zCol = sqlite3NameFromToken(pColumnToken);
  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    goto lookupname_end;
  }

  pExpr->iTable = -1;
  while( pNC && cnt==0 ){
    ExprList *pEList;
    SrcList *pSrcList = pNC->pSrcList;




    if( pSrcList ){
      for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
        Table *pTab = pItem->pTab;
        int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
        Column *pCol;
  
        if( pTab==0 ) continue;
        assert( pTab->nCol>0 );
        if( zTab ){
          if( pItem->zAlias ){
            char *zTabName = pItem->zAlias;
            if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
          }else{
            char *zTabName = pTab->zName;
            if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
            if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
              continue;
            }
          }
        }
        if( 0==(cntTab++) ){
          pExpr->iTable = pItem->iCursor;
          pExpr->pSchema = pTab->pSchema;
          pMatch = pItem;
        }
        for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            const char *zColl = pTab->aCol[j].zColl;
            IdList *pUsing;
            cnt++;
            pExpr->iTable = pItem->iCursor;
            pMatch = pItem;
            pExpr->pSchema = pTab->pSchema;
            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
            pExpr->iColumn = j==pTab->iPKey ? -1 : j;
            pExpr->affinity = pTab->aCol[j].affinity;
            pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
            if( pItem->jointype & JT_NATURAL ){
              /* If this match occurred in the left table of a natural join,
              ** then skip the right table to avoid a duplicate match */
              pItem++;
              i++;
            }
            if( (pUsing = pItem->pUsing)!=0 ){
              /* If this match occurs on a column that is in the USING clause
              ** of a join, skip the search of the right table of the join
              ** to avoid a duplicate match there. */
              int k;
              for(k=0; k<pUsing->nId; k++){
                if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
                  pItem++;
                  i++;
                  break;
                }
              }
            }
            break;
          }
        }
      }
    }

#ifndef SQLITE_OMIT_TRIGGER







|
|




<

>

>
>



<











|






|




<
<



|



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







763
764
765
766
767
768
769
770
771
772
773
774
775

776
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806


807
808
809
810
811
812
813
814



















815
816
817
818
819
820
821
  struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
  NameContext *pTopNC = pNC;        /* First namecontext in the list */

  assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
  zDb = sqlite3NameFromToken(pDbToken);
  zTab = sqlite3NameFromToken(pTableToken);
  zCol = sqlite3NameFromToken(pColumnToken);
  if( sqlite3_malloc_failed ){
    return 1;  /* Leak memory (zDb and zTab) if malloc fails */
  }

  pExpr->iTable = -1;
  while( pNC && cnt==0 ){

    SrcList *pSrcList = pNC->pSrcList;
    ExprList *pEList = pNC->pEList;

    pNC->nRef++;
    /* assert( zTab==0 || pEList==0 ); */
    if( pSrcList ){
      for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
        Table *pTab = pItem->pTab;

        Column *pCol;
  
        if( pTab==0 ) continue;
        assert( pTab->nCol>0 );
        if( zTab ){
          if( pItem->zAlias ){
            char *zTabName = pItem->zAlias;
            if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
          }else{
            char *zTabName = pTab->zName;
            if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
            if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){
              continue;
            }
          }
        }
        if( 0==(cntTab++) ){
          pExpr->iTable = pItem->iCursor;
          pExpr->iDb = pTab->iDb;
          pMatch = pItem;
        }
        for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){


            cnt++;
            pExpr->iTable = pItem->iCursor;
            pMatch = pItem;
            pExpr->iDb = pTab->iDb;
            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
            pExpr->iColumn = j==pTab->iPKey ? -1 : j;
            pExpr->affinity = pTab->aCol[j].affinity;
            pExpr->pColl = pTab->aCol[j].pColl;



















            break;
          }
        }
      }
    }

#ifndef SQLITE_OMIT_TRIGGER
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
        pTab = pTriggerStack->pTab;
      }

      if( pTab ){ 
        int j;
        Column *pCol = pTab->aCol;

        pExpr->pSchema = pTab->pSchema;
        cntTab++;
        for(j=0; j < pTab->nCol; j++, pCol++) {
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
            const char *zColl = pTab->aCol[j].zColl;
            cnt++;
            pExpr->iColumn = j==pTab->iPKey ? -1 : j;
            pExpr->affinity = pTab->aCol[j].affinity;
            pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
            pExpr->pTab = pTab;
            break;
          }
        }
      }
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) */








|



<



|
<







835
836
837
838
839
840
841
842
843
844
845

846
847
848
849

850
851
852
853
854
855
856
        pTab = pTriggerStack->pTab;
      }

      if( pTab ){ 
        int j;
        Column *pCol = pTab->aCol;

        pExpr->iDb = pTab->iDb;
        cntTab++;
        for(j=0; j < pTab->nCol; j++, pCol++) {
          if( sqlite3StrICmp(pCol->zName, zCol)==0 ){

            cnt++;
            pExpr->iColumn = j==pTab->iPKey ? -1 : j;
            pExpr->affinity = pTab->aCol[j].affinity;
            pExpr->pColl = pTab->aCol[j].pColl;

            break;
          }
        }
      }
    }
#endif /* !defined(SQLITE_OMIT_TRIGGER) */

958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
    **     SELECT a+b AS x FROM table WHERE x<10;
    **
    ** In cases like this, replace pExpr with a copy of the expression that
    ** forms the result set entry ("a+b" in the example) and return immediately.
    ** Note that the expression in the result set should have already been
    ** resolved by the time the WHERE clause is resolved.
    */
    if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){
      for(j=0; j<pEList->nExpr; j++){
        char *zAs = pEList->a[j].zName;
        if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
          assert( pExpr->pLeft==0 && pExpr->pRight==0 );
          pExpr->op = TK_AS;
          pExpr->iColumn = j;
          pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr);
          cnt = 1;
          assert( zTab==0 && zDb==0 );
          goto lookupname_end_2;
        }
      } 
    }

    /* Advance to the next name context.  The loop will exit when either
    ** we have a match (cnt>0) or when we run out of name contexts.
    */
    if( cnt==0 ){
      pNC = pNC->pNext;
    }
  }

  /*
  ** If X and Y are NULL (in other words if only the column name Z is
  ** supplied) and the value of Z is enclosed in double-quotes, then
  ** Z is a string literal if it doesn't match any column names.  In that
  ** case, we need to return right away and not make any changes to
  ** pExpr.
  **
  ** Because no reference was made to outer contexts, the pNC->nRef
  ** fields are not changed in any context.
  */
  if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
    sqliteFree(zCol);
    return 0;
  }

  /*
  ** cnt==0 means there was not match.  cnt>1 means there were two or
  ** more matches.  Either way, we have an error.
  */
  if( cnt!=1 ){
    char *z = 0;
    char *zErr;
    zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s";
    if( zDb ){
      sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, (char*)0);
    }else if( zTab ){
      sqlite3SetString(&z, zTab, ".", zCol, (char*)0);
    }else{
      z = sqliteStrDup(zCol);
    }
    sqlite3ErrorMsg(pParse, zErr, z);
    sqliteFree(z);
    pTopNC->nErr++;
  }







|







|

|


















<
<
<















|

|







871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906



907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
    **     SELECT a+b AS x FROM table WHERE x<10;
    **
    ** In cases like this, replace pExpr with a copy of the expression that
    ** forms the result set entry ("a+b" in the example) and return immediately.
    ** Note that the expression in the result set should have already been
    ** resolved by the time the WHERE clause is resolved.
    */
    if( cnt==0 && pEList!=0 && zTab==0 ){
      for(j=0; j<pEList->nExpr; j++){
        char *zAs = pEList->a[j].zName;
        if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
          assert( pExpr->pLeft==0 && pExpr->pRight==0 );
          pExpr->op = TK_AS;
          pExpr->iColumn = j;
          pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr);
          sqliteFree(zCol);
          assert( zTab==0 && zDb==0 );
          return 0;
        }
      } 
    }

    /* Advance to the next name context.  The loop will exit when either
    ** we have a match (cnt>0) or when we run out of name contexts.
    */
    if( cnt==0 ){
      pNC = pNC->pNext;
    }
  }

  /*
  ** If X and Y are NULL (in other words if only the column name Z is
  ** supplied) and the value of Z is enclosed in double-quotes, then
  ** Z is a string literal if it doesn't match any column names.  In that
  ** case, we need to return right away and not make any changes to
  ** pExpr.



  */
  if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
    sqliteFree(zCol);
    return 0;
  }

  /*
  ** cnt==0 means there was not match.  cnt>1 means there were two or
  ** more matches.  Either way, we have an error.
  */
  if( cnt!=1 ){
    char *z = 0;
    char *zErr;
    zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s";
    if( zDb ){
      sqlite3SetString(&z, zDb, ".", zTab, ".", zCol, 0);
    }else if( zTab ){
      sqlite3SetString(&z, zTab, ".", zCol, 0);
    }else{
      z = sqliteStrDup(zCol);
    }
    sqlite3ErrorMsg(pParse, zErr, z);
    sqliteFree(z);
    pTopNC->nErr++;
  }
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042

1043
1044
1045
1046
1047
1048
1049
1050
1051
1052



1053









1054




1055

1056
1057
1058

1059
1060


1061



1062

1063



1064

1065


1066

1067
1068
1069
1070
1071
1072
1073
    if( n>=sizeof(Bitmask)*8 ){
      n = sizeof(Bitmask)*8-1;
    }
    assert( pMatch->iCursor==pExpr->iTable );
    pMatch->colUsed |= 1<<n;
  }

lookupname_end:
  /* Clean up and return
  */
  sqliteFree(zDb);
  sqliteFree(zTab);

  sqlite3ExprDelete(pExpr->pLeft);
  pExpr->pLeft = 0;
  sqlite3ExprDelete(pExpr->pRight);
  pExpr->pRight = 0;
  pExpr->op = TK_COLUMN;
lookupname_end_2:
  sqliteFree(zCol);
  if( cnt==1 ){
    assert( pNC!=0 );
    sqlite3AuthRead(pParse, pExpr, pNC->pSrcList);



    if( pMatch && !pMatch->pSelect ){









      pExpr->pTab = pMatch->pTab;




    }

    /* Increment the nRef value on all name contexts from TopNC up to
    ** the point where the name matched. */
    for(;;){

      assert( pTopNC!=0 );
      pTopNC->nRef++;


      if( pTopNC==pNC ) break;



      pTopNC = pTopNC->pNext;

    }



    return 0;

  } else {


    return 1;

  }
}

/*
** This routine is designed as an xFunc for walkExprTree().
**
** Resolve symbolic names into TK_COLUMN operators for the current







<




>





<
<



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

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

>
>
>
|
>
|
>
>
|
>







941
942
943
944
945
946
947

948
949
950
951
952
953
954
955
956
957


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

986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
    if( n>=sizeof(Bitmask)*8 ){
      n = sizeof(Bitmask)*8-1;
    }
    assert( pMatch->iCursor==pExpr->iTable );
    pMatch->colUsed |= 1<<n;
  }


  /* Clean up and return
  */
  sqliteFree(zDb);
  sqliteFree(zTab);
  sqliteFree(zCol);
  sqlite3ExprDelete(pExpr->pLeft);
  pExpr->pLeft = 0;
  sqlite3ExprDelete(pExpr->pRight);
  pExpr->pRight = 0;
  pExpr->op = TK_COLUMN;


  if( cnt==1 ){
    assert( pNC!=0 );
    sqlite3AuthRead(pParse, pExpr, pNC->pSrcList);
  }
  return cnt!=1;
}

/*
** pExpr is a node that defines a function of some kind.  It might
** be a syntactic function like "count(x)" or it might be a function
** that implements an operator, like "a LIKE b".  
**
** This routine makes *pzName point to the name of the function and 
** *pnName hold the number of characters in the function name.
*/
static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){
  switch( pExpr->op ){
    case TK_FUNCTION: {
      *pzName = pExpr->token.z;
      *pnName = pExpr->token.n;
      break;
    }
    case TK_LIKE: {
      *pzName = "like";
      *pnName = 4;
      break;
    }
    case TK_GLOB: {

      *pzName = "glob";
      *pnName = 4;
      break;
    }
    case TK_CTIME: {
      *pzName = "current_time";
      *pnName = 12;
      break;
    }
    case TK_CDATE: {
      *pzName = "current_date";
      *pnName = 12;
      break;
    }
    case TK_CTIMESTAMP: {
      *pzName = "current_timestamp";
      *pnName = 17;
      break;
    }
  }
}

/*
** This routine is designed as an xFunc for walkExprTree().
**
** Resolve symbolic names into TK_COLUMN operators for the current
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
  assert( pNC!=0 );
  pSrcList = pNC->pSrcList;
  pParse = pNC->pParse;

  if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1;
  ExprSetProperty(pExpr, EP_Resolved);
#ifndef NDEBUG
  if( pSrcList && pSrcList->nAlloc>0 ){
    int i;
    for(i=0; i<pSrcList->nSrc; i++){
      assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
    }
  }
#endif
  switch( pExpr->op ){







|







1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
  assert( pNC!=0 );
  pSrcList = pNC->pSrcList;
  pParse = pNC->pParse;

  if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1;
  ExprSetProperty(pExpr, EP_Resolved);
#ifndef NDEBUG
  if( pSrcList ){
    int i;
    for(i=0; i<pSrcList->nSrc; i++){
      assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
    }
  }
#endif
  switch( pExpr->op ){
1137
1138
1139
1140
1141
1142
1143
1144




1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
      }
      lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr);
      return 1;
    }

    /* Resolve function names
    */
    case TK_CONST_FUNC:




    case TK_FUNCTION: {
      ExprList *pList = pExpr->pList;    /* The argument list */
      int n = pList ? pList->nExpr : 0;  /* Number of arguments */
      int no_such_func = 0;       /* True if no such function exists */
      int wrong_num_args = 0;     /* True if wrong number of arguments */
      int is_agg = 0;             /* True if is an aggregate function */
      int i;
      int nId;                    /* Number of characters in function name */
      const char *zId;            /* The function name. */
      FuncDef *pDef;              /* Information about the function */
      int enc = ENC(pParse->db);  /* The database encoding */

      zId = (char*)pExpr->token.z;
      nId = pExpr->token.n;
      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
      if( pDef==0 ){
        pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
        if( pDef==0 ){
          no_such_func = 1;
        }else{
          wrong_num_args = 1;







|
>
>
>
>










|

<
|







1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098

1099
1100
1101
1102
1103
1104
1105
1106
      }
      lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr);
      return 1;
    }

    /* Resolve function names
    */
    case TK_CTIME:
    case TK_CTIMESTAMP:
    case TK_CDATE:
    case TK_GLOB:
    case TK_LIKE:
    case TK_FUNCTION: {
      ExprList *pList = pExpr->pList;    /* The argument list */
      int n = pList ? pList->nExpr : 0;  /* Number of arguments */
      int no_such_func = 0;       /* True if no such function exists */
      int wrong_num_args = 0;     /* True if wrong number of arguments */
      int is_agg = 0;             /* True if is an aggregate function */
      int i;
      int nId;                    /* Number of characters in function name */
      const char *zId;            /* The function name. */
      FuncDef *pDef;              /* Information about the function */
      int enc = pParse->db->enc;  /* The database encoding */


      getFunctionName(pExpr, &zId, &nId);
      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
      if( pDef==0 ){
        pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
        if( pDef==0 ){
          no_such_func = 1;
        }else{
          wrong_num_args = 1;
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_SELECT:
    case TK_EXISTS:
#endif
    case TK_IN: {
      if( pExpr->pSelect ){
        int nRef = pNC->nRef;
#ifndef SQLITE_OMIT_CHECK
        if( pNC->isCheck ){
          sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
        }
#endif
        sqlite3SelectResolve(pParse, pExpr->pSelect, pNC);
        assert( pNC->nRef>=nRef );
        if( nRef!=pNC->nRef ){
          ExprSetProperty(pExpr, EP_VarSelect);
        }
      }
      break;
    }
#ifndef SQLITE_OMIT_CHECK
    case TK_VARIABLE: {
      if( pNC->isCheck ){
        sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
      }
      break;
    }
#endif
  }
  return 0;
}

/*
** This routine walks an expression tree and resolves references to
** table columns.  Nodes of the form ID.ID or ID resolve into an







<
<
<
<
<






<

<
<
<
<
<
<
<
<







1137
1138
1139
1140
1141
1142
1143





1144
1145
1146
1147
1148
1149

1150








1151
1152
1153
1154
1155
1156
1157
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_SELECT:
    case TK_EXISTS:
#endif
    case TK_IN: {
      if( pExpr->pSelect ){
        int nRef = pNC->nRef;





        sqlite3SelectResolve(pParse, pExpr->pSelect, pNC);
        assert( pNC->nRef>=nRef );
        if( nRef!=pNC->nRef ){
          ExprSetProperty(pExpr, EP_VarSelect);
        }
      }

    }








  }
  return 0;
}

/*
** This routine walks an expression tree and resolves references to
** table columns.  Nodes of the form ID.ID or ID resolve into an
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281

1282
1283
1284
1285
1286
1287
1288
1289

1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310

1311



1312

1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
** If the expression contains aggregate functions then set the EP_Agg
** property on the expression.
*/
int sqlite3ExprResolveNames(
  NameContext *pNC,       /* Namespace to resolve expressions in. */
  Expr *pExpr             /* The expression to be analyzed. */
){
  int savedHasAgg;
  if( pExpr==0 ) return 0;
  savedHasAgg = pNC->hasAgg;
  pNC->hasAgg = 0;
  walkExprTree(pExpr, nameResolverStep, pNC);
  if( pNC->nErr>0 ){
    ExprSetProperty(pExpr, EP_Error);
  }
  if( pNC->hasAgg ){
    ExprSetProperty(pExpr, EP_Agg);
  }else if( savedHasAgg ){
    pNC->hasAgg = 1;
  }
  return ExprHasProperty(pExpr, EP_Error);
}

/*
** A pointer instance of this structure is used to pass information
** through walkExprTree into codeSubqueryStep().
*/
typedef struct QueryCoder QueryCoder;
struct QueryCoder {
  Parse *pParse;       /* The parsing context */
  NameContext *pNC;    /* Namespace of first enclosing query */
};


/*
** Generate code for scalar subqueries used as an expression

** and IN operators.  Examples:
**
**     (SELECT a FROM b)          -- subquery
**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
**     x IN (4,5,11)              -- IN operator with list on right-hand side
**     x IN (SELECT a FROM b)     -- IN operator with subquery on the right
**
** The pExpr parameter describes the expression that contains the IN

** operator or subquery.
*/
#ifndef SQLITE_OMIT_SUBQUERY
void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
  int testAddr = 0;                       /* One-time test address */
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;

  /* This code must be run in its entirety every time it is encountered
  ** if any of the following is true:
  **
  **    *  The right-hand side is a correlated subquery
  **    *  The right-hand side is an expression list containing variables
  **    *  We are inside a trigger
  **
  ** If all of the above are false, then we can run this code just once
  ** save the results, and reuse the same result on subsequent invocations.
  */
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
    int mem = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);

    testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0);



    assert( testAddr>0 || sqlite3ThreadDataReadOnly()->mallocFailed );

    sqlite3VdbeAddOp(v, OP_MemInt, 1, mem);
  }

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;
      KeyInfo keyInfo;
      int addr;        /* Address of OP_OpenVirtual instruction */

      affinity = sqlite3ExprAffinity(pExpr->pLeft);

      /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
      ** expression it is handled the same way. A virtual table is 
      ** filled with single-field index keys representing the results
      ** from the SELECT or the <exprlist>.
      **
      ** If the 'x' expression is a column value, or the SELECT...
      ** statement returns a column value, then the affinity of that
      ** column is used to build the index keys. If both 'x' and the
      ** SELECT... statement are columns, then numeric affinity is used
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, pExpr->iTable, 0);
      memset(&keyInfo, 0, sizeof(keyInfo));
      keyInfo.nField = 1;
      sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1);

      if( pExpr->pSelect ){
        /* Case 1:     expr IN (SELECT ...)
        **







<

<
<




<
<
<
<
<















|
>
|

|
|
<
|

|
>
|



|



|
|
|
<
<
<
<
<
<




>
|
>
>
>
|
>
|






|




|












|







1173
1174
1175
1176
1177
1178
1179

1180


1181
1182
1183
1184





1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205

1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220






1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
** If the expression contains aggregate functions then set the EP_Agg
** property on the expression.
*/
int sqlite3ExprResolveNames(
  NameContext *pNC,       /* Namespace to resolve expressions in. */
  Expr *pExpr             /* The expression to be analyzed. */
){

  if( pExpr==0 ) return 0;


  walkExprTree(pExpr, nameResolverStep, pNC);
  if( pNC->nErr>0 ){
    ExprSetProperty(pExpr, EP_Error);
  }





  return ExprHasProperty(pExpr, EP_Error);
}

/*
** A pointer instance of this structure is used to pass information
** through walkExprTree into codeSubqueryStep().
*/
typedef struct QueryCoder QueryCoder;
struct QueryCoder {
  Parse *pParse;       /* The parsing context */
  NameContext *pNC;    /* Namespace of first enclosing query */
};


/*
** Generate code for subqueries and IN operators.
**
** IN operators comes in two forms:
**
**           expr IN (exprlist)
** and

**           expr IN (SELECT ...)
**
** The first form is handled by creating a set holding the list
** of allowed values.  The second form causes the SELECT to generate 
** a temporary table.
*/
#ifndef SQLITE_OMIT_SUBQUERY
void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
  int label = 0;                         /* Address after sub-select code */
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;

  /* If this is not a variable (correlated) select, then execute
  ** it only once. Unless this is part of a trigger program. In
  ** that case re-execute every time (this could be optimized).






  */
  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
    int mem = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
    label = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_If, 0, label);
    sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, mem, 1);
  }

  if( pExpr->pSelect ){
    sqlite3VdbeAddOp(v, OP_AggContextPush, 0, 0);
  }

  switch( pExpr->op ){
    case TK_IN: {
      char affinity;
      KeyInfo keyInfo;
      int addr;        /* Address of OP_OpenTemp instruction */

      affinity = sqlite3ExprAffinity(pExpr->pLeft);

      /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
      ** expression it is handled the same way. A temporary table is 
      ** filled with single-field index keys representing the results
      ** from the SELECT or the <exprlist>.
      **
      ** If the 'x' expression is a column value, or the SELECT...
      ** statement returns a column value, then the affinity of that
      ** column is used to build the index keys. If both 'x' and the
      ** SELECT... statement are columns, then numeric affinity is used
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite3VdbeAddOp(v, OP_OpenTemp, pExpr->iTable, 0);
      memset(&keyInfo, 0, sizeof(keyInfo));
      keyInfo.nField = 1;
      sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1);

      if( pExpr->pSelect ){
        /* Case 1:     expr IN (SELECT ...)
        **
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385

1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396

1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420

1421
1422

1423
1424
1425
1426
1427
1428
1429
1430
1431



1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500

1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536

1537
1538
1539




1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
        **
	** For each expression, build an index key from the evaluation and
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        int i;
        ExprList *pList = pExpr->pList;
        struct ExprList_item *pItem;

        if( !affinity ){
          affinity = SQLITE_AFF_NUMERIC;
        }
        keyInfo.aColl[0] = pExpr->pLeft->pColl;

        /* Loop through each expression in <exprlist>. */
        for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
          Expr *pE2 = pItem->pExpr;

          /* If the expression is not constant then we will need to
          ** disable the test that was generated above that makes sure
          ** this code only executes once.  Because for a non-constant
          ** expression we need to rerun this code each time.
          */
          if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){
            VdbeOp *aOp = sqlite3VdbeGetOp(v, testAddr-1);

            int i;
            for(i=0; i<3; i++){
              aOp[i].opcode = OP_Noop;
            }
            testAddr = 0;
          }

          /* Evaluate the expression and insert it into the temp table */
          sqlite3ExprCode(pParse, pE2);
          sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
          sqlite3VdbeAddOp(v, OP_IdxInsert, pExpr->iTable, 0);

        }
      }
      sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
      break;
    }

    case TK_EXISTS:
    case TK_SELECT: {
      /* This has to be a scalar SELECT.  Generate code to put the
      ** value of this select in a memory cell and record the number
      ** of the memory cell in iColumn.
      */
      static const Token one = { (u8*)"1", 0, 1 };
      Select *pSel;
      int iMem;
      int sop;

      pExpr->iColumn = iMem = pParse->nMem++;
      pSel = pExpr->pSelect;
      if( pExpr->op==TK_SELECT ){
        sop = SRT_Mem;
        sqlite3VdbeAddOp(v, OP_MemNull, iMem, 0);
        VdbeComment((v, "# Init subquery result"));
      }else{

        sop = SRT_Exists;
        sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem);

        VdbeComment((v, "# Init EXISTS result"));
      }
      sqlite3ExprDelete(pSel->pLimit);
      pSel->pLimit = sqlite3Expr(TK_INTEGER, 0, 0, &one);
      sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0);
      break;
    }
  }




  if( testAddr ){
    sqlite3VdbeJumpHere(v, testAddr);
  }
  return;
}
#endif /* SQLITE_OMIT_SUBQUERY */

/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
*/
static void codeInteger(Vdbe *v, const char *z, int n){
  int i;
  if( sqlite3GetInt32(z, &i) ){
    sqlite3VdbeAddOp(v, OP_Integer, i, 0);
  }else if( sqlite3FitsIn64Bits(z) ){
    sqlite3VdbeOp3(v, OP_Int64, 0, 0, z, n);
  }else{
    sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n);
  }
}

/*
** Generate code into the current Vdbe to evaluate the given
** expression and leave the result on the top of stack.
**
** This code depends on the fact that certain token values (ex: TK_EQ)
** are the same as opcode values (ex: OP_Eq) that implement the corresponding
** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in
** the make process cause these values to align.  Assert()s in the code
** below verify that the numbers are aligned correctly.
*/
void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
  Vdbe *v = pParse->pVdbe;
  int op;
  int stackChng = 1;    /* Amount of change to stack depth */

  if( v==0 ) return;
  if( pExpr==0 ){
    sqlite3VdbeAddOp(v, OP_Null, 0, 0);
    return;
  }
  op = pExpr->op;
  switch( op ){
    case TK_AGG_COLUMN: {
      AggInfo *pAggInfo = pExpr->pAggInfo;
      struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
      if( !pAggInfo->directMode ){
        sqlite3VdbeAddOp(v, OP_MemLoad, pCol->iMem, 0);
        break;
      }else if( pAggInfo->useSortingIdx ){
        sqlite3VdbeAddOp(v, OP_Column, pAggInfo->sortingIdx,
                              pCol->iSorterColumn);
        break;
      }
      /* Otherwise, fall thru into the TK_COLUMN case */
    }
    case TK_COLUMN: {
      if( pExpr->iTable<0 ){
        /* This only happens when coding check constraints */
        assert( pParse->ckOffset>0 );
        sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
      }else if( pExpr->iColumn>=0 ){
        Table *pTab = pExpr->pTab;
        int iCol = pExpr->iColumn;
        sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, iCol);
        sqlite3ColumnDefault(v, pTab, iCol);
#ifndef SQLITE_OMIT_FLOATING_POINT
        if( pTab && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){

          sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0);
        }
#endif
      }else{
        sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0);
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n);
      break;
    }
    case TK_FLOAT:
    case TK_STRING: {
      assert( TK_FLOAT==OP_Real );
      assert( TK_STRING==OP_String8 );
      sqlite3DequoteExpr(pExpr);
      sqlite3VdbeOp3(v, op, 0, 0, (char*)pExpr->token.z, pExpr->token.n);
      break;
    }
    case TK_NULL: {
      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
      break;
    }
#ifndef SQLITE_OMIT_BLOB_LITERAL
    case TK_BLOB: {
      int n;
      const char *z;
      assert( TK_BLOB==OP_HexBlob );
      n = pExpr->token.n - 3;
      z = (char*)pExpr->token.z + 2;
      assert( n>=0 );
      if( n==0 ){
        z = "";
      }
      sqlite3VdbeOp3(v, op, 0, 0, z, n);

      break;
    }
#endif




    case TK_VARIABLE: {
      sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
      if( pExpr->token.n>1 ){
        sqlite3VdbeChangeP3(v, -1, (char*)pExpr->token.z, pExpr->token.n);
      }
      break;
    }
    case TK_REGISTER: {
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0);
      break;
    }
#ifndef SQLITE_OMIT_CAST
    case TK_CAST: {
      /* Expressions of the form:   CAST(pLeft AS token) */
      int aff, op;
      sqlite3ExprCode(pParse, pExpr->pLeft);
      aff = sqlite3AffinityType(&pExpr->token);
      op = aff - SQLITE_AFF_TEXT + OP_ToText;
      assert( op==OP_ToText    || aff!=SQLITE_AFF_TEXT    );
      assert( op==OP_ToBlob    || aff!=SQLITE_AFF_NONE    );
      assert( op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
      assert( op==OP_ToInt     || aff!=SQLITE_AFF_INTEGER );
      assert( op==OP_ToReal    || aff!=SQLITE_AFF_REAL    );
      sqlite3VdbeAddOp(v, op, 0, 0);
      stackChng = 0;
      break;
    }
#endif /* SQLITE_OMIT_CAST */
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {
      assert( TK_LT==OP_Lt );
      assert( TK_LE==OP_Le );
      assert( TK_GT==OP_Gt );
      assert( TK_GE==OP_Ge );
      assert( TK_EQ==OP_Eq );
      assert( TK_NE==OP_Ne );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);
      stackChng = -1;
      break;
    }
    case TK_AND:
    case TK_OR:
    case TK_PLUS:
    case TK_STAR:
    case TK_MINUS:







<
<
<






|
|

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





|
>












|

<
<

|



<
<

>

|
>
|

<
<
|




>
>
>
|
|














|


















<
<


|




<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
|

<
<
|
<
|
<
>
|



|




|






<
|
<
<
<
|




<
<

<
<
<
<
<
<
|
>



>
>
>
>



|







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<















<







1279
1280
1281
1282
1283
1284
1285



1286
1287
1288
1289
1290
1291
1292
1293
1294
1295




1296
1297
1298
1299




1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320


1321
1322
1323
1324
1325


1326
1327
1328
1329
1330
1331
1332


1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375


1376
1377
1378
1379
1380
1381
1382













1383
1384


1385
1386


1387

1388

1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405

1406



1407
1408
1409
1410
1411


1412






1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432

















1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447

1448
1449
1450
1451
1452
1453
1454
        **
	** For each expression, build an index key from the evaluation and
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        int i;



        if( !affinity ){
          affinity = SQLITE_AFF_NUMERIC;
        }
        keyInfo.aColl[0] = pExpr->pLeft->pColl;

        /* Loop through each expression in <exprlist>. */
        for(i=0; i<pExpr->pList->nExpr; i++){
          Expr *pE2 = pExpr->pList->a[i].pExpr;

          /* Check that the expression is constant and valid. */




          if( !sqlite3ExprIsConstant(pE2) ){
            sqlite3ErrorMsg(pParse,
              "right-hand side of IN operator must be constant");
            return;




          }

          /* Evaluate the expression and insert it into the temp table */
          sqlite3ExprCode(pParse, pE2);
          sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
          sqlite3VdbeAddOp(v, OP_String8, 0, 0);
          sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0);
        }
      }
      sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
      break;
    }

    case TK_EXISTS:
    case TK_SELECT: {
      /* This has to be a scalar SELECT.  Generate code to put the
      ** value of this select in a memory cell and record the number
      ** of the memory cell in iColumn.
      */
      int sop;
      Select *pSel;



      pExpr->iColumn = pParse->nMem++;
      pSel = pExpr->pSelect;
      if( pExpr->op==TK_SELECT ){
        sop = SRT_Mem;


      }else{
        static const Token one = { "1", 0, 1 };
        sop = SRT_Exists;
        sqlite3ExprListDelete(pSel->pEList);
        pSel->pEList = sqlite3ExprListAppend(0, 
                          sqlite3Expr(TK_INTEGER, 0, 0, &one), 0);
      }


      sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0);
      break;
    }
  }

  if( pExpr->pSelect ){
    sqlite3VdbeAddOp(v, OP_AggContextPop, 0, 0);
  }
  if( label<0 ){
    sqlite3VdbeResolveLabel(v, label);
  }
  return;
}
#endif /* SQLITE_OMIT_SUBQUERY */

/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
*/
static void codeInteger(Vdbe *v, const char *z, int n){
  int i;
  if( sqlite3GetInt32(z, &i) ){
    sqlite3VdbeAddOp(v, OP_Integer, i, 0);
  }else if( sqlite3FitsIn64Bits(z) ){
    sqlite3VdbeOp3(v, OP_Integer, 0, 0, z, n);
  }else{
    sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n);
  }
}

/*
** Generate code into the current Vdbe to evaluate the given
** expression and leave the result on the top of stack.
**
** This code depends on the fact that certain token values (ex: TK_EQ)
** are the same as opcode values (ex: OP_Eq) that implement the corresponding
** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in
** the make process cause these values to align.  Assert()s in the code
** below verify that the numbers are aligned correctly.
*/
void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
  Vdbe *v = pParse->pVdbe;
  int op;


  if( v==0 ) return;
  if( pExpr==0 ){
    sqlite3VdbeAddOp(v, OP_String8, 0, 0);  /* Empty expression evals to NULL */
    return;
  }
  op = pExpr->op;
  switch( op ){













    case TK_COLUMN: {
      if( !pParse->fillAgg && pExpr->iAgg>=0 ){


        sqlite3VdbeAddOp(v, OP_AggGet, pExpr->iAggCtx, pExpr->iAgg);
      }else if( pExpr->iColumn>=0 ){


        sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);

#ifndef NDEBUG

        if( pExpr->span.z && pExpr->span.n>0 && pExpr->span.n<100 ){
          VdbeComment((v, "# %T", &pExpr->span));
        }
#endif
      }else{
        sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
      }
      break;
    }
    case TK_INTEGER: {
      codeInteger(v, pExpr->token.z, pExpr->token.n);
      break;
    }
    case TK_FLOAT:
    case TK_STRING: {
      assert( TK_FLOAT==OP_Real );
      assert( TK_STRING==OP_String8 );

      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n);



      sqlite3VdbeDequoteP3(v, -1);
      break;
    }
#ifndef SQLITE_OMIT_BLOB_LITERAL
    case TK_BLOB: {


      assert( TK_BLOB==OP_HexBlob );






      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z+1, pExpr->token.n-1);
      sqlite3VdbeDequoteP3(v, -1);
      break;
    }
#endif
    case TK_NULL: {
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      break;
    }
    case TK_VARIABLE: {
      sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
      if( pExpr->token.n>1 ){
        sqlite3VdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
      }
      break;
    }
    case TK_REGISTER: {
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0);
      break;
    }

















    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {
      assert( TK_LT==OP_Lt );
      assert( TK_LE==OP_Le );
      assert( TK_GT==OP_Gt );
      assert( TK_GE==OP_Ge );
      assert( TK_EQ==OP_Eq );
      assert( TK_NE==OP_Ne );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);

      break;
    }
    case TK_AND:
    case TK_OR:
    case TK_PLUS:
    case TK_STAR:
    case TK_MINUS:
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619

1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663




1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
      assert( TK_SLASH==OP_Divide );
      assert( TK_LSHIFT==OP_ShiftLeft );
      assert( TK_RSHIFT==OP_ShiftRight );
      assert( TK_CONCAT==OP_Concat );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      sqlite3VdbeAddOp(v, op, 0, 0);
      stackChng = -1;
      break;
    }
    case TK_UMINUS: {
      Expr *pLeft = pExpr->pLeft;
      assert( pLeft );
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;

        char *z = sqlite3MPrintf("-%.*s", p->n, p->z);
        if( pLeft->op==TK_FLOAT ){
          sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);
        }else{
          codeInteger(v, z, p->n+1);
        }
        sqliteFree(z);
        break;
      }
      /* Fall through into TK_NOT */
    }
    case TK_BITNOT:
    case TK_NOT: {
      assert( TK_BITNOT==OP_BitNot );
      assert( TK_NOT==OP_Not );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3VdbeAddOp(v, op, 0, 0);
      stackChng = 0;
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      int dest;
      assert( TK_ISNULL==OP_IsNull );
      assert( TK_NOTNULL==OP_NotNull );
      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
      sqlite3ExprCode(pParse, pExpr->pLeft);
      dest = sqlite3VdbeCurrentAddr(v) + 2;
      sqlite3VdbeAddOp(v, op, 1, dest);
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
      stackChng = 0;
      break;
    }
    case TK_AGG_FUNCTION: {
      AggInfo *pInfo = pExpr->pAggInfo;
      if( pInfo==0 ){
        sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
            &pExpr->span);
      }else{
        sqlite3VdbeAddOp(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem, 0);
      }
      break;
    }
    case TK_CONST_FUNC:




    case TK_FUNCTION: {
      ExprList *pList = pExpr->pList;
      int nExpr = pList ? pList->nExpr : 0;
      FuncDef *pDef;
      int nId;
      const char *zId;
      int constMask = 0;
      int i;
      u8 enc = ENC(pParse->db);
      CollSeq *pColl = 0;
      zId = (char*)pExpr->token.z;
      nId = pExpr->token.n;
      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
      assert( pDef!=0 );
      nExpr = sqlite3ExprCodeExprList(pParse, pList);
      for(i=0; i<nExpr && i<32; i++){
        if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
          constMask |= (1<<i);
        }
        if( pDef->needCollSeq && !pColl ){
          pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
        }
      }
      if( pDef->needCollSeq ){
        if( !pColl ) pColl = pParse->db->pDfltColl; 
        sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
      }
      sqlite3VdbeOp3(v, OP_Function, constMask, nExpr, (char*)pDef, P3_FUNCDEF);
      stackChng = 1-nExpr;
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      sqlite3CodeSubselect(pParse, pExpr);
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);







<







>
|
















<












<



<
<
<
<
<
|
<


|
>
>
>
>






|

|

<
|





|









|
<







1469
1470
1471
1472
1473
1474
1475

1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500

1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512

1513
1514
1515





1516

1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533

1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550

1551
1552
1553
1554
1555
1556
1557
      assert( TK_SLASH==OP_Divide );
      assert( TK_LSHIFT==OP_ShiftLeft );
      assert( TK_RSHIFT==OP_ShiftRight );
      assert( TK_CONCAT==OP_Concat );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      sqlite3VdbeAddOp(v, op, 0, 0);

      break;
    }
    case TK_UMINUS: {
      Expr *pLeft = pExpr->pLeft;
      assert( pLeft );
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;
        char *z = sqliteMalloc( p->n + 2 );
        sprintf(z, "-%.*s", p->n, p->z);
        if( pLeft->op==TK_FLOAT ){
          sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);
        }else{
          codeInteger(v, z, p->n+1);
        }
        sqliteFree(z);
        break;
      }
      /* Fall through into TK_NOT */
    }
    case TK_BITNOT:
    case TK_NOT: {
      assert( TK_BITNOT==OP_BitNot );
      assert( TK_NOT==OP_Not );
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3VdbeAddOp(v, op, 0, 0);

      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      int dest;
      assert( TK_ISNULL==OP_IsNull );
      assert( TK_NOTNULL==OP_NotNull );
      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
      sqlite3ExprCode(pParse, pExpr->pLeft);
      dest = sqlite3VdbeCurrentAddr(v) + 2;
      sqlite3VdbeAddOp(v, op, 1, dest);
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);

      break;
    }
    case TK_AGG_FUNCTION: {





      sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);

      break;
    }
    case TK_CDATE:
    case TK_CTIME:
    case TK_CTIMESTAMP:
    case TK_GLOB:
    case TK_LIKE:
    case TK_FUNCTION: {
      ExprList *pList = pExpr->pList;
      int nExpr = pList ? pList->nExpr : 0;
      FuncDef *pDef;
      int nId;
      const char *zId;
      int p2 = 0;
      int i;
      u8 enc = pParse->db->enc;
      CollSeq *pColl = 0;

      getFunctionName(pExpr, &zId, &nId);
      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
      assert( pDef!=0 );
      nExpr = sqlite3ExprCodeExprList(pParse, pList);
      for(i=0; i<nExpr && i<32; i++){
        if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
          p2 |= (1<<i);
        }
        if( pDef->needCollSeq && !pColl ){
          pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
        }
      }
      if( pDef->needCollSeq ){
        if( !pColl ) pColl = pParse->db->pDfltColl; 
        sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
      }
      sqlite3VdbeOp3(v, OP_Function, nExpr, p2, (char*)pDef, P3_FUNCDEF);

      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      sqlite3CodeSubselect(pParse, pExpr);
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
      /* Code the <expr> from "<expr> IN (...)". The temporary table
      ** pExpr->iTable contains the values that make up the (...) set.
      */
      sqlite3ExprCode(pParse, pExpr->pLeft);
      addr = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4);            /* addr + 0 */
      sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
      sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);   /* addr + 4 */
      sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);                  /* addr + 6 */

      break;
    }







|







1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
      /* Code the <expr> from "<expr> IN (...)". The temporary table
      ** pExpr->iTable contains the values that make up the (...) set.
      */
      sqlite3ExprCode(pParse, pExpr->pLeft);
      addr = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4);            /* addr + 0 */
      sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);   /* addr + 4 */
      sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);                  /* addr + 6 */

      break;
    }
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756

1757
1758
1759
1760
1761
1762
1763
      codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
      sqlite3VdbeAddOp(v, OP_And, 0, 0);
      break;
    }
    case TK_UPLUS:
    case TK_AS: {
      sqlite3ExprCode(pParse, pExpr->pLeft);
      stackChng = 0;
      break;
    }
    case TK_CASE: {
      int expr_end_label;
      int jumpInst;

      int nExpr;
      int i;
      ExprList *pEList;
      struct ExprList_item *aListelem;

      assert(pExpr->pList);
      assert((pExpr->pList->nExpr % 2) == 0);







<





>







1602
1603
1604
1605
1606
1607
1608

1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
      codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
      sqlite3VdbeAddOp(v, OP_And, 0, 0);
      break;
    }
    case TK_UPLUS:
    case TK_AS: {
      sqlite3ExprCode(pParse, pExpr->pLeft);

      break;
    }
    case TK_CASE: {
      int expr_end_label;
      int jumpInst;
      int addr;
      int nExpr;
      int i;
      ExprList *pEList;
      struct ExprList_item *aListelem;

      assert(pExpr->pList);
      assert((pExpr->pList->nExpr % 2) == 0);
1777
1778
1779
1780
1781
1782
1783
1784

1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810

1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
                                 OP_Ne, 0, 1);
          sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
        }else{
          jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0);
        }
        sqlite3ExprCode(pParse, aListelem[i+1].pExpr);
        sqlite3VdbeAddOp(v, OP_Goto, 0, expr_end_label);
        sqlite3VdbeJumpHere(v, jumpInst);

      }
      if( pExpr->pLeft ){
        sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      }
      if( pExpr->pRight ){
        sqlite3ExprCode(pParse, pExpr->pRight);
      }else{
        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
      }
      sqlite3VdbeResolveLabel(v, expr_end_label);
      break;
    }
#ifndef SQLITE_OMIT_TRIGGER
    case TK_RAISE: {
      if( !pParse->trigStack ){
        sqlite3ErrorMsg(pParse,
                       "RAISE() may only be used within a trigger-program");
	return;
      }
      if( pExpr->iColumn!=OE_Ignore ){
         assert( pExpr->iColumn==OE_Rollback ||
                 pExpr->iColumn == OE_Abort ||
                 pExpr->iColumn == OE_Fail );
         sqlite3DequoteExpr(pExpr);
         sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
                        (char*)pExpr->token.z, pExpr->token.n);

      } else {
         assert( pExpr->iColumn == OE_Ignore );
         sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
         sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
         VdbeComment((v, "# raise(IGNORE)"));
      }
      stackChng = 0;
      break;
    }
#endif
  }

  if( pParse->ckOffset ){
    pParse->ckOffset += stackChng;
    assert( pParse->ckOffset );
  }
}

#ifndef SQLITE_OMIT_TRIGGER
/*
** Generate code that evalutes the given expression and leaves the result
** on the stack.  See also sqlite3ExprCode().







|
>







|















<

|
>






<
<


<
|
<
<
<







1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666

1667
1668
1669
1670
1671
1672
1673
1674
1675


1676
1677

1678



1679
1680
1681
1682
1683
1684
1685
                                 OP_Ne, 0, 1);
          sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
        }else{
          jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0);
        }
        sqlite3ExprCode(pParse, aListelem[i+1].pExpr);
        sqlite3VdbeAddOp(v, OP_Goto, 0, expr_end_label);
        addr = sqlite3VdbeCurrentAddr(v);
        sqlite3VdbeChangeP2(v, jumpInst, addr);
      }
      if( pExpr->pLeft ){
        sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      }
      if( pExpr->pRight ){
        sqlite3ExprCode(pParse, pExpr->pRight);
      }else{
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      }
      sqlite3VdbeResolveLabel(v, expr_end_label);
      break;
    }
#ifndef SQLITE_OMIT_TRIGGER
    case TK_RAISE: {
      if( !pParse->trigStack ){
        sqlite3ErrorMsg(pParse,
                       "RAISE() may only be used within a trigger-program");
	return;
      }
      if( pExpr->iColumn!=OE_Ignore ){
         assert( pExpr->iColumn==OE_Rollback ||
                 pExpr->iColumn == OE_Abort ||
                 pExpr->iColumn == OE_Fail );

         sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn,
                        pExpr->token.z, pExpr->token.n);
         sqlite3VdbeDequoteP3(v, -1);
      } else {
         assert( pExpr->iColumn == OE_Ignore );
         sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
         sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump);
         VdbeComment((v, "# raise(IGNORE)"));
      }


    }
#endif

    break;



  }
}

#ifndef SQLITE_OMIT_TRIGGER
/*
** Generate code that evalutes the given expression and leaves the result
** on the stack.  See also sqlite3ExprCode().
1861
1862
1863
1864
1865
1866
1867

1868

1869
1870
1871
1872
1873
1874
1875
1876
1877
*/
int sqlite3ExprCodeExprList(
  Parse *pParse,     /* Parsing context */
  ExprList *pList    /* The expression list to be coded */
){
  struct ExprList_item *pItem;
  int i, n;

  if( pList==0 ) return 0;

  n = pList->nExpr;
  for(pItem=pList->a, i=n; i>0; i--, pItem++){
    sqlite3ExprCode(pParse, pItem->pExpr);
  }
  return n;
}

/*
** Generate code for a boolean expression such that a jump is made







>

>

|







1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
*/
int sqlite3ExprCodeExprList(
  Parse *pParse,     /* Parsing context */
  ExprList *pList    /* The expression list to be coded */
){
  struct ExprList_item *pItem;
  int i, n;
  Vdbe *v;
  if( pList==0 ) return 0;
  v = sqlite3GetVdbe(pParse);
  n = pList->nExpr;
  for(pItem=pList->a, i=0; i<n; i++, pItem++){
    sqlite3ExprCode(pParse, pItem->pExpr);
  }
  return n;
}

/*
** Generate code for a boolean expression such that a jump is made
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in
** the make process cause these values to align.  Assert()s in the code
** below verify that the numbers are aligned correctly.
*/
void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
  Vdbe *v = pParse->pVdbe;
  int op = 0;
  int ckOffset = pParse->ckOffset;
  if( v==0 || pExpr==0 ) return;
  op = pExpr->op;
  switch( op ){
    case TK_AND: {
      int d2 = sqlite3VdbeMakeLabel(v);
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);







<







1741
1742
1743
1744
1745
1746
1747

1748
1749
1750
1751
1752
1753
1754
** operation.  Special comments in vdbe.c and the mkopcodeh.awk script in
** the make process cause these values to align.  Assert()s in the code
** below verify that the numbers are aligned correctly.
*/
void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
  Vdbe *v = pParse->pVdbe;
  int op = 0;

  if( v==0 || pExpr==0 ) return;
  op = pExpr->op;
  switch( op ){
    case TK_AND: {
      int d2 = sqlite3VdbeMakeLabel(v);
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
      addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);

      pRight = pExpr->pList->a[1].pExpr;
      sqlite3ExprCode(pParse, pRight);
      codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull);

      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      sqlite3VdbeJumpHere(v, addr);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      break;
    }
    default: {
      sqlite3ExprCode(pParse, pExpr);
      sqlite3VdbeAddOp(v, OP_If, jumpIfNull, dest);
      break;
    }
  }
  pParse->ckOffset = ckOffset;
}

/*
** Generate code for a boolean expression such that a jump is made
** to the label "dest" if the expression is false but execution
** continues straight thru if the expression is true.
**
** If the expression evaluates to NULL (neither true nor false) then
** jump if jumpIfNull is true or fall through if jumpIfNull is false.
*/
void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
  Vdbe *v = pParse->pVdbe;
  int op = 0;
  int ckOffset = pParse->ckOffset;
  if( v==0 || pExpr==0 ) return;

  /* The value of pExpr->op and op are related as follows:
  **
  **       pExpr->op            op
  **       ---------          ----------
  **       TK_ISNULL          OP_NotNull







|









<













<







1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821

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

1835
1836
1837
1838
1839
1840
1841
      addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);

      pRight = pExpr->pList->a[1].pExpr;
      sqlite3ExprCode(pParse, pRight);
      codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull);

      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      break;
    }
    default: {
      sqlite3ExprCode(pParse, pExpr);
      sqlite3VdbeAddOp(v, OP_If, jumpIfNull, dest);
      break;
    }
  }

}

/*
** Generate code for a boolean expression such that a jump is made
** to the label "dest" if the expression is false but execution
** continues straight thru if the expression is true.
**
** If the expression evaluates to NULL (neither true nor false) then
** jump if jumpIfNull is true or fall through if jumpIfNull is false.
*/
void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
  Vdbe *v = pParse->pVdbe;
  int op = 0;

  if( v==0 || pExpr==0 ) return;

  /* The value of pExpr->op and op are related as follows:
  **
  **       pExpr->op            op
  **       ---------          ----------
  **       TK_ISNULL          OP_NotNull
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123

2124
2125

2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143

2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155

2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178

2179
2180
2181
2182
2183
2184
2185
2186
2187

2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219

2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231

2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
    }
    default: {
      sqlite3ExprCode(pParse, pExpr);
      sqlite3VdbeAddOp(v, OP_IfNot, jumpIfNull, dest);
      break;
    }
  }
  pParse->ckOffset = ckOffset;
}

/*
** Do a deep comparison of two expression trees.  Return TRUE (non-zero)
** if they are identical and return FALSE if they differ in any way.
*/
int sqlite3ExprCompare(Expr *pA, Expr *pB){
  int i;
  if( pA==0 ){
    return pB==0;
  }else if( pB==0 ){
    return 0;
  }
  if( pA->op!=pB->op ) return 0;
  if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 0;
  if( !sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 0;
  if( !sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 0;
  if( pA->pList ){
    if( pB->pList==0 ) return 0;
    if( pA->pList->nExpr!=pB->pList->nExpr ) return 0;
    for(i=0; i<pA->pList->nExpr; i++){
      if( !sqlite3ExprCompare(pA->pList->a[i].pExpr, pB->pList->a[i].pExpr) ){
        return 0;
      }
    }
  }else if( pB->pList ){
    return 0;
  }
  if( pA->pSelect || pB->pSelect ) return 0;
  if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
  if( pA->token.z ){
    if( pB->token.z==0 ) return 0;
    if( pB->token.n!=pA->token.n ) return 0;
    if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){
      return 0;
    }
  }
  return 1;
}


/*
** Add a new element to the pAggInfo->aCol[] array.  Return the index of
** the new element.  Return a negative number if malloc fails.

*/
static int addAggInfoColumn(AggInfo *pInfo){

  int i;
  i = sqlite3ArrayAllocate((void**)&pInfo->aCol, sizeof(pInfo->aCol[0]), 3);
  if( i<0 ){
    return -1;
  }
  return i;
}    

/*
** Add a new element to the pAggInfo->aFunc[] array.  Return the index of
** the new element.  Return a negative number if malloc fails.
*/
static int addAggInfoFunc(AggInfo *pInfo){
  int i;
  i = sqlite3ArrayAllocate((void**)&pInfo->aFunc, sizeof(pInfo->aFunc[0]), 2);
  if( i<0 ){
    return -1;
  }

  return i;
}    

/*
** This is an xFunc for walkExprTree() used to implement 
** sqlite3ExprAnalyzeAggregates().  See sqlite3ExprAnalyzeAggregates
** for additional information.
**
** This routine analyzes the aggregate function at pExpr.
*/
static int analyzeAggregate(void *pArg, Expr *pExpr){
  int i;

  NameContext *pNC = (NameContext *)pArg;
  Parse *pParse = pNC->pParse;
  SrcList *pSrcList = pNC->pSrcList;
  AggInfo *pAggInfo = pNC->pAggInfo;
  

  switch( pExpr->op ){
    case TK_COLUMN: {
      /* Check to see if the column is in one of the tables in the FROM
      ** clause of the aggregate query */
      if( pSrcList ){
        struct SrcList_item *pItem = pSrcList->a;
        for(i=0; i<pSrcList->nSrc; i++, pItem++){
          struct AggInfo_col *pCol;
          if( pExpr->iTable==pItem->iCursor ){
            /* If we reach this point, it means that pExpr refers to a table
            ** that is in the FROM clause of the aggregate query.  
            **
            ** Make an entry for the column in pAggInfo->aCol[] if there
            ** is not an entry there already.
            */
            pCol = pAggInfo->aCol;
            for(i=0; i<pAggInfo->nColumn; i++, pCol++){

              if( pCol->iTable==pExpr->iTable &&
                  pCol->iColumn==pExpr->iColumn ){
                break;
              }
            }
            if( i>=pAggInfo->nColumn && (i = addAggInfoColumn(pAggInfo))>=0 ){
              pCol = &pAggInfo->aCol[i];
              pCol->iTable = pExpr->iTable;
              pCol->iColumn = pExpr->iColumn;

              pCol->iMem = pParse->nMem++;
              pCol->iSorterColumn = -1;
              pCol->pExpr = pExpr;
              if( pAggInfo->pGroupBy ){
                int j, n;
                ExprList *pGB = pAggInfo->pGroupBy;
                struct ExprList_item *pTerm = pGB->a;
                n = pGB->nExpr;
                for(j=0; j<n; j++, pTerm++){
                  Expr *pE = pTerm->pExpr;
                  if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable &&
                      pE->iColumn==pExpr->iColumn ){
                    pCol->iSorterColumn = j;
                    break;
                  }
                }
              }
              if( pCol->iSorterColumn<0 ){
                pCol->iSorterColumn = pAggInfo->nSortingColumn++;
              }
            }
            /* There is now an entry for pExpr in pAggInfo->aCol[] (either
            ** because it was there before or because we just created it).
            ** Convert the pExpr to be a TK_AGG_COLUMN referring to that
            ** pAggInfo->aCol[] entry.
            */
            pExpr->pAggInfo = pAggInfo;
            pExpr->op = TK_AGG_COLUMN;
            pExpr->iAgg = i;
            break;
          } /* endif pExpr->iTable==pItem->iCursor */
        } /* end loop over pSrcList */

      }
      return 1;
    }
    case TK_AGG_FUNCTION: {
      /* The pNC->nDepth==0 test causes aggregate functions in subqueries
      ** to be ignored */
      if( pNC->nDepth==0 ){
        /* Check to see if pExpr is a duplicate of another aggregate 
        ** function that is already in the pAggInfo structure
        */
        struct AggInfo_func *pItem = pAggInfo->aFunc;
        for(i=0; i<pAggInfo->nFunc; i++, pItem++){

          if( sqlite3ExprCompare(pItem->pExpr, pExpr) ){
            break;
          }
        }
        if( i>=pAggInfo->nFunc ){
          /* pExpr is original.  Make a new entry in pAggInfo->aFunc[]
          */
          u8 enc = ENC(pParse->db);
          i = addAggInfoFunc(pAggInfo);
          if( i>=0 ){
            pItem = &pAggInfo->aFunc[i];
            pItem->pExpr = pExpr;
            pItem->iMem = pParse->nMem++;
            pItem->pFunc = sqlite3FindFunction(pParse->db,
                   (char*)pExpr->token.z, pExpr->token.n,
                   pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0);
            if( pExpr->flags & EP_Distinct ){
              pItem->iDistinct = pParse->nTab++;
            }else{
              pItem->iDistinct = -1;
            }
          }
        }
        /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
        */
        pExpr->iAgg = i;
        pExpr->pAggInfo = pAggInfo;
        return 1;
      }
    }
  }

  /* Recursively walk subqueries looking for TK_COLUMN nodes that need
  ** to be changed to TK_AGG_COLUMN.  But increment nDepth so that
  ** TK_AGG_FUNCTION nodes in subqueries will be unchanged.
  */
  if( pExpr->pSelect ){
    pNC->nDepth++;
    walkSelectExpr(pExpr->pSelect, analyzeAggregate, pNC);
    pNC->nDepth--;
  }
  return 0;
}







<














<


















|
<
|
<



<

|
|
>

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

>
|
|










>



<
<



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




<
<

<
<
<
|
|
>
|



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

<




<
<
<
<
<







1924
1925
1926
1927
1928
1929
1930

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

1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963

1964

1965
1966
1967

1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979


1980









1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998


1999
2000
2001




2002

2003






2004
2005
2006
2007
2008
2009
2010
2011
2012
2013


2014
2015

2016











2017











2018

2019
2020


2021
2022
2023
2024
2025


2026



2027
2028
2029
2030
2031
2032
2033
2034


2035
2036
2037
2038
2039

2040
2041
2042




2043




2044

2045
2046
2047
2048





2049
2050
2051
2052
2053
2054
2055
    }
    default: {
      sqlite3ExprCode(pParse, pExpr);
      sqlite3VdbeAddOp(v, OP_IfNot, jumpIfNull, dest);
      break;
    }
  }

}

/*
** Do a deep comparison of two expression trees.  Return TRUE (non-zero)
** if they are identical and return FALSE if they differ in any way.
*/
int sqlite3ExprCompare(Expr *pA, Expr *pB){
  int i;
  if( pA==0 ){
    return pB==0;
  }else if( pB==0 ){
    return 0;
  }
  if( pA->op!=pB->op ) return 0;

  if( !sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 0;
  if( !sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 0;
  if( pA->pList ){
    if( pB->pList==0 ) return 0;
    if( pA->pList->nExpr!=pB->pList->nExpr ) return 0;
    for(i=0; i<pA->pList->nExpr; i++){
      if( !sqlite3ExprCompare(pA->pList->a[i].pExpr, pB->pList->a[i].pExpr) ){
        return 0;
      }
    }
  }else if( pB->pList ){
    return 0;
  }
  if( pA->pSelect || pB->pSelect ) return 0;
  if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
  if( pA->token.z ){
    if( pB->token.z==0 ) return 0;
    if( pB->token.n!=pA->token.n ) return 0;
    if( sqlite3StrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0;

  }

  return 1;
}


/*
** Add a new element to the pParse->aAgg[] array and return its index.
** The new element is initialized to zero.  The calling function is
** expected to fill it in.
*/
static int appendAggInfo(Parse *pParse){
  if( (pParse->nAgg & 0x7)==0 ){
    int amt = pParse->nAgg + 8;
    AggExpr *aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0]));
    if( aAgg==0 ){
      return -1;
    }


    pParse->aAgg = aAgg;









  }
  memset(&pParse->aAgg[pParse->nAgg], 0, sizeof(pParse->aAgg[0]));
  return pParse->nAgg++;
}

/*
** This is an xFunc for walkExprTree() used to implement 
** sqlite3ExprAnalyzeAggregates().  See sqlite3ExprAnalyzeAggregates
** for additional information.
**
** This routine analyzes the aggregate function at pExpr.
*/
static int analyzeAggregate(void *pArg, Expr *pExpr){
  int i;
  AggExpr *aAgg;
  NameContext *pNC = (NameContext *)pArg;
  Parse *pParse = pNC->pParse;
  SrcList *pSrcList = pNC->pSrcList;



  switch( pExpr->op ){
    case TK_COLUMN: {




      for(i=0; pSrcList && i<pSrcList->nSrc; i++){

        if( pExpr->iTable==pSrcList->a[i].iCursor ){






          aAgg = pParse->aAgg;
          for(i=0; i<pParse->nAgg; i++){
            if( aAgg[i].isAgg ) continue;
            if( aAgg[i].pExpr->iTable==pExpr->iTable
             && aAgg[i].pExpr->iColumn==pExpr->iColumn ){
              break;
            }
          }
          if( i>=pParse->nAgg ){
            i = appendAggInfo(pParse);


            if( i<0 ) return 1;
            pParse->aAgg[i].isAgg = 0;

            pParse->aAgg[i].pExpr = pExpr;











          }











          pExpr->iAgg = i;

          pExpr->iAggCtx = pNC->nDepth;
          return 1;


        }
      }
      return 1;
    }
    case TK_AGG_FUNCTION: {


      if( pNC->nDepth==0 ){



        aAgg = pParse->aAgg;
        for(i=0; i<pParse->nAgg; i++){
          if( !aAgg[i].isAgg ) continue;
          if( sqlite3ExprCompare(aAgg[i].pExpr, pExpr) ){
            break;
          }
        }
        if( i>=pParse->nAgg ){


          u8 enc = pParse->db->enc;
          i = appendAggInfo(pParse);
          if( i<0 ) return 1;
          pParse->aAgg[i].isAgg = 1;
          pParse->aAgg[i].pExpr = pExpr;

          pParse->aAgg[i].pFunc = sqlite3FindFunction(pParse->db,
               pExpr->token.z, pExpr->token.n,
               pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0);




        }




        pExpr->iAgg = i;

        return 1;
      }
    }
  }





  if( pExpr->pSelect ){
    pNC->nDepth++;
    walkSelectExpr(pExpr->pSelect, analyzeAggregate, pNC);
    pNC->nDepth--;
  }
  return 0;
}
2287
2288
2289
2290
2291
2292
2293
2294








2295
2296
2297






2298












2299
2300



















2301






2302

2303






2304






2305















2306
2307


2308


2309
int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
  int nErr = pNC->pParse->nErr;
  walkExprTree(pExpr, analyzeAggregate, pNC);
  return pNC->pParse->nErr - nErr;
}

/*
** Call sqlite3ExprAnalyzeAggregates() for every expression in an








** expression list.  Return the number of errors.
**
** If an error is found, the analysis is cut short.






*/












int sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
  struct ExprList_item *pItem;



















  int i;






  int nErr = 0;

  if( pList ){






    for(pItem=pList->a, i=0; nErr==0 && i<pList->nExpr; i++, pItem++){






      nErr += sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);















    }
  }


  return nErr;


}







|
>
>
>
>
>
>
>
>
|

|
>
>
>
>
>
>

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


>
>
|
>
>

2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
  int nErr = pNC->pParse->nErr;
  walkExprTree(pExpr, analyzeAggregate, pNC);
  return pNC->pParse->nErr - nErr;
}

/*
** Locate a user function given a name, a number of arguments and a flag
** indicating whether the function prefers UTF-16 over UTF-8.  Return a
** pointer to the FuncDef structure that defines that function, or return
** NULL if the function does not exist.
**
** If the createFlag argument is true, then a new (blank) FuncDef
** structure is created and liked into the "db" structure if a
** no matching function previously existed.  When createFlag is true
** and the nArg parameter is -1, then only a function that accepts
** any number of arguments will be returned.
**
** If createFlag is false and nArg is -1, then the first valid
** function found is returned.  A function is valid if either xFunc
** or xStep is non-zero.
**
** If createFlag is false, then a function with the required name and
** number of arguments may be returned even if the eTextRep flag does not
** match that requested.
*/
FuncDef *sqlite3FindFunction(
  sqlite3 *db,       /* An open database */
  const char *zName, /* Name of the function.  Not null-terminated */
  int nName,         /* Number of characters in the name */
  int nArg,          /* Number of arguments.  -1 means any number */
  u8 enc,            /* Preferred text encoding */
  int createFlag     /* Create new entry if true and does not otherwise exist */
){
  FuncDef *p;         /* Iterator variable */
  FuncDef *pFirst;    /* First function with this name */
  FuncDef *pBest = 0; /* Best match found so far */
  int bestmatch = 0;  


  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
  if( nArg<-1 ) nArg = -1;

  pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
  for(p=pFirst; p; p=p->pNext){
    /* During the search for the best function definition, bestmatch is set
    ** as follows to indicate the quality of the match with the definition
    ** pointed to by pBest:
    **
    ** 0: pBest is NULL. No match has been found.
    ** 1: A variable arguments function that prefers UTF-8 when a UTF-16
    **    encoding is requested, or vice versa.
    ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is
    **    requested, or vice versa.
    ** 3: A variable arguments function using the same text encoding.
    ** 4: A function with the exact number of arguments requested that
    **    prefers UTF-8 when a UTF-16 encoding is requested, or vice versa.
    ** 5: A function with the exact number of arguments requested that
    **    prefers UTF-16LE when UTF-16BE is requested, or vice versa.
    ** 6: An exact match.
    **
    ** A larger value of 'matchqual' indicates a more desirable match.
    */
    if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){
      int match = 1;          /* Quality of this match */
      if( p->nArg==nArg || nArg==-1 ){
        match = 4;
      }
      if( enc==p->iPrefEnc ){
        match += 2;
      }
      else if( (enc==SQLITE_UTF16LE && p->iPrefEnc==SQLITE_UTF16BE) ||
               (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
        match += 1;
      }

      if( match>bestmatch ){
        pBest = p;
        bestmatch = match;
      }
    }
  }

  /* If the createFlag parameter is true, and the seach did not reveal an
  ** exact match for the name, number of arguments and encoding, then add a
  ** new entry to the hash table and return it.
  */
  if( createFlag && bestmatch<6 && 
      (pBest = sqliteMalloc(sizeof(*pBest)+nName+1)) ){
    pBest->nArg = nArg;
    pBest->pNext = pFirst;
    pBest->zName = (char*)&pBest[1];
    pBest->iPrefEnc = enc;
    memcpy(pBest->zName, zName, nName);
    pBest->zName[nName] = 0;
    if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
      sqliteFree(pBest);
      return 0;
    }
  }

  if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
    return pBest;
  }
  return 0;
}
Changes to SQLite.Interop/src/func.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.17 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
#include "os.h"

/*
** Return the collating function associated with a function.
*/
static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
  return context->pColl;
}

/*
** Implementation of the non-aggregate min() and max() functions
*/







|



|





<
<
<







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28



29
30
31
32
33
34
35
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.1 2005/03/01 16:04:29 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
#include "os.h"




static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
  return context->pColl;
}

/*
** Implementation of the non-aggregate min() and max() functions
*/
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    case SQLITE_TEXT:    z = "text";    break;
    case SQLITE_FLOAT:   z = "real";    break;
    case SQLITE_BLOB:    z = "blob";    break;
  }
  sqlite3_result_text(context, z, -1, SQLITE_STATIC);
}


/*
** Implementation of the length() function
*/
static void lengthFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int len;

  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_BLOB:
    case SQLITE_INTEGER:
    case SQLITE_FLOAT: {
      sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
      break;
    }
    case SQLITE_TEXT: {
      const unsigned char *z = sqlite3_value_text(argv[0]);
      for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
      sqlite3_result_int(context, len);
      break;
    }
    default: {
      sqlite3_result_null(context);
      break;







<



















|







74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    case SQLITE_TEXT:    z = "text";    break;
    case SQLITE_FLOAT:   z = "real";    break;
    case SQLITE_BLOB:    z = "blob";    break;
  }
  sqlite3_result_text(context, z, -1, SQLITE_STATIC);
}


/*
** Implementation of the length() function
*/
static void lengthFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int len;

  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_BLOB:
    case SQLITE_INTEGER:
    case SQLITE_FLOAT: {
      sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
      break;
    }
    case SQLITE_TEXT: {
      const char *z = sqlite3_value_text(argv[0]);
      for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
      sqlite3_result_int(context, len);
      break;
    }
    default: {
      sqlite3_result_null(context);
      break;
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
** Implementation of the substr() function
*/
static void substrFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const unsigned char *z;
  const unsigned char *z2;
  int i;
  int p1, p2, len;

  assert( argc==3 );
  z = sqlite3_value_text(argv[0]);
  if( z==0 ) return;
  p1 = sqlite3_value_int(argv[1]);







|
|







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
** Implementation of the substr() function
*/
static void substrFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *z;
  const char *z2;
  int i;
  int p1, p2, len;

  assert( argc==3 );
  z = sqlite3_value_text(argv[0]);
  if( z==0 ) return;
  p1 = sqlite3_value_int(argv[1]);
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
  }
  while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p1++; }
  for(; i<p1+p2 && z[i]; i++){
    if( (z[i]&0xc0)==0x80 ) p2++;
  }
  while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
  if( p2<0 ) p2 = 0;
  sqlite3_result_text(context, (char*)&z[p1], p2, SQLITE_TRANSIENT);
}

/*
** Implementation of the round() function
*/
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  int n = 0;
  double r;
  char zBuf[500];  /* larger than the %f representation of the largest double */
  assert( argc==1 || argc==2 );
  if( argc==2 ){
    if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
    n = sqlite3_value_int(argv[1]);
    if( n>30 ) n = 30;
    if( n<0 ) n = 0;
  }
  if( SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  r = sqlite3_value_double(argv[0]);
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r);
  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}

/*
** Implementation of the upper() and lower() SQL functions.
*/
static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  unsigned char *z;
  int i;
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
  if( z==0 ) return;
  strcpy((char*)z, (char*)sqlite3_value_text(argv[0]));
  for(i=0; z[i]; i++){
    z[i] = toupper(z[i]);
  }
  sqlite3_result_text(context, (char*)z, -1, SQLITE_TRANSIENT);
  sqliteFree(z);
}
static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  unsigned char *z;
  int i;
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
  if( z==0 ) return;
  strcpy((char*)z, (char*)sqlite3_value_text(argv[0]));
  for(i=0; z[i]; i++){
    z[i] = tolower(z[i]);
  }
  sqlite3_result_text(context, (char*)z, -1, SQLITE_TRANSIENT);
  sqliteFree(z);
}

/*
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.  
** All three do the same thing.  They return the first non-NULL
** argument.







|








|









|












|



|








|



|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  }
  while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p1++; }
  for(; i<p1+p2 && z[i]; i++){
    if( (z[i]&0xc0)==0x80 ) p2++;
  }
  while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
  if( p2<0 ) p2 = 0;
  sqlite3_result_text(context, &z[p1], p2, SQLITE_TRANSIENT);
}

/*
** Implementation of the round() function
*/
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  int n = 0;
  double r;
  char zBuf[100];
  assert( argc==1 || argc==2 );
  if( argc==2 ){
    if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
    n = sqlite3_value_int(argv[1]);
    if( n>30 ) n = 30;
    if( n<0 ) n = 0;
  }
  if( SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  r = sqlite3_value_double(argv[0]);
  sprintf(zBuf,"%.*f",n,r);
  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}

/*
** Implementation of the upper() and lower() SQL functions.
*/
static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  unsigned char *z;
  int i;
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
  if( z==0 ) return;
  strcpy(z, sqlite3_value_text(argv[0]));
  for(i=0; z[i]; i++){
    z[i] = toupper(z[i]);
  }
  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
  sqliteFree(z);
}
static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
  unsigned char *z;
  int i;
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
  if( z==0 ) return;
  strcpy(z, sqlite3_value_text(argv[0]));
  for(i=0; z[i]; i++){
    z[i] = tolower(z[i]);
  }
  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
  sqliteFree(z);
}

/*
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.  
** All three do the same thing.  They return the first non-NULL
** argument.
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
*/
struct compareInfo {
  u8 matchAll;
  u8 matchOne;
  u8 matchSet;
  u8 noCase;
};

static const struct compareInfo globInfo = { '*', '?', '[', 0 };
/* The correct SQL-92 behavior is for the LIKE operator to ignore
** case.  Thus  'a' LIKE 'A' would be true. */
static const struct compareInfo likeInfoNorm = { '%', '_',   0, 1 };
/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator
** is case sensitive causing 'a' LIKE 'A' to be false */
static const struct compareInfo likeInfoAlt = { '%', '_',   0, 0 };

/*
** X is a pointer to the first byte of a UTF-8 character.  Increment
** X so that it points to the next character.  This only works right
** if X points to a well-formed UTF-8 string.
*/
#define sqliteNextChar(X)  while( (0xc0&*++(X))==0x80 ){}







<

<
<
<
<
<
|







303
304
305
306
307
308
309

310





311
312
313
314
315
316
317
318
*/
struct compareInfo {
  u8 matchAll;
  u8 matchOne;
  u8 matchSet;
  u8 noCase;
};

static const struct compareInfo globInfo = { '*', '?', '[', 0 };





static const struct compareInfo likeInfo = { '%', '_',   0, 1 };

/*
** X is a pointer to the first byte of a UTF-8 character.  Increment
** X so that it points to the next character.  This only works right
** if X points to a well-formed UTF-8 string.
*/
#define sqliteNextChar(X)  while( (0xc0&*++(X))==0x80 ){}
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481

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


507










508

509
510
511
512
513
514
515
516
517
      zString++;
      prevEscape = 0;
    }
  }
  return *zString==0;
}

/*
** Count the number of times that the LIKE operator (or GLOB which is
** just a variation of LIKE) gets called.  This is used for testing
** only.
*/
#ifdef SQLITE_TEST
int sqlite3_like_count = 0;
#endif


/*
** Implementation of the like() SQL function.  This function implements
** the build-in LIKE operator.  The first argument to the function is the
** pattern and the second argument is the string.  So, the SQL statements:
**
**       A LIKE B
**
** is implemented as like(B,A).
**

** This same function (with a different compareInfo structure) computes
** the GLOB operator.
*/
static void likeFunc(
  sqlite3_context *context, 
  int argc, 
  sqlite3_value **argv
){
  const unsigned char *zA = sqlite3_value_text(argv[0]);
  const unsigned char *zB = sqlite3_value_text(argv[1]);
  int escape = 0;
  if( argc==3 ){
    /* The escape character string must consist of a single UTF-8 character.
    ** Otherwise, return an error.
    */
    const unsigned char *zEsc = sqlite3_value_text(argv[2]);
    if( sqlite3utf8CharLen((char*)zEsc, -1)!=1 ){
      sqlite3_result_error(context, 
          "ESCAPE expression must be a single character", -1);
      return;
    }
    escape = sqlite3ReadUtf8(zEsc);
  }
  if( zA && zB ){
    struct compareInfo *pInfo = sqlite3_user_data(context);


#ifdef SQLITE_TEST










    sqlite3_like_count++;

#endif
    sqlite3_result_int(context, patternCompare(zA, zB, pInfo, escape));
  }
}

/*
** Implementation of the NULLIF(x,y) function.  The result is the first
** argument if the arguments are different.  The result is NULL if the
** arguments are equal to each other.







<
<
<
<
<
<
<
<
<










>
|
<














|







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







446
447
448
449
450
451
452









453
454
455
456
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
      zString++;
      prevEscape = 0;
    }
  }
  return *zString==0;
}











/*
** Implementation of the like() SQL function.  This function implements
** the build-in LIKE operator.  The first argument to the function is the
** pattern and the second argument is the string.  So, the SQL statements:
**
**       A LIKE B
**
** is implemented as like(B,A).
**
** If the pointer retrieved by via a call to sqlite3_user_data() is
** not NULL, then this function uses UTF-16. Otherwise UTF-8.

*/
static void likeFunc(
  sqlite3_context *context, 
  int argc, 
  sqlite3_value **argv
){
  const unsigned char *zA = sqlite3_value_text(argv[0]);
  const unsigned char *zB = sqlite3_value_text(argv[1]);
  int escape = 0;
  if( argc==3 ){
    /* The escape character string must consist of a single UTF-8 character.
    ** Otherwise, return an error.
    */
    const unsigned char *zEsc = sqlite3_value_text(argv[2]);
    if( sqlite3utf8CharLen(zEsc, -1)!=1 ){
      sqlite3_result_error(context, 
          "ESCAPE expression must be a single character", -1);
      return;
    }
    escape = sqlite3ReadUtf8(zEsc);
  }
  if( zA && zB ){
    sqlite3_result_int(context, patternCompare(zA, zB, &likeInfo, escape));
  }
}

/*
** Implementation of the glob() SQL function.  This function implements
** the build-in GLOB operator.  The first argument to the function is the
** string and the second argument is the pattern.  So, the SQL statements:
**
**       A GLOB B
**
** is implemented as glob(B,A).
*/
static void globFunc(sqlite3_context *context, int arg, sqlite3_value **argv){
  const unsigned char *zA = sqlite3_value_text(argv[0]);
  const unsigned char *zB = sqlite3_value_text(argv[1]);
  if( zA && zB ){
    sqlite3_result_int(context, patternCompare(zA, zB, &globInfo, 0));
  }
}

/*
** Implementation of the NULLIF(x,y) function.  The result is the first
** argument if the arguments are different.  The result is NULL if the
** arguments are equal to each other.
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
        sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
        sqliteFree(zText);
      }
      break;
    }
    case SQLITE_TEXT: {
      int i,j,n;
      const unsigned char *zArg = sqlite3_value_text(argv[0]);
      char *z;

      for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
      z = sqliteMalloc( i+n+3 );
      if( z==0 ) return;
      z[0] = '\'';
      for(i=0, j=1; zArg[i]; i++){







|







582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
        sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
        sqliteFree(zText);
      }
      break;
    }
    case SQLITE_TEXT: {
      int i,j,n;
      const char *zArg = sqlite3_value_text(argv[0]);
      char *z;

      for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
      z = sqliteMalloc( i+n+3 );
      if( z==0 ) return;
      z[0] = '\'';
      for(i=0, j=1; zArg[i]; i++){
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
  }
  assert( n<sizeof(zBuf) );
  sqlite3Randomness(n, zBuf);
  for(i=0; i<n; i++){
    zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
  }
  zBuf[n] = 0;
  sqlite3_result_text(context, (char*)zBuf, n, SQLITE_TRANSIENT);
}
#endif /* SQLITE_TEST */

#ifdef SQLITE_TEST
/*
** The following two SQL functions are used to test returning a text
** result with a destructor. Function 'test_destructor' takes one argument







|







682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
  }
  assert( n<sizeof(zBuf) );
  sqlite3Randomness(n, zBuf);
  for(i=0; i<n; i++){
    zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
  }
  zBuf[n] = 0;
  sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT);
}
#endif /* SQLITE_TEST */

#ifdef SQLITE_TEST
/*
** The following two SQL functions are used to test returning a text
** result with a destructor. Function 'test_destructor' takes one argument
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
  char *zVal;
  int len;
  sqlite3 *db = sqlite3_user_data(pCtx);
 
  test_destructor_count_var++;
  assert( nArg==1 );
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  len = sqlite3ValueBytes(argv[0], ENC(db)); 
  zVal = sqliteMalloc(len+3);
  zVal[len] = 0;
  zVal[len-1] = 0;
  assert( zVal );
  zVal++;
  memcpy(zVal, sqlite3ValueText(argv[0], ENC(db)), len);
  if( ENC(db)==SQLITE_UTF8 ){
    sqlite3_result_text(pCtx, zVal, -1, destructor);
#ifndef SQLITE_OMIT_UTF16
  }else if( ENC(db)==SQLITE_UTF16LE ){
    sqlite3_result_text16le(pCtx, zVal, -1, destructor);
  }else{
    sqlite3_result_text16be(pCtx, zVal, -1, destructor);
#endif /* SQLITE_OMIT_UTF16 */
  }
}
static void test_destructor_count(







|





|
|


|







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  char *zVal;
  int len;
  sqlite3 *db = sqlite3_user_data(pCtx);
 
  test_destructor_count_var++;
  assert( nArg==1 );
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  len = sqlite3ValueBytes(argv[0], db->enc); 
  zVal = sqliteMalloc(len+3);
  zVal[len] = 0;
  zVal[len-1] = 0;
  assert( zVal );
  zVal++;
  memcpy(zVal, sqlite3ValueText(argv[0], db->enc), len);
  if( db->enc==SQLITE_UTF8 ){
    sqlite3_result_text(pCtx, zVal, -1, destructor);
#ifndef SQLITE_OMIT_UTF16
  }else if( db->enc==SQLITE_UTF16LE ){
    sqlite3_result_text16le(pCtx, zVal, -1, destructor);
  }else{
    sqlite3_result_text16be(pCtx, zVal, -1, destructor);
#endif /* SQLITE_OMIT_UTF16 */
  }
}
static void test_destructor_count(
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
  int nArg,
  sqlite3_value **argv
){
  int i;
  char *zRet = sqliteMalloc(nArg*2);
  if( !zRet ) return;
  for(i=0; i<nArg; i++){
    char const *z = (char*)sqlite3_value_text(argv[i]);
    if( z ){
      char *zAux = sqlite3_get_auxdata(pCtx, i);
      if( zAux ){
        zRet[i*2] = '1';
        if( strcmp(zAux, z) ){
          sqlite3_result_error(pCtx, "Auxilary data corruption", -1);
          return;







|







766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
  int nArg,
  sqlite3_value **argv
){
  int i;
  char *zRet = sqliteMalloc(nArg*2);
  if( !zRet ) return;
  for(i=0; i<nArg; i++){
    char const *z = sqlite3_value_text(argv[i]);
    if( z ){
      char *zAux = sqlite3_get_auxdata(pCtx, i);
      if( zAux ){
        zRet[i*2] = '1';
        if( strcmp(zAux, z) ){
          sqlite3_result_error(pCtx, "Auxilary data corruption", -1);
          return;
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
** returns a copy of it's first argument as an error.
*/
static void test_error(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), 0);
}
#endif /* SQLITE_TEST */

/*
** An instance of the following structure holds the context of a
** sum() or avg() aggregate computation.
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
  double sum;     /* Sum of terms */
  int cnt;        /* Number of elements summed */
  u8 seenFloat;   /* True if there has been any floating point value */
};

/*
** Routines used to compute the sum, average, and total.
**
** The SUM() function follows the (broken) SQL standard which means
** that it returns NULL if it sums over no inputs.  TOTAL returns
** 0.0 in that case.  In addition, TOTAL always returns a float where
** SUM might return an integer if it never encounters a floating point
** value.
*/
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  SumCtx *p;
  int type;
  assert( argc==1 );
  p = sqlite3_aggregate_context(context, sizeof(*p));
  type = sqlite3_value_type(argv[0]);
  if( p && type!=SQLITE_NULL ){
    p->sum += sqlite3_value_double(argv[0]);
    p->cnt++;
    if( type==SQLITE_FLOAT ){
      p->seenFloat = 1;
    }
  }
}
static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){
    if( p->seenFloat ){
      sqlite3_result_double(context, p->sum);
    }else{
      sqlite3_result_int64(context, (i64)p->sum);
    }
  }
}
static void avgFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){
    sqlite3_result_double(context, p->sum/(double)p->cnt);
  }
}
static void totalFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  sqlite3_result_double(context, p ? p->sum : 0.0);
}

/*
** An instance of the following structure holds the context of a
** variance or standard deviation computation.
*/
typedef struct StdDevCtx StdDevCtx;
struct StdDevCtx {







|











<



|
<
<
<
<
<
<



<
|

|
<


<
<
<




|
<
<
|
<
<
<
<



|




<
<
<
<
<







797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815

816
817
818
819






820
821
822

823
824
825

826
827



828
829
830
831
832


833




834
835
836
837
838
839
840
841





842
843
844
845
846
847
848
** returns a copy of it's first argument as an error.
*/
static void test_error(
  sqlite3_context *pCtx, 
  int nArg,
  sqlite3_value **argv
){
  sqlite3_result_error(pCtx, sqlite3_value_text(argv[0]), 0);
}
#endif /* SQLITE_TEST */

/*
** An instance of the following structure holds the context of a
** sum() or avg() aggregate computation.
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
  double sum;     /* Sum of terms */
  int cnt;        /* Number of elements summed */

};

/*
** Routines used to compute the sum or average.






*/
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  SumCtx *p;

  if( argc<1 ) return;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p && SQLITE_NULL!=sqlite3_value_type(argv[0]) ){

    p->sum += sqlite3_value_double(argv[0]);
    p->cnt++;



  }
}
static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));


  sqlite3_result_double(context, p ? p->sum : 0.0);




}
static void avgFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p && p->cnt>0 ){
    sqlite3_result_double(context, p->sum/(double)p->cnt);
  }
}






/*
** An instance of the following structure holds the context of a
** variance or standard deviation computation.
*/
typedef struct StdDevCtx StdDevCtx;
struct StdDevCtx {
897
898
899
900
901
902
903
904
905
906










907
908
909
910
911
912
913
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
    p->n++;
  }
}   
static void countFinalize(sqlite3_context *context){
  CountCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  sqlite3_result_int(context, p ? p->n : 0);
}











/*
** Routines to implement min() and max() aggregate functions.
*/
static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  Mem *pArg  = (Mem *)argv[0];
  Mem *pBest;







|


>
>
>
>
>
>
>
>
>
>







868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
    p->n++;
  }
}   
static void countFinalize(sqlite3_context *context){
  CountCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  sqlite3_result_int(context, p ? p->n : 0);
}

/*
** This function tracks state information for the min() and max()
** aggregate functions.
*/
typedef struct MinMaxCtx MinMaxCtx;
struct MinMaxCtx {
  char *z;         /* The best so far */
  char zBuf[28];   /* Space that can be used for storage */
};

/*
** Routines to implement min() and max() aggregate functions.
*/
static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  Mem *pArg  = (Mem *)argv[0];
  Mem *pBest;
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
    }
  }else{
    sqlite3VdbeMemCopy(pBest, pArg);
  }
}
static void minMaxFinalize(sqlite3_context *context){
  sqlite3_value *pRes;
  pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
  if( pRes ){
    if( pRes->flags ){
      sqlite3_result_value(context, pRes);
    }
    sqlite3VdbeMemRelease(pRes);
  }
}


/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.







|
<
|
|
|
|
<







916
917
918
919
920
921
922
923

924
925
926
927

928
929
930
931
932
933
934
    }
  }else{
    sqlite3VdbeMemCopy(pBest, pArg);
  }
}
static void minMaxFinalize(sqlite3_context *context){
  sqlite3_value *pRes;
  pRes = (sqlite3_value *)sqlite3_aggregate_context(context, sizeof(Mem));

  if( pRes->flags ){
    sqlite3_result_value(context, pRes);
  }
  sqlite3VdbeMemRelease(pRes);

}


/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.
979
980
981
982
983
984
985



986
987
988
989
990
991
992
    { "upper",              1, 0, SQLITE_UTF8,    0, upperFunc  },
    { "lower",              1, 0, SQLITE_UTF8,    0, lowerFunc  },
    { "coalesce",          -1, 0, SQLITE_UTF8,    0, ifnullFunc },
    { "coalesce",           0, 0, SQLITE_UTF8,    0, 0          },
    { "coalesce",           1, 0, SQLITE_UTF8,    0, 0          },
    { "ifnull",             2, 0, SQLITE_UTF8,    1, ifnullFunc },
    { "random",            -1, 0, SQLITE_UTF8,    0, randomFunc },



    { "nullif",             2, 0, SQLITE_UTF8,    1, nullifFunc },
    { "sqlite_version",     0, 0, SQLITE_UTF8,    0, versionFunc},
    { "quote",              1, 0, SQLITE_UTF8,    0, quoteFunc  },
    { "last_insert_rowid",  0, 1, SQLITE_UTF8,    0, last_insert_rowid },
    { "changes",            0, 1, SQLITE_UTF8,    0, changes    },
    { "total_changes",      0, 1, SQLITE_UTF8,    0, total_changes },
#ifdef SQLITE_SOUNDEX







>
>
>







958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
    { "upper",              1, 0, SQLITE_UTF8,    0, upperFunc  },
    { "lower",              1, 0, SQLITE_UTF8,    0, lowerFunc  },
    { "coalesce",          -1, 0, SQLITE_UTF8,    0, ifnullFunc },
    { "coalesce",           0, 0, SQLITE_UTF8,    0, 0          },
    { "coalesce",           1, 0, SQLITE_UTF8,    0, 0          },
    { "ifnull",             2, 0, SQLITE_UTF8,    1, ifnullFunc },
    { "random",            -1, 0, SQLITE_UTF8,    0, randomFunc },
    { "like",               2, 0, SQLITE_UTF8,    0, likeFunc   },
    { "like",               3, 0, SQLITE_UTF8,    0, likeFunc   },
    { "glob",               2, 0, SQLITE_UTF8,    0, globFunc   },
    { "nullif",             2, 0, SQLITE_UTF8,    1, nullifFunc },
    { "sqlite_version",     0, 0, SQLITE_UTF8,    0, versionFunc},
    { "quote",              1, 0, SQLITE_UTF8,    0, quoteFunc  },
    { "last_insert_rowid",  0, 1, SQLITE_UTF8,    0, last_insert_rowid },
    { "changes",            0, 1, SQLITE_UTF8,    0, changes    },
    { "total_changes",      0, 1, SQLITE_UTF8,    0, total_changes },
#ifdef SQLITE_SOUNDEX
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
    u8 needCollSeq;
    void (*xStep)(sqlite3_context*,int,sqlite3_value**);
    void (*xFinalize)(sqlite3_context*);
  } aAggs[] = {
    { "min",    1, 0, 1, minmaxStep,   minMaxFinalize },
    { "max",    1, 2, 1, minmaxStep,   minMaxFinalize },
    { "sum",    1, 0, 0, sumStep,      sumFinalize    },
    { "total",  1, 0, 0, sumStep,      totalFinalize    },
    { "avg",    1, 0, 0, sumStep,      avgFinalize    },
    { "count",  0, 0, 0, countStep,    countFinalize  },
    { "count",  1, 0, 0, countStep,    countFinalize  },
  };
  int i;

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){







<







989
990
991
992
993
994
995

996
997
998
999
1000
1001
1002
    u8 needCollSeq;
    void (*xStep)(sqlite3_context*,int,sqlite3_value**);
    void (*xFinalize)(sqlite3_context*);
  } aAggs[] = {
    { "min",    1, 0, 1, minmaxStep,   minMaxFinalize },
    { "max",    1, 2, 1, minmaxStep,   minMaxFinalize },
    { "sum",    1, 0, 0, sumStep,      sumFinalize    },

    { "avg",    1, 0, 0, sumStep,      avgFinalize    },
    { "count",  0, 0, 0, countStep,    countFinalize  },
    { "count",  1, 0, 0, countStep,    countFinalize  },
  };
  int i;

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
        pFunc->needCollSeq = 1;
      }
    }
  }
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions(db);
#endif
#ifndef SQLITE_OMIT_PARSER
  sqlite3AttachFunctions(db);
#endif
  for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
    void *pArg = 0;
    switch( aAggs[i].argType ){
      case 1: pArg = db; break;
      case 2: pArg = (void *)(-1); break;
    }
    sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
        pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
    if( aAggs[i].needCollSeq ){
      FuncDef *pFunc = sqlite3FindFunction( db, aAggs[i].zName,
          strlen(aAggs[i].zName), aAggs[i].nArg, SQLITE_UTF8, 0);
      if( pFunc && aAggs[i].needCollSeq ){
        pFunc->needCollSeq = 1;
      }
    }
  }
  sqlite3RegisterDateTimeFunctions(db);
#ifdef SQLITE_SSE
  sqlite3SseFunctions(db);
#endif
#ifdef SQLITE_CASE_SENSITIVE_LIKE
  sqlite3RegisterLikeFunctions(db, 1);
#else
  sqlite3RegisterLikeFunctions(db, 0);
#endif
}

/*
** Set the LIKEOPT flag on the 2-argument function with the given name.
*/
static void setLikeOptFlag(sqlite3 *db, const char *zName, int flagVal){
  FuncDef *pDef;
  pDef = sqlite3FindFunction(db, zName, strlen(zName), 2, SQLITE_UTF8, 0);
  if( pDef ){
    pDef->flags = flagVal;
  }
}

/*
** Register the built-in LIKE and GLOB functions.  The caseSensitive
** parameter determines whether or not the LIKE operator is case
** sensitive.  GLOB is always case sensitive.
*/
void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
  struct compareInfo *pInfo;
  if( caseSensitive ){
    pInfo = (struct compareInfo*)&likeInfoAlt;
  }else{
    pInfo = (struct compareInfo*)&likeInfoNorm;
  }
  sqlite3_create_function(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
  sqlite3_create_function(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
  sqlite3_create_function(db, "glob", 2, SQLITE_UTF8, 
      (struct compareInfo*)&globInfo, likeFunc, 0,0);
  setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
  setLikeOptFlag(db, "like", 
      caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
}

/*
** pExpr points to an expression which implements a function.  If
** it is appropriate to apply the LIKE optimization to that function
** then set aWc[0] through aWc[2] to the wildcard characters and
** return TRUE.  If the function is not a LIKE-style function then
** return FALSE.
*/
int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
  FuncDef *pDef;
  if( pExpr->op!=TK_FUNCTION ){
    return 0;
  }
  if( pExpr->pList->nExpr!=2 ){
    return 0;
  }
  pDef = sqlite3FindFunction(db, (char*)pExpr->token.z, pExpr->token.n, 2,
                             SQLITE_UTF8, 0);
  if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
    return 0;
  }

  /* The memcpy() statement assumes that the wildcard characters are
  ** the first three statements in the compareInfo structure.  The
  ** asserts() that follow verify that assumption
  */
  memcpy(aWc, pDef->pUserData, 3);
  assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
  assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
  assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
  *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;
  return 1;
}







<
<
<

















<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1014
1015
1016
1017
1018
1019
1020



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








1038

































































        pFunc->needCollSeq = 1;
      }
    }
  }
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions(db);
#endif



  for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
    void *pArg = 0;
    switch( aAggs[i].argType ){
      case 1: pArg = db; break;
      case 2: pArg = (void *)(-1); break;
    }
    sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
        pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
    if( aAggs[i].needCollSeq ){
      FuncDef *pFunc = sqlite3FindFunction( db, aAggs[i].zName,
          strlen(aAggs[i].zName), aAggs[i].nArg, SQLITE_UTF8, 0);
      if( pFunc && aAggs[i].needCollSeq ){
        pFunc->needCollSeq = 1;
      }
    }
  }
  sqlite3RegisterDateTimeFunctions(db);








}

































































Changes to SQLite.Interop/src/hash.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.1 2005/03/01 16:04:29 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
    pEntry->chain = 0;
  }
  if( pH->copyKey && elem->pKey ){
    sqliteFree(elem->pKey);
  }
  sqliteFree( elem );
  pH->count--;
  if( pH->count<=0 ){
    assert( pH->first==0 );
    assert( pH->count==0 );
    sqlite3HashClear(pH);
  }
}

/* Attempt to locate an element of the hash table pH with a key
** that matches pKey,nKey.  Return the data for this element if it is
** found, or NULL if there is no match.
*/
void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){







<
<
<
<
<







290
291
292
293
294
295
296





297
298
299
300
301
302
303
    pEntry->chain = 0;
  }
  if( pH->copyKey && elem->pKey ){
    sqliteFree(elem->pKey);
  }
  sqliteFree( elem );
  pH->count--;





}

/* Attempt to locate an element of the hash table pH with a key
** that matches pKey,nKey.  Return the data for this element if it is
** found, or NULL if there is no match.
*/
void *sqlite3HashFind(const Hash *pH, const void *pKey, int nKey){
Changes to SQLite.Interop/src/hash.h.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the header file for the generic hash-table implemenation
** used in SQLite.
**
** $Id: hash.h,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_

/* Forward declarations of structures. */
typedef struct Hash Hash;
typedef struct HashElem HashElem;







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the header file for the generic hash-table implemenation
** used in SQLite.
**
** $Id: hash.h,v 1.1 2005/03/01 16:04:29 rmsimpson Exp $
*/
#ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_

/* Forward declarations of structures. */
typedef struct Hash Hash;
typedef struct HashElem HashElem;
Changes to SQLite.Interop/src/insert.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** Set P3 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
**
**  Character      Column affinity
**  ------------------------------
**  'a'            TEXT
**  'b'            NONE
**  'c'            NUMERIC
**  'd'            INTEGER
**  'e'            REAL
*/
void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
  if( !pIdx->zColAff ){
    /* The first time a column affinity string for a particular index is
    ** required, it is allocated and populated here. It is then stored as
    ** a member of the Index structure for subsequent use.
    **







|










|
|
|
<
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.1 2005/03/01 16:04:30 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** Set P3 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
**
**  Character      Column affinity
**  ------------------------------
**  'n'            NUMERIC
**  'i'            INTEGER
**  't'            TEXT

**  'o'            NONE
*/
void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
  if( !pIdx->zColAff ){
    /* The first time a column affinity string for a particular index is
    ** required, it is allocated and populated here. It is then stored as
    ** a member of the Index structure for subsequent use.
    **
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
** Set P3 of the most recently inserted opcode to a column affinity
** string for table pTab. A column affinity string has one character
** for each column indexed by the index, according to the affinity of the
** column:
**
**  Character      Column affinity
**  ------------------------------
**  'a'            TEXT
**  'b'            NONE
**  'c'            NUMERIC
**  'd'            INTEGER
**  'e'            REAL
*/
void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
  /* The first time a column affinity string for a particular table
  ** is required, it is allocated and populated here. It is then 
  ** stored as a member of the Table structure for subsequent use.
  **
  ** The column affinity string will eventually be deleted by







|
|
|
<
|







57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
** Set P3 of the most recently inserted opcode to a column affinity
** string for table pTab. A column affinity string has one character
** for each column indexed by the index, according to the affinity of the
** column:
**
**  Character      Column affinity
**  ------------------------------
**  'n'            NUMERIC
**  'i'            INTEGER
**  't'            TEXT

**  'o'            NONE
*/
void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
  /* The first time a column affinity string for a particular table
  ** is required, it is allocated and populated here. It is then 
  ** stored as a member of the Table structure for subsequent use.
  **
  ** The column affinity string will eventually be deleted by
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
** Return non-zero if SELECT statement p opens the table with rootpage
** iTab in database iDb.  This is used to see if a statement of the form 
** "INSERT INTO <iDb, iTab> SELECT ..." can run without using temporary
** table for the results of the SELECT. 
**
** No checking is done for sub-selects that are part of expressions.
*/
static int selectReadsTable(Select *p, Schema *pSchema, int iTab){
  int i;
  struct SrcList_item *pItem;
  if( p->pSrc==0 ) return 0;
  for(i=0, pItem=p->pSrc->a; i<p->pSrc->nSrc; i++, pItem++){
    if( pItem->pSelect ){
      if( selectReadsTable(pItem->pSelect, pSchema, iTab) ) return 1;
    }else{
      if( pItem->pTab->pSchema==pSchema && pItem->pTab->tnum==iTab ) return 1;
    }
  }
  return 0;
}

/*
** This routine is call to handle SQL of the following forms:







|





|

|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
** Return non-zero if SELECT statement p opens the table with rootpage
** iTab in database iDb.  This is used to see if a statement of the form 
** "INSERT INTO <iDb, iTab> SELECT ..." can run without using temporary
** table for the results of the SELECT. 
**
** No checking is done for sub-selects that are part of expressions.
*/
static int selectReadsTable(Select *p, int iDb, int iTab){
  int i;
  struct SrcList_item *pItem;
  if( p->pSrc==0 ) return 0;
  for(i=0, pItem=p->pSrc->a; i<p->pSrc->nSrc; i++, pItem++){
    if( pItem->pSelect ){
      if( selectReadsTable(p, iDb, iTab) ) return 1;
    }else{
      if( pItem->pTab->iDb==iDb && pItem->pTab->tnum==iTab ) return 1;
    }
  }
  return 0;
}

/*
** This routine is call to handle SQL of the following forms:
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
  int iSelectLoop = 0;  /* Address of code that implements the SELECT */
  int iCleanup = 0;     /* Address of the cleanup code */
  int iInsertBlock = 0; /* Address of the subroutine used to insert data */
  int iCntMem = 0;      /* Memory cell used for the row counter */
  int newIdx = -1;      /* Cursor for the NEW table */
  Db *pDb;              /* The database containing table being inserted into */
  int counterMem = 0;   /* Memory cell holding AUTOINCREMENT counter */
  int iDb;

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                 /* True if attempting to insert into a view */
  int triggers_exist = 0;     /* True if there are FOR EACH ROW triggers */
#endif

#ifndef SQLITE_OMIT_AUTOINCREMENT
  int counterRowid;     /* Memory cell holding rowid of autoinc counter */
#endif

  if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
    goto insert_cleanup;
  }
  db = pParse->db;

  /* Locate the table into which we will be inserting new information.
  */
  assert( pTabList->nSrc==1 );
  zTab = pTabList->a[0].zName;
  if( zTab==0 ) goto insert_cleanup;
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 ){
    goto insert_cleanup;
  }
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iDb<db->nDb );
  pDb = &db->aDb[iDb];
  zDb = pDb->zName;
  if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
    goto insert_cleanup;
  }

  /* Figure out if we have any triggers and if the table being
  ** inserted into is a view







<










<
|
<











<
|
|







208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224

225

226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
  int iSelectLoop = 0;  /* Address of code that implements the SELECT */
  int iCleanup = 0;     /* Address of the cleanup code */
  int iInsertBlock = 0; /* Address of the subroutine used to insert data */
  int iCntMem = 0;      /* Memory cell used for the row counter */
  int newIdx = -1;      /* Cursor for the NEW table */
  Db *pDb;              /* The database containing table being inserted into */
  int counterMem = 0;   /* Memory cell holding AUTOINCREMENT counter */


#ifndef SQLITE_OMIT_TRIGGER
  int isView;                 /* True if attempting to insert into a view */
  int triggers_exist = 0;     /* True if there are FOR EACH ROW triggers */
#endif

#ifndef SQLITE_OMIT_AUTOINCREMENT
  int counterRowid;     /* Memory cell holding rowid of autoinc counter */
#endif


  if( pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;

  db = pParse->db;

  /* Locate the table into which we will be inserting new information.
  */
  assert( pTabList->nSrc==1 );
  zTab = pTabList->a[0].zName;
  if( zTab==0 ) goto insert_cleanup;
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 ){
    goto insert_cleanup;
  }

  assert( pTab->iDb<db->nDb );
  pDb = &db->aDb[pTab->iDb];
  zDb = pDb->zName;
  if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
    goto insert_cleanup;
  }

  /* Figure out if we have any triggers and if the table being
  ** inserted into is a view
272
273
274
275
276
277
278







279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302

303

304
305
306
307
308
309
310
311
312
313
314
315
  if( pTab==0 ) goto insert_cleanup;

  /* If pTab is really a view, make sure it has been initialized.
  */
  if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto insert_cleanup;
  }








  /* Allocate a VDBE
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto insert_cleanup;
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, iDb);

  /* if there are row triggers, allocate a temp table for new.* references. */
  if( triggers_exist ){
    newIdx = pParse->nTab++;
  }

#ifndef SQLITE_OMIT_AUTOINCREMENT
  /* If this is an AUTOINCREMENT table, look up the sequence number in the
  ** sqlite_sequence table and store it in memory cell counterMem.  Also
  ** remember the rowid of the sqlite_sequence table entry in memory cell
  ** counterRowid.
  */
  if( pTab->autoInc ){
    int iCur = pParse->nTab;
    int base = sqlite3VdbeCurrentAddr(v);
    counterRowid = pParse->nMem++;
    counterMem = pParse->nMem++;

    sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead);

    sqlite3VdbeAddOp(v, OP_Rewind, iCur, base+13);
    sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
    sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp(v, OP_Ne, 0x100, base+12);
    sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1);
    sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
    sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1);
    sqlite3VdbeAddOp(v, OP_Goto, 0, base+13);
    sqlite3VdbeAddOp(v, OP_Next, iCur, base+4);
    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
  }







>
>
>
>
>
>
>






|

















>
|
>



|
|







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  if( pTab==0 ) goto insert_cleanup;

  /* If pTab is really a view, make sure it has been initialized.
  */
  if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto insert_cleanup;
  }

  /* Ensure all required collation sequences are available. */
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
      goto insert_cleanup;
    }
  }

  /* Allocate a VDBE
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto insert_cleanup;
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, pTab->iDb);

  /* if there are row triggers, allocate a temp table for new.* references. */
  if( triggers_exist ){
    newIdx = pParse->nTab++;
  }

#ifndef SQLITE_OMIT_AUTOINCREMENT
  /* If this is an AUTOINCREMENT table, look up the sequence number in the
  ** sqlite_sequence table and store it in memory cell counterMem.  Also
  ** remember the rowid of the sqlite_sequence table entry in memory cell
  ** counterRowid.
  */
  if( pTab->autoInc ){
    int iCur = pParse->nTab;
    int base = sqlite3VdbeCurrentAddr(v);
    counterRowid = pParse->nMem++;
    counterMem = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pDb->pSeqTab->tnum);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
    sqlite3VdbeAddOp(v, OP_Rewind, iCur, base+13);
    sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
    sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12);
    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1);
    sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
    sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1);
    sqlite3VdbeAddOp(v, OP_Goto, 0, base+13);
    sqlite3VdbeAddOp(v, OP_Next, iCur, base+4);
    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
  }
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
    int rc, iInitCode;
    iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
    iSelectLoop = sqlite3VdbeCurrentAddr(v);
    iInsertBlock = sqlite3VdbeMakeLabel(v);

    /* Resolve the expressions in the SELECT statement and execute it. */
    rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0);
    if( rc || pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
      goto insert_cleanup;
    }

    iCleanup = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
    assert( pSelect->pEList );
    nColumn = pSelect->pEList->nExpr;

    /* Set useTempTable to TRUE if the result of the SELECT statement
    ** should be written into a temporary table.  Set to FALSE if each
    ** row of the SELECT can be written directly into the result table.
    **
    ** A temp table must be used if the table being updated is also one
    ** of the tables being read by the SELECT statement.  Also use a 
    ** temp table in the case of row triggers.
    */
    if( triggers_exist || selectReadsTable(pSelect,pTab->pSchema,pTab->tnum) ){
      useTempTable = 1;
    }

    if( useTempTable ){
      /* Generate the subroutine that SELECT calls to process each row of
      ** the result.  Store the result in a temporary table
      */
      srcTab = pParse->nTab++;
      sqlite3VdbeResolveLabel(v, iInsertBlock);
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);

      sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_Insert, srcTab, 0);
      sqlite3VdbeAddOp(v, OP_Return, 0, 0);

      /* The following code runs first because the GOTO at the very top
      ** of the program jumps to it.  Create the temporary table, then jump
      ** back up and execute the SELECT code above.
      */
      sqlite3VdbeJumpHere(v, iInitCode);
      sqlite3VdbeAddOp(v, OP_OpenVirtual, srcTab, 0);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn);
      sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
      sqlite3VdbeResolveLabel(v, iCleanup);
    }else{
      sqlite3VdbeJumpHere(v, iInitCode);
    }
  }else{
    /* This is the case if the data for the INSERT is coming from a VALUES
    ** clause
    */
    NameContext sNC;
    memset(&sNC, 0, sizeof(sNC));







|
<
<














|










>
|

|






|
|




|







332
333
334
335
336
337
338
339


340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
    int rc, iInitCode;
    iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
    iSelectLoop = sqlite3VdbeCurrentAddr(v);
    iInsertBlock = sqlite3VdbeMakeLabel(v);

    /* Resolve the expressions in the SELECT statement and execute it. */
    rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0);
    if( rc || pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;



    iCleanup = sqlite3VdbeMakeLabel(v);
    sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
    assert( pSelect->pEList );
    nColumn = pSelect->pEList->nExpr;

    /* Set useTempTable to TRUE if the result of the SELECT statement
    ** should be written into a temporary table.  Set to FALSE if each
    ** row of the SELECT can be written directly into the result table.
    **
    ** A temp table must be used if the table being updated is also one
    ** of the tables being read by the SELECT statement.  Also use a 
    ** temp table in the case of row triggers.
    */
    if( triggers_exist || selectReadsTable(pSelect, pTab->iDb, pTab->tnum) ){
      useTempTable = 1;
    }

    if( useTempTable ){
      /* Generate the subroutine that SELECT calls to process each row of
      ** the result.  Store the result in a temporary table
      */
      srcTab = pParse->nTab++;
      sqlite3VdbeResolveLabel(v, iInsertBlock);
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
      sqlite3TableAffinityStr(v, pTab);
      sqlite3VdbeAddOp(v, OP_NewRecno, srcTab, 0);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_PutIntKey, srcTab, 0);
      sqlite3VdbeAddOp(v, OP_Return, 0, 0);

      /* The following code runs first because the GOTO at the very top
      ** of the program jumps to it.  Create the temporary table, then jump
      ** back up and execute the SELECT code above.
      */
      sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
      sqlite3VdbeAddOp(v, OP_OpenTemp, srcTab, 0);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn);
      sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
      sqlite3VdbeResolveLabel(v, iCleanup);
    }else{
      sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
    }
  }else{
    /* This is the case if the data for the INSERT is coming from a VALUES
    ** clause
    */
    NameContext sNC;
    memset(&sNC, 0, sizeof(sNC));
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478
    sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
  }
    
  /* Initialize the count of rows to be inserted
  */
  if( db->flags & SQLITE_CountRows ){
    iCntMem = pParse->nMem++;

    sqlite3VdbeAddOp(v, OP_MemInt, 0, iCntMem);
  }

  /* Open tables and indices if there are no row triggers */
  if( !triggers_exist ){
    base = pParse->nTab;
    sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
  }







>
|







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
    sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
  }
    
  /* Initialize the count of rows to be inserted
  */
  if( db->flags & SQLITE_CountRows ){
    iCntMem = pParse->nMem++;
    sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iCntMem, 1);
  }

  /* Open tables and indices if there are no row triggers */
  if( !triggers_exist ){
    base = pParse->nTab;
    sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
  }
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
    ** do not attempt any conversions before assembling the record.
    ** If this is a real table, attempt conversions as required by the
    ** table column affinities.
    */
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
    }
    sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);

    /* Fire BEFORE or INSTEAD OF triggers */
    if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, 
        newIdx, -1, onError, endOfLoop) ){
      goto insert_cleanup;
    }
  }

  /* If any triggers exists, the opening of tables and indices is deferred
  ** until now.
  */
  if( triggers_exist && !isView ){
    base = pParse->nTab;
    sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
  }

  /* Push the record number for the new entry onto the stack.  The
  ** record number is a randomly generate integer created by NewRowid
  ** except when the table has an INTEGER PRIMARY KEY column, in which
  ** case the record number is the same as that column. 
  */
  if( !isView ){
    if( keyColumn>=0 ){
      if( useTempTable ){
        sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
      }else if( pSelect ){
        sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
      }else{
        sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
      }
      /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
      ** to generate a unique primary key value.
      */
      sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    }else{
      sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
    }
#ifndef SQLITE_OMIT_AUTOINCREMENT
    if( pTab->autoInc ){
      sqlite3VdbeAddOp(v, OP_MemMax, counterMem, 0);
    }
#endif /* SQLITE_OMIT_AUTOINCREMENT */

    /* Push onto the stack, data for all columns of the new entry, beginning
    ** with the first column.
    */
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        /* The value of the INTEGER PRIMARY KEY column is always a NULL.
        ** Whenever this column is read, the record number will be substituted
        ** in its place.  So will fill this column with a NULL to avoid
        ** taking up data space with information that will never be used. */
        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
        continue;
      }
      if( pColumn==0 ){
        j = i;
      }else{
        for(j=0; j<pColumn->nId; j++){
          if( pColumn->a[j].idx==i ) break;







|

















|












|




|


|
















|







543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
    ** do not attempt any conversions before assembling the record.
    ** If this is a real table, attempt conversions as required by the
    ** table column affinities.
    */
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
    }
    sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);

    /* Fire BEFORE or INSTEAD OF triggers */
    if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, 
        newIdx, -1, onError, endOfLoop) ){
      goto insert_cleanup;
    }
  }

  /* If any triggers exists, the opening of tables and indices is deferred
  ** until now.
  */
  if( triggers_exist && !isView ){
    base = pParse->nTab;
    sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
  }

  /* Push the record number for the new entry onto the stack.  The
  ** record number is a randomly generate integer created by NewRecno
  ** except when the table has an INTEGER PRIMARY KEY column, in which
  ** case the record number is the same as that column. 
  */
  if( !isView ){
    if( keyColumn>=0 ){
      if( useTempTable ){
        sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
      }else if( pSelect ){
        sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
      }else{
        sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
      }
      /* If the PRIMARY KEY expression is NULL, then use OP_NewRecno
      ** to generate a unique primary key value.
      */
      sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    }else{
      sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
    }
#ifndef SQLITE_OMIT_AUTOINCREMENT
    if( pTab->autoInc ){
      sqlite3VdbeAddOp(v, OP_MemMax, counterMem, 0);
    }
#endif /* SQLITE_OMIT_AUTOINCREMENT */

    /* Push onto the stack, data for all columns of the new entry, beginning
    ** with the first column.
    */
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        /* The value of the INTEGER PRIMARY KEY column is always a NULL.
        ** Whenever this column is read, the record number will be substituted
        ** in its place.  So will fill this column with a NULL to avoid
        ** taking up data space with information that will never be used. */
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
        continue;
      }
      if( pColumn==0 ){
        j = i;
      }else{
        for(j=0; j<pColumn->nId; j++){
          if( pColumn->a[j].idx==i ) break;
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
    sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
                            (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1);
  }

  /* Update the count of rows that are inserted
  */
  if( (db->flags & SQLITE_CountRows)!=0 ){
    sqlite3VdbeAddOp(v, OP_MemIncr, 1, iCntMem);
  }

  if( triggers_exist ){
    /* Close all tables opened */
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Close, base, 0);
      for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){







|







632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
    sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
                            (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1);
  }

  /* Update the count of rows that are inserted
  */
  if( (db->flags & SQLITE_CountRows)!=0 ){
    sqlite3VdbeAddOp(v, OP_MemIncr, iCntMem, 0);
  }

  if( triggers_exist ){
    /* Close all tables opened */
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Close, base, 0);
      for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
677
678
679
680
681
682
683

684

685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
  /* Update the sqlite_sequence table by storing the content of the
  ** counter value in memory counterMem back into the sqlite_sequence
  ** table.
  */
  if( pTab->autoInc ){
    int iCur = pParse->nTab;
    int base = sqlite3VdbeCurrentAddr(v);

    sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);

    sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
    sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7);
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0);
    sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0);
    sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
    sqlite3VdbeAddOp(v, OP_Insert, iCur, 0);
    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
  }
#endif

  /*
  ** Return the number of rows inserted. If this routine is 
  ** generating code because of a call to sqlite3NestedParse(), do not
  ** invoke the callback function.
  */
  if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
    sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
    sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
  }

insert_cleanup:
  sqlite3SrcListDelete(pTabList);
  sqlite3ExprListDelete(pList);
  sqlite3SelectDelete(pSelect);
  sqlite3IdListDelete(pColumn);
}

/*
** Generate code to do a constraint check prior to an INSERT or an UPDATE.
**
** When this routine is called, the stack contains (from bottom to top)
** the following values:
**
**    1.  The rowid of the row to be updated before the update.  This
**        value is omitted unless we are doing an UPDATE that involves a
**        change to the record number.
**
**    2.  The rowid of the row after the update.
**
**    3.  The data in the first column of the entry after the update.
**
**    i.  Data from middle columns...
**
**    N.  The data in the last column of the entry after the update.
**
** The old rowid shown as entry (1) above is omitted unless both isUpdate
** and rowidChng are 1.  isUpdate is true for UPDATEs and false for
** INSERTs and rowidChng is true if the record number is being changed.
**
** The code generated by this routine pushes additional entries onto
** the stack which are the keys for new index entries for the new record.
** The order of index keys is the same as the order of the indices on
** the pTable->pIndex list.  A key is only created for index i if 
** aIdxUsed!=0 and aIdxUsed[i]!=0.
**







>
|
>



|



|


















|
|









|



|







|
|
|







680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
  /* Update the sqlite_sequence table by storing the content of the
  ** counter value in memory counterMem back into the sqlite_sequence
  ** table.
  */
  if( pTab->autoInc ){
    int iCur = pParse->nTab;
    int base = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pDb->pSeqTab->tnum);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
    sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
    sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7);
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp(v, OP_NewRecno, iCur, 0);
    sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0);
    sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, iCur, 0);
    sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
  }
#endif

  /*
  ** Return the number of rows inserted. If this routine is 
  ** generating code because of a call to sqlite3NestedParse(), do not
  ** invoke the callback function.
  */
  if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
    sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
    sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
  }

insert_cleanup:
  sqlite3SrcListDelete(pTabList);
  if( pList ) sqlite3ExprListDelete(pList);
  if( pSelect ) sqlite3SelectDelete(pSelect);
  sqlite3IdListDelete(pColumn);
}

/*
** Generate code to do a constraint check prior to an INSERT or an UPDATE.
**
** When this routine is called, the stack contains (from bottom to top)
** the following values:
**
**    1.  The recno of the row to be updated before the update.  This
**        value is omitted unless we are doing an UPDATE that involves a
**        change to the record number.
**
**    2.  The recno of the row after the update.
**
**    3.  The data in the first column of the entry after the update.
**
**    i.  Data from middle columns...
**
**    N.  The data in the last column of the entry after the update.
**
** The old recno shown as entry (1) above is omitted unless both isUpdate
** and recnoChng are 1.  isUpdate is true for UPDATEs and false for
** INSERTs and recnoChng is true if the record number is being changed.
**
** The code generated by this routine pushes additional entries onto
** the stack which are the keys for new index entries for the new record.
** The order of index keys is the same as the order of the indices on
** the pTable->pIndex list.  A key is only created for index i if 
** aIdxUsed!=0 and aIdxUsed[i]!=0.
**
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814

815
816
817
818
819
820
821
822
** Without the isUpdate flag, the "base" cursor might be moved.
*/
void sqlite3GenerateConstraintChecks(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int base,           /* Index of a read/write cursor pointing at pTab */
  char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
  int rowidChng,      /* True if the record number will change */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int overrideError,  /* Override onError to this if not OE_Default */
  int ignoreDest      /* Jump to this label on an OE_Ignore resolution */
){
  int i;
  Vdbe *v;
  int nCol;
  int onError;
  int addr;
  int extra;
  int iCur;
  Index *pIdx;
  int seenReplace = 0;
  int jumpInst1=0, jumpInst2;

  int hasTwoRowids = (isUpdate && rowidChng);

  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  nCol = pTab->nCol;

  /* Test all NOT NULL constraints.







|














>
|







798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
** Without the isUpdate flag, the "base" cursor might be moved.
*/
void sqlite3GenerateConstraintChecks(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int base,           /* Index of a read/write cursor pointing at pTab */
  char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
  int recnoChng,      /* True if the record number will change */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int overrideError,  /* Override onError to this if not OE_Default */
  int ignoreDest      /* Jump to this label on an OE_Ignore resolution */
){
  int i;
  Vdbe *v;
  int nCol;
  int onError;
  int addr;
  int extra;
  int iCur;
  Index *pIdx;
  int seenReplace = 0;
  int jumpInst1=0, jumpInst2;
  int contAddr;
  int hasTwoRecnos = (isUpdate && recnoChng);

  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  nCol = pTab->nCol;

  /* Test all NOT NULL constraints.
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
        sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
        sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
                        " may not be NULL", (char*)0);
        sqlite3VdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
        break;
      }
      case OE_Ignore: {
        sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
        sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
        break;
      }
      case OE_Replace: {
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
        sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0);
        break;
      }
    }
    sqlite3VdbeJumpHere(v, addr);
  }

  /* Test all CHECK constraints
  */
#ifndef SQLITE_OMIT_CHECK
  if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){
    int allOk = sqlite3VdbeMakeLabel(v);
    assert( pParse->ckOffset==0 );
    pParse->ckOffset = nCol;
    sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, 1);
    assert( pParse->ckOffset==nCol );
    pParse->ckOffset = 0;
    sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort);
    sqlite3VdbeResolveLabel(v, allOk);
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */

  /* If we have an INTEGER PRIMARY KEY, make sure the primary key
  ** of the new record does not previously exist.  Except, if this
  ** is an UPDATE and the primary key is not changing, that is OK.
  */
  if( rowidChng ){
    onError = pTab->keyConf;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    







|









|




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





|







853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875











876
877
878
879
880
881
882
883
884
885
886
887
888
        sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
        sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
                        " may not be NULL", (char*)0);
        sqlite3VdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
        break;
      }
      case OE_Ignore: {
        sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
        sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
        break;
      }
      case OE_Replace: {
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
        sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0);
        break;
      }
    }
    sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
  }

  /* Test all CHECK constraints
  */
  /**** TBD ****/












  /* If we have an INTEGER PRIMARY KEY, make sure the primary key
  ** of the new record does not previously exist.  Except, if this
  ** is an UPDATE and the primary key is not changing, that is OK.
  */
  if( recnoChng ){
    onError = pTab->keyConf;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928

929
930
931
932
933
934
935
936
937
938
        sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
                         "PRIMARY KEY must be unique", P3_STATIC);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
        if( isUpdate ){
          sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1);
          sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
        }
        seenReplace = 1;
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
        sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
        break;
      }
    }

    sqlite3VdbeJumpHere(v, jumpInst2);
    if( isUpdate ){
      sqlite3VdbeJumpHere(v, jumpInst1);
      sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
      sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
    }
  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.







|







|




>
|

|







904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
        sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
                         "PRIMARY KEY must be unique", P3_STATIC);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
        if( isUpdate ){
          sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1);
          sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
        }
        seenReplace = 1;
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
        sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
        break;
      }
    }
    contAddr = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeChangeP2(v, jumpInst2, contAddr);
    if( isUpdate ){
      sqlite3VdbeChangeP2(v, jumpInst1, contAddr);
      sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
      sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
    }
  }

  /* Test all UNIQUE constraints by creating entries for each UNIQUE
  ** index and making sure that duplicate entries do not already exist.
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
      int idx = pIdx->aiColumn[i];
      if( idx==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
      }else{
        sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
      }
    }
    jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0);
    sqlite3IndexAffinityStr(v, pIdx);

    /* Find out what action to take in case there is an indexing conflict */
    onError = pIdx->onError;
    if( onError==OE_None ) continue;  /* pIdx is not a UNIQUE index */
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    if( seenReplace ){
      if( onError==OE_Ignore ) onError = OE_Replace;
      else if( onError==OE_Fail ) onError = OE_Abort;
    }
    

    /* Check to see if the new index entry will be unique */
    sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1);
    jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);

    /* Generate code that executes if the new index entry is not unique */
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
        || onError==OE_Ignore || onError==OE_Replace );
    switch( onError ){
      case OE_Rollback:







|

















|







945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
      int idx = pIdx->aiColumn[i];
      if( idx==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
      }else{
        sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
      }
    }
    jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24));
    sqlite3IndexAffinityStr(v, pIdx);

    /* Find out what action to take in case there is an indexing conflict */
    onError = pIdx->onError;
    if( onError==OE_None ) continue;  /* pIdx is not a UNIQUE index */
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
    }
    if( seenReplace ){
      if( onError==OE_Ignore ) onError = OE_Replace;
      else if( onError==OE_Fail ) onError = OE_Abort;
    }
    

    /* Check to see if the new index entry will be unique */
    sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
    jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);

    /* Generate code that executes if the new index entry is not unique */
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
        || onError==OE_Ignore || onError==OE_Replace );
    switch( onError ){
      case OE_Rollback:
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024


1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105

1106


1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
        strcpy(&zErrMsg[n1], 
            pIdx->nColumn>1 ? " are not unique" : " is not unique");
        sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0);
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0);
        sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0);
        if( isUpdate ){
          sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1);
          sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
        }
        seenReplace = 1;
        break;
      }
    }


#if NULL_DISTINCT_FOR_UNIQUE
    sqlite3VdbeJumpHere(v, jumpInst1);
#endif
    sqlite3VdbeJumpHere(v, jumpInst2);
  }
}

/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite3GenerateConstraintChecks.
** The stack must contain keys for all active indices followed by data
** and the rowid for the new entry.  This routine creates the new
** entries in all indices and in the main table.
**
** The arguments to this routine should be the same as the first six
** arguments to sqlite3GenerateConstraintChecks.
*/
void sqlite3CompleteInsertion(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int base,           /* Index of a read/write cursor pointing at pTab */
  char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
  int rowidChng,      /* True if the record number will change */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int newIdx          /* Index of NEW table for triggers.  -1 if none */
){
  int i;
  Vdbe *v;
  int nIdx;
  Index *pIdx;
  int pik_flags;

  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  for(i=nIdx-1; i>=0; i--){
    if( aIdxUsed && aIdxUsed[i]==0 ) continue;
    sqlite3VdbeAddOp(v, OP_IdxInsert, base+i+1, 0);
  }
  sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
  sqlite3TableAffinityStr(v, pTab);
#ifndef SQLITE_OMIT_TRIGGER
  if( newIdx>=0 ){
    sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
    sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
    sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
  }
#endif
  if( pParse->nested ){
    pik_flags = 0;
  }else{
    pik_flags = OPFLAG_NCHANGE;
    pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
  }
  sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags);
  if( !pParse->nested ){
    sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
  }
  
  if( isUpdate && rowidChng ){
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
  }
}

/*
** Generate code that will open cursors for a table and for all
** indices of that table.  The "base" parameter is the cursor number used
** for the table.  Indices are opened on subsequent cursors.
*/
void sqlite3OpenTableAndIndices(
  Parse *pParse,   /* Parsing context */
  Table *pTab,     /* Table to be opened */
  int base,        /* Cursor number assigned to the table */
  int op           /* OP_OpenRead or OP_OpenWrite */
){
  int i;
  int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  Index *pIdx;
  Vdbe *v = sqlite3GetVdbe(pParse);
  assert( v!=0 );

  sqlite3OpenTable(pParse, base, iDb, pTab, op);


  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
    assert( pIdx->pSchema==pTab->pSchema );
    sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
    VdbeComment((v, "# %s", pIdx->zName));
    sqlite3VdbeOp3(v, op, i+base, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF);

  }
  if( pParse->nTab<=base+i ){
    pParse->nTab = base+i;
  }
}







|






|






>
>

|

|







|










|















|







|





|
<

|
<
<
|
<
|
















<



>
|
>
>

<
<
|
<
|
>





1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075

1076
1077


1078

1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
1103


1104

1105
1106
1107
1108
1109
1110
1111
        strcpy(&zErrMsg[n1], 
            pIdx->nColumn>1 ? " are not unique" : " is not unique");
        sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0);
        break;
      }
      case OE_Ignore: {
        assert( seenReplace==0 );
        sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0);
        sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
        break;
      }
      case OE_Replace: {
        sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0);
        if( isUpdate ){
          sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
          sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
        }
        seenReplace = 1;
        break;
      }
    }
    contAddr = sqlite3VdbeCurrentAddr(v);
    assert( contAddr<(1<<24) );
#if NULL_DISTINCT_FOR_UNIQUE
    sqlite3VdbeChangeP2(v, jumpInst1, contAddr | (1<<24));
#endif
    sqlite3VdbeChangeP2(v, jumpInst2, contAddr);
  }
}

/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite3GenerateConstraintChecks.
** The stack must contain keys for all active indices followed by data
** and the recno for the new entry.  This routine creates the new
** entries in all indices and in the main table.
**
** The arguments to this routine should be the same as the first six
** arguments to sqlite3GenerateConstraintChecks.
*/
void sqlite3CompleteInsertion(
  Parse *pParse,      /* The parser context */
  Table *pTab,        /* the table into which we are inserting */
  int base,           /* Index of a read/write cursor pointing at pTab */
  char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
  int recnoChng,      /* True if the record number will change */
  int isUpdate,       /* True for UPDATE, False for INSERT */
  int newIdx          /* Index of NEW table for triggers.  -1 if none */
){
  int i;
  Vdbe *v;
  int nIdx;
  Index *pIdx;
  int pik_flags;

  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
  for(i=nIdx-1; i>=0; i--){
    if( aIdxUsed && aIdxUsed[i]==0 ) continue;
    sqlite3VdbeAddOp(v, OP_IdxPut, base+i+1, 0);
  }
  sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
  sqlite3TableAffinityStr(v, pTab);
#ifndef SQLITE_OMIT_TRIGGER
  if( newIdx>=0 ){
    sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
    sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
  }
#endif
  if( pParse->nested ){
    pik_flags = 0;
  }else{
    pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));

  }
  sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags);


  

  if( isUpdate && recnoChng ){
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
  }
}

/*
** Generate code that will open cursors for a table and for all
** indices of that table.  The "base" parameter is the cursor number used
** for the table.  Indices are opened on subsequent cursors.
*/
void sqlite3OpenTableAndIndices(
  Parse *pParse,   /* Parsing context */
  Table *pTab,     /* Table to be opened */
  int base,        /* Cursor number assigned to the table */
  int op           /* OP_OpenRead or OP_OpenWrite */
){
  int i;

  Index *pIdx;
  Vdbe *v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeAddOp(v, op, base, pTab->tnum);
  VdbeComment((v, "# %s", pTab->zName));
  sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol);
  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){


    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);

    sqlite3VdbeOp3(v, op, i+base, pIdx->tnum,
                   (char*)&pIdx->keyInfo, P3_KEYINFO);
  }
  if( pParse->nTab<=base+i ){
    pParse->nTab = base+i;
  }
}
Changes to SQLite.Interop/src/keywordhash.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


21
22
23
24
25
26

27
28
29
30
31
32
33

34
35
36
37
38
39
40

41


42
43
44
45
46
47
48
49
50
51
52


53


54
55
56
57
58
59
60
61
62

63
64
65

66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* Hash score: 159 */
static int keywordCode(const char *z, int n){
  static const char zText[537] =
    "ABORTABLEFTEMPORARYADDATABASELECTHENDEFAULTRANSACTIONATURALTER"
    "AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREGEXPLAINITIALLYANALYZE"
    "XCLUSIVEXISTSTATEMENTANDEFERRABLEATTACHAVINGLOBEFOREIGNOREINDEX"
    "AUTOINCREMENTBEGINNERENAMEBETWEENOTNULLIKEBYCASCADEFERREDELETE"
    "CASECASTCOLLATECOLUMNCOMMITCONFLICTCONSTRAINTERSECTCREATECROSS"
    "CURRENT_DATECURRENT_TIMESTAMPLANDESCDETACHDISTINCTDROPRAGMATCH"
    "FAILIMITFROMFULLGROUPDATEIFIMMEDIATEINSERTINSTEADINTOFFSETISNULL"
    "JOINORDEREPLACEOUTERESTRICTPRIMARYQUERYRIGHTROLLBACKROWHENUNION"
    "UNIQUEUSINGVACUUMVALUESVIEWHERE";
  static const unsigned char aHash[127] = {
      92,  80, 107,  91,   0,   4,   0,   0, 114,   0,  83,   0,   0,
      96,  44,  76,  93,   0, 106, 109,  97,  90,   0,  10,   0,   0,
     113,   0, 110, 103,   0,  28,  48,   0,  41,   0,   0,  65,  71,
       0,  63,  19,   0, 105,  36, 104,   0, 108,  75,   0,   0,  33,
       0,  61,  37,   0,   8,   0, 115,  38,  12,   0,  77,  40,  25,
      66,   0,   0,  31,  81,  53,  30,  50,  20,  88,   0,  34,   0,
      74,  26,   0,  72,   0,   0,   0,  64,  47,  67,  22,  87,  29,


      69,  86,   0,   1,   0,   9, 101,  58,  18,   0, 112,  82,  99,
      55,   6,  85,   0,   0,  49,  94,   0, 102,   0,  70,   0,   0,
      15,   0, 116,  51,  56,   0,   2,  54,   0, 111,
  };
  static const unsigned char aNext[116] = {
       0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,

       0,   0,   0,   0,   0,   0,   0,   0,  17,   0,   0,   0,   0,
       0,  11,   0,   0,   0,   0,   5,  13,   0,   7,   0,   0,   0,
       0,   0,   0,   0,   0,   0,   0,  42,   0,   0,   0,   0,   0,
       0,  16,   0,   0,  23,  52,   0,   0,   0,   0,  45,   0,  59,
       0,   0,   0,   0,   0,   0,   0,   0,  43,  73,   0,  24,  60,
      21,   0,  79,   0,   0,  68,   0,   0,  84,  46,   0,   0,   0,
       0,   0,   0,   0,   0,  39,  95,  98,   0,   0, 100,   0,  32,

       0,  14,  27,  78,   0,  57,  89,   0,  35,   0,  62,   0,
  };
  static const unsigned char aLen[116] = {
       5,   5,   4,   4,   9,   2,   3,   8,   2,   6,   4,   3,   7,
      11,   2,   7,   5,   5,   4,   5,   3,   5,  10,   6,   4,   6,
       7,   6,   7,   9,   3,   7,   9,   6,   9,   3,  10,   6,   6,
       4,   6,   7,   3,   6,   7,   5,  13,   2,   2,   5,   5,   6,

       7,   7,   3,   4,   4,   2,   7,   3,   8,   6,   4,   4,   7,


       6,   6,   8,  10,   9,   6,   5,  12,  17,  12,   4,   4,   6,
       8,   2,   4,   6,   5,   4,   5,   4,   4,   5,   6,   2,   9,
       6,   7,   4,   6,   2,   3,   6,   4,   5,   7,   5,   8,   7,
       5,   5,   8,   3,   4,   5,   6,   5,   6,   6,   4,   5,
  };
  static const unsigned short int aOffset[116] = {
       0,   4,   7,  10,  10,  14,  19,  21,  26,  27,  32,  34,  36,
      42,  51,  52,  57,  61,  65,  67,  71,  74,  78,  86,  91,  94,
      99, 105, 108, 113, 118, 122, 128, 136, 141, 150, 152, 162, 167,
     172, 175, 177, 177, 181, 185, 187, 192, 194, 196, 205, 208, 212,
     218, 224, 224, 227, 230, 234, 236, 237, 241, 248, 254, 258, 262,


     269, 275, 281, 289, 296, 305, 311, 316, 328, 328, 344, 348, 352,


     358, 359, 366, 369, 373, 378, 381, 386, 390, 394, 397, 403, 405,
     414, 420, 427, 430, 430, 433, 436, 442, 446, 450, 457, 461, 469,
     476, 481, 486, 494, 496, 500, 505, 511, 516, 522, 528, 531,
  };
  static const unsigned char aCode[116] = {
    TK_ABORT,      TK_TABLE,      TK_JOIN_KW,    TK_TEMP,       TK_TEMP,       
    TK_OR,         TK_ADD,        TK_DATABASE,   TK_AS,         TK_SELECT,     
    TK_THEN,       TK_END,        TK_DEFAULT,    TK_TRANSACTION,TK_ON,         
    TK_JOIN_KW,    TK_ALTER,      TK_RAISE,      TK_EACH,       TK_CHECK,      

    TK_KEY,        TK_AFTER,      TK_REFERENCES, TK_ESCAPE,     TK_ELSE,       
    TK_EXCEPT,     TK_TRIGGER,    TK_LIKE_KW,    TK_EXPLAIN,    TK_INITIALLY,  
    TK_ALL,        TK_ANALYZE,    TK_EXCLUSIVE,  TK_EXISTS,     TK_STATEMENT,  

    TK_AND,        TK_DEFERRABLE, TK_ATTACH,     TK_HAVING,     TK_LIKE_KW,    
    TK_BEFORE,     TK_FOREIGN,    TK_FOR,        TK_IGNORE,     TK_REINDEX,    
    TK_INDEX,      TK_AUTOINCR,   TK_TO,         TK_IN,         TK_BEGIN,      
    TK_JOIN_KW,    TK_RENAME,     TK_BETWEEN,    TK_NOTNULL,    TK_NOT,        
    TK_NULL,       TK_LIKE_KW,    TK_BY,         TK_CASCADE,    TK_ASC,        
    TK_DEFERRED,   TK_DELETE,     TK_CASE,       TK_CAST,       TK_COLLATE,    
    TK_COLUMNKW,   TK_COMMIT,     TK_CONFLICT,   TK_CONSTRAINT, TK_INTERSECT,  
    TK_CREATE,     TK_JOIN_KW,    TK_CTIME_KW,   TK_CTIME_KW,   TK_CTIME_KW,   

    TK_PLAN,       TK_DESC,       TK_DETACH,     TK_DISTINCT,   TK_IS,         
    TK_DROP,       TK_PRAGMA,     TK_MATCH,      TK_FAIL,       TK_LIMIT,      
    TK_FROM,       TK_JOIN_KW,    TK_GROUP,      TK_UPDATE,     TK_IF,         
    TK_IMMEDIATE,  TK_INSERT,     TK_INSTEAD,    TK_INTO,       TK_OFFSET,     
    TK_OF,         TK_SET,        TK_ISNULL,     TK_JOIN,       TK_ORDER,      
    TK_REPLACE,    TK_JOIN_KW,    TK_RESTRICT,   TK_PRIMARY,    TK_QUERY,      
    TK_JOIN_KW,    TK_ROLLBACK,   TK_ROW,        TK_WHEN,       TK_UNION,      
    TK_UNIQUE,     TK_USING,      TK_VACUUM,     TK_VALUES,     TK_VIEW,       
    TK_WHERE,      
  };
  int h, i;
  if( n<2 ) return TK_ID;
  h = ((sqlite3UpperToLower[((unsigned char*)z)[0]]*4) ^
      (sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3) ^
      n) % 127;
  for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
    if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
      return aCode[i];
    }
  }
  return TK_ID;
}
int sqlite3KeywordCode(const unsigned char *z, int n){
  return keywordCode((char*)z, n);
}
|

|
|
|
|
|
|
|
|
<
|

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

|

>
|
<
|
|
<
|
|
>
|

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

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

|

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













|
|

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21


22
23
24
25
26
27

28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43



44
45
46
47
48
49


50
51
52
53
54
55


56
57
58


59
60
61
62
63
64
65
66
67
68
69

70
71
72
73

74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* Hash score: 148 */
static int keywordCode(const char *z, int n){
  static const char zText[504] =
    "ABORTABLEFTEMPORARYAFTERAISELECTHENDATABASEACHECKEYALTEREFERENCES"
    "CAPELSEXCEPTRANSACTIONATURALIKEXCLUSIVEXISTSTATEMENTRIGGEREINDEX"
    "PLAINITIALLYANDEFAULTATTACHAVINGLOBEFOREIGNORENAMEAUTOINCREMENT"
    "BEGINNEREPLACEBETWEENOTNULLIMITBYCASCADEFERRABLECASECOLLATECOMMIT"
    "CONFLICTCONSTRAINTERSECTCREATECROSSCURRENT_DATECURRENT_TIMESTAMP"
    "RAGMATCHDEFERREDELETEDESCDETACHDISTINCTDROPRIMARYFAILFROMFULL"
    "GROUPDATEIMMEDIATEINSERTINSTEADINTOFFSETISNULLJOINORDERESTRICT"

    "OUTERIGHTROLLBACKROWHENUNIONUNIQUEUSINGVACUUMVALUESVIEWHERE";
  static const unsigned char aHash[127] = {
      87,  78,  99,  86,   0,   4,   0,   0, 106,   0,  72,   0,   0,
      90,  43,   0,  88,   0,  98, 101,  92,   0,   0,   9,   0,   0,
     105,   0, 102,  96,   0,  10,  46,   0,  40,   0,   0,  61,  66,
       0,  60,  14,   0,   0,  35,  80,   0, 100,  69,   0,   0,  26,
       0,  73,  59,   0,  12,   0, 107,  37,  11,   0,  75,  39,  20,
       0,   0,   0,  34,  79,  51,  33,  48,  15,  84,   0,  36,   0,
      70,  21,   0,  67,   0,   0,   0,   0,  45,  62,  17,  83,  32,
      64,  82,   0,   1,   0,  13,  50,  56,   8,   0, 104,  71,  94,
      52,   6,  55,   0,   0,  47,  89,   0,  97,   0,  65,   0,   0,


      23,   0, 108,  49,  54,   0,   2,  53,   0, 103,
  };
  static const unsigned char aNext[108] = {
       0,   0,   0,   0,   0,   3,   0,   0,   0,   0,   0,   0,   0,
       0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,  18,   5,
       0,   0,   0,   0,   0,   0,   0,   0,   0,  27,   0,   0,   0,

       0,   0,   0,   0,   0,  42,   0,   0,   0,   0,   0,   0,   0,
      24,   0,   0,  44,   0,   0,   0,  30,  57,   0,   0,   0,   0,

       0,   0,   0,  68,  41,   0,   0,   0,   0,  19,  58,  16,   0,
      77,   0,  63,   0,  81,  31,   0,   0,   0,   0,   0,   0,   0,
      38,  91,  93,   0,   0,  95,  22,  29,  76,   0,  25,  85,   0,
      28,   0,  74,   0,
  };
  static const unsigned char aLen[108] = {
       5,   5,   4,   4,   9,   2,   5,   5,   6,   4,   3,   8,   2,
       4,   5,   3,   5,  10,   6,   4,   6,  11,   2,   7,   4,   9,
       6,   9,   7,   7,   5,   7,   9,   3,   3,   7,   6,   6,   4,
       6,   3,   7,   6,   6,  13,   2,   2,   5,   5,   7,   7,   3,
       7,   4,   5,   2,   7,   3,  10,   4,   7,   6,   8,  10,   9,
       6,   5,  12,  12,  17,   6,   5,   8,   6,   4,   6,   8,   2,
       4,   7,   4,   4,   4,   5,   6,   9,   6,   7,   4,   2,   6,
       3,   6,   4,   5,   8,   5,   5,   8,   3,   4,   5,   6,   5,



       6,   6,   4,   5,
  };
  static const unsigned short int aOffset[108] = {
       0,   4,   7,  10,  10,  14,  19,  23,  26,  31,  33,  35,  40,
      42,  44,  48,  51,  55,  63,  68,  71,  76,  85,  86,  92,  95,
     103, 108, 116, 122, 124, 127, 132, 137, 141, 143, 150, 155, 160,


     163, 165, 165, 169, 173, 179, 181, 183, 192, 195, 199, 206, 212,
     212, 215, 218, 223, 225, 226, 230, 240, 244, 251, 257, 265, 272,
     281, 287, 292, 304, 304, 320, 324, 329, 336, 342, 346, 352, 353,
     360, 363, 370, 374, 378, 382, 385, 391, 400, 406, 413, 416, 416,
     419, 422, 428, 432, 436, 444, 448, 453, 461, 463, 467, 472, 478,
     483, 489, 495, 498,


  };
  static const unsigned char aCode[108] = {
    TK_ABORT,      TK_TABLE,      TK_JOIN_KW,    TK_TEMP,       TK_TEMP,       


    TK_OR,         TK_AFTER,      TK_RAISE,      TK_SELECT,     TK_THEN,       
    TK_END,        TK_DATABASE,   TK_AS,         TK_EACH,       TK_CHECK,      
    TK_KEY,        TK_ALTER,      TK_REFERENCES, TK_ESCAPE,     TK_ELSE,       
    TK_EXCEPT,     TK_TRANSACTION,TK_ON,         TK_JOIN_KW,    TK_LIKE,       
    TK_EXCLUSIVE,  TK_EXISTS,     TK_STATEMENT,  TK_TRIGGER,    TK_REINDEX,    
    TK_INDEX,      TK_EXPLAIN,    TK_INITIALLY,  TK_ALL,        TK_AND,        
    TK_DEFAULT,    TK_ATTACH,     TK_HAVING,     TK_GLOB,       TK_BEFORE,     
    TK_FOR,        TK_FOREIGN,    TK_IGNORE,     TK_RENAME,     TK_AUTOINCR,   
    TK_TO,         TK_IN,         TK_BEGIN,      TK_JOIN_KW,    TK_REPLACE,    
    TK_BETWEEN,    TK_NOT,        TK_NOTNULL,    TK_NULL,       TK_LIMIT,      
    TK_BY,         TK_CASCADE,    TK_ASC,        TK_DEFERRABLE, TK_CASE,       

    TK_COLLATE,    TK_COMMIT,     TK_CONFLICT,   TK_CONSTRAINT, TK_INTERSECT,  
    TK_CREATE,     TK_JOIN_KW,    TK_CDATE,      TK_CTIME,      TK_CTIMESTAMP, 
    TK_PRAGMA,     TK_MATCH,      TK_DEFERRED,   TK_DELETE,     TK_DESC,       
    TK_DETACH,     TK_DISTINCT,   TK_IS,         TK_DROP,       TK_PRIMARY,    

    TK_FAIL,       TK_FROM,       TK_JOIN_KW,    TK_GROUP,      TK_UPDATE,     
    TK_IMMEDIATE,  TK_INSERT,     TK_INSTEAD,    TK_INTO,       TK_OF,         
    TK_OFFSET,     TK_SET,        TK_ISNULL,     TK_JOIN,       TK_ORDER,      

    TK_RESTRICT,   TK_JOIN_KW,    TK_JOIN_KW,    TK_ROLLBACK,   TK_ROW,        
    TK_WHEN,       TK_UNION,      TK_UNIQUE,     TK_USING,      TK_VACUUM,     
    TK_VALUES,     TK_VIEW,       TK_WHERE,      
  };
  int h, i;
  if( n<2 ) return TK_ID;
  h = ((sqlite3UpperToLower[((unsigned char*)z)[0]]*4) ^
      (sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3) ^
      n) % 127;
  for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
    if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
      return aCode[i];
    }
  }
  return TK_ID;
}
int sqlite3KeywordCode(const char *z, int n){
  return keywordCode(z, n);
}
Changes to SQLite.Interop/src/legacy.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: legacy.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/

#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: legacy.c,v 1.1 2005/03/01 16:04:30 rmsimpson Exp $
*/

#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
66
67
68
69
70
71
72

73
74
75
76
77
78
79

    db->nChange += nChange;
    nCallback = 0;

    nCol = sqlite3_column_count(pStmt);
    azCols = sqliteMalloc(2*nCol*sizeof(const char *));
    if( nCol && !azCols ){

      goto exec_out;
    }

    while( 1 ){
      int i;
      rc = sqlite3_step(pStmt);








>







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

    db->nChange += nChange;
    nCallback = 0;

    nCol = sqlite3_column_count(pStmt);
    azCols = sqliteMalloc(2*nCol*sizeof(const char *));
    if( nCol && !azCols ){
      rc = SQLITE_NOMEM;
      goto exec_out;
    }

    while( 1 ){
      int i;
      rc = sqlite3_step(pStmt);

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
    azCols = 0;
  }

exec_out:
  if( pStmt ) sqlite3_finalize(pStmt);
  if( azCols ) sqliteFree(azCols);

  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    rc = SQLITE_NOMEM;
    sqlite3MallocClearFailed();
  }

  if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
    *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
    if( *pzErrMsg ){
      strcpy(*pzErrMsg, sqlite3_errmsg(db));
    }
  }else if( pzErrMsg ){
    *pzErrMsg = 0;
  }

  return rc;
}







|

<

<











118
119
120
121
122
123
124
125
126

127

128
129
130
131
132
133
134
135
136
137
138
    azCols = 0;
  }

exec_out:
  if( pStmt ) sqlite3_finalize(pStmt);
  if( azCols ) sqliteFree(azCols);

  if( sqlite3_malloc_failed ){
    rc = SQLITE_NOMEM;

  }

  if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
    *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db)));
    if( *pzErrMsg ){
      strcpy(*pzErrMsg, sqlite3_errmsg(db));
    }
  }else if( pzErrMsg ){
    *pzErrMsg = 0;
  }

  return rc;
}
Changes to SQLite.Interop/src/main.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
































































































































































































































































































































































28
29
30
31
32
33
34
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
** SQLITE_LITTLEENDIAN macros.
*/
const int sqlite3one = 1;

































































































































































































































































































































































/*
** The version of the library
*/
const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";
const char sqlite3_version[] = SQLITE_VERSION;
const char *sqlite3_libversion(void){ return sqlite3_version; }







|










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







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.1 2005/03/01 16:04:30 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
** SQLITE_LITTLEENDIAN macros.
*/
const int sqlite3one = 1;

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
*/
static void corruptSchema(InitData *pData, const char *zExtra){
  if( !sqlite3_malloc_failed ){
    sqlite3SetString(pData->pzErrMsg, "malformed database schema",
       zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
  }
}

/*
** This is the callback routine for the code that initializes the
** database.  See sqlite3Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
**
** Each callback contains the following information:
**
**     argv[0] = name of thing being created
**     argv[1] = root page number for table or index.  NULL for trigger or view.
**     argv[2] = SQL text for the CREATE statement.
**     argv[3] = "1" for temporary files, "0" for main database, "2" or more
**               for auxiliary database files.
**
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
  InitData *pData = (InitData*)pInit;
  sqlite3 *db = pData->db;
  int iDb;

  assert( argc==4 );
  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
  if( argv[1]==0 || argv[3]==0 ){
    corruptSchema(pData, 0);
    return 1;
  }
  iDb = atoi(argv[3]);
  assert( iDb>=0 && iDb<db->nDb );
  if( argv[2] && argv[2][0] ){
    /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    ** But because db->init.busy is set to 1, no VDBE code is generated
    ** or executed.  All the parser does is build the internal data
    ** structures that describe the table, index, or view.
    */
    char *zErr;
    int rc;
    assert( db->init.busy );
    db->init.iDb = iDb;
    db->init.newTnum = atoi(argv[1]);
    rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
    db->init.iDb = 0;
    if( SQLITE_OK!=rc ){
      corruptSchema(pData, zErr);
      sqlite3_free(zErr);
      return rc;
    }
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
    ** been created when we processed the CREATE TABLE.  All we have
    ** to do here is record the root page number for that index.
    */
    Index *pIndex;
    pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName);
    if( pIndex==0 || pIndex->tnum!=0 ){
      /* This can occur if there exists an index on a TEMP table which
      ** has the same name as another index on a permanent index.  Since
      ** the permanent table is hidden by the TEMP table, we can also
      ** safely ignore the index on the permanent table.
      */
      /* Do Nothing */;
    }else{
      pIndex->tnum = atoi(argv[1]);
    }
  }
  return 0;
}

/*
** Attempt to read the database schema and initialize internal
** data structures for a single database file.  The index of the
** database file is given by iDb.  iDb==0 is used for the main
** database.  iDb==1 should never be used.  iDb>=2 is used for
** auxiliary databases.  Return one of the SQLITE_ error codes to
** indicate success or failure.
*/
static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
  int rc;
  BtCursor *curMain;
  int size;
  Table *pTab;
  char const *azArg[5];
  char zDbNum[30];
  int meta[10];
  InitData initData;
  char const *zMasterSchema;
  char const *zMasterName;

  /*
  ** The master database table has a structure like this
  */
  static const char master_schema[] = 
     "CREATE TABLE sqlite_master(\n"
     "  type text,\n"
     "  name text,\n"
     "  tbl_name text,\n"
     "  rootpage integer,\n"
     "  sql text\n"
     ")"
  ;
  static const char temp_master_schema[] = 
     "CREATE TEMP TABLE sqlite_temp_master(\n"
     "  type text,\n"
     "  name text,\n"
     "  tbl_name text,\n"
     "  rootpage integer,\n"
     "  sql text\n"
     ")"
  ;

  assert( iDb>=0 && iDb<db->nDb );

  /* zMasterSchema and zInitScript are set to point at the master schema
  ** and initialisation script appropriate for the database being
  ** initialised. zMasterName is the name of the master table.
  */
  if( iDb==1 ){
    zMasterSchema = temp_master_schema;
    zMasterName = TEMP_MASTER_NAME;
  }else{
    zMasterSchema = master_schema;
    zMasterName = MASTER_NAME;
  }

  /* Construct the schema tables.  */
  sqlite3SafetyOff(db);
  azArg[0] = zMasterName;
  azArg[1] = "1";
  azArg[2] = zMasterSchema;
  sprintf(zDbNum, "%d", iDb);
  azArg[3] = zDbNum;
  azArg[4] = 0;
  initData.db = db;
  initData.pzErrMsg = pzErrMsg;
  rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0);
  if( rc!=SQLITE_OK ){
    sqlite3SafetyOn(db);
    return rc;
  }
  pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
  if( pTab ){
    pTab->readOnly = 1;
  }
  sqlite3SafetyOn(db);

  /* Create a cursor to hold the database open
  */
  if( db->aDb[iDb].pBt==0 ){
    if( iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded);
    return SQLITE_OK;
  }
  rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain);
  if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
    sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
    return rc;
  }

  /* Get the database meta information.
  **
  ** Meta values are as follows:
  **    meta[0]   Schema cookie.  Changes with each schema change.
  **    meta[1]   File format of schema layer.
  **    meta[2]   Size of the page cache.
  **    meta[3]   Use freelist if 0.  Autovacuum if greater than zero.
  **    meta[4]   Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE
  **    meta[5]   The user cookie. Used by the application.
  **    meta[6]   
  **    meta[7]
  **    meta[8]
  **    meta[9]
  **
  ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to
  ** the possible values of meta[4].
  */
  if( rc==SQLITE_OK ){
    int i;
    for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
      rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, (u32 *)&meta[i]);
    }
    if( rc ){
      sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
      sqlite3BtreeCloseCursor(curMain);
      return rc;
    }
  }else{
    memset(meta, 0, sizeof(meta));
  }
  db->aDb[iDb].schema_cookie = meta[0];

  /* If opening a non-empty database, check the text encoding. For the
  ** main database, set sqlite3.enc to the encoding of the main database.
  ** For an attached db, it is an error if the encoding is not the same
  ** as sqlite3.enc.
  */
  if( meta[4] ){  /* text encoding */
    if( iDb==0 ){
      /* If opening the main database, set db->enc. */
      db->enc = (u8)meta[4];
      db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0);
    }else{
      /* If opening an attached database, the encoding much match db->enc */
      if( meta[4]!=db->enc ){
        sqlite3BtreeCloseCursor(curMain);
        sqlite3SetString(pzErrMsg, "attached databases must use the same"
            " text encoding as main database", (char*)0);
        return SQLITE_ERROR;
      }
    }
  }

  size = meta[2];
  if( size==0 ){ size = MAX_PAGES; }
  db->aDb[iDb].cache_size = size;

  if( iDb==0 ){
    db->file_format = meta[1];
    if( db->file_format==0 ){
      /* This happens if the database was initially empty */
      db->file_format = 1;
    }

    if( db->file_format==2 ){
      /* File format 2 is treated exactly as file format 1. New 
      ** databases are created with file format 1.
      */ 
      db->file_format = 1;
    }
  }

  /*
  ** file_format==1    Version 3.0.0.
  ** file_format==2    Version 3.1.3.
  **
  ** Version 3.0 can only use files with file_format==1. Version 3.1.3
  ** can read and write files with file_format==1 or file_format==2.
  */
  if( meta[1]>2 ){
    sqlite3BtreeCloseCursor(curMain);
    sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
    return SQLITE_ERROR;
  }

  sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);

  /* Read the schema information out of the schema tables
  */
  assert( db->init.busy );
  if( rc==SQLITE_EMPTY ){
    /* For an empty database, there is nothing to read */
    rc = SQLITE_OK;
  }else{
    char *zSql;
    zSql = sqlite3MPrintf(
        "SELECT name, rootpage, sql, '%s' FROM '%q'.%s",
        zDbNum, db->aDb[iDb].zName, zMasterName);
    sqlite3SafetyOff(db);
    rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
    sqlite3SafetyOn(db);
    sqliteFree(zSql);
    sqlite3BtreeCloseCursor(curMain);
  }
  if( sqlite3_malloc_failed ){
    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
    rc = SQLITE_NOMEM;
    sqlite3ResetInternalSchema(db, 0);
  }
  if( rc==SQLITE_OK ){
    DbSetProperty(db, iDb, DB_SchemaLoaded);
  }else{
    sqlite3ResetInternalSchema(db, iDb);
  }
  return rc;
}

/*
** Initialize all database files - the main database file, the file
** used to store temporary tables, and any additional database files
** created using ATTACH statements.  Return a success code.  If an
** error occurs, write an error message into *pzErrMsg.
**
** After the database is initialized, the SQLITE_Initialized
** bit is set in the flags field of the sqlite structure. 
*/
int sqlite3Init(sqlite3 *db, char **pzErrMsg){
  int i, rc;
  
  if( db->init.busy ) return SQLITE_OK;
  assert( (db->flags & SQLITE_Initialized)==0 );
  rc = SQLITE_OK;
  db->init.busy = 1;
  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
    if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
    rc = sqlite3InitOne(db, i, pzErrMsg);
    if( rc ){
      sqlite3ResetInternalSchema(db, i);
    }
  }

  /* Once all the other databases have been initialised, load the schema
  ** for the TEMP database. This is loaded last, as the TEMP database
  ** schema may contain references to objects in other databases.
  */
  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
    rc = sqlite3InitOne(db, 1, pzErrMsg);
    if( rc ){
      sqlite3ResetInternalSchema(db, 1);
    }
  }

  db->init.busy = 0;
  if( rc==SQLITE_OK ){
    db->flags |= SQLITE_Initialized;
    sqlite3CommitInternalChanges(db);
  }

  if( rc!=SQLITE_OK ){
    db->flags &= ~SQLITE_Initialized;
  }
  return rc;
}

/*
** This routine is a no-op if the database schema is already initialised.
** Otherwise, the schema is loaded. An error code is returned.
*/
int sqlite3ReadSchema(Parse *pParse){
  int rc = SQLITE_OK;
  sqlite3 *db = pParse->db;
  if( !db->init.busy ){
    if( (db->flags & SQLITE_Initialized)==0 ){
      rc = sqlite3Init(db, &pParse->zErrMsg);
    }
  }
  assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized)||db->init.busy );
  if( rc!=SQLITE_OK ){
    pParse->rc = rc;
    pParse->nErr++;
  }
  return rc;
}

/*
** The version of the library
*/
const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";
const char sqlite3_version[] = SQLITE_VERSION;
const char *sqlite3_libversion(void){ return sqlite3_version; }
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
  if( !db ){
    return SQLITE_OK;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }

#ifdef SQLITE_SSE
  sqlite3_finalize(db->pFetch);
#endif 

  /* If there are any outstanding VMs, return SQLITE_BUSY. */
  if( db->pVdbe ){
    sqlite3Error(db, SQLITE_BUSY, 
        "Unable to close due to unfinalised statements");
    return SQLITE_BUSY;
  }
  assert( !sqlite3SafetyCheck(db) );

  /* FIX ME: db->magic may be set to SQLITE_MAGIC_CLOSED if the database
  ** cannot be opened for some reason. So this routine needs to run in
  ** that case. But maybe there should be an extra magic value for the
  ** "failed to open" state.
  */
  if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){
    /* printf("DID NOT CLOSE\n"); fflush(stdout); */
    return SQLITE_ERROR;
  }

  /* sqlite3_close() may not invoke sqliteMalloc(). */
  sqlite3MallocDisallow();

  for(j=0; j<db->nDb; j++){
    struct Db *pDb = &db->aDb[j];
    if( pDb->pBt ){
      sqlite3BtreeClose(pDb->pBt);
      pDb->pBt = 0;
      if( j!=1 ){
        pDb->pSchema = 0;
      }
    }
  }
  sqlite3ResetInternalSchema(db, 0);
  assert( db->nDb<=2 );
  assert( db->aDb==db->aDbStatic );
  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
    FuncDef *pFunc, *pNext;







<
<
<
<


















<
<
<





<
<
<







457
458
459
460
461
462
463




464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481



482
483
484
485
486



487
488
489
490
491
492
493
  if( !db ){
    return SQLITE_OK;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }





  /* If there are any outstanding VMs, return SQLITE_BUSY. */
  if( db->pVdbe ){
    sqlite3Error(db, SQLITE_BUSY, 
        "Unable to close due to unfinalised statements");
    return SQLITE_BUSY;
  }
  assert( !sqlite3SafetyCheck(db) );

  /* FIX ME: db->magic may be set to SQLITE_MAGIC_CLOSED if the database
  ** cannot be opened for some reason. So this routine needs to run in
  ** that case. But maybe there should be an extra magic value for the
  ** "failed to open" state.
  */
  if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){
    /* printf("DID NOT CLOSE\n"); fflush(stdout); */
    return SQLITE_ERROR;
  }




  for(j=0; j<db->nDb; j++){
    struct Db *pDb = &db->aDb[j];
    if( pDb->pBt ){
      sqlite3BtreeClose(pDb->pBt);
      pDb->pBt = 0;



    }
  }
  sqlite3ResetInternalSchema(db, 0);
  assert( db->nDb<=2 );
  assert( db->aDb==db->aDbStatic );
  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
    FuncDef *pFunc, *pNext;
159
160
161
162
163
164
165



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229

230
231
232
233
234

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
    CollSeq *pColl = (CollSeq *)sqliteHashData(i);
    sqliteFree(pColl);
  }
  sqlite3HashClear(&db->aCollSeq);

  sqlite3HashClear(&db->aFunc);
  sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */



  if( db->pErr ){
    sqlite3ValueFree(db->pErr);
  }

  db->magic = SQLITE_MAGIC_ERROR;

  /* The temp-database schema is allocated differently from the other schema
  ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()).
  ** So it needs to be freed here. Todo: Why not roll the temp schema into
  ** the same sqliteMalloc() as the one that allocates the database 
  ** structure?
  */
  sqliteFree(db->aDb[1].pSchema);
  sqliteFree(db);
  sqlite3MallocAllow();
  sqlite3ReleaseThreadData();
  return SQLITE_OK;
}

/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite3 *db){
  int i;
  int inTrans = 0;
  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].pBt ){
      if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
        inTrans = 1;
      }
      sqlite3BtreeRollback(db->aDb[i].pBt);
      db->aDb[i].inTrans = 0;
    }
  }
  if( db->flags&SQLITE_InternChanges ){
    sqlite3ResetInternalSchema(db, 0);
  }

  /* If one has been configured, invoke the rollback-hook callback */
  if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
    db->xRollbackCallback(db->pRollbackArg);
  }
}

/*
** Return a static string that describes the kind of error specified in the
** argument.
*/
const char *sqlite3ErrStr(int rc){
  const char *z;
  switch( rc ){
    case SQLITE_ROW:
    case SQLITE_DONE:
    case SQLITE_OK:         z = "not an error";                          break;
    case SQLITE_ERROR:      z = "SQL logic error or missing database";   break;

    case SQLITE_PERM:       z = "access permission denied";              break;
    case SQLITE_ABORT:      z = "callback requested query abort";        break;
    case SQLITE_BUSY:       z = "database is locked";                    break;
    case SQLITE_LOCKED:     z = "database table is locked";              break;
    case SQLITE_NOMEM:      z = "out of memory";                         break;
    case SQLITE_READONLY:   z = "attempt to write a readonly database";  break;
    case SQLITE_INTERRUPT:  z = "interrupted";                           break;
    case SQLITE_IOERR:      z = "disk I/O error";                        break;
    case SQLITE_CORRUPT:    z = "database disk image is malformed";      break;

    case SQLITE_FULL:       z = "database or disk is full";              break;
    case SQLITE_CANTOPEN:   z = "unable to open database file";          break;
    case SQLITE_PROTOCOL:   z = "database locking protocol failure";     break;
    case SQLITE_EMPTY:      z = "table contains no data";                break;
    case SQLITE_SCHEMA:     z = "database schema has changed";           break;

    case SQLITE_CONSTRAINT: z = "constraint failed";                     break;
    case SQLITE_MISMATCH:   z = "datatype mismatch";                     break;
    case SQLITE_MISUSE:     z = "library routine called out of sequence";break;
    case SQLITE_NOLFS:      z = "kernel lacks large file support";       break;
    case SQLITE_AUTH:       z = "authorization denied";                  break;
    case SQLITE_FORMAT:     z = "auxiliary database format error";       break;
    case SQLITE_RANGE:      z = "bind or column index out of range";     break;
    case SQLITE_NOTADB:     z = "file is encrypted or is not a database";break;
    default:                z = "unknown error";                         break;
  }
  return z;
}

/*
** This routine implements a busy callback that sleeps and tries
** again until a timeout value is reached.  The timeout value is
** an integer number of milliseconds passed in as the first
** argument.
*/
static int sqliteDefaultBusyCallback(
 void *ptr,               /* Database connection */
 int count                /* Number of times table has been busy */
){
#if SQLITE_MIN_SLEEP_MS==1
  static const u8 delays[] =
     { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50, 100 };
  static const u8 totals[] =
     { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228 };
# define NDELAY (sizeof(delays)/sizeof(delays[0]))
  int timeout = ((sqlite3 *)ptr)->busyTimeout;
  int delay, prior;

  assert( count>=0 );
  if( count < NDELAY ){
    delay = delays[count];
    prior = totals[count];
  }else{
    delay = delays[NDELAY-1];
    prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
  }
  if( prior + delay > timeout ){
    delay = timeout - prior;
    if( delay<=0 ) return 0;
  }
  sqlite3OsSleep(delay);
  return 1;
#else
  int timeout = ((sqlite3 *)ptr)->busyTimeout;
  if( (count+1)*1000 > timeout ){
    return 0;
  }
  sqlite3OsSleep(1000);
  return 1;
#endif
}

/*
** Invoke the given busy handler.
**
** This routine is called when an operation failed with a lock.
** If this routine returns non-zero, the lock is retried.  If it
** returns 0, the operation aborts with an SQLITE_BUSY error.
*/
int sqlite3InvokeBusyHandler(BusyHandler *p){
  int rc;
  if( p==0 || p->xFunc==0 || p->nBusy<0 ) return 0;
  rc = p->xFunc(p->pArg, p->nBusy);
  if( rc==0 ){
    p->nBusy = -1;
  }else{
    p->nBusy++;
  }
  return rc; 
}

/*
** This routine sets the busy callback for an Sqlite database to the
** given callback function with the given argument.
*/
int sqlite3_busy_handler(
  sqlite3 *db,
  int (*xBusy)(void*,int),
  void *pArg
){
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  db->busyHandler.xFunc = xBusy;
  db->busyHandler.pArg = pArg;
  db->busyHandler.nBusy = 0;
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** This routine sets the progress callback for an Sqlite database to the
** given callback function with the given argument. The progress callback will







>
>
>





<
<
<
<
<
<
<
<

<
<








<


<
<
<




<
|
<
<
<
<
<
<













>









>
|




>




















|



|
|
|
|

|
|

<
|
|
|


|








|








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














<







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515








516


517
518
519
520
521
522
523
524

525
526



527
528
529
530

531






532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593

594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616



















617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
    CollSeq *pColl = (CollSeq *)sqliteHashData(i);
    sqliteFree(pColl);
  }
  sqlite3HashClear(&db->aCollSeq);

  sqlite3HashClear(&db->aFunc);
  sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
  if( db->pValue ){
    sqlite3ValueFree(db->pValue);
  }
  if( db->pErr ){
    sqlite3ValueFree(db->pErr);
  }

  db->magic = SQLITE_MAGIC_ERROR;








  sqliteFree(db);


  return SQLITE_OK;
}

/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite3 *db){
  int i;

  for(i=0; i<db->nDb; i++){
    if( db->aDb[i].pBt ){



      sqlite3BtreeRollback(db->aDb[i].pBt);
      db->aDb[i].inTrans = 0;
    }
  }

  sqlite3ResetInternalSchema(db, 0);






}

/*
** Return a static string that describes the kind of error specified in the
** argument.
*/
const char *sqlite3ErrStr(int rc){
  const char *z;
  switch( rc ){
    case SQLITE_ROW:
    case SQLITE_DONE:
    case SQLITE_OK:         z = "not an error";                          break;
    case SQLITE_ERROR:      z = "SQL logic error or missing database";   break;
    case SQLITE_INTERNAL:   z = "internal SQLite implementation flaw";   break;
    case SQLITE_PERM:       z = "access permission denied";              break;
    case SQLITE_ABORT:      z = "callback requested query abort";        break;
    case SQLITE_BUSY:       z = "database is locked";                    break;
    case SQLITE_LOCKED:     z = "database table is locked";              break;
    case SQLITE_NOMEM:      z = "out of memory";                         break;
    case SQLITE_READONLY:   z = "attempt to write a readonly database";  break;
    case SQLITE_INTERRUPT:  z = "interrupted";                           break;
    case SQLITE_IOERR:      z = "disk I/O error";                        break;
    case SQLITE_CORRUPT:    z = "database disk image is malformed";      break;
    case SQLITE_NOTFOUND:   z = "table or record not found";             break;
    case SQLITE_FULL:       z = "database is full";                      break;
    case SQLITE_CANTOPEN:   z = "unable to open database file";          break;
    case SQLITE_PROTOCOL:   z = "database locking protocol failure";     break;
    case SQLITE_EMPTY:      z = "table contains no data";                break;
    case SQLITE_SCHEMA:     z = "database schema has changed";           break;
    case SQLITE_TOOBIG:     z = "too much data for one table row";       break;
    case SQLITE_CONSTRAINT: z = "constraint failed";                     break;
    case SQLITE_MISMATCH:   z = "datatype mismatch";                     break;
    case SQLITE_MISUSE:     z = "library routine called out of sequence";break;
    case SQLITE_NOLFS:      z = "kernel lacks large file support";       break;
    case SQLITE_AUTH:       z = "authorization denied";                  break;
    case SQLITE_FORMAT:     z = "auxiliary database format error";       break;
    case SQLITE_RANGE:      z = "bind or column index out of range";     break;
    case SQLITE_NOTADB:     z = "file is encrypted or is not a database";break;
    default:                z = "unknown error";                         break;
  }
  return z;
}

/*
** This routine implements a busy callback that sleeps and tries
** again until a timeout value is reached.  The timeout value is
** an integer number of milliseconds passed in as the first
** argument.
*/
static int sqliteDefaultBusyCallback(
 void *Timeout,           /* Maximum amount of time to wait */
 int count                /* Number of times table has been busy */
){
#if SQLITE_MIN_SLEEP_MS==1
  static const char delays[] =
     { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50,  50, 100};
  static const short int totals[] =
     { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228, 287};
# define NDELAY (sizeof(delays)/sizeof(delays[0]))
  ptr timeout = (ptr)Timeout;
  ptr delay, prior;


  if( count <= NDELAY ){
    delay = delays[count-1];
    prior = totals[count-1];
  }else{
    delay = delays[NDELAY-1];
    prior = totals[NDELAY-1] + delay*(count-NDELAY-1);
  }
  if( prior + delay > timeout ){
    delay = timeout - prior;
    if( delay<=0 ) return 0;
  }
  sqlite3OsSleep(delay);
  return 1;
#else
  int timeout = (int)Timeout;
  if( (count+1)*1000 > timeout ){
    return 0;
  }
  sqlite3OsSleep(1000);
  return 1;
#endif
}




















/*
** This routine sets the busy callback for an Sqlite database to the
** given callback function with the given argument.
*/
int sqlite3_busy_handler(
  sqlite3 *db,
  int (*xBusy)(void*,int),
  void *pArg
){
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  db->busyHandler.xFunc = xBusy;
  db->busyHandler.pArg = pArg;

  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** This routine sets the progress callback for an Sqlite database to the
** given callback function with the given argument. The progress callback will
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369

/*
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
int sqlite3_busy_timeout(sqlite3 *db, int ms){
  if( ms>0 ){
    db->busyTimeout = ms;
    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
  }else{
    sqlite3_busy_handler(db, 0, 0);
  }
  return SQLITE_OK;
}

/*







<
|







660
661
662
663
664
665
666

667
668
669
670
671
672
673
674

/*
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
int sqlite3_busy_timeout(sqlite3 *db, int ms){
  if( ms>0 ){

    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)(ptr)ms);
  }else{
    sqlite3_busy_handler(db, 0, 0);
  }
  return SQLITE_OK;
}

/*
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477

478
479
480
481


482

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
    }else{
      sqlite3ExpirePreparedStatements(db);
    }
  }

  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);
  if( p==0 ) return SQLITE_NOMEM;
  p->flags = 0;
  p->xFunc = xFunc;
  p->xStep = xStep;
  p->xFinalize = xFinal;
  p->pUserData = pUserData;
  return SQLITE_OK;
}
#ifndef SQLITE_OMIT_UTF16
int sqlite3_create_function16(
  sqlite3 *db,
  const void *zFunctionName,
  int nArg,
  int eTextRep,
  void *pUserData,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
){
  int rc;
  char *zFunc8;


  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }


  zFunc8 = sqlite3utf16to8(zFunctionName, -1);

  if( !zFunc8 ){
    return SQLITE_NOMEM;
  }
  rc = sqlite3_create_function(db, zFunc8, nArg, eTextRep, 
      pUserData, xFunc, xStep, xFinal);
  sqliteFree(zFunc8);
  return rc;
}
#endif

#ifndef SQLITE_OMIT_TRACE
/*
** Register a trace function.  The pArg from the previously registered trace
** is returned.  
**
** A NULL trace function means that no tracing is executes.  A non-NULL
** trace is a pointer to a function that is invoked at the start of each
** SQL statement.
*/
void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
  void *pOld = db->pTraceArg;
  db->xTrace = xTrace;
  db->pTraceArg = pArg;
  return pOld;
}
/*
** Register a profile function.  The pArg from the previously registered 
** profile function is returned.  
**
** A NULL profile function means that no profiling is executes.  A non-NULL
** profile is a pointer to a function that is invoked at the conclusion of
** each SQL statement that is run.
*/
void *sqlite3_profile(
  sqlite3 *db,
  void (*xProfile)(void*,const char*,sqlite_uint64),
  void *pArg
){
  void *pOld = db->pProfileArg;
  db->xProfile = xProfile;
  db->pProfileArg = pArg;
  return pOld;
}
#endif /* SQLITE_OMIT_TRACE */

/*** EXPERIMENTAL ***
**
** Register a function to be invoked when a transaction comments.
** If the invoked function returns non-zero, then the commit becomes a
** rollback.
*/
void *sqlite3_commit_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  int (*xCallback)(void*),  /* Function to invoke on each commit */
  void *pArg                /* Argument to the function */
){
  void *pOld = db->pCommitArg;
  db->xCommitCallback = xCallback;
  db->pCommitArg = pArg;
  return pOld;
}

/*
** Register a callback to be invoked each time a row is updated,
** inserted or deleted using this database connection.
*/
void *sqlite3_update_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
  void *pArg                /* Argument to the function */
){
  void *pRet = db->pUpdateArg;
  db->xUpdateCallback = xCallback;
  db->pUpdateArg = pArg;
  return pRet;
}

/*
** Register a callback to be invoked each time a transaction is rolled
** back by this database connection.
*/
void *sqlite3_rollback_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  void (*xCallback)(void*), /* Callback function */
  void *pArg                /* Argument to the function */
){
  void *pRet = db->pRollbackArg;
  db->xRollbackCallback = xCallback;
  db->pRollbackArg = pArg;
  return pRet;
}

/*
** This routine is called to create a connection to a database BTree
** driver.  If zFilename is the name of a file, then that file is
** opened and used.  If zFilename is the magic name ":memory:" then
** the database is stored in memory (and is thus forgotten as soon as
** the connection is closed.)  If zFilename is NULL then the database
** is a "virtual" database for transient use only and is deleted as
** soon as the connection is closed.
**
** A virtual database can be either a disk file (that is automatically
** deleted when the file is closed) or it an be held entirely in memory,
** depending on the values of the TEMP_STORE compile-time macro and the
** db->temp_store variable, according to the following chart:
**
**       TEMP_STORE     db->temp_store     Location of temporary database
**       ----------     --------------     ------------------------------
**           0               any             file
**           1                1              file







<


















|
>




>
>
|
>





<




<






|







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|













<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
|

|
|







756
757
758
759
760
761
762

763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795

796
797
798
799

800
801
802
803
804
805
806
807
808
809
810
811
812
813



















814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831





























832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
    }else{
      sqlite3ExpirePreparedStatements(db);
    }
  }

  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);
  if( p==0 ) return SQLITE_NOMEM;

  p->xFunc = xFunc;
  p->xStep = xStep;
  p->xFinalize = xFinal;
  p->pUserData = pUserData;
  return SQLITE_OK;
}
#ifndef SQLITE_OMIT_UTF16
int sqlite3_create_function16(
  sqlite3 *db,
  const void *zFunctionName,
  int nArg,
  int eTextRep,
  void *pUserData,
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  void (*xFinal)(sqlite3_context*)
){
  int rc;
  char const *zFunc8;
  sqlite3_value *pTmp;

  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  pTmp = sqlite3GetTransientValue(db);
  sqlite3ValueSetStr(pTmp, -1, zFunctionName, SQLITE_UTF16NATIVE,SQLITE_STATIC);
  zFunc8 = sqlite3ValueText(pTmp, SQLITE_UTF8);

  if( !zFunc8 ){
    return SQLITE_NOMEM;
  }
  rc = sqlite3_create_function(db, zFunc8, nArg, eTextRep, 
      pUserData, xFunc, xStep, xFinal);

  return rc;
}
#endif


/*
** Register a trace function.  The pArg from the previously registered trace
** is returned.  
**
** A NULL trace function means that no tracing is executes.  A non-NULL
** trace is a pointer to a function that is invoked at the start of each
** sqlite3_exec().
*/
void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
  void *pOld = db->pTraceArg;
  db->xTrace = xTrace;
  db->pTraceArg = pArg;
  return pOld;
}




















/*** EXPERIMENTAL ***
**
** Register a function to be invoked when a transaction comments.
** If either function returns non-zero, then the commit becomes a
** rollback.
*/
void *sqlite3_commit_hook(
  sqlite3 *db,              /* Attach the hook to this database */
  int (*xCallback)(void*),  /* Function to invoke on each commit */
  void *pArg                /* Argument to the function */
){
  void *pOld = db->pCommitArg;
  db->xCommitCallback = xCallback;
  db->pCommitArg = pArg;
  return pOld;
}































/*
** This routine is called to create a connection to a database BTree
** driver.  If zFilename is the name of a file, then that file is
** opened and used.  If zFilename is the magic name ":memory:" then
** the database is stored in memory (and is thus forgotten as soon as
** the connection is closed.)  If zFilename is NULL then the database
** is for temporary use only and is deleted as soon as the connection
** is closed.
**
** A temporary database can be either a disk file (that is automatically
** deleted when the file is closed) or a set of red-black trees held in memory,
** depending on the values of the TEMP_STORE compile-time macro and the
** db->temp_store variable, according to the following chart:
**
**       TEMP_STORE     db->temp_store     Location of temporary database
**       ----------     --------------     ------------------------------
**           0               any             file
**           1                1              file
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
#endif
#if TEMP_STORE==3
    zFilename = ":memory:";
#endif
#endif /* SQLITE_OMIT_MEMORYDB */
  }

  rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btree_flags);
  if( rc==SQLITE_OK ){
    sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler);
    sqlite3BtreeSetCacheSize(*ppBtree, nCache);
  }
  return rc;
}

/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite3_errmsg(sqlite3 *db){
  const char *z;
  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    return sqlite3ErrStr(SQLITE_NOMEM);
  }
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return sqlite3ErrStr(SQLITE_MISUSE);
  }
  z = (char*)sqlite3_value_text(db->pErr);
  if( z==0 ){
    z = sqlite3ErrStr(db->errCode);
  }
  return z;
}

#ifndef SQLITE_OMIT_UTF16







|













|





|







885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
#endif
#if TEMP_STORE==3
    zFilename = ":memory:";
#endif
#endif /* SQLITE_OMIT_MEMORYDB */
  }

  rc = sqlite3BtreeOpen(zFilename, ppBtree, btree_flags);
  if( rc==SQLITE_OK ){
    sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler);
    sqlite3BtreeSetCacheSize(*ppBtree, nCache);
  }
  return rc;
}

/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite3_errmsg(sqlite3 *db){
  const char *z;
  if( sqlite3_malloc_failed ){
    return sqlite3ErrStr(SQLITE_NOMEM);
  }
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return sqlite3ErrStr(SQLITE_MISUSE);
  }
  z = sqlite3_value_text(db->pErr);
  if( z==0 ){
    z = sqlite3ErrStr(db->errCode);
  }
  return z;
}

#ifndef SQLITE_OMIT_UTF16
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717




















































































































































718
719
720



721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738

739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764

765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
    0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
  };

  const void *z;
  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
  }
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
  }
  z = sqlite3_value_text16(db->pErr);
  if( z==0 ){
    sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
         SQLITE_UTF8, SQLITE_STATIC);
    z = sqlite3_value_text16(db->pErr);
  }
  return z;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Return the most recent error code generated by an SQLite routine. If NULL is
** passed to this function, we assume a malloc() failed during sqlite3_open().
*/
int sqlite3_errcode(sqlite3 *db){
  if( !db || sqlite3ThreadDataReadOnly()->mallocFailed ){
    return SQLITE_NOMEM;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  return db->errCode;
}

/*




















































































































































** This routine does the work of opening a database on behalf of
** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"  
** is UTF-8 encoded.



*/
static int openDatabase(
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb         /* OUT: Returned database handle */
){
  sqlite3 *db;
  int rc;
  CollSeq *pColl;

  assert( !sqlite3ThreadDataReadOnly()->mallocFailed );

  /* Allocate the sqlite data structure */
  db = sqliteMalloc( sizeof(sqlite3) );
  if( db==0 ) goto opendb_out;
  db->priorNewRowid = 0;
  db->magic = SQLITE_MAGIC_BUSY;
  db->nDb = 2;
  db->aDb = db->aDbStatic;

  db->autoCommit = 1;
  db->flags |= SQLITE_ShortColNames;
  sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);

#if 0
  for(i=0; i<db->nDb; i++){
    sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1);
  }
#endif
 
  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
  ** and UTF-16, so add a version for each to avoid any unnecessary
  ** conversions. The only error that can occur here is a malloc() failure.
  */
  if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
      sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
      (db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0 
  ){
    /* sqlite3_create_collation() is an external API. So the mallocFailed flag
    ** will have been cleared before returning. So set it explicitly here.
    */
    sqlite3ThreadData()->mallocFailed = 1;

    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }

  /* Also add a UTF-8 case-insensitive collation sequence. */
  sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);

  /* Set flags on the built-in collating sequences */
  db->pDfltColl->type = SQLITE_COLL_BINARY;
  pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "NOCASE", 6, 0);
  if( pColl ){
    pColl->type = SQLITE_COLL_NOCASE;
  }

  /* Open the backend database driver */
  rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
  if( rc!=SQLITE_OK ){
    sqlite3Error(db, rc, 0);
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }
#ifndef SQLITE_OMIT_PARSER
  db->aDb[0].pSchema = sqlite3SchemaGet(db->aDb[0].pBt);
  db->aDb[1].pSchema = sqlite3SchemaGet(0);
#endif

  if( db->aDb[0].pSchema ){
    ENC(db) = SQLITE_UTF8;
  }

  /* The default safety_level for the main database is 'full'; for the temp
  ** database it is 'NONE'. This matches the pager layer defaults.  
  */
  db->aDb[0].zName = "main";
  db->aDb[0].safety_level = 3;
#ifndef SQLITE_OMIT_TEMPDB
  db->aDb[1].zName = "temp";
  db->aDb[1].safety_level = 1;
#endif

  /* Register all built-in functions, but do not attempt to read the
  ** database schema yet. This is delayed until the first time the database
  ** is accessed.
  */
  sqlite3RegisterBuiltinFunctions(db);
  sqlite3Error(db, SQLITE_OK, 0);
  db->magic = SQLITE_MAGIC_OPEN;

opendb_out:
  if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
    sqlite3_close(db);
    db = 0;
  }
  *ppDb = db;
  sqlite3MallocClearFailed();
  return rc;
}

/*
** Open a new database handle.
*/
int sqlite3_open(
  const char *zFilename, 







|
















|
<


|









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


|
>
>
>






|
<
<
<








>




<
<






<
|






|
<
<
<
<
|
>







<
<
<
<
<
<
<







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

<
<

<










|
|
<


<
|







938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962

963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135



1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148


1149
1150
1151
1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
1162




1163
1164
1165
1166
1167
1168
1169
1170
1171







1172
1173
1174
1175
1176
1177
1178




1179
1180

1181

1182
1183


1184


1185

1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197

1198
1199

1200
1201
1202
1203
1204
1205
1206
1207
    0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
  };

  const void *z;
  if( sqlite3_malloc_failed ){
    return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
  }
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
  }
  z = sqlite3_value_text16(db->pErr);
  if( z==0 ){
    sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
         SQLITE_UTF8, SQLITE_STATIC);
    z = sqlite3_value_text16(db->pErr);
  }
  return z;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Return the most recent error code generated by an SQLite routine.

*/
int sqlite3_errcode(sqlite3 *db){
  if( sqlite3_malloc_failed ){
    return SQLITE_NOMEM;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  return db->errCode;
}

/*
** Check schema cookies in all databases.  If any cookie is out
** of date, return 0.  If all schema cookies are current, return 1.
*/
static int schemaIsValid(sqlite3 *db){
  int iDb;
  int rc;
  BtCursor *curTemp;
  int cookie;
  int allOk = 1;

  for(iDb=0; allOk && iDb<db->nDb; iDb++){
    Btree *pBt;
    pBt = db->aDb[iDb].pBt;
    if( pBt==0 ) continue;
    rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp);
    if( rc==SQLITE_OK ){
      rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie);
      if( rc==SQLITE_OK && cookie!=db->aDb[iDb].schema_cookie ){
        allOk = 0;
      }
      sqlite3BtreeCloseCursor(curTemp);
    }
  }
  return allOk;
}

/*
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
*/
int sqlite3_prepare(
  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char** pzTail       /* OUT: End of parsed string */
){
  Parse sParse;
  char *zErrMsg = 0;
  int rc = SQLITE_OK;

  if( sqlite3_malloc_failed ){
    return SQLITE_NOMEM;
  }

  assert( ppStmt );
  *ppStmt = 0;
  if( sqlite3SafetyOn(db) ){
    return SQLITE_MISUSE;
  }

  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sqlite3RunParser(&sParse, zSql, &zErrMsg);

  if( sqlite3_malloc_failed ){
    rc = SQLITE_NOMEM;
    sqlite3RollbackAll(db);
    sqlite3ResetInternalSchema(db, 0);
    db->flags &= ~SQLITE_InTrans;
    goto prepare_out;
  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){
    sParse.rc = SQLITE_SCHEMA;
  }
  if( sParse.rc==SQLITE_SCHEMA ){
    sqlite3ResetInternalSchema(db, 0);
  }
  if( pzTail ) *pzTail = sParse.zTail;
  rc = sParse.rc;

#ifndef SQLITE_OMIT_EXPLAIN
  if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
    sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
    sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC);
    sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC);
    sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC);
    sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC);
    sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC);
  } 
#endif

prepare_out:
  if( sqlite3SafetyOff(db) ){
    rc = SQLITE_MISUSE;
  }
  if( rc==SQLITE_OK ){
    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
  }else if( sParse.pVdbe ){
    sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
  }

  if( zErrMsg ){
    sqlite3Error(db, rc, "%s", zErrMsg);
    sqliteFree(zErrMsg);
  }else{
    sqlite3Error(db, rc, 0);
  }
  return rc;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
*/
int sqlite3_prepare16(
  sqlite3 *db,              /* Database handle. */ 
  const void *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const void **pzTail       /* OUT: End of parsed string */
){
  /* This function currently works by first transforming the UTF-16
  ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
  ** tricky bit is figuring out the pointer to return in *pzTail.
  */
  char const *zSql8 = 0;
  char const *zTail8 = 0;
  int rc;
  sqlite3_value *pTmp;

  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  pTmp = sqlite3GetTransientValue(db);
  sqlite3ValueSetStr(pTmp, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zSql8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
  if( !zSql8 ){
    sqlite3Error(db, SQLITE_NOMEM, 0);
    return SQLITE_NOMEM;
  }
  rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8);

  if( zTail8 && pzTail ){
    /* If sqlite3_prepare returns a tail pointer, we calculate the
    ** equivalent pointer into the UTF-16 string by counting the unicode
    ** characters between zSql8 and zTail8, and then returning a pointer
    ** the same number of characters into the UTF-16 string.
    */
    int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8);
    *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed);
  }
 
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** This routine does the work of opening a database on behalf of
** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"  
** is UTF-8 encoded. The fourth argument, "def_enc" is one of the TEXT_*
** macros from sqliteInt.h. If we end up creating a new database file
** (not opening an existing one), the text encoding of the database
** will be set to this value.
*/
static int openDatabase(
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb         /* OUT: Returned database handle */
){
  sqlite3 *db;
  int rc, i;




  /* Allocate the sqlite data structure */
  db = sqliteMalloc( sizeof(sqlite3) );
  if( db==0 ) goto opendb_out;
  db->priorNewRowid = 0;
  db->magic = SQLITE_MAGIC_BUSY;
  db->nDb = 2;
  db->aDb = db->aDbStatic;
  db->enc = SQLITE_UTF8;
  db->autoCommit = 1;
  db->flags |= SQLITE_ShortColNames;
  sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);


  for(i=0; i<db->nDb; i++){
    sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1);
  }

  
  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
  ** and UTF-16, so add a version for each to avoid any unnecessary
  ** conversions. The only error that can occur here is a malloc() failure.
  */
  if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
      sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
      !(db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0)) ){




    rc = db->errCode;
    assert( rc!=SQLITE_OK );
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }

  /* Also add a UTF-8 case-insensitive collation sequence. */
  sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);








  /* Open the backend database driver */
  rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
  if( rc!=SQLITE_OK ){
    sqlite3Error(db, rc, 0);
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }




  db->aDb[0].zName = "main";
  db->aDb[1].zName = "temp";



  /* The default safety_level for the main database is 'full' for the temp
  ** database it is 'NONE'. This matches the pager layer defaults.  */


  db->aDb[0].safety_level = 3;


  db->aDb[1].safety_level = 1;


  /* Register all built-in functions, but do not attempt to read the
  ** database schema yet. This is delayed until the first time the database
  ** is accessed.
  */
  sqlite3RegisterBuiltinFunctions(db);
  sqlite3Error(db, SQLITE_OK, 0);
  db->magic = SQLITE_MAGIC_OPEN;

opendb_out:
  if( sqlite3_errcode(db)==SQLITE_OK && sqlite3_malloc_failed ){
    sqlite3Error(db, SQLITE_NOMEM, 0);

  }
  *ppDb = db;

  return sqlite3_errcode(db);
}

/*
** Open a new database handle.
*/
int sqlite3_open(
  const char *zFilename, 
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859

860

861
862
863
864
865
866
867
  const void *zFilename, 
  sqlite3 **ppDb
){
  char const *zFilename8;   /* zFilename encoded in UTF-8 instead of UTF-16 */
  int rc = SQLITE_NOMEM;
  sqlite3_value *pVal;

  assert( zFilename );
  assert( ppDb );
  *ppDb = 0;
  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zFilename8 ){
    rc = openDatabase(zFilename8, ppDb);
    if( rc==SQLITE_OK && *ppDb ){
      rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
    }
  }else{
    assert( sqlite3ThreadDataReadOnly()->mallocFailed );
    sqlite3MallocClearFailed();
  }

  sqlite3ValueFree(pVal);


  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** The following routine destroys a virtual machine that is created by







<








|

<
<
<

>
|
>







1218
1219
1220
1221
1222
1223
1224

1225
1226
1227
1228
1229
1230
1231
1232
1233
1234



1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
  const void *zFilename, 
  sqlite3 **ppDb
){
  char const *zFilename8;   /* zFilename encoded in UTF-8 instead of UTF-16 */
  int rc = SQLITE_NOMEM;
  sqlite3_value *pVal;


  assert( ppDb );
  *ppDb = 0;
  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zFilename8 ){
    rc = openDatabase(zFilename8, ppDb);
    if( rc==SQLITE_OK && *ppDb ){
      sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
    }



  }
  if( pVal ){
    sqlite3ValueFree(pVal);
  }

  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** The following routine destroys a virtual machine that is created by
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
*/
int sqlite3_reset(sqlite3_stmt *pStmt){
  int rc;
  if( pStmt==0 ){
    rc = SQLITE_OK;
  }else{
    rc = sqlite3VdbeReset((Vdbe*)pStmt);
    sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0);
  }
  return rc;
}

/*
** Register a new collation sequence with the database handle db.
*/







|







1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
*/
int sqlite3_reset(sqlite3_stmt *pStmt){
  int rc;
  if( pStmt==0 ){
    rc = SQLITE_OK;
  }else{
    rc = sqlite3VdbeReset((Vdbe*)pStmt);
    sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0, 0);
  }
  return rc;
}

/*
** Register a new collation sequence with the database handle db.
*/
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978


979
980
981
982
983
984
985
986
987
988
989
      return SQLITE_BUSY;
    }
    sqlite3ExpirePreparedStatements(db);
  }

  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
  if( 0==pColl ){
    rc = SQLITE_NOMEM;
  }else{
    pColl->xCmp = xCompare;
    pColl->pUser = pCtx;
    pColl->enc = enc;
  }
  sqlite3Error(db, rc, 0);
  return rc;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Register a new collation sequence with the database handle db.
*/
int sqlite3_create_collation16(
  sqlite3* db, 
  const char *zName, 
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*)
){
  char *zName8;
  int rc;
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }


  zName8 = sqlite3utf16to8(zName, -1);
  rc = sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);
  sqliteFree(zName8);
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/







|




















|
|



>
>
|
|
<
<







1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360


1361
1362
1363
1364
1365
1366
1367
      return SQLITE_BUSY;
    }
    sqlite3ExpirePreparedStatements(db);
  }

  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
  if( 0==pColl ){
   rc = SQLITE_NOMEM;
  }else{
    pColl->xCmp = xCompare;
    pColl->pUser = pCtx;
    pColl->enc = enc;
  }
  sqlite3Error(db, rc, 0);
  return rc;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Register a new collation sequence with the database handle db.
*/
int sqlite3_create_collation16(
  sqlite3* db, 
  const char *zName, 
  int enc, 
  void* pCtx,
  int(*xCompare)(void*,int,const void*,int,const void*)
){
  char const *zName8;
  sqlite3_value *pTmp;
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  pTmp = sqlite3GetTransientValue(db);
  sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zName8 = sqlite3ValueText(pTmp, SQLITE_UTF8);
  return sqlite3_create_collation(db, zName8, enc, pCtx, xCompare);


}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
  }
  db->xCollNeeded = 0;
  db->xCollNeeded16 = xCollNeeded16;
  db->pCollNeededArg = pCollNeededArg;
  return SQLITE_OK;
}
#endif /* SQLITE_OMIT_UTF16 */

#ifndef SQLITE_OMIT_GLOBALRECOVER
/*
** This function is now an anachronism. It used to be used to recover from a
** malloc() failure, but SQLite now does this automatically.
*/
int sqlite3_global_recover(){
  return SQLITE_OK;
}
#endif

/*
** Test to see whether or not the database connection is in autocommit
** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on
** by default.  Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_get_autocommit(sqlite3 *db){
  return db->autoCommit;
}

#ifdef SQLITE_DEBUG
/*
** The following routine is subtituted for constant SQLITE_CORRUPT in
** debugging builds.  This provides a way to set a breakpoint for when
** corruption is first detected.
*/
int sqlite3Corrupt(void){
  return SQLITE_CORRUPT;
}
#endif


#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** Enable or disable the shared pager and schema features for the
** current thread.
**
** This routine should only be called when there are no open
** database connections.
*/
int sqlite3_enable_shared_cache(int enable){
  ThreadData *pTd = sqlite3ThreadData();
  
  /* It is only legal to call sqlite3_enable_shared_cache() when there
  ** are no currently open b-trees that were opened by the calling thread.
  ** This condition is only easy to detect if the shared-cache were 
  ** previously enabled (and is being disabled). 
  */
  if( pTd->pBtree && !enable ){
    assert( pTd->useSharedData );
    return SQLITE_MISUSE;
  }

  pTd->useSharedData = enable;
  sqlite3ReleaseThreadData();
  return SQLITE_OK;
}
#endif

/*
** This is a convenience routine that makes sure that all thread-specific
** data for this thread has been deallocated.
*/
void sqlite3_thread_cleanup(void){
  ThreadData *pTd = sqlite3ThreadData();
  memset(pTd, 0, sizeof(*pTd));
  sqlite3ReleaseThreadData();
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1394
1395
1396
1397
1398
1399
1400







































































  }
  db->xCollNeeded = 0;
  db->xCollNeeded16 = xCollNeeded16;
  db->pCollNeededArg = pCollNeededArg;
  return SQLITE_OK;
}
#endif /* SQLITE_OMIT_UTF16 */







































































Deleted SQLite.Interop/src/md5.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
/*
** SQLite uses this code for testing only.  It is not a part of
** the SQLite library.  This file implements two new TCL commands
** "md5" and "md5file" that compute md5 checksums on arbitrary text
** and on complete files.  These commands are used by the "testfixture"
** program to help verify the correct operation of the SQLite library.
**
** The original use of these TCL commands was to test the ROLLBACK
** feature of SQLite.  First compute the MD5-checksum of the database.
** Then make some changes but rollback the changes rather than commit
** them.  Compute a second MD5-checksum of the file and verify that the
** two checksums are the same.  Such is the original use of this code.
** New uses may have been added since this comment was written.
*/
/*
 * This code implements the MD5 message-digest algorithm.
 * The algorithm is due to Ron Rivest.  This code was
 * written by Colin Plumb in 1993, no copyright is claimed.
 * This code is in the public domain; do with it what you wish.
 *
 * Equivalent code is available from RSA Data Security, Inc.
 * This code has been tested against that, and is equivalent,
 * except that you don't need to include two pages of legalese
 * with every copy.
 *
 * To compute the message digest of a chunk of bytes, declare an
 * MD5Context structure, pass it to MD5Init, call MD5Update as
 * needed on buffers full of bytes, and then call MD5Final, which
 * will fill a supplied 16-byte array with the digest.
 */
#include <tcl.h>
#include <string.h>
#include "sqlite3.h"

/*
 * If compiled on a machine that doesn't have a 32-bit integer,
 * you just set "uint32" to the appropriate datatype for an
 * unsigned 32-bit integer.  For example:
 *
 *       cc -Duint32='unsigned long' md5.c
 *
 */
#ifndef uint32
#  define uint32 unsigned int
#endif

struct Context {
  uint32 buf[4];
  uint32 bits[2];
  unsigned char in[64];
};
typedef char MD5Context[88];

/*
 * Note: this code is harmless on little-endian machines.
 */
static void byteReverse (unsigned char *buf, unsigned longs){
        uint32 t;
        do {
                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
                            ((unsigned)buf[1]<<8 | buf[0]);
                *(uint32 *)buf = t;
                buf += 4;
        } while (--longs);
}
/* The four core functions - F1 is optimized somewhat */

/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))

/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )

/*
 * The core of the MD5 algorithm, this alters an existing MD5 hash to
 * reflect the addition of 16 longwords of new data.  MD5Update blocks
 * the data and converts bytes into longwords for this routine.
 */
static void MD5Transform(uint32 buf[4], const uint32 in[16]){
        register uint32 a, b, c, d;

        a = buf[0];
        b = buf[1];
        c = buf[2];
        d = buf[3];

        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);

        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);

        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);

        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);

        buf[0] += a;
        buf[1] += b;
        buf[2] += c;
        buf[3] += d;
}

/*
 * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
 * initialization constants.
 */
static void MD5Init(MD5Context *pCtx){
        struct Context *ctx = (struct Context *)pCtx;
        ctx->buf[0] = 0x67452301;
        ctx->buf[1] = 0xefcdab89;
        ctx->buf[2] = 0x98badcfe;
        ctx->buf[3] = 0x10325476;
        ctx->bits[0] = 0;
        ctx->bits[1] = 0;
}

/*
 * Update context to reflect the concatenation of another buffer full
 * of bytes.
 */
static 
void MD5Update(MD5Context *pCtx, const unsigned char *buf, unsigned int len){
        struct Context *ctx = (struct Context *)pCtx;
        uint32 t;

        /* Update bitcount */

        t = ctx->bits[0];
        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
                ctx->bits[1]++; /* Carry from low to high */
        ctx->bits[1] += len >> 29;

        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */

        /* Handle any leading odd-sized chunks */

        if ( t ) {
                unsigned char *p = (unsigned char *)ctx->in + t;

                t = 64-t;
                if (len < t) {
                        memcpy(p, buf, len);
                        return;
                }
                memcpy(p, buf, t);
                byteReverse(ctx->in, 16);
                MD5Transform(ctx->buf, (uint32 *)ctx->in);
                buf += t;
                len -= t;
        }

        /* Process data in 64-byte chunks */

        while (len >= 64) {
                memcpy(ctx->in, buf, 64);
                byteReverse(ctx->in, 16);
                MD5Transform(ctx->buf, (uint32 *)ctx->in);
                buf += 64;
                len -= 64;
        }

        /* Handle any remaining bytes of data. */

        memcpy(ctx->in, buf, len);
}

/*
 * Final wrapup - pad to 64-byte boundary with the bit pattern 
 * 1 0* (64-bit count of bits processed, MSB-first)
 */
static void MD5Final(unsigned char digest[16], MD5Context *pCtx){
        struct Context *ctx = (struct Context *)pCtx;
        unsigned count;
        unsigned char *p;

        /* Compute number of bytes mod 64 */
        count = (ctx->bits[0] >> 3) & 0x3F;

        /* Set the first char of padding to 0x80.  This is safe since there is
           always at least one byte free */
        p = ctx->in + count;
        *p++ = 0x80;

        /* Bytes of padding needed to make 64 bytes */
        count = 64 - 1 - count;

        /* Pad out to 56 mod 64 */
        if (count < 8) {
                /* Two lots of padding:  Pad the first block to 64 bytes */
                memset(p, 0, count);
                byteReverse(ctx->in, 16);
                MD5Transform(ctx->buf, (uint32 *)ctx->in);

                /* Now fill the next block with 56 bytes */
                memset(ctx->in, 0, 56);
        } else {
                /* Pad block to 56 bytes */
                memset(p, 0, count-8);
        }
        byteReverse(ctx->in, 14);

        /* Append length in bits and transform */
        ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
        ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];

        MD5Transform(ctx->buf, (uint32 *)ctx->in);
        byteReverse((unsigned char *)ctx->buf, 4);
        memcpy(digest, ctx->buf, 16);
        memset(ctx, 0, sizeof(ctx));    /* In case it's sensitive */
}

/*
** Convert a digest into base-16.  digest should be declared as
** "unsigned char digest[16]" in the calling function.  The MD5
** digest is stored in the first 16 bytes.  zBuf should
** be "char zBuf[33]".
*/
static void DigestToBase16(unsigned char *digest, char *zBuf){
  static char const zEncode[] = "0123456789abcdef";
  int i, j;

  for(j=i=0; i<16; i++){
    int a = digest[i];
    zBuf[j++] = zEncode[(a>>4)&0xf];
    zBuf[j++] = zEncode[a & 0xf];
  }
  zBuf[j] = 0;
}

/*
** A TCL command for md5.  The argument is the text to be hashed.  The
** Result is the hash in base64.  
*/
static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
  MD5Context ctx;
  unsigned char digest[16];

  if( argc!=2 ){
    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 
        " TEXT\"", 0);
    return TCL_ERROR;
  }
  MD5Init(&ctx);
  MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
  MD5Final(digest, &ctx);
  DigestToBase16(digest, interp->result);
  return TCL_OK;
}

/*
** A TCL command to take the md5 hash of a file.  The argument is the
** name of the file.
*/
static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){
  FILE *in;
  MD5Context ctx;
  unsigned char digest[16];
  char zBuf[10240];

  if( argc!=2 ){
    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 
        " FILENAME\"", 0);
    return TCL_ERROR;
  }
  in = fopen(argv[1],"rb");
  if( in==0 ){
    Tcl_AppendResult(interp,"unable to open file \"", argv[1], 
         "\" for reading", 0);
    return TCL_ERROR;
  }
  MD5Init(&ctx);
  for(;;){
    int n;
    n = fread(zBuf, 1, sizeof(zBuf), in);
    if( n<=0 ) break;
    MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
  }
  fclose(in);
  MD5Final(digest, &ctx);
  DigestToBase16(digest, interp->result);
  return TCL_OK;
}

/*
** Register the two TCL commands above with the TCL interpreter.
*/
int Md5_Init(Tcl_Interp *interp){
  Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd, 0, 0);
  Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd, 0, 0);
  return TCL_OK;
}

/*
** During testing, the special md5sum() aggregate function is available.
** inside SQLite.  The following routines implement that function.
*/
static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
  MD5Context *p;
  int i;
  if( argc<1 ) return;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p==0 ) return;
  if( sqlite3_aggregate_count(context)==1 ){
    MD5Init(p);
  }
  for(i=0; i<argc; i++){
    const char *zData = (char*)sqlite3_value_text(argv[i]);
    if( zData ){
      MD5Update(p, (unsigned char*)zData, strlen(zData));
    }
  }
}
static void md5finalize(sqlite3_context *context){
  MD5Context *p;
  unsigned char digest[16];
  char zBuf[33];
  p = sqlite3_aggregate_context(context, sizeof(*p));
  MD5Final(digest,p);
  DigestToBase16(digest, zBuf);
  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
void Md5_Register(sqlite3 *db){
  sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, 
      md5step, md5finalize);
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































Changes to SQLite.Interop/src/opcodes.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69














70
71
72



73

74
75
76
77
78
79
80
81
82
83
84

85


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134


135
136
137
138
139
140
141
142
143
144
145
146
147
/* Automatically generated.  Do not edit */
/* See the mkopcodec.awk script for details. */
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
const char *const sqlite3OpcodeNames[] = { "?",
 /*   1 */ "MemLoad",
 /* 125 */ "HexBlob",
 /*   2 */ "Column",
 /*   3 */ "SetCookie",
 /*   4 */ "IfMemPos",
 /* 124 */ "Real",
 /*   5 */ "Sequence",
 /*   6 */ "MoveGt",
 /*  71 */ "Ge",
 /*   7 */ "RowKey",
 /*  67 */ "Eq",
 /*   8 */ "OpenWrite",
 /*  65 */ "NotNull",
 /*   9 */ "If",
 /* 140 */ "ToInt",
 /*  86 */ "String8",
 /*  10 */ "Pop",
 /*  11 */ "CollSeq",
 /*  12 */ "OpenRead",
 /*  13 */ "Expire",
 /*  14 */ "AutoCommit",
 /*  68 */ "Gt",
 /*  15 */ "IntegrityCk",

 /*  17 */ "Sort",
 /*  18 */ "Function",
 /*  60 */ "And",
 /*  78 */ "Subtract",
 /*  19 */ "Noop",
 /*  20 */ "Return",
 /*  81 */ "Remainder",
 /*  21 */ "NewRowid",
 /*  79 */ "Multiply",
 /*  22 */ "IfMemNeg",
 /*  23 */ "Variable",
 /*  24 */ "String",
 /*  25 */ "RealAffinity",
 /*  26 */ "ParseSchema",
 /*  27 */ "Close",
 /*  28 */ "CreateIndex",
 /*  29 */ "IsUnique",
 /*  30 */ "IdxIsNull",
 /*  31 */ "NotFound",
 /*  32 */ "Int64",
 /*  33 */ "MustBeInt",
 /*  34 */ "Halt",
 /*  35 */ "Rowid",
 /*  36 */ "IdxLT",
 /*  37 */ "AddImm",
 /*  38 */ "Statement",
 /*  39 */ "RowData",
 /*  40 */ "MemMax",
 /*  41 */ "Push",
 /*  59 */ "Or",
 /*  42 */ "NotExists",
 /*  43 */ "MemIncr",
 /*  44 */ "Gosub",
 /*  80 */ "Divide",
 /*  45 */ "Integer",
 /* 139 */ "ToNumeric",
 /*  46 */ "MemInt",
 /*  47 */ "Prev",
 /*  82 */ "Concat",
 /*  73 */ "BitAnd",
 /*  48 */ "CreateTable",
 /*  49 */ "Last",














 /*  64 */ "IsNull",
 /*  50 */ "IdxRowid",
 /*  51 */ "MakeIdxRec",



 /*  76 */ "ShiftRight",

 /*  52 */ "ResetCount",
 /*  53 */ "FifoWrite",
 /*  54 */ "Callback",
 /*  55 */ "ContextPush",
 /*  56 */ "DropTrigger",
 /*  57 */ "DropIndex",
 /*  58 */ "IdxGE",
 /*  61 */ "IdxDelete",
 /*  62 */ "Vacuum",
 /*  63 */ "MoveLe",
 /*  72 */ "IfNot",

 /*  84 */ "DropTable",


 /*  87 */ "MakeRecord",
 /* 138 */ "ToBlob",
 /*  88 */ "Delete",
 /*  89 */ "AggFinal",
 /*  75 */ "ShiftLeft",
 /*  90 */ "Dup",
 /*  91 */ "Goto",
 /*  92 */ "TableLock",
 /*  93 */ "FifoRead",
 /*  94 */ "Clear",
 /*  95 */ "IdxGT",
 /*  96 */ "MoveLt",
 /*  69 */ "Le",
 /*  97 */ "VerifyCookie",
 /*  98 */ "AggStep",
 /*  99 */ "Pull",
 /* 137 */ "ToText",
 /*  16 */ "Not",

 /* 141 */ "ToReal",

 /* 100 */ "SetNumColumns",
 /* 101 */ "AbsValue",
 /* 102 */ "Transaction",
 /*  83 */ "Negative",
 /*  66 */ "Ne",
 /* 103 */ "ContextPop",
 /*  74 */ "BitOr",
 /* 104 */ "Next",
 /* 105 */ "IdxInsert",
 /* 106 */ "Distinct",
 /*  70 */ "Lt",
 /* 107 */ "Insert",
 /* 108 */ "Destroy",
 /* 109 */ "ReadCookie",
 /* 110 */ "ForceInt",
 /* 111 */ "LoadAnalysis",
 /* 112 */ "OpenVirtual",
 /* 113 */ "Explain",
 /* 114 */ "IfMemZero",
 /* 115 */ "OpenPseudo",
 /* 116 */ "Null",
 /* 117 */ "Blob",
 /*  77 */ "Add",
 /* 118 */ "MemStore",
 /* 119 */ "Rewind",
 /* 120 */ "MoveGe",
 /*  85 */ "BitNot",
 /* 121 */ "MemMove",
 /* 122 */ "MemNull",
 /* 123 */ "Found",


 /* 126 */ "NullRow",
 /* 127 */ "NotUsed_127",
 /* 128 */ "NotUsed_128",
 /* 129 */ "NotUsed_129",
 /* 130 */ "NotUsed_130",
 /* 131 */ "NotUsed_131",
 /* 132 */ "NotUsed_132",
 /* 133 */ "NotUsed_133",
 /* 134 */ "NotUsed_134",
 /* 135 */ "NotUsed_135",
 /* 136 */ "NotUsed_136",
};
#endif




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



|
|
<
<
<
<
<


1
2
3
4
5

6
7
8

9
10

11

12

13


14
15
16
17
18

19
20
21
22


23
24

25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
48

49

50
51


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

92
93

94
95
96
97
98
99






100
101
102
103
104
105
106


107

108
109
110

111
112
113
114
115
116
117
118
119
120
121

122
123
124

125
126
127
128
129
130
131
132
133
134
135





136
137
/* Automatically generated.  Do not edit */
/* See the mkopcodec.awk script for details. */
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
const char *const sqlite3OpcodeNames[] = { "?",
 /*   1 */ "ContextPop",

 /*   2 */ "IntegrityCk",
 /*   3 */ "DropTrigger",
 /*   4 */ "DropIndex",

 /*   5 */ "Recno",
 /*   6 */ "KeyAsData",

 /*   7 */ "Delete",

 /*   8 */ "MoveGt",

 /*   9 */ "VerifyCookie",


 /*  10 */ "Push",
 /*  11 */ "Dup",
 /*  12 */ "Blob",
 /*  13 */ "IdxGT",
 /*  14 */ "IdxRecno",

 /*  15 */ "RowKey",
 /*  16 */ "PutStrKey",
 /*  17 */ "IsUnique",
 /*  18 */ "SetNumColumns",


 /*  19 */ "Expire",
 /*  20 */ "IdxIsNull",

 /*  21 */ "NullRow",

 /*  22 */ "OpenPseudo",
 /*  23 */ "OpenWrite",
 /*  24 */ "OpenRead",
 /*  25 */ "Transaction",
 /*  26 */ "AutoCommit",
 /*  27 */ "Pop",
 /*  28 */ "Halt",
 /*  29 */ "Vacuum",
 /*  30 */ "ListRead",
 /*  31 */ "RowData",
 /*  32 */ "NotExists",
 /*  33 */ "MoveLe",
 /*  34 */ "SetCookie",
 /*  35 */ "Variable",
 /*  36 */ "AggNext",
 /*  37 */ "AggReset",
 /*  38 */ "Sort",
 /*  39 */ "AggContextPush",
 /*  40 */ "IdxDelete",
 /*  41 */ "ResetCount",

 /*  42 */ "OpenTemp",
 /*  43 */ "Integer",
 /*  44 */ "AggSet",

 /*  45 */ "CreateIndex",

 /*  46 */ "IdxPut",
 /*  47 */ "MoveLt",


 /*  48 */ "Return",
 /*  49 */ "MemLoad",
 /*  50 */ "SortNext",
 /*  51 */ "IdxLT",
 /*  52 */ "Rewind",
 /*  53 */ "AddImm",
 /*  54 */ "AggFunc",
 /*  55 */ "AggInit",
 /*  56 */ "MemIncr",
 /*  57 */ "ListReset",
 /*  58 */ "Clear",
 /*  59 */ "PutIntKey",
 /*  60 */ "If",
 /*  61 */ "Callback",
 /*  62 */ "SortReset",
 /*  63 */ "SortPut",
 /*  64 */ "Or",
 /*  65 */ "And",
 /*  66 */ "Not",
 /*  67 */ "AggContextPop",
 /*  68 */ "Last",
 /*  69 */ "NotFound",
 /*  70 */ "IsNull",
 /*  71 */ "NotNull",
 /*  72 */ "Ne",
 /*  73 */ "Eq",
 /*  74 */ "Gt",
 /*  75 */ "Le",
 /*  76 */ "Lt",
 /*  77 */ "Ge",
 /*  78 */ "MakeRecord",
 /*  79 */ "BitAnd",
 /*  80 */ "BitOr",
 /*  81 */ "ShiftLeft",
 /*  82 */ "ShiftRight",
 /*  83 */ "Add",
 /*  84 */ "Subtract",
 /*  85 */ "Multiply",
 /*  86 */ "Divide",
 /*  87 */ "Remainder",

 /*  88 */ "Concat",
 /*  89 */ "Negative",

 /*  90 */ "String",
 /*  91 */ "BitNot",
 /*  92 */ "String8",
 /*  93 */ "Goto",
 /*  94 */ "AggFocus",
 /*  95 */ "IfMemPos",






 /*  96 */ "DropTable",
 /*  97 */ "Column",
 /*  98 */ "Noop",
 /*  99 */ "AggGet",
 /* 100 */ "CreateTable",
 /* 101 */ "NewRecno",
 /* 102 */ "Found",


 /* 103 */ "Distinct",

 /* 104 */ "Close",
 /* 105 */ "Statement",
 /* 106 */ "IfNot",

 /* 107 */ "Pull",
 /* 108 */ "MemMax",
 /* 109 */ "MemStore",
 /* 110 */ "Next",
 /* 111 */ "Prev",
 /* 112 */ "MoveGe",
 /* 113 */ "MustBeInt",
 /* 114 */ "ForceInt",
 /* 115 */ "CollSeq",
 /* 116 */ "Gosub",
 /* 117 */ "ContextPush",

 /* 118 */ "ListRewind",
 /* 119 */ "ListWrite",
 /* 120 */ "ParseSchema",

 /* 121 */ "Destroy",
 /* 122 */ "IdxGE",
 /* 123 */ "FullKey",
 /* 124 */ "ReadCookie",
 /* 125 */ "AbsValue",
 /* 126 */ "Function",
 /* 127 */ "NotUsed_127",
 /* 128 */ "NotUsed_128",
 /* 129 */ "NotUsed_129",
 /* 130 */ "Real",
 /* 131 */ "HexBlob",





};
#endif
Changes to SQLite.Interop/src/opcodes.h.
1
2
























3




4
5




6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102


103
104
105
106
107

108
109
110
111


112


113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/* Automatically generated.  Do not edit */
/* See the mkopcodeh.awk script for details */
























#define OP_MemLoad                              1




#define OP_HexBlob                            125   /* same as TK_BLOB     */
#define OP_Column                               2




#define OP_SetCookie                            3
#define OP_IfMemPos                             4
#define OP_Real                               124   /* same as TK_FLOAT    */
#define OP_Sequence                             5
#define OP_MoveGt                               6
#define OP_Ge                                  71   /* same as TK_GE       */
#define OP_RowKey                               7
#define OP_Eq                                  67   /* same as TK_EQ       */
#define OP_OpenWrite                            8
#define OP_NotNull                             65   /* same as TK_NOTNULL  */
#define OP_If                                   9
#define OP_ToInt                              140   /* same as TK_TO_INT   */
#define OP_String8                             86   /* same as TK_STRING   */
#define OP_Pop                                 10
#define OP_CollSeq                             11
#define OP_OpenRead                            12
#define OP_Expire                              13
#define OP_AutoCommit                          14
#define OP_Gt                                  68   /* same as TK_GT       */
#define OP_IntegrityCk                         15
#define OP_Sort                                17
#define OP_Function                            18
#define OP_And                                 60   /* same as TK_AND      */
#define OP_Subtract                            78   /* same as TK_MINUS    */
#define OP_Noop                                19
#define OP_Return                              20
#define OP_Remainder                           81   /* same as TK_REM      */
#define OP_NewRowid                            21
#define OP_Multiply                            79   /* same as TK_STAR     */
#define OP_IfMemNeg                            22
#define OP_Variable                            23
#define OP_String                              24
#define OP_RealAffinity                        25
#define OP_ParseSchema                         26
#define OP_Close                               27
#define OP_CreateIndex                         28
#define OP_IsUnique                            29
#define OP_IdxIsNull                           30
#define OP_NotFound                            31
#define OP_Int64                               32
#define OP_MustBeInt                           33
#define OP_Halt                                34
#define OP_Rowid                               35
#define OP_IdxLT                               36


#define OP_AddImm                              37
#define OP_Statement                           38
#define OP_RowData                             39
#define OP_MemMax                              40
#define OP_Push                                41
#define OP_Or                                  59   /* same as TK_OR       */
#define OP_NotExists                           42
#define OP_MemIncr                             43
#define OP_Gosub                               44
#define OP_Divide                              80   /* same as TK_SLASH    */
#define OP_Integer                             45
#define OP_ToNumeric                          139   /* same as TK_TO_NUMERIC*/
#define OP_MemInt                              46
#define OP_Prev                                47
#define OP_Concat                              82   /* same as TK_CONCAT   */
#define OP_BitAnd                              73   /* same as TK_BITAND   */
#define OP_CreateTable                         48
#define OP_Last                                49
#define OP_IsNull                              64   /* same as TK_ISNULL   */
#define OP_IdxRowid                            50
#define OP_MakeIdxRec                          51
#define OP_ShiftRight                          76   /* same as TK_RSHIFT   */
#define OP_ResetCount                          52
#define OP_FifoWrite                           53
#define OP_Callback                            54
#define OP_ContextPush                         55
#define OP_DropTrigger                         56
#define OP_DropIndex                           57
#define OP_IdxGE                               58
#define OP_IdxDelete                           61
#define OP_Vacuum                              62
#define OP_MoveLe                              63
#define OP_IfNot                               72
#define OP_DropTable                           84
#define OP_MakeRecord                          87
#define OP_ToBlob                             138   /* same as TK_TO_BLOB  */
#define OP_Delete                              88
#define OP_AggFinal                            89
#define OP_ShiftLeft                           75   /* same as TK_LSHIFT   */
#define OP_Dup                                 90
#define OP_Goto                                91
#define OP_TableLock                           92
#define OP_FifoRead                            93
#define OP_Clear                               94
#define OP_IdxGT                               95
#define OP_MoveLt                              96
#define OP_Le                                  69   /* same as TK_LE       */
#define OP_VerifyCookie                        97
#define OP_AggStep                             98
#define OP_Pull                                99
#define OP_ToText                             137   /* same as TK_TO_TEXT  */
#define OP_Not                                 16   /* same as TK_NOT      */
#define OP_ToReal                             141   /* same as TK_TO_REAL  */


#define OP_SetNumColumns                      100
#define OP_AbsValue                           101
#define OP_Transaction                        102
#define OP_Negative                            83   /* same as TK_UMINUS   */
#define OP_Ne                                  66   /* same as TK_NE       */

#define OP_ContextPop                         103
#define OP_BitOr                               74   /* same as TK_BITOR    */
#define OP_Next                               104
#define OP_IdxInsert                          105


#define OP_Distinct                           106


#define OP_Lt                                  70   /* same as TK_LT       */
#define OP_Insert                             107
#define OP_Destroy                            108
#define OP_ReadCookie                         109
#define OP_ForceInt                           110
#define OP_LoadAnalysis                       111
#define OP_OpenVirtual                        112
#define OP_Explain                            113
#define OP_IfMemZero                          114
#define OP_OpenPseudo                         115
#define OP_Null                               116
#define OP_Blob                               117
#define OP_Add                                 77   /* same as TK_PLUS     */
#define OP_MemStore                           118
#define OP_Rewind                             119
#define OP_MoveGe                             120
#define OP_BitNot                              85   /* same as TK_BITNOT   */
#define OP_MemMove                            121
#define OP_MemNull                            122
#define OP_Found                              123
#define OP_NullRow                            126

/* The following opcode values are never used */
#define OP_NotUsed_127                        127
#define OP_NotUsed_128                        128
#define OP_NotUsed_129                        129
#define OP_NotUsed_130                        130
#define OP_NotUsed_131                        131
#define OP_NotUsed_132                        132
#define OP_NotUsed_133                        133
#define OP_NotUsed_134                        134
#define OP_NotUsed_135                        135
#define OP_NotUsed_136                        136

#define NOPUSH_MASK_0 32600
#define NOPUSH_MASK_1 61019
#define NOPUSH_MASK_2 40822
#define NOPUSH_MASK_3 65522
#define NOPUSH_MASK_4 65535
#define NOPUSH_MASK_5 56123
#define NOPUSH_MASK_6 53215
#define NOPUSH_MASK_7 18893
#define NOPUSH_MASK_8 15872
#define NOPUSH_MASK_9 0


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





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50






51
52
53

54







55
56
57



58
59

60
61

62
63
64
65
66
67
68



69
70

71


72




73
74




75
76
77
78




79
80
81
82

83
84
85
86
87


88
89

90
91


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

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


















/* Automatically generated.  Do not edit */
/* See the mkopcodeh.awk script for details */
#define OP_ContextPop                           1
#define OP_IntegrityCk                          2
#define OP_DropTrigger                          3
#define OP_DropIndex                            4
#define OP_Recno                                5
#define OP_KeyAsData                            6
#define OP_Delete                               7
#define OP_MoveGt                               8
#define OP_VerifyCookie                         9
#define OP_Push                                10
#define OP_Dup                                 11
#define OP_Blob                                12
#define OP_IdxGT                               13
#define OP_IdxRecno                            14
#define OP_RowKey                              15
#define OP_PutStrKey                           16
#define OP_IsUnique                            17
#define OP_SetNumColumns                       18
#define OP_Eq                                  73   /* same as TK_EQ       */
#define OP_Expire                              19
#define OP_IdxIsNull                           20
#define OP_NullRow                             21
#define OP_OpenPseudo                          22
#define OP_OpenWrite                           23
#define OP_OpenRead                            24
#define OP_Transaction                         25
#define OP_AutoCommit                          26
#define OP_Negative                            89   /* same as TK_UMINUS   */
#define OP_Pop                                 27
#define OP_Halt                                28
#define OP_Vacuum                              29
#define OP_ListRead                            30
#define OP_RowData                             31
#define OP_NotExists                           32
#define OP_MoveLe                              33
#define OP_SetCookie                           34
#define OP_Variable                            35
#define OP_AggNext                             36
#define OP_AggReset                            37
#define OP_Sort                                38
#define OP_AggContextPush                      39
#define OP_IdxDelete                           40
#define OP_ResetCount                          41
#define OP_OpenTemp                            42
#define OP_NotNull                             71   /* same as TK_NOTNULL  */
#define OP_Ge                                  77   /* same as TK_GE       */
#define OP_Remainder                           87   /* same as TK_REM      */
#define OP_Divide                              86   /* same as TK_SLASH    */






#define OP_Integer                             43
#define OP_AggSet                              44
#define OP_CreateIndex                         45

#define OP_IdxPut                              46







#define OP_MoveLt                              47
#define OP_And                                 65   /* same as TK_AND      */
#define OP_ShiftLeft                           81   /* same as TK_LSHIFT   */



#define OP_Real                               130   /* same as TK_FLOAT    */
#define OP_Return                              48

#define OP_MemLoad                             49
#define OP_SortNext                            50

#define OP_IdxLT                               51
#define OP_Rewind                              52
#define OP_Gt                                  74   /* same as TK_GT       */
#define OP_AddImm                              53
#define OP_Subtract                            84   /* same as TK_MINUS    */
#define OP_AggFunc                             54
#define OP_AggInit                             55



#define OP_MemIncr                             56
#define OP_ListReset                           57

#define OP_Clear                               58


#define OP_PutIntKey                           59




#define OP_IsNull                              70   /* same as TK_ISNULL   */
#define OP_If                                  60




#define OP_Callback                            61
#define OP_SortReset                           62
#define OP_SortPut                             63
#define OP_AggContextPop                       67




#define OP_Last                                68
#define OP_NotFound                            69
#define OP_MakeRecord                          78
#define OP_BitAnd                              79   /* same as TK_BITAND   */

#define OP_Add                                 83   /* same as TK_PLUS     */
#define OP_HexBlob                            131   /* same as TK_BLOB     */
#define OP_String                              90
#define OP_Goto                                93
#define OP_AggFocus                            94


#define OP_IfMemPos                            95
#define OP_DropTable                           96

#define OP_Column                              97
#define OP_Noop                                98


#define OP_Not                                 66   /* same as TK_NOT      */
#define OP_Le                                  75   /* same as TK_LE       */
#define OP_BitOr                               80   /* same as TK_BITOR    */
#define OP_Multiply                            85   /* same as TK_STAR     */
#define OP_String8                             92   /* same as TK_STRING   */
#define OP_AggGet                              99
#define OP_CreateTable                        100
#define OP_NewRecno                           101
#define OP_Found                              102
#define OP_Distinct                           103
#define OP_Close                              104
#define OP_Statement                          105
#define OP_IfNot                              106
#define OP_Pull                               107
#define OP_MemMax                             108
#define OP_MemStore                           109
#define OP_Next                               110
#define OP_Prev                               111
#define OP_MoveGe                             112
#define OP_Lt                                  76   /* same as TK_LT       */
#define OP_Ne                                  72   /* same as TK_NE       */
#define OP_MustBeInt                          113

#define OP_ForceInt                           114
#define OP_ShiftRight                          82   /* same as TK_RSHIFT   */
#define OP_CollSeq                            115
#define OP_Gosub                              116
#define OP_ContextPush                        117
#define OP_ListRewind                         118
#define OP_ListWrite                          119
#define OP_ParseSchema                        120
#define OP_Destroy                            121
#define OP_IdxGE                              122
#define OP_FullKey                            123
#define OP_ReadCookie                         124
#define OP_BitNot                              91   /* same as TK_BITNOT   */
#define OP_AbsValue                           125
#define OP_Or                                  64   /* same as TK_OR       */
#define OP_Function                           126
#define OP_Concat                              88   /* same as TK_CONCAT   */

/* The following opcode values are never used */
#define OP_NotUsed_127                        127
#define OP_NotUsed_128                        128
#define OP_NotUsed_129                        129


















Deleted SQLite.Interop/src/os.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
** 2005 November 29
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains OS interface code that is common to all
** architectures.
*/
#define _SQLITE_OS_C_ 1
#include "sqliteInt.h"
#include "os.h"

/*
** The following routines are convenience wrappers around methods
** of the OsFile object.  This is mostly just syntactic sugar.  All
** of this would be completely automatic if SQLite were coded using
** C++ instead of plain old C.
*/
int sqlite3OsClose(OsFile **pId){
  OsFile *id;
  if( pId!=0 && (id = *pId)!=0 ){
    return id->pMethod->xClose(pId);
  }else{
    return SQLITE_OK;
  }
}
int sqlite3OsOpenDirectory(OsFile *id, const char *zName){
  return id->pMethod->xOpenDirectory(id, zName);
}
int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
  return id->pMethod->xRead(id, pBuf, amt);
}
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
  return id->pMethod->xWrite(id, pBuf, amt);
}
int sqlite3OsSeek(OsFile *id, i64 offset){
  return id->pMethod->xSeek(id, offset);
}
int sqlite3OsTruncate(OsFile *id, i64 size){
  return id->pMethod->xTruncate(id, size);
}
int sqlite3OsSync(OsFile *id, int fullsync){
  return id->pMethod->xSync(id, fullsync);
}
void sqlite3OsSetFullSync(OsFile *id, int value){
  id->pMethod->xSetFullSync(id, value);
}
int sqlite3OsFileHandle(OsFile *id){
  return id->pMethod->xFileHandle(id);
}
int sqlite3OsFileSize(OsFile *id, i64 *pSize){
  return id->pMethod->xFileSize(id, pSize);
}
int sqlite3OsLock(OsFile *id, int lockType){
  return id->pMethod->xLock(id, lockType);
}
int sqlite3OsUnlock(OsFile *id, int lockType){
  return id->pMethod->xUnlock(id, lockType);
}
int sqlite3OsLockState(OsFile *id){
  return id->pMethod->xLockState(id);
}
int sqlite3OsCheckReservedLock(OsFile *id){
  return id->pMethod->xCheckReservedLock(id);
}

#ifdef SQLITE_ENABLE_REDEF_IO
/*
** A function to return a pointer to the virtual function table.
** This routine really does not accomplish very much since the
** virtual function table is a global variable and anybody who
** can call this function can just as easily access the variable
** for themselves.  Nevertheless, we include this routine for
** backwards compatibility with an earlier redefinable I/O
** interface design.
*/
struct sqlite3OsVtbl *sqlite3_os_switch(void){
  return &sqlite3Os;
}
#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































Changes to SQLite.Interop/src/os.h.
14
15
16
17
18
19
20
21
22


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
** "os.c") attempt to abstract the underlying operating system so that
** the SQLite library will work on both POSIX and windows systems.
*/
#ifndef _SQLITE_OS_H_
#define _SQLITE_OS_H_

/*
** Figure out if we are dealing with Unix, Windows, or some other
** operating system.


*/
#if !defined(OS_UNIX) && !defined(OS_OTHER)
# define OS_OTHER 0
# ifndef OS_WIN
#   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
#     define OS_WIN 1
#     define OS_UNIX 0
#   else
#     define OS_WIN 0
#     define OS_UNIX 1
#  endif
# else
#  define OS_UNIX 0
# endif
#else
# ifndef OS_WIN
#  define OS_WIN 0
# endif
#endif


/*
** Define the maximum size of a temporary filename
*/
#if OS_WIN
# include <windows.h>
# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
#else
# define SQLITE_TEMPNAME_SIZE 200


#endif

/* If the SET_FULLSYNC macro is not defined above, then make it
** a no-op
*/
#ifndef SET_FULLSYNC
# define SET_FULLSYNC(x,y)
#endif

/*
** Temporary files are named starting with this prefix followed by 16 random
** alphanumeric characters, and no file extension. They are stored in the
** OS's standard temporary file directory, and are deleted prior to exit.
** If sqlite is being embedded in another program, you may wish to change the
** prefix to reflect your program's name, so that if your program exits
** prematurely, old temporary files can be easily identified. This can be done
** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
*/
#ifndef TEMP_FILE_PREFIX
# define TEMP_FILE_PREFIX "sqlite_"
#endif

/*
** Define the interfaces for Unix and for Windows.
*/
#if OS_UNIX
#define sqlite3OsOpenReadWrite      sqlite3UnixOpenReadWrite
#define sqlite3OsOpenExclusive      sqlite3UnixOpenExclusive
#define sqlite3OsOpenReadOnly       sqlite3UnixOpenReadOnly
#define sqlite3OsDelete             sqlite3UnixDelete
#define sqlite3OsFileExists         sqlite3UnixFileExists
#define sqlite3OsFullPathname       sqlite3UnixFullPathname
#define sqlite3OsIsDirWritable      sqlite3UnixIsDirWritable
#define sqlite3OsSyncDirectory      sqlite3UnixSyncDirectory
#define sqlite3OsTempFileName       sqlite3UnixTempFileName
#define sqlite3OsRandomSeed         sqlite3UnixRandomSeed
#define sqlite3OsSleep              sqlite3UnixSleep
#define sqlite3OsCurrentTime        sqlite3UnixCurrentTime
#define sqlite3OsEnterMutex         sqlite3UnixEnterMutex
#define sqlite3OsLeaveMutex         sqlite3UnixLeaveMutex
#define sqlite3OsInMutex            sqlite3UnixInMutex
#define sqlite3OsThreadSpecificData sqlite3UnixThreadSpecificData
#define sqlite3OsMalloc             sqlite3GenericMalloc
#define sqlite3OsRealloc            sqlite3GenericRealloc
#define sqlite3OsFree               sqlite3GenericFree
#define sqlite3OsAllocationSize     sqlite3GenericAllocationSize
#endif
#if OS_WIN
#define sqlite3OsOpenReadWrite      sqlite3WinOpenReadWrite
#define sqlite3OsOpenExclusive      sqlite3WinOpenExclusive
#define sqlite3OsOpenReadOnly       sqlite3WinOpenReadOnly
#define sqlite3OsDelete             sqlite3WinDelete
#define sqlite3OsFileExists         sqlite3WinFileExists
#define sqlite3OsFullPathname       sqlite3WinFullPathname
#define sqlite3OsIsDirWritable      sqlite3WinIsDirWritable
#define sqlite3OsSyncDirectory      sqlite3WinSyncDirectory
#define sqlite3OsTempFileName       sqlite3WinTempFileName
#define sqlite3OsRandomSeed         sqlite3WinRandomSeed
#define sqlite3OsSleep              sqlite3WinSleep
#define sqlite3OsCurrentTime        sqlite3WinCurrentTime
#define sqlite3OsEnterMutex         sqlite3WinEnterMutex
#define sqlite3OsLeaveMutex         sqlite3WinLeaveMutex
#define sqlite3OsInMutex            sqlite3WinInMutex
#define sqlite3OsThreadSpecificData sqlite3WinThreadSpecificData
#define sqlite3OsMalloc             sqlite3GenericMalloc
#define sqlite3OsRealloc            sqlite3GenericRealloc
#define sqlite3OsFree               sqlite3GenericFree
#define sqlite3OsAllocationSize     sqlite3GenericAllocationSize
#endif

/*
** If using an alternative OS interface, then we must have an "os_other.h"
** header file available for that interface.  Presumably the "os_other.h"
** header file contains #defines similar to those above.
*/
#if OS_OTHER
# include "os_other.h"
#endif



/*
** Forward declarations
*/
typedef struct OsFile OsFile;
typedef struct IoMethod IoMethod;

/*
** An instance of the following structure contains pointers to all
** methods on an OsFile object.
*/
struct IoMethod {
  int (*xClose)(OsFile**);
  int (*xOpenDirectory)(OsFile*, const char*);
  int (*xRead)(OsFile*, void*, int amt);
  int (*xWrite)(OsFile*, const void*, int amt);
  int (*xSeek)(OsFile*, i64 offset);
  int (*xTruncate)(OsFile*, i64 size);
  int (*xSync)(OsFile*, int);
  void (*xSetFullSync)(OsFile *id, int setting);
  int (*xFileHandle)(OsFile *id);
  int (*xFileSize)(OsFile*, i64 *pSize);
  int (*xLock)(OsFile*, int);
  int (*xUnlock)(OsFile*, int);
  int (*xLockState)(OsFile *id);
  int (*xCheckReservedLock)(OsFile *id);
};

/*
** The OsFile object describes an open disk file in an OS-dependent way.
** The version of OsFile defined here is a generic version.  Each OS
** implementation defines its own subclass of this structure that contains
** additional information needed to handle file I/O.  But the pMethod
** entry (pointing to the virtual function table) always occurs first
** so that we can always find the appropriate methods.
*/
struct OsFile {
  IoMethod const *pMethod;
};

/*
** The following values may be passed as the second argument to
** sqlite3OsLock(). The various locks exhibit the following semantics:
**
** SHARED:    Any number of processes may hold a SHARED lock simultaneously.
** RESERVED:  A single process may hold a RESERVED lock on a file at
**            any time. Other processes may hold and obtain new SHARED locks.







|
|
>
>

|
<

















<

|

|
|
<
|
<
>
>

|
<
<
<
|
<















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48

49

50
51
52
53



54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69


































































































70
71
72
73
74
75
76
** "os.c") attempt to abstract the underlying operating system so that
** the SQLite library will work on both POSIX and windows systems.
*/
#ifndef _SQLITE_OS_H_
#define _SQLITE_OS_H_

/*
** Figure out if we are dealing with Unix, Windows or MacOS.
**
** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix.
**      The MacOS build is designed to use CodeWarrior (tested with v8)
*/
#if !defined(OS_UNIX) && !defined(OS_TEST)

# ifndef OS_WIN
#   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
#     define OS_WIN 1
#     define OS_UNIX 0
#   else
#     define OS_WIN 0
#     define OS_UNIX 1
#  endif
# else
#  define OS_UNIX 0
# endif
#else
# ifndef OS_WIN
#  define OS_WIN 0
# endif
#endif


/*
** Invoke the appropriate operating-system specific header file.
*/
#if OS_TEST
# include "os_test.h"

#endif

#if OS_UNIX
# include "os_unix.h"
#endif
#if OS_WIN



# include "os_win.h"

#endif

/*
** Temporary files are named starting with this prefix followed by 16 random
** alphanumeric characters, and no file extension. They are stored in the
** OS's standard temporary file directory, and are deleted prior to exit.
** If sqlite is being embedded in another program, you may wish to change the
** prefix to reflect your program's name, so that if your program exits
** prematurely, old temporary files can be easily identified. This can be done
** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
*/
#ifndef TEMP_FILE_PREFIX
# define TEMP_FILE_PREFIX "sqlite_"
#endif



































































































/*
** The following values may be passed as the second argument to
** sqlite3OsLock(). The various locks exhibit the following semantics:
**
** SHARED:    Any number of processes may hold a SHARED lock simultaneously.
** RESERVED:  A single process may hold a RESERVED lock on a file at
**            any time. Other processes may hold and obtain new SHARED locks.
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
** WinNT reader will lock out all other Win95 readers.
**
** The following #defines specify the range of bytes used for locking.
** SHARED_SIZE is the number of bytes available in the pool from which
** a random byte is selected for a shared lock.  The pool of bytes for
** shared locks begins at SHARED_FIRST. 
**
** These #defines are available in sqlite_aux.h so that adaptors for
** connecting SQLite to other operating systems can use the same byte
** ranges for locking.  In particular, the same locking strategy and
** byte ranges are used for Unix.  This leaves open the possiblity of having
** clients on win95, winNT, and unix all talking to the same shared file
** and all locking correctly.  To do so would require that samba (or whatever
** tool is being used for file sharing) implements locks correctly between
** windows and unix.  I'm guessing that isn't likely to happen, but by
** using the same locking range we are at least open to the possibility.
**
** Locking in windows is manditory.  For this reason, we cannot store







|
<
<
|







117
118
119
120
121
122
123
124


125
126
127
128
129
130
131
132
** WinNT reader will lock out all other Win95 readers.
**
** The following #defines specify the range of bytes used for locking.
** SHARED_SIZE is the number of bytes available in the pool from which
** a random byte is selected for a shared lock.  The pool of bytes for
** shared locks begins at SHARED_FIRST. 
**
** These #defines are available in os.h so that Unix can use the same


** byte ranges for locking.  This leaves open the possiblity of having
** clients on win95, winNT, and unix all talking to the same shared file
** and all locking correctly.  To do so would require that samba (or whatever
** tool is being used for file sharing) implements locks correctly between
** windows and unix.  I'm guessing that isn't likely to happen, but by
** using the same locking range we are at least open to the possibility.
**
** Locking in windows is manditory.  For this reason, we cannot store
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266



267




268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
** Changing the value of PENDING_BYTE results in a subtly incompatible
** file format.  Depending on how it is changed, you might not notice
** the incompatibility right away, even running a full regression test.
** The default location of PENDING_BYTE is the first byte past the
** 1GB boundary.
**
*/
#ifndef SQLITE_TEST
#define PENDING_BYTE      0x40000000  /* First byte past the 1GB boundary */
#else
extern unsigned int sqlite3_pending_byte;
#define PENDING_BYTE sqlite3_pending_byte
#endif

#define RESERVED_BYTE     (PENDING_BYTE+1)
#define SHARED_FIRST      (PENDING_BYTE+2)
#define SHARED_SIZE       510

/*
** Prototypes for operating system interface routines.
*/
int sqlite3OsClose(OsFile**);



int sqlite3OsOpenDirectory(OsFile*, const char*);




int sqlite3OsRead(OsFile*, void*, int amt);
int sqlite3OsWrite(OsFile*, const void*, int amt);
int sqlite3OsSeek(OsFile*, i64 offset);
int sqlite3OsTruncate(OsFile*, i64 size);
int sqlite3OsSync(OsFile*, int);
void sqlite3OsSetFullSync(OsFile *id, int setting);
int sqlite3OsFileHandle(OsFile *id);
int sqlite3OsFileSize(OsFile*, i64 *pSize);
int sqlite3OsLock(OsFile*, int);
int sqlite3OsUnlock(OsFile*, int);
int sqlite3OsLockState(OsFile *id);
int sqlite3OsCheckReservedLock(OsFile *id);
int sqlite3OsOpenReadWrite(const char*, OsFile**, int*);
int sqlite3OsOpenExclusive(const char*, OsFile**, int);
int sqlite3OsOpenReadOnly(const char*, OsFile**);
int sqlite3OsDelete(const char*);
int sqlite3OsFileExists(const char*);
char *sqlite3OsFullPathname(const char*);
int sqlite3OsIsDirWritable(char*);
int sqlite3OsSyncDirectory(const char*);
int sqlite3OsTempFileName(char*);
int sqlite3OsRandomSeed(char*);
int sqlite3OsSleep(int ms);
int sqlite3OsCurrentTime(double*);

void sqlite3OsEnterMutex(void);
void sqlite3OsLeaveMutex(void);
int sqlite3OsInMutex(void);
ThreadData *sqlite3OsThreadSpecificData(int);
void *sqlite3OsMalloc(int);
void *sqlite3OsRealloc(void *, int);
void sqlite3OsFree(void *);
int sqlite3OsAllocationSize(void *);

/*
** If the SQLITE_ENABLE_REDEF_IO macro is defined, then the OS-layer
** interface routines are not called directly but are invoked using
** pointers to functions.  This allows the implementation of various
** OS-layer interface routines to be modified at run-time.  There are
** obscure but legitimate reasons for wanting to do this.  But for
** most users, a direct call to the underlying interface is preferable
** so the the redefinable I/O interface is turned off by default.
*/
#ifdef SQLITE_ENABLE_REDEF_IO

/*
** When redefinable I/O is enabled, a single global instance of the
** following structure holds pointers to the routines that SQLite 
** uses to talk with the underlying operating system.  Modify this
** structure (before using any SQLite API!) to accomodate perculiar
** operating system interfaces or behaviors.
*/
struct sqlite3OsVtbl {
  int (*xOpenReadWrite)(const char*, OsFile**, int*);
  int (*xOpenExclusive)(const char*, OsFile**, int);
  int (*xOpenReadOnly)(const char*, OsFile**);

  int (*xDelete)(const char*);
  int (*xFileExists)(const char*);
  char *(*xFullPathname)(const char*);
  int (*xIsDirWritable)(char*);
  int (*xSyncDirectory)(const char*);
  int (*xTempFileName)(char*);

  int (*xRandomSeed)(char*);
  int (*xSleep)(int ms);
  int (*xCurrentTime)(double*);

  void (*xEnterMutex)(void);
  void (*xLeaveMutex)(void);
  int (*xInMutex)(void);
  ThreadData *(*xThreadSpecificData)(int);

  void *(*xMalloc)(int);
  void *(*xRealloc)(void *, int);
  void (*xFree)(void *);
  int (*xAllocationSize)(void *);
};

/* Macro used to comment out routines that do not exists when there is
** no disk I/O 
*/
#ifdef SQLITE_OMIT_DISKIO
# define IF_DISKIO(X)  0
#else
# define IF_DISKIO(X)  X
#endif

#ifdef _SQLITE_OS_C_
  /*
  ** The os.c file implements the global virtual function table.
  */
  struct sqlite3OsVtbl sqlite3Os = {
    IF_DISKIO( sqlite3OsOpenReadWrite ),
    IF_DISKIO( sqlite3OsOpenExclusive ),
    IF_DISKIO( sqlite3OsOpenReadOnly ),
    IF_DISKIO( sqlite3OsDelete ),
    IF_DISKIO( sqlite3OsFileExists ),
    IF_DISKIO( sqlite3OsFullPathname ),
    IF_DISKIO( sqlite3OsIsDirWritable ),
    IF_DISKIO( sqlite3OsSyncDirectory ),
    IF_DISKIO( sqlite3OsTempFileName ),
    sqlite3OsRandomSeed,
    sqlite3OsSleep,
    sqlite3OsCurrentTime,
    sqlite3OsEnterMutex,
    sqlite3OsLeaveMutex,
    sqlite3OsInMutex,
    sqlite3OsThreadSpecificData,
    sqlite3OsMalloc,
    sqlite3OsRealloc,
    sqlite3OsFree,
    sqlite3OsAllocationSize
  };
#else
  /*
  ** Files other than os.c just reference the global virtual function table. 
  */
  extern struct sqlite3OsVtbl sqlite3Os;
#endif /* _SQLITE_OS_C_ */


/* This additional API routine is available with redefinable I/O */
struct sqlite3OsVtbl *sqlite3_os_switch(void);


/*
** Redefine the OS interface to go through the virtual function table
** rather than calling routines directly.
*/
#undef sqlite3OsOpenReadWrite
#undef sqlite3OsOpenExclusive
#undef sqlite3OsOpenReadOnly
#undef sqlite3OsDelete
#undef sqlite3OsFileExists
#undef sqlite3OsFullPathname
#undef sqlite3OsIsDirWritable
#undef sqlite3OsSyncDirectory
#undef sqlite3OsTempFileName
#undef sqlite3OsRandomSeed
#undef sqlite3OsSleep
#undef sqlite3OsCurrentTime
#undef sqlite3OsEnterMutex
#undef sqlite3OsLeaveMutex
#undef sqlite3OsInMutex
#undef sqlite3OsThreadSpecificData
#undef sqlite3OsMalloc
#undef sqlite3OsRealloc
#undef sqlite3OsFree
#undef sqlite3OsAllocationSize
#define sqlite3OsOpenReadWrite      sqlite3Os.xOpenReadWrite
#define sqlite3OsOpenExclusive      sqlite3Os.xOpenExclusive
#define sqlite3OsOpenReadOnly       sqlite3Os.xOpenReadOnly
#define sqlite3OsDelete             sqlite3Os.xDelete
#define sqlite3OsFileExists         sqlite3Os.xFileExists
#define sqlite3OsFullPathname       sqlite3Os.xFullPathname
#define sqlite3OsIsDirWritable      sqlite3Os.xIsDirWritable
#define sqlite3OsSyncDirectory      sqlite3Os.xSyncDirectory
#define sqlite3OsTempFileName       sqlite3Os.xTempFileName
#define sqlite3OsRandomSeed         sqlite3Os.xRandomSeed
#define sqlite3OsSleep              sqlite3Os.xSleep
#define sqlite3OsCurrentTime        sqlite3Os.xCurrentTime
#define sqlite3OsEnterMutex         sqlite3Os.xEnterMutex
#define sqlite3OsLeaveMutex         sqlite3Os.xLeaveMutex
#define sqlite3OsInMutex            sqlite3Os.xInMutex
#define sqlite3OsThreadSpecificData sqlite3Os.xThreadSpecificData
#define sqlite3OsMalloc             sqlite3Os.xMalloc
#define sqlite3OsRealloc            sqlite3Os.xRealloc
#define sqlite3OsFree               sqlite3Os.xFree
#define sqlite3OsAllocationSize     sqlite3Os.xAllocationSize

#endif /* SQLITE_ENABLE_REDEF_IO */

#endif /* _SQLITE_OS_H_ */







<

<
<
|
<
<




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



<
|
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<



>


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


141
142
143
144
145
146
147

148


149


150
151
152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167

168

169
170













171
172
173
174
175
176












































































































177




178







179





















180

181
182
** Changing the value of PENDING_BYTE results in a subtly incompatible
** file format.  Depending on how it is changed, you might not notice
** the incompatibility right away, even running a full regression test.
** The default location of PENDING_BYTE is the first byte past the
** 1GB boundary.
**
*/

#define PENDING_BYTE      0x40000000  /* First byte past the 1GB boundary */


/* #define PENDING_BYTE     0x5400   // Page 22 - for testing */


#define RESERVED_BYTE     (PENDING_BYTE+1)
#define SHARED_FIRST      (PENDING_BYTE+2)
#define SHARED_SIZE       510


int sqlite3OsDelete(const char*);

int sqlite3OsFileExists(const char*);
int sqlite3OsOpenReadWrite(const char*, OsFile*, int*);
int sqlite3OsOpenExclusive(const char*, OsFile*, int);
int sqlite3OsOpenReadOnly(const char*, OsFile*);
int sqlite3OsOpenDirectory(const char*, OsFile*);
int sqlite3OsSyncDirectory(const char*);
int sqlite3OsTempFileName(char*);
int sqlite3OsIsDirWritable(char*);
int sqlite3OsClose(OsFile*);
int sqlite3OsRead(OsFile*, void*, int amt);
int sqlite3OsWrite(OsFile*, const void*, int amt);
int sqlite3OsSeek(OsFile*, i64 offset);

int sqlite3OsSync(OsFile*);

int sqlite3OsTruncate(OsFile*, i64 size);
int sqlite3OsFileSize(OsFile*, i64 *pSize);













int sqlite3OsRandomSeed(char*);
int sqlite3OsSleep(int ms);
int sqlite3OsCurrentTime(double*);
int sqlite3OsFileModTime(OsFile*, double*);
void sqlite3OsEnterMutex(void);
void sqlite3OsLeaveMutex(void);












































































































char *sqlite3OsFullPathname(const char*);




int sqlite3OsLock(OsFile*, int);







int sqlite3OsUnlock(OsFile*, int);





















int sqlite3OsCheckReservedLock(OsFile *id);


#endif /* _SQLITE_OS_H_ */
Changes to SQLite.Interop/src/os_common.h.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
** switch.  The following code should catch this problem at compile-time.
*/
#ifdef MEMORY_DEBUG
# error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
#endif


/*
 * When testing, this global variable stores the location of the
 * pending-byte in the database file.
 */
#ifdef SQLITE_TEST
unsigned int sqlite3_pending_byte = 0x40000000;
#endif

int sqlite3_os_trace = 0;
#ifdef SQLITE_DEBUG
static int last_page = 0;
#define SEEK(X)           last_page=(X)
#define TRACE1(X)         if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
#define TRACE2(X,Y)       if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z)     if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)







<
<
<
<
<
<
<
<







24
25
26
27
28
29
30








31
32
33
34
35
36
37
** switch.  The following code should catch this problem at compile-time.
*/
#ifdef MEMORY_DEBUG
# error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
#endif










int sqlite3_os_trace = 0;
#ifdef SQLITE_DEBUG
static int last_page = 0;
#define SEEK(X)           last_page=(X)
#define TRACE1(X)         if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
#define TRACE2(X,Y)       if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z)     if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

/*
** If we compile with the SQLITE_TEST macro set, then the following block
** of code will give us the ability to simulate a disk I/O error.  This
** is used for testing the I/O recovery logic.
*/
#ifdef SQLITE_TEST
int sqlite3_io_error_hit = 0;
int sqlite3_io_error_pending = 0;
int sqlite3_diskfull_pending = 0;
int sqlite3_diskfull = 0;
#define SimulateIOError(A)  \
   if( sqlite3_io_error_pending ) \
     if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
static void local_ioerr(){
  sqlite3_io_error_hit = 1;  /* Really just a place to set a breakpoint */
}
#define SimulateDiskfullError \
   if( sqlite3_diskfull_pending ){ \
     if( sqlite3_diskfull_pending == 1 ){ \
       local_ioerr(); \
       sqlite3_diskfull = 1; \
       return SQLITE_FULL; \
     }else{ \
       sqlite3_diskfull_pending--; \
     } \
   }
#else
#define SimulateIOError(A)
#define SimulateDiskfullError
#endif

/*
** When testing, keep a count of the number of open files.
*/
#ifdef SQLITE_TEST
int sqlite3_open_file_count = 0;
#define OpenCounter(X)  sqlite3_open_file_count+=(X)
#else
#define OpenCounter(X)
#endif

/*
** sqlite3GenericMalloc
** sqlite3GenericRealloc
** sqlite3GenericOsFree
** sqlite3GenericAllocationSize
**
** Implementation of the os level dynamic memory allocation interface in terms
** of the standard malloc(), realloc() and free() found in many operating
** systems. No rocket science here.
**
** There are two versions of these four functions here. The version
** implemented here is only used if memory-management or memory-debugging is
** enabled. This version allocates an extra 8-bytes at the beginning of each
** block and stores the size of the allocation there.
**
** If neither memory-management or debugging is enabled, the second
** set of implementations is used instead.
*/
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || defined (SQLITE_MEMDEBUG)
void *sqlite3GenericMalloc(int n){
  char *p = (char *)malloc(n+8);
  assert(n>0);
  assert(sizeof(int)<=8);
  if( p ){
    *(int *)p = n;
    p += 8;
  }
  return (void *)p;
}
void *sqlite3GenericRealloc(void *p, int n){
  char *p2 = ((char *)p - 8);
  assert(n>0);
  p2 = realloc(p2, n+8);
  if( p2 ){
    *(int *)p2 = n;
    p2 += 8;
  }
  return (void *)p2;
}
void sqlite3GenericFree(void *p){
  assert(p);
  free((void *)((char *)p - 8));
}
int sqlite3GenericAllocationSize(void *p){
  return p ? *(int *)((char *)p - 8) : 0;
}
#else
void *sqlite3GenericMalloc(int n){
  char *p = (char *)malloc(n);
  return (void *)p;
}
void *sqlite3GenericRealloc(void *p, int n){
  assert(n>0);
  p = realloc(p, n);
  return p;
}
void sqlite3GenericFree(void *p){
  assert(p);
  free(p);
}
#if 0   /* Never actually invoked */
int sqlite3GenericAllocationSize(void *p){
  assert(0);
}
#endif
#endif







<


<




|


|
|
<
<
<
<
<
<
<














<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
76
77
78
79
80
81
82

83
84

85
86
87
88
89
90
91
92
93







94
95
96
97
98
99
100
101
102
103
104
105
106
107




































































/*
** If we compile with the SQLITE_TEST macro set, then the following block
** of code will give us the ability to simulate a disk I/O error.  This
** is used for testing the I/O recovery logic.
*/
#ifdef SQLITE_TEST

int sqlite3_io_error_pending = 0;
int sqlite3_diskfull_pending = 0;

#define SimulateIOError(A)  \
   if( sqlite3_io_error_pending ) \
     if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
static void local_ioerr(){
  sqlite3_io_error_pending = 0;  /* Really just a place to set a breakpoint */
}
#define SimulateDiskfullError \
   if( sqlite3_diskfull_pending ) \
     if( sqlite3_diskfull_pending-- == 1 ){ local_ioerr(); return SQLITE_FULL; }







#else
#define SimulateIOError(A)
#define SimulateDiskfullError
#endif

/*
** When testing, keep a count of the number of open files.
*/
#ifdef SQLITE_TEST
int sqlite3_open_file_count = 0;
#define OpenCounter(X)  sqlite3_open_file_count+=(X)
#else
#define OpenCounter(X)
#endif



































































Changes to SQLite.Interop/src/os_unix.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147


148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184
**
** This file contains code that is specific to Unix systems.
*/
#include "sqliteInt.h"
#include "os.h"
#if OS_UNIX              /* This file is used on unix only */

/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it.  If the OS lacks
** large file support, these should be no-ops.
**
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
** on the compiler command line.  This is necessary if you are compiling
** on a recent machine (ex: RedHat 7.2) but you want your code to work
** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
** without this option, LFS is enable.  But LFS does not exist in the kernel
** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
** portability you should omit LFS.
*/
#ifndef SQLITE_DISABLE_LFS
# define _LARGE_FILE       1
# ifndef _FILE_OFFSET_BITS
#   define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif

/*
** standard include files.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>

/*
** If we are to be thread-safe, include the pthreads header and define
** the SQLITE_UNIX_THREADS macro.
*/
#if defined(THREADSAFE) && THREADSAFE
# include <pthread.h>
# define SQLITE_UNIX_THREADS 1
#endif

/*
** Default permissions when creating a new file
*/
#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
#endif



/*
** The unixFile structure is subclass of OsFile specific for the unix
** protability layer.
*/
typedef struct unixFile unixFile;
struct unixFile {
  IoMethod const *pMethod;  /* Always the first entry */
  struct openCnt *pOpen;    /* Info about all open fd's on this inode */
  struct lockInfo *pLock;   /* Info about locks on this inode */
  int h;                    /* The file descriptor */
  unsigned char locktype;   /* The type of lock held on this fd */
  unsigned char isOpen;     /* True if needs to be closed */
  unsigned char fullSync;   /* Use F_FULLSYNC if available */
  int dirfd;                /* File descriptor for the directory */
#ifdef SQLITE_UNIX_THREADS
  pthread_t tid;            /* The thread that "owns" this OsFile */
#endif
};

/*
** Provide the ability to override some OS-layer functions during
** testing.  This is used to simulate OS crashes to verify that 
** commits are atomic even in the event of an OS crash.
*/
#ifdef SQLITE_CRASH_TEST
  extern int sqlite3CrashTestEnable;
  extern int sqlite3CrashOpenReadWrite(const char*, OsFile**, int*);
  extern int sqlite3CrashOpenExclusive(const char*, OsFile**, int);
  extern int sqlite3CrashOpenReadOnly(const char*, OsFile**, int);
# define CRASH_TEST_OVERRIDE(X,A,B,C) \
    if(sqlite3CrashTestEnable){ return X(A,B,C); }
#else
# define CRASH_TEST_OVERRIDE(X,A,B,C)  /* no-op */
#endif


/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"

/*
** Do not include any of the File I/O interface procedures if the
** SQLITE_OMIT_DISKIO macro is defined (indicating that the database
** will be in-memory only)
*/
#ifndef SQLITE_OMIT_DISKIO


/*
** Define various macros that are missing from some systems.
*/
#ifndef O_LARGEFILE
# define O_LARGEFILE 0
#endif
#ifdef SQLITE_DISABLE_LFS
# undef O_LARGEFILE
# define O_LARGEFILE 0
#endif
#ifndef O_NOFOLLOW
# define O_NOFOLLOW 0
#endif
#ifndef O_BINARY
# define O_BINARY 0
#endif


/*
** The DJGPP compiler environment looks mostly like Unix, but it
** lacks the fcntl() system call.  So redefine fcntl() to be something
** that always succeeds.  This means that locking does not occur under
** DJGPP.  But it's DOS - what did you expect?
*/
#ifdef __DJGPP__
# define fcntl(A,B,C) 0
#endif

/*
** The threadid macro resolves to the thread-id or to 0.  Used for
** testing and debugging only.


*/
#ifdef SQLITE_UNIX_THREADS
#define threadid pthread_self()
#else
#define threadid 0
#endif


/*
** Set or check the OsFile.tid field.  This field is set when an OsFile
** is first opened.  All subsequent uses of the OsFile verify that the
** same thread is operating on the OsFile.  Some operating systems do
** not allow locks to be overridden by other threads and that restriction
** means that sqlite3* database handles cannot be moved from one thread
** to another.  This logic makes sure a user does not try to do that
** by mistake.
**
** Version 3.3.1 (2006-01-15):  OsFiles can be moved from one thread to
** another as long as we are running on a system that supports threads
** overriding each others locks (which now the most common behavior)
** or if no locks are held.  But the OsFile.pLock field needs to be
** recomputed because its key includes the thread-id.  See the 
** transferOwnership() function below for additional information
*/

#if defined(SQLITE_UNIX_THREADS)
# define SET_THREADID(X)   (X)->tid = pthread_self()
# define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \
                            !pthread_equal((X)->tid, pthread_self()))
#else
# define SET_THREADID(X)
# define CHECK_THREADID(X) 0
#endif

/*
** Here is the dirt on POSIX advisory locks:  ANSI STD 1003.1 (1996)
** section 6.5.2.2 lines 483 through 490 specify that when a process
** sets or clears a lock, that operation overrides any prior locks set
** by the same process.  It does not explicitly say so, but this implies







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
|
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













>





|






|
|
>
>

|
|
<
|


>

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

>
|
<
<
<
<
|
|







12
13
14
15
16
17
18




















19



20

21
22










































































23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60












61

62
63
64




65
66
67
68
69
70
71
72
73
**
** This file contains code that is specific to Unix systems.
*/
#include "sqliteInt.h"
#include "os.h"
#if OS_UNIX              /* This file is used on unix only */

























#include <time.h>

#include <errno.h>
#include <unistd.h>










































































#ifndef O_LARGEFILE
# define O_LARGEFILE 0
#endif
#ifdef SQLITE_DISABLE_LFS
# undef O_LARGEFILE
# define O_LARGEFILE 0
#endif
#ifndef O_NOFOLLOW
# define O_NOFOLLOW 0
#endif
#ifndef O_BINARY
# define O_BINARY 0
#endif


/*
** The DJGPP compiler environment looks mostly like Unix, but it
** lacks the fcntl() system call.  So redefine fcntl() to be something
** that always succeeds.  This means that locking does not occur under
** DJGPP.  But its DOS - what did you expect?
*/
#ifdef __DJGPP__
# define fcntl(A,B,C) 0
#endif

/*
** Macros used to determine whether or not to use threads.  The
** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for
** Posix threads and SQLITE_W32_THREADS is defined if we are
** synchronizing using Win32 threads.
*/
#if defined(THREADSAFE) && THREADSAFE
# include <pthread.h>

# define SQLITE_UNIX_THREADS 1
#endif


/*












** Include code that is common to all os_*.c files

*/
#include "os_common.h"





#if defined(THREADSAFE) && THREADSAFE && defined(__linux__)
#define getpid pthread_self
#endif

/*
** Here is the dirt on POSIX advisory locks:  ANSI STD 1003.1 (1996)
** section 6.5.2.2 lines 483 through 490 specify that when a process
** sets or clears a lock, that operation overrides any prior locks set
** by the same process.  It does not explicitly say so, but this implies
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

/*
** An instance of the following structure serves as the key used
** to locate a particular lockInfo structure given its inode.
**
** If threads cannot override each others locks, then we set the
** lockKey.tid field to the thread ID.  If threads can override
** each others locks then tid is always set to zero.  tid is omitted
** if we compile without threading support.
*/
struct lockKey {
  dev_t dev;       /* Device number */
  ino_t ino;       /* Inode number */
#ifdef SQLITE_UNIX_THREADS
  pthread_t tid;   /* Thread ID or zero if threads can override each other */
#endif
};

/*
** An instance of the following structure is allocated for each open
** inode on each thread with a different process ID.  (Threads have
** different process IDs on linux, but not on most other unixes.)







|
|





|







168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

/*
** An instance of the following structure serves as the key used
** to locate a particular lockInfo structure given its inode.
**
** If threads cannot override each others locks, then we set the
** lockKey.tid field to the thread ID.  If threads can override
** each others locks then tid is always set to zero.  tid is also
** set to zero if we compile without threading support.
*/
struct lockKey {
  dev_t dev;       /* Device number */
  ino_t ino;       /* Inode number */
#ifdef SQLITE_UNIX_THREADS
  pthread_t tid;   /* Thread ID or zero if threads cannot override each other */
#endif
};

/*
** An instance of the following structure is allocated for each open
** inode on each thread with a different process ID.  (Threads have
** different process IDs on linux, but not on most other unixes.)
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
  int nRef;             /* Number of pointers to this structure */
  int nLock;            /* Number of outstanding locks */
  int nPending;         /* Number of pending close() operations */
  int *aPending;        /* Malloced space holding fd's awaiting a close() */
};

/* 
** These hash tables map inodes and file descriptors (really, lockKey and
** openKey structures) into lockInfo and openCnt structures.  Access to 
** these hash tables must be protected by a mutex.
*/
static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
static Hash openHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };


#ifdef SQLITE_UNIX_THREADS
/*
** This variable records whether or not threads can override each others
** locks.
**
**    0:  No.  Threads cannot override each others locks.
**    1:  Yes.  Threads can override each others locks.
**   -1:  We don't know yet.
**
** This variable normally has file scope only.  But during testing, we make
** it a global so that the test code can change its value in order to verify
** that the right stuff happens in either case.
*/
#ifdef SQLITE_TEST
int threadsOverrideEachOthersLocks = -1;
#else
static int threadsOverrideEachOthersLocks = -1;
#endif

/*
** This structure holds information passed into individual test
** threads by the testThreadLockingBehavior() routine.
*/
struct threadTestData {
  int fd;                /* File to be locked */
  struct flock lock;     /* The locking operation */
  int result;            /* Result of the locking operation */
};

#ifdef SQLITE_LOCK_TRACE
/*
** Print out information about all locking operations.
**
** This routine is used for troubleshooting locks on multithreaded
** platforms.  Enable by compiling with the -DSQLITE_LOCK_TRACE
** command-line option on the compiler.  This code is normally
** turned off.
*/
static int lockTrace(int fd, int op, struct flock *p){
  char *zOpName, *zType;
  int s;
  int savedErrno;
  if( op==F_GETLK ){
    zOpName = "GETLK";
  }else if( op==F_SETLK ){
    zOpName = "SETLK";
  }else{
    s = fcntl(fd, op, p);
    sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s);
    return s;
  }
  if( p->l_type==F_RDLCK ){
    zType = "RDLCK";
  }else if( p->l_type==F_WRLCK ){
    zType = "WRLCK";
  }else if( p->l_type==F_UNLCK ){
    zType = "UNLCK";
  }else{
    assert( 0 );
  }
  assert( p->l_whence==SEEK_SET );
  s = fcntl(fd, op, p);
  savedErrno = errno;
  sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n",
     threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len,
     (int)p->l_pid, s);
  if( s && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){
    struct flock l2;
    l2 = *p;
    fcntl(fd, F_GETLK, &l2);
    if( l2.l_type==F_RDLCK ){
      zType = "RDLCK";
    }else if( l2.l_type==F_WRLCK ){
      zType = "WRLCK";
    }else if( l2.l_type==F_UNLCK ){
      zType = "UNLCK";
    }else{
      assert( 0 );
    }
    sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n",
       zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid);
  }
  errno = savedErrno;
  return s;
}
#define fcntl lockTrace
#endif /* SQLITE_LOCK_TRACE */

/*
** The testThreadLockingBehavior() routine launches two separate
** threads on this routine.  This routine attempts to lock a file
** descriptor then returns.  The success or failure of that attempt
** allows the testThreadLockingBehavior() procedure to determine
** whether or not threads can override each others locks.
*/







|
<
|













<
<
<
<

<
<
<

<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







221
222
223
224
225
226
227
228

229
230
231
232
233
234
235
236
237
238
239
240
241
242




243



244

245
246
247
248
249
250
251
252
253
254
255



























































256
257
258
259
260
261
262
  int nRef;             /* Number of pointers to this structure */
  int nLock;            /* Number of outstanding locks */
  int nPending;         /* Number of pending close() operations */
  int *aPending;        /* Malloced space holding fd's awaiting a close() */
};

/* 
** These hash table maps inodes and process IDs into lockInfo and openCnt

** structures.  Access to these hash tables must be protected by a mutex.
*/
static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
static Hash openHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };


#ifdef SQLITE_UNIX_THREADS
/*
** This variable records whether or not threads can override each others
** locks.
**
**    0:  No.  Threads cannot override each others locks.
**    1:  Yes.  Threads can override each others locks.
**   -1:  We don't know yet.




*/



static int threadsOverrideEachOthersLocks = -1;


/*
** This structure holds information passed into individual test
** threads by the testThreadLockingBehavior() routine.
*/
struct threadTestData {
  int fd;                /* File to be locked */
  struct flock lock;     /* The locking operation */
  int result;            /* Result of the locking operation */
};




























































/*
** The testThreadLockingBehavior() routine launches two separate
** threads on this routine.  This routine attempts to lock a file
** descriptor then returns.  The success or failure of that attempt
** allows the testThreadLockingBehavior() procedure to determine
** whether or not threads can override each others locks.
*/
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721

722

723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

767
768
769
770

771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800

801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824

825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
}
#endif /* SQLITE_UNIX_THREADS */

/*
** Release a lockInfo structure previously allocated by findLockInfo().
*/
static void releaseLockInfo(struct lockInfo *pLock){
  assert( sqlite3OsInMutex() );
  pLock->nRef--;
  if( pLock->nRef==0 ){
    sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
    sqliteFree(pLock);
  }
}

/*
** Release a openCnt structure previously allocated by findLockInfo().
*/
static void releaseOpenCnt(struct openCnt *pOpen){
  assert( sqlite3OsInMutex() );
  pOpen->nRef--;
  if( pOpen->nRef==0 ){
    sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
    free(pOpen->aPending);
    sqliteFree(pOpen);
  }
}

/*
** Given a file descriptor, locate lockInfo and openCnt structures that
** describes that file descriptor.  Create new ones if necessary.  The
** return values might be uninitialized if an error occurs.
**
** Return the number of errors.
*/
static int findLockInfo(
  int fd,                      /* The file descriptor used in the key */
  struct lockInfo **ppLock,    /* Return the lockInfo structure here */
  struct openCnt **ppOpen      /* Return the openCnt structure here */
){
  int rc;
  struct lockKey key1;
  struct openKey key2;
  struct stat statbuf;
  struct lockInfo *pLock;
  struct openCnt *pOpen;
  rc = fstat(fd, &statbuf);
  if( rc!=0 ) return 1;

  assert( sqlite3OsInMutex() );
  memset(&key1, 0, sizeof(key1));
  key1.dev = statbuf.st_dev;
  key1.ino = statbuf.st_ino;
#ifdef SQLITE_UNIX_THREADS
  if( threadsOverrideEachOthersLocks<0 ){
    testThreadLockingBehavior(fd);
  }
  key1.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self();
#endif
  memset(&key2, 0, sizeof(key2));
  key2.dev = statbuf.st_dev;
  key2.ino = statbuf.st_ino;
  pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1));
  if( pLock==0 ){
    struct lockInfo *pOld;
    pLock = sqliteMallocRaw( sizeof(*pLock) );
    if( pLock==0 ){
      rc = 1;
      goto exit_findlockinfo;
    }
    pLock->key = key1;
    pLock->nRef = 1;
    pLock->cnt = 0;
    pLock->locktype = 0;
    pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
    if( pOld!=0 ){
      assert( pOld==pLock );
      sqliteFree(pLock);
      rc = 1;
      goto exit_findlockinfo;
    }
  }else{
    pLock->nRef++;
  }
  *ppLock = pLock;
  if( ppOpen!=0 ){
    pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
    if( pOpen==0 ){
      struct openCnt *pOld;
      pOpen = sqliteMallocRaw( sizeof(*pOpen) );
      if( pOpen==0 ){
        releaseLockInfo(pLock);
        rc = 1;
        goto exit_findlockinfo;
      }
      pOpen->key = key2;
      pOpen->nRef = 1;
      pOpen->nLock = 0;
      pOpen->nPending = 0;
      pOpen->aPending = 0;
      pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
      if( pOld!=0 ){
        assert( pOld==pOpen );
        sqliteFree(pOpen);
        releaseLockInfo(pLock);
        rc = 1;
        goto exit_findlockinfo;
      }
    }else{
      pOpen->nRef++;
    }
    *ppOpen = pOpen;
  }

exit_findlockinfo:
  return rc;
}

#ifdef SQLITE_DEBUG
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string represetation of the supplied
** integer lock-type.
*/
static const char *locktypeName(int locktype){
  switch( locktype ){
  case NO_LOCK: return "NONE";
  case SHARED_LOCK: return "SHARED";
  case RESERVED_LOCK: return "RESERVED";
  case PENDING_LOCK: return "PENDING";
  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
  }
  return "ERROR";
}
#endif

/*
** If we are currently in a different thread than the thread that the
** unixFile argument belongs to, then transfer ownership of the unixFile
** over to the current thread.
**
** A unixFile is only owned by a thread on systems where one thread is
** unable to override locks created by a different thread.  RedHat9 is
** an example of such a system.
**
** Ownership transfer is only allowed if the unixFile is currently unlocked.
** If the unixFile is locked and an ownership is wrong, then return
** SQLITE_MISUSE.  SQLITE_OK is returned if everything works.
*/
#ifdef SQLITE_UNIX_THREADS
static int transferOwnership(unixFile *pFile){
  int rc;
  pthread_t hSelf;
  if( threadsOverrideEachOthersLocks ){
    /* Ownership transfers not needed on this system */
    return SQLITE_OK;
  }
  hSelf = pthread_self();
  if( pthread_equal(pFile->tid, hSelf) ){
    /* We are still in the same thread */
    TRACE1("No-transfer, same thread\n");
    return SQLITE_OK;
  }
  if( pFile->locktype!=NO_LOCK ){
    /* We cannot change ownership while we are holding a lock! */
    return SQLITE_MISUSE;
  }
  TRACE4("Transfer ownership of %d from %d to %d\n", pFile->h,pFile->tid,hSelf);
  pFile->tid = hSelf;
  releaseLockInfo(pFile->pLock);
  rc = findLockInfo(pFile->h, &pFile->pLock, 0);
  TRACE5("LOCK    %d is now %s(%s,%d)\n", pFile->h,
     locktypeName(pFile->locktype),
     locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
  return rc;
}
#else
  /* On single-threaded builds, ownership transfer is a no-op */
# define transferOwnership(X) SQLITE_OK
#endif

/*
** Delete the named file
*/
int sqlite3UnixDelete(const char *zFilename){
  unlink(zFilename);
  return SQLITE_OK;
}

/*
** Return TRUE if the named file exists.
*/
int sqlite3UnixFileExists(const char *zFilename){
  return access(zFilename, 0)==0;
}

/* Forward declaration */
static int allocateUnixFile(unixFile *pInit, OsFile **pId);

/*
** Attempt to open a file for both reading and writing.  If that
** fails, try opening it read-only.  If the file does not exist,
** try to create it.
**
** On success, a handle for the open file is written to *id
** and *pReadonly is set to 0 if the file was opened for reading and
** writing or 1 if the file was opened read-only.  The function returns
** SQLITE_OK.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id and *pReadonly unchanged.
*/
int sqlite3UnixOpenReadWrite(
  const char *zFilename,
  OsFile **pId,
  int *pReadonly
){
  int rc;
  unixFile f;

  CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadWrite, zFilename, pId, pReadonly);
  assert( 0==*pId );
  f.dirfd = -1;
  SET_THREADID(&f);
  f.h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
                          SQLITE_DEFAULT_FILE_PERMISSIONS);
  if( f.h<0 ){
#ifdef EISDIR
    if( errno==EISDIR ){
      return SQLITE_CANTOPEN;
    }
#endif
    f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
    if( f.h<0 ){
      return SQLITE_CANTOPEN; 
    }
    *pReadonly = 1;
  }else{
    *pReadonly = 0;
  }
  sqlite3OsEnterMutex();
  rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
  sqlite3OsLeaveMutex();
  if( rc ){
    close(f.h);
    return SQLITE_NOMEM;
  }
  f.locktype = 0;

  TRACE3("OPEN    %-3d %s\n", f.h, zFilename);

  return allocateUnixFile(&f, pId);
}


/*
** Attempt to open a new file for exclusive access by this process.
** The file will be opened for both reading and writing.  To avoid
** a potential security problem, we do not allow the file to have
** previously existed.  Nor do we allow the file to be a symbolic
** link.
**
** If delFlag is true, then make arrangements to automatically delete
** the file when it is closed.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
  int rc;
  unixFile f;

  CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag);
  assert( 0==*pId );
  if( access(zFilename, 0)==0 ){
    return SQLITE_CANTOPEN;
  }
  SET_THREADID(&f);
  f.dirfd = -1;
  f.h = open(zFilename,
                O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY,
                SQLITE_DEFAULT_FILE_PERMISSIONS);
  if( f.h<0 ){
    return SQLITE_CANTOPEN;
  }
  sqlite3OsEnterMutex();
  rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
  sqlite3OsLeaveMutex();
  if( rc ){
    close(f.h);
    unlink(zFilename);
    return SQLITE_NOMEM;
  }
  f.locktype = 0;

  if( delFlag ){
    unlink(zFilename);
  }
  TRACE3("OPEN-EX %-3d %s\n", f.h, zFilename);

  return allocateUnixFile(&f, pId);
}

/*
** Attempt to open a new file for read-only access.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){
  int rc;
  unixFile f;

  CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadOnly, zFilename, pId, 0);
  assert( 0==*pId );
  SET_THREADID(&f);
  f.dirfd = -1;
  f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
  if( f.h<0 ){
    return SQLITE_CANTOPEN;
  }
  sqlite3OsEnterMutex();
  rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
  sqlite3OsLeaveMutex();
  if( rc ){
    close(f.h);
    return SQLITE_NOMEM;
  }
  f.locktype = 0;

  TRACE3("OPEN-RO %-3d %s\n", f.h, zFilename);

  return allocateUnixFile(&f, pId);
}

/*
** Attempt to open a file descriptor for the directory that contains a
** file.  This file descriptor can be used to fsync() the directory
** in order to make sure the creation of a new file is actually written
** to disk.
**
** This routine is only meaningful for Unix.  It is a no-op under
** windows since windows does not support hard links.
**
** On success, a handle for a previously open file at *id is
** updated with the new directory file descriptor and SQLITE_OK is
** returned.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id unchanged.
*/
static int unixOpenDirectory(
  OsFile *id,
  const char *zDirname

){
  unixFile *pFile = (unixFile*)id;
  if( pFile==0 ){
    /* Do not open the directory if the corresponding file is not already
    ** open. */
    return SQLITE_CANTOPEN;
  }
  SET_THREADID(pFile);
  assert( pFile->dirfd<0 );
  pFile->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0);
  if( pFile->dirfd<0 ){
    return SQLITE_CANTOPEN; 
  }
  TRACE3("OPENDIR %-3d %s\n", pFile->dirfd, zDirname);
  return SQLITE_OK;
}

/*
** If the following global variable points to a string which is the
** name of a directory, then that directory will be used to store
** temporary files.
**
** See also the "PRAGMA temp_store_directory" SQL command.
*/
char *sqlite3_temp_directory = 0;

/*
** Create a temporary file name in zBuf.  zBuf must be big enough to
** hold at least SQLITE_TEMPNAME_SIZE characters.
*/
int sqlite3UnixTempFileName(char *zBuf){
  static const char *azDirs[] = {
     0,
     "/var/tmp",
     "/usr/tmp",
     "/tmp",
     ".",
  };







<











<



|






|
|
















<
<
















|
<
<
<








|
<





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

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|







|



<
<
<













|

|



<
<
<
|
|
<
|
<
|





|
|







|


|


|
>
|
>
|

















|

<
<
<
|



<
|
|
|
<
|



|


|



|
>



|
>
|









|

<
<
<
|
<
|
|
|



|


|


|
>
|
|
|











|






|
<
|
>

<
|




<
|
|
|


|







<
<







|







295
296
297
298
299
300
301

302
303
304
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340


341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357



358
359
360
361
362
363
364
365
366

367
368
369
370
371

372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387
388
389
390

391
392
393
394
395




















396
397














































398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413



414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432



433
434

435

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480



481
482
483
484

485
486
487

488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517



518

519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

555
556
557

558
559
560
561
562

563
564
565
566
567
568
569
570
571
572
573
574
575


576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
}
#endif /* SQLITE_UNIX_THREADS */

/*
** Release a lockInfo structure previously allocated by findLockInfo().
*/
static void releaseLockInfo(struct lockInfo *pLock){

  pLock->nRef--;
  if( pLock->nRef==0 ){
    sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
    sqliteFree(pLock);
  }
}

/*
** Release a openCnt structure previously allocated by findLockInfo().
*/
static void releaseOpenCnt(struct openCnt *pOpen){

  pOpen->nRef--;
  if( pOpen->nRef==0 ){
    sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
    sqliteFree(pOpen->aPending);
    sqliteFree(pOpen);
  }
}

/*
** Given a file descriptor, locate lockInfo and openCnt structures that
** describes that file descriptor.  Create a new ones if necessary.  The
** return values might be unset if an error occurs.
**
** Return the number of errors.
*/
static int findLockInfo(
  int fd,                      /* The file descriptor used in the key */
  struct lockInfo **ppLock,    /* Return the lockInfo structure here */
  struct openCnt **ppOpen      /* Return the openCnt structure here */
){
  int rc;
  struct lockKey key1;
  struct openKey key2;
  struct stat statbuf;
  struct lockInfo *pLock;
  struct openCnt *pOpen;
  rc = fstat(fd, &statbuf);
  if( rc!=0 ) return 1;


  memset(&key1, 0, sizeof(key1));
  key1.dev = statbuf.st_dev;
  key1.ino = statbuf.st_ino;
#ifdef SQLITE_UNIX_THREADS
  if( threadsOverrideEachOthersLocks<0 ){
    testThreadLockingBehavior(fd);
  }
  key1.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self();
#endif
  memset(&key2, 0, sizeof(key2));
  key2.dev = statbuf.st_dev;
  key2.ino = statbuf.st_ino;
  pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1));
  if( pLock==0 ){
    struct lockInfo *pOld;
    pLock = sqliteMallocRaw( sizeof(*pLock) );
    if( pLock==0 ) return 1;



    pLock->key = key1;
    pLock->nRef = 1;
    pLock->cnt = 0;
    pLock->locktype = 0;
    pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
    if( pOld!=0 ){
      assert( pOld==pLock );
      sqliteFree(pLock);
      return 1;

    }
  }else{
    pLock->nRef++;
  }
  *ppLock = pLock;

  pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
  if( pOpen==0 ){
    struct openCnt *pOld;
    pOpen = sqliteMallocRaw( sizeof(*pOpen) );
    if( pOpen==0 ){
      releaseLockInfo(pLock);
      return 1;

    }
    pOpen->key = key2;
    pOpen->nRef = 1;
    pOpen->nLock = 0;
    pOpen->nPending = 0;
    pOpen->aPending = 0;
    pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
    if( pOld!=0 ){
      assert( pOld==pOpen );
      sqliteFree(pOpen);
      releaseLockInfo(pLock);
      return 1;

    }
  }else{
    pOpen->nRef++;
  }
  *ppOpen = pOpen;




















  return 0;
}















































/*
** Delete the named file
*/
int sqlite3OsDelete(const char *zFilename){
  unlink(zFilename);
  return SQLITE_OK;
}

/*
** Return TRUE if the named file exists.
*/
int sqlite3OsFileExists(const char *zFilename){
  return access(zFilename, 0)==0;
}




/*
** Attempt to open a file for both reading and writing.  If that
** fails, try opening it read-only.  If the file does not exist,
** try to create it.
**
** On success, a handle for the open file is written to *id
** and *pReadonly is set to 0 if the file was opened for reading and
** writing or 1 if the file was opened read-only.  The function returns
** SQLITE_OK.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id and *pReadonly unchanged.
*/
int sqlite3OsOpenReadWrite(
  const char *zFilename,
  OsFile *id,
  int *pReadonly
){
  int rc;



  assert( !id->isOpen );
  id->dirfd = -1;

  id->h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, 0644);

  if( id->h<0 ){
#ifdef EISDIR
    if( errno==EISDIR ){
      return SQLITE_CANTOPEN;
    }
#endif
    id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
    if( id->h<0 ){
      return SQLITE_CANTOPEN; 
    }
    *pReadonly = 1;
  }else{
    *pReadonly = 0;
  }
  sqlite3OsEnterMutex();
  rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
  sqlite3OsLeaveMutex();
  if( rc ){
    close(id->h);
    return SQLITE_NOMEM;
  }
  id->locktype = 0;
  id->isOpen = 1;
  TRACE3("OPEN    %-3d %s\n", id->h, zFilename);
  OpenCounter(+1);
  return SQLITE_OK;
}


/*
** Attempt to open a new file for exclusive access by this process.
** The file will be opened for both reading and writing.  To avoid
** a potential security problem, we do not allow the file to have
** previously existed.  Nor do we allow the file to be a symbolic
** link.
**
** If delFlag is true, then make arrangements to automatically delete
** the file when it is closed.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
  int rc;



  assert( !id->isOpen );
  if( access(zFilename, 0)==0 ){
    return SQLITE_CANTOPEN;
  }

  id->dirfd = -1;
  id->h = open(zFilename,
                O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, 0600);

  if( id->h<0 ){
    return SQLITE_CANTOPEN;
  }
  sqlite3OsEnterMutex();
  rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
  sqlite3OsLeaveMutex();
  if( rc ){
    close(id->h);
    unlink(zFilename);
    return SQLITE_NOMEM;
  }
  id->locktype = 0;
  id->isOpen = 1;
  if( delFlag ){
    unlink(zFilename);
  }
  TRACE3("OPEN-EX %-3d %s\n", id->h, zFilename);
  OpenCounter(+1);
  return SQLITE_OK;
}

/*
** Attempt to open a new file for read-only access.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
  int rc;



  assert( !id->isOpen );

  id->dirfd = -1;
  id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
  if( id->h<0 ){
    return SQLITE_CANTOPEN;
  }
  sqlite3OsEnterMutex();
  rc = findLockInfo(id->h, &id->pLock, &id->pOpen);
  sqlite3OsLeaveMutex();
  if( rc ){
    close(id->h);
    return SQLITE_NOMEM;
  }
  id->locktype = 0;
  id->isOpen = 1;
  TRACE3("OPEN-RO %-3d %s\n", id->h, zFilename);
  OpenCounter(+1);
  return SQLITE_OK;
}

/*
** Attempt to open a file descriptor for the directory that contains a
** file.  This file descriptor can be used to fsync() the directory
** in order to make sure the creation of a new file is actually written
** to disk.
**
** This routine is only meaningful for Unix.  It is a no-op under
** windows since windows does not support hard links.
**
** On success, a handle for a previously open file is at *id is
** updated with the new directory file descriptor and SQLITE_OK is
** returned.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id unchanged.
*/
int sqlite3OsOpenDirectory(

  const char *zDirname,
  OsFile *id
){

  if( !id->isOpen ){
    /* Do not open the directory if the corresponding file is not already
    ** open. */
    return SQLITE_CANTOPEN;
  }

  assert( id->dirfd<0 );
  id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0644);
  if( id->dirfd<0 ){
    return SQLITE_CANTOPEN; 
  }
  TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname);
  return SQLITE_OK;
}

/*
** If the following global variable points to a string which is the
** name of a directory, then that directory will be used to store
** temporary files.


*/
char *sqlite3_temp_directory = 0;

/*
** Create a temporary file name in zBuf.  zBuf must be big enough to
** hold at least SQLITE_TEMPNAME_SIZE characters.
*/
int sqlite3OsTempFileName(char *zBuf){
  static const char *azDirs[] = {
     0,
     "/var/tmp",
     "/usr/tmp",
     "/tmp",
     ".",
  };
884
885
886
887
888
889
890

891
892
893
894
895
896
897
898
899
900
901
902
903
904
905

906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158


















1159
1160
1161
1162
1163
1164
1165
      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
    }
    zBuf[j] = 0;
  }while( access(zBuf,0)==0 );
  return SQLITE_OK; 
}


/*
** Check that a given pathname is a directory and is writable 
**
*/
int sqlite3UnixIsDirWritable(char *zBuf){
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
  struct stat buf;
  if( zBuf==0 ) return 0;
  if( zBuf[0]==0 ) return 0;
  if( stat(zBuf, &buf) ) return 0;
  if( !S_ISDIR(buf.st_mode) ) return 0;
  if( access(zBuf, 07) ) return 0;
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
  return 1;
}


/*
** Read data from a file into a buffer.  Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong.
*/
static int unixRead(OsFile *id, void *pBuf, int amt){
  int got;
  assert( id );
  SimulateIOError(SQLITE_IOERR);
  TIMER_START;
  got = read(((unixFile*)id)->h, pBuf, amt);
  TIMER_END;
  TRACE5("READ    %-3d %5d %7d %d\n", ((unixFile*)id)->h, got,
          last_page, TIMER_ELAPSED);
  SEEK(0);
  /* if( got<0 ) got = 0; */
  if( got==amt ){
    return SQLITE_OK;
  }else{
    return SQLITE_IOERR;
  }
}

/*
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.
*/
static int unixWrite(OsFile *id, const void *pBuf, int amt){
  int wrote = 0;
  assert( id );
  assert( amt>0 );
  SimulateIOError(SQLITE_IOERR);
  SimulateDiskfullError;
  TIMER_START;
  while( amt>0 && (wrote = write(((unixFile*)id)->h, pBuf, amt))>0 ){
    amt -= wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  TIMER_END;
  TRACE5("WRITE   %-3d %5d %7d %d\n", ((unixFile*)id)->h, wrote,
          last_page, TIMER_ELAPSED);
  SEEK(0);
  if( amt>0 ){
    return SQLITE_FULL;
  }
  return SQLITE_OK;
}

/*
** Move the read/write pointer in a file.
*/
static int unixSeek(OsFile *id, i64 offset){
  assert( id );
  SEEK(offset/1024 + 1);
#ifdef SQLITE_TEST
  if( offset ) SimulateDiskfullError
#endif
  lseek(((unixFile*)id)->h, offset, SEEK_SET);
  return SQLITE_OK;
}

#ifdef SQLITE_TEST
/*
** Count the number of fullsyncs and normal syncs.  This is used to test
** that syncs and fullsyncs are occuring at the right times.
*/
int sqlite3_sync_count = 0;
int sqlite3_fullsync_count = 0;
#endif

/*
** Use the fdatasync() API only if the HAVE_FDATASYNC macro is defined.
** Otherwise use fsync() in its place.
*/
#ifndef HAVE_FDATASYNC
# define fdatasync fsync
#endif


/*
** The fsync() system call does not work as advertised on many
** unix systems.  The following procedure is an attempt to make
** it work better.
**
** The SQLITE_NO_SYNC macro disables all fsync()s.  This is useful
** for testing when we want to run through the test suite quickly.
** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
** or power failure will likely corrupt the database file.
*/
static int full_fsync(int fd, int fullSync, int dataOnly){
  int rc;

  /* Record the number of times that we do a normal fsync() and 
  ** FULLSYNC.  This is used during testing to verify that this procedure
  ** gets called with the correct arguments.
  */
#ifdef SQLITE_TEST
  if( fullSync ) sqlite3_fullsync_count++;
  sqlite3_sync_count++;
#endif

  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
  ** no-op
  */
#ifdef SQLITE_NO_SYNC
  rc = SQLITE_OK;
#else

#ifdef F_FULLFSYNC
  if( fullSync ){
    rc = fcntl(fd, F_FULLFSYNC, 0);
  }else{
    rc = 1;
  }
  /* If the FULLSYNC failed, try to do a normal fsync() */
  if( rc ) rc = fsync(fd);

#else /* if !defined(F_FULLSYNC) */
  if( dataOnly ){
    rc = fdatasync(fd);
  }else{
    rc = fsync(fd);
  }
#endif /* defined(F_FULLFSYNC) */
#endif /* defined(SQLITE_NO_SYNC) */

  return rc;

}

/*
** Make sure all writes to a particular file are committed to disk.
**
** If dataOnly==0 then both the file itself and its metadata (file
** size, access time, etc) are synced.  If dataOnly!=0 then only the
** file data is synced.
**
** Under Unix, also make sure that the directory entry for the file
** has been created by fsync-ing the directory that contains the file.
** If we do not do this and we encounter a power failure, the directory
** entry for the journal might not exist after we reboot.  The next
** SQLite to access the file will not know that the journal exists (because
** the directory entry for the journal was never created) and the transaction
** will not roll back - possibly leading to database corruption.
*/
static int unixSync(OsFile *id, int dataOnly){
  unixFile *pFile = (unixFile*)id;
  assert( pFile );
  SimulateIOError(SQLITE_IOERR);
  TRACE2("SYNC    %-3d\n", pFile->h);
  if( full_fsync(pFile->h, pFile->fullSync, dataOnly) ){
    return SQLITE_IOERR;
  }
  if( pFile->dirfd>=0 ){
    TRACE2("DIRSYNC %-3d\n", pFile->dirfd);
#ifndef SQLITE_DISABLE_DIRSYNC
    if( full_fsync(pFile->dirfd, pFile->fullSync, 0) ){
        return SQLITE_IOERR;
    }
#endif
    close(pFile->dirfd);  /* Only need to sync once, so close the directory */
    pFile->dirfd = -1;    /* when we are done. */
  }
  return SQLITE_OK;
}

/*
** Sync the directory zDirname. This is a no-op on operating systems other
** than UNIX.
**
** This is used to make sure the master journal file has truely been deleted
** before making changes to individual journals on a multi-database commit.
** The F_FULLFSYNC option is not needed here.
*/
int sqlite3UnixSyncDirectory(const char *zDirname){
#ifdef SQLITE_DISABLE_DIRSYNC
  return SQLITE_OK;
#else
  int fd;
  int r;
  SimulateIOError(SQLITE_IOERR);
  fd = open(zDirname, O_RDONLY|O_BINARY, 0);
  TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname);
  if( fd<0 ){
    return SQLITE_CANTOPEN; 
  }
  r = fsync(fd);
  close(fd);
  return ((r==0)?SQLITE_OK:SQLITE_IOERR);
#endif
}

/*
** Truncate an open file to a specified size
*/
static int unixTruncate(OsFile *id, i64 nByte){
  assert( id );
  SimulateIOError(SQLITE_IOERR);
  return ftruncate(((unixFile*)id)->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
}

/*
** Determine the current size of a file in bytes
*/
static int unixFileSize(OsFile *id, i64 *pSize){
  struct stat buf;
  assert( id );
  SimulateIOError(SQLITE_IOERR);
  if( fstat(((unixFile*)id)->h, &buf)!=0 ){
    return SQLITE_IOERR;
  }
  *pSize = buf.st_size;
  return SQLITE_OK;
}

/*
** This routine checks if there is a RESERVED lock held on the specified
** file by this or any other process. If such a lock is held, return
** non-zero.  If the file is unlocked or holds only SHARED locks, then
** return zero.
*/
static int unixCheckReservedLock(OsFile *id){
  int r = 0;
  unixFile *pFile = (unixFile*)id;

  assert( pFile );
  sqlite3OsEnterMutex(); /* Because pFile->pLock is shared across threads */

  /* Check if a thread in this process holds such a lock */
  if( pFile->pLock->locktype>SHARED_LOCK ){
    r = 1;
  }

  /* Otherwise see if some other process holds it.
  */
  if( !r ){
    struct flock lock;
    lock.l_whence = SEEK_SET;
    lock.l_start = RESERVED_BYTE;
    lock.l_len = 1;
    lock.l_type = F_WRLCK;
    fcntl(pFile->h, F_GETLK, &lock);
    if( lock.l_type!=F_UNLCK ){
      r = 1;
    }
  }
  
  sqlite3OsLeaveMutex();
  TRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);

  return r;
}



















/*
** Lock the file with the lock specified by parameter locktype - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK







>




|
<






<


>






|

|


|

<
|













|

|




|




<
|










|
|

<
<
<
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












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

|

|

<
|
<
<
<
<

<
<
<
<
|
|
<
|
<
<

>





<
<
<
<








|
<
|

|
|


|
|
<
|
<
<
<
|
|







<
<
<
<

|
<
<
<



|







<





|
|

|





|

|

|












|

<

|
|


|











|






|



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







612
613
614
615
616
617
618
619
620
621
622
623
624

625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646

647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672

673
674
675
676
677
678
679
680
681
682
683
684
685
686



687
688
689


















690
691
692
693
694
695
696
697
698
699
700
701
702














703
704
705
706
707

708




709




710
711

712


713
714
715
716
717
718
719




720
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
736

737



738
739
740
741
742
743
744
745
746




747
748



749
750
751
752
753
754
755
756
757
758
759

760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792

793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
    }
    zBuf[j] = 0;
  }while( access(zBuf,0)==0 );
  return SQLITE_OK; 
}

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
** Check that a given pathname is a directory and is writable 
**
*/
int sqlite3OsIsDirWritable(char *zBuf){

  struct stat buf;
  if( zBuf==0 ) return 0;
  if( zBuf[0]==0 ) return 0;
  if( stat(zBuf, &buf) ) return 0;
  if( !S_ISDIR(buf.st_mode) ) return 0;
  if( access(zBuf, 07) ) return 0;

  return 1;
}
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */

/*
** Read data from a file into a buffer.  Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong.
*/
int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
  int got;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  TIMER_START;
  got = read(id->h, pBuf, amt);
  TIMER_END;

  TRACE4("READ    %-3d %7d %d\n", id->h, last_page, TIMER_ELAPSED);
  SEEK(0);
  /* if( got<0 ) got = 0; */
  if( got==amt ){
    return SQLITE_OK;
  }else{
    return SQLITE_IOERR;
  }
}

/*
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.
*/
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
  int wrote = 0;
  assert( id->isOpen );
  assert( amt>0 );
  SimulateIOError(SQLITE_IOERR);
  SimulateDiskfullError;
  TIMER_START;
  while( amt>0 && (wrote = write(id->h, pBuf, amt))>0 ){
    amt -= wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  TIMER_END;

  TRACE4("WRITE   %-3d %7d %d\n", id->h, last_page, TIMER_ELAPSED);
  SEEK(0);
  if( amt>0 ){
    return SQLITE_FULL;
  }
  return SQLITE_OK;
}

/*
** Move the read/write pointer in a file.
*/
int sqlite3OsSeek(OsFile *id, i64 offset){
  assert( id->isOpen );
  SEEK(offset/1024 + 1);



  lseek(id->h, offset, SEEK_SET);
  return SQLITE_OK;
}



















/*
** The fsync() system call does not work as advertised on many
** unix systems.  The following procedure is an attempt to make
** it work better.
**
** The SQLITE_NO_SYNC macro disables all fsync()s.  This is useful
** for testing when we want to run through the test suite quickly.
** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
** or power failure will likely corrupt the database file.
*/
static int full_fsync(int fd){














#ifdef SQLITE_NO_SYNC
  return SQLITE_OK;
#else
  int rc;
#ifdef F_FULLFSYNC

  rc = fcntl(fd, F_FULLFSYNC, 0);




  if( rc ) rc = fsync(fd);




#else
  rc = fsync(fd);

#endif


  return rc;
#endif
}

/*
** Make sure all writes to a particular file are committed to disk.
**




** Under Unix, also make sure that the directory entry for the file
** has been created by fsync-ing the directory that contains the file.
** If we do not do this and we encounter a power failure, the directory
** entry for the journal might not exist after we reboot.  The next
** SQLite to access the file will not know that the journal exists (because
** the directory entry for the journal was never created) and the transaction
** will not roll back - possibly leading to database corruption.
*/
int sqlite3OsSync(OsFile *id){

  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  TRACE2("SYNC    %-3d\n", id->h);
  if( full_fsync(id->h) ){
    return SQLITE_IOERR;
  }
  if( id->dirfd>=0 ){
    TRACE2("DIRSYNC %-3d\n", id->dirfd);

    full_fsync(id->dirfd);



    close(id->dirfd);  /* Only need to sync once, so close the directory */
    id->dirfd = -1;    /* when we are done. */
  }
  return SQLITE_OK;
}

/*
** Sync the directory zDirname. This is a no-op on operating systems other
** than UNIX.




*/
int sqlite3OsSyncDirectory(const char *zDirname){



  int fd;
  int r;
  SimulateIOError(SQLITE_IOERR);
  fd = open(zDirname, O_RDONLY|O_BINARY, 0644);
  TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname);
  if( fd<0 ){
    return SQLITE_CANTOPEN; 
  }
  r = fsync(fd);
  close(fd);
  return ((r==0)?SQLITE_OK:SQLITE_IOERR);

}

/*
** Truncate an open file to a specified size
*/
int sqlite3OsTruncate(OsFile *id, i64 nByte){
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  return ftruncate(id->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
}

/*
** Determine the current size of a file in bytes
*/
int sqlite3OsFileSize(OsFile *id, i64 *pSize){
  struct stat buf;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  if( fstat(id->h, &buf)!=0 ){
    return SQLITE_IOERR;
  }
  *pSize = buf.st_size;
  return SQLITE_OK;
}

/*
** This routine checks if there is a RESERVED lock held on the specified
** file by this or any other process. If such a lock is held, return
** non-zero.  If the file is unlocked or holds only SHARED locks, then
** return zero.
*/
int sqlite3OsCheckReservedLock(OsFile *id){
  int r = 0;


  assert( id->isOpen );
  sqlite3OsEnterMutex(); /* Needed because id->pLock is shared across threads */

  /* Check if a thread in this process holds such a lock */
  if( id->pLock->locktype>SHARED_LOCK ){
    r = 1;
  }

  /* Otherwise see if some other process holds it.
  */
  if( !r ){
    struct flock lock;
    lock.l_whence = SEEK_SET;
    lock.l_start = RESERVED_BYTE;
    lock.l_len = 1;
    lock.l_type = F_WRLCK;
    fcntl(id->h, F_GETLK, &lock);
    if( lock.l_type!=F_UNLCK ){
      r = 1;
    }
  }
  
  sqlite3OsLeaveMutex();
  TRACE3("TEST WR-LOCK %d %d\n", id->h, r);

  return r;
}

#ifdef SQLITE_DEBUG
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string represetation of the supplied
** integer lock-type.
*/
static const char * locktypeName(int locktype){
  switch( locktype ){
  case NO_LOCK: return "NONE";
  case SHARED_LOCK: return "SHARED";
  case RESERVED_LOCK: return "RESERVED";
  case PENDING_LOCK: return "PENDING";
  case EXCLUSIVE_LOCK: return "EXCLUSIVE";
  }
  return "ERROR";
}
#endif

/*
** Lock the file with the lock specified by parameter locktype - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** This routine will only increase a lock.  Use the sqlite3OsUnlock()
** routine to lower a locking level.
*/
static int unixLock(OsFile *id, int locktype){
  /* The following describes the implementation of the various locks and
  ** lock transitions in terms of the POSIX advisory shared and exclusive
  ** lock primitives (called read-locks and write-locks below, to avoid
  ** confusion with SQLite lock names). The algorithms are complicated
  ** slightly in order to be compatible with windows systems simultaneously
  ** accessing the same database file, in case that is ever required.
  **







|







857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** This routine will only increase a lock.  Use the sqlite3OsUnlock()
** routine to lower a locking level.
*/
int sqlite3OsLock(OsFile *id, int locktype){
  /* The following describes the implementation of the various locks and
  ** lock transitions in terms of the POSIX advisory shared and exclusive
  ** lock primitives (called read-locks and write-locks below, to avoid
  ** confusion with SQLite lock names). The algorithms are complicated
  ** slightly in order to be compatible with windows systems simultaneously
  ** accessing the same database file, in case that is ever required.
  **
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384




1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490

1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
  **
  ** The reason a single byte cannot be used instead of the 'shared byte
  ** range' is that some versions of windows do not support read-locks. By
  ** locking a random byte from a range, concurrent SHARED locks may exist
  ** even if the locking primitive used is always a write-lock.
  */
  int rc = SQLITE_OK;
  unixFile *pFile = (unixFile*)id;
  struct lockInfo *pLock = pFile->pLock;
  struct flock lock;
  int s;

  assert( pFile );
  TRACE7("LOCK    %d %s was %s(%s,%d) pid=%d\n", pFile->h,
      locktypeName(locktype), locktypeName(pFile->locktype),
      locktypeName(pLock->locktype), pLock->cnt , getpid());

  /* If there is already a lock of this type or more restrictive on the
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( pFile->locktype>=locktype ){
    TRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
            locktypeName(locktype));
    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );

  /* This mutex is needed because pFile->pLock is shared across threads
  */
  sqlite3OsEnterMutex();

  /* Make sure the current thread owns the pFile.
  */
  rc = transferOwnership(pFile);
  if( rc!=SQLITE_OK ){
    sqlite3OsLeaveMutex();
    return rc;
  }
  pLock = pFile->pLock;

  /* If some thread using this PID has a lock via a different OsFile*
  ** handle that precludes the requested lock, return BUSY.
  */
  if( (pFile->locktype!=pLock->locktype && 
          (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK))
  ){
    rc = SQLITE_BUSY;
    goto end_lock;
  }

  /* If a SHARED lock is requested, and some thread using this PID already
  ** has a SHARED or RESERVED lock, then increment reference counts and
  ** return SQLITE_OK.
  */
  if( locktype==SHARED_LOCK && 
      (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){
    assert( locktype==SHARED_LOCK );
    assert( pFile->locktype==0 );
    assert( pLock->cnt>0 );
    pFile->locktype = SHARED_LOCK;
    pLock->cnt++;
    pFile->pOpen->nLock++;
    goto end_lock;
  }

  lock.l_len = 1L;

  lock.l_whence = SEEK_SET;

  /* A PENDING lock is needed before acquiring a SHARED lock and before
  ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
  ** be released.
  */
  if( locktype==SHARED_LOCK 
      || (locktype==EXCLUSIVE_LOCK && pFile->locktype<PENDING_LOCK)
  ){
    lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
    lock.l_start = PENDING_BYTE;
    s = fcntl(pFile->h, F_SETLK, &lock);
    if( s ){
      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
      goto end_lock;
    }
  }


  /* If control gets to this point, then actually go ahead and make
  ** operating system calls for the specified lock.
  */
  if( locktype==SHARED_LOCK ){
    assert( pLock->cnt==0 );
    assert( pLock->locktype==0 );

    /* Now get the read-lock */
    lock.l_start = SHARED_FIRST;
    lock.l_len = SHARED_SIZE;
    s = fcntl(pFile->h, F_SETLK, &lock);

    /* Drop the temporary PENDING lock */
    lock.l_start = PENDING_BYTE;
    lock.l_len = 1L;
    lock.l_type = F_UNLCK;
    if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
      rc = SQLITE_IOERR;  /* This should never happen */
      goto end_lock;
    }
    if( s ){
      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
    }else{
      pFile->locktype = SHARED_LOCK;
      pFile->pOpen->nLock++;
      pLock->cnt = 1;
    }
  }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){
    /* We are trying for an exclusive lock but another thread in this
    ** same process is still holding a shared lock. */
    rc = SQLITE_BUSY;
  }else{
    /* The request was for a RESERVED or EXCLUSIVE lock.  It is
    ** assumed that there is a SHARED or greater lock on the file
    ** already.
    */
    assert( 0!=pFile->locktype );
    lock.l_type = F_WRLCK;
    switch( locktype ){
      case RESERVED_LOCK:
        lock.l_start = RESERVED_BYTE;
        break;
      case EXCLUSIVE_LOCK:
        lock.l_start = SHARED_FIRST;
        lock.l_len = SHARED_SIZE;
        break;
      default:
        assert(0);
    }
    s = fcntl(pFile->h, F_SETLK, &lock);
    if( s ){
      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
    }
  }
  
  if( rc==SQLITE_OK ){
    pFile->locktype = locktype;
    pLock->locktype = locktype;
  }else if( locktype==EXCLUSIVE_LOCK ){
    pFile->locktype = PENDING_LOCK;
    pLock->locktype = PENDING_LOCK;
  }

end_lock:
  sqlite3OsLeaveMutex();
  TRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
      rc==SQLITE_OK ? "ok" : "failed");
  return rc;
}

/*
** Lower the locking level on file descriptor pFile to locktype.  locktype
** must be either NO_LOCK or SHARED_LOCK.
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.




*/
static int unixUnlock(OsFile *id, int locktype){
  struct lockInfo *pLock;
  struct flock lock;
  int rc = SQLITE_OK;
  unixFile *pFile = (unixFile*)id;

  assert( pFile );
  TRACE7("UNLOCK  %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype,
      pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid());

  assert( locktype<=SHARED_LOCK );
  if( pFile->locktype<=locktype ){
    return SQLITE_OK;
  }
  if( CHECK_THREADID(pFile) ){
    return SQLITE_MISUSE;
  }
  sqlite3OsEnterMutex();
  pLock = pFile->pLock;
  assert( pLock->cnt!=0 );
  if( pFile->locktype>SHARED_LOCK ){
    assert( pLock->locktype==pFile->locktype );
    if( locktype==SHARED_LOCK ){
      lock.l_type = F_RDLCK;
      lock.l_whence = SEEK_SET;
      lock.l_start = SHARED_FIRST;
      lock.l_len = SHARED_SIZE;
      if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
        /* This should never happen */
        rc = SQLITE_IOERR;
      }
    }
    lock.l_type = F_UNLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = PENDING_BYTE;
    lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
    if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
      pLock->locktype = SHARED_LOCK;
    }else{
      rc = SQLITE_IOERR;  /* This should never happen */
    }
  }
  if( locktype==NO_LOCK ){
    struct openCnt *pOpen;

    /* Decrement the shared lock counter.  Release the lock using an
    ** OS call only when all threads in this same process have released
    ** the lock.
    */
    pLock->cnt--;
    if( pLock->cnt==0 ){
      lock.l_type = F_UNLCK;
      lock.l_whence = SEEK_SET;
      lock.l_start = lock.l_len = 0L;
      if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
        pLock->locktype = NO_LOCK;
      }else{
        rc = SQLITE_IOERR;  /* This should never happen */
      }
    }

    /* Decrement the count of locks against this same file.  When the
    ** count reaches zero, close any other file descriptors whose close
    ** was deferred because of outstanding locks.
    */
    pOpen = pFile->pOpen;
    pOpen->nLock--;
    assert( pOpen->nLock>=0 );
    if( pOpen->nLock==0 && pOpen->nPending>0 ){
      int i;
      for(i=0; i<pOpen->nPending; i++){
        close(pOpen->aPending[i]);
      }
      free(pOpen->aPending);
      pOpen->nPending = 0;
      pOpen->aPending = 0;
    }
  }
  sqlite3OsLeaveMutex();
  pFile->locktype = locktype;
  return rc;
}

/*
** Close a file.
*/
static int unixClose(OsFile **pId){
  unixFile *id = (unixFile*)*pId;
  int rc;

  if( !id ) return SQLITE_OK;
  unixUnlock(*pId, NO_LOCK);
  if( id->dirfd>=0 ) close(id->dirfd);
  id->dirfd = -1;
  sqlite3OsEnterMutex();

  if( id->pOpen->nLock ){
    /* If there are outstanding locks, do not actually close the file just
    ** yet because that would clear those locks.  Instead, add the file
    ** descriptor to pOpen->aPending.  It will be automatically closed when
    ** the last lock is cleared.
    */
    int *aNew;
    struct openCnt *pOpen = id->pOpen;
    aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );

    if( aNew==0 ){
      /* If a malloc fails, just leak the file descriptor */
    }else{
      pOpen->aPending = aNew;
      pOpen->aPending[pOpen->nPending] = id->h;
      pOpen->nPending++;
    }
  }else{
    /* There are no outstanding locks so we can close the file immediately */
    close(id->h);
  }
  releaseLockInfo(id->pLock);
  releaseOpenCnt(id->pOpen);

  sqlite3OsLeaveMutex();
  id->isOpen = 0;
  TRACE2("CLOSE   %-3d\n", id->h);
  OpenCounter(-1);
  sqliteFree(id);
  *pId = 0;
  return rc;
}

/*
** Turn a relative pathname into a full pathname.  Return a pointer
** to the full pathname stored in space obtained from sqliteMalloc().
** The calling function is responsible for freeing this space once it
** is no longer needed.
*/
char *sqlite3UnixFullPathname(const char *zRelative){
  char *zFull = 0;
  if( zRelative[0]=='/' ){
    sqlite3SetString(&zFull, zRelative, (char*)0);
  }else{
    char *zBuf = sqliteMalloc(5000);
    if( zBuf==0 ){
      return 0;
    }
    zBuf[0] = 0;
    sqlite3SetString(&zFull, getcwd(zBuf, 5000), "/", zRelative,
                    (char*)0);
    sqliteFree(zBuf);
  }
  return zFull;
}

/*
** Change the value of the fullsync flag in the given file descriptor.
*/
static void unixSetFullSync(OsFile *id, int v){
  ((unixFile*)id)->fullSync = v;
}

/*
** Return the underlying file handle for an OsFile
*/
static int unixFileHandle(OsFile *id){
  return ((unixFile*)id)->h;
}

/*
** Return an integer that indices the type of lock currently held
** by this handle.  (Used for testing and analysis only.)
*/
static int unixLockState(OsFile *id){
  return ((unixFile*)id)->locktype;
}

/*
** This vector defines all the methods that can operate on an OsFile
** for unix.
*/
static const IoMethod sqlite3UnixIoMethod = {
  unixClose,
  unixOpenDirectory,
  unixRead,
  unixWrite,
  unixSeek,
  unixTruncate,
  unixSync,
  unixSetFullSync,
  unixFileHandle,
  unixFileSize,
  unixLock,
  unixUnlock,
  unixLockState,
  unixCheckReservedLock,
};

/*
** Allocate memory for a unixFile.  Initialize the new unixFile
** to the value given in pInit and return a pointer to the new
** OsFile.  If we run out of memory, close the file and return NULL.
*/
static int allocateUnixFile(unixFile *pInit, OsFile **pId){
  unixFile *pNew;
  pNew = sqliteMalloc( sizeof(unixFile) );
  if( pNew==0 ){
    close(pInit->h);
    sqlite3OsEnterMutex();
    releaseLockInfo(pInit->pLock);
    releaseOpenCnt(pInit->pOpen);
    sqlite3OsLeaveMutex();
    *pId = 0;
    return SQLITE_NOMEM;
  }else{
    *pNew = *pInit;
    pNew->pMethod = &sqlite3UnixIoMethod;
    *pId = (OsFile*)pNew;
    OpenCounter(+1);
    return SQLITE_OK;
  }
}


#endif /* SQLITE_OMIT_DISKIO */
/***************************************************************************
** Everything above deals with file I/O.  Everything that follows deals
** with other miscellanous aspects of the operating system interface
****************************************************************************/


/*
** Get information to seed the random number generator.  The seed
** is written into the buffer zBuf[256].  The calling function must
** supply a sufficiently large buffer.
*/
int sqlite3UnixRandomSeed(char *zBuf){
  /* We have to initialize zBuf to prevent valgrind from reporting
  ** errors.  The reports issued by valgrind are incorrect - we would
  ** prefer that the randomness be increased by making use of the
  ** uninitialized space in zBuf - but valgrind errors tend to worry
  ** some users.  Rather than argue, it seems easier just to initialize
  ** the whole array and silence valgrind, even if that means less randomness
  ** in the random seed.
  **
  ** When testing, initializing zBuf[] to zero is all we do.  That means
  ** that we always use the same random number sequence.  This makes the
  ** tests repeatable.
  */
  memset(zBuf, 0, 256);
#if !defined(SQLITE_TEST)
  {
    int pid, fd;
    fd = open("/dev/urandom", O_RDONLY);
    if( fd<0 ){
      time_t t;
      time(&t);
      memcpy(zBuf, &t, sizeof(t));
      pid = getpid();
      memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
    }else{
      read(fd, zBuf, 256);
      close(fd);
    }
  }
#endif
  return SQLITE_OK;
}

/*
** Sleep for a little while.  Return the amount of time slept.
** The argument is the number of milliseconds we want to sleep.
*/
int sqlite3UnixSleep(int ms){
#if defined(HAVE_USLEEP) && HAVE_USLEEP
  usleep(ms*1000);
  return ms;
#else
  sleep((ms+999)/1000);
  return 1000*((ms+999)/1000);
#endif







<
|



|
|
|
|





|
<
|





|

|

|



<
<
<
<
<
<
<
<
<



|













|

|

|




<







|



|

















|





|
<
<
<



|
|











|












|






|


|





|





|




>
>
>
>

|



<

|
|
|


|


<
<
<

|

|
|





|








|
|
<
<
<













|
|
<
<
<






|







|





|






|
<
<
<
|
|



<








|
>




|
<







<




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






|









|








|
<
<













<

|







897
898
899
900
901
902
903

904
905
906
907
908
909
910
911
912
913
914
915
916
917

918
919
920
921
922
923
924
925
926
927
928
929
930
931









932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957

958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993



994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058

1059
1060
1061
1062
1063
1064
1065
1066
1067



1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088



1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103



1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131



1132
1133
1134
1135
1136

1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151

1152
1153
1154
1155
1156
1157
1158

1159
1160
1161
1162




























































































1163
1164









1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190


1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203

1204
1205
1206
1207
1208
1209
1210
1211
1212
  **
  ** The reason a single byte cannot be used instead of the 'shared byte
  ** range' is that some versions of windows do not support read-locks. By
  ** locking a random byte from a range, concurrent SHARED locks may exist
  ** even if the locking primitive used is always a write-lock.
  */
  int rc = SQLITE_OK;

  struct lockInfo *pLock = id->pLock;
  struct flock lock;
  int s;

  assert( id->isOpen );
  TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", id->h, locktypeName(locktype), 
      locktypeName(id->locktype), locktypeName(pLock->locktype), pLock->cnt
      ,getpid() );

  /* If there is already a lock of this type or more restrictive on the
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( id->locktype>=locktype ){

    TRACE3("LOCK %d %s ok (already held)\n", id->h, locktypeName(locktype));
    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
  assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );

  /* This mutex is needed because id->pLock is shared across threads
  */
  sqlite3OsEnterMutex();










  /* If some thread using this PID has a lock via a different OsFile*
  ** handle that precludes the requested lock, return BUSY.
  */
  if( (id->locktype!=pLock->locktype && 
          (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK))
  ){
    rc = SQLITE_BUSY;
    goto end_lock;
  }

  /* If a SHARED lock is requested, and some thread using this PID already
  ** has a SHARED or RESERVED lock, then increment reference counts and
  ** return SQLITE_OK.
  */
  if( locktype==SHARED_LOCK && 
      (pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){
    assert( locktype==SHARED_LOCK );
    assert( id->locktype==0 );
    assert( pLock->cnt>0 );
    id->locktype = SHARED_LOCK;
    pLock->cnt++;
    id->pOpen->nLock++;
    goto end_lock;
  }

  lock.l_len = 1L;

  lock.l_whence = SEEK_SET;

  /* A PENDING lock is needed before acquiring a SHARED lock and before
  ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
  ** be released.
  */
  if( locktype==SHARED_LOCK 
      || (locktype==EXCLUSIVE_LOCK && id->locktype<PENDING_LOCK)
  ){
    lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
    lock.l_start = PENDING_BYTE;
    s = fcntl(id->h, F_SETLK, &lock);
    if( s ){
      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
      goto end_lock;
    }
  }


  /* If control gets to this point, then actually go ahead and make
  ** operating system calls for the specified lock.
  */
  if( locktype==SHARED_LOCK ){
    assert( pLock->cnt==0 );
    assert( pLock->locktype==0 );

    /* Now get the read-lock */
    lock.l_start = SHARED_FIRST;
    lock.l_len = SHARED_SIZE;
    s = fcntl(id->h, F_SETLK, &lock);

    /* Drop the temporary PENDING lock */
    lock.l_start = PENDING_BYTE;
    lock.l_len = 1L;
    lock.l_type = F_UNLCK;
    fcntl(id->h, F_SETLK, &lock);



    if( s ){
      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
    }else{
      id->locktype = SHARED_LOCK;
      id->pOpen->nLock++;
      pLock->cnt = 1;
    }
  }else if( locktype==EXCLUSIVE_LOCK && pLock->cnt>1 ){
    /* We are trying for an exclusive lock but another thread in this
    ** same process is still holding a shared lock. */
    rc = SQLITE_BUSY;
  }else{
    /* The request was for a RESERVED or EXCLUSIVE lock.  It is
    ** assumed that there is a SHARED or greater lock on the file
    ** already.
    */
    assert( 0!=id->locktype );
    lock.l_type = F_WRLCK;
    switch( locktype ){
      case RESERVED_LOCK:
        lock.l_start = RESERVED_BYTE;
        break;
      case EXCLUSIVE_LOCK:
        lock.l_start = SHARED_FIRST;
        lock.l_len = SHARED_SIZE;
        break;
      default:
        assert(0);
    }
    s = fcntl(id->h, F_SETLK, &lock);
    if( s ){
      rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
    }
  }
  
  if( rc==SQLITE_OK ){
    id->locktype = locktype;
    pLock->locktype = locktype;
  }else if( locktype==EXCLUSIVE_LOCK ){
    id->locktype = PENDING_LOCK;
    pLock->locktype = PENDING_LOCK;
  }

end_lock:
  sqlite3OsLeaveMutex();
  TRACE4("LOCK %d %s %s\n", id->h, locktypeName(locktype), 
      rc==SQLITE_OK ? "ok" : "failed");
  return rc;
}

/*
** Lower the locking level on file descriptor id to locktype.  locktype
** must be either NO_LOCK or SHARED_LOCK.
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
**
** It is not possible for this routine to fail if the second argument
** is NO_LOCK.  If the second argument is SHARED_LOCK, this routine
** might return SQLITE_IOERR instead of SQLITE_OK.
*/
int sqlite3OsUnlock(OsFile *id, int locktype){
  struct lockInfo *pLock;
  struct flock lock;
  int rc = SQLITE_OK;


  assert( id->isOpen );
  TRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", id->h, locktype, id->locktype, 
      id->pLock->locktype, id->pLock->cnt, getpid());

  assert( locktype<=SHARED_LOCK );
  if( id->locktype<=locktype ){
    return SQLITE_OK;
  }



  sqlite3OsEnterMutex();
  pLock = id->pLock;
  assert( pLock->cnt!=0 );
  if( id->locktype>SHARED_LOCK ){
    assert( pLock->locktype==id->locktype );
    if( locktype==SHARED_LOCK ){
      lock.l_type = F_RDLCK;
      lock.l_whence = SEEK_SET;
      lock.l_start = SHARED_FIRST;
      lock.l_len = SHARED_SIZE;
      if( fcntl(id->h, F_SETLK, &lock)!=0 ){
        /* This should never happen */
        rc = SQLITE_IOERR;
      }
    }
    lock.l_type = F_UNLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = PENDING_BYTE;
    lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
    fcntl(id->h, F_SETLK, &lock);
    pLock->locktype = SHARED_LOCK;



  }
  if( locktype==NO_LOCK ){
    struct openCnt *pOpen;

    /* Decrement the shared lock counter.  Release the lock using an
    ** OS call only when all threads in this same process have released
    ** the lock.
    */
    pLock->cnt--;
    if( pLock->cnt==0 ){
      lock.l_type = F_UNLCK;
      lock.l_whence = SEEK_SET;
      lock.l_start = lock.l_len = 0L;
      fcntl(id->h, F_SETLK, &lock);
      pLock->locktype = NO_LOCK;



    }

    /* Decrement the count of locks against this same file.  When the
    ** count reaches zero, close any other file descriptors whose close
    ** was deferred because of outstanding locks.
    */
    pOpen = id->pOpen;
    pOpen->nLock--;
    assert( pOpen->nLock>=0 );
    if( pOpen->nLock==0 && pOpen->nPending>0 ){
      int i;
      for(i=0; i<pOpen->nPending; i++){
        close(pOpen->aPending[i]);
      }
      sqliteFree(pOpen->aPending);
      pOpen->nPending = 0;
      pOpen->aPending = 0;
    }
  }
  sqlite3OsLeaveMutex();
  id->locktype = locktype;
  return rc;
}

/*
** Close a file.
*/
int sqlite3OsClose(OsFile *id){



  if( !id->isOpen ) return SQLITE_OK;
  sqlite3OsUnlock(id, NO_LOCK);
  if( id->dirfd>=0 ) close(id->dirfd);
  id->dirfd = -1;
  sqlite3OsEnterMutex();

  if( id->pOpen->nLock ){
    /* If there are outstanding locks, do not actually close the file just
    ** yet because that would clear those locks.  Instead, add the file
    ** descriptor to pOpen->aPending.  It will be automatically closed when
    ** the last lock is cleared.
    */
    int *aNew;
    struct openCnt *pOpen = id->pOpen;
    pOpen->nPending++;
    aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*sizeof(int) );
    if( aNew==0 ){
      /* If a malloc fails, just leak the file descriptor */
    }else{
      pOpen->aPending = aNew;
      pOpen->aPending[pOpen->nPending-1] = id->h;

    }
  }else{
    /* There are no outstanding locks so we can close the file immediately */
    close(id->h);
  }
  releaseLockInfo(id->pLock);
  releaseOpenCnt(id->pOpen);

  sqlite3OsLeaveMutex();
  id->isOpen = 0;
  TRACE2("CLOSE   %-3d\n", id->h);
  OpenCounter(-1);




























































































  return SQLITE_OK;
}










/*
** Get information to seed the random number generator.  The seed
** is written into the buffer zBuf[256].  The calling function must
** supply a sufficiently large buffer.
*/
int sqlite3OsRandomSeed(char *zBuf){
  /* We have to initialize zBuf to prevent valgrind from reporting
  ** errors.  The reports issued by valgrind are incorrect - we would
  ** prefer that the randomness be increased by making use of the
  ** uninitialized space in zBuf - but valgrind errors tend to worry
  ** some users.  Rather than argue, it seems easier just to initialize
  ** the whole array and silence valgrind, even if that means less randomness
  ** in the random seed.
  **
  ** When testing, initializing zBuf[] to zero is all we do.  That means
  ** that we always use the same random number sequence.* This makes the
  ** tests repeatable.
  */
  memset(zBuf, 0, 256);
#if !defined(SQLITE_TEST)
  {
    int pid, fd;
    fd = open("/dev/urandom", O_RDONLY);
    if( fd<0 ){
      time((time_t*)zBuf);


      pid = getpid();
      memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
    }else{
      read(fd, zBuf, 256);
      close(fd);
    }
  }
#endif
  return SQLITE_OK;
}

/*
** Sleep for a little while.  Return the amount of time slept.

*/
int sqlite3OsSleep(int ms){
#if defined(HAVE_USLEEP) && HAVE_USLEEP
  usleep(ms*1000);
  return ms;
#else
  sleep((ms+999)/1000);
  return 1000*((ms+999)/1000);
#endif
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830




















1831
/*
** The following pair of routine implement mutual exclusion for
** multi-threaded processes.  Only a single thread is allowed to
** executed code that is surrounded by EnterMutex() and LeaveMutex().
**
** SQLite uses only a single Mutex.  There is not much critical
** code and what little there is executes quickly and without blocking.
**
** This mutex is not recursive.
*/
void sqlite3UnixEnterMutex(){
#ifdef SQLITE_UNIX_THREADS
  pthread_mutex_lock(&mutex);
#endif
  assert( !inMutex );
  inMutex = 1;
}
void sqlite3UnixLeaveMutex(){
  assert( inMutex );
  inMutex = 0;
#ifdef SQLITE_UNIX_THREADS
  pthread_mutex_unlock(&mutex);
#endif
}

/*
** Return TRUE if we are currently within the mutex and FALSE if not.
*/
int sqlite3UnixInMutex(){
  return inMutex;
}

/*
** Remember the number of thread-specific-data blocks allocated.
** Use this to verify that we are not leaking thread-specific-data.
** Ticket #1601
*/
#ifdef SQLITE_TEST
int sqlite3_tsd_count = 0;
# ifdef SQLITE_UNIX_THREADS
    static pthread_mutex_t tsd_counter_mutex = PTHREAD_MUTEX_INITIALIZER;
#   define TSD_COUNTER(N) \
             pthread_mutex_lock(&tsd_counter_mutex); \
             sqlite3_tsd_count += N; \
             pthread_mutex_unlock(&tsd_counter_mutex);
# else
#   define TSD_COUNTER(N)  sqlite3_tsd_count += N
# endif
#else
# define TSD_COUNTER(N)  /* no-op */
#endif


/*
** If called with allocateFlag>0, then return a pointer to thread
** specific data for the current thread.  Allocate and zero the
** thread-specific data if it does not already exist.
**
** If called with allocateFlag==0, then check the current thread
** specific data.  Return it if it exists.  If it does not exist,
** then return NULL.
**
** If called with allocateFlag<0, check to see if the thread specific
** data is allocated and is all zero.  If it is then deallocate it.
** Return a pointer to the thread specific data or NULL if it is
** unallocated or gets deallocated.
*/
ThreadData *sqlite3UnixThreadSpecificData(int allocateFlag){
  static const ThreadData zeroData;
#ifdef SQLITE_UNIX_THREADS
  static pthread_key_t key;
  static int keyInit = 0;
  ThreadData *pTsd;

  if( !keyInit ){
    sqlite3OsEnterMutex();
    if( !keyInit ){
      int rc;
      rc = pthread_key_create(&key, 0);
      if( rc ){
        sqlite3OsLeaveMutex();
        return 0;
      }
      keyInit = 1;
    }
    sqlite3OsLeaveMutex();
  }

  pTsd = pthread_getspecific(key);
  if( allocateFlag>0 ){
    if( pTsd==0 ){
      pTsd = sqlite3OsMalloc(sizeof(zeroData));
      if( pTsd ){
        *pTsd = zeroData;
        pthread_setspecific(key, pTsd);
        TSD_COUNTER(+1);
      }
    }
  }else if( pTsd!=0 && allocateFlag<0 
            && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
    sqlite3OsFree(pTsd);
    pthread_setspecific(key, 0);
    TSD_COUNTER(-1);
    pTsd = 0;
  }
  return pTsd;
#else
  static ThreadData *pTsd = 0;
  if( allocateFlag>0 ){
    if( pTsd==0 ){
      pTsd = sqlite3OsMalloc( sizeof(zeroData) );
      if( pTsd ){
        *pTsd = zeroData;
        TSD_COUNTER(+1);
      }
    }
  }else if( pTsd!=0 && allocateFlag<0
            && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
    sqlite3OsFree(pTsd);
    TSD_COUNTER(-1);
    pTsd = 0;
  }
  return pTsd;
#endif
}

/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3OsCurrentTime().  This is used for testing.
*/
#ifdef SQLITE_TEST
int sqlite3_current_time = 0;
#endif

/*
** Find the current time (in Universal Coordinated Time).  Write the
** current time and date as a Julian Day number into *prNow and
** return 0.  Return 1 if the time and date cannot be found.
*/
int sqlite3UnixCurrentTime(double *prNow){
#ifdef NO_GETTOD
  time_t t;
  time(&t);
  *prNow = t/86400.0 + 2440587.5;
#else
  struct timeval sNow;
  struct timezone sTz;  /* Not used */
  gettimeofday(&sNow, &sTz);
  *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_usec/86400000000.0;
#endif
#ifdef SQLITE_TEST
  if( sqlite3_current_time ){
    *prNow = sqlite3_current_time/86400.0 + 2440587.5;
  }
#endif
  return 0;
}





















#endif /* OS_UNIX */







<
<

|






|








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

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

|
<















|
<



<
<
<
<
<
<








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

1223
1224
1225
1226
1227
1228
1229


1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246





1247



















1248
1249




1250








1251








1252





1253





1254












1255





1256





1257




1258


1259
1260
1261

1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277

1278
1279
1280






1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
/*
** The following pair of routine implement mutual exclusion for
** multi-threaded processes.  Only a single thread is allowed to
** executed code that is surrounded by EnterMutex() and LeaveMutex().
**
** SQLite uses only a single Mutex.  There is not much critical
** code and what little there is executes quickly and without blocking.


*/
void sqlite3OsEnterMutex(){
#ifdef SQLITE_UNIX_THREADS
  pthread_mutex_lock(&mutex);
#endif
  assert( !inMutex );
  inMutex = 1;
}
void sqlite3OsLeaveMutex(){
  assert( inMutex );
  inMutex = 0;
#ifdef SQLITE_UNIX_THREADS
  pthread_mutex_unlock(&mutex);
#endif
}

/*





** Turn a relative pathname into a full pathname.  Return a pointer



















** to the full pathname stored in space obtained from sqliteMalloc().
** The calling function is responsible for freeing this space once it




** is no longer needed.








*/








char *sqlite3OsFullPathname(const char *zRelative){





  char *zFull = 0;





  if( zRelative[0]=='/' ){












    sqlite3SetString(&zFull, zRelative, (char*)0);





  }else{





    char zBuf[5000];




    sqlite3SetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,


                    (char*)0);
  }
  return zFull;

}

/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3OsCurrentTime().  This is used for testing.
*/
#ifdef SQLITE_TEST
int sqlite3_current_time = 0;
#endif

/*
** Find the current time (in Universal Coordinated Time).  Write the
** current time and date as a Julian Day number into *prNow and
** return 0.  Return 1 if the time and date cannot be found.
*/
int sqlite3OsCurrentTime(double *prNow){

  time_t t;
  time(&t);
  *prNow = t/86400.0 + 2440587.5;






#ifdef SQLITE_TEST
  if( sqlite3_current_time ){
    *prNow = sqlite3_current_time/86400.0 + 2440587.5;
  }
#endif
  return 0;
}

#if 0 /* NOT USED */
/*
** Find the time that the file was last modified.  Write the
** modification time and date as a Julian Day number into *prNow and
** return SQLITE_OK.  Return SQLITE_ERROR if the modification
** time cannot be found.
*/
int sqlite3OsFileModTime(OsFile *id, double *prNow){
  int rc;
  struct stat statbuf;
  if( fstat(id->h, &statbuf)==0 ){
    *prNow = statbuf.st_mtime/86400.0 + 2440587.5;
    rc = SQLITE_OK;
  }else{
    rc = SQLITE_ERROR;
  }
  return rc;
}
#endif /* NOT USED */

#endif /* OS_UNIX */
Added SQLite.Interop/src/os_unix.h.


















































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
** 2004 May 22
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This header file defined OS-specific features for Unix.
*/
#ifndef _SQLITE_OS_UNIX_H_
#define _SQLITE_OS_UNIX_H_

/*
** Helpful hint:  To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE
** to the compiler command line.
*/

/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
**
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
** on the compiler command line.  This is necessary if you are compiling
** on a recent machine (ex: RedHat 7.2) but you want your code to work
** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
** without this option, LFS is enable.  But LFS does not exist in the kernel
** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
** portability you should omit LFS.
**
** Similar is true for MacOS.  LFS is only supported on MacOS 9 and later.
*/
#ifndef SQLITE_DISABLE_LFS
# define _LARGE_FILE       1
# ifndef _FILE_OFFSET_BITS
#   define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif

/*
** standard include files.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

/*
** The OsFile structure is a operating-system independing representation
** of an open file handle.  It is defined differently for each architecture.
**
** This is the definition for Unix.
**
** OsFile.locktype takes one of the values SHARED_LOCK, RESERVED_LOCK,
** PENDING_LOCK or EXCLUSIVE_LOCK.
*/
typedef struct OsFile OsFile;
struct OsFile {
  struct Pager *pPager;     /* The pager that owns this OsFile.  Might be 0 */
  struct openCnt *pOpen;    /* Info about all open fd's on this inode */
  struct lockInfo *pLock;   /* Info about locks on this inode */
  int h;                    /* The file descriptor */
  unsigned char locktype;   /* The type of lock held on this fd */
  unsigned char isOpen;     /* True if needs to be closed */
  int dirfd;                /* File descriptor for the directory */
};

/*
** Maximum number of characters in a temporary file name
*/
#define SQLITE_TEMPNAME_SIZE 200

/*
** Minimum interval supported by sqlite3OsSleep().
*/
#if defined(HAVE_USLEEP) && HAVE_USLEEP
# define SQLITE_MIN_SLEEP_MS 1
#else
# define SQLITE_MIN_SLEEP_MS 1000
#endif


#endif /* _SQLITE_OS_UNIX_H_ */
Changes to SQLite.Interop/src/os_win.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544









545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655


656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
*/
#include "sqliteInt.h"
#include "os.h"
#if OS_WIN               /* This file is used for windows only */

#include <winbase.h>

#ifdef __CYGWIN__
# include <sys/cygwin.h>
#endif

/*
** Macros used to determine whether or not to use threads.
*/
#if defined(THREADSAFE) && THREADSAFE
# define SQLITE_W32_THREADS 1
#endif

/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"

/*
** Determine if we are dealing with WindowsCE - which has a much
** reduced API.
*/
#if defined(_WIN32_WCE)
# define OS_WINCE 1
#else
# define OS_WINCE 0
#endif

/*
** WinCE lacks native support for file locking so we have to fake it
** with some code of our own.
*/
#if OS_WINCE
typedef struct winceLock {
  int nReaders;       /* Number of reader locks obtained */
  BOOL bPending;      /* Indicates a pending lock has been obtained */
  BOOL bReserved;     /* Indicates a reserved lock has been obtained */
  BOOL bExclusive;    /* Indicates an exclusive lock has been obtained */
} winceLock;
#endif

/*
** The winFile structure is a subclass of OsFile specific to the win32
** portability layer.
*/
typedef struct winFile winFile;
struct winFile {
  IoMethod const *pMethod;/* Must be first */
  HANDLE h;               /* Handle for accessing the file */
  unsigned char locktype; /* Type of lock currently held on this file */
  short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
#if OS_WINCE
  WCHAR *zDeleteOnClose;  /* Name of file to delete when closing */
  HANDLE hMutex;          /* Mutex used to control access to shared lock */  
  HANDLE hShared;         /* Shared memory segment used for locking */
  winceLock local;        /* Locks obtained by this instance of winFile */
  winceLock *shared;      /* Global shared lock memory for the file  */
#endif
};


/*
** Do not include any of the File I/O interface procedures if the
** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
** will be in-memory only)
*/
#ifndef SQLITE_OMIT_DISKIO

/*
** The following variable is (normally) set once and never changes
** thereafter.  It records whether the operating system is Win95
** or WinNT.
**
** 0:   Operating system unknown.
** 1:   Operating system is Win95.
** 2:   Operating system is WinNT.
**
** In order to facilitate testing on a WinNT system, the test fixture
** can manually set this value to 1 to emulate Win98 behavior.
*/
int sqlite3_os_type = 0;

/*
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
**
** Here is an interesting observation:  Win95, Win98, and WinME lack
** the LockFileEx() API.  But we can still statically link against that
** API as long as we don't call it win running Win95/98/ME.  A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
#if OS_WINCE
# define isNT()  (1)
#else
  static int isNT(void){
    if( sqlite3_os_type==0 ){
      OSVERSIONINFO sInfo;
      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
      GetVersionEx(&sInfo);
      sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
    }
    return sqlite3_os_type==2;
  }
#endif /* OS_WINCE */

/*
** Convert a UTF-8 string to UTF-32.  Space to hold the returned string
** is obtained from sqliteMalloc.
*/
static WCHAR *utf8ToUnicode(const char *zFilename){
  int nByte;
  WCHAR *zWideFilename;

  if( !isNT() ){
    return 0;
  }
  nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR);
  zWideFilename = sqliteMalloc( nByte*sizeof(zWideFilename[0]) );
  if( zWideFilename==0 ){
    return 0;
  }
  nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nByte);
  if( nByte==0 ){
    sqliteFree(zWideFilename);
    zWideFilename = 0;
  }
  return zWideFilename;
}

/*
** Convert UTF-32 to UTF-8.  Space to hold the returned string is
** obtained from sqliteMalloc().
*/
static char *unicodeToUtf8(const WCHAR *zWideFilename){
  int nByte;
  char *zFilename;

  nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
  zFilename = sqliteMalloc( nByte );
  if( zFilename==0 ){
    return 0;
  }
  nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
                              0, 0);
  if( nByte == 0 ){
    sqliteFree(zFilename);
    zFilename = 0;
  }
  return zFilename;
}

#if OS_WINCE
/*************************************************************************
** This section contains code for WinCE only.
*/
/*
** WindowsCE does not have a localtime() function.  So create a
** substitute.
*/
#include <time.h>
struct tm *__cdecl localtime(const time_t *t)
{
  static struct tm y;
  FILETIME uTm, lTm;
  SYSTEMTIME pTm;
  i64 t64;
  t64 = *t;
  t64 = (t64 + 11644473600)*10000000;
  uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
  uTm.dwHighDateTime= t64 >> 32;
  FileTimeToLocalFileTime(&uTm,&lTm);
  FileTimeToSystemTime(&lTm,&pTm);
  y.tm_year = pTm.wYear - 1900;
  y.tm_mon = pTm.wMonth - 1;
  y.tm_wday = pTm.wDayOfWeek;
  y.tm_mday = pTm.wDay;
  y.tm_hour = pTm.wHour;
  y.tm_min = pTm.wMinute;
  y.tm_sec = pTm.wSecond;
  return &y;
}

/* This will never be called, but defined to make the code compile */
#define GetTempPathA(a,b)

#define LockFile(a,b,c,d,e)       winceLockFile(&a, b, c, d, e)
#define UnlockFile(a,b,c,d,e)     winceUnlockFile(&a, b, c, d, e)
#define LockFileEx(a,b,c,d,e,f)   winceLockFileEx(&a, b, c, d, e, f)

#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]

/*
** Acquire a lock on the handle h
*/
static void winceMutexAcquire(HANDLE h){
   DWORD dwErr;
   do {
     dwErr = WaitForSingleObject(h, INFINITE);
   } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
}
/*
** Release a lock acquired by winceMutexAcquire()
*/
#define winceMutexRelease(h) ReleaseMutex(h)

/*
** Create the mutex and shared memory used for locking in the file
** descriptor pFile
*/
static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
  WCHAR *zTok;
  WCHAR *zName = utf8ToUnicode(zFilename);
  BOOL bInit = TRUE;

  /* Initialize the local lockdata */
  ZeroMemory(&pFile->local, sizeof(pFile->local));

  /* Replace the backslashes from the filename and lowercase it
  ** to derive a mutex name. */
  zTok = CharLowerW(zName);
  for (;*zTok;zTok++){
    if (*zTok == '\\') *zTok = '_';
  }

  /* Create/open the named mutex */
  pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
  if (!pFile->hMutex){
    sqliteFree(zName);
    return FALSE;
  }

  /* Acquire the mutex before continuing */
  winceMutexAcquire(pFile->hMutex);
  
  /* Since the names of named mutexes, semaphores, file mappings etc are 
  ** case-sensitive, take advantage of that by uppercasing the mutex name
  ** and using that as the shared filemapping name.
  */
  CharUpperW(zName);
  pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
                                       PAGE_READWRITE, 0, sizeof(winceLock),
                                       zName);  

  /* Set a flag that indicates we're the first to create the memory so it 
  ** must be zero-initialized */
  if (GetLastError() == ERROR_ALREADY_EXISTS){
    bInit = FALSE;
  }

  sqliteFree(zName);

  /* If we succeeded in making the shared memory handle, map it. */
  if (pFile->hShared){
    pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, 
             FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
    /* If mapping failed, close the shared memory handle and erase it */
    if (!pFile->shared){
      CloseHandle(pFile->hShared);
      pFile->hShared = NULL;
    }
  }

  /* If shared memory could not be created, then close the mutex and fail */
  if (pFile->hShared == NULL){
    winceMutexRelease(pFile->hMutex);
    CloseHandle(pFile->hMutex);
    pFile->hMutex = NULL;
    return FALSE;
  }
  
  /* Initialize the shared memory if we're supposed to */
  if (bInit) {
    ZeroMemory(pFile->shared, sizeof(winceLock));
  }

  winceMutexRelease(pFile->hMutex);
  return TRUE;
}

/*
** Destroy the part of winFile that deals with wince locks
*/
static void winceDestroyLock(winFile *pFile){
  if (pFile->hMutex){
    /* Acquire the mutex */
    winceMutexAcquire(pFile->hMutex);

    /* The following blocks should probably assert in debug mode, but they
       are to cleanup in case any locks remained open */
    if (pFile->local.nReaders){
      pFile->shared->nReaders --;
    }
    if (pFile->local.bReserved){
      pFile->shared->bReserved = FALSE;
    }
    if (pFile->local.bPending){
      pFile->shared->bPending = FALSE;
    }
    if (pFile->local.bExclusive){
      pFile->shared->bExclusive = FALSE;
    }

    /* De-reference and close our copy of the shared memory handle */
    UnmapViewOfFile(pFile->shared);
    CloseHandle(pFile->hShared);

    /* Done with the mutex */
    winceMutexRelease(pFile->hMutex);    
    CloseHandle(pFile->hMutex);
    pFile->hMutex = NULL;
  }
}

/* 
** An implementation of the LockFile() API of windows for wince
*/
static BOOL winceLockFile(
  HANDLE *phFile,
  DWORD dwFileOffsetLow,
  DWORD dwFileOffsetHigh,
  DWORD nNumberOfBytesToLockLow,
  DWORD nNumberOfBytesToLockHigh
){
  winFile *pFile = HANDLE_TO_WINFILE(phFile);
  BOOL bReturn = FALSE;

  if (!pFile->hMutex) return TRUE;
  winceMutexAcquire(pFile->hMutex);

  /* Wanting an exclusive lock? */
  if (dwFileOffsetLow == SHARED_FIRST
       && nNumberOfBytesToLockLow == SHARED_SIZE){
    if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
       pFile->shared->bExclusive = TRUE;
       pFile->local.bExclusive = TRUE;
       bReturn = TRUE;
    }
  }

  /* Want a read-only lock? */
  else if ((dwFileOffsetLow >= SHARED_FIRST &&
            dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&
            nNumberOfBytesToLockLow == 1){
    if (pFile->shared->bExclusive == 0){
      pFile->local.nReaders ++;
      if (pFile->local.nReaders == 1){
        pFile->shared->nReaders ++;
      }
      bReturn = TRUE;
    }
  }

  /* Want a pending lock? */
  else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
    /* If no pending lock has been acquired, then acquire it */
    if (pFile->shared->bPending == 0) {
      pFile->shared->bPending = TRUE;
      pFile->local.bPending = TRUE;
      bReturn = TRUE;
    }
  }
  /* Want a reserved lock? */
  else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
    if (pFile->shared->bReserved == 0) {
      pFile->shared->bReserved = TRUE;
      pFile->local.bReserved = TRUE;
      bReturn = TRUE;
    }
  }

  winceMutexRelease(pFile->hMutex);
  return bReturn;
}

/*
** An implementation of the UnlockFile API of windows for wince
*/
static BOOL winceUnlockFile(
  HANDLE *phFile,
  DWORD dwFileOffsetLow,
  DWORD dwFileOffsetHigh,
  DWORD nNumberOfBytesToUnlockLow,
  DWORD nNumberOfBytesToUnlockHigh
){
  winFile *pFile = HANDLE_TO_WINFILE(phFile);
  BOOL bReturn = FALSE;

  if (!pFile->hMutex) return TRUE;
  winceMutexAcquire(pFile->hMutex);

  /* Releasing a reader lock or an exclusive lock */
  if (dwFileOffsetLow >= SHARED_FIRST &&
       dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){
    /* Did we have an exclusive lock? */
    if (pFile->local.bExclusive){
      pFile->local.bExclusive = FALSE;
      pFile->shared->bExclusive = FALSE;
      bReturn = TRUE;
    }

    /* Did we just have a reader lock? */
    else if (pFile->local.nReaders){
      pFile->local.nReaders --;
      if (pFile->local.nReaders == 0)
      {
        pFile->shared->nReaders --;
      }
      bReturn = TRUE;
    }
  }

  /* Releasing a pending lock */
  else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
    if (pFile->local.bPending){
      pFile->local.bPending = FALSE;
      pFile->shared->bPending = FALSE;
      bReturn = TRUE;
    }
  }
  /* Releasing a reserved lock */
  else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
    if (pFile->local.bReserved) {
      pFile->local.bReserved = FALSE;
      pFile->shared->bReserved = FALSE;
      bReturn = TRUE;
    }
  }

  winceMutexRelease(pFile->hMutex);
  return bReturn;
}

/*
** An implementation of the LockFileEx() API of windows for wince
*/
static BOOL winceLockFileEx(
  HANDLE *phFile,
  DWORD dwFlags,
  DWORD dwReserved,
  DWORD nNumberOfBytesToLockLow,
  DWORD nNumberOfBytesToLockHigh,
  LPOVERLAPPED lpOverlapped
){
  /* If the caller wants a shared read lock, forward this call
  ** to winceLockFile */
  if (lpOverlapped->Offset == SHARED_FIRST &&
      dwFlags == 1 &&
      nNumberOfBytesToLockLow == SHARED_SIZE){
    return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
  }
  return FALSE;
}
/*
** End of the special code for wince
*****************************************************************************/
#endif /* OS_WINCE */

/*
** Delete the named file
*/
int sqlite3WinDelete(const char *zFilename){
  WCHAR *zWide = utf8ToUnicode(zFilename);
  if( zWide ){
    DeleteFileW(zWide);
    sqliteFree(zWide);
  }else{
#if OS_WINCE
    return SQLITE_NOMEM;
#else
    DeleteFileA(zFilename);
#endif
  }
  TRACE2("DELETE \"%s\"\n", zFilename);
  return SQLITE_OK;
}

/*
** Return TRUE if the named file exists.
*/
int sqlite3WinFileExists(const char *zFilename){
  int exists = 0;
  WCHAR *zWide = utf8ToUnicode(zFilename);
  if( zWide ){
    exists = GetFileAttributesW(zWide) != 0xffffffff;
    sqliteFree(zWide);
  }else{
#if OS_WINCE
    return SQLITE_NOMEM;
#else
    exists = GetFileAttributesA(zFilename) != 0xffffffff;
#endif
  }
  return exists;
}

/* Forward declaration */
int allocateWinFile(winFile *pInit, OsFile **pId);

/*
** Attempt to open a file for both reading and writing.  If that
** fails, try opening it read-only.  If the file does not exist,
** try to create it.
**
** On success, a handle for the open file is written to *id
** and *pReadonly is set to 0 if the file was opened for reading and
** writing or 1 if the file was opened read-only.  The function returns
** SQLITE_OK.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id and *pReadonly unchanged.
*/
int sqlite3WinOpenReadWrite(
  const char *zFilename,
  OsFile **pId,
  int *pReadonly
){
  winFile f;
  HANDLE h;
  WCHAR *zWide = utf8ToUnicode(zFilename);
  assert( *pId==0 );
  if( zWide ){
    h = CreateFileW(zWide,
       GENERIC_READ | GENERIC_WRITE,
       FILE_SHARE_READ | FILE_SHARE_WRITE,









       NULL,
       OPEN_ALWAYS,
       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
       NULL
    );
    if( h==INVALID_HANDLE_VALUE ){
      h = CreateFileW(zWide,
         GENERIC_READ,
         FILE_SHARE_READ,
         NULL,
         OPEN_ALWAYS,
         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
         NULL
      );
      if( h==INVALID_HANDLE_VALUE ){
        sqliteFree(zWide);
        return SQLITE_CANTOPEN;
      }
      *pReadonly = 1;
    }else{
      *pReadonly = 0;
    }
#if OS_WINCE
    if (!winceCreateLock(zFilename, &f)){
      CloseHandle(h);
      sqliteFree(zWide);
      return SQLITE_CANTOPEN;
    }
#endif
    sqliteFree(zWide);
  }else{
#if OS_WINCE
    return SQLITE_NOMEM;
#else
    h = CreateFileA(zFilename,
       GENERIC_READ | GENERIC_WRITE,
       FILE_SHARE_READ | FILE_SHARE_WRITE,
       NULL,
       OPEN_ALWAYS,
       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
       NULL
    );
    if( h==INVALID_HANDLE_VALUE ){
      h = CreateFileA(zFilename,
         GENERIC_READ,
         FILE_SHARE_READ,
         NULL,
         OPEN_ALWAYS,
         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
         NULL
      );
      if( h==INVALID_HANDLE_VALUE ){
        return SQLITE_CANTOPEN;
      }
      *pReadonly = 1;
    }else{
      *pReadonly = 0;
    }
#endif /* OS_WINCE */
  }
  f.h = h;
  f.locktype = NO_LOCK;
  f.sharedLockByte = 0;
#if OS_WINCE
  f.zDeleteOnClose = 0;
#endif
  TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
  return allocateWinFile(&f, pId);
}


/*
** Attempt to open a new file for exclusive access by this process.
** The file will be opened for both reading and writing.  To avoid
** a potential security problem, we do not allow the file to have
** previously existed.  Nor do we allow the file to be a symbolic
** link.
**
** If delFlag is true, then make arrangements to automatically delete
** the file when it is closed.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
  winFile f;
  HANDLE h;
  int fileflags;
  WCHAR *zWide = utf8ToUnicode(zFilename);
  assert( *pId == 0 );
  fileflags = FILE_FLAG_RANDOM_ACCESS;
#if !OS_WINCE
  if( delFlag ){
    fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
  }
#endif
  if( zWide ){
    h = CreateFileW(zWide,
       GENERIC_READ | GENERIC_WRITE,
       0,
       NULL,
       CREATE_ALWAYS,
       fileflags,
       NULL
    );
    sqliteFree(zWide);
  }else{
#if OS_WINCE
    return SQLITE_NOMEM;
#else


    h = CreateFileA(zFilename,
       GENERIC_READ | GENERIC_WRITE,
       0,
       NULL,
       CREATE_ALWAYS,
       fileflags,
       NULL
    );
#endif /* OS_WINCE */
  }
  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
  }
  f.h = h;
  f.locktype = NO_LOCK;
  f.sharedLockByte = 0;
#if OS_WINCE
  f.zDeleteOnClose = delFlag ? utf8ToUnicode(zFilename) : 0;
  f.hMutex = NULL;
#endif
  TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
  return allocateWinFile(&f, pId);
}

/*
** Attempt to open a new file for read-only access.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
  winFile f;
  HANDLE h;
  WCHAR *zWide = utf8ToUnicode(zFilename);
  assert( *pId==0 );
  if( zWide ){
    h = CreateFileW(zWide,
       GENERIC_READ,
       0,
       NULL,
       OPEN_EXISTING,
       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
       NULL
    );
    sqliteFree(zWide);
  }else{
#if OS_WINCE
    return SQLITE_NOMEM;
#else
    h = CreateFileA(zFilename,
       GENERIC_READ,
       0,
       NULL,
       OPEN_EXISTING,
       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
       NULL
    );
#endif
  }
  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
  }
  f.h = h;
  f.locktype = NO_LOCK;
  f.sharedLockByte = 0;
#if OS_WINCE
  f.zDeleteOnClose = 0;
  f.hMutex = NULL;
#endif
  TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
  return allocateWinFile(&f, pId);
}

/*
** Attempt to open a file descriptor for the directory that contains a
** file.  This file descriptor can be used to fsync() the directory
** in order to make sure the creation of a new file is actually written
** to disk.
**
** This routine is only meaningful for Unix.  It is a no-op under
** windows since windows does not support hard links.
**
** On success, a handle for a previously open file is at *id is
** updated with the new directory file descriptor and SQLITE_OK is
** returned.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id unchanged.
*/
static int winOpenDirectory(
  OsFile *id,
  const char *zDirname

){
  return SQLITE_OK;
}

/*
** If the following global variable points to a string which is the
** name of a directory, then that directory will be used to store
** temporary files.
*/
char *sqlite3_temp_directory = 0;

/*
** Create a temporary file name in zBuf.  zBuf must be big enough to
** hold at least SQLITE_TEMPNAME_SIZE characters.
*/
int sqlite3WinTempFileName(char *zBuf){
  static char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  int i, j;
  char zTempPath[SQLITE_TEMPNAME_SIZE];
  if( sqlite3_temp_directory ){
    strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
    zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
  }else if( isNT() ){
    char *zMulti;
    WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
    GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
    zMulti = unicodeToUtf8(zWidePath);
    if( zMulti ){
      strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
      zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
      sqliteFree(zMulti);
    }
  }else{
    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
  }
  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
  zTempPath[i] = 0;
  for(;;){
    sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);







<
<
<
<












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



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







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














|

|


<

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






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

|

















|
<


<
|
<
<

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

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



|
|
|
<
<
|
|

|









|
<

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



|
|
|
<
<
|
|

|


















|
<
|
>















|









<
<
<
<
<
<
<
<
<
<







14
15
16
17
18
19
20




21
22
23
24
25
26
27
28
29
30
31
32

























































































































































































































































































































































































































































33
34
35
36








37


38
39
40
41
42
43
44
45









46

47





48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67

68

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










87
88
89
90
91
92






































93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119

120


121
122







123




124



125
126
127
128
129
130
131
132
133
134


135
136
137
138
139
140


141
142
143
144
145
146
147
148
149
150
151
152
153
154

155

156














157
158
159
160
161
162
163
164


165
166
167
168
169
170


171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220










221
222
223
224
225
226
227
*/
#include "sqliteInt.h"
#include "os.h"
#if OS_WIN               /* This file is used for windows only */

#include <winbase.h>





/*
** Macros used to determine whether or not to use threads.
*/
#if defined(THREADSAFE) && THREADSAFE
# define SQLITE_W32_THREADS 1
#endif

/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"


























































































































































































































































































































































































































































/*
** Delete the named file
*/
int sqlite3OsDelete(const char *zFilename){








  DeleteFileA(zFilename);


  TRACE2("DELETE \"%s\"\n", zFilename);
  return SQLITE_OK;
}

/*
** Return TRUE if the named file exists.
*/
int sqlite3OsFileExists(const char *zFilename){









  return GetFileAttributesA(zFilename) != 0xffffffff;

}






/*
** Attempt to open a file for both reading and writing.  If that
** fails, try opening it read-only.  If the file does not exist,
** try to create it.
**
** On success, a handle for the open file is written to *id
** and *pReadonly is set to 0 if the file was opened for reading and
** writing or 1 if the file was opened read-only.  The function returns
** SQLITE_OK.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id and *pReadonly unchanged.
*/
int sqlite3OsOpenReadWrite(
  const char *zFilename,
  OsFile *id,
  int *pReadonly
){

  HANDLE h;

  assert( !id->isOpen );

  h = CreateFileA(zFilename,
     GENERIC_READ | GENERIC_WRITE,
     FILE_SHARE_READ | FILE_SHARE_WRITE,
     NULL,
     OPEN_ALWAYS,
     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
     NULL
  );
  if( h==INVALID_HANDLE_VALUE ){
    h = CreateFileA(zFilename,
       GENERIC_READ,
       FILE_SHARE_READ,
       NULL,
       OPEN_ALWAYS,
       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
       NULL
    );
    if( h==INVALID_HANDLE_VALUE ){










      return SQLITE_CANTOPEN;
    }
    *pReadonly = 1;
  }else{
    *pReadonly = 0;
  }






































  id->h = h;
  id->locktype = NO_LOCK;
  id->sharedLockByte = 0;

  id->isOpen = 1;
  OpenCounter(+1);
  TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
  return SQLITE_OK;
}


/*
** Attempt to open a new file for exclusive access by this process.
** The file will be opened for both reading and writing.  To avoid
** a potential security problem, we do not allow the file to have
** previously existed.  Nor do we allow the file to be a symbolic
** link.
**
** If delFlag is true, then make arrangements to automatically delete
** the file when it is closed.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){

  HANDLE h;
  int fileflags;

  assert( !id->isOpen );


  if( delFlag ){
    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS 







                     | FILE_FLAG_DELETE_ON_CLOSE;




  }else{



    fileflags = FILE_FLAG_RANDOM_ACCESS;
  }
  h = CreateFileA(zFilename,
     GENERIC_READ | GENERIC_WRITE,
     0,
     NULL,
     CREATE_ALWAYS,
     fileflags,
     NULL
  );


  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
  }
  id->h = h;
  id->locktype = NO_LOCK;
  id->sharedLockByte = 0;


  id->isOpen = 1;
  OpenCounter(+1);
  TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
  return SQLITE_OK;
}

/*
** Attempt to open a new file for read-only access.
**
** On success, write the file handle into *id and return SQLITE_OK.
**
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){

  HANDLE h;

  assert( !id->isOpen );














  h = CreateFileA(zFilename,
     GENERIC_READ,
     0,
     NULL,
     OPEN_EXISTING,
     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
     NULL
  );


  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
  }
  id->h = h;
  id->locktype = NO_LOCK;
  id->sharedLockByte = 0;


  id->isOpen = 1;
  OpenCounter(+1);
  TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
  return SQLITE_OK;
}

/*
** Attempt to open a file descriptor for the directory that contains a
** file.  This file descriptor can be used to fsync() the directory
** in order to make sure the creation of a new file is actually written
** to disk.
**
** This routine is only meaningful for Unix.  It is a no-op under
** windows since windows does not support hard links.
**
** On success, a handle for a previously open file is at *id is
** updated with the new directory file descriptor and SQLITE_OK is
** returned.
**
** On failure, the function returns SQLITE_CANTOPEN and leaves
** *id unchanged.
*/
int sqlite3OsOpenDirectory(

  const char *zDirname,
  OsFile *id
){
  return SQLITE_OK;
}

/*
** If the following global variable points to a string which is the
** name of a directory, then that directory will be used to store
** temporary files.
*/
char *sqlite3_temp_directory = 0;

/*
** Create a temporary file name in zBuf.  zBuf must be big enough to
** hold at least SQLITE_TEMPNAME_SIZE characters.
*/
int sqlite3OsTempFileName(char *zBuf){
  static char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  int i, j;
  char zTempPath[SQLITE_TEMPNAME_SIZE];
  if( sqlite3_temp_directory ){
    strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
    zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;










  }else{
    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
  }
  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
  zTempPath[i] = 0;
  for(;;){
    sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943








944
945
946


947







948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
  TRACE2("TEMP FILENAME: %s\n", zBuf);
  return SQLITE_OK; 
}

/*
** Close a file.
*/
static int winClose(OsFile **pId){
  winFile *pFile;
  if( pId && (pFile = (winFile*)*pId)!=0 ){
    TRACE2("CLOSE %d\n", pFile->h);
    CloseHandle(pFile->h);
#if OS_WINCE
    winceDestroyLock(pFile);
    if( pFile->zDeleteOnClose ){
      DeleteFileW(pFile->zDeleteOnClose);
      sqliteFree(pFile->zDeleteOnClose);
    }
#endif
    OpenCounter(-1);
    sqliteFree(pFile);
    *pId = 0;
  }
  return SQLITE_OK;
}

/*
** Read data from a file into a buffer.  Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong.
*/
static int winRead(OsFile *id, void *pBuf, int amt){
  DWORD got;
  assert( id!=0 );
  SimulateIOError(SQLITE_IOERR);
  TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
  if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
    got = 0;
  }
  if( got==(DWORD)amt ){
    return SQLITE_OK;
  }else{
    return SQLITE_IOERR;
  }
}

/*
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.
*/
static int winWrite(OsFile *id, const void *pBuf, int amt){
  int rc = 0;
  DWORD wrote;
  assert( id!=0 );
  SimulateIOError(SQLITE_IOERR);
  SimulateDiskfullError;
  TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
  assert( amt>0 );
  while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
         && wrote>0 ){
    amt -= wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  if( !rc || amt>(int)wrote ){
    return SQLITE_FULL;
  }
  return SQLITE_OK;
}

/*
** Some microsoft compilers lack this definition.
*/
#ifndef INVALID_SET_FILE_POINTER
# define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif

/*
** Move the read/write pointer in a file.
*/
static int winSeek(OsFile *id, i64 offset){
  LONG upperBits = offset>>32;
  LONG lowerBits = offset & 0xffffffff;
  DWORD rc;
  assert( id!=0 );
#ifdef SQLITE_TEST
  if( offset ) SimulateDiskfullError
#endif
  SEEK(offset/1024 + 1);
  rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
  TRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset);
  if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
    return SQLITE_FULL;
  }
  return SQLITE_OK;
}

/*
** Make sure all writes to a particular file are committed to disk.
*/
static int winSync(OsFile *id, int dataOnly){
  assert( id!=0 );
  TRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
  if( FlushFileBuffers(((winFile*)id)->h) ){
    return SQLITE_OK;
  }else{
    return SQLITE_IOERR;
  }
}

/*
** Sync the directory zDirname. This is a no-op on operating systems other
** than UNIX.
*/
int sqlite3WinSyncDirectory(const char *zDirname){
  SimulateIOError(SQLITE_IOERR);
  return SQLITE_OK;
}

/*
** Truncate an open file to a specified size
*/
static int winTruncate(OsFile *id, i64 nByte){
  LONG upperBits = nByte>>32;
  assert( id!=0 );
  TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
  SimulateIOError(SQLITE_IOERR);
  SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
  SetEndOfFile(((winFile*)id)->h);
  return SQLITE_OK;
}

/*
** Determine the current size of a file in bytes
*/
static int winFileSize(OsFile *id, i64 *pSize){
  DWORD upperBits, lowerBits;
  assert( id!=0 );
  SimulateIOError(SQLITE_IOERR);
  lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
  *pSize = (((i64)upperBits)<<32) + lowerBits;
  return SQLITE_OK;
}

/*
** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.








*/
#ifndef LOCKFILE_FAIL_IMMEDIATELY
# define LOCKFILE_FAIL_IMMEDIATELY 1


#endif








/*
** Acquire a reader lock.
** Different API routines are called depending on whether or not this
** is Win95 or WinNT.
*/
static int getReadLock(winFile *id){
  int res;
  if( isNT() ){
    OVERLAPPED ovlp;
    ovlp.Offset = SHARED_FIRST;
    ovlp.OffsetHigh = 0;
    ovlp.hEvent = 0;
    res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
  }else{
    int lk;
    sqlite3Randomness(sizeof(lk), &lk);
    id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
    res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
  }
  return res;
}

/*
** Undo a readlock
*/
static int unlockReadLock(winFile *pFile){
  int res;
  if( isNT() ){
    res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  }else{
    res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
  }
  return res;
}

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
** Check that a given pathname is a directory and is writable 
**
*/
int sqlite3WinIsDirWritable(char *zDirname){
  int fileAttr;
  WCHAR *zWide;
  if( zDirname==0 ) return 0;
  if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
  zWide = utf8ToUnicode(zDirname);
  if( zWide ){
    fileAttr = GetFileAttributesW(zWide);
    sqliteFree(zWide);
  }else{
#if OS_WINCE
    return 0;
#else
    fileAttr = GetFileAttributesA(zDirname);
#endif
  }
  if( fileAttr == 0xffffffff ) return 0;
  if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
    return 0;
  }
  return 1;
}
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */







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

<
|









|

|

|
|













|


|


|

|
<









<
<
<
<
<
<
<



|



|
<
<
<

|
|
<
<
<






|
|
|
|










|







|

|
|

|
|






|

|

|





|
>
>
>
>
>
>
>
>

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






|



















|


|

|









|

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







236
237
238
239
240
241
242
243

244
245
246







247

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293
294







295
296
297
298
299
300
301
302



303
304
305



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366


367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

420
421


422








423
424
425
426
427
428
429
  TRACE2("TEMP FILENAME: %s\n", zBuf);
  return SQLITE_OK; 
}

/*
** Close a file.
*/
int sqlite3OsClose(OsFile *id){

  if( id->isOpen ){
    TRACE2("CLOSE %d\n", id->h);
    CloseHandle(id->h);







    OpenCounter(-1);

    id->isOpen = 0;
  }
  return SQLITE_OK;
}

/*
** Read data from a file into a buffer.  Return SQLITE_OK if all
** bytes were read successfully and SQLITE_IOERR if anything goes
** wrong.
*/
int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
  DWORD got;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  TRACE3("READ %d lock=%d\n", id->h, id->locktype);
  if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
    got = 0;
  }
  if( got==(DWORD)amt ){
    return SQLITE_OK;
  }else{
    return SQLITE_IOERR;
  }
}

/*
** Write data from a buffer into a file.  Return SQLITE_OK on success
** or some other error code on failure.
*/
int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
  int rc = 0;
  DWORD wrote;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  SimulateDiskfullError;
  TRACE3("WRITE %d lock=%d\n", id->h, id->locktype);
  assert( amt>0 );
  while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){

    amt -= wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  if( !rc || amt>(int)wrote ){
    return SQLITE_FULL;
  }
  return SQLITE_OK;
}








/*
** Move the read/write pointer in a file.
*/
int sqlite3OsSeek(OsFile *id, i64 offset){
  LONG upperBits = offset>>32;
  LONG lowerBits = offset & 0xffffffff;
  DWORD rc;
  assert( id->isOpen );



  SEEK(offset/1024 + 1);
  rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
  TRACE3("SEEK %d %lld\n", id->h, offset);



  return SQLITE_OK;
}

/*
** Make sure all writes to a particular file are committed to disk.
*/
int sqlite3OsSync(OsFile *id){
  assert( id->isOpen );
  TRACE3("SYNC %d lock=%d\n", id->h, id->locktype);
  if( FlushFileBuffers(id->h) ){
    return SQLITE_OK;
  }else{
    return SQLITE_IOERR;
  }
}

/*
** Sync the directory zDirname. This is a no-op on operating systems other
** than UNIX.
*/
int sqlite3OsSyncDirectory(const char *zDirname){
  SimulateIOError(SQLITE_IOERR);
  return SQLITE_OK;
}

/*
** Truncate an open file to a specified size
*/
int sqlite3OsTruncate(OsFile *id, i64 nByte){
  LONG upperBits = nByte>>32;
  assert( id->isOpen );
  TRACE3("TRUNCATE %d %lld\n", id->h, nByte);
  SimulateIOError(SQLITE_IOERR);
  SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
  SetEndOfFile(id->h);
  return SQLITE_OK;
}

/*
** Determine the current size of a file in bytes
*/
int sqlite3OsFileSize(OsFile *id, i64 *pSize){
  DWORD upperBits, lowerBits;
  assert( id->isOpen );
  SimulateIOError(SQLITE_IOERR);
  lowerBits = GetFileSize(id->h, &upperBits);
  *pSize = (((i64)upperBits)<<32) + lowerBits;
  return SQLITE_OK;
}

/*
** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
** Return false (zero) for Win95, Win98, or WinME.
**
** Here is an interesting observation:  Win95, Win98, and WinME lack
** the LockFileEx() API.  But we can still statically link against that
** API as long as we don't call it win running Win95/98/ME.  A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/


static int isNT(void){
  static int osType = 0;   /* 0=unknown 1=win95 2=winNT */
  if( osType==0 ){
    OSVERSIONINFO sInfo;
    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
    GetVersionEx(&sInfo);
    osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
  }
  return osType==2;
}

/*
** Acquire a reader lock.
** Different API routines are called depending on whether or not this
** is Win95 or WinNT.
*/
static int getReadLock(OsFile *id){
  int res;
  if( isNT() ){
    OVERLAPPED ovlp;
    ovlp.Offset = SHARED_FIRST;
    ovlp.OffsetHigh = 0;
    ovlp.hEvent = 0;
    res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
  }else{
    int lk;
    sqlite3Randomness(sizeof(lk), &lk);
    id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
    res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
  }
  return res;
}

/*
** Undo a readlock
*/
static int unlockReadLock(OsFile *id){
  int res;
  if( isNT() ){
    res = UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  }else{
    res = UnlockFile(id->h, SHARED_FIRST + id->sharedLockByte, 0, 1, 0);
  }
  return res;
}

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
** Check that a given pathname is a directory and is writable 
**
*/
int sqlite3OsIsDirWritable(char *zBuf){
  int fileAttr;

  if(! zBuf ) return 0;
  if(! isNT() && strlen(zBuf) > MAX_PATH ) return 0;


  fileAttr = GetFileAttributesA(zBuf);








  if( fileAttr == 0xffffffff ) return 0;
  if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
    return 0;
  }
  return 1;
}
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396



1397





1398


1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441




1442



1443




1444
1445
1446
1447
1448
1449
1450
1451
1452
1453

1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
**
**    UNLOCKED -> SHARED
**    SHARED -> RESERVED
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** This routine will only increase a lock.  The winUnlock() routine
** erases all locks at once and returns us immediately to locking level 0.
** It is not possible to lower the locking level one step at a time.  You
** must go straight to locking level 0.
*/
static int winLock(OsFile *id, int locktype){
  int rc = SQLITE_OK;    /* Return code from subroutines */
  int res = 1;           /* Result of a windows lock call */
  int newLocktype;       /* Set id->locktype to this value before exiting */
  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
  winFile *pFile = (winFile*)id;

  assert( pFile!=0 );
  TRACE5("LOCK %d %d was %d(%d)\n",
          pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);

  /* If there is already a lock of this type or more restrictive on the
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( pFile->locktype>=locktype ){
    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );

  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
  ** the PENDING_LOCK byte is temporary.
  */
  newLocktype = pFile->locktype;
  if( pFile->locktype==NO_LOCK
   || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
  ){
    int cnt = 3;
    while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
      /* Try 3 times to get the pending lock.  The pending lock might be
      ** held by another reader process who will release it momentarily.
      */
      TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
      Sleep(1);
    }
    gotPendingLock = res;
  }

  /* Acquire a shared lock
  */
  if( locktype==SHARED_LOCK && res ){
    assert( pFile->locktype==NO_LOCK );
    res = getReadLock(pFile);
    if( res ){
      newLocktype = SHARED_LOCK;
    }
  }

  /* Acquire a RESERVED lock
  */
  if( locktype==RESERVED_LOCK && res ){
    assert( pFile->locktype==SHARED_LOCK );
    res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
    if( res ){
      newLocktype = RESERVED_LOCK;
    }
  }

  /* Acquire a PENDING lock
  */
  if( locktype==EXCLUSIVE_LOCK && res ){
    newLocktype = PENDING_LOCK;
    gotPendingLock = 0;
  }

  /* Acquire an EXCLUSIVE lock
  */
  if( locktype==EXCLUSIVE_LOCK && res ){
    assert( pFile->locktype>=SHARED_LOCK );
    res = unlockReadLock(pFile);
    TRACE2("unreadlock = %d\n", res);
    res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
    if( res ){
      newLocktype = EXCLUSIVE_LOCK;
    }else{
      TRACE2("error-code = %d\n", GetLastError());
    }
  }

  /* If we are holding a PENDING lock that ought to be released, then
  ** release it now.
  */
  if( gotPendingLock && locktype==SHARED_LOCK ){
    UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
  }

  /* Update the state of the lock has held in the file descriptor then
  ** return the appropriate result code.
  */
  if( res ){
    rc = SQLITE_OK;
  }else{
    TRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
           locktype, newLocktype);
    rc = SQLITE_BUSY;
  }
  pFile->locktype = newLocktype;
  return rc;
}

/*
** This routine checks if there is a RESERVED lock held on the specified
** file by this or any other process. If such a lock is held, return
** non-zero, otherwise zero.
*/
static int winCheckReservedLock(OsFile *id){
  int rc;
  winFile *pFile = (winFile*)id;
  assert( pFile!=0 );
  if( pFile->locktype>=RESERVED_LOCK ){
    rc = 1;
    TRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
  }else{
    rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
    if( rc ){
      UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
    }
    rc = !rc;
    TRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
  }
  return rc;
}

/*
** Lower the locking level on file descriptor id to locktype.  locktype
** must be either NO_LOCK or SHARED_LOCK.
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
**
** It is not possible for this routine to fail if the second argument
** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
** might return SQLITE_IOERR;
*/
static int winUnlock(OsFile *id, int locktype){
  int type;
  int rc = SQLITE_OK;
  winFile *pFile = (winFile*)id;
  assert( pFile!=0 );
  assert( locktype<=SHARED_LOCK );
  TRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
          pFile->locktype, pFile->sharedLockByte);
  type = pFile->locktype;
  if( type>=EXCLUSIVE_LOCK ){
    UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
    if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
      /* This should never happen.  We should always be able to
      ** reacquire the read lock */
      rc = SQLITE_IOERR;
    }
  }
  if( type>=RESERVED_LOCK ){
    UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
  }
  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
    unlockReadLock(pFile);
  }
  if( type>=PENDING_LOCK ){
    UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
  }
  pFile->locktype = locktype;
  return rc;
}

/*
** Turn a relative pathname into a full pathname.  Return a pointer
** to the full pathname stored in space obtained from sqliteMalloc().
** The calling function is responsible for freeing this space once it
** is no longer needed.
*/
char *sqlite3WinFullPathname(const char *zRelative){
  char *zFull;
#if defined(__CYGWIN__)
  int nByte;
  nByte = strlen(zRelative) + MAX_PATH + 1001;
  zFull = sqliteMalloc( nByte );
  if( zFull==0 ) return 0;
  if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
#elif OS_WINCE
  /* WinCE has no concept of a relative pathname, or so I am told. */
  zFull = sqliteStrDup(zRelative);
#else
  char *zNotUsed;
  WCHAR *zWide;
  int nByte;
  zWide = utf8ToUnicode(zRelative);
  if( zWide ){
    WCHAR *zTemp, *zNotUsedW;
    nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1;
    zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
    if( zTemp==0 ) return 0;
    GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW);
    sqliteFree(zWide);
    zFull = unicodeToUtf8(zTemp);
    sqliteFree(zTemp);
  }else{
    nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
    zFull = sqliteMalloc( nByte*sizeof(zFull[0]) );
    if( zFull==0 ) return 0;
    GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
  }
#endif
  return zFull;
}

/*
** The fullSync option is meaningless on windows.   This is a no-op.
*/
static void winSetFullSync(OsFile *id, int v){
  return;
}

/*
** Return the underlying file handle for an OsFile
*/
static int winFileHandle(OsFile *id){
  return (int)((winFile*)id)->h;
}

/*
** Return an integer that indices the type of lock currently held
** by this handle.  (Used for testing and analysis only.)
*/
static int winLockState(OsFile *id){
  return ((winFile*)id)->locktype;
}

/*
** This vector defines all the methods that can operate on an OsFile
** for win32.
*/
static const IoMethod sqlite3WinIoMethod = {
  winClose,
  winOpenDirectory,
  winRead,
  winWrite,
  winSeek,
  winTruncate,
  winSync,
  winSetFullSync,
  winFileHandle,
  winFileSize,
  winLock,
  winUnlock,
  winLockState,
  winCheckReservedLock,
};

/*
** Allocate memory for an OsFile.  Initialize the new OsFile
** to the value given in pInit and return a pointer to the new
** OsFile.  If we run out of memory, close the file and return NULL.
*/
int allocateWinFile(winFile *pInit, OsFile **pId){
  winFile *pNew;
  pNew = sqliteMalloc( sizeof(*pNew) );
  if( pNew==0 ){
    CloseHandle(pInit->h);
#if OS_WINCE
    sqliteFree(pInit->zDeleteOnClose);
#endif
    *pId = 0;
    return SQLITE_NOMEM;
  }else{
    *pNew = *pInit;
    pNew->pMethod = &sqlite3WinIoMethod;
    *pId = (OsFile*)pNew;
    return SQLITE_OK;
  }
}


#endif /* SQLITE_OMIT_DISKIO */
/***************************************************************************
** Everything above deals with file I/O.  Everything that follows deals
** with other miscellanous aspects of the operating system interface
****************************************************************************/

/*
** Get information to seed the random number generator.  The seed
** is written into the buffer zBuf[256].  The calling function must
** supply a sufficiently large buffer.
*/
int sqlite3WinRandomSeed(char *zBuf){
  /* We have to initialize zBuf to prevent valgrind from reporting
  ** errors.  The reports issued by valgrind are incorrect - we would
  ** prefer that the randomness be increased by making use of the
  ** uninitialized space in zBuf - but valgrind errors tend to worry
  ** some users.  Rather than argue, it seems easier just to initialize
  ** the whole array and silence valgrind, even if that means less randomness
  ** in the random seed.
  **
  ** When testing, initializing zBuf[] to zero is all we do.  That means
  ** that we always use the same random number sequence.* This makes the
  ** tests repeatable.
  */
  memset(zBuf, 0, 256);
  GetSystemTime((LPSYSTEMTIME)zBuf);
  return SQLITE_OK;
}

/*
** Sleep for a little while.  Return the amount of time slept.
*/
int sqlite3WinSleep(int ms){
  Sleep(ms);
  return ms;
}

/*
** Static variables used for thread synchronization
*/
static int inMutex = 0;
#ifdef SQLITE_W32_THREADS
  static CRITICAL_SECTION cs;
#endif

/*
** The following pair of routine implement mutual exclusion for
** multi-threaded processes.  Only a single thread is allowed to
** executed code that is surrounded by EnterMutex() and LeaveMutex().
**
** SQLite uses only a single Mutex.  There is not much critical
** code and what little there is executes quickly and without blocking.
*/
void sqlite3WinEnterMutex(){
#ifdef SQLITE_W32_THREADS
  static int isInit = 0;
  while( !isInit ){
    static long lock = 0;
    if( InterlockedIncrement(&lock)==1 ){
      InitializeCriticalSection(&cs);
      isInit = 1;
    }else{
      Sleep(1);
    }
  }
  EnterCriticalSection(&cs);
#endif
  assert( !inMutex );
  inMutex = 1;
}
void sqlite3WinLeaveMutex(){
  assert( inMutex );
  inMutex = 0;
#ifdef SQLITE_W32_THREADS
  LeaveCriticalSection(&cs);
#endif
}

/*
** Return TRUE if we are currently within the mutex and FALSE if not.



*/





int sqlite3WinInMutex(){


  return inMutex;
}


/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3OsCurrentTime().  This is used for testing.
*/
#ifdef SQLITE_TEST
int sqlite3_current_time = 0;
#endif

/*
** Find the current time (in Universal Coordinated Time).  Write the
** current time and date as a Julian Day number into *prNow and
** return 0.  Return 1 if the time and date cannot be found.
*/
int sqlite3WinCurrentTime(double *prNow){
  FILETIME ft;
  /* FILETIME structure is a 64-bit value representing the number of 
     100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
  */
  double now;
#if OS_WINCE
  SYSTEMTIME time;
  GetSystemTime(&time);
  SystemTimeToFileTime(&time,&ft);
#else
  GetSystemTimeAsFileTime( &ft );
#endif
  now = ((double)ft.dwHighDateTime) * 4294967296.0; 
  *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
#ifdef SQLITE_TEST
  if( sqlite3_current_time ){
    *prNow = sqlite3_current_time/86400.0 + 2440587.5;
  }
#endif
  return 0;
}

/*
** Remember the number of thread-specific-data blocks allocated.
** Use this to verify that we are not leaking thread-specific-data.




** Ticket #1601



*/




#ifdef SQLITE_TEST
int sqlite3_tsd_count = 0;
# define TSD_COUNTER_INCR InterlockedIncrement(&sqlite3_tsd_count)
# define TSD_COUNTER_DECR InterlockedDecrement(&sqlite3_tsd_count)
#else
# define TSD_COUNTER_INCR  /* no-op */
# define TSD_COUNTER_DECR  /* no-op */
#endif




/*
** If called with allocateFlag>1, then return a pointer to thread
** specific data for the current thread.  Allocate and zero the
** thread-specific data if it does not already exist necessary.
**
** If called with allocateFlag==0, then check the current thread
** specific data.  Return it if it exists.  If it does not exist,
** then return NULL.
**
** If called with allocateFlag<0, check to see if the thread specific
** data is allocated and is all zero.  If it is then deallocate it.
** Return a pointer to the thread specific data or NULL if it is
** unallocated or gets deallocated.
*/
ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){
  static int key;
  static int keyInit = 0;
  static const ThreadData zeroData;
  ThreadData *pTsd;

  if( !keyInit ){
    sqlite3OsEnterMutex();
    if( !keyInit ){
      key = TlsAlloc();
      if( key==0xffffffff ){
        sqlite3OsLeaveMutex();
        return 0;
      }
      keyInit = 1;
    }
    sqlite3OsLeaveMutex();
  }
  pTsd = TlsGetValue(key);
  if( allocateFlag>0 ){
    if( !pTsd ){
      pTsd = sqlite3OsMalloc( sizeof(zeroData) );
      if( pTsd ){
        *pTsd = zeroData;
        TlsSetValue(key, pTsd);
        TSD_COUNTER_INCR;
      }
    }
  }else if( pTsd!=0 && allocateFlag<0 
              && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
    sqlite3OsFree(pTsd);
    TlsSetValue(key, 0);
    TSD_COUNTER_DECR;
    pTsd = 0;
  }
  return pTsd;
}
#endif /* OS_WIN */







|




|




<

|

|





|





|

|





|
|
|


|












|
|








|
|















|
|

|











|








|



|








|

<
|
|

|

|

|


|















|


<
|

|
|
|

|
|






|


|


|

|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|




















|




















|
















|








|
>
>
>

>
>
>
>
>
|
>
>
|

<














|





<
<
<
<
<

<











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

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624


















































































































625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711

712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731





732

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759



760



761
762
763
764



















765































766
**
**    UNLOCKED -> SHARED
**    SHARED -> RESERVED
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** This routine will only increase a lock.  The sqlite3OsUnlock() routine
** erases all locks at once and returns us immediately to locking level 0.
** It is not possible to lower the locking level one step at a time.  You
** must go straight to locking level 0.
*/
int sqlite3OsLock(OsFile *id, int locktype){
  int rc = SQLITE_OK;    /* Return code from subroutines */
  int res = 1;           /* Result of a windows lock call */
  int newLocktype;       /* Set id->locktype to this value before exiting */
  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */


  assert( id->isOpen );
  TRACE5("LOCK %d %d was %d(%d)\n",
          id->h, locktype, id->locktype, id->sharedLockByte);

  /* If there is already a lock of this type or more restrictive on the
  ** OsFile, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3OsEnterMutex() hasn't been called yet.
  */
  if( id->locktype>=locktype ){
    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
  assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );

  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
  ** the PENDING_LOCK byte is temporary.
  */
  newLocktype = id->locktype;
  if( id->locktype==NO_LOCK
   || (locktype==EXCLUSIVE_LOCK && id->locktype==RESERVED_LOCK)
  ){
    int cnt = 3;
    while( cnt-->0 && (res = LockFile(id->h, PENDING_BYTE, 0, 1, 0))==0 ){
      /* Try 3 times to get the pending lock.  The pending lock might be
      ** held by another reader process who will release it momentarily.
      */
      TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
      Sleep(1);
    }
    gotPendingLock = res;
  }

  /* Acquire a shared lock
  */
  if( locktype==SHARED_LOCK && res ){
    assert( id->locktype==NO_LOCK );
    res = getReadLock(id);
    if( res ){
      newLocktype = SHARED_LOCK;
    }
  }

  /* Acquire a RESERVED lock
  */
  if( locktype==RESERVED_LOCK && res ){
    assert( id->locktype==SHARED_LOCK );
    res = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
    if( res ){
      newLocktype = RESERVED_LOCK;
    }
  }

  /* Acquire a PENDING lock
  */
  if( locktype==EXCLUSIVE_LOCK && res ){
    newLocktype = PENDING_LOCK;
    gotPendingLock = 0;
  }

  /* Acquire an EXCLUSIVE lock
  */
  if( locktype==EXCLUSIVE_LOCK && res ){
    assert( id->locktype>=SHARED_LOCK );
    res = unlockReadLock(id);
    TRACE2("unreadlock = %d\n", res);
    res = LockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
    if( res ){
      newLocktype = EXCLUSIVE_LOCK;
    }else{
      TRACE2("error-code = %d\n", GetLastError());
    }
  }

  /* If we are holding a PENDING lock that ought to be released, then
  ** release it now.
  */
  if( gotPendingLock && locktype==SHARED_LOCK ){
    UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
  }

  /* Update the state of the lock has held in the file descriptor then
  ** return the appropriate result code.
  */
  if( res ){
    rc = SQLITE_OK;
  }else{
    TRACE4("LOCK FAILED %d trying for %d but got %d\n", id->h,
           locktype, newLocktype);
    rc = SQLITE_BUSY;
  }
  id->locktype = newLocktype;
  return rc;
}

/*
** This routine checks if there is a RESERVED lock held on the specified
** file by this or any other process. If such a lock is held, return
** non-zero, otherwise zero.
*/
int sqlite3OsCheckReservedLock(OsFile *id){
  int rc;

  assert( id->isOpen );
  if( id->locktype>=RESERVED_LOCK ){
    rc = 1;
    TRACE3("TEST WR-LOCK %d %d (local)\n", id->h, rc);
  }else{
    rc = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
    if( rc ){
      UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
    }
    rc = !rc;
    TRACE3("TEST WR-LOCK %d %d (remote)\n", id->h, rc);
  }
  return rc;
}

/*
** Lower the locking level on file descriptor id to locktype.  locktype
** must be either NO_LOCK or SHARED_LOCK.
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
**
** It is not possible for this routine to fail if the second argument
** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
** might return SQLITE_IOERR;
*/
int sqlite3OsUnlock(OsFile *id, int locktype){
  int type;
  int rc = SQLITE_OK;

  assert( id->isOpen );
  assert( locktype<=SHARED_LOCK );
  TRACE5("UNLOCK %d to %d was %d(%d)\n", id->h, locktype,
          id->locktype, id->sharedLockByte);
  type = id->locktype;
  if( type>=EXCLUSIVE_LOCK ){
    UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
    if( locktype==SHARED_LOCK && !getReadLock(id) ){
      /* This should never happen.  We should always be able to
      ** reacquire the read lock */
      rc = SQLITE_IOERR;
    }
  }
  if( type>=RESERVED_LOCK ){
    UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
  }
  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
    unlockReadLock(id);
  }
  if( type>=PENDING_LOCK ){
    UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
  }
  id->locktype = locktype;
  return rc;
}

/*


















































































































** Get information to seed the random number generator.  The seed
** is written into the buffer zBuf[256].  The calling function must
** supply a sufficiently large buffer.
*/
int sqlite3OsRandomSeed(char *zBuf){
  /* We have to initialize zBuf to prevent valgrind from reporting
  ** errors.  The reports issued by valgrind are incorrect - we would
  ** prefer that the randomness be increased by making use of the
  ** uninitialized space in zBuf - but valgrind errors tend to worry
  ** some users.  Rather than argue, it seems easier just to initialize
  ** the whole array and silence valgrind, even if that means less randomness
  ** in the random seed.
  **
  ** When testing, initializing zBuf[] to zero is all we do.  That means
  ** that we always use the same random number sequence.* This makes the
  ** tests repeatable.
  */
  memset(zBuf, 0, 256);
  GetSystemTime((LPSYSTEMTIME)zBuf);
  return SQLITE_OK;
}

/*
** Sleep for a little while.  Return the amount of time slept.
*/
int sqlite3OsSleep(int ms){
  Sleep(ms);
  return ms;
}

/*
** Static variables used for thread synchronization
*/
static int inMutex = 0;
#ifdef SQLITE_W32_THREADS
  static CRITICAL_SECTION cs;
#endif

/*
** The following pair of routine implement mutual exclusion for
** multi-threaded processes.  Only a single thread is allowed to
** executed code that is surrounded by EnterMutex() and LeaveMutex().
**
** SQLite uses only a single Mutex.  There is not much critical
** code and what little there is executes quickly and without blocking.
*/
void sqlite3OsEnterMutex(){
#ifdef SQLITE_W32_THREADS
  static int isInit = 0;
  while( !isInit ){
    static long lock = 0;
    if( InterlockedIncrement(&lock)==1 ){
      InitializeCriticalSection(&cs);
      isInit = 1;
    }else{
      Sleep(1);
    }
  }
  EnterCriticalSection(&cs);
#endif
  assert( !inMutex );
  inMutex = 1;
}
void sqlite3OsLeaveMutex(){
  assert( inMutex );
  inMutex = 0;
#ifdef SQLITE_W32_THREADS
  LeaveCriticalSection(&cs);
#endif
}

/*
** Turn a relative pathname into a full pathname.  Return a pointer
** to the full pathname stored in space obtained from sqliteMalloc().
** The calling function is responsible for freeing this space once it
** is no longer needed.
*/
char *sqlite3OsFullPathname(const char *zRelative){
  char *zNotUsed;
  char *zFull;
  int nByte;
  nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
  zFull = sqliteMalloc( nByte );
  if( zFull==0 ) return 0;
  GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
  return zFull;
}


/*
** The following variable, if set to a non-zero value, becomes the result
** returned from sqlite3OsCurrentTime().  This is used for testing.
*/
#ifdef SQLITE_TEST
int sqlite3_current_time = 0;
#endif

/*
** Find the current time (in Universal Coordinated Time).  Write the
** current time and date as a Julian Day number into *prNow and
** return 0.  Return 1 if the time and date cannot be found.
*/
int sqlite3OsCurrentTime(double *prNow){
  FILETIME ft;
  /* FILETIME structure is a 64-bit value representing the number of 
     100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
  */
  double now;





  GetSystemTimeAsFileTime( &ft );

  now = ((double)ft.dwHighDateTime) * 4294967296.0; 
  *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
#ifdef SQLITE_TEST
  if( sqlite3_current_time ){
    *prNow = sqlite3_current_time/86400.0 + 2440587.5;
  }
#endif
  return 0;
}

/*
** Find the time that the file was last modified.  Write the
** modification time and date as a Julian Day number into *prNow and
** return SQLITE_OK.  Return SQLITE_ERROR if the modification
** time cannot be found.
*/
int sqlite3OsFileModTime(OsFile *id, double *prMTime){
  int rc;
  FILETIME ft;
  /* FILETIME structure is a 64-bit value representing the number of 
  ** 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
  */
  if( GetFileTime(id->h, 0, 0, &ft) ){
    double t;
    t = ((double)ft.dwHighDateTime) * 4294967296.0; 
    *prMTime = (t + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
    rc = SQLITE_OK;



  }else{



    rc = SQLITE_ERROR;
  }
  return rc;
}



















































#endif /* OS_WIN */
Added SQLite.Interop/src/os_win.h.
















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
** 2004 May 22
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This header file defines OS-specific features for Win32
*/
#ifndef _SQLITE_OS_WIN_H_
#define _SQLITE_OS_WIN_H_

#include <windows.h>
#include <winbase.h>

/*
** The OsFile structure is a operating-system independing representation
** of an open file handle.  It is defined differently for each architecture.
**
** This is the definition for Win32.
*/
typedef struct OsFile OsFile;
struct OsFile {
  HANDLE h;               /* Handle for accessing the file */
  unsigned char locktype; /* Type of lock currently held on this file */
  unsigned char isOpen;   /* True if needs to be closed */
  short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
};


#define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
#define SQLITE_MIN_SLEEP_MS 1


#endif /* _SQLITE_OS_WIN_H_ */
Changes to SQLite.Interop/src/pager.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.17 2006/01/16 15:51:47 rmsimpson Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>

/*







|

<







14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.1 2005/03/01 16:04:31 rmsimpson Exp $
*/

#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>

/*
42
43
44
45
46
47
48
49


50
51
52
53
54




55
56

57
58
59
60
61
62
63
#define TRACE3(X,Y,Z)
#define TRACE4(X,Y,Z,W)
#define TRACE5(X,Y,Z,W,V)
#endif

/*
** The following two macros are used within the TRACEX() macros above
** to print out file-descriptors. 


**
** PAGERID() takes a pointer to a Pager struct as it's argument. The
** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile
** struct as it's argument.
*/




#define PAGERID(p) FILEHANDLEID(&(p)->fd)
#define FILEHANDLEID(fd) (sqlite3OsFileHandle(&fd))


/*
** The page cache as a whole is always in one of the following
** states:
**
**   PAGER_UNLOCK        The page cache is not currently reading or 
**                       writing the database file.  There is no







|
>
>





>
>
>
>
|
|
>







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#define TRACE3(X,Y,Z)
#define TRACE4(X,Y,Z,W)
#define TRACE5(X,Y,Z,W,V)
#endif

/*
** The following two macros are used within the TRACEX() macros above
** to print out file-descriptors. They are required so that tracing
** can be turned on when using both the regular os_unix.c and os_test.c
** backends.
**
** PAGERID() takes a pointer to a Pager struct as it's argument. The
** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile
** struct as it's argument.
*/
#ifdef OS_TEST
#define PAGERID(p) (p->fd->fd.h)
#define FILEHANDLEID(fd) (fd->fd.h)
#else
#define PAGERID(p) (p->fd.h)
#define FILEHANDLEID(fd) (fd.h)
#endif

/*
** The page cache as a whole is always in one of the following
** states:
**
**   PAGER_UNLOCK        The page cache is not currently reading or 
**                       writing the database file.  There is no
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  u8 needSync;                   /* Sync journal before writing this page */
  u8 alwaysRollback;             /* Disable dont_rollback() for this page */
  short int nRef;                /* Number of users of this page */
  PgHdr *pDirty;                 /* Dirty pages sorted by PgHdr.pgno */
#ifdef SQLITE_CHECK_PAGES
  u32 pageHash;
#endif
  /* pPager->pageSize bytes of page data follow this header */
  /* Pager.nExtra bytes of local data follow the page data */
};

/*
** For an in-memory only database, some extra information is recorded about
** each page so that changes can be rolled back.  (Journal files are not
** used for in-memory databases.)  The following information is added to







|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  u8 needSync;                   /* Sync journal before writing this page */
  u8 alwaysRollback;             /* Disable dont_rollback() for this page */
  short int nRef;                /* Number of users of this page */
  PgHdr *pDirty;                 /* Dirty pages sorted by PgHdr.pgno */
#ifdef SQLITE_CHECK_PAGES
  u32 pageHash;
#endif
  /* pPager->psAligned bytes of page data follow this header */
  /* Pager.nExtra bytes of local data follow the page data */
};

/*
** For an in-memory only database, some extra information is recorded about
** each page so that changes can be rolled back.  (Journal files are not
** used for in-memory databases.)  The following information is added to
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
























238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315

/*
** Convert a pointer to a PgHdr into a pointer to its data
** and back again.
*/
#define PGHDR_TO_DATA(P)  ((void*)(&(P)[1]))
#define DATA_TO_PGHDR(D)  (&((PgHdr*)(D))[-1])
#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->pageSize])
#define PGHDR_TO_HIST(P,PGR)  \
            ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra])

/*
** How big to make the hash table used for locating in-memory pages
** by page number. This macro looks a little silly, but is evaluated
** at compile-time, not run-time (at least for gcc this is true).
*/
#define N_PG_HASH (\
  (MAX_PAGES>1024)?2048: \
  (MAX_PAGES>512)?1024: \
  (MAX_PAGES>256)?512: \
  (MAX_PAGES>128)?256: \
  (MAX_PAGES>64)?128:64 \
)

/*
** Hash a page number
*/
#define pager_hash(PN)  ((PN)&(N_PG_HASH-1))

/*
** A open page cache is an instance of the following structure.
**
** Pager.errCode may be set to SQLITE_IOERR, SQLITE_CORRUPT, SQLITE_PROTOCOL
** or SQLITE_FULL. Once one of the first three errors occurs, it persists
** and is returned as the result of every major pager API call.  The
** SQLITE_FULL return code is slightly different. It persists only until the
** next successful rollback is performed on the pager cache. Also,
** SQLITE_FULL does not affect the sqlite3pager_get() and sqlite3pager_lookup()
** APIs, they may still be used successfully.
*/
struct Pager {
























  u8 journalOpen;             /* True if journal file descriptors is valid */
  u8 journalStarted;          /* True if header of journal is synced */
  u8 useJournal;              /* Use a rollback journal on this file */
  u8 noReadlock;              /* Do not bother to obtain readlocks */
  u8 stmtOpen;                /* True if the statement subjournal is open */
  u8 stmtInUse;               /* True we are in a statement subtransaction */
  u8 stmtAutoopen;            /* Open stmt journal when main journal is opened*/
  u8 noSync;                  /* Do not sync the journal if true */
  u8 fullSync;                /* Do extra syncs of the journal for robustness */
  u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
  u8 errCode;                 /* One of several kinds of errors */
  u8 tempFile;                /* zFilename is a temporary file */
  u8 readOnly;                /* True for a read-only database */
  u8 needSync;                /* True if an fsync() is needed on the journal */
  u8 dirtyCache;              /* True if cached pages have changed */
  u8 alwaysRollback;          /* Disable dont_rollback() for all pages */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  int dbSize;                 /* Number of pages in the file */
  int origDbSize;             /* dbSize before the current change */
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
  u32 cksumInit;              /* Quasi-random value added to every checksum */
  int stmtNRec;               /* Number of records in stmt subjournal */
  int nExtra;                 /* Add this many bytes to each in-memory page */
  int pageSize;               /* Number of bytes in a page */
  int nPage;                  /* Total number of in-memory pages */
  int nMaxPage;               /* High water mark of nPage */
  int nRef;                   /* Number of in-memory pages with PgHdr.nRef>0 */
  int mxPage;                 /* Maximum number of pages to hold in cache */
  u8 *aInJournal;             /* One bit for each page in the database file */
  u8 *aInStmt;                /* One bit for each page in the database */
  char *zFilename;            /* Name of the database file */
  char *zJournal;             /* Name of the journal file */
  char *zDirectory;           /* Directory hold database and journal files */
  OsFile *fd, *jfd;           /* File descriptors for database and journal */
  OsFile *stfd;               /* File descriptor for the statement subjournal*/
  BusyHandler *pBusyHandler;  /* Pointer to sqlite.busyHandler */
  PgHdr *pFirst, *pLast;      /* List of free pages */
  PgHdr *pFirstSynced;        /* First free page with PgHdr.needSync==0 */
  PgHdr *pAll;                /* List of all pages */
  PgHdr *pStmt;               /* List of pages in the statement subjournal */
  i64 journalOff;             /* Current byte offset in the journal file */
  i64 journalHdr;             /* Byte offset to previous journal header */
  i64 stmtHdrOff;             /* First journal header written this statement */
  i64 stmtCksum;              /* cksumInit when statement was started */
  i64 stmtJSize;              /* Size of journal at stmt_begin() */
  int sectorSize;             /* Assumed sector size during rollback */
#ifdef SQLITE_TEST
  int nHit, nMiss, nOvfl;     /* Cache hits, missing, and LRU overflows */
  int nRead,nWrite;           /* Database pages read/written */
#endif
  void (*xDestructor)(void*,int); /* Call this routine when freeing pages */
  void (*xReiniter)(void*,int);   /* Call this routine when reloading pages */
  void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
  void *pCodecArg;            /* First argument to xCodec() */
  PgHdr *aHash[N_PG_HASH];    /* Hash table to map page number to PgHdr */
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  Pager *pNext;               /* Linked list of pagers in this thread */
#endif
};

/*
** If SQLITE_TEST is defined then increment the variable given in
** the argument
*/

#ifdef SQLITE_TEST
# define TEST_INCR(x)  x++
#else
# define TEST_INCR(x)
#endif

/*
** Journal files begin with the following magic string.  The data
** was obtained from /dev/random.  It is used only as a sanity check.
**
** Since version 2.8.0, the journal format contains additional sanity
** checking information.  If the power fails while the journal is begin







|

|



|
<

|
<
<
<
<
<
<








<
<
<
<
<
<
<
<


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










|






<
<
<
<
<
<
<
<
<
<
<
<
<


<
<
<
<
|









<

<
<
<
<
<
<
<
<

<
<
<



|
<

>
|
|
|
|
<







203
204
205
206
207
208
209
210
211
212
213
214
215
216

217
218






219
220
221
222
223
224
225
226








227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269













270
271




272
273
274
275
276
277
278
279
280
281

282








283



284
285
286
287

288
289
290
291
292
293

294
295
296
297
298
299
300

/*
** Convert a pointer to a PgHdr into a pointer to its data
** and back again.
*/
#define PGHDR_TO_DATA(P)  ((void*)(&(P)[1]))
#define DATA_TO_PGHDR(D)  (&((PgHdr*)(D))[-1])
#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->psAligned])
#define PGHDR_TO_HIST(P,PGR)  \
            ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->psAligned+(PGR)->nExtra])

/*
** How big to make the hash table used for locating in-memory pages
** by page number.

*/
#define N_PG_HASH 2048







/*
** Hash a page number
*/
#define pager_hash(PN)  ((PN)&(N_PG_HASH-1))

/*
** A open page cache is an instance of the following structure.








*/
struct Pager {
  char *zFilename;            /* Name of the database file */
  char *zJournal;             /* Name of the journal file */
  char *zDirectory;           /* Directory hold database and journal files */
  OsFile fd, jfd;             /* File descriptors for database and journal */
  OsFile stfd;                /* File descriptor for the statement subjournal*/
  int dbSize;                 /* Number of pages in the file */
  int origDbSize;             /* dbSize before the current change */
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
  i64 stmtJSize;              /* Size of journal at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
  u32 cksumInit;              /* Quasi-random value added to every checksum */
  int stmtNRec;               /* Number of records in stmt subjournal */
  int nExtra;                 /* Add this many bytes to each in-memory page */
  void (*xDestructor)(void*,int); /* Call this routine when freeing pages */
  void (*xReiniter)(void*,int);   /* Call this routine when reloading pages */
  int pageSize;               /* Number of bytes in a page */
  int psAligned;              /* pageSize rounded up to a multiple of 8 */
  int nPage;                  /* Total number of in-memory pages */
  int nRef;                   /* Number of in-memory pages with PgHdr.nRef>0 */
  int mxPage;                 /* Maximum number of pages to hold in cache */
  int nHit, nMiss, nOvfl;     /* Cache hits, missing, and LRU overflows */
  int nRead,nWrite;           /* Database pages read/written */
  void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
  void *pCodecArg;            /* First argument to xCodec() */
  u8 journalOpen;             /* True if journal file descriptors is valid */
  u8 journalStarted;          /* True if header of journal is synced */
  u8 useJournal;              /* Use a rollback journal on this file */
  u8 noReadlock;              /* Do not bother to obtain readlocks */
  u8 stmtOpen;                /* True if the statement subjournal is open */
  u8 stmtInUse;               /* True we are in a statement subtransaction */
  u8 stmtAutoopen;            /* Open stmt journal when main journal is opened*/
  u8 noSync;                  /* Do not sync the journal if true */
  u8 fullSync;                /* Do extra syncs of the journal for robustness */
  u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
  u8 errMask;                 /* One of several kinds of errors */
  u8 tempFile;                /* zFilename is a temporary file */
  u8 readOnly;                /* True for a read-only database */
  u8 needSync;                /* True if an fsync() is needed on the journal */
  u8 dirtyCache;              /* True if cached pages have changed */
  u8 alwaysRollback;          /* Disable dont_rollback() for all pages */
  u8 memDb;                   /* True to inhibit all file I/O */













  u8 *aInJournal;             /* One bit for each page in the database file */
  u8 *aInStmt;                /* One bit for each page in the database */




  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  BusyHandler *pBusyHandler;  /* Pointer to sqlite.busyHandler */
  PgHdr *pFirst, *pLast;      /* List of free pages */
  PgHdr *pFirstSynced;        /* First free page with PgHdr.needSync==0 */
  PgHdr *pAll;                /* List of all pages */
  PgHdr *pStmt;               /* List of pages in the statement subjournal */
  i64 journalOff;             /* Current byte offset in the journal file */
  i64 journalHdr;             /* Byte offset to previous journal header */
  i64 stmtHdrOff;             /* First journal header written this statement */
  i64 stmtCksum;              /* cksumInit when statement was started */

  int sectorSize;             /* Assumed sector size during rollback */








  PgHdr *aHash[N_PG_HASH];    /* Hash table to map page number to PgHdr */



};

/*
** These are bits that can be set in Pager.errMask.

*/
#define PAGER_ERR_FULL     0x01  /* a write() failed */
#define PAGER_ERR_MEM      0x02  /* malloc() failed */
#define PAGER_ERR_LOCK     0x04  /* error in the locking protocol */
#define PAGER_ERR_CORRUPT  0x08  /* database or journal corruption */
#define PAGER_ERR_DISK     0x10  /* general disk I/O error - bad hard drive? */


/*
** Journal files begin with the following magic string.  The data
** was obtained from /dev/random.  It is used only as a sanity check.
**
** Since version 2.8.0, the journal format contains additional sanity
** checking information.  If the power fails while the journal is begin
402
403
404
405
406
407
408
409

410
411


412
413

414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432



433
434
435
436
437
438
439
440
441
442
443



444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479
480
481
482
483
484
** Read a 32-bit integer from the given file descriptor.  Store the integer
** that is read in *pRes.  Return SQLITE_OK if everything worked, or an
** error code is something goes wrong.
**
** All values are stored on disk as big-endian.
*/
static int read32bits(OsFile *fd, u32 *pRes){
  unsigned char ac[4];

  int rc = sqlite3OsRead(fd, ac, sizeof(ac));
  if( rc==SQLITE_OK ){


    *pRes = (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
  }

  return rc;
}

/*
** Write a 32-bit integer into a string buffer in big-endian byte order.
*/
static void put32bits(char *ac, u32 val){
  ac[0] = (val>>24) & 0xff;
  ac[1] = (val>>16) & 0xff;
  ac[2] = (val>>8) & 0xff;
  ac[3] = val & 0xff;
}

/*
** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
** on success or an error code is something goes wrong.
*/
static int write32bits(OsFile *fd, u32 val){
  unsigned char ac[4];



  put32bits(ac, val);
  return sqlite3OsWrite(fd, ac, 4);
}

/*
** Write the 32-bit integer 'val' into the page identified by page header
** 'p' at offset 'offset'.
*/
static void store32bits(u32 val, PgHdr *p, int offset){
  unsigned char *ac;
  ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];



  put32bits(ac, val);
}

/*
** Read a 32-bit integer at offset 'offset' from the page identified by
** page header 'p'.
*/
static u32 retrieve32bits(PgHdr *p, int offset){
  unsigned char *ac;
  ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
  return (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
}


/*
** This function should be called when an error occurs within the pager
** code. The first argument is a pointer to the pager structure, the
** second the error-code about to be returned by a pager API function. 
** The value returned is a copy of the second argument to this function. 
**
** If the second argument is SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_PROTOCOL,
** the error becomes persistent. All subsequent API calls on this Pager
** will immediately return the same error code.
*/
static int pager_error(Pager *pPager, int rc){
  assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK );
  if( 
    rc==SQLITE_FULL || 

    rc==SQLITE_IOERR || 
    rc==SQLITE_CORRUPT ||
    rc==SQLITE_PROTOCOL
  ){
    pPager->errCode = rc;
  }
  return rc;
}

#ifdef SQLITE_CHECK_PAGES
/*
** Return a 32-bit hash of the page data for pPage.
*/







|
>
|

>
>
|

>

<
<
<
<
<
<
<
<
<
<








>
>
>
|










>
>
>
|














|
<
<
<
<
<
<
|

|
<
<
|
>
|
|
|
<
|
<







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403










404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444






445
446
447


448
449
450
451
452

453

454
455
456
457
458
459
460
** Read a 32-bit integer from the given file descriptor.  Store the integer
** that is read in *pRes.  Return SQLITE_OK if everything worked, or an
** error code is something goes wrong.
**
** All values are stored on disk as big-endian.
*/
static int read32bits(OsFile *fd, u32 *pRes){
  u32 res;
  int rc;
  rc = sqlite3OsRead(fd, &res, sizeof(res));
  if( rc==SQLITE_OK ){
    unsigned char ac[4];
    memcpy(ac, &res, 4);
    res = (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
  }
  *pRes = res;
  return rc;










}

/*
** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
** on success or an error code is something goes wrong.
*/
static int write32bits(OsFile *fd, u32 val){
  unsigned char ac[4];
  ac[0] = (val>>24) & 0xff;
  ac[1] = (val>>16) & 0xff;
  ac[2] = (val>>8) & 0xff;
  ac[3] = val & 0xff;
  return sqlite3OsWrite(fd, ac, 4);
}

/*
** Write the 32-bit integer 'val' into the page identified by page header
** 'p' at offset 'offset'.
*/
static void store32bits(u32 val, PgHdr *p, int offset){
  unsigned char *ac;
  ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
  ac[0] = (val>>24) & 0xff;
  ac[1] = (val>>16) & 0xff;
  ac[2] = (val>>8) & 0xff;
  ac[3] = val & 0xff;
}

/*
** Read a 32-bit integer at offset 'offset' from the page identified by
** page header 'p'.
*/
static u32 retrieve32bits(PgHdr *p, int offset){
  unsigned char *ac;
  ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
  return (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
}


/*
** Convert the bits in the pPager->errMask into an approprate






** return code.
*/
static int pager_errcode(Pager *pPager){


  int rc = SQLITE_OK;
  if( pPager->errMask & PAGER_ERR_LOCK )    rc = SQLITE_PROTOCOL;
  if( pPager->errMask & PAGER_ERR_DISK )    rc = SQLITE_IOERR;
  if( pPager->errMask & PAGER_ERR_FULL )    rc = SQLITE_FULL;
  if( pPager->errMask & PAGER_ERR_MEM )     rc = SQLITE_NOMEM;

  if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = SQLITE_CORRUPT;

  return rc;
}

#ifdef SQLITE_CHECK_PAGES
/*
** Return a 32-bit hash of the page data for pPage.
*/
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
** is defined, and NDEBUG is not defined, an assert() statement checks
** that the page is either dirty or still matches the calculated page-hash.
*/
#define CHECK_PAGE(x) checkPage(x)
static void checkPage(PgHdr *pPg){
  Pager *pPager = pPg->pPager;
  assert( !pPg->pageHash || pPager->errCode || MEMDB || pPg->dirty || 
      pPg->pageHash==pager_pagehash(pPg) );
}

#else
#define CHECK_PAGE(x)
#endif








|







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
** is defined, and NDEBUG is not defined, an assert() statement checks
** that the page is either dirty or still matches the calculated page-hash.
*/
#define CHECK_PAGE(x) checkPage(x)
static void checkPage(PgHdr *pPg){
  Pager *pPager = pPg->pPager;
  assert( !pPg->pageHash || pPager->errMask || MEMDB || pPg->dirty || 
      pPg->pageHash==pager_pagehash(pPg) );
}

#else
#define CHECK_PAGE(x)
#endif

597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641


642
643


644
645
646


647
648


649
650
651

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
  if( c ){
    offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
  }
  assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
  assert( offset>=c );
  assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
  pPager->journalOff = offset;
  return sqlite3OsSeek(pPager->jfd, pPager->journalOff);
}

/*
** The journal file must be open when this routine is called. A journal
** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
** current location.
**
** The format for the journal header is as follows:
** - 8 bytes: Magic identifying journal format.
** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
** - 4 bytes: Random number used for page hash.
** - 4 bytes: Initial database page count.
** - 4 bytes: Sector size used by the process that wrote this journal.
** 
** Followed by (JOURNAL_HDR_SZ - 24) bytes of unused space.
*/
static int writeJournalHdr(Pager *pPager){
  char zHeader[sizeof(aJournalMagic)+16];

  int rc = seekJournalHdr(pPager);
  if( rc ) return rc;

  pPager->journalHdr = pPager->journalOff;
  if( pPager->stmtHdrOff==0 ){
    pPager->stmtHdrOff = pPager->journalHdr;
  }
  pPager->journalOff += JOURNAL_HDR_SZ(pPager);

  /* FIX ME: 
  **
  ** Possibly for a pager not in no-sync mode, the journal magic should not
  ** be written until nRec is filled in as part of next syncJournal(). 
  **
  ** Actually maybe the whole journal header should be delayed until that
  ** point. Think about this.
  */
  memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));


  /* The nRec Field. 0xFFFFFFFF for no-sync journals. */
  put32bits(&zHeader[sizeof(aJournalMagic)], pPager->noSync ? 0xffffffff : 0);


  /* The random check-hash initialiser */ 
  sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
  put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);


  /* The initial database size */
  put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbSize);


  /* The assumed sector size for this process */
  put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
  rc = sqlite3OsWrite(pPager->jfd, zHeader, sizeof(zHeader));


  /* The journal header has been written successfully. Seek the journal
  ** file descriptor to the end of the journal header sector.
  */
  if( rc==SQLITE_OK ){
    rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff-1);
    if( rc==SQLITE_OK ){
      rc = sqlite3OsWrite(pPager->jfd, "\000", 1);
    }
  }
  return rc;
}

/*
** The journal file must be open when this is called. A journal header file
** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal







|

















<


















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





|
<
|
<







573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633

634
635
636
637
638
639
640

641

642
643
644
645
646
647
648
  if( c ){
    offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
  }
  assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
  assert( offset>=c );
  assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
  pPager->journalOff = offset;
  return sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
}

/*
** The journal file must be open when this routine is called. A journal
** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
** current location.
**
** The format for the journal header is as follows:
** - 8 bytes: Magic identifying journal format.
** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
** - 4 bytes: Random number used for page hash.
** - 4 bytes: Initial database page count.
** - 4 bytes: Sector size used by the process that wrote this journal.
** 
** Followed by (JOURNAL_HDR_SZ - 24) bytes of unused space.
*/
static int writeJournalHdr(Pager *pPager){


  int rc = seekJournalHdr(pPager);
  if( rc ) return rc;

  pPager->journalHdr = pPager->journalOff;
  if( pPager->stmtHdrOff==0 ){
    pPager->stmtHdrOff = pPager->journalHdr;
  }
  pPager->journalOff += JOURNAL_HDR_SZ(pPager);

  /* FIX ME: 
  **
  ** Possibly for a pager not in no-sync mode, the journal magic should not
  ** be written until nRec is filled in as part of next syncJournal(). 
  **
  ** Actually maybe the whole journal header should be delayed until that
  ** point. Think about this.
  */
  rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));

  if( rc==SQLITE_OK ){
    /* The nRec Field. 0xFFFFFFFF for no-sync journals. */
    rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0);
  }
  if( rc==SQLITE_OK ){
    /* The random check-hash initialiser */ 
    sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
    rc = write32bits(&pPager->jfd, pPager->cksumInit);
  }
  if( rc==SQLITE_OK ){
    /* The initial database size */
    rc = write32bits(&pPager->jfd, pPager->dbSize);
  }
  if( rc==SQLITE_OK ){
    /* The assumed sector size for this process */
    rc = write32bits(&pPager->jfd, pPager->sectorSize);

  }

  /* The journal header has been written successfully. Seek the journal
  ** file descriptor to the end of the journal header sector.
  */
  if( rc==SQLITE_OK ){
    sqlite3OsSeek(&pPager->jfd, pPager->journalOff-1);

    rc = sqlite3OsWrite(&pPager->jfd, "\000", 1);

  }
  return rc;
}

/*
** The journal file must be open when this is called. A journal header file
** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777


778


779
780
781
782
783
784
785
786
787
788
789
  rc = seekJournalHdr(pPager);
  if( rc ) return rc;

  if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
    return SQLITE_DONE;
  }

  rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic));
  if( rc ) return rc;

  if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
    return SQLITE_DONE;
  }

  rc = read32bits(pPager->jfd, pNRec);
  if( rc ) return rc;

  rc = read32bits(pPager->jfd, &pPager->cksumInit);
  if( rc ) return rc;

  rc = read32bits(pPager->jfd, pDbSize);
  if( rc ) return rc;

  /* Update the assumed sector-size to match the value used by 
  ** the process that created this journal. If this journal was
  ** created by a process other than this one, then this routine
  ** is being called from within pager_playback(). The local value
  ** of Pager.sectorSize is restored at the end of that routine.
  */
  rc = read32bits(pPager->jfd, (u32 *)&pPager->sectorSize);
  if( rc ) return rc;

  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
  rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff);
  return rc;
}


/*
** Write the supplied master journal name into the journal file for pager
** pPager at the current location. The master journal name must be the last
** thing written to a journal file. If the pager is in full-sync mode, the
** journal file descriptor is advanced to the next sector boundary before
** anything is written. The format is:
**
** + 4 bytes: PAGER_MJ_PGNO.
** + N bytes: length of master journal name.
** + 4 bytes: N
** + 4 bytes: Master journal name checksum.
** + 8 bytes: aJournalMagic[].
**
** The master journal page checksum is the sum of the bytes in the master
** journal name.
**
** If zMaster is a NULL pointer (occurs for a single database transaction), 
** this call is a no-op.
*/
static int writeMasterJournal(Pager *pPager, const char *zMaster){
  int rc;
  int len; 
  int i; 
  u32 cksum = 0;
  char zBuf[sizeof(aJournalMagic)+2*4];

  if( !zMaster || pPager->setMaster) return SQLITE_OK;
  pPager->setMaster = 1;

  len = strlen(zMaster);
  for(i=0; i<len; i++){
    cksum += zMaster[i];
  }

  /* If in full-sync mode, advance to the next disk sector before writing
  ** the master journal name. This is in case the previous page written to
  ** the journal has already been synced.
  */
  if( pPager->fullSync ){
    rc = seekJournalHdr(pPager);
    if( rc!=SQLITE_OK ) return rc;
  }
  pPager->journalOff += (len+20);

  rc = write32bits(pPager->jfd, PAGER_MJ_PGNO(pPager));
  if( rc!=SQLITE_OK ) return rc;

  rc = sqlite3OsWrite(pPager->jfd, zMaster, len);
  if( rc!=SQLITE_OK ) return rc;



  put32bits(zBuf, len);


  put32bits(&zBuf[4], cksum);
  memcpy(&zBuf[8], aJournalMagic, sizeof(aJournalMagic));
  rc = sqlite3OsWrite(pPager->jfd, zBuf, 8+sizeof(aJournalMagic));
  pPager->needSync = !pPager->noSync;
  return rc;
}

/*
** Add or remove a page from the list of all pages that are in the
** statement journal.
**







|






|


|


|








|



|



















<
<
<





|
<



















|


|


>
>
|
>
>
|
|
<
|







671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723



724
725
726
727
728
729

730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

762
763
764
765
766
767
768
769
  rc = seekJournalHdr(pPager);
  if( rc ) return rc;

  if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
    return SQLITE_DONE;
  }

  rc = sqlite3OsRead(&pPager->jfd, aMagic, sizeof(aMagic));
  if( rc ) return rc;

  if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
    return SQLITE_DONE;
  }

  rc = read32bits(&pPager->jfd, pNRec);
  if( rc ) return rc;

  rc = read32bits(&pPager->jfd, &pPager->cksumInit);
  if( rc ) return rc;

  rc = read32bits(&pPager->jfd, pDbSize);
  if( rc ) return rc;

  /* Update the assumed sector-size to match the value used by 
  ** the process that created this journal. If this journal was
  ** created by a process other than this one, then this routine
  ** is being called from within pager_playback(). The local value
  ** of Pager.sectorSize is restored at the end of that routine.
  */
  rc = read32bits(&pPager->jfd, (u32 *)&pPager->sectorSize);
  if( rc ) return rc;

  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
  rc = sqlite3OsSeek(&pPager->jfd, pPager->journalOff);
  return rc;
}


/*
** Write the supplied master journal name into the journal file for pager
** pPager at the current location. The master journal name must be the last
** thing written to a journal file. If the pager is in full-sync mode, the
** journal file descriptor is advanced to the next sector boundary before
** anything is written. The format is:
**
** + 4 bytes: PAGER_MJ_PGNO.
** + N bytes: length of master journal name.
** + 4 bytes: N
** + 4 bytes: Master journal name checksum.
** + 8 bytes: aJournalMagic[].
**
** The master journal page checksum is the sum of the bytes in the master
** journal name.



*/
static int writeMasterJournal(Pager *pPager, const char *zMaster){
  int rc;
  int len; 
  int i; 
  u32 cksum = 0; 


  if( !zMaster || pPager->setMaster) return SQLITE_OK;
  pPager->setMaster = 1;

  len = strlen(zMaster);
  for(i=0; i<len; i++){
    cksum += zMaster[i];
  }

  /* If in full-sync mode, advance to the next disk sector before writing
  ** the master journal name. This is in case the previous page written to
  ** the journal has already been synced.
  */
  if( pPager->fullSync ){
    rc = seekJournalHdr(pPager);
    if( rc!=SQLITE_OK ) return rc;
  }
  pPager->journalOff += (len+20);

  rc = write32bits(&pPager->jfd, PAGER_MJ_PGNO(pPager));
  if( rc!=SQLITE_OK ) return rc;

  rc = sqlite3OsWrite(&pPager->jfd, zMaster, len);
  if( rc!=SQLITE_OK ) return rc;

  rc = write32bits(&pPager->jfd, len);
  if( rc!=SQLITE_OK ) return rc;

  rc = write32bits(&pPager->jfd, cksum);
  if( rc!=SQLITE_OK ) return rc;

  rc = sqlite3OsWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic));

  pPager->needSync = 1;
  return rc;
}

/*
** Add or remove a page from the list of all pages that are in the
** statement journal.
**
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
** Unlock the database and clear the in-memory cache.  This routine
** sets the state of the pager back to what it was when it was first
** opened.  Any outstanding pages are invalidated and subsequent attempts
** to access those pages will likely result in a coredump.
*/
static void pager_reset(Pager *pPager){
  PgHdr *pPg, *pNext;
  if( pPager->errCode ) return;
  for(pPg=pPager->pAll; pPg; pPg=pNext){
    pNext = pPg->pNextAll;
    sqliteFree(pPg);
  }
  pPager->pFirst = 0;
  pPager->pFirstSynced = 0;
  pPager->pLast = 0;
  pPager->pAll = 0;
  memset(pPager->aHash, 0, sizeof(pPager->aHash));
  pPager->nPage = 0;
  if( pPager->state>=PAGER_RESERVED ){
    sqlite3pager_rollback(pPager);
  }
  sqlite3OsUnlock(pPager->fd, NO_LOCK);
  pPager->state = PAGER_UNLOCK;
  pPager->dbSize = -1;
  pPager->nRef = 0;
  assert( pPager->journalOpen==0 );
}

/*







<













|







818
819
820
821
822
823
824

825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
** Unlock the database and clear the in-memory cache.  This routine
** sets the state of the pager back to what it was when it was first
** opened.  Any outstanding pages are invalidated and subsequent attempts
** to access those pages will likely result in a coredump.
*/
static void pager_reset(Pager *pPager){
  PgHdr *pPg, *pNext;

  for(pPg=pPager->pAll; pPg; pPg=pNext){
    pNext = pPg->pNextAll;
    sqliteFree(pPg);
  }
  pPager->pFirst = 0;
  pPager->pFirstSynced = 0;
  pPager->pLast = 0;
  pPager->pAll = 0;
  memset(pPager->aHash, 0, sizeof(pPager->aHash));
  pPager->nPage = 0;
  if( pPager->state>=PAGER_RESERVED ){
    sqlite3pager_rollback(pPager);
  }
  sqlite3OsUnlock(&pPager->fd, NO_LOCK);
  pPager->state = PAGER_UNLOCK;
  pPager->dbSize = -1;
  pPager->nRef = 0;
  assert( pPager->journalOpen==0 );
}

/*
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
#ifdef SQLITE_CHECK_PAGES
      pPg->pageHash = pager_pagehash(pPg);
#endif
    }
    pPager->dirtyCache = 0;
    pPager->nRec = 0;
  }else{
    assert( pPager->aInJournal==0 );
    assert( pPager->dirtyCache==0 || pPager->useJournal==0 );
  }
  rc = sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
  pPager->state = PAGER_SHARED;
  pPager->origDbSize = 0;
  pPager->setMaster = 0;
  return rc;
}

/*







<


|







877
878
879
880
881
882
883

884
885
886
887
888
889
890
891
892
893
#ifdef SQLITE_CHECK_PAGES
      pPg->pageHash = pager_pagehash(pPg);
#endif
    }
    pPager->dirtyCache = 0;
    pPager->nRec = 0;
  }else{

    assert( pPager->dirtyCache==0 || pPager->useJournal==0 );
  }
  rc = sqlite3OsUnlock(&pPager->fd, SHARED_LOCK);
  pPager->state = PAGER_SHARED;
  pPager->origDbSize = 0;
  pPager->setMaster = 0;
  return rc;
}

/*
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
** though fast and simple, catches the mostly likely kind of corruption.
**
** FIX ME:  Consider adding every 200th (or so) byte of the data to the
** checksum.  That way if a single page spans 3 or more disk sectors and
** only the middle sector is corrupt, we will still have a reasonable
** chance of failing the checksum and thus detecting the problem.
*/
static u32 pager_cksum(Pager *pPager, Pgno pgno, const u8 *aData){
  u32 cksum = pPager->cksumInit;
  int i = pPager->pageSize-200;
  while( i>0 ){
    cksum += aData[i];
    i -= 200;
  }
  return cksum;







|







906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
** though fast and simple, catches the mostly likely kind of corruption.
**
** FIX ME:  Consider adding every 200th (or so) byte of the data to the
** checksum.  That way if a single page spans 3 or more disk sectors and
** only the middle sector is corrupt, we will still have a reasonable
** chance of failing the checksum and thus detecting the problem.
*/
static u32 pager_cksum(Pager *pPager, Pgno pgno, const char *aData){
  u32 cksum = pPager->cksumInit;
  int i = pPager->pageSize-200;
  while( i>0 ){
    cksum += aData[i];
    i -= 200;
  }
  return cksum;
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
*/
static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
  int rc;
  PgHdr *pPg;                   /* An existing page in the cache */
  Pgno pgno;                    /* The page number of a page in journal */
  u32 cksum;                    /* Checksum used for sanity checking */
  u8 aData[SQLITE_MAX_PAGE_SIZE];  /* Temp storage for a page */

  /* useCksum should be true for the main journal and false for
  ** statement journals.  Verify that this is always the case
  */
  assert( jfd == (useCksum ? pPager->jfd : pPager->stfd) );


  rc = read32bits(jfd, &pgno);
  if( rc!=SQLITE_OK ) return rc;
  rc = sqlite3OsRead(jfd, &aData, pPager->pageSize);
  if( rc!=SQLITE_OK ) return rc;
  pPager->journalOff += pPager->pageSize + 4;








<
<
<
<
<
<







930
931
932
933
934
935
936






937
938
939
940
941
942
943
*/
static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
  int rc;
  PgHdr *pPg;                   /* An existing page in the cache */
  Pgno pgno;                    /* The page number of a page in journal */
  u32 cksum;                    /* Checksum used for sanity checking */
  u8 aData[SQLITE_MAX_PAGE_SIZE];  /* Temp storage for a page */







  rc = read32bits(jfd, &pgno);
  if( rc!=SQLITE_OK ) return rc;
  rc = sqlite3OsRead(jfd, &aData, pPager->pageSize);
  if( rc!=SQLITE_OK ) return rc;
  pPager->journalOff += pPager->pageSize + 4;

993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037



1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066

1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097

1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110

  /* If the pager is in RESERVED state, then there must be a copy of this
  ** page in the pager cache. In this case just update the pager cache,
  ** not the database file. The page is left marked dirty in this case.
  **
  ** If in EXCLUSIVE state, then we update the pager cache if it exists
  ** and the main file. The page is then marked not dirty.
  **
  ** Ticket #1171:  The statement journal might contain page content that is
  ** different from the page content at the start of the transaction.
  ** This occurs when a page is changed prior to the start of a statement
  ** then changed again within the statement.  When rolling back such a
  ** statement we must not write to the original database unless we know
  ** for certain that original page contents are in the main rollback
  ** journal.  Otherwise, if a full ROLLBACK occurs after the statement
  ** rollback the full ROLLBACK will not restore the page to its original
  ** content.  Two conditions must be met before writing to the database
  ** files. (1) the database must be locked.  (2) we know that the original
  ** page content is in the main journal either because the page is not in
  ** cache or else it is marked as needSync==0.
  */
  pPg = pager_lookup(pPager, pgno);
  assert( pPager->state>=PAGER_EXCLUSIVE || pPg!=0 );
  TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno);
  if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){
    rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize);
    if( rc==SQLITE_OK ){
      rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize);
    }
    if( pPg ) pPg->dirty = 0;
  }
  if( pPg ){
    /* No page should ever be explicitly rolled back that is in use, except
    ** for page 1 which is held in use in order to keep the lock on the
    ** database active. However such a page may be rolled back as a result
    ** of an internal error resulting in an automatic call to
    ** sqlite3pager_rollback().
    */
    void *pData;
    /* assert( pPg->nRef==0 || pPg->pgno==1 ); */
    pData = PGHDR_TO_DATA(pPg);
    memcpy(pData, aData, pPager->pageSize);
    if( pPager->xDestructor ){  /*** FIX ME:  Should this be xReinit? ***/
      pPager->xDestructor(pData, pPager->pageSize);
    }



#ifdef SQLITE_CHECK_PAGES
    pPg->pageHash = pager_pagehash(pPg);
#endif

    CODEC(pPager, pData, pPg->pgno, 3);
  }
  return rc;
}

/*
** Parameter zMaster is the name of a master journal file. A single journal
** file that referred to the master journal file has just been rolled back.
** This routine checks if it is possible to delete the master journal file,
** and does so if it is.
**
** The master journal file contains the names of all child journals.
** To tell if a master journal can be deleted, check to each of the
** children.  If all children are either missing or do not refer to
** a different master journal, then this master journal can be deleted.
*/
static int pager_delmaster(const char *zMaster){
  int rc;
  int master_open = 0;
  OsFile *master = 0;
  char *zMasterJournal = 0; /* Contents of master journal file */
  i64 nMasterJournal;       /* Size of master journal file */

  /* Open the master journal file exclusively in case some other process
  ** is running this routine also. Not that it makes too much difference.
  */

  rc = sqlite3OsOpenReadOnly(zMaster, &master);
  if( rc!=SQLITE_OK ) goto delmaster_out;
  master_open = 1;
  rc = sqlite3OsFileSize(master, &nMasterJournal);
  if( rc!=SQLITE_OK ) goto delmaster_out;

  if( nMasterJournal>0 ){
    char *zJournal;
    char *zMasterPtr = 0;

    /* Load the entire master journal file into space obtained from
    ** sqliteMalloc() and pointed to by zMasterJournal. 
    */
    zMasterJournal = (char *)sqliteMalloc(nMasterJournal);
    if( !zMasterJournal ){
      rc = SQLITE_NOMEM;
      goto delmaster_out;
    }
    rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal);
    if( rc!=SQLITE_OK ) goto delmaster_out;

    zJournal = zMasterJournal;
    while( (zJournal-zMasterJournal)<nMasterJournal ){
      if( sqlite3OsFileExists(zJournal) ){
        /* One of the journals pointed to by the master journal exists.
        ** Open it and check if it points at the master journal. If
        ** so, return without deleting the master journal file.
        */
        OsFile *journal = 0;
        int c;


        rc = sqlite3OsOpenReadOnly(zJournal, &journal);
        if( rc!=SQLITE_OK ){
          goto delmaster_out;
        }

        rc = readMasterJournal(journal, &zMasterPtr);
        sqlite3OsClose(&journal);
        if( rc!=SQLITE_OK ){
          goto delmaster_out;
        }

        c = zMasterPtr!=0 && strcmp(zMasterPtr, zMaster)==0;
        sqliteFree(zMasterPtr);







<
<
<
<
<
<
<
<
<
<
<
<
<


|

|
|
<
|
<
<















>
>
>

|

>



















|






>



|














|









|


>





|







965
966
967
968
969
970
971













972
973
974
975
976
977

978


979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072

  /* If the pager is in RESERVED state, then there must be a copy of this
  ** page in the pager cache. In this case just update the pager cache,
  ** not the database file. The page is left marked dirty in this case.
  **
  ** If in EXCLUSIVE state, then we update the pager cache if it exists
  ** and the main file. The page is then marked not dirty.













  */
  pPg = pager_lookup(pPager, pgno);
  assert( pPager->state>=PAGER_EXCLUSIVE || pPg );
  TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno);
  if( pPager->state>=PAGER_EXCLUSIVE ){
    sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize);

    rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize);


  }
  if( pPg ){
    /* No page should ever be explicitly rolled back that is in use, except
    ** for page 1 which is held in use in order to keep the lock on the
    ** database active. However such a page may be rolled back as a result
    ** of an internal error resulting in an automatic call to
    ** sqlite3pager_rollback().
    */
    void *pData;
    /* assert( pPg->nRef==0 || pPg->pgno==1 ); */
    pData = PGHDR_TO_DATA(pPg);
    memcpy(pData, aData, pPager->pageSize);
    if( pPager->xDestructor ){  /*** FIX ME:  Should this be xReinit? ***/
      pPager->xDestructor(pData, pPager->pageSize);
    }
    if( pPager->state>=PAGER_EXCLUSIVE ){
      pPg->dirty = 0;
      pPg->needSync = 0;
#ifdef SQLITE_CHECK_PAGES
      pPg->pageHash = pager_pagehash(pPg);
#endif
    }
    CODEC(pPager, pData, pPg->pgno, 3);
  }
  return rc;
}

/*
** Parameter zMaster is the name of a master journal file. A single journal
** file that referred to the master journal file has just been rolled back.
** This routine checks if it is possible to delete the master journal file,
** and does so if it is.
**
** The master journal file contains the names of all child journals.
** To tell if a master journal can be deleted, check to each of the
** children.  If all children are either missing or do not refer to
** a different master journal, then this master journal can be deleted.
*/
static int pager_delmaster(const char *zMaster){
  int rc;
  int master_open = 0;
  OsFile master;
  char *zMasterJournal = 0; /* Contents of master journal file */
  i64 nMasterJournal;       /* Size of master journal file */

  /* Open the master journal file exclusively in case some other process
  ** is running this routine also. Not that it makes too much difference.
  */
  memset(&master, 0, sizeof(master));
  rc = sqlite3OsOpenReadOnly(zMaster, &master);
  if( rc!=SQLITE_OK ) goto delmaster_out;
  master_open = 1;
  rc = sqlite3OsFileSize(&master, &nMasterJournal);
  if( rc!=SQLITE_OK ) goto delmaster_out;

  if( nMasterJournal>0 ){
    char *zJournal;
    char *zMasterPtr = 0;

    /* Load the entire master journal file into space obtained from
    ** sqliteMalloc() and pointed to by zMasterJournal. 
    */
    zMasterJournal = (char *)sqliteMalloc(nMasterJournal);
    if( !zMasterJournal ){
      rc = SQLITE_NOMEM;
      goto delmaster_out;
    }
    rc = sqlite3OsRead(&master, zMasterJournal, nMasterJournal);
    if( rc!=SQLITE_OK ) goto delmaster_out;

    zJournal = zMasterJournal;
    while( (zJournal-zMasterJournal)<nMasterJournal ){
      if( sqlite3OsFileExists(zJournal) ){
        /* One of the journals pointed to by the master journal exists.
        ** Open it and check if it points at the master journal. If
        ** so, return without deleting the master journal file.
        */
        OsFile journal;
        int c;

        memset(&journal, 0, sizeof(journal));
        rc = sqlite3OsOpenReadOnly(zJournal, &journal);
        if( rc!=SQLITE_OK ){
          goto delmaster_out;
        }

        rc = readMasterJournal(&journal, &zMasterPtr);
        sqlite3OsClose(&journal);
        if( rc!=SQLITE_OK ){
          goto delmaster_out;
        }

        c = zMasterPtr!=0 && strcmp(zMasterPtr, zMaster)==0;
        sqliteFree(zMasterPtr);
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
static int pager_reload_cache(Pager *pPager){
  PgHdr *pPg;
  int rc = SQLITE_OK;
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    char zBuf[SQLITE_MAX_PAGE_SIZE];
    if( !pPg->dirty ) continue;
    if( (int)pPg->pgno <= pPager->origDbSize ){
      rc = sqlite3OsSeek(pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1));
      if( rc==SQLITE_OK ){
        rc = sqlite3OsRead(pPager->fd, zBuf, pPager->pageSize);
      }
      TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
      if( rc ) break;
      CODEC(pPager, zBuf, pPg->pgno, 2);
    }else{
      memset(zBuf, 0, pPager->pageSize);
    }
    if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), pPager->pageSize) ){







|
<
|
<







1103
1104
1105
1106
1107
1108
1109
1110

1111

1112
1113
1114
1115
1116
1117
1118
static int pager_reload_cache(Pager *pPager){
  PgHdr *pPg;
  int rc = SQLITE_OK;
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    char zBuf[SQLITE_MAX_PAGE_SIZE];
    if( !pPg->dirty ) continue;
    if( (int)pPg->pgno <= pPager->origDbSize ){
      sqlite3OsSeek(&pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1));

      rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize);

      TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
      if( rc ) break;
      CODEC(pPager, zBuf, pPg->pgno, 2);
    }else{
      memset(zBuf, 0, pPager->pageSize);
    }
    if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), pPager->pageSize) ){
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188

/*
** Truncate the main file of the given pager to the number of pages
** indicated.
*/
static int pager_truncate(Pager *pPager, int nPage){
  assert( pPager->state>=PAGER_EXCLUSIVE );
  return sqlite3OsTruncate(pPager->fd, pPager->pageSize*(i64)nPage);
}

/*
** Playback the journal and thus restore the database file to
** the state it was in before we started making changes.  
**
** The journal file format is as follows: 







|







1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148

/*
** Truncate the main file of the given pager to the number of pages
** indicated.
*/
static int pager_truncate(Pager *pPager, int nPage){
  assert( pPager->state>=PAGER_EXCLUSIVE );
  return sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(i64)nPage);
}

/*
** Playback the journal and thus restore the database file to
** the state it was in before we started making changes.  
**
** The journal file format is as follows: 
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
  int rc;                  /* Result code of a subroutine */
  char *zMaster = 0;       /* Name of master journal file if any */

  /* Figure out how many records are in the journal.  Abort early if
  ** the journal is empty.
  */
  assert( pPager->journalOpen );
  rc = sqlite3OsFileSize(pPager->jfd, &szJ);
  if( rc!=SQLITE_OK ){
    goto end_playback;
  }

  /* Read the master journal name from the journal, if it is present.
  ** If a master journal file name is specified, but the file is not
  ** present on disk, then the journal is not hot and does not need to be
  ** played back.
  */
  rc = readMasterJournal(pPager->jfd, &zMaster);
  assert( rc!=SQLITE_DONE );
  if( rc!=SQLITE_OK || (zMaster && !sqlite3OsFileExists(zMaster)) ){
    sqliteFree(zMaster);
    zMaster = 0;
    if( rc==SQLITE_DONE ) rc = SQLITE_OK;
    goto end_playback;
  }
  sqlite3OsSeek(pPager->jfd, 0);
  pPager->journalOff = 0;

  /* This loop terminates either when the readJournalHdr() call returns
  ** SQLITE_DONE or an IO error occurs. */
  while( 1 ){

    /* Read the next journal header from the journal file.  If there are







|









|







|







1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
  int rc;                  /* Result code of a subroutine */
  char *zMaster = 0;       /* Name of master journal file if any */

  /* Figure out how many records are in the journal.  Abort early if
  ** the journal is empty.
  */
  assert( pPager->journalOpen );
  rc = sqlite3OsFileSize(&pPager->jfd, &szJ);
  if( rc!=SQLITE_OK ){
    goto end_playback;
  }

  /* Read the master journal name from the journal, if it is present.
  ** If a master journal file name is specified, but the file is not
  ** present on disk, then the journal is not hot and does not need to be
  ** played back.
  */
  rc = readMasterJournal(&pPager->jfd, &zMaster);
  assert( rc!=SQLITE_DONE );
  if( rc!=SQLITE_OK || (zMaster && !sqlite3OsFileExists(zMaster)) ){
    sqliteFree(zMaster);
    zMaster = 0;
    if( rc==SQLITE_DONE ) rc = SQLITE_OK;
    goto end_playback;
  }
  sqlite3OsSeek(&pPager->jfd, 0);
  pPager->journalOff = 0;

  /* This loop terminates either when the readJournalHdr() call returns
  ** SQLITE_DONE or an IO error occurs. */
  while( 1 ){

    /* Read the next journal header from the journal file.  If there are
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
      rc = pager_truncate(pPager, mxPg);
      if( rc!=SQLITE_OK ){
        goto end_playback;
      }
      pPager->dbSize = mxPg;
    }

    /* rc = sqlite3OsSeek(pPager->jfd, JOURNAL_HDR_SZ(pPager)); */
    if( rc!=SQLITE_OK ) goto end_playback;
  
    /* Copy original pages out of the journal and back into the database file.
    */
    for(i=0; i<nRec; i++){
      rc = pager_playback_one_page(pPager, pPager->jfd, 1);
      if( rc!=SQLITE_OK ){
        if( rc==SQLITE_DONE ){
          rc = SQLITE_OK;
          pPager->journalOff = szJ;
          break;
        }else{
          goto end_playback;







|





|







1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
      rc = pager_truncate(pPager, mxPg);
      if( rc!=SQLITE_OK ){
        goto end_playback;
      }
      pPager->dbSize = mxPg;
    }

    /* rc = sqlite3OsSeek(&pPager->jfd, JOURNAL_HDR_SZ(pPager)); */
    if( rc!=SQLITE_OK ) goto end_playback;
  
    /* Copy original pages out of the journal and back into the database file.
    */
    for(i=0; i<nRec; i++){
      rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
      if( rc!=SQLITE_OK ){
        if( rc==SQLITE_DONE ){
          rc = SQLITE_OK;
          pPager->journalOff = szJ;
          break;
        }else{
          goto end_playback;
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
  int i;                   /* Loop counter */
  int rc;

  szJ = pPager->journalOff;
#ifndef NDEBUG 
  {
    i64 os_szJ;
    rc = sqlite3OsFileSize(pPager->jfd, &os_szJ);
    if( rc!=SQLITE_OK ) return rc;
    assert( szJ==os_szJ );
  }
#endif

  /* Set hdrOff to be the offset to the first journal header written
  ** this statement transaction, or the end of the file if no journal







|







1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
  int i;                   /* Loop counter */
  int rc;

  szJ = pPager->journalOff;
#ifndef NDEBUG 
  {
    i64 os_szJ;
    rc = sqlite3OsFileSize(&pPager->jfd, &os_szJ);
    if( rc!=SQLITE_OK ) return rc;
    assert( szJ==os_szJ );
  }
#endif

  /* Set hdrOff to be the offset to the first journal header written
  ** this statement transaction, or the end of the file if no journal
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465

1466
1467
1468
1469
1470
1471
1472
1473
1474
1475







1476
1477







1478
1479
1480
1481
1482
1483
1484
    rc = pager_truncate(pPager, pPager->stmtSize);
  }
  pPager->dbSize = pPager->stmtSize;

  /* Figure out how many records are in the statement journal.
  */
  assert( pPager->stmtInUse && pPager->journalOpen );
  sqlite3OsSeek(pPager->stfd, 0);
  nRec = pPager->stmtNRec;
  
  /* Copy original pages out of the statement journal and back into the
  ** database file.  Note that the statement journal omits checksums from
  ** each record since power-failure recovery is not important to statement
  ** journals.
  */
  for(i=nRec-1; i>=0; i--){
    rc = pager_playback_one_page(pPager, pPager->stfd, 0);
    assert( rc!=SQLITE_DONE );
    if( rc!=SQLITE_OK ) goto end_stmt_playback;
  }

  /* Now roll some pages back from the transaction journal. Pager.stmtJSize
  ** was the size of the journal file when this statement was started, so
  ** everything after that needs to be rolled back, either into the
  ** database, the memory cache, or both.
  **
  ** If it is not zero, then Pager.stmtHdrOff is the offset to the start
  ** of the first journal header written during this statement transaction.
  */
  rc = sqlite3OsSeek(pPager->jfd, pPager->stmtJSize);
  if( rc!=SQLITE_OK ){
    goto end_stmt_playback;
  }
  pPager->journalOff = pPager->stmtJSize;
  pPager->cksumInit = pPager->stmtCksum;
  assert( JOURNAL_HDR_SZ(pPager)<(pPager->pageSize+8) );
  while( pPager->journalOff <= (hdrOff-(pPager->pageSize+8)) ){
    rc = pager_playback_one_page(pPager, pPager->jfd, 1);
    assert( rc!=SQLITE_DONE );
    if( rc!=SQLITE_OK ) goto end_stmt_playback;
  }

  while( pPager->journalOff < szJ ){
    u32 nRec;
    u32 dummy;
    rc = readJournalHdr(pPager, szJ, &nRec, &dummy);
    if( rc!=SQLITE_OK ){
      assert( rc!=SQLITE_DONE );
      goto end_stmt_playback;
    }
    if( nRec==0 ){
      nRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);
    }
    for(i=nRec-1; i>=0 && pPager->journalOff < szJ; i--){
      rc = pager_playback_one_page(pPager, pPager->jfd, 1);
      assert( rc!=SQLITE_DONE );
      if( rc!=SQLITE_OK ) goto end_stmt_playback;
    }
  }

  pPager->journalOff = szJ;
  
end_stmt_playback:
  if( rc!=SQLITE_OK ){

    rc = pager_error(pPager, SQLITE_CORRUPT);
  }else{
    pPager->journalOff = szJ;
    /* pager_reload_cache(pPager); */
  }
  return rc;
}

/*
** Change the maximum number of in-memory pages that are allowed.







*/
void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){







  if( mxPage>10 ){
    pPager->mxPage = mxPage;
  }else{
    pPager->mxPage = 10;
  }
}








|








|












|







|
















|









>
|









>
>
>
>
>
>
>


>
>
>
>
>
>
>







1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
    rc = pager_truncate(pPager, pPager->stmtSize);
  }
  pPager->dbSize = pPager->stmtSize;

  /* Figure out how many records are in the statement journal.
  */
  assert( pPager->stmtInUse && pPager->journalOpen );
  sqlite3OsSeek(&pPager->stfd, 0);
  nRec = pPager->stmtNRec;
  
  /* Copy original pages out of the statement journal and back into the
  ** database file.  Note that the statement journal omits checksums from
  ** each record since power-failure recovery is not important to statement
  ** journals.
  */
  for(i=nRec-1; i>=0; i--){
    rc = pager_playback_one_page(pPager, &pPager->stfd, 0);
    assert( rc!=SQLITE_DONE );
    if( rc!=SQLITE_OK ) goto end_stmt_playback;
  }

  /* Now roll some pages back from the transaction journal. Pager.stmtJSize
  ** was the size of the journal file when this statement was started, so
  ** everything after that needs to be rolled back, either into the
  ** database, the memory cache, or both.
  **
  ** If it is not zero, then Pager.stmtHdrOff is the offset to the start
  ** of the first journal header written during this statement transaction.
  */
  rc = sqlite3OsSeek(&pPager->jfd, pPager->stmtJSize);
  if( rc!=SQLITE_OK ){
    goto end_stmt_playback;
  }
  pPager->journalOff = pPager->stmtJSize;
  pPager->cksumInit = pPager->stmtCksum;
  assert( JOURNAL_HDR_SZ(pPager)<(pPager->pageSize+8) );
  while( pPager->journalOff <= (hdrOff-(pPager->pageSize+8)) ){
    rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
    assert( rc!=SQLITE_DONE );
    if( rc!=SQLITE_OK ) goto end_stmt_playback;
  }

  while( pPager->journalOff < szJ ){
    u32 nRec;
    u32 dummy;
    rc = readJournalHdr(pPager, szJ, &nRec, &dummy);
    if( rc!=SQLITE_OK ){
      assert( rc!=SQLITE_DONE );
      goto end_stmt_playback;
    }
    if( nRec==0 ){
      nRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);
    }
    for(i=nRec-1; i>=0 && pPager->journalOff < szJ; i--){
      rc = pager_playback_one_page(pPager, &pPager->jfd, 1);
      assert( rc!=SQLITE_DONE );
      if( rc!=SQLITE_OK ) goto end_stmt_playback;
    }
  }

  pPager->journalOff = szJ;
  
end_stmt_playback:
  if( rc!=SQLITE_OK ){
    pPager->errMask |= PAGER_ERR_CORRUPT;
    rc = SQLITE_CORRUPT;  /* bkpt-CORRUPT */
  }else{
    pPager->journalOff = szJ;
    /* pager_reload_cache(pPager); */
  }
  return rc;
}

/*
** Change the maximum number of in-memory pages that are allowed.
**
** The maximum number is the absolute value of the mxPage parameter.
** If mxPage is negative, the noSync flag is also set.  noSync bypasses
** calls to sqlite3OsSync().  The pager runs much faster with noSync on,
** but if the operating system crashes or there is an abrupt power 
** failure, the database file might be left in an inconsistent and
** unrepairable state.  
*/
void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){
  if( mxPage>=0 ){
    pPager->noSync = pPager->tempFile;
    if( pPager->noSync ) pPager->needSync = 0; 
  }else{
    pPager->noSync = 1;
    mxPage = -mxPage;
  }
  if( mxPage>10 ){
    pPager->mxPage = mxPage;
  }else{
    pPager->mxPage = 10;
  }
}

1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
  pPager->noSync =  level==1 || pPager->tempFile;
  pPager->fullSync = level==3 && !pPager->tempFile;
  if( pPager->noSync ) pPager->needSync = 0;
}
#endif

/*
** The following global variable is incremented whenever the library
** attempts to open a temporary file.  This information is used for
** testing and analysis only.  
*/
int sqlite3_opentemp_count = 0;

/*
** Open a temporary file.  Write the name of the file into zFile
** (zFile must be at least SQLITE_TEMPNAME_SIZE bytes long.)  Write
** the file descriptor into *fd.  Return SQLITE_OK on success or some
** other error code if we fail.
**
** The OS will automatically delete the temporary file when it is
** closed.
*/
static int sqlite3pager_opentemp(char *zFile, OsFile **pFd){
  int cnt = 8;
  int rc;
  sqlite3_opentemp_count++;  /* Used for testing and analysis only */
  do{
    cnt--;
    sqlite3OsTempFileName(zFile);
    rc = sqlite3OsOpenExclusive(zFile, pFd, 1);
  }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
  return rc;
}

/*
** Create a new page cache and put a pointer to the page cache in *ppPager.
** The file to be cached need not exist.  The file is not locked until







<
<
<
<
<
<
<
|
|






|


<



|







1488
1489
1490
1491
1492
1493
1494







1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505

1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
  pPager->noSync =  level==1 || pPager->tempFile;
  pPager->fullSync = level==3 && !pPager->tempFile;
  if( pPager->noSync ) pPager->needSync = 0;
}
#endif

/*







** Open a temporary file.  Write the name of the file into zName
** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.)  Write
** the file descriptor into *fd.  Return SQLITE_OK on success or some
** other error code if we fail.
**
** The OS will automatically delete the temporary file when it is
** closed.
*/
static int sqlite3pager_opentemp(char *zFile, OsFile *fd){
  int cnt = 8;
  int rc;

  do{
    cnt--;
    sqlite3OsTempFileName(zFile);
    rc = sqlite3OsOpenExclusive(zFile, fd, 1);
  }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
  return rc;
}

/*
** Create a new page cache and put a pointer to the page cache in *ppPager.
** The file to be cached need not exist.  The file is not locked until
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587

1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600

1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616



1617
1618
1619
1620
1621


1622


1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651



1652
1653
1654
1655
1656
1657
1658
1659

1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
*/
int sqlite3pager_open(
  Pager **ppPager,         /* Return the Pager structure here */
  const char *zFilename,   /* Name of the database file to open */
  int nExtra,              /* Extra bytes append to each in-memory page */
  int flags                /* flags controlling this file */
){
  Pager *pPager = 0;
  char *zFullPathname = 0;
  int nameLen;
  OsFile *fd;
  int rc = SQLITE_OK;
  int i;
  int tempFile = 0;
  int memDb = 0;
  int readOnly = 0;
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
  char zTemp[SQLITE_TEMPNAME_SIZE];
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  const ThreadData *pTsdro = sqlite3ThreadDataReadOnly();
#endif

  /* If malloc() has already failed return SQLITE_NOMEM. Before even
  ** testing for this, set *ppPager to NULL so the caller knows the pager
  ** structure was never allocated. 
  */
  *ppPager = 0;

  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    return SQLITE_NOMEM;
  }
  memset(&fd, 0, sizeof(fd));

  /* Open the pager file and set zFullPathname to point at malloc()ed 
  ** memory containing the complete filename (i.e. including the directory).
  */
  if( zFilename && zFilename[0] ){
#ifndef SQLITE_OMIT_MEMORYDB
    if( strcmp(zFilename,":memory:")==0 ){
      memDb = 1;
      zFullPathname = sqliteStrDup("");

    }else
#endif
    {
      zFullPathname = sqlite3OsFullPathname(zFilename);
      if( zFullPathname ){
        rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly);
      }
    }
  }else{
    rc = sqlite3pager_opentemp(zTemp, &fd);
    zFilename = zTemp;
    zFullPathname = sqlite3OsFullPathname(zFilename);
    if( rc==SQLITE_OK ){
      tempFile = 1;
    }
  }




  /* Allocate the Pager structure. As part of the same allocation, allocate
  ** space for the full paths of the file, directory and journal 
  ** (Pager.zFilename, Pager.zDirectory and Pager.zJournal).
  */


  if( zFullPathname ){


    nameLen = strlen(zFullPathname);
    pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
  }

  /* If an error occured in either of the blocks above, free the memory 
  ** pointed to by zFullPathname, free the Pager structure and close the 
  ** file. Since the pager is not allocated there is no need to set 
  ** any Pager.errMask variables.
  */
  if( !pPager || !zFullPathname || rc!=SQLITE_OK ){
    sqlite3OsClose(&fd);
    sqliteFree(zFullPathname);
    sqliteFree(pPager);
    return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);
  }

  TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
  pPager->zFilename = (char*)&pPager[1];
  pPager->zDirectory = &pPager->zFilename[nameLen+1];
  pPager->zJournal = &pPager->zDirectory[nameLen+1];
  strcpy(pPager->zFilename, zFullPathname);
  strcpy(pPager->zDirectory, zFullPathname);

  for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){}
  if( i>0 ) pPager->zDirectory[i-1] = 0;
  strcpy(pPager->zJournal, zFullPathname);
  sqliteFree(zFullPathname);
  strcpy(&pPager->zJournal[nameLen], "-journal");
  pPager->fd = fd;



  /* pPager->journalOpen = 0; */
  pPager->useJournal = useJournal && !memDb;
  pPager->noReadlock = noReadlock && readOnly;
  /* pPager->stmtOpen = 0; */
  /* pPager->stmtInUse = 0; */
  /* pPager->nRef = 0; */
  pPager->dbSize = memDb-1;
  pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE;

  /* pPager->stmtSize = 0; */
  /* pPager->stmtJSize = 0; */
  /* pPager->nPage = 0; */
  /* pPager->nMaxPage = 0; */
  pPager->mxPage = 100;
  assert( PAGER_UNLOCK==0 );
  /* pPager->state = PAGER_UNLOCK; */
  /* pPager->errMask = 0; */
  pPager->tempFile = tempFile;
  pPager->memDb = memDb;
  pPager->readOnly = readOnly;
  /* pPager->needSync = 0; */
  pPager->noSync = pPager->tempFile || !useJournal;
  pPager->fullSync = (pPager->noSync?0:1);
  /* pPager->pFirst = 0; */
  /* pPager->pFirstSynced = 0; */
  /* pPager->pLast = 0; */
  pPager->nExtra = FORCE_ALIGNMENT(nExtra);
  pPager->sectorSize = PAGER_SECTOR_SIZE;
  /* pPager->pBusyHandler = 0; */
  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
  *ppPager = pPager;
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  if( pTsdro->useMemoryManagement ){
    ThreadData *pTsd = sqlite3ThreadData();
    pPager->pNext = pTsd->pPager;
    pTsd->pPager = pPager;
  }
#endif
  return SQLITE_OK;
}

/*
** Set the busy handler function.
*/
void sqlite3pager_set_busyhandler(Pager *pPager, BusyHandler *pBusyHandler){







|


|








<
<
<

<
<
<
<

>
|


<
<
<
<
<





>
















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


<
|

<






<






>
>
>
|


|
|
|


>
|
|
|
<

<
|
|



|


|
|
|


|
|

<
<
<
<
<
<
<







1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545



1546




1547
1548
1549
1550
1551





1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577




1578
1579
1580
1581
1582
1583
1584

1585






1586
1587

1588
1589

1590
1591
1592
1593
1594
1595

1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616

1617

1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633







1634
1635
1636
1637
1638
1639
1640
*/
int sqlite3pager_open(
  Pager **ppPager,         /* Return the Pager structure here */
  const char *zFilename,   /* Name of the database file to open */
  int nExtra,              /* Extra bytes append to each in-memory page */
  int flags                /* flags controlling this file */
){
  Pager *pPager;
  char *zFullPathname = 0;
  int nameLen;
  OsFile fd;
  int rc = SQLITE_OK;
  int i;
  int tempFile = 0;
  int memDb = 0;
  int readOnly = 0;
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
  char zTemp[SQLITE_TEMPNAME_SIZE];








  *ppPager = 0;
  memset(&fd, 0, sizeof(fd));
  if( sqlite3_malloc_failed ){
    return SQLITE_NOMEM;
  }





  if( zFilename && zFilename[0] ){
#ifndef SQLITE_OMIT_MEMORYDB
    if( strcmp(zFilename,":memory:")==0 ){
      memDb = 1;
      zFullPathname = sqliteStrDup("");
      rc = SQLITE_OK;
    }else
#endif
    {
      zFullPathname = sqlite3OsFullPathname(zFilename);
      if( zFullPathname ){
        rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly);
      }
    }
  }else{
    rc = sqlite3pager_opentemp(zTemp, &fd);
    zFilename = zTemp;
    zFullPathname = sqlite3OsFullPathname(zFilename);
    if( rc==SQLITE_OK ){
      tempFile = 1;
    }
  }
  if( !zFullPathname ){
    sqlite3OsClose(&fd);
    return SQLITE_NOMEM;
  }




  if( rc!=SQLITE_OK ){
    sqlite3OsClose(&fd);
    sqliteFree(zFullPathname);
    return rc;
  }
  nameLen = strlen(zFullPathname);
  pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );

  if( pPager==0 ){






    sqlite3OsClose(&fd);
    sqliteFree(zFullPathname);

    return SQLITE_NOMEM;
  }

  TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
  pPager->zFilename = (char*)&pPager[1];
  pPager->zDirectory = &pPager->zFilename[nameLen+1];
  pPager->zJournal = &pPager->zDirectory[nameLen+1];
  strcpy(pPager->zFilename, zFullPathname);
  strcpy(pPager->zDirectory, zFullPathname);

  for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){}
  if( i>0 ) pPager->zDirectory[i-1] = 0;
  strcpy(pPager->zJournal, zFullPathname);
  sqliteFree(zFullPathname);
  strcpy(&pPager->zJournal[nameLen], "-journal");
  pPager->fd = fd;
#if OS_UNIX
  pPager->fd.pPager = pPager;
#endif
  pPager->journalOpen = 0;
  pPager->useJournal = useJournal && !memDb;
  pPager->noReadlock = noReadlock && readOnly;
  pPager->stmtOpen = 0;
  pPager->stmtInUse = 0;
  pPager->nRef = 0;
  pPager->dbSize = memDb-1;
  pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
  pPager->psAligned = FORCE_ALIGNMENT(pPager->pageSize);
  pPager->stmtSize = 0;
  pPager->stmtJSize = 0;
  pPager->nPage = 0;

  pPager->mxPage = 100;

  pPager->state = PAGER_UNLOCK;
  pPager->errMask = 0;
  pPager->tempFile = tempFile;
  pPager->memDb = memDb;
  pPager->readOnly = readOnly;
  pPager->needSync = 0;
  pPager->noSync = pPager->tempFile || !useJournal;
  pPager->fullSync = (pPager->noSync?0:1);
  pPager->pFirst = 0;
  pPager->pFirstSynced = 0;
  pPager->pLast = 0;
  pPager->nExtra = FORCE_ALIGNMENT(nExtra);
  pPager->sectorSize = PAGER_SECTOR_SIZE;
  pPager->pBusyHandler = 0;
  memset(pPager->aHash, 0, sizeof(pPager->aHash));
  *ppPager = pPager;







  return SQLITE_OK;
}

/*
** Set the busy handler function.
*/
void sqlite3pager_set_busyhandler(Pager *pPager, BusyHandler *pBusyHandler){
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725

1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796

1797
1798
1799
1800
1801
1802
1803
1804

1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
** page data.
*/
void sqlite3pager_set_reiniter(Pager *pPager, void (*xReinit)(void*,int)){
  pPager->xReiniter = xReinit;
}

/*
** Set the page size.  Return the new size.  If the suggest new page
** size is inappropriate, then an alternative page size is selected
** and returned.

*/
int sqlite3pager_set_pagesize(Pager *pPager, int pageSize){
  assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );
  if( !pPager->memDb ){
    pPager->pageSize = pageSize;
  }
  return pPager->pageSize;
}

/*
** The following set of routines are used to disable the simulated
** I/O error mechanism.  These routines are used to avoid simulated
** errors in places where we do not care about errors.
**
** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops
** and generate no code.
*/
#ifdef SQLITE_TEST
extern int sqlite3_io_error_pending;
extern int sqlite3_io_error_hit;
static int saved_cnt;
void clear_simulated_io_error(){
  sqlite3_io_error_hit = 0;
}
void disable_simulated_io_errors(void){
  saved_cnt = sqlite3_io_error_pending;
  sqlite3_io_error_pending = -1;
}
void enable_simulated_io_errors(void){
  sqlite3_io_error_pending = saved_cnt;
}
#else
# define clear_simulated_io_error()
# define disable_simulated_io_errors()
# define enable_simulated_io_errors()
#endif

/*
** Read the first N bytes from the beginning of the file into memory
** that pDest points to. 
**
** No error checking is done. The rational for this is that this function 
** may be called even if the file does not exist or contain a header. In 
** these cases sqlite3OsRead() will return an error, to which the correct 
** response is to zero the memory at pDest and continue.  A real IO error 
** will presumably recur and be picked up later (Todo: Think about this).
*/
void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
  memset(pDest, 0, N);
  if( MEMDB==0 ){
    sqlite3OsSeek(pPager->fd, 0);
    sqlite3OsRead(pPager->fd, pDest, N);
    clear_simulated_io_error();
  }
}

/*
** Return the total number of pages in the disk file associated with
** pPager. 
**
** If the PENDING_BYTE lies on the page directly after the end of the
** file, then consider this page part of the file too. For example, if
** PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the
** file is 4096 bytes, 5 is returned instead of 4.
*/
int sqlite3pager_pagecount(Pager *pPager){
  i64 n;
  assert( pPager!=0 );
  if( pPager->dbSize>=0 ){
    n = pPager->dbSize;
  } else {

    if( sqlite3OsFileSize(pPager->fd, &n)!=SQLITE_OK ){
      pager_error(pPager, SQLITE_IOERR);
      return 0;
    }
    if( n>0 && n<pPager->pageSize ){
      n = 1;
    }else{
      n /= pPager->pageSize;

    }
    if( pPager->state!=PAGER_UNLOCK ){
      pPager->dbSize = n;
    }
  }
  if( n==(PENDING_BYTE/pPager->pageSize) ){
    n++;
  }
  return n;
}

/*
** Forward declaration
*/







|
<
|
>

|

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

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


|
<
<
<
<
<
<




|
|
<





|
<
<
<
<
<





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







1661
1662
1663
1664
1665
1666
1667
1668

1669
1670
1671
1672
1673

1674



1675














1676



1677









1678
1679
1680






1681
1682
1683
1684
1685
1686

1687
1688
1689
1690
1691
1692





1693
1694
1695
1696
1697
1698

1699
1700
1701
1702
1703
1704


1705
1706
1707
1708
1709




1710
1711
1712
1713
1714
1715
1716
** page data.
*/
void sqlite3pager_set_reiniter(Pager *pPager, void (*xReinit)(void*,int)){
  pPager->xReiniter = xReinit;
}

/*
** Set the page size.

**
** The page size must only be changed when the cache is empty.
*/
void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){
  assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );

  pPager->pageSize = pageSize;



  pPager->psAligned = FORCE_ALIGNMENT(pageSize);














}













/*
** Read the first N bytes from the beginning of the file into memory
** that pDest points to.  No error checking is done.






*/
void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
  memset(pDest, 0, N);
  if( MEMDB==0 ){
    sqlite3OsSeek(&pPager->fd, 0);
    sqlite3OsRead(&pPager->fd, pDest, N);

  }
}

/*
** Return the total number of pages in the disk file associated with
** pPager.





*/
int sqlite3pager_pagecount(Pager *pPager){
  i64 n;
  assert( pPager!=0 );
  if( pPager->dbSize>=0 ){
    return pPager->dbSize;

  }
  if( sqlite3OsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
    pPager->errMask |= PAGER_ERR_DISK;
    return 0;
  }
  n /= pPager->pageSize;


  if( !MEMDB && n==PENDING_BYTE/pPager->pageSize ){
    n++;
  }
  if( pPager->state!=PAGER_UNLOCK ){
    pPager->dbSize = n;




  }
  return n;
}

/*
** Forward declaration
*/
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927

1928
1929
1930




1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
}
#else
#define memoryTruncate(p)
#endif

/*
** Try to obtain a lock on a file.  Invoke the busy callback if the lock
** is currently not available.  Repeat until the busy callback returns
** false or until the lock succeeds.
**
** Return SQLITE_OK on success and an error code if we cannot obtain
** the lock.
*/
static int pager_wait_on_lock(Pager *pPager, int locktype){
  int rc;
  assert( PAGER_SHARED==SHARED_LOCK );
  assert( PAGER_RESERVED==RESERVED_LOCK );
  assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
  if( pPager->state>=locktype ){
    rc = SQLITE_OK;
  }else{

    do {
      rc = sqlite3OsLock(pPager->fd, locktype);
    }while( rc==SQLITE_BUSY && sqlite3InvokeBusyHandler(pPager->pBusyHandler) );




    if( rc==SQLITE_OK ){
      pPager->state = locktype;
    }
  }
  return rc;
}

/*
** Truncate the file to the number of pages specified.
*/
int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
  int rc;
  sqlite3pager_pagecount(pPager);
  if( pPager->errCode ){
    rc = pPager->errCode;
    return rc;
  }
  if( nPage>=(unsigned)pPager->dbSize ){
    return SQLITE_OK;
  }
  if( MEMDB ){
    pPager->dbSize = nPage;







|













>

|
|
>
>
>
>













|
|







1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
}
#else
#define memoryTruncate(p)
#endif

/*
** Try to obtain a lock on a file.  Invoke the busy callback if the lock
** is currently not available.  Repeate until the busy callback returns
** false or until the lock succeeds.
**
** Return SQLITE_OK on success and an error code if we cannot obtain
** the lock.
*/
static int pager_wait_on_lock(Pager *pPager, int locktype){
  int rc;
  assert( PAGER_SHARED==SHARED_LOCK );
  assert( PAGER_RESERVED==RESERVED_LOCK );
  assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
  if( pPager->state>=locktype ){
    rc = SQLITE_OK;
  }else{
    int busy = 1;
    do {
      rc = sqlite3OsLock(&pPager->fd, locktype);
    }while( rc==SQLITE_BUSY && 
        pPager->pBusyHandler && 
        pPager->pBusyHandler->xFunc && 
        pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++)
    );
    if( rc==SQLITE_OK ){
      pPager->state = locktype;
    }
  }
  return rc;
}

/*
** Truncate the file to the number of pages specified.
*/
int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
  int rc;
  sqlite3pager_pagecount(pPager);
  if( pPager->errMask!=0 ){
    rc = pager_errcode(pPager);
    return rc;
  }
  if( nPage>=(unsigned)pPager->dbSize ){
    return SQLITE_OK;
  }
  if( MEMDB ){
    pPager->dbSize = nPage;
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001



2002

2003

2004

2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
** Shutdown the page cache.  Free all memory and close all files.
**
** If a transaction was in progress when this routine is called, that
** transaction is rolled back.  All outstanding pages are invalidated
** and their memory is freed.  Any attempt to use a page associated
** with this page cache after this function returns will likely
** result in a coredump.
**
** This function always succeeds. If a transaction is active an attempt
** is made to roll it back. If an error occurs during the rollback 
** a hot journal may be left in the filesystem but no error is returned
** to the caller.
*/
int sqlite3pager_close(Pager *pPager){
  PgHdr *pPg, *pNext;
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  const ThreadData *pTsd = sqlite3ThreadDataReadOnly();
#endif

  switch( pPager->state ){
    case PAGER_RESERVED:
    case PAGER_SYNCED: 
    case PAGER_EXCLUSIVE: {
      /* We ignore any IO errors that occur during the rollback
      ** operation. So disable IO error simulation so that testing
      ** works more easily.
      */



      disable_simulated_io_errors();

      sqlite3pager_rollback(pPager);

      enable_simulated_io_errors();

      if( !MEMDB ){
        sqlite3OsUnlock(pPager->fd, NO_LOCK);
      }
      assert( pPager->errCode || pPager->journalOpen==0 );
      break;
    }
    case PAGER_SHARED: {
      if( !MEMDB ){
        sqlite3OsUnlock(pPager->fd, NO_LOCK);
      }
      break;
    }
    default: {
      /* Do nothing */
      break;
    }







<
<
<
<
<



<
<
<
<








>
>
>
|
>

>
|
>

|

|




|







1878
1879
1880
1881
1882
1883
1884





1885
1886
1887




1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
** Shutdown the page cache.  Free all memory and close all files.
**
** If a transaction was in progress when this routine is called, that
** transaction is rolled back.  All outstanding pages are invalidated
** and their memory is freed.  Any attempt to use a page associated
** with this page cache after this function returns will likely
** result in a coredump.





*/
int sqlite3pager_close(Pager *pPager){
  PgHdr *pPg, *pNext;




  switch( pPager->state ){
    case PAGER_RESERVED:
    case PAGER_SYNCED: 
    case PAGER_EXCLUSIVE: {
      /* We ignore any IO errors that occur during the rollback
      ** operation. So disable IO error simulation so that testing
      ** works more easily.
      */
#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN))
      extern int sqlite3_io_error_pending;
      int ioerr_cnt = sqlite3_io_error_pending;
      sqlite3_io_error_pending = -1;
#endif
      sqlite3pager_rollback(pPager);
#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN))
      sqlite3_io_error_pending = ioerr_cnt;
#endif
      if( !MEMDB ){
        sqlite3OsUnlock(&pPager->fd, NO_LOCK);
      }
      assert( pPager->journalOpen==0 );
      break;
    }
    case PAGER_SHARED: {
      if( !MEMDB ){
        sqlite3OsUnlock(&pPager->fd, NO_LOCK);
      }
      break;
    }
    default: {
      /* Do nothing */
      break;
    }
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
      assert( !pHist->pStmt );
    }
#endif
    pNext = pPg->pNextAll;
    sqliteFree(pPg);
  }
  TRACE2("CLOSE %d\n", PAGERID(pPager));
  assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
  if( pPager->journalOpen ){
    sqlite3OsClose(&pPager->jfd);
  }
  sqliteFree(pPager->aInJournal);
  if( pPager->stmtOpen ){
    sqlite3OsClose(&pPager->stfd);
  }
  sqlite3OsClose(&pPager->fd);
  /* Temp files are automatically deleted by the OS
  ** if( pPager->tempFile ){
  **   sqlite3OsDelete(pPager->zFilename);
  ** }
  */

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  /* Remove the pager from the linked list of pagers starting at 
  ** ThreadData.pPager if memory-management is enabled.
  */
  if( pTsd->useMemoryManagement ){
    if( pPager==pTsd->pPager ){
      pTsd->pPager = pPager->pNext;
    }else{
      Pager *pTmp;
      for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext);
      pTmp->pNext = pPager->pNext;
    }
  }
#endif

#ifdef SQLITE_HAS_CODEC
  sqlite3pager_free_codecarg(pPager->pCodecArg);
#endif
  sqliteFree(pPager);
  return SQLITE_OK;
}

/*
** Return the page number for the given page data.
*/







<
<
|
<
<
|
<
<
<






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1928
1929
1930
1931
1932
1933
1934


1935


1936



1937
1938
1939
1940
1941
1942


















1943
1944
1945
1946
1947
1948
1949
      assert( !pHist->pStmt );
    }
#endif
    pNext = pPg->pNextAll;
    sqliteFree(pPg);
  }
  TRACE2("CLOSE %d\n", PAGERID(pPager));


  sqlite3OsClose(&pPager->fd);


  assert( pPager->journalOpen==0 );



  /* Temp files are automatically deleted by the OS
  ** if( pPager->tempFile ){
  **   sqlite3OsDelete(pPager->zFilename);
  ** }
  */



















  sqliteFree(pPager);
  return SQLITE_OK;
}

/*
** Return the page number for the given page data.
*/
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
      ** was turned off after the transaction was started.  Ticket #615 */
#ifndef NDEBUG
      {
        /* Make sure the pPager->nRec counter we are keeping agrees
        ** with the nRec computed from the size of the journal file.
        */
        i64 jSz;
        rc = sqlite3OsFileSize(pPager->jfd, &jSz);
        if( rc!=0 ) return rc;
        assert( pPager->journalOff==jSz );
      }
#endif
      {
        /* Write the nRec value into the journal file header. If in
        ** full-synchronous mode, sync the journal first. This ensures that
        ** all data has really hit the disk before nRec is updated to mark
        ** it as a candidate for rollback. 
        */
        if( pPager->fullSync ){
          TRACE2("SYNC journal of %d\n", PAGERID(pPager));
          rc = sqlite3OsSync(pPager->jfd, 0);
          if( rc!=0 ) return rc;
        }
        rc = sqlite3OsSeek(pPager->jfd,
                           pPager->journalHdr + sizeof(aJournalMagic));
        if( rc ) return rc;
        rc = write32bits(pPager->jfd, pPager->nRec);
        if( rc ) return rc;

        rc = sqlite3OsSeek(pPager->jfd, pPager->journalOff);
        if( rc ) return rc;
      }
      TRACE2("SYNC journal of %d\n", PAGERID(pPager));
      rc = sqlite3OsSync(pPager->jfd, pPager->fullSync);
      if( rc!=0 ) return rc;
      pPager->journalStarted = 1;
    }
    pPager->needSync = 0;

    /* Erase the needSync flag from every page.
    */







|












|


<
|
<
|


|
<


|







2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063

2064

2065
2066
2067
2068

2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
      ** was turned off after the transaction was started.  Ticket #615 */
#ifndef NDEBUG
      {
        /* Make sure the pPager->nRec counter we are keeping agrees
        ** with the nRec computed from the size of the journal file.
        */
        i64 jSz;
        rc = sqlite3OsFileSize(&pPager->jfd, &jSz);
        if( rc!=0 ) return rc;
        assert( pPager->journalOff==jSz );
      }
#endif
      {
        /* Write the nRec value into the journal file header. If in
        ** full-synchronous mode, sync the journal first. This ensures that
        ** all data has really hit the disk before nRec is updated to mark
        ** it as a candidate for rollback. 
        */
        if( pPager->fullSync ){
          TRACE2("SYNC journal of %d\n", PAGERID(pPager));
          rc = sqlite3OsSync(&pPager->jfd);
          if( rc!=0 ) return rc;
        }

        sqlite3OsSeek(&pPager->jfd, pPager->journalHdr + sizeof(aJournalMagic));

        rc = write32bits(&pPager->jfd, pPager->nRec);
        if( rc ) return rc;

        sqlite3OsSeek(&pPager->jfd, pPager->journalOff);

      }
      TRACE2("SYNC journal of %d\n", PAGERID(pPager));
      rc = sqlite3OsSync(&pPager->jfd);
      if( rc!=0 ) return rc;
      pPager->journalStarted = 1;
    }
    pPager->needSync = 0;

    /* Erase the needSync flag from every page.
    */
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  while( pList ){
    assert( pList->dirty );
    rc = sqlite3OsSeek(pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize);
    if( rc ) return rc;
    /* If there are dirty pages in the page cache with page numbers greater
    ** than Pager.dbSize, this means sqlite3pager_truncate() was called to
    ** make the file smaller (presumably by auto-vacuum code). Do not write
    ** any such pages to the file.
    */
    if( pList->pgno<=pPager->dbSize ){
      CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
      TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno);
      rc = sqlite3OsWrite(pPager->fd, PGHDR_TO_DATA(pList),
                             pPager->pageSize);
      CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
      TEST_INCR(pPager->nWrite);
    }
#ifndef NDEBUG
    else{
      TRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno);
    }
#endif
    if( rc ) return rc;







|
<








|
<

|







2129
2130
2131
2132
2133
2134
2135
2136

2137
2138
2139
2140
2141
2142
2143
2144
2145

2146
2147
2148
2149
2150
2151
2152
2153
2154
  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  while( pList ){
    assert( pList->dirty );
    sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize);

    /* If there are dirty pages in the page cache with page numbers greater
    ** than Pager.dbSize, this means sqlite3pager_truncate() was called to
    ** make the file smaller (presumably by auto-vacuum code). Do not write
    ** any such pages to the file.
    */
    if( pList->pgno<=pPager->dbSize ){
      CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
      TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno);
      rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize);

      CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
      pPager->nWrite++;
    }
#ifndef NDEBUG
    else{
      TRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno);
    }
#endif
    if( rc ) return rc;
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
      p->pDirty = pList;
      pList = p;
    }
  }
  return pList;
}

/*
** Return TRUE if there is a hot journal on the given pager.
** A hot journal is one that needs to be played back.
**
** If the current size of the database file is 0 but a journal file
** exists, that is probably an old journal left over from a prior
** database with the same name.  Just delete the journal.
*/
static int hasHotJournal(Pager *pPager){
  if( !pPager->useJournal ) return 0;
  if( !sqlite3OsFileExists(pPager->zJournal) ) return 0;
  if( sqlite3OsCheckReservedLock(pPager->fd) ) return 0;
  if( sqlite3pager_pagecount(pPager)==0 ){
    sqlite3OsDelete(pPager->zJournal);
    return 0;
  }else{
    return 1;
  }
}

/*
** Try to find a page in the cache that can be recycled. 
**
** This routine may return SQLITE_IOERR, SQLITE_FULL or SQLITE_OK. It 
** does not set the pPager->errCode variable.
*/
static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
  PgHdr *pPg;
  *ppPg = 0;

  /* Find a page to recycle.  Try to locate a page that does not
  ** require us to do an fsync() on the journal.
  */
  pPg = pPager->pFirstSynced;

  /* If we could not find a page that does not require an fsync()
  ** on the journal file then fsync the journal file.  This is a
  ** very slow operation, so we work hard to avoid it.  But sometimes
  ** it can't be helped.
  */
  if( pPg==0 && pPager->pFirst && syncOk && !MEMDB){
    int rc = syncJournal(pPager);
    if( rc!=0 ){
      return rc;
    }
    if( pPager->fullSync ){
      /* If in full-sync mode, write a new journal header into the
      ** journal file. This is done to avoid ever modifying a journal
      ** header that is involved in the rollback of pages that have
      ** already been written to the database (in case the header is
      ** trashed when the nRec field is updated).
      */
      pPager->nRec = 0;
      assert( pPager->journalOff > 0 );
      rc = writeJournalHdr(pPager);
      if( rc!=0 ){
        return rc;
      }
    }
    pPg = pPager->pFirst;
  }
  if( pPg==0 ){
    return SQLITE_OK;
  }

  assert( pPg->nRef==0 );

  /* Write the page to the database file if it is dirty.
  */
  if( pPg->dirty ){
    int rc;
    assert( pPg->needSync==0 );
    pPg->pDirty = 0;
    rc = pager_write_pagelist( pPg );
    if( rc!=SQLITE_OK ){
      return rc;
    }
  }
  assert( pPg->dirty==0 );

  /* If the page we are recycling is marked as alwaysRollback, then
  ** set the global alwaysRollback flag, thus disabling the
  ** sqlite_dont_rollback() optimization for the rest of this transaction.
  ** It is necessary to do this because the page marked alwaysRollback
  ** might be reloaded at a later time but at that point we won't remember
  ** that is was marked alwaysRollback.  This means that all pages must
  ** be marked as alwaysRollback from here on out.
  */
  if( pPg->alwaysRollback ){
    pPager->alwaysRollback = 1;
  }

  /* Unlink the old page from the free list and the hash table
  */
  unlinkPage(pPg);
  TEST_INCR(pPager->nOvfl);

  *ppPg = pPg;
  return SQLITE_OK;
}

/*
** This function is called to free superfluous dynamically allocated memory
** held by the pager system. Memory in use by any SQLite pager allocated
** by the current thread may be sqliteFree()ed.
**
** nReq is the number of bytes of memory required. Once this much has
** been released, the function returns. A negative value for nReq means
** free as much memory as possible. The return value is the total number 
** of bytes of memory released.
*/
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
int sqlite3pager_release_memory(int nReq){
  const ThreadData *pTsdro = sqlite3ThreadDataReadOnly();
  Pager *p;
  int nReleased = 0;
  int i;

  /* If the the global mutex is held, this subroutine becomes a
  ** o-op; zero bytes of memory are freed.  This is because
  ** some of the code invoked by this function may also
  ** try to obtain the mutex, resulting in a deadlock.
  */
  if( sqlite3OsInMutex() ){
    return 0;
  }

  /* Outermost loop runs for at most two iterations. First iteration we
  ** try to find memory that can be released without calling fsync(). Second
  ** iteration (which only runs if the first failed to free nReq bytes of
  ** memory) is permitted to call fsync(). This is of course much more 
  ** expensive.
  */
  for(i=0; i<=1; i++){

    /* Loop through all the SQLite pagers opened by the current thread. */
    for(p=pTsdro->pPager; p && (nReq<0 || nReleased<nReq); p=p->pNext){
      PgHdr *pPg;
      int rc;

      /* For each pager, try to free as many pages as possible (without 
      ** calling fsync() if this is the first iteration of the outermost 
      ** loop).
      */
      while( SQLITE_OK==(rc = pager_recycle(p, i, &pPg)) && pPg) {
        /* We've found a page to free. At this point the page has been 
        ** removed from the page hash-table, free-list and synced-list 
        ** (pFirstSynced). It is still in the all pages (pAll) list. 
        ** Remove it from this list before freeing.
        **
        ** Todo: Check the Pager.pStmt list to make sure this is Ok. It 
        ** probably is though.
        */
        PgHdr *pTmp;
        assert( pPg );
        page_remove_from_stmt_list(pPg);
        if( pPg==p->pAll ){
           p->pAll = pPg->pNextAll;
        }else{
          for( pTmp=p->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll );
          pTmp->pNextAll = pPg->pNextAll;
        }
        nReleased += sqliteAllocSize(pPg);
        sqliteFree(pPg);
      }

      if( rc!=SQLITE_OK ){
        /* An error occured whilst writing to the database file or 
        ** journal in pager_recycle(). The error is not returned to the 
        ** caller of this function. Instead, set the Pager.errCode variable.
        ** The error will be returned to the user (or users, in the case 
        ** of a shared pager cache) of the pager for which the error occured.
        */
        assert( rc==SQLITE_IOERR || rc==SQLITE_FULL );
        assert( p->state>=PAGER_RESERVED );
        pager_error(p, rc);
      }
    }
  }

  return nReleased;
}
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */

/*
** Acquire a page.
**
** A read lock on the disk file is obtained when the first page is acquired. 
** This read lock is dropped when the last page is released.
**
** A _get works for any page number greater than 0.  If the database







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2174
2175
2176
2177
2178
2179
2180
























































































































































































2181
2182
2183
2184
2185
2186
2187
      p->pDirty = pList;
      pList = p;
    }
  }
  return pList;
}

























































































































































































/*
** Acquire a page.
**
** A read lock on the disk file is obtained when the first page is acquired. 
** This read lock is dropped when the last page is released.
**
** A _get works for any page number greater than 0.  If the database
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551



2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618




2619
2620
2621
2622
2623
2624
2625
2626
2627
2628

















2629







2630






2631
2632

2633





2634
2635

2636
2637

2638

















2639
2640
2641
2642
2643
2644
2645
** just returns 0.  This routine acquires a read-lock the first time it
** has to go to disk, and could also playback an old journal if necessary.
** Since _lookup() never goes to disk, it never has to deal with locks
** or journal files.
*/
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
  PgHdr *pPg;
  int rc;

  /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
  ** number greater than this, or zero, is requested.
  */
  if( pgno>PAGER_MAX_PGNO || pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
    return SQLITE_CORRUPT_BKPT;
  }

  /* Make sure we have not hit any critical errors.
  */ 
  assert( pPager!=0 );
  *ppPage = 0;
  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
    return pPager->errCode;
  }

  /* If this is the first page accessed, then get a SHARED lock
  ** on the database file.
  */
  if( pPager->nRef==0 && !MEMDB ){
    if( !pPager->noReadlock ){
      rc = pager_wait_on_lock(pPager, SHARED_LOCK);
      if( rc!=SQLITE_OK ){
        return pager_error(pPager, rc);
      }
    }

    /* If a journal file exists, and there is no RESERVED lock on the
    ** database file, then it either needs to be played back or deleted.
    */
    if( hasHotJournal(pPager) ){



       int rc;

       /* Get an EXCLUSIVE lock on the database file. At this point it is
       ** important that a RESERVED lock is not obtained on the way to the
       ** EXCLUSIVE lock. If it were, another process might open the
       ** database file, detect the RESERVED lock, and conclude that the
       ** database is safe to read while this process is still rolling it 
       ** back.
       ** 
       ** Because the intermediate RESERVED lock is not requested, the
       ** second process will get to this point in the code and fail to
       ** obtain it's own EXCLUSIVE lock on the database file.
       */
       rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
       if( rc!=SQLITE_OK ){
         sqlite3OsUnlock(pPager->fd, NO_LOCK);
         pPager->state = PAGER_UNLOCK;
         return pager_error(pPager, rc);
       }
       pPager->state = PAGER_EXCLUSIVE;

       /* Open the journal for reading only.  Return SQLITE_BUSY if
       ** we are unable to open the journal file. 
       **
       ** The journal file does not need to be locked itself.  The
       ** journal file is never open unless the main database file holds
       ** a write lock, so there is never any chance of two or more
       ** processes opening the journal at the same time.
       */
       rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd);
       if( rc!=SQLITE_OK ){
         sqlite3OsUnlock(pPager->fd, NO_LOCK);
         pPager->state = PAGER_UNLOCK;
         return SQLITE_BUSY;
       }
       pPager->journalOpen = 1;
       pPager->journalStarted = 0;
       pPager->journalOff = 0;
       pPager->setMaster = 0;
       pPager->journalHdr = 0;

       /* Playback and delete the journal.  Drop the database write
       ** lock and reacquire the read lock.
       */
       rc = pager_playback(pPager);
       if( rc!=SQLITE_OK ){
         return pager_error(pPager, rc);
       }
    }
    pPg = 0;
  }else{
    /* Search for page in cache */
    pPg = pager_lookup(pPager, pgno);
    if( MEMDB && pPager->state==PAGER_UNLOCK ){
      pPager->state = PAGER_SHARED;
    }
  }
  if( pPg==0 ){
    /* The requested page is not in the page cache. */
    int h;
    TEST_INCR(pPager->nMiss);
    if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB ){
      /* Create a new page */
      pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize
                              + sizeof(u32) + pPager->nExtra
                              + MEMDB*sizeof(PgHistory) );
      if( pPg==0 ){




        return SQLITE_NOMEM;
      }
      memset(pPg, 0, sizeof(*pPg));
      if( MEMDB ){
        memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory));
      }
      pPg->pPager = pPager;
      pPg->pNextAll = pPager->pAll;
      pPager->pAll = pPg;
      pPager->nPage++;

















      if( pPager->nPage>pPager->nMaxPage ){







        assert( pPager->nMaxPage==(pPager->nPage-1) );






        pPager->nMaxPage++;
      }

    }else{





      rc = pager_recycle(pPager, 1, &pPg);
      if( rc!=SQLITE_OK ){

        return pager_error(pPager, rc);
      }

      assert(pPg) ;

















    }
    pPg->pgno = pgno;
    if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
      sqlite3CheckMemory(pPager->aInJournal, pgno/8);
      assert( pPager->journalOpen );
      pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
      pPg->needSync = 0;







|




|
|






|
|









|






|
>
>
>













|

|

|













|














|













|


|



>
>
>
>










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

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







2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
** just returns 0.  This routine acquires a read-lock the first time it
** has to go to disk, and could also playback an old journal if necessary.
** Since _lookup() never goes to disk, it never has to deal with locks
** or journal files.
*/
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
  PgHdr *pPg;
  int rc, n;

  /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
  ** number greater than this, or zero, is requested.
  */
  if( pgno>PAGER_MAX_PGNO || pgno==0 ){
    return SQLITE_CORRUPT;
  }

  /* Make sure we have not hit any critical errors.
  */ 
  assert( pPager!=0 );
  *ppPage = 0;
  if( pPager->errMask & ~(PAGER_ERR_FULL) ){
    return pager_errcode(pPager);
  }

  /* If this is the first page accessed, then get a SHARED lock
  ** on the database file.
  */
  if( pPager->nRef==0 && !MEMDB ){
    if( !pPager->noReadlock ){
      rc = pager_wait_on_lock(pPager, SHARED_LOCK);
      if( rc!=SQLITE_OK ){
        return rc;
      }
    }

    /* If a journal file exists, and there is no RESERVED lock on the
    ** database file, then it either needs to be played back or deleted.
    */
    if( pPager->useJournal && 
        sqlite3OsFileExists(pPager->zJournal) &&
        !sqlite3OsCheckReservedLock(&pPager->fd) 
    ){
       int rc;

       /* Get an EXCLUSIVE lock on the database file. At this point it is
       ** important that a RESERVED lock is not obtained on the way to the
       ** EXCLUSIVE lock. If it were, another process might open the
       ** database file, detect the RESERVED lock, and conclude that the
       ** database is safe to read while this process is still rolling it 
       ** back.
       ** 
       ** Because the intermediate RESERVED lock is not requested, the
       ** second process will get to this point in the code and fail to
       ** obtain it's own EXCLUSIVE lock on the database file.
       */
       rc = sqlite3OsLock(&pPager->fd, EXCLUSIVE_LOCK);
       if( rc!=SQLITE_OK ){
         sqlite3OsUnlock(&pPager->fd, NO_LOCK);
         pPager->state = PAGER_UNLOCK;
         return rc;
       }
       pPager->state = PAGER_EXCLUSIVE;

       /* Open the journal for reading only.  Return SQLITE_BUSY if
       ** we are unable to open the journal file. 
       **
       ** The journal file does not need to be locked itself.  The
       ** journal file is never open unless the main database file holds
       ** a write lock, so there is never any chance of two or more
       ** processes opening the journal at the same time.
       */
       rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd);
       if( rc!=SQLITE_OK ){
         sqlite3OsUnlock(&pPager->fd, NO_LOCK);
         pPager->state = PAGER_UNLOCK;
         return SQLITE_BUSY;
       }
       pPager->journalOpen = 1;
       pPager->journalStarted = 0;
       pPager->journalOff = 0;
       pPager->setMaster = 0;
       pPager->journalHdr = 0;

       /* Playback and delete the journal.  Drop the database write
       ** lock and reacquire the read lock.
       */
       rc = pager_playback(pPager);
       if( rc!=SQLITE_OK ){
         return rc;
       }
    }
    pPg = 0;
  }else{
    /* Search for page in cache */
    pPg = pager_lookup(pPager, pgno);
    if( MEMDB && pPager->state==PAGER_UNLOCK ){
      pPager->state = PAGER_SHARED;
    }
  }
  if( pPg==0 ){
    /* The requested page is not in the page cache. */
    int h;
    pPager->nMiss++;
    if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB ){
      /* Create a new page */
      pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->psAligned
                              + sizeof(u32) + pPager->nExtra
                              + MEMDB*sizeof(PgHistory) );
      if( pPg==0 ){
        if( !MEMDB ){
          pager_unwritelock(pPager);
        }
        pPager->errMask |= PAGER_ERR_MEM;
        return SQLITE_NOMEM;
      }
      memset(pPg, 0, sizeof(*pPg));
      if( MEMDB ){
        memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory));
      }
      pPg->pPager = pPager;
      pPg->pNextAll = pPager->pAll;
      pPager->pAll = pPg;
      pPager->nPage++;
    }else{
      /* Find a page to recycle.  Try to locate a page that does not
      ** require us to do an fsync() on the journal.
      */
      pPg = pPager->pFirstSynced;

      /* If we could not find a page that does not require an fsync()
      ** on the journal file then fsync the journal file.  This is a
      ** very slow operation, so we work hard to avoid it.  But sometimes
      ** it can't be helped.
      */
      if( pPg==0 ){
        int rc = syncJournal(pPager);
        if( rc!=0 ){
          sqlite3pager_rollback(pPager);
          return SQLITE_IOERR;
        }
        if( pPager->fullSync ){
          /* If in full-sync mode, write a new journal header into the
	  ** journal file. This is done to avoid ever modifying a journal
	  ** header that is involved in the rollback of pages that have
	  ** already been written to the database (in case the header is
	  ** trashed when the nRec field is updated).
          */
          pPager->nRec = 0;
          assert( pPager->journalOff > 0 );
          rc = writeJournalHdr(pPager);
          if( rc!=0 ){
            sqlite3pager_rollback(pPager);
            return SQLITE_IOERR;
          }
        }
        pPg = pPager->pFirst;
      }
      assert( pPg->nRef==0 );

      /* Write the page to the database file if it is dirty.
      */
      if( pPg->dirty ){
        assert( pPg->needSync==0 );
        pPg->pDirty = 0;
        rc = pager_write_pagelist( pPg );
        if( rc!=SQLITE_OK ){
          sqlite3pager_rollback(pPager);
          return SQLITE_IOERR;
        }
      }
      assert( pPg->dirty==0 );

      /* If the page we are recycling is marked as alwaysRollback, then
      ** set the global alwaysRollback flag, thus disabling the
      ** sqlite_dont_rollback() optimization for the rest of this transaction.
      ** It is necessary to do this because the page marked alwaysRollback
      ** might be reloaded at a later time but at that point we won't remember
      ** that is was marked alwaysRollback.  This means that all pages must
      ** be marked as alwaysRollback from here on out.
      */
      if( pPg->alwaysRollback ){
        pPager->alwaysRollback = 1;
      }

      /* Unlink the old page from the free list and the hash table
      */
      unlinkPage(pPg);
      pPager->nOvfl++;
    }
    pPg->pgno = pgno;
    if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
      sqlite3CheckMemory(pPager->aInJournal, pgno/8);
      assert( pPager->journalOpen );
      pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
      pPg->needSync = 0;
2663
2664
2665
2666
2667
2668
2669

2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
    if( pPg->pNextHash ){
      assert( pPg->pNextHash->pPrevHash==0 );
      pPg->pNextHash->pPrevHash = pPg;
    }
    if( pPager->nExtra>0 ){
      memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
    }

    if( pPager->errCode ){
      sqlite3pager_unref(PGHDR_TO_DATA(pPg));
      rc = pPager->errCode;
      return rc;
    }
    if( sqlite3pager_pagecount(pPager)<(int)pgno ){
      memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
    }else{
      int rc;
      assert( MEMDB==0 );
      rc = sqlite3OsSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize);
      if( rc==SQLITE_OK ){
        rc = sqlite3OsRead(pPager->fd, PGHDR_TO_DATA(pPg),
                              pPager->pageSize);
      }
      TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
      CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
      if( rc!=SQLITE_OK ){
        i64 fileSize;
        if( sqlite3OsFileSize(pPager->fd,&fileSize)!=SQLITE_OK
               || fileSize>=pgno*pPager->pageSize ){
          sqlite3pager_unref(PGHDR_TO_DATA(pPg));
          return pager_error(pPager, rc);
        }else{
          clear_simulated_io_error();
          memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
        }
      }else{
        TEST_INCR(pPager->nRead);
      }
    }
#ifdef SQLITE_CHECK_PAGES
    pPg->pageHash = pager_pagehash(pPg);
#endif
  }else{
    /* The requested page is in the page cache. */
    TEST_INCR(pPager->nHit);
    page_ref(pPg);
  }
  *ppPage = PGHDR_TO_DATA(pPg);
  return SQLITE_OK;
}

/*







>
|

|


|




|
<
|
<
<




|


|

<



|







|







2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429

2430


2431
2432
2433
2434
2435
2436
2437
2438
2439

2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
    if( pPg->pNextHash ){
      assert( pPg->pNextHash->pPrevHash==0 );
      pPg->pNextHash->pPrevHash = pPg;
    }
    if( pPager->nExtra>0 ){
      memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
    }
    n = sqlite3pager_pagecount(pPager);
    if( pPager->errMask!=0 ){
      sqlite3pager_unref(PGHDR_TO_DATA(pPg));
      rc = pager_errcode(pPager);
      return rc;
    }
    if( n<(int)pgno ){
      memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
    }else{
      int rc;
      assert( MEMDB==0 );
      sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize);

      rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize);


      TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
      CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
      if( rc!=SQLITE_OK ){
        i64 fileSize;
        if( sqlite3OsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK
               || fileSize>=pgno*pPager->pageSize ){
          sqlite3pager_unref(PGHDR_TO_DATA(pPg));
          return rc;
        }else{

          memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
        }
      }else{
        pPager->nRead++;
      }
    }
#ifdef SQLITE_CHECK_PAGES
    pPg->pageHash = pager_pagehash(pPg);
#endif
  }else{
    /* The requested page is in the page cache. */
    pPager->nHit++;
    page_ref(pPg);
  }
  *ppPage = PGHDR_TO_DATA(pPg);
  return SQLITE_OK;
}

/*
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
** has ever happened.
*/
void *sqlite3pager_lookup(Pager *pPager, Pgno pgno){
  PgHdr *pPg;

  assert( pPager!=0 );
  assert( pgno!=0 );
  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
    return 0;
  }
  pPg = pager_lookup(pPager, pgno);
  if( pPg==0 ) return 0;
  page_ref(pPg);
  return PGHDR_TO_DATA(pPg);
}







|







2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
** has ever happened.
*/
void *sqlite3pager_lookup(Pager *pPager, Pgno pgno){
  PgHdr *pPg;

  assert( pPager!=0 );
  assert( pgno!=0 );
  if( pPager->errMask & ~(PAGER_ERR_FULL) ){
    return 0;
  }
  pPg = pager_lookup(pPager, pgno);
  if( pPg==0 ) return 0;
  page_ref(pPg);
  return PGHDR_TO_DATA(pPg);
}
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
*/
static int pager_open_journal(Pager *pPager){
  int rc;
  assert( !MEMDB );
  assert( pPager->state>=PAGER_RESERVED );
  assert( pPager->journalOpen==0 );
  assert( pPager->useJournal );
  assert( pPager->aInJournal==0 );
  sqlite3pager_pagecount(pPager);
  pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
  if( pPager->aInJournal==0 ){
    rc = SQLITE_NOMEM;
    goto failed_to_open_journal;
  }
  rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,
                                 pPager->tempFile);
  pPager->journalOff = 0;
  pPager->setMaster = 0;
  pPager->journalHdr = 0;
  if( rc!=SQLITE_OK ){
    goto failed_to_open_journal;
  }
  sqlite3OsSetFullSync(pPager->jfd, pPager->fullSync);
  sqlite3OsSetFullSync(pPager->fd, pPager->fullSync);
  sqlite3OsOpenDirectory(pPager->jfd, pPager->zDirectory);
  pPager->journalOpen = 1;
  pPager->journalStarted = 0;
  pPager->needSync = 0;
  pPager->alwaysRollback = 0;
  pPager->nRec = 0;
  if( pPager->errCode ){
    rc = pPager->errCode;
    goto failed_to_open_journal;
  }
  pPager->origDbSize = pPager->dbSize;

  rc = writeJournalHdr(pPager);

  if( pPager->stmtAutoopen && rc==SQLITE_OK ){
    rc = sqlite3pager_stmt_begin(pPager);
  }
  if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
    rc = pager_unwritelock(pPager);
    if( rc==SQLITE_OK ){
      rc = SQLITE_FULL;
    }
  }
  return rc;

failed_to_open_journal:
  sqliteFree(pPager->aInJournal);
  pPager->aInJournal = 0;
  if( rc==SQLITE_NOMEM ){
    /* If this was a malloc() failure, then we will not be closing the pager
    ** file. So delete any journal file we may have just created. Otherwise,
    ** the system will get confused, we have a read-lock on the file and a
    ** mysterious journal has appeared in the filesystem.
    */
    sqlite3OsDelete(pPager->zJournal);
  }else{
    sqlite3OsUnlock(pPager->fd, NO_LOCK);
    pPager->state = PAGER_UNLOCK;
  }
  return rc;
}

/*
** Acquire a write-lock on the database.  The lock is removed when
** the any of the following happen:
**







<






|
<






<
<
|





|
|
|








|










<
<
<
<
<
<
<
<
|
|
<







2542
2543
2544
2545
2546
2547
2548

2549
2550
2551
2552
2553
2554
2555

2556
2557
2558
2559
2560
2561


2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589








2590
2591

2592
2593
2594
2595
2596
2597
2598
*/
static int pager_open_journal(Pager *pPager){
  int rc;
  assert( !MEMDB );
  assert( pPager->state>=PAGER_RESERVED );
  assert( pPager->journalOpen==0 );
  assert( pPager->useJournal );

  sqlite3pager_pagecount(pPager);
  pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
  if( pPager->aInJournal==0 ){
    rc = SQLITE_NOMEM;
    goto failed_to_open_journal;
  }
  rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile);

  pPager->journalOff = 0;
  pPager->setMaster = 0;
  pPager->journalHdr = 0;
  if( rc!=SQLITE_OK ){
    goto failed_to_open_journal;
  }


  sqlite3OsOpenDirectory(pPager->zDirectory, &pPager->jfd);
  pPager->journalOpen = 1;
  pPager->journalStarted = 0;
  pPager->needSync = 0;
  pPager->alwaysRollback = 0;
  pPager->nRec = 0;
  if( pPager->errMask!=0 ){
    rc = pager_errcode(pPager);
    return rc;
  }
  pPager->origDbSize = pPager->dbSize;

  rc = writeJournalHdr(pPager);

  if( pPager->stmtAutoopen && rc==SQLITE_OK ){
    rc = sqlite3pager_stmt_begin(pPager);
  }
  if( rc!=SQLITE_OK ){
    rc = pager_unwritelock(pPager);
    if( rc==SQLITE_OK ){
      rc = SQLITE_FULL;
    }
  }
  return rc;

failed_to_open_journal:
  sqliteFree(pPager->aInJournal);
  pPager->aInJournal = 0;








  sqlite3OsUnlock(&pPager->fd, NO_LOCK);
  pPager->state = PAGER_UNLOCK;

  return rc;
}

/*
** Acquire a write-lock on the database.  The lock is removed when
** the any of the following happen:
**
2895
2896
2897
2898
2899
2900
2901



2902

2903
2904
2905
2906
2907
2908
2909
  assert( pPager->state!=PAGER_UNLOCK );
  if( pPager->state==PAGER_SHARED ){
    assert( pPager->aInJournal==0 );
    if( MEMDB ){
      pPager->state = PAGER_EXCLUSIVE;
      pPager->origDbSize = pPager->dbSize;
    }else{



      rc = sqlite3OsLock(pPager->fd, RESERVED_LOCK);

      if( rc==SQLITE_OK ){
        pPager->state = PAGER_RESERVED;
        if( exFlag ){
          rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
        }
      }
      if( rc!=SQLITE_OK ){







>
>
>
|
>







2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
  assert( pPager->state!=PAGER_UNLOCK );
  if( pPager->state==PAGER_SHARED ){
    assert( pPager->aInJournal==0 );
    if( MEMDB ){
      pPager->state = PAGER_EXCLUSIVE;
      pPager->origDbSize = pPager->dbSize;
    }else{
      if( SQLITE_BUSY_RESERVED_LOCK || exFlag ){
        rc = pager_wait_on_lock(pPager, RESERVED_LOCK);
      }else{
        rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK);
      }
      if( rc==SQLITE_OK ){
        pPager->state = PAGER_RESERVED;
        if( exFlag ){
          rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
        }
      }
      if( rc!=SQLITE_OK ){
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
int sqlite3pager_write(void *pData){
  PgHdr *pPg = DATA_TO_PGHDR(pData);
  Pager *pPager = pPg->pPager;
  int rc = SQLITE_OK;

  /* Check for errors
  */
  if( pPager->errCode ){ 
    return pPager->errCode;
  }
  if( pPager->readOnly ){
    return SQLITE_PERM;
  }

  assert( !pPager->setMaster );








|
|







2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
int sqlite3pager_write(void *pData){
  PgHdr *pPg = DATA_TO_PGHDR(pData);
  Pager *pPager = pPg->pPager;
  int rc = SQLITE_OK;

  /* Check for errors
  */
  if( pPager->errMask ){ 
    return pager_errcode(pPager);
  }
  if( pPager->readOnly ){
    return SQLITE_PERM;
  }

  assert( !pPager->setMaster );

2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
          assert( pHist->pOrig==0 );
          pHist->pOrig = sqliteMallocRaw( pPager->pageSize );
          if( pHist->pOrig ){
            memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
          }
        }else{
          u32 cksum;
          /* We should never write to the journal file the page that
          ** contains the database locks.  The following assert verifies
          ** that we do not. */
          assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
          CODEC(pPager, pData, pPg->pgno, 7);
          cksum = pager_cksum(pPager, pPg->pgno, pData);
          saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
          store32bits(cksum, pPg, pPager->pageSize);
          szPg = pPager->pageSize+8;
          store32bits(pPg->pgno, pPg, -4);
          rc = sqlite3OsWrite(pPager->jfd, &((char*)pData)[-4], szPg);
          pPager->journalOff += szPg;
          TRACE4("JOURNAL %d page %d needSync=%d\n",
                  PAGERID(pPager), pPg->pgno, pPg->needSync);
          CODEC(pPager, pData, pPg->pgno, 0);
          *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
          if( rc!=SQLITE_OK ){
            sqlite3pager_rollback(pPager);
            if( !pPager->errCode ){
              pager_error(pPager, SQLITE_FULL);
            }
            return rc;
          }
          pPager->nRec++;
          assert( pPager->aInJournal!=0 );
          pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
          pPg->needSync = !pPager->noSync;
          if( pPager->stmtInUse ){







<
<
<
<






|







|
<
<







2732
2733
2734
2735
2736
2737
2738




2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753


2754
2755
2756
2757
2758
2759
2760
          assert( pHist->pOrig==0 );
          pHist->pOrig = sqliteMallocRaw( pPager->pageSize );
          if( pHist->pOrig ){
            memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
          }
        }else{
          u32 cksum;




          CODEC(pPager, pData, pPg->pgno, 7);
          cksum = pager_cksum(pPager, pPg->pgno, pData);
          saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
          store32bits(cksum, pPg, pPager->pageSize);
          szPg = pPager->pageSize+8;
          store32bits(pPg->pgno, pPg, -4);
          rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
          pPager->journalOff += szPg;
          TRACE4("JOURNAL %d page %d needSync=%d\n",
                  PAGERID(pPager), pPg->pgno, pPg->needSync);
          CODEC(pPager, pData, pPg->pgno, 0);
          *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
          if( rc!=SQLITE_OK ){
            sqlite3pager_rollback(pPager);
            pPager->errMask |= PAGER_ERR_FULL;


            return rc;
          }
          pPager->nRec++;
          assert( pPager->aInJournal!=0 );
          pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
          pPg->needSync = !pPager->noSync;
          if( pPager->stmtInUse ){
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
        if( pHist->pStmt ){
          memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize);
        }
        TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
      }else{
        store32bits(pPg->pgno, pPg, -4);
        CODEC(pPager, pData, pPg->pgno, 7);
        rc = sqlite3OsWrite(pPager->stfd,((char*)pData)-4,
                               pPager->pageSize+4);
        TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
        CODEC(pPager, pData, pPg->pgno, 0);
        if( rc!=SQLITE_OK ){
          sqlite3pager_rollback(pPager);
          if( !pPager->errCode ){
            pager_error(pPager, SQLITE_FULL);
          }
          return rc;
        }
        pPager->stmtNRec++;
        assert( pPager->aInStmt!=0 );
        pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
      }
      page_add_to_stmt_list(pPg);







|
<




|
<
<







2787
2788
2789
2790
2791
2792
2793
2794

2795
2796
2797
2798
2799


2800
2801
2802
2803
2804
2805
2806
        if( pHist->pStmt ){
          memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize);
        }
        TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
      }else{
        store32bits(pPg->pgno, pPg, -4);
        CODEC(pPager, pData, pPg->pgno, 7);
        rc = sqlite3OsWrite(&pPager->stfd,((char*)pData)-4, pPager->pageSize+4);

        TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
        CODEC(pPager, pData, pPg->pgno, 0);
        if( rc!=SQLITE_OK ){
          sqlite3pager_rollback(pPager);
          pPager->errMask |= PAGER_ERR_FULL;


          return rc;
        }
        pPager->stmtNRec++;
        assert( pPager->aInStmt!=0 );
        pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
      }
      page_add_to_stmt_list(pPg);
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
  PgHdr *pPg;

  if( MEMDB ) return;

  pPg = pager_lookup(pPager, pgno);
  pPg->alwaysRollback = 1;
  if( pPg && pPg->dirty && !pPager->stmtInUse ){
    if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
      /* If this pages is the last page in the file and the file has grown
      ** during the current transaction, then do NOT mark the page as clean.
      ** When the database file grows, we must make sure that the last page
      ** gets written at least once so that the disk file will be the correct
      ** size. If you do not write this page and the size of the file
      ** on the disk ends up being too small, that can lead to database







|







2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){
  PgHdr *pPg;

  if( MEMDB ) return;

  pPg = pager_lookup(pPager, pgno);
  pPg->alwaysRollback = 1;
  if( pPg && pPg->dirty ){
    if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
      /* If this pages is the last page in the file and the file has grown
      ** during the current transaction, then do NOT mark the page as clean.
      ** When the database file grows, we must make sure that the last page
      ** gets written at least once so that the disk file will be the correct
      ** size. If you do not write this page and the size of the file
      ** on the disk ends up being too small, that can lead to database
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
** and an error code is returned.  If the commit worked, SQLITE_OK
** is returned.
*/
int sqlite3pager_commit(Pager *pPager){
  int rc;
  PgHdr *pPg;

  if( pPager->errCode==SQLITE_FULL ){
    rc = sqlite3pager_rollback(pPager);
    if( rc==SQLITE_OK ){
      rc = SQLITE_FULL;
    }
    return rc;
  }
  if( pPager->errCode ){
    rc = pPager->errCode;
    return rc;
  }
  if( pPager->state<PAGER_RESERVED ){
    return SQLITE_ERROR;
  }
  TRACE2("COMMIT %d\n", PAGERID(pPager));
  if( MEMDB ){







|






|
|







2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
** and an error code is returned.  If the commit worked, SQLITE_OK
** is returned.
*/
int sqlite3pager_commit(Pager *pPager){
  int rc;
  PgHdr *pPg;

  if( pPager->errMask==PAGER_ERR_FULL ){
    rc = sqlite3pager_rollback(pPager);
    if( rc==SQLITE_OK ){
      rc = SQLITE_FULL;
    }
    return rc;
  }
  if( pPager->errMask!=0 ){
    rc = pager_errcode(pPager);
    return rc;
  }
  if( pPager->state<PAGER_RESERVED ){
    return SQLITE_ERROR;
  }
  TRACE2("COMMIT %d\n", PAGERID(pPager));
  if( MEMDB ){
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376

  if( !pPager->dirtyCache || !pPager->journalOpen ){
    rc = pager_unwritelock(pPager);
    pPager->dbSize = -1;
    return rc;
  }

  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
    if( pPager->state>=PAGER_EXCLUSIVE ){
      pager_playback(pPager);
    }
    return pPager->errCode;
  }
  if( pPager->state==PAGER_RESERVED ){
    int rc2;
    rc = pager_reload_cache(pPager);
    rc2 = pager_unwritelock(pPager);
    if( rc==SQLITE_OK ){
      rc = rc2;
    }
  }else{
    rc = pager_playback(pPager);
  }
  if( rc!=SQLITE_OK ){
    rc = SQLITE_CORRUPT_BKPT;
    pager_error(pPager, SQLITE_CORRUPT);
  }
  pPager->dbSize = -1;
  return rc;
}

/*
** Return TRUE if the database file is opened read-only.  Return FALSE







|



|












|
|







3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103

  if( !pPager->dirtyCache || !pPager->journalOpen ){
    rc = pager_unwritelock(pPager);
    pPager->dbSize = -1;
    return rc;
  }

  if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
    if( pPager->state>=PAGER_EXCLUSIVE ){
      pager_playback(pPager);
    }
    return pager_errcode(pPager);
  }
  if( pPager->state==PAGER_RESERVED ){
    int rc2;
    rc = pager_reload_cache(pPager);
    rc2 = pager_unwritelock(pPager);
    if( rc==SQLITE_OK ){
      rc = rc2;
    }
  }else{
    rc = pager_playback(pPager);
  }
  if( rc!=SQLITE_OK ){
    rc = SQLITE_CORRUPT;  /* bkpt-CORRUPT */
    pPager->errMask |= PAGER_ERR_CORRUPT;
  }
  pPager->dbSize = -1;
  return rc;
}

/*
** Return TRUE if the database file is opened read-only.  Return FALSE
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
int *sqlite3pager_stats(Pager *pPager){
  static int a[11];
  a[0] = pPager->nRef;
  a[1] = pPager->nPage;
  a[2] = pPager->mxPage;
  a[3] = pPager->dbSize;
  a[4] = pPager->state;
  a[5] = pPager->errCode;
#ifdef SQLITE_TEST
  a[6] = pPager->nHit;
  a[7] = pPager->nMiss;
  a[8] = pPager->nOvfl;
  a[9] = pPager->nRead;
  a[10] = pPager->nWrite;
#endif
  return a;
}

/*
** Set the statement rollback point.
**
** This routine should be called with the transaction journal already







|
<





<







3113
3114
3115
3116
3117
3118
3119
3120

3121
3122
3123
3124
3125

3126
3127
3128
3129
3130
3131
3132
int *sqlite3pager_stats(Pager *pPager){
  static int a[11];
  a[0] = pPager->nRef;
  a[1] = pPager->nPage;
  a[2] = pPager->mxPage;
  a[3] = pPager->dbSize;
  a[4] = pPager->state;
  a[5] = pPager->errMask;

  a[6] = pPager->nHit;
  a[7] = pPager->nMiss;
  a[8] = pPager->nOvfl;
  a[9] = pPager->nRead;
  a[10] = pPager->nWrite;

  return a;
}

/*
** Set the statement rollback point.
**
** This routine should be called with the transaction journal already
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
  if( !pPager->journalOpen ){
    pPager->stmtAutoopen = 1;
    return SQLITE_OK;
  }
  assert( pPager->journalOpen );
  pPager->aInStmt = sqliteMalloc( pPager->dbSize/8 + 1 );
  if( pPager->aInStmt==0 ){
    /* sqlite3OsLock(pPager->fd, SHARED_LOCK); */
    return SQLITE_NOMEM;
  }
#ifndef NDEBUG
  rc = sqlite3OsFileSize(pPager->jfd, &pPager->stmtJSize);
  if( rc ) goto stmt_begin_failed;
  assert( pPager->stmtJSize == pPager->journalOff );
#endif
  pPager->stmtJSize = pPager->journalOff;
  pPager->stmtSize = pPager->dbSize;
  pPager->stmtHdrOff = 0;
  pPager->stmtCksum = pPager->cksumInit;







|



|







3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
  if( !pPager->journalOpen ){
    pPager->stmtAutoopen = 1;
    return SQLITE_OK;
  }
  assert( pPager->journalOpen );
  pPager->aInStmt = sqliteMalloc( pPager->dbSize/8 + 1 );
  if( pPager->aInStmt==0 ){
    sqlite3OsLock(&pPager->fd, SHARED_LOCK);
    return SQLITE_NOMEM;
  }
#ifndef NDEBUG
  rc = sqlite3OsFileSize(&pPager->jfd, &pPager->stmtJSize);
  if( rc ) goto stmt_begin_failed;
  assert( pPager->stmtJSize == pPager->journalOff );
#endif
  pPager->stmtJSize = pPager->journalOff;
  pPager->stmtSize = pPager->dbSize;
  pPager->stmtHdrOff = 0;
  pPager->stmtCksum = pPager->cksumInit;
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
** Commit a statement.
*/
int sqlite3pager_stmt_commit(Pager *pPager){
  if( pPager->stmtInUse ){
    PgHdr *pPg, *pNext;
    TRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
    if( !MEMDB ){
      sqlite3OsSeek(pPager->stfd, 0);
      /* sqlite3OsTruncate(pPager->stfd, 0); */
      sqliteFree( pPager->aInStmt );
      pPager->aInStmt = 0;
    }
    for(pPg=pPager->pStmt; pPg; pPg=pNext){
      pNext = pPg->pNextStmt;
      assert( pPg->inStmt );
      pPg->inStmt = 0;







|
|







3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
** Commit a statement.
*/
int sqlite3pager_stmt_commit(Pager *pPager){
  if( pPager->stmtInUse ){
    PgHdr *pPg, *pNext;
    TRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
    if( !MEMDB ){
      sqlite3OsSeek(&pPager->stfd, 0);
      /* sqlite3OsTruncate(&pPager->stfd, 0); */
      sqliteFree( pPager->aInStmt );
      pPager->aInStmt = 0;
    }
    for(pPg=pPager->pStmt; pPg; pPg=pNext){
      pNext = pPg->pNextStmt;
      assert( pPg->inStmt );
      pPg->inStmt = 0;
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
/*
** Return the full pathname of the journal file.
*/
const char *sqlite3pager_journalname(Pager *pPager){
  return pPager->zJournal;
}

/*
** Return true if fsync() calls are disabled for this pager.  Return FALSE
** if fsync()s are executed normally.
*/
int sqlite3pager_nosync(Pager *pPager){
  return pPager->noSync;
}

/*
** Set the codec for this pager
*/
void sqlite3pager_set_codec(
  Pager *pPager,
  void (*xCodec)(void*,void*,Pgno,int),
  void *pCodecArg







<
<
<
<
<
<
<
<







3260
3261
3262
3263
3264
3265
3266








3267
3268
3269
3270
3271
3272
3273
/*
** Return the full pathname of the journal file.
*/
const char *sqlite3pager_journalname(Pager *pPager){
  return pPager->zJournal;
}









/*
** Set the codec for this pager
*/
void sqlite3pager_set_codec(
  Pager *pPager,
  void (*xCodec)(void*,void*,Pgno,int),
  void *pCodecArg
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
      if( nTrunc!=0 ){
        /* If this transaction has made the database smaller, then all pages
        ** being discarded by the truncation must be written to the journal
        ** file.
        */
        Pgno i;
        void *pPage;
        int iSkip = PAGER_MJ_PGNO(pPager);
        for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
          if( !(pPager->aInJournal[i/8] & (1<<(i&7))) && i!=iSkip ){
            rc = sqlite3pager_get(pPager, i, &pPage);
            if( rc!=SQLITE_OK ) goto sync_exit;
            rc = sqlite3pager_write(pPage);
            sqlite3pager_unref(pPage);
            if( rc!=SQLITE_OK ) goto sync_exit;
          }
        } 







<

|







3348
3349
3350
3351
3352
3353
3354

3355
3356
3357
3358
3359
3360
3361
3362
3363
      if( nTrunc!=0 ){
        /* If this transaction has made the database smaller, then all pages
        ** being discarded by the truncation must be written to the journal
        ** file.
        */
        Pgno i;
        void *pPage;

        for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
          if( !(pPager->aInJournal[i/8] & (1<<(i&7))) ){
            rc = sqlite3pager_get(pPager, i, &pPage);
            if( rc!=SQLITE_OK ) goto sync_exit;
            rc = sqlite3pager_write(pPage);
            sqlite3pager_unref(pPage);
            if( rc!=SQLITE_OK ) goto sync_exit;
          }
        } 
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
    /* Write all dirty pages to the database file */
    pPg = pager_get_all_dirty_pages(pPager);
    rc = pager_write_pagelist(pPg);
    if( rc!=SQLITE_OK ) goto sync_exit;

    /* Sync the database file. */
    if( !pPager->noSync ){
      rc = sqlite3OsSync(pPager->fd, 0);
    }

    pPager->state = PAGER_SYNCED;
  }

sync_exit:
  return rc;







|







3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
    /* Write all dirty pages to the database file */
    pPg = pager_get_all_dirty_pages(pPager);
    rc = pager_write_pagelist(pPg);
    if( rc!=SQLITE_OK ) goto sync_exit;

    /* Sync the database file. */
    if( !pPager->noSync ){
      rc = sqlite3OsSync(&pPager->fd);
    }

    pPager->state = PAGER_SYNCED;
  }

sync_exit:
  return rc;
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703

3704
3705
3706
3707
3708
3709
3710
** by this routine. The same applies to the page pData refers to on entry to
** this routine.
**
** References to the page refered to by pData remain valid. Updating any
** meta-data associated with page pData (i.e. data stored in the nExtra bytes
** allocated along with the page) is the responsibility of the caller.
**
** A transaction must be active when this routine is called. It used to be
** required that a statement transaction was not active, but this restriction
** has been removed (CREATE INDEX needs to move a page when a statement
** transaction is active).
*/
int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){
  PgHdr *pPg = DATA_TO_PGHDR(pData);
  PgHdr *pPgOld; 
  int h;
  Pgno needSyncPgno = 0;


  assert( pPg->nRef>0 );

  TRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", 
      PAGERID(pPager), pPg->pgno, pPg->needSync, pgno);

  if( pPg->needSync ){
    needSyncPgno = pPg->pgno;







|
|
<
<







>







3402
3403
3404
3405
3406
3407
3408
3409
3410


3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
** by this routine. The same applies to the page pData refers to on entry to
** this routine.
**
** References to the page refered to by pData remain valid. Updating any
** meta-data associated with page pData (i.e. data stored in the nExtra bytes
** allocated along with the page) is the responsibility of the caller.
**
** A transaction must be active when this routine is called, however it is 
** illegal to call this routine if a statment transaction is active.


*/
int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){
  PgHdr *pPg = DATA_TO_PGHDR(pData);
  PgHdr *pPgOld; 
  int h;
  Pgno needSyncPgno = 0;

  assert( !pPager->stmtInUse );
  assert( pPg->nRef>0 );

  TRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", 
      PAGERID(pPager), pPg->pgno, pPg->needSync, pgno);

  if( pPg->needSync ){
    needSyncPgno = pPg->pgno;
3777
3778
3779
3780
3781
3782
3783



3784

3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Return the current state of the file lock for the given pager.
** The return value is one of NO_LOCK, SHARED_LOCK, RESERVED_LOCK,
** PENDING_LOCK, or EXCLUSIVE_LOCK.
*/
int sqlite3pager_lockstate(Pager *pPager){



  return sqlite3OsLockState(pPager->fd);

}
#endif

#ifdef SQLITE_DEBUG
/*
** Print a listing of all referenced pages and their ref count.
*/
void sqlite3pager_refdump(Pager *pPager){
  PgHdr *pPg;
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    if( pPg->nRef<=0 ) continue;
    sqlite3DebugPrintf("PAGE %3d addr=%p nRef=%d\n", 
       pPg->pgno, PGHDR_TO_DATA(pPg), pPg->nRef);
  }
}
#endif

#endif /* SQLITE_OMIT_DISKIO */







>
>
>
|
>
















<
<
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519


#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Return the current state of the file lock for the given pager.
** The return value is one of NO_LOCK, SHARED_LOCK, RESERVED_LOCK,
** PENDING_LOCK, or EXCLUSIVE_LOCK.
*/
int sqlite3pager_lockstate(Pager *pPager){
#ifdef OS_TEST
  return pPager->fd->fd.locktype;
#else
  return pPager->fd.locktype;
#endif
}
#endif

#ifdef SQLITE_DEBUG
/*
** Print a listing of all referenced pages and their ref count.
*/
void sqlite3pager_refdump(Pager *pPager){
  PgHdr *pPg;
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    if( pPg->nRef<=0 ) continue;
    sqlite3DebugPrintf("PAGE %3d addr=%p nRef=%d\n", 
       pPg->pgno, PGHDR_TO_DATA(pPg), pPg->nRef);
  }
}
#endif


Changes to SQLite.Interop/src/pager.h.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem.  The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.16 2006/01/16 15:51:47 rmsimpson Exp $
*/

#ifndef _PAGER_H_
#define _PAGER_H_

/*
** The default size of a database page.
*/
#ifndef SQLITE_DEFAULT_PAGE_SIZE
# define SQLITE_DEFAULT_PAGE_SIZE 1024
#endif

/* Maximum page size.  The upper bound on this value is 32768.  This a limit
** imposed by necessity of storing the value in a 2-byte unsigned integer
** and the fact that the page size must be a power of 2.
**
** This value is used to initialize certain arrays on the stack at
** various places in the code.  On embedded machines where stack space
** is limited and the flexibility of having large pages is not needed,

** it makes good sense to reduce the maximum page size to something more
** reasonable, like 1024.
*/
#ifndef SQLITE_MAX_PAGE_SIZE
# define SQLITE_MAX_PAGE_SIZE 32768
#endif

/*
** Maximum number of pages in one database.
*/
#define SQLITE_MAX_PAGE 1073741823








|


<
<
<







|
|
|
<
<
|
<
>
|
<


|







9
10
11
12
13
14
15
16
17
18



19
20
21
22
23
24
25
26
27
28


29

30
31

32
33
34
35
36
37
38
39
40
41
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem.  The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.1 2005/03/01 16:04:31 rmsimpson Exp $
*/




/*
** The default size of a database page.
*/
#ifndef SQLITE_DEFAULT_PAGE_SIZE
# define SQLITE_DEFAULT_PAGE_SIZE 1024
#endif

/* Maximum page size.  The upper bound on this value is 65536 (a limit
** imposed by the 2-byte size of cell array pointers.)  The
** maximum page size determines the amount of stack space allocated


** by many of the routines in pager.c and btree.c  On embedded architectures

** or any machine where memory and especially stack memory is limited,
** one may wish to chose a smaller value for the maximum page size.

*/
#ifndef SQLITE_MAX_PAGE_SIZE
# define SQLITE_MAX_PAGE_SIZE 8192
#endif

/*
** Maximum number of pages in one database.
*/
#define SQLITE_MAX_PAGE 1073741823

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
** routines:
*/
int sqlite3pager_open(Pager **ppPager, const char *zFilename,
                     int nExtra, int flags);
void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler);
void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int));
int sqlite3pager_set_pagesize(Pager*, int);
void sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
void sqlite3pager_set_cachesize(Pager*, int);
int sqlite3pager_close(Pager *pPager);
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);
void *sqlite3pager_lookup(Pager *pPager, Pgno pgno);
int sqlite3pager_ref(void*);
int sqlite3pager_unref(void*);







|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
** routines:
*/
int sqlite3pager_open(Pager **ppPager, const char *zFilename,
                     int nExtra, int flags);
void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler);
void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int));
void sqlite3pager_set_pagesize(Pager*, int);
void sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
void sqlite3pager_set_cachesize(Pager*, int);
int sqlite3pager_close(Pager *pPager);
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);
void *sqlite3pager_lookup(Pager *pPager, Pgno pgno);
int sqlite3pager_ref(void*);
int sqlite3pager_unref(void*);
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
void sqlite3pager_dont_rollback(void*);
void sqlite3pager_dont_write(Pager*, Pgno);
int *sqlite3pager_stats(Pager*);
void sqlite3pager_set_safety_level(Pager*,int);
const char *sqlite3pager_filename(Pager*);
const char *sqlite3pager_dirname(Pager*);
const char *sqlite3pager_journalname(Pager*);
int sqlite3pager_nosync(Pager*);
int sqlite3pager_rename(Pager*, const char *zNewName);
void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);
int sqlite3pager_movepage(Pager*,void*,Pgno);
int sqlite3pager_reset(Pager*);
int sqlite3pager_release_memory(int);

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
int sqlite3pager_lockstate(Pager*);
#endif

#ifdef SQLITE_TEST
void sqlite3pager_refdump(Pager*);
int pager3_refinfo_enable;
#endif

#endif /* _PAGER_H_ */







<



<
<









<
<
93
94
95
96
97
98
99

100
101
102


103
104
105
106
107
108
109
110
111


void sqlite3pager_dont_rollback(void*);
void sqlite3pager_dont_write(Pager*, Pgno);
int *sqlite3pager_stats(Pager*);
void sqlite3pager_set_safety_level(Pager*,int);
const char *sqlite3pager_filename(Pager*);
const char *sqlite3pager_dirname(Pager*);
const char *sqlite3pager_journalname(Pager*);

int sqlite3pager_rename(Pager*, const char *zNewName);
void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);
int sqlite3pager_movepage(Pager*,void*,Pgno);



#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
int sqlite3pager_lockstate(Pager*);
#endif

#ifdef SQLITE_TEST
void sqlite3pager_refdump(Pager*);
int pager3_refinfo_enable;
#endif


Changes to SQLite.Interop/src/parse.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/* Driver template for the LEMON parser generator.
** The author disclaims copyright to this source code.
*/
/* First off, code is include which follows the "include" declaration
** in the input file. */
#include <stdio.h>
#line 51 "parse.y"

#include "sqliteInt.h"
#include "parse.h"

/*
** An instance of this structure holds information about the
** LIMIT clause of a SELECT statement.
*/
struct LimitVal {
  Expr *pLimit;    /* The LIMIT expression.  NULL if there is no limit */
  Expr *pOffset;   /* The OFFSET expression.  NULL if there is none */
};

/*
** An instance of this structure is used to store the LIKE,
** GLOB, NOT LIKE, and NOT GLOB operators.
*/
struct LikeOp {
  Token operator;  /* "like" or "glob" or "regexp" */
  int not;         /* True if the NOT keyword is present */
};

/*
** An instance of the following structure describes the event of a
** TRIGGER.  "a" is the event type, one of TK_UPDATE, TK_INSERT,
** TK_DELETE, or TK_INSTEAD.  If the event is of the form
**






|


















|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/* Driver template for the LEMON parser generator.
** The author disclaims copyright to this source code.
*/
/* First off, code is include which follows the "include" declaration
** in the input file. */
#include <stdio.h>
#line 33 "parse.y"

#include "sqliteInt.h"
#include "parse.h"

/*
** An instance of this structure holds information about the
** LIMIT clause of a SELECT statement.
*/
struct LimitVal {
  Expr *pLimit;    /* The LIMIT expression.  NULL if there is no limit */
  Expr *pOffset;   /* The OFFSET expression.  NULL if there is none */
};

/*
** An instance of this structure is used to store the LIKE,
** GLOB, NOT LIKE, and NOT GLOB operators.
*/
struct LikeOp {
  int opcode;   /* Either TK_GLOB or TK_LIKE */
  int not;      /* True if the NOT keyword is present */
};

/*
** An instance of the following structure describes the event of a
** TRIGGER.  "a" is the event type, one of TK_UPDATE, TK_INSERT,
** TK_DELETE, or TK_INSTEAD.  If the event is of the form
**
89
90
91
92
93
94
95
96
97
98
99
100



101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
**    sqlite3ParserARG_FETCH     Code to extract %extra_argument from yypParser
**    YYNSTATE           the combined number of states.
**    YYNRULE            the number of rules in the grammar
**    YYERRORSYMBOL      is the code number of the error symbol.  If not
**                       defined, then do no error processing.
*/
#define YYCODETYPE unsigned char
#define YYNOCODE 240
#define YYACTIONTYPE unsigned short int
#define sqlite3ParserTOKENTYPE Token
typedef union {
  sqlite3ParserTOKENTYPE yy0;



  struct {int value; int mask;} yy13;
  struct TrigEvent yy132;
  IdList* yy160;
  Expr* yy178;
  int yy230;
  Select* yy239;
  TriggerStep* yy247;
  struct LimitVal yy270;

  SrcList* yy285;
  Expr * yy292;
  Token yy384;
  struct LikeOp yy440;
  ExprList* yy462;
  int yy479;
} YYMINORTYPE;
#define YYSTACKDEPTH 100
#define sqlite3ParserARG_SDECL Parse *pParse;
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
#define YYNSTATE 561
#define YYNRULE 295
#define YYERRORSYMBOL 137
#define YYERRSYMDT yy479
#define YYFALLBACK 1
#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)

/* Next are that tables used to determine what action to take based on the
** current state and lookahead token.  These tables are used to implement







|




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






|
|
|
|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

107
108

109
110
111
112


113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
**    sqlite3ParserARG_FETCH     Code to extract %extra_argument from yypParser
**    YYNSTATE           the combined number of states.
**    YYNRULE            the number of rules in the grammar
**    YYERRORSYMBOL      is the code number of the error symbol.  If not
**                       defined, then do no error processing.
*/
#define YYCODETYPE unsigned char
#define YYNOCODE 239
#define YYACTIONTYPE unsigned short int
#define sqlite3ParserTOKENTYPE Token
typedef union {
  sqlite3ParserTOKENTYPE yy0;
  struct AttachKey yy40;
  int yy60;
  struct TrigEvent yy62;
  struct {int value; int mask;} yy243;
  struct LikeOp yy258;
  ExprList* yy266;

  IdList* yy272;
  Select* yy331;

  struct LimitVal yy348;
  Token yy406;
  SrcList* yy427;
  Expr* yy454;


  TriggerStep* yy455;
  int yy477;
} YYMINORTYPE;
#define YYSTACKDEPTH 100
#define sqlite3ParserARG_SDECL Parse *pParse;
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
#define YYNSTATE 564
#define YYNRULE 305
#define YYERRORSYMBOL 141
#define YYERRSYMDT yy477
#define YYFALLBACK 1
#define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)

/* Next are that tables used to determine what action to take based on the
** current state and lookahead token.  These tables are used to implement
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241









242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273














274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305



















306
307
308
309
310
311
312
313
314

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

332

333
334


335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

356
357
358
359
360






361


362
363
364
365
366











367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403














404



405



406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458









459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477



















478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495














496


497




498
499
500
501
502
503
504
505
506
507
508









509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584








585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622

623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642



643
644

645
646
647
648
649
650
651
**  yy_shift_ofst[]    For each state, the offset into yy_action for
**                     shifting terminals.
**  yy_reduce_ofst[]   For each state, the offset into yy_action for
**                     shifting non-terminals after a reduce.
**  yy_default[]       Default action for each state.
*/
static const YYACTIONTYPE yy_action[] = {
 /*     0 */   281,   67,  344,   80,  150,  157,  225,  517,   92,   92,
 /*    10 */    92,   92,  288,   59,   59,   59,   59,   58,   58,   57,
 /*    20 */    57,   57,   65,  346,  478,   48,  544,   86,   59,   59,
 /*    30 */    59,   59,   58,   58,   57,   57,   57,   65,   67,  481,
 /*    40 */    80,  150,  231,   64,   88,  295,  525,  518,  530,  530,
 /*    50 */    72,   72,   92,   92,   92,   92,  219,   59,   59,   59,
 /*    60 */    59,   58,   58,   57,   57,   57,   65,  281,  252,  189,
 /*    70 */   517,  296,  344,   81,   59,   59,   59,   59,   58,   58,
 /*    80 */    57,   57,   57,   65,  166,  115,  246,  303,  264,  323,
 /*    90 */   196,  236,  158,  544,  478,   49,  387,   69,  228,  857,
 /*   100 */   128,  560,  247,   56,    2,  381,   22,  476,  456,  363,
 /*   110 */    64,   88,  295,  525,  518,  530,  530,   72,   72,   92,
 /*   120 */    92,   92,   92,  283,   59,   59,   59,   59,   58,   58,
 /*   130 */    57,   57,   57,   65,  281,  344,  279,  386,  395,  553,
 /*   140 */   388,  165,  386,  276,  361,  288,  223,  439,  520,  451,
 /*   150 */   344,   58,   58,   57,   57,   57,   65,  478,   38,  365,
 /*   160 */   544,  145,  143,  282,   67,  393,   80,  150,  451,  500,
 /*   170 */   393,  189,  478,   36,  500,  424,  425,   64,   88,  295,
 /*   180 */   525,  518,  530,  530,   72,   72,   92,   92,   92,   92,
 /*   190 */    71,   59,   59,   59,   59,   58,   58,   57,   57,   57,
 /*   200 */    65,  281,  508,  508,  508,  429,  146,  508,  508,  508,
 /*   210 */   294,  512,  507,  198,  344,  520,  350,  357,  362,  246,
 /*   220 */   303,  264,  323,  196,  236,  283,  221,  544,  367,  310,
 /*   230 */   228,  228,   57,   57,   57,   65,  478,   48,  308,  299,
 /*   240 */   534,  537,  306,  417,   64,   88,  295,  525,  518,  530,
 /*   250 */   530,   72,   72,   92,   92,   92,   92,  551,   59,   59,
 /*   260 */    59,   59,   58,   58,   57,   57,   57,   65,  281,  550,
 /*   270 */   202,  416,  198,  375,  520,  350,  357,  362,  512,  507,
 /*   280 */   413,  414,  344,  293,  344,  372,   21,  367,  198,  522,
 /*   290 */   517,  350,  357,  362,  544,  359,  539,  371,  374,  126,
 /*   300 */   403,  209,  200,  367,  478,   18,  478,   43,  194,  169,
 /*   310 */   384,   64,   88,  295,  525,  518,  530,  530,   72,   72,
 /*   320 */    92,   92,   92,   92,  232,   59,   59,   59,   59,   58,
 /*   330 */    58,   57,   57,   57,   65,  511,  344,  512,  507,  427,
 /*   340 */   281,  420,  479,  479,  148,  419,  331,  233,  344,   67,
 /*   350 */   344,   80,  150,  517,  344,  176,  155,  309,  478,   32,
 /*   360 */   315,  436,  149,  184,  464,  195,  544,  348,   78,  533,
 /*   370 */   478,   51,  478,   51,  378,  428,  478,   51,  479,  443,
 /*   380 */   158,  377,   85,   64,   88,  295,  525,  518,  530,  530,
 /*   390 */    72,   72,   92,   92,   92,   92,  479,   59,   59,   59,
 /*   400 */    59,   58,   58,   57,   57,   57,   65,  281,  387,  467,
 /*   410 */   504,  162,   77,  324,  344,  290,  521,  457,   22,  300,
 /*   420 */   353,  520,  513,  513,  432,  487,   14,  487,  329,  271,
 /*   430 */   257,  487,  426,  544,  523,  524,  478,   51,  217,  208,
 /*   440 */   206,  144,  380,  355,  534,  537,  353,   55,  513,  513,
 /*   450 */    64,   88,  295,  525,  518,  530,  530,   72,   72,   92,
 /*   460 */    92,   92,   92,  375,   59,   59,   59,   59,   58,   58,
 /*   470 */    57,   57,   57,   65,  281,  372,   11,  127,   71,  218,
 /*   480 */   520,  241,  182,  126,  512,  507,  164,  155,  374,  520,
 /*   490 */   338,  488,  452,  398,  543,  353,  200,  513,  513,    1,
 /*   500 */   544,  401,  353,  520,  513,  513,  200,  553,  366,  165,
 /*   510 */   157,  463,  517,  358,  540,  538,  479,   64,   88,  295,
 /*   520 */   525,  518,  530,  530,   72,   72,   92,   92,   92,   92,
 /*   530 */   468,   59,   59,   59,   59,   58,   58,   57,   57,   57,
 /*   540 */    65,  370,  541,  512,  507,  437,  281,  344,  172,  506,
 /*   550 */   239,  344,  512,  507,  344,  387,  224,  448,   93,  344,
 /*   560 */    89,  344,  313,  344,  555,   22,  512,  507,  182,  478,
 /*   570 */    27,  520,  544,  478,   43,  517,  478,   50,  561,  547,
 /*   580 */   369,  478,   47,  478,  114,  478,   95,  528,   91,   64,
 /*   590 */    88,  295,  525,  518,  530,  530,   72,   72,   92,   92,
 /*   600 */    92,   92,  479,   59,   59,   59,   59,   58,   58,   57,
 /*   610 */    57,   57,   65,  281,  226,  344,  251,  174,  110,  344,
 /*   620 */   141,  147,  344,  465,  344,  449,  325,  370,  270,  344,
 /*   630 */   421,  344,  450,  554,  512,  507,    2,  478,   52,  544,









 /*   640 */   595,  478,   44,  311,  478,   30,  478,   45,  313,  173,
 /*   650 */   418,  478,   53,  478,   25,  479,   64,   88,  295,  525,
 /*   660 */   518,  530,  530,   72,   72,   92,   92,   92,   92,  344,
 /*   670 */    59,   59,   59,   59,   58,   58,   57,   57,   57,   65,
 /*   680 */   281,  344,  404,  479,  433,  344,  470,  344,  152,  344,
 /*   690 */   469,  478,  112,  344,  415,  314,  415,  344,  411,  344,
 /*   700 */   126,  287,  161,  478,   94,  440,  544,  478,  113,  478,
 /*   710 */    12,  478,   99,  401,  465,  478,   41,  292,  456,  478,
 /*   720 */   100,  478,   46,   64,   88,  295,  525,  518,  530,  530,
 /*   730 */    72,   72,   92,   92,   92,   92,  344,   59,   59,   59,
 /*   740 */    59,   58,   58,   57,   57,   57,   65,  281,  344,  485,
 /*   750 */    19,  404,  344,  514,  344,   79,  307,  260,  478,  111,
 /*   760 */   344,  242,  344,  548,  548,  344,  503,  501,  497,  466,
 /*   770 */   478,   42,  404,  544,  478,   26,  478,   39,  478,    3,
 /*   780 */   304,  423,  478,   31,  478,   40,  291,  478,   37,  305,
 /*   790 */    64,   88,  295,  525,  518,  530,  530,   72,   72,   92,
 /*   800 */    92,   92,   92,  344,   59,   59,   59,   59,   58,   58,
 /*   810 */    57,   57,   57,   65,  281,  344,  470,  404,  126,  344,
 /*   820 */   469,  344,   20,  344,  139,  478,   97,  344,  320,    7,
 /*   830 */   242,  344,  190,  181,  180,  208,  451,  478,   28,  258,
 /*   840 */   544,  478,   54,  478,   35,  478,   33,  222,  327,  478,
 /*   850 */    34,  262,  204,  478,   29,  435,  191,   64,   76,  295,
 /*   860 */   525,  518,  530,  530,   72,   72,   92,   92,   92,   92,
 /*   870 */   404,   59,   59,   59,   59,   58,   58,   57,   57,   57,
 /*   880 */    65,  281,  404,  454,  177,  162,  344,  208,  344,  175,
 /*   890 */   479,  320,  447,  235,  211,  794,  242,  286,  456,  516,
 /*   900 */   352,  441,  409,  410,  409,  298,  385,  544,  478,   24,
 /*   910 */   478,   98,  252,  252,  252,  252,  275,  284,  479,  252,
 /*   920 */   334,  252,  252,  479,  281,   88,  295,  525,  518,  530,
 /*   930 */   530,   72,   72,   92,   92,   92,   92,  274,   59,   59,
 /*   940 */    59,   59,   58,   58,   57,   57,   57,   65,  517,  242,
 /*   950 */   544,  244,  252,  237,  340,  215,  494,  214,  390,  546,














 /*   960 */   492,  242,  256,  489,  475,  406,   79,  397,  273,  295,
 /*   970 */   525,  518,  530,  530,   72,   72,   92,   92,   92,   92,
 /*   980 */   116,   59,   59,   59,   59,   58,   58,   57,   57,   57,
 /*   990 */    65,   62,  345,  484,    4,  407,  412,  269,  289,  126,
 /*  1000 */   519,  259,   23,  550,  202,  552,  349,   62,  345,  549,
 /*  1010 */     4,  517,  354,  493,  289,   14,  547,  369,  402,  316,
 /*  1020 */   240,  453,  349,  339,  472,  356,  142,  266,  471,  477,
 /*  1030 */   249,  319,  505,  386,  459,  343,  529,  428,  255,  339,
 /*  1040 */    71,  458,  499,  118,  333,  130,  121,  192,  389,  386,
 /*  1050 */   123,  156,   60,   61,  483,  103,   87,  125,  212,  480,
 /*  1060 */    62,  328,  330,  178,  277,  500,  229,  210,   60,   61,
 /*  1070 */   438,  297,  399,  491,  476,  473,   62,  328,  330,   62,
 /*  1080 */   345,  500,    4,  474,  208,  302,  289,  342,  207,  186,
 /*  1090 */   498,   68,  278,  120,  349,  136,  400,  556,  508,  508,
 /*  1100 */   508,  509,  510,   17,  312,  106,  243,  326,  205,  245,
 /*  1110 */   373,  339,  434,  285,  508,  508,  508,  509,  510,   17,
 /*  1120 */    74,  386,  160,  431,  248,    8,  321,  227,  220,  230,
 /*  1130 */   102,  332,  137,  382,  383,  536,  405,  234,   75,  183,
 /*  1140 */    60,   61,  317,  170,  265,  254,  135,  336,   62,  328,
 /*  1150 */   330,  442,  267,  500,  263,   66,  318,  261,  201,  455,
 /*  1160 */   447,   73,  461,  408,  168,  531,  443,   83,  482,  446,
 /*  1170 */   376,  171,  396,  167,  444,  542,  545,  208,  238,  272,
 /*  1180 */   213,  163,  188,  101,  364,   96,  508,  508,  508,  509,
 /*  1190 */   510,   17,  490,   63,  270,  322,  153,  105,  335,  535,
 /*  1200 */   526,  108,  558,  394,  527,  532,  250,  515,  379,  391,
 /*  1210 */    13,  368,  557,  107,  351,  337,  216,  257,   82,  132,
 /*  1220 */   559,  280,  109,  179,  347,  140,  208,  159,   65,  185,
 /*  1230 */   502,  341,  268,  193,  392,  131,  129,  203,  496,  151,
 /*  1240 */    10,  104,  154,  430,  486,  138,  253,  199,  495,  422,
 /*  1250 */   360,  162,  445,    5,   15,  597,    9,  187,  117,  122,
 /*  1260 */   596,  119,  133,   16,    6,  124,  301,  134,   14,   90,
 /*  1270 */    70,  462,   84,  460,  197,



















};
static const YYCODETYPE yy_lookahead[] = {
 /*     0 */    16,  216,  146,  218,  219,   21,  146,   23,   68,   69,
 /*    10 */    70,   71,   16,   73,   74,   75,   76,   77,   78,   79,
 /*    20 */    80,   81,   82,  146,  168,  169,   42,   72,   73,   74,
 /*    30 */    75,   76,   77,   78,   79,   80,   81,   82,  216,  217,
 /*    40 */   218,  219,  146,   59,   60,   61,   62,   63,   64,   65,
 /*    50 */    66,   67,   68,   69,   70,   71,  146,   73,   74,   75,
 /*    60 */    76,   77,   78,   79,   80,   81,   82,   16,  146,   43,

 /*    70 */    86,  215,  146,   22,   73,   74,   75,   76,   77,   78,
 /*    80 */    79,   80,   81,   82,   88,   89,   90,   91,   92,   93,
 /*    90 */    94,   95,   22,   42,  168,  169,  146,   46,  102,  138,
 /*   100 */   139,  140,  152,   19,  143,  155,  156,   23,  160,  187,
 /*   110 */    59,   60,   61,   62,   63,   64,   65,   66,   67,   68,
 /*   120 */    69,   70,   71,   97,   73,   74,   75,   76,   77,   78,
 /*   130 */    79,   80,   81,   82,   16,  146,  157,   58,   20,  160,
 /*   140 */   161,  162,   58,  189,   16,   16,  220,  199,   23,  146,
 /*   150 */   146,   77,   78,   79,   80,   81,   82,  168,  169,  237,
 /*   160 */    42,   77,   78,  149,  216,   86,  218,  219,  146,   90,
 /*   170 */    86,   43,  168,  169,   90,   89,   90,   59,   60,   61,
 /*   180 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
 /*   190 */   120,   73,   74,   75,   76,   77,   78,   79,   80,   81,
 /*   200 */    82,   16,  123,  124,  125,   20,   22,  123,  124,  125,
 /*   210 */   207,   86,   87,   88,  146,   23,   91,   92,   93,   90,
 /*   220 */    91,   92,   93,   94,   95,   97,  146,   42,  103,  207,
 /*   230 */   102,  102,   79,   80,   81,   82,  168,  169,  224,  163,

 /*   240 */   164,  165,  228,  177,   59,   60,   61,   62,   63,   64,

 /*   250 */    65,   66,   67,   68,   69,   70,   71,  146,   73,   74,
 /*   260 */    75,   76,   77,   78,   79,   80,   81,   82,   16,   77,


 /*   270 */    78,  177,   88,   12,   23,   91,   92,   93,   86,   87,
 /*   280 */    51,   52,  146,  215,  146,   24,   19,  103,   88,   97,
 /*   290 */    23,   91,   92,   93,   42,  141,  142,   20,   37,   22,
 /*   300 */    39,  147,  226,  103,  168,  169,  168,  169,  154,  154,
 /*   310 */    49,   59,   60,   61,   62,   63,   64,   65,   66,   67,
 /*   320 */    68,   69,   70,   71,   14,   73,   74,   75,   76,   77,

 /*   330 */    78,   79,   80,   81,   82,   20,  146,   86,   87,  146,
 /*   340 */    16,   25,  188,  188,  154,   29,  208,  209,  146,  216,
 /*   350 */   146,  218,  219,   86,  146,  200,  201,   41,  168,  169,
 /*   360 */   205,   20,  154,   53,  113,   55,   42,  213,   44,  236,
 /*   370 */   168,  169,  168,  169,  175,  176,  168,  169,  188,   49,
 /*   380 */    22,  182,  130,   59,   60,   61,   62,   63,   64,   65,
 /*   390 */    66,   67,   68,   69,   70,   71,  188,   73,   74,   75,
 /*   400 */    76,   77,   78,   79,   80,   81,   82,   16,  146,   20,
 /*   410 */    20,   22,   21,  211,  146,  211,  146,  155,  156,  211,
 /*   420 */   105,   23,  107,  108,   20,  223,   22,  223,   98,   99,
 /*   430 */   100,  223,  177,   42,  164,  165,  168,  169,   14,  109,
 /*   440 */   191,  179,  180,  163,  164,  165,  105,  198,  107,  108,
 /*   450 */    59,   60,   61,   62,   63,   64,   65,   66,   67,   68,
 /*   460 */    69,   70,   71,   12,   73,   74,   75,   76,   77,   78,
 /*   470 */    79,   80,   81,   82,   16,   24,   19,   53,  120,   55,

 /*   480 */    23,   20,  154,   22,   86,   87,  200,  201,   37,   23,
 /*   490 */    39,  223,  166,  167,   42,  105,  226,  107,  108,   19,
 /*   500 */    42,  175,  105,   23,  107,  108,  226,  160,  161,  162,
 /*   510 */    21,  113,   23,   16,   62,   63,  188,   59,   60,   61,
 /*   520 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,






 /*   530 */    22,   73,   74,   75,   76,   77,   78,   79,   80,   81,


 /*   540 */    82,  213,   90,   86,   87,   79,   16,  146,   19,  146,
 /*   550 */    20,  146,   86,   87,  146,  146,  132,  229,  129,  146,
 /*   560 */   131,  146,  234,  146,  155,  156,   86,   87,  154,  168,
 /*   570 */   169,   23,   42,  168,  169,   86,  168,  169,    0,    1,
 /*   580 */     2,  168,  169,  168,  169,  168,  169,   90,  130,   59,











 /*   590 */    60,   61,   62,   63,   64,   65,   66,   67,   68,   69,
 /*   600 */    70,   71,  188,   73,   74,   75,   76,   77,   78,   79,
 /*   610 */    80,   81,   82,   16,  209,  146,   90,  230,   21,  146,
 /*   620 */   112,  154,  146,   22,  146,   27,  231,  213,  102,  146,
 /*   630 */    30,  146,   34,  140,   86,   87,  143,  168,  169,   42,
 /*   640 */   111,  168,  169,  229,  168,  169,  168,  169,  234,  154,
 /*   650 */    50,  168,  169,  168,  169,  188,   59,   60,   61,   62,
 /*   660 */    63,   64,   65,   66,   67,   68,   69,   70,   71,  146,
 /*   670 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
 /*   680 */    16,  146,  146,  188,   20,  146,  106,  146,   87,  146,
 /*   690 */   110,  168,  169,  146,   98,   99,  100,  146,   20,  146,
 /*   700 */    22,  101,   19,  168,  169,  167,   42,  168,  169,  168,
 /*   710 */   169,  168,  169,  175,  113,  168,  169,  181,  160,  168,
 /*   720 */   169,  168,  169,   59,   60,   61,   62,   63,   64,   65,
 /*   730 */    66,   67,   68,   69,   70,   71,  146,   73,   74,   75,
 /*   740 */    76,   77,   78,   79,   80,   81,   82,   16,  146,  146,
 /*   750 */    67,  146,  146,   20,  146,   22,  146,  199,  168,  169,
 /*   760 */   146,  225,  146,  123,  124,  146,    7,    8,    9,  202,
 /*   770 */   168,  169,  146,   42,  168,  169,  168,  169,  168,  169,
 /*   780 */   146,   18,  168,  169,  168,  169,  181,  168,  169,   79,
 /*   790 */    59,   60,   61,   62,   63,   64,   65,   66,   67,   68,
 /*   800 */    69,   70,   71,  146,   73,   74,   75,   76,   77,   78,
 /*   810 */    79,   80,   81,   82,   16,  146,  106,  146,   22,  146,
 /*   820 */   110,  146,   19,  146,   21,  168,  169,  146,  146,  190,
 /*   830 */   225,  146,   98,   99,  100,  109,  146,  168,  169,  146,
 /*   840 */    42,  168,  169,  168,  169,  168,  169,  146,  122,  168,
 /*   850 */   169,  225,  181,  168,  169,   92,  154,   59,   60,   61,
 /*   860 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
 /*   870 */   146,   73,   74,   75,   76,   77,   78,   79,   80,   81,
 /*   880 */    82,   16,  146,   20,  154,   22,  146,  109,  146,  154,
 /*   890 */   188,  146,   96,  146,  212,  132,  225,  207,  160,  146,
 /*   900 */   122,  184,  185,  184,  185,  181,  146,   42,  168,  169,
 /*   910 */   168,  169,  146,  146,  146,  146,  146,  181,  188,  146,
 /*   920 */   146,  146,  146,  188,   16,   60,   61,   62,   63,   64,
 /*   930 */    65,   66,   67,   68,   69,   70,   71,  199,   73,   74,
 /*   940 */    75,   76,   77,   78,   79,   80,   81,   82,   23,  225,
 /*   950 */    42,  146,  146,  187,  187,  187,  187,  212,  159,  227,














 /*   960 */   187,  225,  187,  187,   20,  171,   22,  168,  146,   61,



 /*   970 */    62,   63,   64,   65,   66,   67,   68,   69,   70,   71,



 /*   980 */   146,   73,   74,   75,   76,   77,   78,   79,   80,   81,
 /*   990 */    82,   16,   17,  187,   19,    7,    8,   20,   23,   22,
 /*  1000 */    20,  171,   22,   77,   78,  160,   31,   16,   17,  227,
 /*  1010 */    19,   86,  172,   20,   23,   22,    1,    2,  171,  146,
 /*  1020 */   192,  146,   31,   48,  171,  146,  190,  144,  148,  171,
 /*  1030 */   146,  146,  193,   58,  146,  222,  146,  176,  146,   48,
 /*  1040 */   120,  193,  193,   59,   15,  183,  186,  111,  151,   58,
 /*  1050 */   186,    6,   77,   78,  145,   19,  129,  186,  221,  193,
 /*  1060 */    85,   86,   87,  151,  173,   90,   95,  210,   77,   78,
 /*  1070 */    79,   40,  178,  145,   23,  159,   85,   86,   87,   16,
 /*  1080 */    17,   90,   19,  145,  109,  151,   23,   15,  210,  150,
 /*  1090 */   197,  119,  173,   19,   31,  214,  159,  136,  123,  124,
 /*  1100 */   125,  126,  127,  128,   97,  238,  193,  117,  210,  194,
 /*  1110 */   170,   48,  170,  151,  123,  124,  125,  126,  127,  128,
 /*  1120 */   118,   58,    5,  170,  195,   22,  153,   10,   11,   12,
 /*  1130 */    13,  115,  214,  170,  170,   33,  151,  196,  235,  150,
 /*  1140 */    77,   78,   38,   26,  170,   28,  151,  151,   85,   86,
 /*  1150 */    87,  183,   35,   90,  232,   97,  114,  203,  210,  204,
 /*  1160 */    96,  129,  170,  233,   47,  145,   49,  235,  151,  172,
 /*  1170 */   170,   54,  178,   56,  204,  151,  151,  109,  135,  203,
 /*  1180 */   174,  183,  134,  174,   57,  158,  123,  124,  125,  126,
 /*  1190 */   127,  128,  188,   19,  102,  146,  146,   14,  185,    1,
 /*  1200 */    90,   19,  180,  168,   20,   20,   20,  106,  180,  168,
 /*  1210 */    19,   44,   20,   19,   44,   98,   99,  100,   19,  121,
 /*  1220 */     4,  104,   19,  111,    3,   19,  109,  121,   82,  111,
 /*  1230 */    11,   16,  146,   97,   17,  101,  112,   44,   20,   19,
 /*  1240 */     5,   19,  111,   20,   17,   21,  132,   22,   20,   45,
 /*  1250 */   133,   22,   11,  116,   22,  111,    1,  112,   32,   45,
 /*  1260 */   111,  101,   20,   19,  116,   97,   36,   19,   22,   67,
 /*  1270 */    19,  113,   67,   20,   94,
};
#define YY_SHIFT_USE_DFLT (-61)
#define YY_SHIFT_MAX 371
static const short yy_shift_ofst[] = {
 /*     0 */  1015,  975, 1117,  -16,  975, 1063, 1063, 1063,  125,  330,
 /*    10 */   330, 1068,  324, 1063, 1063, 1063, 1063, 1063,  -45,  192,
 /*    20 */   548,  926,  925,  926,   51,  391,  118,  185,  252,  458,
 /*    30 */   530,  597,  664,  731,  731,  731,  731,  731,  731,  731,
 /*    40 */   731,  731,  798,  731,  731,  731,  731,  731,  731,  731,
 /*    50 */   731,  731,  865,  908,  908,  991, 1063, 1063, 1063, 1063,
 /*    60 */  1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
 /*    70 */  1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
 /*    80 */  1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063,
 /*    90 */  1063, 1063, 1063, 1063,  -60,  -60,   -4,    1,    1,   74,
 /*   100 */   153,  128,  763,  548,  548,  548,  548,  548,  548,  548,
 /*   110 */   925, 1146,  -61,  -61,  -61,   84,  129,  261,  261,  548,
 /*   120 */   548,  548,  548,  548,  548,  548,  548,  548,  578,  548,
 /*   130 */   548,  548,  548,  489,  548,  489,  778,  726, 1068, 1068,
 /*   140 */  1068,  -61,  -61,   79,  184,   79,  200,  390,  341,  315,
 /*   150 */   480,  451,  251,  398,  466,  457,  548,  548,  548,  548,
 /*   160 */   759,  548,  548,  548,  601,  267,  548,  548,  548,  397,
 /*   170 */   548,  548,  710,  397,  596,  397,  601,  397,  316,  548,
 /*   180 */   600,  600,  397,  548,  548,  548,  548,  548,  548,  548,









 /*   190 */   600,  397,  548,  548,  397,  548,  548,  548,  548,  548,
 /*   200 */   640,  598,  640,  598,  796,  598,  508,  598,  580,  803,
 /*   210 */   598,   70,  429,   26,  358,  920,  984, 1029, 1029,  936,
 /*   220 */  1045,  920, 1036,  927, 1029,  936,  971, 1045, 1031, 1051,
 /*   230 */  1045,  936, 1072,  971,  972, 1036, 1051, 1074,  961, 1007,
 /*   240 */   920, 1007,  971,  990,  936, 1002, 1007, 1103, 1016, 1074,
 /*   250 */  1007, 1007,  936, 1072, 1102,  936, 1104,  984,  936, 1007,
 /*   260 */  1058, 1042,  971, 1032, 1007, 1064, 1045, 1102,  936, 1007,
 /*   270 */  1031,  984, 1042,  936, 1058,  936, 1068,  -61,  -61,  -61,
 /*   280 */   424,  452,  310,  734,  277,  683,  389,   86,  526,  529,
 /*   290 */   404,  461,  678,  733,  863,  497,  944,  988,  977,  980,
 /*   300 */   993,  229, 1136, 1193, 1222, 1223, 1235, 1131, 1114, 1204,
 /*   310 */  1229, 1241, 1226, 1255, 1214, 1242, 1160, 1230, 1248, 1202,
 /*   320 */  1205, 1253, 1158, 1251, 1246, 1168, 1148, 1244, 1149, 1145,
 /*   330 */  1144, 1232, 1137, 1227, 1228, 1225, 1224, 1124, 1218, 1220,
 /*   340 */  1134, 1217, 1215, 1219, 1118, 1206, 1112, 1216, 1098, 1199,
 /*   350 */  1170, 1194, 1191, 1101, 1186, 1185, 1184, 1182, 1110, 1198,
 /*   360 */  1183, 1092, 1174, 1127, 1048, 1043, 1192, 1167, 1203, 1221,
 /*   370 */  1106, 1180,



















};
#define YY_REDUCE_USE_DFLT (-216)
#define YY_REDUCE_MAX 279
static const short yy_reduce_ofst[] = {
 /*     0 */   -39,  208,  154,  -52,  190,  138,  202,  204,  262,  328,
 /*    10 */   414,  155,  133,   68,  268,  405, -144,  -74, -178,  270,
 /*    20 */   -50,   76,  -21,  280, -215, -215, -215, -215, -215, -215,
 /*    30 */  -215, -215, -215, -215, -215, -215, -215, -215, -215, -215,
 /*    40 */  -215, -215, -215, -215, -215, -215, -215, -215, -215, -215,
 /*    50 */  -215, -215, -215, -215, -215,  610,  606,  590,  551,  543,
 /*    60 */   539,  523,  483,  476,  469,  415,  408,  136,  740,  -11,
 /*    70 */   401,  413,  417,  473,  478,  485,  535,  541,  547,  553,
 /*    80 */   602,  608,  614,    4,  616,  619,  657,  669,  673,  675,
 /*    90 */   677,  681,  742,  685, -215, -215,  326, -215, -215, -215,
 /*   100 */  -215,  199,   14,  536,  605,  -78,  409,  671,  724,  736,
 /*   110 */   347, -215, -215, -215, -215,  799,  538,  719,  717,  745,
 /*   120 */   690,  806,   22,  776,  775,  773,  626,  769,  493,  768,
 /*   130 */   767,  682,  766,  738,    3,  558,  735,  730,  702,  495,














 /*   140 */   467,  286,  249, 1041, 1028, 1035, 1022,  -46,  -46,  -46,


 /*   150 */  1086, 1013, 1050, 1049, -123,  892,  890,  888,  885,  884,




 /*   160 */   883,  879,  875,  873,  567,  845,  834,  822,  805,  -46,
 /*   170 */   770,  753,  639,  -46,  395,  -46,  567,  -46,  387,  403,
 /*   180 */    94,   66,  -46, -104, -140, -123,  -90,   80,  111,  193,
 /*   190 */   255,  -46,  603,  634,  -46,  693,  701,  747,  760,  774,
 /*   200 */   732,  794,  782,  830,  840,  847,  828,  853,  836,  880,
 /*   210 */   858,  839,  813,  861,  848,  849,  862,  860,  864,  897,
 /*   220 */   909,  866,  891,  837,  871,  912,  857,  928,  894,  916,
 /*   230 */   938,  934,  939,  878,  893,  919,  937,  881,  867,  940,
 /*   240 */   913,  942,  898,  915,  962,  929,  953,  973,  941,  918,
 /*   250 */   963,  964,  985,  989,  903,  995,  922,  968,  996,  974,
 /*   260 */   954,  955,  948,  930,  992,  997, 1020,  932, 1017, 1000,









 /*   270 */   994,  998,  970, 1024,  976, 1025, 1004, 1006, 1009, 1027,
};
static const YYACTIONTYPE yy_default[] = {
 /*     0 */   567,  791,  856,  682,  856,  856,  791,  791,  856,  829,
 /*    10 */   829,  686,  842,  856,  791,  856,  856,  787,  762,  813,
 /*    20 */   856,  813,  598,  813,  717,  856,  856,  856,  856,  856,
 /*    30 */   856,  856,  856,  724,  782,  784,  846,  783,  718,  719,
 /*    40 */   725,  843,  856,  706,  827,  715,  730,  722,  731,  786,
 /*    50 */   698,  790,  752,  768,  751,  856,  856,  856,  856,  856,
 /*    60 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
 /*    70 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
 /*    80 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
 /*    90 */   856,  856,  856,  856,  773,  754,  591,  761,  753,  755,
 /*   100 */   756,  651,  586,  856,  856,  856,  856,  856,  856,  856,
 /*   110 */   856,  757,  769,  770,  758,  856,  856,  856,  856,  856,
 /*   120 */   856,  856,  856,  856,  856,  856,  856,  856,  567,  856,
 /*   130 */   856,  856,  856,  682,  856,  682,  856,  856,  856,  856,
 /*   140 */   856,  686,  676,  856,  642,  856,  856,  856,  856,  856,
 /*   150 */   856,  856,  856,  856,  856,  856,  572,  856,  856,  856,
 /*   160 */   574,  856,  856,  856,  684,  600,  856,  847,  856,  689,
 /*   170 */   849,  801,  674,  588,  856,  727,  690,  832,  819,  856,
 /*   180 */   856,  856,  834,  856,  856,  856,  856,  856,  856,  856,
 /*   190 */   856,  663,  856,  856,  665,  856,  856,  856,  856,  856,
 /*   200 */   856,  709,  856,  709,  624,  709,  683,  709,  674,  856,
 /*   210 */   709,  721,  785,  621,  721,  721,  655,  662,  662,  691,
 /*   220 */   571,  721,  795,  856,  662,  691,  710,  571,  638,  856,
 /*   230 */   571,  691,  583,  710,  716,  795,  856,  732,  854,  653,
 /*   240 */   721,  653,  710,  712,  691,  714,  653,  641,  702,  732,
 /*   250 */   653,  653,  691,  583,  845,  691,  823,  655,  691,  653,
 /*   260 */   699,  701,  710,  826,  653,  624,  571,  845,  691,  653,
 /*   270 */   638,  655,  701,  691,  699,  691,  856,  626,  626,  608,
 /*   280 */   856,  856,  856,  856,  856,  808,  856,  856,  856,  739,
 /*   290 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
 /*   300 */   856,  856,  856,  856,  856,  856,  856,  856,  856,  856,
 /*   310 */   822,  856,  856,  856,  821,  856,  856,  856,  856,  856,
 /*   320 */   856,  856,  856,  856,  713,  856,  856,  856,  744,  856,
 /*   330 */   740,  703,  856,  856,  856,  856,  856,  856,  856,  856,
 /*   340 */   856,  856,  856,  856,  856,  856,  741,  856,  856,  856,
 /*   350 */   856,  856,  856,  668,  856,  856,  856,  856,  856,  856,
 /*   360 */   856,  856,  856,  853,  856,  856,  856,  856,  856,  568,
 /*   370 */   856,  856,  838,  649,  839,  837,  648,  650,  652,  644,
 /*   380 */   645,  590,  647,  617,  659,  646,  750,  592,  599,  582,
 /*   390 */   615,  614,  584,  744,  613,  612,  636,  611,  610,  637,
 /*   400 */   623,  622,  798,  658,  799,  693,  797,  639,  815,  657,
 /*   410 */   654,  796,  640,  824,  825,  820,  631,  630,  635,  816,
 /*   420 */   817,  634,  818,  585,  633,  632,  629,  628,  627,  620,
 /*   430 */   749,  616,  748,  737,  792,  793,  777,  679,  678,  677,
 /*   440 */   609,  656,  728,  729,  688,  814,  618,  625,  828,  707,
 /*   450 */   708,  735,  607,  734,  700,  687,  681,  589,  830,  680,
 /*   460 */   587,  619,  697,  696,  695,  694,  685,  733,  675,  672,
 /*   470 */   673,  581,  705,  711,  580,  831,  593,  704,  736,  666,
 /*   480 */   833,  763,  779,  579,  660,  692,  661,  789,  788,  664,
 /*   490 */   667,  578,  800,  776,  840,  836,  835,  577,  671,  720,
 /*   500 */   738,  576,  781,  575,  780,  723,  742,  597,  743,  745,
 /*   510 */   746,  778,  596,  670,  726,  669,  802,  594,  774,  601,
 /*   520 */   595,  803,  804,  805,  806,  771,  767,  807,  765,  573,
 /*   530 */   764,  570,  602,  841,  605,  566,  844,  606,  775,  564,
 /*   540 */   772,  766,  848,  760,  759,  850,  809,  565,  811,  810,
 /*   550 */   812,  851,  604,  603,  562,  852,  855,  747,  643,  569,
 /*   560 */   563,
};
#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))

/* The next table maps tokens into fallback tokens.  If a construct
** like the following:
** 
**      %fallback ID X Y Z.
**
** appears in the grammer, then ID becomes a fallback token for X, Y,
** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
** but it does not parse, the type of the token is changed to ID and
** the parse is retried before an error is thrown.
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
    0,  /*          $ => nothing */








    0,  /*       SEMI => nothing */
   23,  /*    EXPLAIN => ID */
   23,  /*      QUERY => ID */
   23,  /*       PLAN => ID */
   23,  /*      BEGIN => ID */
    0,  /* TRANSACTION => nothing */
   23,  /*   DEFERRED => ID */
   23,  /*  IMMEDIATE => ID */
   23,  /*  EXCLUSIVE => ID */
    0,  /*     COMMIT => nothing */
   23,  /*        END => ID */
    0,  /*   ROLLBACK => nothing */
    0,  /*     CREATE => nothing */
    0,  /*      TABLE => nothing */
   23,  /*         IF => ID */
    0,  /*        NOT => nothing */
    0,  /*     EXISTS => nothing */
   23,  /*       TEMP => ID */
    0,  /*         LP => nothing */
    0,  /*         RP => nothing */
    0,  /*         AS => nothing */
    0,  /*      COMMA => nothing */
    0,  /*         ID => nothing */
   23,  /*      ABORT => ID */
   23,  /*      AFTER => ID */
   23,  /*    ANALYZE => ID */
   23,  /*        ASC => ID */
   23,  /*     ATTACH => ID */
   23,  /*     BEFORE => ID */
   23,  /*    CASCADE => ID */
   23,  /*       CAST => ID */
   23,  /*   CONFLICT => ID */
   23,  /*   DATABASE => ID */
   23,  /*       DESC => ID */
   23,  /*     DETACH => ID */
   23,  /*       EACH => ID */
   23,  /*       FAIL => ID */
   23,  /*        FOR => ID */

   23,  /*     IGNORE => ID */
   23,  /*  INITIALLY => ID */
   23,  /*    INSTEAD => ID */
   23,  /*    LIKE_KW => ID */
   23,  /*      MATCH => ID */
   23,  /*        KEY => ID */
   23,  /*         OF => ID */
   23,  /*     OFFSET => ID */
   23,  /*     PRAGMA => ID */
   23,  /*      RAISE => ID */
   23,  /*    REPLACE => ID */
   23,  /*   RESTRICT => ID */
   23,  /*        ROW => ID */
   23,  /*  STATEMENT => ID */
   23,  /*    TRIGGER => ID */
   23,  /*     VACUUM => ID */
   23,  /*       VIEW => ID */
   23,  /*    REINDEX => ID */
   23,  /*     RENAME => ID */
   23,  /*   CTIME_KW => ID */



    0,  /*         OR => nothing */
    0,  /*        AND => nothing */

    0,  /*         IS => nothing */
    0,  /*    BETWEEN => nothing */
    0,  /*         IN => nothing */
    0,  /*     ISNULL => nothing */
    0,  /*    NOTNULL => nothing */
    0,  /*         NE => nothing */
    0,  /*         EQ => nothing */







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


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

|
<

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

|
<

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


|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
















>
>
>
>
>
>
>
>

|
<
<
|

|
|
|

|



<
<
<
|





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


>







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250









251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287














288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335
336

337
338
339


340
341
342
343

344
345
346
347
348
349
350
351
352
353
354
355
356

357
358
359
360
361
362









363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398


399









400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475

476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504









505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535

536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678


679
680
681
682
683
684
685
686
687
688



689
690
691
692
693
694
695
696

697
698
699
700

701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
**  yy_shift_ofst[]    For each state, the offset into yy_action for
**                     shifting terminals.
**  yy_reduce_ofst[]   For each state, the offset into yy_action for
**                     shifting non-terminals after a reduce.
**  yy_default[]       Default action for each state.
*/
static const YYACTIONTYPE yy_action[] = {
 /*     0 */   263,  261,  261,  154,  124,  126,  128,  130,  132,  134,
 /*    10 */   136,  138,  140,  142,  350,  567,  145,  641,  261,  369,
 /*    20 */   144,  114,  116,  112,  118,    7,  124,  126,  128,  130,
 /*    30 */   132,  134,  136,  138,  140,  142,  136,  138,  140,  142,
 /*    40 */   110,   94,  146,  157,  162,  167,  156,  161,  120,  122,
 /*    50 */   114,  116,  112,  118,    9,  124,  126,  128,  130,  132,
 /*    60 */   134,  136,  138,  140,  142,  574,  223,  262,  262,  124,
 /*    70 */   126,  128,  130,  132,  134,  136,  138,  140,  142,   13,
 /*    80 */    96,  145,   13,    2,  262,  144,    4,   78,  371,   92,
 /*    90 */    10,  373,  380,  385,  132,  134,  136,  138,  140,  142,
 /*   100 */    75,    3,  562,  388,  296,  110,   94,  146,  157,  162,
 /*   110 */   167,  156,  161,  120,  122,  114,  116,  112,  118,   77,
 /*   120 */   124,  126,  128,  130,  132,  134,  136,  138,  140,  142,
 /*   130 */   145,   65,  573,   13,  144,   11,  371,   66,  292,  373,
 /*   140 */   380,  385,  870,    1,  563,   14,   15,    4,   14,   15,
 /*   150 */   172,  388,   51,  665,  110,   94,  146,  157,  162,  167,
 /*   160 */   156,  161,  120,  122,  114,  116,  112,  118,   72,  124,
 /*   170 */   126,  128,  130,  132,  134,  136,  138,  140,  142,   51,
 /*   180 */    37,  341,   40,   59,   67,   69,  305,  336,  107,  106,
 /*   190 */   108,  847,  572,   34,  338,   96,  366,  349,   13,   14,
 /*   200 */    15,  371,   12,  145,  373,  380,  385,  144,  564,   40,
 /*   210 */    59,   67,   69,  305,  336,   75,  388,    3,  562,  190,
 /*   220 */   345,  338,   44,   45,   95,  460,  802,  110,   94,  146,
 /*   230 */   157,  162,  167,  156,  161,  120,  122,  114,  116,  112,
 /*   240 */   118,  575,  124,  126,  128,  130,  132,  134,  136,  138,
 /*   250 */   140,  142,   20,   48,  800,  364,  362,  101,  102,  367,
 /*   260 */   499,  295,   49,  596,   14,   15,  191,   32,   33,   27,
 /*   270 */   148,  403,   96,   50,  147,  534,   46,  145,  494,  466,
 /*   280 */   456,  144,  580,  279,   36,  340,   47,  399,  309,   81,
 /*   290 */   368,  401,   75,  335,  398,  505,  176,  501,  150,  151,
 /*   300 */   197,  110,   94,  146,  157,  162,  167,  156,  161,  120,
 /*   310 */   122,  114,  116,  112,  118,   77,  124,  126,  128,  130,
 /*   320 */   132,  134,  136,  138,  140,  142,  149,  280,  258,  169,
 /*   330 */    96,   39,  281,   13,  298,  367,   96,  175,   22,  335,
 /*   340 */    28,  145,  188,  402,   33,  144,  217,    6,    5,  171,
 /*   350 */    75,  173,  174,   25,  176,  581,   75,   57,   58,  507,
 /*   360 */   235,  351,  356,  357,  265,  110,   94,  146,  157,  162,
 /*   370 */   167,  156,  161,  120,  122,  114,  116,  112,  118,  503,
 /*   380 */   124,  126,  128,  130,  132,  134,  136,  138,  140,  142,
 /*   390 */   457,   77,  243,  294,   48,  227,  236,  293,  297,   14,
 /*   400 */    15,  288,   96,   49,  217,  152,  222,  163,  168,  278,
 /*   410 */    24,   13,  687,   13,   50,  145,  518,  201,  152,  144,
 /*   420 */   163,  168,   75,  358,  582,  171,  176,  173,  174,  263,
 /*   430 */   171,  261,  173,  174,  354,  356,  357,  588,  211,  110,
 /*   440 */    94,  146,  157,  162,  167,  156,  161,  120,  122,  114,
 /*   450 */   116,  112,  118,  654,  124,  126,  128,  130,  132,  134,
 /*   460 */   136,  138,  140,  142,  303,   13,  688,   96,  250,  817,
 /*   470 */    96,   16,   17,   18,  246,   81,  216,   14,   15,   14,
 /*   480 */    15,  145,   13,  406,  435,  144,   13,   75,  487,  387,
 /*   490 */    75,  493,  248,  258,  235,  660,  358,  262,  310,  852,
 /*   500 */   171,   26,  173,  174,  253,  110,   94,  146,  157,  162,
 /*   510 */   167,  156,  161,  120,  122,  114,  116,  112,  118,  397,
 /*   520 */   124,  126,  128,  130,  132,  134,  136,  138,  140,  142,
 /*   530 */   229,   14,   15,  489,  250,  152,  252,  163,  168,  171,
 /*   540 */   839,  173,  174,  360,  361,   96,  145,  533,   14,   15,
 /*   550 */   144,  866,   14,   15,  801,  442,  312,  275,  255,  453,
 /*   560 */   850,  338,  251,  535,  536,   75,  662,  247,   13,  493,
 /*   570 */   110,   94,  146,  157,  162,  167,  156,  161,  120,  122,
 /*   580 */   114,  116,  112,  118,  845,  124,  126,  128,  130,  132,
 /*   590 */   134,  136,  138,  140,  142,  726,   96,  171,   96,  173,
 /*   600 */   174,  171,  252,  173,  174,  152,  583,  163,  168,   42,
 /*   610 */   720,  525,   96,  145,  441,  271,   75,  144,   75,  170,
 /*   620 */   302,  640,   91,   31,  358,  313,  320,  322,  251,  432,
 /*   630 */   434,  433,   75,  844,   14,   15,  176,  110,   94,  146,
 /*   640 */   157,  162,  167,  156,  161,  120,  122,  114,  116,  112,
 /*   650 */   118,   77,  124,  126,  128,  130,  132,  134,  136,  138,
 /*   660 */   140,  142,  171,   96,  173,  174,  331,   52,  171,   96,
 /*   670 */   173,  174,   96,  195,  213,  207,   29,  348,  145,   54,
 /*   680 */   310,  318,  144,   75,  455,  342,  217,   93,   83,   75,
 /*   690 */    30,  452,   75,  109,  587,  286,  111,  171,  265,  173,
 /*   700 */   174,  319,  110,   94,  146,  157,  162,  167,  156,  161,
 /*   710 */   120,  122,  114,  116,  112,  118,   77,  124,  126,  128,
 /*   720 */   130,  132,  134,  136,  138,  140,  142,  244,   96,  187,









 /*   730 */    96,   96,  810,  331,  214,  266,  215,   35,  312,   96,
 /*   740 */    96,  479,  328,  145,  623,   38,  327,  144,   75,  455,
 /*   750 */    75,   75,  113,  689,  115,  117,  315,  461,  426,   75,
 /*   760 */    75,   77,  463,  119,  121,  407,  325,  110,  165,  146,
 /*   770 */   157,  162,  167,  156,  161,  120,  122,  114,  116,  112,
 /*   780 */   118,   77,  124,  126,  128,  130,  132,  134,  136,  138,
 /*   790 */   140,  142,   42,   96,   96,   96,   96,  824,  273,  159,
 /*   800 */   415,   96,  410,  272,   96,  273,  479,   41,  145,  332,
 /*   810 */   537,   43,  144,   75,   75,   75,   75,  123,  125,  127,
 /*   820 */   129,   75,  465,   64,   75,  131,   53,  463,  133,  158,
 /*   830 */   317,  316,  265,   94,  146,  157,  162,  167,  156,  161,
 /*   840 */   120,  122,  114,  116,  112,  118,  219,  124,  126,  128,
 /*   850 */   130,  132,  134,  136,  138,  140,  142,   96,  689,   96,
 /*   860 */    96,  532,   96,  331,  299,   96,  215,   96,   96,  283,
 /*   870 */    96,  261,  219,   96,  145,   96,  840,   75,  144,   75,
 /*   880 */    75,  135,   75,  137,  139,   75,  141,   75,   75,  143,
 /*   890 */    75,  153,  155,   75,  164,   75,  376,  166,   56,  178,
 /*   900 */   146,  157,  162,  167,  156,  161,  120,  122,  114,  116,
 /*   910 */   112,  118,  652,  124,  126,  128,  130,  132,  134,  136,
 /*   920 */   138,  140,  142,   76,   96,   96,   96,   71,  438,  364,
 /*   930 */   362,  437,   96,   96,   96,   96,  331,  262,  233,  332,
 /*   940 */    96,   55,  331,  439,   75,   75,   75,  331,  180,  182,
 /*   950 */   184,  199,   75,   75,   75,   75,  196,  198,  208,  210,
 /*   960 */    75,  107,  106,  108,  212,  720,  326,  177,  327,  382,
 /*   970 */   430,  431,  107,  106,  108,  391,  548,   61,   96,   96,
 /*   980 */   449,  471,  458,   45,  183,  181,  300,   96,  476,  352,
 /*   990 */    96,  353,  179,   73,   74,  343,  346,   95,   75,   75,
 /*  1000 */   290,   96,  224,  240,  345,  275,   42,   75,   95,   76,
 /*  1010 */    75,  245,  332,   71,  277,  383,  275,  327,  332,   96,
 /*  1020 */    75,   75,  404,  332,  287,  386,   96,  392,  421,  327,
 /*  1030 */   101,  102,  103,  104,  105,  185,  189,  199,   96,   75,
 /*  1040 */    96,  101,  102,  427,  414,   60,   75,  107,  106,  108,
 /*  1050 */   474,  470,  486,  177,   77,  450,  421,  327,   75,  484,
 /*  1060 */    75,  273,  478,  436,  491,  492,  423,  490,  421,  421,
 /*  1070 */   183,  181,  421,  421,  483,  421,   77,  421,  179,   73,
 /*  1080 */    74,  476,  244,   95,   77,   81,  526,  860,  490,  421,
 /*  1090 */   689,  522,   62,   64,  500,   70,  597,   63,  523,   68,














 /*  1100 */   598,   76,   81,   79,   81,   71,  502,  504,   84,   80,
 /*  1110 */   506,  510,  244,  514,  239,  520,  101,  102,  103,  104,
 /*  1120 */   105,  185,  189,   77,  546,  241,   82,  558,   86,  199,
 /*  1130 */    85,  225,   90,   87,   97,   88,   99,  142,   89,  107,
 /*  1140 */   106,  108,  160,   98,  516,  177,  100,  218,  666,  667,
 /*  1150 */   668,  186,  209,  193,  192,  194,  200,  204,  203,  202,
 /*  1160 */   206,  205,  183,  181,  219,  220,  221,  226,  228,  232,
 /*  1170 */   179,   73,   74,  230,  233,   95,  234,  231,  237,  242,
 /*  1180 */   238,  215,  260,  249,  257,  276,  267,  254,  256,  259,
 /*  1190 */   264,  269,  270,   76,  274,  282,  301,   71,  219,  268,
 /*  1200 */   285,  291,  284,  306,  324,  307,  311,  308,  101,  102,
 /*  1210 */   103,  104,  105,  185,  189,  803,  355,  329,  375,  304,
 /*  1220 */   314,  199,  321,  337,  330,  365,  334,  372,  309,  333,
 /*  1230 */   323,  107,  106,  108,  344,  339,  347,  177,  374,  378,
 /*  1240 */   400,  359,  370,  377,  381,  379,  384,  389,  363,  390,
 /*  1250 */   393,  394,  396,   54,  183,  181,  289,  408,  395,  409,
 /*  1260 */   411,  413,  179,   73,   74,  412,  416,   95,  417,  420,
 /*  1270 */   428,  422,  832,  429,  443,  440,  444,  837,  838,   76,
 /*  1280 */   446,  445,  448,   71,  451,  808,  809,  459,  454,  447,
 /*  1290 */   418,  727,  728,  831,  464,  462,  846,  457,  469,  419,
 /*  1300 */   101,  102,  103,  104,  105,  185,  189,  199,  467,  468,
 /*  1310 */   472,  473,  475,  424,  848,  477,  480,  107,  106,  108,
 /*  1320 */   425,  482,  488,  177,  485,  849,  481,  495,  496,  851,
 /*  1330 */   659,  661,  816,  858,  497,  509,  511,  719,  513,  515,
 /*  1340 */   183,  181,  722,  517,  725,  519,  521,  524,  179,   73,
 /*  1350 */    74,  818,  528,   95,  530,  819,  820,  531,  538,  821,
 /*  1360 */     8,  822,  539,  823,  549,   19,   21,   23,  405,  541,
 /*  1370 */   542,  544,  543,  859,  547,  861,  862,  865,  545,  540,
 /*  1380 */   551,  867,  557,  555,  552,  550,  101,  102,  103,  104,
 /*  1390 */   105,  185,  189,  554,  560,  559,  561,  868,  529,  545,
 /*  1400 */   460,  545,  545,  545,  545,  527,  545,  553,  545,  545,
 /*  1410 */   545,  545,  556,  545,  545,  545,  545,  545,  545,  545,
 /*  1420 */   545,  545,  545,  545,  545,  545,  545,  545,  545,  545,
 /*  1430 */   545,  545,  545,  545,  545,  545,  545,  545,  545,  545,
 /*  1440 */   545,  545,  545,  545,  545,  545,  545,  545,  545,  545,
 /*  1450 */   545,  545,  545,  508,  512,  456,  545,  545,  545,  498,
 /*  1460 */   545,  545,  545,  545,   81,
};
static const YYCODETYPE yy_lookahead[] = {
 /*     0 */    24,   26,   26,   78,   79,   80,   81,   82,   83,   84,
 /*    10 */    85,   86,   87,   88,   22,    9,   40,   23,   26,   25,
 /*    20 */    44,   74,   75,   76,   77,    9,   79,   80,   81,   82,
 /*    30 */    83,   84,   85,   86,   87,   88,   85,   86,   87,   88,

 /*    40 */    64,   65,   66,   67,   68,   69,   70,   71,   72,   73,
 /*    50 */    74,   75,   76,   77,  148,   79,   80,   81,   82,   83,
 /*    60 */    84,   85,   86,   87,   88,    9,   25,   92,   92,   79,
 /*    70 */    80,   81,   82,   83,   84,   85,   86,   87,   88,   26,
 /*    80 */   150,   40,   26,  144,   92,   44,  147,  157,   94,   48,
 /*    90 */   149,   97,   98,   99,   83,   84,   85,   86,   87,   88,

 /*   100 */   170,    9,   10,  109,  174,   64,   65,   66,   67,   68,
 /*   110 */    69,   70,   71,   72,   73,   74,   75,   76,   77,  189,
 /*   120 */    79,   80,   81,   82,   83,   84,   85,   86,   87,   88,


 /*   130 */    40,   29,    9,   26,   44,   12,   94,   35,   85,   97,
 /*   140 */    98,   99,  142,  143,  144,   92,   93,  147,   92,   93,
 /*   150 */   112,  109,   66,  115,   64,   65,   66,   67,   68,   69,
 /*   160 */    70,   71,   72,   73,   74,   75,   76,   77,   22,   79,

 /*   170 */    80,   81,   82,   83,   84,   85,   86,   87,   88,   66,
 /*   180 */    94,   95,   96,   97,   98,   99,  100,  101,   60,   61,
 /*   190 */    62,   17,    9,  160,  108,  150,  163,  164,   26,   92,
 /*   200 */    93,   94,  150,   40,   97,   98,   99,   44,    0,   96,
 /*   210 */    97,   98,   99,  100,  101,  170,  109,    9,   10,  174,
 /*   220 */    92,  108,  186,  187,   96,   51,  136,   64,   65,   66,
 /*   230 */    67,   68,   69,   70,   71,   72,   73,   74,   75,   76,
 /*   240 */    77,    9,   79,   80,   81,   82,   83,   84,   85,   86,
 /*   250 */    87,   88,  149,   18,   17,   83,   84,  129,  130,  150,
 /*   260 */    20,   23,   27,  117,   92,   93,  221,  158,  159,   22,
 /*   270 */    40,   24,  150,   38,   44,  103,   41,   40,  104,  105,
 /*   280 */   106,   44,    9,  157,  168,  169,   51,  177,  178,  115,
 /*   290 */   181,  182,  170,  177,  184,   55,  174,   57,   68,   69,

 /*   300 */   137,   64,   65,   66,   67,   68,   69,   70,   71,   72,
 /*   310 */    73,   74,   75,   76,   77,  189,   79,   80,   81,   82,
 /*   320 */    83,   84,   85,   86,   87,   88,   96,  201,  202,   22,
 /*   330 */   150,  169,  206,   26,  212,  150,  150,   23,  149,  177,
 /*   340 */   155,   40,   23,  158,  159,   44,  224,  145,  146,  111,
 /*   350 */   170,  113,  114,  151,  174,    9,  170,   13,   14,  157,









 /*   360 */   174,  165,  166,  167,  163,   64,   65,   66,   67,   68,
 /*   370 */    69,   70,   71,   72,   73,   74,   75,   76,   77,  139,
 /*   380 */    79,   80,   81,   82,   83,   84,   85,   86,   87,   88,
 /*   390 */    64,  189,  212,  112,   18,  209,  210,  116,   23,   92,
 /*   400 */    93,  200,  150,   27,  224,  217,  218,  219,  220,   22,
 /*   410 */   149,   26,   23,   26,   38,   40,  214,   41,  217,   44,
 /*   420 */   219,  220,  170,  227,    9,  111,  174,  113,  114,   24,
 /*   430 */   111,   26,  113,  114,  165,  166,  167,    9,  137,   64,
 /*   440 */    65,   66,   67,   68,   69,   70,   71,   72,   73,   74,
 /*   450 */    75,   76,   77,  127,   79,   80,   81,   82,   83,   84,
 /*   460 */    85,   86,   87,   88,   23,   26,   23,  150,   25,    9,
 /*   470 */   150,   13,   14,   15,   25,  115,  224,   92,   93,   92,
 /*   480 */    93,   40,   26,  153,   47,   44,   26,  170,  128,  171,
 /*   490 */   170,  174,  201,  202,  174,    9,  227,   92,   45,    9,
 /*   500 */   111,  152,  113,  114,  119,   64,   65,   66,   67,   68,
 /*   510 */    69,   70,   71,   72,   73,   74,   75,   76,   77,   66,
 /*   520 */    79,   80,   81,   82,   83,   84,   85,   86,   87,   88,
 /*   530 */   210,   92,   93,  216,   25,  217,   93,  219,  220,  111,
 /*   540 */   103,  113,  114,  129,  130,  150,   40,  150,   92,   93,
 /*   550 */    44,    9,   92,   93,   17,  225,  103,  150,  119,  229,
 /*   560 */     9,  108,  119,  166,  167,  170,    9,  118,   26,  174,
 /*   570 */    64,   65,   66,   67,   68,   69,   70,   71,   72,   73,
 /*   580 */    74,   75,   76,   77,   11,   79,   80,   81,   82,   83,
 /*   590 */    84,   85,   86,   87,   88,    9,  150,  111,  150,  113,
 /*   600 */   114,  111,   93,  113,  114,  217,    9,  219,  220,  103,
 /*   610 */     9,  216,  150,   40,   21,  208,  170,   44,  170,  157,
 /*   620 */   174,   23,  174,   25,  227,  104,  105,  106,  119,  104,
 /*   630 */   105,  106,  170,   11,   92,   93,  174,   64,   65,   66,
 /*   640 */    67,   68,   69,   70,   71,   72,   73,   74,   75,   76,
 /*   650 */    77,  189,   79,   80,   81,   82,   83,   84,   85,   86,
 /*   660 */    87,   88,  111,  150,  113,  114,  150,   96,  111,  150,
 /*   670 */   113,  114,  150,  136,  212,  138,  156,  162,   40,  108,
 /*   680 */    45,   32,   44,  170,  157,  170,  224,  174,  192,  170,
 /*   690 */    23,   98,  170,  174,    9,  199,  174,  111,  163,  113,
 /*   700 */   114,   52,   64,   65,   66,   67,   68,   69,   70,   71,
 /*   710 */    72,   73,   74,   75,   76,   77,  189,   79,   80,   81,


 /*   720 */    82,   83,   84,   85,   86,   87,   88,  126,  150,  157,









 /*   730 */   150,  150,  139,  150,   23,  200,   25,  161,  103,  150,
 /*   740 */   150,  214,  226,   40,   23,  150,   25,   44,  170,  157,
 /*   750 */   170,  170,  174,   24,  174,  174,  107,  230,  136,  170,
 /*   760 */   170,  189,  235,  174,  174,   20,  183,   64,   65,   66,
 /*   770 */    67,   68,   69,   70,   71,   72,   73,   74,   75,   76,
 /*   780 */    77,  189,   79,   80,   81,   82,   83,   84,   85,   86,
 /*   790 */    87,   88,  103,  150,  150,  150,  150,    9,   25,   66,
 /*   800 */    55,  150,   57,   23,  150,   25,  214,  171,   40,  226,
 /*   810 */    22,   33,   44,  170,  170,  170,  170,  174,  174,  174,
 /*   820 */   174,  170,  230,  102,  170,  174,  171,  235,  174,   96,
 /*   830 */    95,   96,  163,   65,   66,   67,   68,   69,   70,   71,
 /*   840 */    72,   73,   74,   75,   76,   77,  117,   79,   80,   81,
 /*   850 */    82,   83,   84,   85,   86,   87,   88,  150,  103,  150,
 /*   860 */   150,   73,  150,  150,   23,  150,   25,  150,  150,  200,
 /*   870 */   150,   26,  117,  150,   40,  150,  103,  170,   44,  170,
 /*   880 */   170,  174,  170,  174,  174,  170,  174,  170,  170,  174,
 /*   890 */   170,  174,  174,  170,  174,  170,  183,  174,   42,  174,
 /*   900 */    66,   67,   68,   69,   70,   71,   72,   73,   74,   75,
 /*   910 */    76,   77,    9,   79,   80,   81,   82,   83,   84,   85,
 /*   920 */    86,   87,   88,   22,  150,  150,  150,   26,   28,   83,
 /*   930 */    84,   31,  150,  150,  150,  150,  150,   92,   26,  226,
 /*   940 */   150,  180,  150,   43,  170,  170,  170,  150,  174,  174,
 /*   950 */   174,   50,  170,  170,  170,  170,  174,  174,  174,  174,
 /*   960 */   170,   60,   61,   62,  174,    9,   23,   66,   25,  183,
 /*   970 */    53,   54,   60,   61,   62,  183,  131,  172,  150,  150,
 /*   980 */   183,   25,  186,  187,   83,   84,   85,  150,  150,   23,
 /*   990 */   150,   25,   91,   92,   93,   83,   84,   96,  170,  170,
 /*  1000 */   150,  150,  174,  174,   92,  150,  103,  170,   96,   22,
 /*  1010 */   170,  174,  226,   26,  174,   23,  150,   25,  226,  150,
 /*  1020 */   170,  170,  157,  226,  174,  174,  150,   23,  150,   25,
 /*  1030 */   129,  130,  131,  132,  133,  134,  135,   50,  150,  170,
 /*  1040 */   150,  129,  130,  174,  157,   46,  170,   60,   61,   62,
 /*  1050 */   174,  213,  157,   66,  189,   23,  150,   25,  170,   23,
 /*  1060 */   170,   25,  174,  208,  174,   23,  188,   25,  150,  150,
 /*  1070 */    83,   84,  150,  150,  208,  150,  189,  150,   91,   92,
 /*  1080 */    93,  150,  126,   96,  189,  115,   23,    9,   25,  150,
 /*  1090 */     9,  157,  171,  102,  188,   22,  117,  173,  128,  171,
 /*  1100 */   117,   22,  115,  190,  115,   26,  188,  188,  193,  189,
 /*  1110 */   188,  188,  126,  188,  124,  188,  129,  130,  131,  132,
 /*  1120 */   133,  134,  135,  189,   46,  123,  191,  188,  195,   50,
 /*  1130 */   194,  121,  125,  196,  117,  197,  117,   88,  198,   60,
 /*  1140 */    61,   62,   96,  150,  213,   66,  150,  150,  115,  115,
 /*  1150 */   115,   22,  136,  223,  222,   17,   22,   25,  187,   23,
 /*  1160 */    23,  150,   83,   84,  117,  150,  154,  122,   25,  101,
 /*  1170 */    91,   92,   93,  211,   26,   96,  162,  172,  211,  122,
 /*  1180 */   172,   25,  154,  203,  119,  103,  204,  150,  150,  150,
 /*  1190 */   150,  120,   22,   22,  150,   23,   23,   26,  117,  205,
 /*  1200 */   205,  117,  204,  150,   22,  175,  150,  176,  129,  130,
 /*  1210 */   131,  132,  133,  134,  135,  136,   23,  211,   22,  171,
 /*  1220 */   179,   50,  179,  162,  172,  163,  172,  150,  178,  211,
 /*  1230 */   179,   60,   61,   62,  170,  180,  170,   66,   46,   23,
 /*  1240 */   182,  228,  182,  173,   22,  171,  171,   46,  228,   22,
 /*  1250 */   100,  150,  176,  108,   83,   84,   85,  150,  175,  154,
 /*  1260 */   150,   24,   91,   92,   93,  154,  150,   96,  154,  103,
 /*  1270 */    39,  154,   11,   37,  139,   47,  150,  103,  103,   22,
 /*  1280 */   103,  154,   22,   26,  171,    9,  139,  185,   11,  150,
 /*  1290 */   231,  127,  127,    9,    9,   17,   17,   64,  107,  232,
 /*  1300 */   129,  130,  131,  132,  133,  134,  135,   50,  185,  150,
 /*  1310 */   150,   73,  194,  233,    9,   73,  127,   60,   61,   62,
 /*  1320 */   234,   22,   22,   66,  215,    9,  150,  118,  150,    9,
 /*  1330 */     9,    9,    9,    9,  194,  118,  194,    9,  185,  107,
 /*  1340 */    83,   84,    9,  194,    9,  127,  215,   22,   91,   92,
 /*  1350 */    93,    9,  150,   96,  150,    9,    9,  154,  150,    9,
 /*  1360 */    11,    9,   23,    9,   34,   16,   17,   18,   19,  236,
 /*  1370 */   163,  150,   24,    9,  163,    9,    9,    9,  237,   30,
 /*  1380 */   236,    9,   20,  154,  150,   36,  129,  130,  131,  132,
 /*  1390 */   133,  134,  135,  150,  140,   59,  150,    9,   49,  238,
 /*  1400 */    51,  238,  238,  238,  238,   56,  238,   58,  238,  238,
 /*  1410 */   238,  238,   63,  238,  238,  238,  238,  238,  238,  238,
 /*  1420 */   238,  238,  238,  238,  238,  238,  238,  238,  238,  238,
 /*  1430 */   238,  238,  238,  238,  238,  238,  238,  238,  238,  238,
 /*  1440 */   238,  238,  238,  238,  238,  238,  238,  238,  238,  238,
 /*  1450 */   238,  238,  238,  104,  105,  106,  238,  238,  238,  110,

 /*  1460 */   238,  238,  238,  238,  115,
};
#define YY_SHIFT_USE_DFLT (-76)

static const short yy_shift_ofst[] = {
 /*     0 */    92,  208,  -76,  -76, 1349,    6,   16,  -76,  458,  123,
 /*    10 */   183,   56,  232,  -76,  -76,  -76,  -76,  -76,  -76,  123,
 /*    20 */   273,  123,  346,  123,  415,  247,  597,  456,  598,  667,
 /*    30 */   685,  107,  -76,  -25,  -76,   86,  -76,  456,  113,  -76,
 /*    40 */   689,  -76,  778,  235,  -76,  -76,  -76,  -76,  -76,  -76,
 /*    50 */   -76,  571,  689,  -76,  856,  -76,  344,  -76,  -76,  999,
 /*    60 */   102,  689,  991,  -76,  -76,  -76,  -76,  689,  -76, 1073,
 /*    70 */  1257,  146,  901,  979,  983,  -76,  987,  -76,  238,  989,
 /*    80 */   -76,  281,  -76,  449,  986, 1002,  990, 1010, 1007,  -76,
 /*    90 */  1257,   41, 1257,  638, 1257,  -76, 1017,  456, 1019,  456,
 /*   100 */   -76,  -76,  -76,  -76,  -76,  -76,  -76,  -76,  -76,  834,
 /*   110 */  1257,  768, 1257,  -10, 1257,  -10, 1257,  -10, 1257,  -10,
 /*   120 */  1257,  -53, 1257,  -53, 1257,   11, 1257,   11, 1257,   11,
 /*   130 */  1257,   11, 1257,  -49, 1257,  -49, 1257, 1049, 1257, 1049,
 /*   140 */  1257, 1049, 1257,  -76,  -76,  -76,  230,  -76,  -76,  -76,
 /*   150 */   -76,  -76, 1257,  -75, 1257,  -10,  -76,  733,  -76, 1046,
 /*   160 */   -76,  -76,  -76, 1257,  703, 1257,  -53,  -76,  307,  987,
 /*   170 */   314,   38, 1033, 1034, 1035,  -76,  638, 1257,  834, 1257,
 /*   180 */   -76, 1257,  -76, 1257,  -76, 1129,  989,  319,  -76, 1079,
 /*   190 */    90, 1016,  537, 1138,  -76, 1257,  163, 1257,  638, 1134,
 /*   200 */   376, 1136,  -76, 1132,  456, 1137,  -76, 1257,  237, 1257,
 /*   210 */   301, 1257,  638,  711,  -76, 1257,  -76,  -76, 1047,  456,
 /*   220 */   -76,  -76,  -76, 1257,  638, 1045, 1257, 1143, 1257, 1068,
 /*   230 */   102,  -76, 1148,  -76,  -76,  638, 1068,  102,  -76, 1257,
 /*   240 */   638, 1057, 1257, 1156, 1257,  638,  -76,  -76,  509,  -76,
 /*   250 */   -76,  -76,  385,  -76,  439,  -76, 1065,  -76,  387, 1047,
 /*   260 */   405,  -76,  -76,  456,  -76,  -76, 1082, 1071,  -76, 1170,
 /*   270 */   456,  780,  -76,  456,  -76,  -76, 1257,  638,  989,  389,









 /*   280 */   443, 1172,  405, 1082, 1071,  -76, 1171,  -24,  -76,  -76,
 /*   290 */  1084,   53,  -76,  -76,  -76,  -76,  375,  -76,  841,  -76,
 /*   300 */  1173,  -76,  441,  689,  -76,  456, 1182,  -76,  635,  -76,
 /*   310 */   456,  -76,  521,  649,  -76,  735,  -76,  -76,  -76,  -76,
 /*   320 */   649,  -76,  649,  -76,  456,  943,  -76,  456, 1068,  102,
 /*   330 */   -76,  -76, 1068,  102,  -76,  -76, 1148,  -76,  856,  -76,
 /*   340 */   -76,  912,  -76,  128,  -76,  -76,  128,  -76,  -76,   -8,
 /*   350 */   846,  966,  -76,  846, 1193,  -76,  -76,  -76,  414,  -76,
 /*   360 */   -76,  -76,  414,  -76,  -76,  -76,  -76,  -76,   -6,   42,
 /*   370 */   -76,  456,  -76, 1192, 1196,  456,  721, 1216,  689,  -76,
 /*   380 */  1222,  456,  992,  689,  -76, 1257,  506,  -76, 1201, 1227,
 /*   390 */   456, 1004, 1150,  456, 1182,  -76,  453, 1145,  -76,  -76,
 /*   400 */   -76,  -76,  -76,  989,  428,  593,  745,  456, 1047,  -76,
 /*   410 */   456,  729, 1237,  989,  486,  456, 1047,  900,  525, 1166,
 /*   420 */   456, 1047,  -76, 1231,  622, 1261, 1257,  573, 1236,  917,
 /*   430 */   -76,  -76, 1174, 1175,  437,  456,  773,  -76,  -76, 1228,
 /*   440 */   -76,  -76, 1135,  456,  755, 1177,  456, 1260,  456, 1032,
 /*   450 */   903, 1276, 1147, 1277,  174,  490,  326,  235,  -76, 1164,
 /*   460 */  1165, 1278, 1284, 1285,  174, 1279, 1233,  456, 1191,  456,
 /*   470 */   956,  456, 1238, 1257,  638, 1305, 1242, 1257,  638, 1189,
 /*   480 */   456, 1299,  456, 1036,  -76,  360,  551, 1300, 1257, 1042,
 /*   490 */  1257,  638, 1316,  638, 1209,  456,  601, 1320,  240,  456,
 /*   500 */  1321,  456, 1322,  456, 1323,  456, 1324,  557, 1217,  456,
 /*   510 */   601, 1328, 1233,  456, 1232,  456,  956, 1333, 1218,  456,
 /*   520 */  1299,  970,  586, 1325, 1257, 1063, 1335,  460, 1342,  456,
 /*   530 */  1047,  788,  172, 1346, 1347, 1350, 1352,  456, 1339, 1354,
 /*   540 */  1330,  -25, 1348,  456, 1078, 1364,  845, 1366, 1367,  -76,
 /*   550 */  1330,  456, 1368,  542, 1081, 1372, 1362,  456, 1336, 1254,
 /*   560 */   456, 1388,  -76,  -76,
};
#define YY_REDUCE_USE_DFLT (-95)

static const short yy_reduce_ofst[] = {
 /*     0 */     0,  -61,  -95,  -95,  202,  -95,  -95,  -95,  -94,  -59,
 /*    10 */   -95,   52,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  103,
 /*    20 */   -95,  189,  -95,  261,  -95,  349,  -95,  185,  520,  -95,
 /*    30 */   -95,  109,  -95,   33,  576,  116,  -95,  595,  162,  -95,
 /*    40 */   636,  -95,  -95,   36,  -95,  -95,  -95,  -95,  -95,  -95,
 /*    50 */   -95,  -95,  655,  -95,  761,  -95,  -95,  -95,  -95,  -95,
 /*    60 */   805,  921,  924,  -95,  -95,  -95,  -95,  928,  -95,  -95,
 /*    70 */   446,  -95,  122,  -95,  -95,  -95,  -70,  -95,  913,  920,
 /*    80 */   -95,  935,  496,  915,  936,  933,  937,  938,  940,  -95,
 /*    90 */   448,  388,  513,  388,  519,  -95,  -95,  993,  -95,  996,
 /*   100 */   -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  388,
 /*   110 */   522,  388,  578,  388,  580,  388,  581,  388,  589,  388,
 /*   120 */   590,  388,  643,  388,  644,  388,  645,  388,  646,  388,
 /*   130 */   651,  388,  654,  388,  707,  388,  709,  388,  710,  388,
 /*   140 */   712,  388,  715,  388,  -95,  -95,  -95,  -95,  -95,  -95,
 /*   150 */   -95,  -95,  717,  188,  718,  388,  -95,  -95,  -95,  -95,
 /*   160 */   -95,  -95,  -95,  720,  388,  723,  388,  -95,  997,  462,
 /*   170 */   913,  -95,  -95,  -95,  -95,  -95,  388,  725,  388,  774,
 /*   180 */   388,  775,  388,  776,  388,  -95,  572,  913,  -95,   45,
 /*   190 */   388,  932,  930,  -95,  -95,  782,  388,  783,  388,  -95,
 /*   200 */   971,  -95,  -95,  -95, 1011,  -95,  -95,  784,  388,  785,
 /*   210 */   388,  790,  388,  -95,  -95,  252,  -95,  -95, 1012, 1015,
 /*   220 */   -95,  -95,  -95,  828,  388,  -95,  186,  -95,  320,  962,
 /*   230 */  1005,  -95, 1014,  -95,  -95,  388,  967, 1008,  -95,  829,
 /*   240 */   388,  -95,  180,  -95,  837,  388,  -95,  291,  980,  -95,
 /*   250 */   -95,  -95, 1037,  -95, 1038,  -95,  -95,  -95, 1039, 1028,
 /*   260 */   535,  -95,  -95, 1040,  -95,  -95,  982,  994,  -95,  -95,
 /*   270 */   407,  -95,  -95, 1044,  -95,  -95,  840,  388,  126,  913,
 /*   280 */   980,  -95,  669,  998,  995,  -95,  850,  201,  -95,  -95,
 /*   290 */   -95,  993,  -95,  -95,  -95,  -95,  388,  -95,  -95,  -95,
 /*   300 */   -95,  -95,  388, 1048,  -95, 1053, 1030, 1031, 1050,  -95,
 /*   310 */  1056,  -95,  -95, 1041,  -95,  -95,  -95,  -95,  -95,  -95,
 /*   320 */  1043,  -95, 1051,  -95,  583,  -95,  -95,  516, 1006, 1052,
 /*   330 */   -95,  -95, 1018, 1054,  -95,  -95, 1061,  -95, 1055,  -95,
 /*   340 */   -95,  515,  -95, 1064,  -95,  -95, 1066,  -95,  -95, 1062,
 /*   350 */   196,  -95,  -95,  269,  -95,  -95,  -95,  -95, 1013,  -95,
 /*   360 */   -95,  -95, 1020,  -95,  -95,  -95,  -95,  -95, 1058, 1060,
 /*   370 */   -95, 1077,  -95,  -95,  -95,  713, 1070,  -95, 1074,  -95,
 /*   380 */   -95,  786,  -95, 1075,  -95,  851,  318,  -95,  -95,  -95,
 /*   390 */   792,  -95,  -95, 1101, 1083, 1076,  110,  -95,  -95,  -95,
 /*   400 */   -95,  -95,  -95,  865,  913,  330,  -95, 1107, 1105,  -95,
 /*   410 */  1110, 1111,  -95,  887,  913, 1116, 1114, 1059, 1067,  -95,
 /*   420 */   878, 1117,  -95, 1080, 1086,  -95,  869,  388,  -95,  -95,
 /*   430 */   -95,  -95,  -95,  -95,  -95,  855,  -95,  -95,  -95,  -95,
 /*   440 */   -95,  -95,  -95, 1126, 1127,  -95, 1139,  -95,  797,  -95,
 /*   450 */  1113,  -95,  -95,  -95,  527,  913, 1102,  796,  -95,  -95,
 /*   460 */   -95,  -95,  -95,  -95,  592,  -95, 1123, 1159,  -95,  838,
 /*   470 */  1118, 1160,  -95,  876,  388,  -95,  -95,  888,  388,  -95,
 /*   480 */  1176, 1109,  866,  -95,  -95,  895,  913,  -95,  317,  -95,
 /*   490 */   890,  388,  -95,  388,  -95, 1178, 1140,  -95,  -95,  906,
 /*   500 */   -95,  918,  -95,  919,  -95,  922,  -95,  913,  -95,  923,
 /*   510 */  1142,  -95, 1153,  925,  -95,  931, 1149,  -95,  -95,  927,
 /*   520 */  1131,  934,  913,  -95,  395,  -95,  -95, 1202,  -95, 1204,
 /*   530 */  1203,  -95,  397,  -95,  -95,  -95,  -95, 1208,  -95,  -95,
 /*   540 */  1133, 1207,  -95, 1221, 1141,  -95, 1211,  -95,  -95,  -95,
 /*   550 */  1144, 1234,  -95, 1243, 1229,  -95,  -95,  939,  -95,  -95,
 /*   560 */  1246,  -95,  -95,  -95,
};
static const YYACTIONTYPE yy_default[] = {
 /*     0 */   570,  570,  565,  568,  869,  869,  869,  569,  576,  869,
 /*    10 */   869,  869,  869,  596,  597,  598,  577,  578,  579,  869,
 /*    20 */   869,  869,  869,  869,  869,  869,  869,  869,  869,  869,
 /*    30 */   869,  869,  589,  599,  608,  591,  607,  869,  869,  609,
 /*    40 */   652,  615,  869,  869,  653,  656,  657,  658,  855,  856,
 /*    50 */   857,  869,  652,  616,  637,  635,  869,  638,  639,  869,
 /*    60 */   708,  652,  623,  617,  624,  706,  707,  652,  618,  869,
 /*    70 */   869,  738,  807,  744,  739,  735,  869,  663,  869,  869,
 /*    80 */   664,  672,  674,  681,  720,  711,  713,  701,  715,  669,
 /*    90 */   869,  716,  869,  717,  869,  737,  869,  869,  740,  869,
 /*   100 */   741,  742,  743,  745,  746,  747,  750,  751,  752,  753,
 /*   110 */   869,  754,  869,  755,  869,  756,  869,  757,  869,  758,
 /*   120 */   869,  759,  869,  760,  869,  761,  869,  762,  869,  763,
 /*   130 */   869,  764,  869,  765,  869,  766,  869,  767,  869,  768,
 /*   140 */   869,  769,  869,  770,  771,  772,  869,  773,  774,  781,
 /*   150 */   788,  791,  869,  776,  869,  775,  778,  869,  779,  869,
 /*   160 */   782,  780,  787,  869,  869,  869,  789,  790,  869,  807,
 /*   170 */   869,  869,  869,  869,  869,  794,  806,  869,  783,  869,
 /*   180 */   784,  869,  785,  869,  786,  869,  869,  869,  796,  869,
 /*   190 */   869,  869,  869,  869,  797,  869,  869,  869,  798,  869,
 /*   200 */   869,  869,  853,  869,  869,  869,  854,  869,  869,  869,
 /*   210 */   869,  869,  799,  869,  792,  807,  804,  805,  689,  869,
 /*   220 */   690,  795,  777,  869,  718,  869,  869,  702,  869,  709,
 /*   230 */   708,  703,  869,  593,  710,  705,  709,  708,  704,  869,
 /*   240 */   714,  869,  807,  712,  869,  721,  673,  684,  682,  683,
 /*   250 */   692,  693,  869,  694,  869,  695,  869,  696,  869,  689,
 /*   260 */   680,  594,  595,  869,  678,  679,  698,  700,  685,  869,
 /*   270 */   869,  869,  699,  869,  733,  734,  869,  697,  684,  869,
 /*   280 */   869,  869,  680,  698,  700,  686,  869,  680,  675,  676,
 /*   290 */   869,  869,  677,  670,  671,  793,  869,  736,  869,  748,
 /*   300 */   869,  749,  869,  652,  619,  869,  811,  625,  620,  626,
 /*   310 */   869,  627,  869,  869,  628,  869,  631,  632,  633,  634,
 /*   320 */   869,  629,  869,  630,  869,  869,  812,  869,  709,  708,
 /*   330 */   813,  815,  709,  708,  814,  621,  869,  622,  637,  636,
 /*   340 */   610,  869,  611,  869,  612,  744,  869,  613,  614,  600,
 /*   350 */   830,  869,  601,  830,  869,  602,  605,  606,  869,  825,
 /*   360 */   827,  828,  869,  826,  829,  604,  603,  592,  869,  869,
 /*   370 */   642,  869,  645,  869,  869,  869,  869,  869,  652,  646,
 /*   380 */   869,  869,  869,  652,  647,  869,  652,  648,  869,  869,
 /*   390 */   869,  869,  869,  869,  811,  625,  650,  869,  649,  651,
 /*   400 */   643,  644,  590,  869,  869,  586,  869,  869,  689,  584,
 /*   410 */   869,  869,  869,  869,  869,  869,  689,  836,  869,  869,
 /*   420 */   869,  689,  691,  841,  869,  869,  869,  869,  869,  869,
 /*   430 */   842,  843,  869,  869,  869,  869,  869,  833,  834,  869,
 /*   440 */   835,  585,  869,  869,  869,  869,  869,  869,  869,  869,
 /*   450 */   869,  869,  869,  869,  869,  869,  869,  869,  655,  869,
 /*   460 */   869,  869,  869,  869,  869,  869,  654,  869,  869,  869,
 /*   470 */   869,  869,  869,  869,  723,  869,  869,  869,  724,  869,
 /*   480 */   869,  731,  869,  869,  732,  869,  869,  869,  869,  869,
 /*   490 */   869,  729,  869,  730,  869,  869,  869,  869,  869,  869,
 /*   500 */   869,  869,  869,  869,  869,  869,  869,  869,  869,  869,
 /*   510 */   869,  869,  654,  869,  869,  869,  869,  869,  869,  869,
 /*   520 */   731,  869,  869,  869,  869,  869,  869,  869,  869,  869,
 /*   530 */   689,  869,  830,  869,  869,  869,  869,  869,  869,  869,
 /*   540 */   864,  869,  869,  869,  869,  869,  869,  869,  869,  863,
 /*   550 */   864,  869,  869,  869,  869,  869,  869,  869,  869,  869,
 /*   560 */   869,  869,  571,  566,
};
#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))

/* The next table maps tokens into fallback tokens.  If a construct
** like the following:
** 
**      %fallback ID X Y Z.
**
** appears in the grammer, then ID becomes a fallback token for X, Y,
** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
** but it does not parse, the type of the token is changed to ID and
** the parse is retried before an error is thrown.
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
    0,  /*          $ => nothing */
    0,  /* END_OF_FILE => nothing */
    0,  /*    ILLEGAL => nothing */
    0,  /*      SPACE => nothing */
    0,  /* UNCLOSED_STRING => nothing */
    0,  /*    COMMENT => nothing */
    0,  /*   FUNCTION => nothing */
    0,  /*     COLUMN => nothing */
    0,  /* AGG_FUNCTION => nothing */
    0,  /*       SEMI => nothing */
   26,  /*    EXPLAIN => ID */


   26,  /*      BEGIN => ID */
    0,  /* TRANSACTION => nothing */
   26,  /*   DEFERRED => ID */
   26,  /*  IMMEDIATE => ID */
   26,  /*  EXCLUSIVE => ID */
    0,  /*     COMMIT => nothing */
   26,  /*        END => ID */
    0,  /*   ROLLBACK => nothing */
    0,  /*     CREATE => nothing */
    0,  /*      TABLE => nothing */



   26,  /*       TEMP => ID */
    0,  /*         LP => nothing */
    0,  /*         RP => nothing */
    0,  /*         AS => nothing */
    0,  /*      COMMA => nothing */
    0,  /*         ID => nothing */
   26,  /*      ABORT => ID */
   26,  /*      AFTER => ID */

   26,  /*        ASC => ID */
   26,  /*     ATTACH => ID */
   26,  /*     BEFORE => ID */
   26,  /*    CASCADE => ID */

   26,  /*   CONFLICT => ID */
   26,  /*   DATABASE => ID */
   26,  /*       DESC => ID */
   26,  /*     DETACH => ID */
   26,  /*       EACH => ID */
   26,  /*       FAIL => ID */
   26,  /*        FOR => ID */
   26,  /*       GLOB => ID */
   26,  /*     IGNORE => ID */
   26,  /*  INITIALLY => ID */
   26,  /*    INSTEAD => ID */
   26,  /*       LIKE => ID */
   26,  /*      MATCH => ID */
   26,  /*        KEY => ID */
   26,  /*         OF => ID */
   26,  /*     OFFSET => ID */
   26,  /*     PRAGMA => ID */
   26,  /*      RAISE => ID */
   26,  /*    REPLACE => ID */
   26,  /*   RESTRICT => ID */
   26,  /*        ROW => ID */
   26,  /*  STATEMENT => ID */
   26,  /*    TRIGGER => ID */
   26,  /*     VACUUM => ID */
   26,  /*       VIEW => ID */
   26,  /*    REINDEX => ID */
   26,  /*     RENAME => ID */
   26,  /*      CDATE => ID */
   26,  /*      CTIME => ID */
   26,  /* CTIMESTAMP => ID */
   26,  /*      ALTER => ID */
    0,  /*         OR => nothing */
    0,  /*        AND => nothing */
    0,  /*        NOT => nothing */
    0,  /*         IS => nothing */
    0,  /*    BETWEEN => nothing */
    0,  /*         IN => nothing */
    0,  /*     ISNULL => nothing */
    0,  /*    NOTNULL => nothing */
    0,  /*         NE => nothing */
    0,  /*         EQ => nothing */
684
685
686
687
688
689
690
691
692

693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711

712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
    0,  /*     INSERT => nothing */
    0,  /*        SET => nothing */
    0,  /* DEFERRABLE => nothing */
    0,  /*    FOREIGN => nothing */
    0,  /*       DROP => nothing */
    0,  /*      UNION => nothing */
    0,  /*        ALL => nothing */
    0,  /*     EXCEPT => nothing */
    0,  /*  INTERSECT => nothing */

    0,  /*     SELECT => nothing */
    0,  /*   DISTINCT => nothing */
    0,  /*        DOT => nothing */
    0,  /*       FROM => nothing */
    0,  /*       JOIN => nothing */
    0,  /*      USING => nothing */
    0,  /*      ORDER => nothing */
    0,  /*         BY => nothing */
    0,  /*      GROUP => nothing */
    0,  /*     HAVING => nothing */
    0,  /*      LIMIT => nothing */
    0,  /*      WHERE => nothing */
    0,  /*       INTO => nothing */
    0,  /*     VALUES => nothing */
    0,  /*    INTEGER => nothing */
    0,  /*      FLOAT => nothing */
    0,  /*       BLOB => nothing */
    0,  /*   REGISTER => nothing */
    0,  /*   VARIABLE => nothing */

    0,  /*       CASE => nothing */
    0,  /*       WHEN => nothing */
    0,  /*       THEN => nothing */
    0,  /*       ELSE => nothing */
    0,  /*      INDEX => nothing */
    0,  /*      ALTER => nothing */
    0,  /*         TO => nothing */
    0,  /*        ADD => nothing */
    0,  /*   COLUMNKW => nothing */
};
#endif /* YYFALLBACK */

/* The following structure represents a single element of the
** parser's stack.  Information stored includes:
**
**   +  The state number for the parser at this level of the stack.







<

>



















>





<

<
<







774
775
776
777
778
779
780

781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807

808


809
810
811
812
813
814
815
    0,  /*     INSERT => nothing */
    0,  /*        SET => nothing */
    0,  /* DEFERRABLE => nothing */
    0,  /*    FOREIGN => nothing */
    0,  /*       DROP => nothing */
    0,  /*      UNION => nothing */
    0,  /*        ALL => nothing */

    0,  /*  INTERSECT => nothing */
    0,  /*     EXCEPT => nothing */
    0,  /*     SELECT => nothing */
    0,  /*   DISTINCT => nothing */
    0,  /*        DOT => nothing */
    0,  /*       FROM => nothing */
    0,  /*       JOIN => nothing */
    0,  /*      USING => nothing */
    0,  /*      ORDER => nothing */
    0,  /*         BY => nothing */
    0,  /*      GROUP => nothing */
    0,  /*     HAVING => nothing */
    0,  /*      LIMIT => nothing */
    0,  /*      WHERE => nothing */
    0,  /*       INTO => nothing */
    0,  /*     VALUES => nothing */
    0,  /*    INTEGER => nothing */
    0,  /*      FLOAT => nothing */
    0,  /*       BLOB => nothing */
    0,  /*   REGISTER => nothing */
    0,  /*   VARIABLE => nothing */
    0,  /*     EXISTS => nothing */
    0,  /*       CASE => nothing */
    0,  /*       WHEN => nothing */
    0,  /*       THEN => nothing */
    0,  /*       ELSE => nothing */
    0,  /*      INDEX => nothing */

    0,  /*         TO => nothing */


};
#endif /* YYFALLBACK */

/* The following structure represents a single element of the
** parser's stack.  Information stored includes:
**
**   +  The state number for the parser at this level of the stack.
784
785
786
787
788
789
790


791
792
793
794
795
796
797
798
799
800
801
802
803
804
805

806
807
808
809
810

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

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

892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922




923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991

992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040

1041



1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064










1065



1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108

1109
1110
1111
1112
1113
1114
1115
1116
1117

1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140

1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
}
#endif /* NDEBUG */

#ifndef NDEBUG
/* For tracing shifts, the names of all terminals and nonterminals
** are required.  The following table supplies these names */
static const char *const yyTokenName[] = { 


  "$",             "SEMI",          "EXPLAIN",       "QUERY",       
  "PLAN",          "BEGIN",         "TRANSACTION",   "DEFERRED",    
  "IMMEDIATE",     "EXCLUSIVE",     "COMMIT",        "END",         
  "ROLLBACK",      "CREATE",        "TABLE",         "IF",          
  "NOT",           "EXISTS",        "TEMP",          "LP",          
  "RP",            "AS",            "COMMA",         "ID",          
  "ABORT",         "AFTER",         "ANALYZE",       "ASC",         
  "ATTACH",        "BEFORE",        "CASCADE",       "CAST",        
  "CONFLICT",      "DATABASE",      "DESC",          "DETACH",      
  "EACH",          "FAIL",          "FOR",           "IGNORE",      
  "INITIALLY",     "INSTEAD",       "LIKE_KW",       "MATCH",       
  "KEY",           "OF",            "OFFSET",        "PRAGMA",      
  "RAISE",         "REPLACE",       "RESTRICT",      "ROW",         
  "STATEMENT",     "TRIGGER",       "VACUUM",        "VIEW",        
  "REINDEX",       "RENAME",        "CTIME_KW",      "OR",          

  "AND",           "IS",            "BETWEEN",       "IN",          
  "ISNULL",        "NOTNULL",       "NE",            "EQ",          
  "GT",            "LE",            "LT",            "GE",          
  "ESCAPE",        "BITAND",        "BITOR",         "LSHIFT",      
  "RSHIFT",        "PLUS",          "MINUS",         "STAR",        

  "SLASH",         "REM",           "CONCAT",        "UMINUS",      
  "UPLUS",         "BITNOT",        "STRING",        "JOIN_KW",     
  "CONSTRAINT",    "DEFAULT",       "NULL",          "PRIMARY",     
  "UNIQUE",        "CHECK",         "REFERENCES",    "COLLATE",     
  "AUTOINCR",      "ON",            "DELETE",        "UPDATE",      
  "INSERT",        "SET",           "DEFERRABLE",    "FOREIGN",     
  "DROP",          "UNION",         "ALL",           "EXCEPT",      
  "INTERSECT",     "SELECT",        "DISTINCT",      "DOT",         
  "FROM",          "JOIN",          "USING",         "ORDER",       
  "BY",            "GROUP",         "HAVING",        "LIMIT",       
  "WHERE",         "INTO",          "VALUES",        "INTEGER",     
  "FLOAT",         "BLOB",          "REGISTER",      "VARIABLE",    
  "CASE",          "WHEN",          "THEN",          "ELSE",        
  "INDEX",         "ALTER",         "TO",            "ADD",         
  "COLUMNKW",      "error",         "input",         "cmdlist",     
  "ecmd",          "cmdx",          "cmd",           "explain",     
  "transtype",     "trans_opt",     "nm",            "create_table",
  "create_table_args",  "temp",          "ifnotexists",   "dbnm",        
  "columnlist",    "conslist_opt",  "select",        "column",      
  "columnid",      "type",          "carglist",      "id",          
  "ids",           "typetoken",     "typename",      "signed",      
  "plus_num",      "minus_num",     "carg",          "ccons",       
  "term",          "expr",          "onconf",        "sortorder",   
  "autoinc",       "idxlist_opt",   "refargs",       "defer_subclause",
  "refarg",        "refact",        "init_deferred_pred_opt",  "conslist",    
  "tcons",         "idxlist",       "defer_subclause_opt",  "orconf",      
  "resolvetype",   "raisetype",     "ifexists",      "fullname",    
  "oneselect",     "multiselect_op",  "distinct",      "selcollist",  
  "from",          "where_opt",     "groupby_opt",   "having_opt",  
  "orderby_opt",   "limit_opt",     "sclp",          "as",          
  "seltablist",    "stl_prefix",    "joinop",        "on_opt",      
  "using_opt",     "seltablist_paren",  "joinop2",       "inscollist",  
  "sortlist",      "sortitem",      "collate",       "exprlist",    
  "setlist",       "insert_cmd",    "inscollist_opt",  "itemlist",    
  "likeop",        "escape",        "between_op",    "in_op",       
  "case_operand",  "case_exprlist",  "case_else",     "expritem",    
  "uniqueflag",    "idxitem",       "plus_opt",      "number",      
  "trigger_decl",  "trigger_cmd_list",  "trigger_time",  "trigger_event",
  "foreach_clause",  "when_clause",   "trigger_cmd",   "database_kw_opt",
  "key_opt",       "add_column_fullname",  "kwcolumn_opt",
};
#endif /* NDEBUG */

#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const yyRuleName[] = {
 /*   0 */ "input ::= cmdlist",
 /*   1 */ "cmdlist ::= cmdlist ecmd",
 /*   2 */ "cmdlist ::= ecmd",
 /*   3 */ "cmdx ::= cmd",
 /*   4 */ "ecmd ::= SEMI",
 /*   5 */ "ecmd ::= explain cmdx SEMI",
 /*   6 */ "explain ::=",
 /*   7 */ "explain ::= EXPLAIN",
 /*   8 */ "explain ::= EXPLAIN QUERY PLAN",
 /*   9 */ "cmd ::= BEGIN transtype trans_opt",

 /*  10 */ "trans_opt ::=",
 /*  11 */ "trans_opt ::= TRANSACTION",
 /*  12 */ "trans_opt ::= TRANSACTION nm",
 /*  13 */ "transtype ::=",
 /*  14 */ "transtype ::= DEFERRED",
 /*  15 */ "transtype ::= IMMEDIATE",
 /*  16 */ "transtype ::= EXCLUSIVE",
 /*  17 */ "cmd ::= COMMIT trans_opt",
 /*  18 */ "cmd ::= END trans_opt",
 /*  19 */ "cmd ::= ROLLBACK trans_opt",
 /*  20 */ "cmd ::= create_table create_table_args",
 /*  21 */ "create_table ::= CREATE temp TABLE ifnotexists nm dbnm",
 /*  22 */ "ifnotexists ::=",
 /*  23 */ "ifnotexists ::= IF NOT EXISTS",
 /*  24 */ "temp ::= TEMP",
 /*  25 */ "temp ::=",
 /*  26 */ "create_table_args ::= LP columnlist conslist_opt RP",
 /*  27 */ "create_table_args ::= AS select",
 /*  28 */ "columnlist ::= columnlist COMMA column",
 /*  29 */ "columnlist ::= column",
 /*  30 */ "column ::= columnid type carglist",
 /*  31 */ "columnid ::= nm",
 /*  32 */ "id ::= ID",
 /*  33 */ "ids ::= ID|STRING",

 /*  34 */ "nm ::= ID",
 /*  35 */ "nm ::= STRING",
 /*  36 */ "nm ::= JOIN_KW",
 /*  37 */ "type ::=",
 /*  38 */ "type ::= typetoken",
 /*  39 */ "typetoken ::= typename",
 /*  40 */ "typetoken ::= typename LP signed RP",
 /*  41 */ "typetoken ::= typename LP signed COMMA signed RP",
 /*  42 */ "typename ::= ids",
 /*  43 */ "typename ::= typename ids",
 /*  44 */ "signed ::= plus_num",
 /*  45 */ "signed ::= minus_num",
 /*  46 */ "carglist ::= carglist carg",
 /*  47 */ "carglist ::=",
 /*  48 */ "carg ::= CONSTRAINT nm ccons",
 /*  49 */ "carg ::= ccons",
 /*  50 */ "carg ::= DEFAULT term",
 /*  51 */ "carg ::= DEFAULT LP expr RP",
 /*  52 */ "carg ::= DEFAULT PLUS term",
 /*  53 */ "carg ::= DEFAULT MINUS term",
 /*  54 */ "carg ::= DEFAULT id",
 /*  55 */ "ccons ::= NULL onconf",
 /*  56 */ "ccons ::= NOT NULL onconf",
 /*  57 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
 /*  58 */ "ccons ::= UNIQUE onconf",
 /*  59 */ "ccons ::= CHECK LP expr RP",
 /*  60 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
 /*  61 */ "ccons ::= defer_subclause",
 /*  62 */ "ccons ::= COLLATE id",
 /*  63 */ "autoinc ::=",
 /*  64 */ "autoinc ::= AUTOINCR",




 /*  65 */ "refargs ::=",
 /*  66 */ "refargs ::= refargs refarg",
 /*  67 */ "refarg ::= MATCH nm",
 /*  68 */ "refarg ::= ON DELETE refact",
 /*  69 */ "refarg ::= ON UPDATE refact",
 /*  70 */ "refarg ::= ON INSERT refact",
 /*  71 */ "refact ::= SET NULL",
 /*  72 */ "refact ::= SET DEFAULT",
 /*  73 */ "refact ::= CASCADE",
 /*  74 */ "refact ::= RESTRICT",
 /*  75 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
 /*  76 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
 /*  77 */ "init_deferred_pred_opt ::=",
 /*  78 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
 /*  79 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
 /*  80 */ "conslist_opt ::=",
 /*  81 */ "conslist_opt ::= COMMA conslist",
 /*  82 */ "conslist ::= conslist COMMA tcons",
 /*  83 */ "conslist ::= conslist tcons",
 /*  84 */ "conslist ::= tcons",
 /*  85 */ "tcons ::= CONSTRAINT nm",
 /*  86 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
 /*  87 */ "tcons ::= UNIQUE LP idxlist RP onconf",
 /*  88 */ "tcons ::= CHECK LP expr RP onconf",
 /*  89 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
 /*  90 */ "defer_subclause_opt ::=",
 /*  91 */ "defer_subclause_opt ::= defer_subclause",
 /*  92 */ "onconf ::=",
 /*  93 */ "onconf ::= ON CONFLICT resolvetype",
 /*  94 */ "orconf ::=",
 /*  95 */ "orconf ::= OR resolvetype",
 /*  96 */ "resolvetype ::= raisetype",
 /*  97 */ "resolvetype ::= IGNORE",
 /*  98 */ "resolvetype ::= REPLACE",
 /*  99 */ "cmd ::= DROP TABLE ifexists fullname",
 /* 100 */ "ifexists ::= IF EXISTS",
 /* 101 */ "ifexists ::=",
 /* 102 */ "cmd ::= CREATE temp VIEW nm dbnm AS select",
 /* 103 */ "cmd ::= DROP VIEW ifexists fullname",
 /* 104 */ "cmd ::= select",
 /* 105 */ "select ::= oneselect",
 /* 106 */ "select ::= select multiselect_op oneselect",
 /* 107 */ "multiselect_op ::= UNION",
 /* 108 */ "multiselect_op ::= UNION ALL",

 /* 109 */ "multiselect_op ::= EXCEPT|INTERSECT",
 /* 110 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
 /* 111 */ "distinct ::= DISTINCT",
 /* 112 */ "distinct ::= ALL",
 /* 113 */ "distinct ::=",
 /* 114 */ "sclp ::= selcollist COMMA",
 /* 115 */ "sclp ::=",
 /* 116 */ "selcollist ::= sclp expr as",
 /* 117 */ "selcollist ::= sclp STAR",
 /* 118 */ "selcollist ::= sclp nm DOT STAR",
 /* 119 */ "as ::= AS nm",
 /* 120 */ "as ::= ids",
 /* 121 */ "as ::=",
 /* 122 */ "from ::=",
 /* 123 */ "from ::= FROM seltablist",
 /* 124 */ "stl_prefix ::= seltablist joinop",
 /* 125 */ "stl_prefix ::=",
 /* 126 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt",
 /* 127 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt",
 /* 128 */ "seltablist_paren ::= select",
 /* 129 */ "seltablist_paren ::= seltablist",
 /* 130 */ "dbnm ::=",
 /* 131 */ "dbnm ::= DOT nm",
 /* 132 */ "fullname ::= nm dbnm",
 /* 133 */ "joinop ::= COMMA|JOIN",

 /* 134 */ "joinop ::= JOIN_KW JOIN",
 /* 135 */ "joinop ::= JOIN_KW nm JOIN",
 /* 136 */ "joinop ::= JOIN_KW nm nm JOIN",
 /* 137 */ "on_opt ::= ON expr",
 /* 138 */ "on_opt ::=",
 /* 139 */ "using_opt ::= USING LP inscollist RP",
 /* 140 */ "using_opt ::=",
 /* 141 */ "orderby_opt ::=",
 /* 142 */ "orderby_opt ::= ORDER BY sortlist",
 /* 143 */ "sortlist ::= sortlist COMMA sortitem collate sortorder",
 /* 144 */ "sortlist ::= sortitem collate sortorder",
 /* 145 */ "sortitem ::= expr",
 /* 146 */ "sortorder ::= ASC",
 /* 147 */ "sortorder ::= DESC",
 /* 148 */ "sortorder ::=",
 /* 149 */ "collate ::=",
 /* 150 */ "collate ::= COLLATE id",
 /* 151 */ "groupby_opt ::=",
 /* 152 */ "groupby_opt ::= GROUP BY exprlist",
 /* 153 */ "having_opt ::=",
 /* 154 */ "having_opt ::= HAVING expr",
 /* 155 */ "limit_opt ::=",
 /* 156 */ "limit_opt ::= LIMIT expr",
 /* 157 */ "limit_opt ::= LIMIT expr OFFSET expr",
 /* 158 */ "limit_opt ::= LIMIT expr COMMA expr",
 /* 159 */ "cmd ::= DELETE FROM fullname where_opt",
 /* 160 */ "where_opt ::=",
 /* 161 */ "where_opt ::= WHERE expr",
 /* 162 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt",
 /* 163 */ "setlist ::= setlist COMMA nm EQ expr",
 /* 164 */ "setlist ::= nm EQ expr",
 /* 165 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
 /* 166 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
 /* 167 */ "insert_cmd ::= INSERT orconf",
 /* 168 */ "insert_cmd ::= REPLACE",
 /* 169 */ "itemlist ::= itemlist COMMA expr",
 /* 170 */ "itemlist ::= expr",
 /* 171 */ "inscollist_opt ::=",
 /* 172 */ "inscollist_opt ::= LP inscollist RP",
 /* 173 */ "inscollist ::= inscollist COMMA nm",
 /* 174 */ "inscollist ::= nm",
 /* 175 */ "expr ::= term",
 /* 176 */ "expr ::= LP expr RP",
 /* 177 */ "term ::= NULL",
 /* 178 */ "expr ::= ID",
 /* 179 */ "expr ::= JOIN_KW",
 /* 180 */ "expr ::= nm DOT nm",
 /* 181 */ "expr ::= nm DOT nm DOT nm",
 /* 182 */ "term ::= INTEGER|FLOAT|BLOB",

 /* 183 */ "term ::= STRING",



 /* 184 */ "expr ::= REGISTER",
 /* 185 */ "expr ::= VARIABLE",
 /* 186 */ "expr ::= CAST LP expr AS typetoken RP",
 /* 187 */ "expr ::= ID LP distinct exprlist RP",
 /* 188 */ "expr ::= ID LP STAR RP",
 /* 189 */ "term ::= CTIME_KW",
 /* 190 */ "expr ::= expr AND expr",
 /* 191 */ "expr ::= expr OR expr",
 /* 192 */ "expr ::= expr LT|GT|GE|LE expr",
 /* 193 */ "expr ::= expr EQ|NE expr",
 /* 194 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
 /* 195 */ "expr ::= expr PLUS|MINUS expr",
 /* 196 */ "expr ::= expr STAR|SLASH|REM expr",
 /* 197 */ "expr ::= expr CONCAT expr",
 /* 198 */ "likeop ::= LIKE_KW",
 /* 199 */ "likeop ::= NOT LIKE_KW",
 /* 200 */ "escape ::= ESCAPE expr",
 /* 201 */ "escape ::=",
 /* 202 */ "expr ::= expr likeop expr escape",
 /* 203 */ "expr ::= expr ISNULL|NOTNULL",
 /* 204 */ "expr ::= expr IS NULL",
 /* 205 */ "expr ::= expr NOT NULL",
 /* 206 */ "expr ::= expr IS NOT NULL",










 /* 207 */ "expr ::= NOT|BITNOT expr",



 /* 208 */ "expr ::= MINUS expr",
 /* 209 */ "expr ::= PLUS expr",
 /* 210 */ "between_op ::= BETWEEN",
 /* 211 */ "between_op ::= NOT BETWEEN",
 /* 212 */ "expr ::= expr between_op expr AND expr",
 /* 213 */ "in_op ::= IN",
 /* 214 */ "in_op ::= NOT IN",
 /* 215 */ "expr ::= expr in_op LP exprlist RP",
 /* 216 */ "expr ::= LP select RP",
 /* 217 */ "expr ::= expr in_op LP select RP",
 /* 218 */ "expr ::= expr in_op nm dbnm",
 /* 219 */ "expr ::= EXISTS LP select RP",
 /* 220 */ "expr ::= CASE case_operand case_exprlist case_else END",
 /* 221 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
 /* 222 */ "case_exprlist ::= WHEN expr THEN expr",
 /* 223 */ "case_else ::= ELSE expr",
 /* 224 */ "case_else ::=",
 /* 225 */ "case_operand ::= expr",
 /* 226 */ "case_operand ::=",
 /* 227 */ "exprlist ::= exprlist COMMA expritem",
 /* 228 */ "exprlist ::= expritem",
 /* 229 */ "expritem ::= expr",
 /* 230 */ "expritem ::=",
 /* 231 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP onconf",
 /* 232 */ "uniqueflag ::= UNIQUE",
 /* 233 */ "uniqueflag ::=",
 /* 234 */ "idxlist_opt ::=",
 /* 235 */ "idxlist_opt ::= LP idxlist RP",
 /* 236 */ "idxlist ::= idxlist COMMA idxitem collate sortorder",
 /* 237 */ "idxlist ::= idxitem collate sortorder",
 /* 238 */ "idxitem ::= nm",
 /* 239 */ "cmd ::= DROP INDEX ifexists fullname",
 /* 240 */ "cmd ::= VACUUM",
 /* 241 */ "cmd ::= VACUUM nm",
 /* 242 */ "cmd ::= PRAGMA nm dbnm EQ nm",
 /* 243 */ "cmd ::= PRAGMA nm dbnm EQ ON",
 /* 244 */ "cmd ::= PRAGMA nm dbnm EQ plus_num",
 /* 245 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
 /* 246 */ "cmd ::= PRAGMA nm dbnm LP nm RP",
 /* 247 */ "cmd ::= PRAGMA nm dbnm",
 /* 248 */ "plus_num ::= plus_opt number",
 /* 249 */ "minus_num ::= MINUS number",
 /* 250 */ "number ::= INTEGER|FLOAT",

 /* 251 */ "plus_opt ::= PLUS",
 /* 252 */ "plus_opt ::=",
 /* 253 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
 /* 254 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
 /* 255 */ "trigger_time ::= BEFORE",
 /* 256 */ "trigger_time ::= AFTER",
 /* 257 */ "trigger_time ::= INSTEAD OF",
 /* 258 */ "trigger_time ::=",
 /* 259 */ "trigger_event ::= DELETE|INSERT",

 /* 260 */ "trigger_event ::= UPDATE",
 /* 261 */ "trigger_event ::= UPDATE OF inscollist",
 /* 262 */ "foreach_clause ::=",
 /* 263 */ "foreach_clause ::= FOR EACH ROW",
 /* 264 */ "foreach_clause ::= FOR EACH STATEMENT",
 /* 265 */ "when_clause ::=",
 /* 266 */ "when_clause ::= WHEN expr",
 /* 267 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list",
 /* 268 */ "trigger_cmd_list ::=",
 /* 269 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
 /* 270 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
 /* 271 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
 /* 272 */ "trigger_cmd ::= DELETE FROM nm where_opt",
 /* 273 */ "trigger_cmd ::= select",
 /* 274 */ "expr ::= RAISE LP IGNORE RP",
 /* 275 */ "expr ::= RAISE LP raisetype COMMA nm RP",
 /* 276 */ "raisetype ::= ROLLBACK",
 /* 277 */ "raisetype ::= ABORT",
 /* 278 */ "raisetype ::= FAIL",
 /* 279 */ "cmd ::= DROP TRIGGER fullname",
 /* 280 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
 /* 281 */ "key_opt ::=",
 /* 282 */ "key_opt ::= KEY expr",

 /* 283 */ "database_kw_opt ::= DATABASE",
 /* 284 */ "database_kw_opt ::=",
 /* 285 */ "cmd ::= DETACH database_kw_opt expr",
 /* 286 */ "cmd ::= REINDEX",
 /* 287 */ "cmd ::= REINDEX nm dbnm",
 /* 288 */ "cmd ::= ANALYZE",
 /* 289 */ "cmd ::= ANALYZE nm dbnm",
 /* 290 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
 /* 291 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
 /* 292 */ "add_column_fullname ::= fullname",
 /* 293 */ "kwcolumn_opt ::=",
 /* 294 */ "kwcolumn_opt ::= COLUMNKW",
};
#endif /* NDEBUG */

/*
** This function returns the symbolic name associated with a token
** value.
*/







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


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















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







872
873
874
875
876
877
878
879
880
881

882
883
884
885

886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913

914
915
916
917
918
919
920
921
922
923
924
925

926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953

954
955
956
957
958
959
960
961

962
963
964
965
966


967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982

983
984
985
986
987
988
989
990
991
992
993

994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011




1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041


1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249


1250




1251
1252
1253
1254
1255
1256
1257
}
#endif /* NDEBUG */

#ifndef NDEBUG
/* For tracing shifts, the names of all terminals and nonterminals
** are required.  The following table supplies these names */
static const char *const yyTokenName[] = { 
  "$",             "END_OF_FILE",   "ILLEGAL",       "SPACE",       
  "UNCLOSED_STRING",  "COMMENT",       "FUNCTION",      "COLUMN",      
  "AGG_FUNCTION",  "SEMI",          "EXPLAIN",       "BEGIN",       

  "TRANSACTION",   "DEFERRED",      "IMMEDIATE",     "EXCLUSIVE",   
  "COMMIT",        "END",           "ROLLBACK",      "CREATE",      
  "TABLE",         "TEMP",          "LP",            "RP",          
  "AS",            "COMMA",         "ID",            "ABORT",       

  "AFTER",         "ASC",           "ATTACH",        "BEFORE",      
  "CASCADE",       "CONFLICT",      "DATABASE",      "DESC",        
  "DETACH",        "EACH",          "FAIL",          "FOR",         
  "GLOB",          "IGNORE",        "INITIALLY",     "INSTEAD",     
  "LIKE",          "MATCH",         "KEY",           "OF",          
  "OFFSET",        "PRAGMA",        "RAISE",         "REPLACE",     
  "RESTRICT",      "ROW",           "STATEMENT",     "TRIGGER",     
  "VACUUM",        "VIEW",          "REINDEX",       "RENAME",      
  "CDATE",         "CTIME",         "CTIMESTAMP",    "ALTER",       
  "OR",            "AND",           "NOT",           "IS",          
  "BETWEEN",       "IN",            "ISNULL",        "NOTNULL",     
  "NE",            "EQ",            "GT",            "LE",          
  "LT",            "GE",            "ESCAPE",        "BITAND",      
  "BITOR",         "LSHIFT",        "RSHIFT",        "PLUS",        
  "MINUS",         "STAR",          "SLASH",         "REM",         
  "CONCAT",        "UMINUS",        "UPLUS",         "BITNOT",      
  "STRING",        "JOIN_KW",       "CONSTRAINT",    "DEFAULT",     
  "NULL",          "PRIMARY",       "UNIQUE",        "CHECK",       
  "REFERENCES",    "COLLATE",       "AUTOINCR",      "ON",          
  "DELETE",        "UPDATE",        "INSERT",        "SET",         
  "DEFERRABLE",    "FOREIGN",       "DROP",          "UNION",       
  "ALL",           "INTERSECT",     "EXCEPT",        "SELECT",      
  "DISTINCT",      "DOT",           "FROM",          "JOIN",        
  "USING",         "ORDER",         "BY",            "GROUP",       
  "HAVING",        "LIMIT",         "WHERE",         "INTO",        
  "VALUES",        "INTEGER",       "FLOAT",         "BLOB",        
  "REGISTER",      "VARIABLE",      "EXISTS",        "CASE",        
  "WHEN",          "THEN",          "ELSE",          "INDEX",       

  "TO",            "error",         "input",         "cmdlist",     
  "ecmd",          "cmdx",          "cmd",           "explain",     
  "transtype",     "trans_opt",     "nm",            "create_table",
  "create_table_args",  "temp",          "dbnm",          "columnlist",  
  "conslist_opt",  "select",        "column",        "columnid",    
  "type",          "carglist",      "id",            "ids",         
  "typename",      "signed",        "plus_num",      "minus_num",   
  "carg",          "ccons",         "term",          "onconf",      
  "sortorder",     "autoinc",       "expr",          "idxlist_opt", 
  "refargs",       "defer_subclause",  "refarg",        "refact",      
  "init_deferred_pred_opt",  "conslist",      "tcons",         "idxlist",     
  "defer_subclause_opt",  "orconf",        "resolvetype",   "raisetype",   

  "fullname",      "oneselect",     "multiselect_op",  "distinct",    
  "selcollist",    "from",          "where_opt",     "groupby_opt", 
  "having_opt",    "orderby_opt",   "limit_opt",     "sclp",        
  "as",            "seltablist",    "stl_prefix",    "joinop",      
  "on_opt",        "using_opt",     "seltablist_paren",  "joinop2",     
  "inscollist",    "sortlist",      "sortitem",      "collate",     
  "exprlist",      "setlist",       "insert_cmd",    "inscollist_opt",
  "itemlist",      "likeop",        "escape",        "between_op",  
  "in_op",         "case_operand",  "case_exprlist",  "case_else",   
  "expritem",      "uniqueflag",    "idxitem",       "plus_opt",    
  "number",        "trigger_decl",  "trigger_cmd_list",  "trigger_time",
  "trigger_event",  "foreach_clause",  "when_clause",   "trigger_cmd", 
  "database_kw_opt",  "key_opt",     
};
#endif /* NDEBUG */

#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const yyRuleName[] = {
 /*   0 */ "input ::= cmdlist",
 /*   1 */ "cmdlist ::= cmdlist ecmd",
 /*   2 */ "cmdlist ::= ecmd",
 /*   3 */ "cmdx ::= cmd",
 /*   4 */ "ecmd ::= SEMI",
 /*   5 */ "ecmd ::= explain cmdx SEMI",
 /*   6 */ "explain ::=",
 /*   7 */ "explain ::= EXPLAIN",

 /*   8 */ "cmd ::= BEGIN transtype trans_opt",
 /*   9 */ "trans_opt ::=",
 /*  10 */ "trans_opt ::= TRANSACTION",
 /*  11 */ "trans_opt ::= TRANSACTION nm",
 /*  12 */ "transtype ::=",
 /*  13 */ "transtype ::= DEFERRED",
 /*  14 */ "transtype ::= IMMEDIATE",
 /*  15 */ "transtype ::= EXCLUSIVE",

 /*  16 */ "cmd ::= COMMIT trans_opt",
 /*  17 */ "cmd ::= END trans_opt",
 /*  18 */ "cmd ::= ROLLBACK trans_opt",
 /*  19 */ "cmd ::= create_table create_table_args",
 /*  20 */ "create_table ::= CREATE temp TABLE nm dbnm",


 /*  21 */ "temp ::= TEMP",
 /*  22 */ "temp ::=",
 /*  23 */ "create_table_args ::= LP columnlist conslist_opt RP",
 /*  24 */ "create_table_args ::= AS select",
 /*  25 */ "columnlist ::= columnlist COMMA column",
 /*  26 */ "columnlist ::= column",
 /*  27 */ "column ::= columnid type carglist",
 /*  28 */ "columnid ::= nm",
 /*  29 */ "id ::= ID",
 /*  30 */ "ids ::= ID",
 /*  31 */ "ids ::= STRING",
 /*  32 */ "nm ::= ID",
 /*  33 */ "nm ::= STRING",
 /*  34 */ "nm ::= JOIN_KW",
 /*  35 */ "type ::=",
 /*  36 */ "type ::= typename",

 /*  37 */ "type ::= typename LP signed RP",
 /*  38 */ "type ::= typename LP signed COMMA signed RP",
 /*  39 */ "typename ::= ids",
 /*  40 */ "typename ::= typename ids",
 /*  41 */ "signed ::= plus_num",
 /*  42 */ "signed ::= minus_num",
 /*  43 */ "carglist ::= carglist carg",
 /*  44 */ "carglist ::=",
 /*  45 */ "carg ::= CONSTRAINT nm ccons",
 /*  46 */ "carg ::= ccons",
 /*  47 */ "carg ::= DEFAULT term",

 /*  48 */ "carg ::= DEFAULT PLUS term",
 /*  49 */ "carg ::= DEFAULT MINUS term",
 /*  50 */ "carg ::= DEFAULT id",
 /*  51 */ "ccons ::= NULL onconf",
 /*  52 */ "ccons ::= NOT NULL onconf",
 /*  53 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
 /*  54 */ "ccons ::= UNIQUE onconf",
 /*  55 */ "ccons ::= CHECK LP expr RP onconf",
 /*  56 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
 /*  57 */ "ccons ::= defer_subclause",
 /*  58 */ "ccons ::= COLLATE id",
 /*  59 */ "autoinc ::=",
 /*  60 */ "autoinc ::= AUTOINCR",
 /*  61 */ "refargs ::=",
 /*  62 */ "refargs ::= refargs refarg",
 /*  63 */ "refarg ::= MATCH nm",
 /*  64 */ "refarg ::= ON DELETE refact",
 /*  65 */ "refarg ::= ON UPDATE refact",




 /*  66 */ "refarg ::= ON INSERT refact",
 /*  67 */ "refact ::= SET NULL",
 /*  68 */ "refact ::= SET DEFAULT",
 /*  69 */ "refact ::= CASCADE",
 /*  70 */ "refact ::= RESTRICT",
 /*  71 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
 /*  72 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
 /*  73 */ "init_deferred_pred_opt ::=",
 /*  74 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
 /*  75 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
 /*  76 */ "conslist_opt ::=",
 /*  77 */ "conslist_opt ::= COMMA conslist",
 /*  78 */ "conslist ::= conslist COMMA tcons",
 /*  79 */ "conslist ::= conslist tcons",
 /*  80 */ "conslist ::= tcons",
 /*  81 */ "tcons ::= CONSTRAINT nm",
 /*  82 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
 /*  83 */ "tcons ::= UNIQUE LP idxlist RP onconf",
 /*  84 */ "tcons ::= CHECK expr onconf",
 /*  85 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
 /*  86 */ "defer_subclause_opt ::=",
 /*  87 */ "defer_subclause_opt ::= defer_subclause",
 /*  88 */ "onconf ::=",
 /*  89 */ "onconf ::= ON CONFLICT resolvetype",
 /*  90 */ "orconf ::=",
 /*  91 */ "orconf ::= OR resolvetype",
 /*  92 */ "resolvetype ::= raisetype",
 /*  93 */ "resolvetype ::= IGNORE",
 /*  94 */ "resolvetype ::= REPLACE",
 /*  95 */ "cmd ::= DROP TABLE fullname",


 /*  96 */ "cmd ::= CREATE temp VIEW nm dbnm AS select",
 /*  97 */ "cmd ::= DROP VIEW fullname",
 /*  98 */ "cmd ::= select",
 /*  99 */ "select ::= oneselect",
 /* 100 */ "select ::= select multiselect_op oneselect",
 /* 101 */ "multiselect_op ::= UNION",
 /* 102 */ "multiselect_op ::= UNION ALL",
 /* 103 */ "multiselect_op ::= INTERSECT",
 /* 104 */ "multiselect_op ::= EXCEPT",
 /* 105 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
 /* 106 */ "distinct ::= DISTINCT",
 /* 107 */ "distinct ::= ALL",
 /* 108 */ "distinct ::=",
 /* 109 */ "sclp ::= selcollist COMMA",
 /* 110 */ "sclp ::=",
 /* 111 */ "selcollist ::= sclp expr as",
 /* 112 */ "selcollist ::= sclp STAR",
 /* 113 */ "selcollist ::= sclp nm DOT STAR",
 /* 114 */ "as ::= AS nm",
 /* 115 */ "as ::= ids",
 /* 116 */ "as ::=",
 /* 117 */ "from ::=",
 /* 118 */ "from ::= FROM seltablist",
 /* 119 */ "stl_prefix ::= seltablist joinop",
 /* 120 */ "stl_prefix ::=",
 /* 121 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt",
 /* 122 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt",
 /* 123 */ "seltablist_paren ::= select",
 /* 124 */ "seltablist_paren ::= seltablist",
 /* 125 */ "dbnm ::=",
 /* 126 */ "dbnm ::= DOT nm",
 /* 127 */ "fullname ::= nm dbnm",
 /* 128 */ "joinop ::= COMMA",
 /* 129 */ "joinop ::= JOIN",
 /* 130 */ "joinop ::= JOIN_KW JOIN",
 /* 131 */ "joinop ::= JOIN_KW nm JOIN",
 /* 132 */ "joinop ::= JOIN_KW nm nm JOIN",
 /* 133 */ "on_opt ::= ON expr",
 /* 134 */ "on_opt ::=",
 /* 135 */ "using_opt ::= USING LP inscollist RP",
 /* 136 */ "using_opt ::=",
 /* 137 */ "orderby_opt ::=",
 /* 138 */ "orderby_opt ::= ORDER BY sortlist",
 /* 139 */ "sortlist ::= sortlist COMMA sortitem collate sortorder",
 /* 140 */ "sortlist ::= sortitem collate sortorder",
 /* 141 */ "sortitem ::= expr",
 /* 142 */ "sortorder ::= ASC",
 /* 143 */ "sortorder ::= DESC",
 /* 144 */ "sortorder ::=",
 /* 145 */ "collate ::=",
 /* 146 */ "collate ::= COLLATE id",
 /* 147 */ "groupby_opt ::=",
 /* 148 */ "groupby_opt ::= GROUP BY exprlist",
 /* 149 */ "having_opt ::=",
 /* 150 */ "having_opt ::= HAVING expr",
 /* 151 */ "limit_opt ::=",
 /* 152 */ "limit_opt ::= LIMIT expr",
 /* 153 */ "limit_opt ::= LIMIT expr OFFSET expr",
 /* 154 */ "limit_opt ::= LIMIT expr COMMA expr",
 /* 155 */ "cmd ::= DELETE FROM fullname where_opt",
 /* 156 */ "where_opt ::=",
 /* 157 */ "where_opt ::= WHERE expr",
 /* 158 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt",
 /* 159 */ "setlist ::= setlist COMMA nm EQ expr",
 /* 160 */ "setlist ::= nm EQ expr",
 /* 161 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
 /* 162 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
 /* 163 */ "insert_cmd ::= INSERT orconf",
 /* 164 */ "insert_cmd ::= REPLACE",
 /* 165 */ "itemlist ::= itemlist COMMA expr",
 /* 166 */ "itemlist ::= expr",
 /* 167 */ "inscollist_opt ::=",
 /* 168 */ "inscollist_opt ::= LP inscollist RP",
 /* 169 */ "inscollist ::= inscollist COMMA nm",
 /* 170 */ "inscollist ::= nm",
 /* 171 */ "expr ::= term",
 /* 172 */ "expr ::= LP expr RP",
 /* 173 */ "term ::= NULL",
 /* 174 */ "expr ::= ID",
 /* 175 */ "expr ::= JOIN_KW",
 /* 176 */ "expr ::= nm DOT nm",
 /* 177 */ "expr ::= nm DOT nm DOT nm",
 /* 178 */ "term ::= INTEGER",
 /* 179 */ "term ::= FLOAT",
 /* 180 */ "term ::= STRING",
 /* 181 */ "expr ::= BLOB",
 /* 182 */ "expr ::= REGISTER",
 /* 183 */ "expr ::= VARIABLE",
 /* 184 */ "expr ::= ID LP exprlist RP",
 /* 185 */ "expr ::= ID LP STAR RP",
 /* 186 */ "term ::= CTIME",
 /* 187 */ "term ::= CDATE",
 /* 188 */ "term ::= CTIMESTAMP",
 /* 189 */ "expr ::= expr AND expr",
 /* 190 */ "expr ::= expr OR expr",
 /* 191 */ "expr ::= expr LT expr",
 /* 192 */ "expr ::= expr GT expr",
 /* 193 */ "expr ::= expr LE expr",
 /* 194 */ "expr ::= expr GE expr",
 /* 195 */ "expr ::= expr NE expr",
 /* 196 */ "expr ::= expr EQ expr",
 /* 197 */ "expr ::= expr BITAND expr",
 /* 198 */ "expr ::= expr BITOR expr",
 /* 199 */ "expr ::= expr LSHIFT expr",
 /* 200 */ "expr ::= expr RSHIFT expr",
 /* 201 */ "expr ::= expr PLUS expr",
 /* 202 */ "expr ::= expr MINUS expr",
 /* 203 */ "expr ::= expr STAR expr",
 /* 204 */ "expr ::= expr SLASH expr",
 /* 205 */ "expr ::= expr REM expr",
 /* 206 */ "expr ::= expr CONCAT expr",
 /* 207 */ "likeop ::= LIKE",
 /* 208 */ "likeop ::= GLOB",
 /* 209 */ "likeop ::= NOT LIKE",
 /* 210 */ "likeop ::= NOT GLOB",
 /* 211 */ "escape ::= ESCAPE expr",
 /* 212 */ "escape ::=",
 /* 213 */ "expr ::= expr likeop expr escape",
 /* 214 */ "expr ::= expr ISNULL",
 /* 215 */ "expr ::= expr IS NULL",
 /* 216 */ "expr ::= expr NOTNULL",
 /* 217 */ "expr ::= expr NOT NULL",
 /* 218 */ "expr ::= expr IS NOT NULL",
 /* 219 */ "expr ::= NOT expr",
 /* 220 */ "expr ::= BITNOT expr",
 /* 221 */ "expr ::= MINUS expr",
 /* 222 */ "expr ::= PLUS expr",
 /* 223 */ "between_op ::= BETWEEN",
 /* 224 */ "between_op ::= NOT BETWEEN",
 /* 225 */ "expr ::= expr between_op expr AND expr",
 /* 226 */ "in_op ::= IN",
 /* 227 */ "in_op ::= NOT IN",
 /* 228 */ "expr ::= expr in_op LP exprlist RP",
 /* 229 */ "expr ::= LP select RP",
 /* 230 */ "expr ::= expr in_op LP select RP",
 /* 231 */ "expr ::= expr in_op nm dbnm",
 /* 232 */ "expr ::= EXISTS LP select RP",
 /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END",
 /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
 /* 235 */ "case_exprlist ::= WHEN expr THEN expr",
 /* 236 */ "case_else ::= ELSE expr",
 /* 237 */ "case_else ::=",
 /* 238 */ "case_operand ::= expr",
 /* 239 */ "case_operand ::=",
 /* 240 */ "exprlist ::= exprlist COMMA expritem",
 /* 241 */ "exprlist ::= expritem",
 /* 242 */ "expritem ::= expr",
 /* 243 */ "expritem ::=",
 /* 244 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON nm LP idxlist RP onconf",
 /* 245 */ "uniqueflag ::= UNIQUE",
 /* 246 */ "uniqueflag ::=",
 /* 247 */ "idxlist_opt ::=",
 /* 248 */ "idxlist_opt ::= LP idxlist RP",
 /* 249 */ "idxlist ::= idxlist COMMA idxitem collate sortorder",
 /* 250 */ "idxlist ::= idxitem collate sortorder",
 /* 251 */ "idxitem ::= nm",
 /* 252 */ "cmd ::= DROP INDEX fullname",
 /* 253 */ "cmd ::= VACUUM",
 /* 254 */ "cmd ::= VACUUM nm",
 /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nm",
 /* 256 */ "cmd ::= PRAGMA nm dbnm EQ ON",
 /* 257 */ "cmd ::= PRAGMA nm dbnm EQ plus_num",
 /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
 /* 259 */ "cmd ::= PRAGMA nm dbnm LP nm RP",
 /* 260 */ "cmd ::= PRAGMA nm dbnm",
 /* 261 */ "plus_num ::= plus_opt number",
 /* 262 */ "minus_num ::= MINUS number",
 /* 263 */ "number ::= INTEGER",
 /* 264 */ "number ::= FLOAT",
 /* 265 */ "plus_opt ::= PLUS",
 /* 266 */ "plus_opt ::=",
 /* 267 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
 /* 268 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
 /* 269 */ "trigger_time ::= BEFORE",
 /* 270 */ "trigger_time ::= AFTER",
 /* 271 */ "trigger_time ::= INSTEAD OF",
 /* 272 */ "trigger_time ::=",
 /* 273 */ "trigger_event ::= DELETE",
 /* 274 */ "trigger_event ::= INSERT",
 /* 275 */ "trigger_event ::= UPDATE",
 /* 276 */ "trigger_event ::= UPDATE OF inscollist",
 /* 277 */ "foreach_clause ::=",
 /* 278 */ "foreach_clause ::= FOR EACH ROW",
 /* 279 */ "foreach_clause ::= FOR EACH STATEMENT",
 /* 280 */ "when_clause ::=",
 /* 281 */ "when_clause ::= WHEN expr",
 /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list",
 /* 283 */ "trigger_cmd_list ::=",
 /* 284 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
 /* 285 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
 /* 286 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
 /* 287 */ "trigger_cmd ::= DELETE FROM nm where_opt",
 /* 288 */ "trigger_cmd ::= select",
 /* 289 */ "expr ::= RAISE LP IGNORE RP",
 /* 290 */ "expr ::= RAISE LP raisetype COMMA nm RP",
 /* 291 */ "raisetype ::= ROLLBACK",
 /* 292 */ "raisetype ::= ABORT",
 /* 293 */ "raisetype ::= FAIL",
 /* 294 */ "cmd ::= DROP TRIGGER fullname",
 /* 295 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt",
 /* 296 */ "key_opt ::=",
 /* 297 */ "key_opt ::= KEY ids",
 /* 298 */ "key_opt ::= KEY BLOB",
 /* 299 */ "database_kw_opt ::= DATABASE",
 /* 300 */ "database_kw_opt ::=",
 /* 301 */ "cmd ::= DETACH database_kw_opt nm",
 /* 302 */ "cmd ::= REINDEX",
 /* 303 */ "cmd ::= REINDEX nm dbnm",


 /* 304 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",




};
#endif /* NDEBUG */

/*
** This function returns the symbolic name associated with a token
** value.
*/
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255






1256













1257
1258
1259

1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
    ** reduce or during error processing or when a parser is 
    ** being destroyed before it is finished parsing.
    **
    ** Note: during a reduce, the only symbols destroyed are those
    ** which appear on the RHS of the rule, but which are not used
    ** inside the C code.
    */
    case 154:
    case 188:
    case 205:
#line 368 "parse.y"
{sqlite3SelectDelete((yypminor->yy239));}
#line 1217 "parse.c"
      break;
    case 168:
    case 169:
    case 193:
    case 195:
    case 203:
    case 209:
    case 217:
    case 220:
    case 222:
    case 223:
    case 233:
#line 625 "parse.y"
{sqlite3ExprDelete((yypminor->yy178));}
#line 1232 "parse.c"
      break;
    case 173:
    case 181:
    case 191:
    case 194:
    case 196:
    case 198:
    case 208:
    case 211:
    case 212:
    case 215:
    case 221:
#line 857 "parse.y"
{sqlite3ExprListDelete((yypminor->yy462));}
#line 1247 "parse.c"
      break;
    case 187:
    case 192:
    case 200:
    case 201:
#line 496 "parse.y"
{sqlite3SrcListDelete((yypminor->yy285));}
#line 1255 "parse.c"
      break;
    case 197:






#line 557 "parse.y"













{
  sqlite3ExprDelete((yypminor->yy270).pLimit);
  sqlite3ExprDelete((yypminor->yy270).pOffset);

}
#line 1263 "parse.c"
      break;
    case 204:
    case 207:
    case 214:
#line 513 "parse.y"
{sqlite3IdListDelete((yypminor->yy160));}
#line 1270 "parse.c"
      break;
    case 229:
    case 234:
#line 951 "parse.y"
{sqlite3DeleteTriggerStep((yypminor->yy247));}
#line 1276 "parse.c"
      break;
    case 231:
#line 935 "parse.y"
{sqlite3IdListDelete((yypminor->yy132).b);}
#line 1281 "parse.c"
      break;
    case 236:
#line 1010 "parse.y"
{sqlite3ExprDelete((yypminor->yy292));}
#line 1286 "parse.c"
      break;
    default:  break;   /* If no destructor action specified: do nothing */
  }
}

/*
** Pop the parser's stack once.







|
|
|
|
|
|

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

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

|
<
<
<
<
<

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

<
|
>

|

|
|
|
|
|
|

|
|
|
|
|

|
|
|
|
<
<
<
<
<







1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321




1322
1323
1324
1325
1326
1327














1328
1329





1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351

1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373





1374
1375
1376
1377
1378
1379
1380
    ** reduce or during error processing or when a parser is 
    ** being destroyed before it is finished parsing.
    **
    ** Note: during a reduce, the only symbols destroyed are those
    ** which appear on the RHS of the rule, but which are not used
    ** inside the C code.
    */
    case 157:
    case 189:
    case 206:
#line 325 "parse.y"
{sqlite3SelectDelete((yypminor->yy331));}
#line 1315 "parse.c"
      break;
    case 170:
    case 174:
    case 194:
    case 196:
    case 204:
    case 210:
    case 224:




#line 584 "parse.y"
{sqlite3ExprDelete((yypminor->yy454));}
#line 1326 "parse.c"
      break;
    case 175:
    case 183:














    case 192:
    case 195:





    case 197:
    case 199:
    case 209:
    case 212:
    case 213:
    case 216:
    case 222:
#line 796 "parse.y"
{sqlite3ExprListDelete((yypminor->yy266));}
#line 1341 "parse.c"
      break;
    case 188:
    case 193:
    case 201:
    case 202:
#line 454 "parse.y"
{sqlite3SrcListDelete((yypminor->yy427));}
#line 1349 "parse.c"
      break;
    case 198:
#line 516 "parse.y"
{

  sqlite3ExprDelete((yypminor->yy348).pLimit);
  sqlite3ExprDelete((yypminor->yy348).pOffset);
}
#line 1357 "parse.c"
      break;
    case 205:
    case 208:
    case 215:
#line 472 "parse.y"
{sqlite3IdListDelete((yypminor->yy272));}
#line 1364 "parse.c"
      break;
    case 230:
    case 235:
#line 889 "parse.y"
{sqlite3DeleteTriggerStep((yypminor->yy455));}
#line 1370 "parse.c"
      break;
    case 232:
#line 873 "parse.y"
{sqlite3IdListDelete((yypminor->yy62).b);}
#line 1375 "parse.c"





      break;
    default:  break;   /* If no destructor action specified: do nothing */
  }
}

/*
** Pop the parser's stack once.
1346
1347
1348
1349
1350
1351
1352

1353

1354
1355
1356
1357
1358
1359
1360
static int yy_find_shift_action(
  yyParser *pParser,        /* The parser */
  int iLookAhead            /* The look-ahead token */
){
  int i;
  int stateno = pParser->yystack[pParser->yyidx].stateno;
 

  if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){

    return yy_default[stateno];
  }
  if( iLookAhead==YYNOCODE ){
    return YY_NO_ACTION;
  }
  i += iLookAhead;
  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){







>
|
>







1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
static int yy_find_shift_action(
  yyParser *pParser,        /* The parser */
  int iLookAhead            /* The look-ahead token */
){
  int i;
  int stateno = pParser->yystack[pParser->yyidx].stateno;
 
  /* if( pParser->yyidx<0 ) return YY_NO_ACTION;  */
  i = yy_shift_ofst[stateno];
  if( i==YY_SHIFT_USE_DFLT ){
    return yy_default[stateno];
  }
  if( iLookAhead==YYNOCODE ){
    return YY_NO_ACTION;
  }
  i += iLookAhead;
  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
static int yy_find_reduce_action(
  int stateno,              /* Current state number */
  int iLookAhead            /* The look-ahead token */
){
  int i;
  /* int stateno = pParser->yystack[pParser->yyidx].stateno; */
 
  if( stateno>YY_REDUCE_MAX ||
      (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){
    return yy_default[stateno];
  }
  if( iLookAhead==YYNOCODE ){
    return YY_NO_ACTION;
  }
  i += iLookAhead;
  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){







|
|







1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
static int yy_find_reduce_action(
  int stateno,              /* Current state number */
  int iLookAhead            /* The look-ahead token */
){
  int i;
  /* int stateno = pParser->yystack[pParser->yyidx].stateno; */
 
  i = yy_reduce_ofst[stateno];
  if( i==YY_REDUCE_USE_DFLT ){
    return yy_default[stateno];
  }
  if( iLookAhead==YYNOCODE ){
    return YY_NO_ACTION;
  }
  i += iLookAhead;
  if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489

1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504


1505
1506


1507
1508
1509



1510


1511

1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542


1543
1544
1545
1546


1547


1548
1549
1550
1551
1552
1553
1554
1555


1556
1557
1558
1559


1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619


1620
1621
1622

1623
1624
1625
1626


1627
1628

1629
1630


1631
1632
1633
1634
1635
1636
1637
1638
1639


1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651

1652
1653
1654


1655
1656
1657









































1658
1659


1660
1661
1662

1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673



1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696






1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709

1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721

1722
1723
1724
1725
1726
1727



1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740

1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
/* The following table contains information about every rule that
** is used during the reduce.
*/
static const struct {
  YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
  unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
} yyRuleInfo[] = {
  { 138, 1 },
  { 139, 2 },
  { 139, 1 },
  { 141, 1 },
  { 140, 1 },
  { 140, 3 },
  { 143, 0 },
  { 143, 1 },
  { 143, 3 },
  { 142, 3 },
  { 145, 0 },
  { 145, 1 },
  { 145, 2 },
  { 144, 0 },
  { 144, 1 },
  { 144, 1 },
  { 144, 1 },
  { 142, 2 },
  { 142, 2 },
  { 142, 2 },
  { 142, 2 },
  { 147, 6 },
  { 150, 0 },
  { 150, 3 },
  { 149, 1 },
  { 149, 0 },
  { 148, 4 },
  { 148, 2 },
  { 152, 3 },
  { 152, 1 },
  { 155, 3 },
  { 156, 1 },

  { 159, 1 },
  { 160, 1 },
  { 146, 1 },
  { 146, 1 },
  { 146, 1 },
  { 157, 0 },
  { 157, 1 },
  { 161, 1 },
  { 161, 4 },
  { 161, 6 },
  { 162, 1 },
  { 162, 2 },
  { 163, 1 },
  { 163, 1 },
  { 158, 2 },


  { 158, 0 },
  { 166, 3 },


  { 166, 1 },
  { 166, 2 },
  { 166, 4 },



  { 166, 3 },


  { 166, 3 },

  { 166, 2 },
  { 167, 2 },
  { 167, 3 },
  { 167, 5 },
  { 167, 2 },
  { 167, 4 },
  { 167, 4 },
  { 167, 1 },
  { 167, 2 },
  { 172, 0 },
  { 172, 1 },
  { 174, 0 },
  { 174, 2 },
  { 176, 2 },
  { 176, 3 },
  { 176, 3 },
  { 176, 3 },
  { 177, 2 },
  { 177, 2 },
  { 177, 1 },
  { 177, 1 },
  { 175, 3 },
  { 175, 2 },
  { 178, 0 },
  { 178, 2 },
  { 178, 2 },
  { 153, 0 },
  { 153, 2 },
  { 179, 3 },
  { 179, 2 },
  { 179, 1 },


  { 180, 2 },
  { 180, 7 },
  { 180, 5 },
  { 180, 5 },


  { 180, 10 },


  { 182, 0 },
  { 182, 1 },
  { 170, 0 },
  { 170, 3 },
  { 183, 0 },
  { 183, 2 },
  { 184, 1 },
  { 184, 1 },


  { 184, 1 },
  { 142, 4 },
  { 186, 2 },
  { 186, 0 },


  { 142, 7 },
  { 142, 4 },
  { 142, 1 },
  { 154, 1 },
  { 154, 3 },
  { 189, 1 },
  { 189, 2 },
  { 189, 1 },
  { 188, 9 },
  { 190, 1 },
  { 190, 1 },
  { 190, 0 },
  { 198, 2 },
  { 198, 0 },
  { 191, 3 },
  { 191, 2 },
  { 191, 4 },
  { 199, 2 },
  { 199, 1 },
  { 199, 0 },
  { 192, 0 },
  { 192, 2 },
  { 201, 2 },
  { 201, 0 },
  { 200, 6 },
  { 200, 7 },
  { 205, 1 },
  { 205, 1 },
  { 151, 0 },
  { 151, 2 },
  { 187, 2 },
  { 202, 1 },
  { 202, 2 },
  { 202, 3 },
  { 202, 4 },
  { 203, 2 },
  { 203, 0 },
  { 204, 4 },
  { 204, 0 },
  { 196, 0 },
  { 196, 3 },
  { 208, 5 },
  { 208, 3 },
  { 209, 1 },
  { 171, 1 },
  { 171, 1 },
  { 171, 0 },
  { 210, 0 },
  { 210, 2 },
  { 194, 0 },
  { 194, 3 },
  { 195, 0 },
  { 195, 2 },
  { 197, 0 },
  { 197, 2 },
  { 197, 4 },
  { 197, 4 },
  { 142, 4 },
  { 193, 0 },
  { 193, 2 },


  { 142, 6 },
  { 212, 5 },
  { 212, 3 },

  { 142, 8 },
  { 142, 5 },
  { 213, 2 },
  { 213, 1 },


  { 215, 3 },
  { 215, 1 },

  { 214, 0 },
  { 214, 3 },


  { 207, 3 },
  { 207, 1 },
  { 169, 1 },
  { 169, 3 },
  { 168, 1 },
  { 169, 1 },
  { 169, 1 },
  { 169, 3 },
  { 169, 5 },


  { 168, 1 },
  { 168, 1 },
  { 169, 1 },
  { 169, 1 },
  { 169, 6 },
  { 169, 5 },
  { 169, 4 },
  { 168, 1 },
  { 169, 3 },
  { 169, 3 },
  { 169, 3 },
  { 169, 3 },

  { 169, 3 },
  { 169, 3 },
  { 169, 3 },


  { 169, 3 },
  { 216, 1 },
  { 216, 2 },









































  { 217, 2 },
  { 217, 0 },


  { 169, 4 },
  { 169, 2 },
  { 169, 3 },

  { 169, 3 },
  { 169, 4 },
  { 169, 2 },
  { 169, 2 },
  { 169, 2 },
  { 218, 1 },
  { 218, 2 },
  { 169, 5 },
  { 219, 1 },
  { 219, 2 },
  { 169, 5 },



  { 169, 3 },
  { 169, 5 },
  { 169, 4 },
  { 169, 4 },
  { 169, 5 },
  { 221, 5 },
  { 221, 4 },
  { 222, 2 },
  { 222, 0 },
  { 220, 1 },
  { 220, 0 },
  { 211, 3 },
  { 211, 1 },
  { 223, 1 },
  { 223, 0 },
  { 142, 12 },
  { 224, 1 },
  { 224, 0 },
  { 173, 0 },
  { 173, 3 },
  { 181, 5 },
  { 181, 3 },
  { 225, 1 },






  { 142, 4 },
  { 142, 1 },
  { 142, 2 },
  { 142, 5 },
  { 142, 5 },
  { 142, 5 },
  { 142, 5 },
  { 142, 6 },
  { 142, 3 },
  { 164, 2 },
  { 165, 2 },
  { 227, 1 },
  { 226, 1 },

  { 226, 0 },
  { 142, 5 },
  { 228, 10 },
  { 230, 1 },
  { 230, 1 },
  { 230, 2 },
  { 230, 0 },
  { 231, 1 },
  { 231, 1 },
  { 231, 3 },
  { 232, 0 },
  { 232, 3 },

  { 232, 3 },
  { 233, 0 },
  { 233, 2 },
  { 229, 3 },
  { 229, 0 },
  { 234, 6 },



  { 234, 8 },
  { 234, 5 },
  { 234, 4 },
  { 234, 1 },
  { 169, 4 },
  { 169, 6 },
  { 185, 1 },
  { 185, 1 },
  { 185, 1 },
  { 142, 3 },
  { 142, 6 },
  { 236, 0 },
  { 236, 2 },

  { 235, 1 },
  { 235, 0 },
  { 142, 3 },
  { 142, 1 },
  { 142, 3 },
  { 142, 1 },
  { 142, 3 },
  { 142, 6 },
  { 142, 6 },
  { 237, 1 },
  { 238, 0 },
  { 238, 1 },
};

static void yy_accept(yyParser*);  /* Forward Declaration */

/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.







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

|
>

<
<
<
<
<
<
<
<
<

<


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

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


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

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


|
<
<
|
|
|

<

|

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


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

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

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


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


|
<
<
<

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

|
|
|
|
>


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







1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557

1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568

1569

1570
1571


1572
1573
1574
1575
1576
1577









1578

1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610

1611



1612





1613
1614
1615


1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634

1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651


1652
1653
1654


1655
1656
1657
1658

1659
1660
1661
1662

1663
1664


1665





























1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688

1689
1690

1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770

1771

1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790



1791
1792
1793



1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818



1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852


1853




1854
1855
1856
1857
1858
1859
1860
/* The following table contains information about every rule that
** is used during the reduce.
*/
static const struct {
  YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
  unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
} yyRuleInfo[] = {
  { 142, 1 },
  { 143, 2 },
  { 143, 1 },
  { 145, 1 },
  { 144, 1 },
  { 144, 3 },
  { 147, 0 },
  { 147, 1 },
  { 146, 3 },

  { 149, 0 },
  { 149, 1 },
  { 149, 2 },
  { 148, 0 },
  { 148, 1 },
  { 148, 1 },
  { 148, 1 },
  { 146, 2 },
  { 146, 2 },
  { 146, 2 },
  { 146, 2 },

  { 151, 5 },

  { 153, 1 },
  { 153, 0 },


  { 152, 4 },
  { 152, 2 },
  { 155, 3 },
  { 155, 1 },
  { 158, 3 },
  { 159, 1 },









  { 162, 1 },

  { 163, 1 },
  { 163, 1 },
  { 150, 1 },
  { 150, 1 },
  { 150, 1 },
  { 160, 0 },
  { 160, 1 },
  { 160, 4 },
  { 160, 6 },
  { 164, 1 },
  { 164, 2 },
  { 165, 1 },
  { 165, 1 },
  { 161, 2 },
  { 161, 0 },
  { 168, 3 },
  { 168, 1 },
  { 168, 2 },
  { 168, 3 },
  { 168, 3 },
  { 168, 2 },
  { 169, 2 },
  { 169, 3 },
  { 169, 5 },
  { 169, 2 },
  { 169, 5 },
  { 169, 4 },
  { 169, 1 },
  { 169, 2 },
  { 173, 0 },
  { 173, 1 },
  { 176, 0 },

  { 176, 2 },



  { 178, 2 },





  { 178, 3 },
  { 178, 3 },
  { 178, 3 },


  { 179, 2 },
  { 179, 2 },
  { 179, 1 },
  { 179, 1 },
  { 177, 3 },
  { 177, 2 },
  { 180, 0 },
  { 180, 2 },
  { 180, 2 },
  { 156, 0 },
  { 156, 2 },
  { 181, 3 },
  { 181, 2 },
  { 181, 1 },
  { 182, 2 },
  { 182, 7 },
  { 182, 5 },
  { 182, 3 },
  { 182, 10 },

  { 184, 0 },
  { 184, 1 },
  { 171, 0 },
  { 171, 3 },
  { 185, 0 },
  { 185, 2 },
  { 186, 1 },
  { 186, 1 },
  { 186, 1 },
  { 146, 3 },
  { 146, 7 },
  { 146, 3 },
  { 146, 1 },
  { 157, 1 },
  { 157, 3 },
  { 190, 1 },
  { 190, 2 },


  { 190, 1 },
  { 190, 1 },
  { 189, 9 },


  { 191, 1 },
  { 191, 1 },
  { 191, 0 },
  { 199, 2 },

  { 199, 0 },
  { 192, 3 },
  { 192, 2 },
  { 192, 4 },

  { 200, 2 },
  { 200, 1 },


  { 200, 0 },





























  { 193, 0 },
  { 193, 2 },
  { 202, 2 },
  { 202, 0 },
  { 201, 6 },
  { 201, 7 },
  { 206, 1 },
  { 206, 1 },
  { 154, 0 },
  { 154, 2 },
  { 188, 2 },
  { 203, 1 },
  { 203, 1 },
  { 203, 2 },
  { 203, 3 },
  { 203, 4 },
  { 204, 2 },
  { 204, 0 },
  { 205, 4 },
  { 205, 0 },
  { 197, 0 },
  { 197, 3 },
  { 209, 5 },

  { 209, 3 },
  { 210, 1 },

  { 172, 1 },
  { 172, 1 },
  { 172, 0 },
  { 211, 0 },
  { 211, 2 },
  { 195, 0 },
  { 195, 3 },
  { 196, 0 },
  { 196, 2 },
  { 198, 0 },
  { 198, 2 },
  { 198, 4 },
  { 198, 4 },
  { 146, 4 },
  { 194, 0 },
  { 194, 2 },
  { 146, 6 },
  { 213, 5 },
  { 213, 3 },
  { 146, 8 },
  { 146, 5 },
  { 214, 2 },
  { 214, 1 },
  { 216, 3 },
  { 216, 1 },
  { 215, 0 },
  { 215, 3 },
  { 208, 3 },
  { 208, 1 },
  { 174, 1 },
  { 174, 3 },
  { 170, 1 },
  { 174, 1 },
  { 174, 1 },
  { 174, 3 },
  { 174, 5 },
  { 170, 1 },
  { 170, 1 },
  { 170, 1 },
  { 174, 1 },
  { 174, 1 },
  { 174, 1 },
  { 174, 4 },
  { 174, 4 },
  { 170, 1 },
  { 170, 1 },
  { 170, 1 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 174, 3 },
  { 217, 1 },
  { 217, 1 },
  { 217, 2 },
  { 217, 2 },
  { 218, 2 },
  { 218, 0 },
  { 174, 4 },
  { 174, 2 },
  { 174, 3 },
  { 174, 2 },
  { 174, 3 },
  { 174, 4 },
  { 174, 2 },
  { 174, 2 },
  { 174, 2 },

  { 174, 2 },

  { 219, 1 },
  { 219, 2 },
  { 174, 5 },
  { 220, 1 },
  { 220, 2 },
  { 174, 5 },
  { 174, 3 },
  { 174, 5 },
  { 174, 4 },
  { 174, 4 },
  { 174, 5 },
  { 222, 5 },
  { 222, 4 },
  { 223, 2 },
  { 223, 0 },
  { 221, 1 },
  { 221, 0 },
  { 212, 3 },
  { 212, 1 },



  { 224, 1 },
  { 224, 0 },
  { 146, 11 },



  { 225, 1 },
  { 225, 0 },
  { 175, 0 },
  { 175, 3 },
  { 183, 5 },
  { 183, 3 },
  { 226, 1 },
  { 146, 3 },
  { 146, 1 },
  { 146, 2 },
  { 146, 5 },
  { 146, 5 },
  { 146, 5 },
  { 146, 5 },
  { 146, 6 },
  { 146, 3 },
  { 166, 2 },
  { 167, 2 },
  { 228, 1 },
  { 228, 1 },
  { 227, 1 },
  { 227, 0 },
  { 146, 5 },
  { 229, 10 },
  { 231, 1 },



  { 231, 1 },
  { 231, 2 },
  { 231, 0 },
  { 232, 1 },
  { 232, 1 },
  { 232, 1 },
  { 232, 3 },
  { 233, 0 },
  { 233, 3 },
  { 233, 3 },
  { 234, 0 },
  { 234, 2 },
  { 230, 3 },
  { 230, 0 },
  { 235, 6 },
  { 235, 8 },
  { 235, 5 },
  { 235, 4 },
  { 235, 1 },
  { 174, 4 },
  { 174, 6 },
  { 187, 1 },
  { 187, 1 },
  { 187, 1 },
  { 146, 3 },
  { 146, 6 },
  { 237, 0 },
  { 237, 2 },
  { 237, 2 },
  { 236, 1 },
  { 236, 0 },
  { 146, 3 },
  { 146, 1 },
  { 146, 3 },


  { 146, 6 },




};

static void yy_accept(yyParser*);  /* Forward Declaration */

/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826





1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856










1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873






1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907


1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931




1932




1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970

1971
1972
1973
1974
1975
1976
1977

1978
1979
1980
1981
1982
1983

1984
1985
1986
1987
1988
1989
1990
1991
1992





1993





1994
1995
1996
1997
1998
1999
2000
2001
2002
2003





2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114


2115

2116
2117
2118

2119





2120
2121
2122
2123

2124





2125
2126
2127
2128
2129
2130
2131
2132
2133
2134



2135
2136
2137
2138

2139

2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151

2152
2153
2154

2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165


2166


2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177






2178

2179








2180
2181
2182
2183














2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249

2250










2251
2252
2253
2254








2255




2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311





2312
2313
2314
2315
2316
2317
2318
2319
2320
2321








2322
2323
2324
2325
2326






2327
2328
2329
2330
2331

2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367


2368

2369
2370
2371
2372
2373


2374

2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399




2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455

2456
2457
2458
2459
2460

2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471




2472
2473
2474
2475
2476
2477




2478
2479
2480
2481
2482

2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523














2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546

2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583









2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605




2606
2607
2608
2609
2610
2611
2612
2613
2614
2615

2616

2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678






2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692





2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704

2705
2706



2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719





2720

2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742

2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768

2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799










2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830


2831
2832
2833
2834
2835
2836

2837

2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858

2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893


2894



2895
2896
2897
2898


2899

2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924


2925
2926
2927
2928
2929
2930
2931
2932
2933
2934

2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958

2959


2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002

3003

3004
3005
3006
3007
3008
3009

3010

3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032

3033

3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060




3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
  **   case 0:
  **  #line <lineno> <grammarfile>
  **     { ... }           // User supplied code
  **  #line <lineno> <thisfile>
  **     break;
  */
      case 3:
#line 95 "parse.y"
{ sqlite3FinishCoding(pParse); }
#line 1806 "parse.c"
        break;
      case 6:
#line 98 "parse.y"
{ sqlite3BeginParse(pParse, 0); }
#line 1811 "parse.c"
        break;
      case 7:
#line 100 "parse.y"
{ sqlite3BeginParse(pParse, 1); }
#line 1816 "parse.c"
        break;
      case 8:
#line 101 "parse.y"
{ sqlite3BeginParse(pParse, 2); }
#line 1821 "parse.c"
        break;
      case 9:
#line 107 "parse.y"
{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy230);}
#line 1826 "parse.c"
        break;
      case 13:





#line 112 "parse.y"
{yygotominor.yy230 = TK_DEFERRED;}
#line 1831 "parse.c"
        break;
      case 14:
      case 15:
      case 16:
      case 107:
      case 109:
#line 113 "parse.y"
{yygotominor.yy230 = yymsp[0].major;}
#line 1840 "parse.c"
        break;
      case 17:
      case 18:
#line 116 "parse.y"
{sqlite3CommitTransaction(pParse);}
#line 1846 "parse.c"
        break;
      case 19:
#line 118 "parse.y"
{sqlite3RollbackTransaction(pParse);}
#line 1851 "parse.c"
        break;
      case 21:
#line 123 "parse.y"
{
   sqlite3StartTable(pParse,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384,yymsp[-4].minor.yy230,0,yymsp[-2].minor.yy230);
}
#line 1858 "parse.c"










        break;
      case 22:
      case 25:
      case 63:
      case 77:
      case 79:
      case 90:
      case 101:
      case 112:
      case 113:
      case 210:
      case 213:
#line 127 "parse.y"
{yygotominor.yy230 = 0;}
#line 1873 "parse.c"
        break;
      case 23:






      case 24:
      case 64:
      case 78:
      case 100:
      case 111:
      case 211:
      case 214:
#line 128 "parse.y"
{yygotominor.yy230 = 1;}
#line 1885 "parse.c"
        break;
      case 26:
#line 134 "parse.y"
{
  sqlite3EndTable(pParse,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy0,0);
}
#line 1892 "parse.c"
        break;
      case 27:
#line 137 "parse.y"
{
  sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy239);
  sqlite3SelectDelete(yymsp[0].minor.yy239);
}
#line 1900 "parse.c"
        break;
      case 30:
#line 149 "parse.y"
{
  yygotominor.yy384.z = yymsp[-2].minor.yy384.z;
  yygotominor.yy384.n = (pParse->sLastToken.z-yymsp[-2].minor.yy384.z) + pParse->sLastToken.n;
}
#line 1908 "parse.c"
        break;


      case 31:
#line 153 "parse.y"
{
  sqlite3AddColumn(pParse,&yymsp[0].minor.yy384);
  yygotominor.yy384 = yymsp[0].minor.yy384;
}
#line 1916 "parse.c"
        break;
      case 32:
      case 33:
      case 34:
      case 35:
      case 36:
      case 250:
#line 163 "parse.y"
{yygotominor.yy384 = yymsp[0].minor.yy0;}
#line 1926 "parse.c"
        break;
      case 38:
#line 222 "parse.y"
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy384);}
#line 1931 "parse.c"
        break;
      case 39:




      case 42:




      case 119:
      case 120:
      case 131:
      case 150:
      case 238:
      case 248:
      case 249:
#line 223 "parse.y"
{yygotominor.yy384 = yymsp[0].minor.yy384;}
#line 1944 "parse.c"
        break;
      case 40:
#line 224 "parse.y"
{
  yygotominor.yy384.z = yymsp[-3].minor.yy384.z;
  yygotominor.yy384.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy384.z;
}
#line 1952 "parse.c"
        break;
      case 41:
#line 228 "parse.y"
{
  yygotominor.yy384.z = yymsp[-5].minor.yy384.z;
  yygotominor.yy384.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy384.z;
}
#line 1960 "parse.c"
        break;
      case 43:
#line 234 "parse.y"
{yygotominor.yy384.z=yymsp[-1].minor.yy384.z; yygotominor.yy384.n=yymsp[0].minor.yy384.n+(yymsp[0].minor.yy384.z-yymsp[-1].minor.yy384.z);}
#line 1965 "parse.c"
        break;
      case 44:
#line 236 "parse.y"
{ yygotominor.yy230 = atoi((char*)yymsp[0].minor.yy384.z); }
#line 1970 "parse.c"
        break;
      case 45:

#line 237 "parse.y"
{ yygotominor.yy230 = -atoi((char*)yymsp[0].minor.yy384.z); }
#line 1975 "parse.c"
        break;
      case 50:
      case 52:
#line 246 "parse.y"

{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy178);}
#line 1981 "parse.c"
        break;
      case 51:
#line 247 "parse.y"
{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy178);}

#line 1986 "parse.c"
        break;
      case 53:
#line 249 "parse.y"
{
  Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy178, 0, 0);
  sqlite3AddDefaultValue(pParse,p);
}
#line 1994 "parse.c"





        break;





      case 54:
#line 253 "parse.y"
{
  Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy384);
  sqlite3AddDefaultValue(pParse,p);
}
#line 2002 "parse.c"
        break;
      case 56:
#line 262 "parse.y"





{sqlite3AddNotNull(pParse, yymsp[0].minor.yy230);}
#line 2007 "parse.c"
        break;
      case 57:
#line 264 "parse.y"
{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy230,yymsp[0].minor.yy230,yymsp[-2].minor.yy230);}
#line 2012 "parse.c"
        break;
      case 58:
#line 265 "parse.y"
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy230,0,0,0,0);}
#line 2017 "parse.c"
        break;
      case 59:
#line 266 "parse.y"
{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy178);}
#line 2022 "parse.c"
        break;
      case 60:
#line 268 "parse.y"
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy384,yymsp[-1].minor.yy462,yymsp[0].minor.yy230);}
#line 2027 "parse.c"
        break;
      case 61:
#line 269 "parse.y"
{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy230);}
#line 2032 "parse.c"
        break;
      case 62:
#line 270 "parse.y"
{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy384.z, yymsp[0].minor.yy384.n);}
#line 2037 "parse.c"
        break;
      case 65:
#line 283 "parse.y"
{ yygotominor.yy230 = OE_Restrict * 0x010101; }
#line 2042 "parse.c"
        break;
      case 66:
#line 284 "parse.y"
{ yygotominor.yy230 = (yymsp[-1].minor.yy230 & yymsp[0].minor.yy13.mask) | yymsp[0].minor.yy13.value; }
#line 2047 "parse.c"
        break;
      case 67:
#line 286 "parse.y"
{ yygotominor.yy13.value = 0;     yygotominor.yy13.mask = 0x000000; }
#line 2052 "parse.c"
        break;
      case 68:
#line 287 "parse.y"
{ yygotominor.yy13.value = yymsp[0].minor.yy230;     yygotominor.yy13.mask = 0x0000ff; }
#line 2057 "parse.c"
        break;
      case 69:
#line 288 "parse.y"
{ yygotominor.yy13.value = yymsp[0].minor.yy230<<8;  yygotominor.yy13.mask = 0x00ff00; }
#line 2062 "parse.c"
        break;
      case 70:
#line 289 "parse.y"
{ yygotominor.yy13.value = yymsp[0].minor.yy230<<16; yygotominor.yy13.mask = 0xff0000; }
#line 2067 "parse.c"
        break;
      case 71:
#line 291 "parse.y"
{ yygotominor.yy230 = OE_SetNull; }
#line 2072 "parse.c"
        break;
      case 72:
#line 292 "parse.y"
{ yygotominor.yy230 = OE_SetDflt; }
#line 2077 "parse.c"
        break;
      case 73:
#line 293 "parse.y"
{ yygotominor.yy230 = OE_Cascade; }
#line 2082 "parse.c"
        break;
      case 74:
#line 294 "parse.y"
{ yygotominor.yy230 = OE_Restrict; }
#line 2087 "parse.c"
        break;
      case 75:
      case 76:
      case 91:
      case 93:
      case 95:
      case 96:
      case 167:
#line 296 "parse.y"
{yygotominor.yy230 = yymsp[0].minor.yy230;}
#line 2098 "parse.c"
        break;
      case 80:
#line 306 "parse.y"
{yygotominor.yy384.n = 0; yygotominor.yy384.z = 0;}
#line 2103 "parse.c"
        break;
      case 81:
#line 307 "parse.y"
{yygotominor.yy384 = yymsp[-1].minor.yy0;}
#line 2108 "parse.c"
        break;
      case 86:
#line 313 "parse.y"
{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy462,yymsp[0].minor.yy230,yymsp[-2].minor.yy230,0);}
#line 2113 "parse.c"
        break;
      case 87:
#line 315 "parse.y"


{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy462,yymsp[0].minor.yy230,0,0,0,0);}

#line 2118 "parse.c"
        break;
      case 88:

#line 316 "parse.y"





{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy178);}
#line 2123 "parse.c"
        break;
      case 89:

#line 318 "parse.y"





{
    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy462, &yymsp[-3].minor.yy384, yymsp[-2].minor.yy462, yymsp[-1].minor.yy230);
    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy230);
}
#line 2131 "parse.c"
        break;
      case 92:
      case 94:
#line 332 "parse.y"
{yygotominor.yy230 = OE_Default;}



#line 2137 "parse.c"
        break;
      case 97:
#line 337 "parse.y"

{yygotominor.yy230 = OE_Ignore;}

#line 2142 "parse.c"
        break;
      case 98:
      case 168:
#line 338 "parse.y"
{yygotominor.yy230 = OE_Replace;}
#line 2148 "parse.c"
        break;
      case 99:
#line 342 "parse.y"
{
  sqlite3DropTable(pParse, yymsp[0].minor.yy285, 0, yymsp[-1].minor.yy230);

}
#line 2155 "parse.c"
        break;

      case 102:
#line 352 "parse.y"
{
  sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy384, &yymsp[-2].minor.yy384, yymsp[0].minor.yy239, yymsp[-5].minor.yy230);
}
#line 2162 "parse.c"
        break;
      case 103:
#line 355 "parse.y"
{
  sqlite3DropTable(pParse, yymsp[0].minor.yy285, 1, yymsp[-1].minor.yy230);


}


#line 2169 "parse.c"
        break;
      case 104:
#line 362 "parse.y"
{
  sqlite3Select(pParse, yymsp[0].minor.yy239, SRT_Callback, 0, 0, 0, 0, 0);
  sqlite3SelectDelete(yymsp[0].minor.yy239);
}
#line 2177 "parse.c"
        break;
      case 105:






      case 128:

#line 372 "parse.y"








{yygotominor.yy239 = yymsp[0].minor.yy239;}
#line 2183 "parse.c"
        break;
      case 106:














#line 374 "parse.y"
{
  if( yymsp[0].minor.yy239 ){
    yymsp[0].minor.yy239->op = yymsp[-1].minor.yy230;
    yymsp[0].minor.yy239->pPrior = yymsp[-2].minor.yy239;
  }
  yygotominor.yy239 = yymsp[0].minor.yy239;
}
#line 2194 "parse.c"
        break;
      case 108:
#line 383 "parse.y"
{yygotominor.yy230 = TK_ALL;}
#line 2199 "parse.c"
        break;
      case 110:
#line 387 "parse.y"
{
  yygotominor.yy239 = sqlite3SelectNew(yymsp[-6].minor.yy462,yymsp[-5].minor.yy285,yymsp[-4].minor.yy178,yymsp[-3].minor.yy462,yymsp[-2].minor.yy178,yymsp[-1].minor.yy462,yymsp[-7].minor.yy230,yymsp[0].minor.yy270.pLimit,yymsp[0].minor.yy270.pOffset);
}
#line 2206 "parse.c"
        break;
      case 114:
      case 235:
#line 408 "parse.y"
{yygotominor.yy462 = yymsp[-1].minor.yy462;}
#line 2212 "parse.c"
        break;
      case 115:
      case 141:
      case 151:
      case 234:
#line 409 "parse.y"
{yygotominor.yy462 = 0;}
#line 2220 "parse.c"
        break;
      case 116:
#line 410 "parse.y"
{
   yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-2].minor.yy462,yymsp[-1].minor.yy178,yymsp[0].minor.yy384.n?&yymsp[0].minor.yy384:0);
}
#line 2227 "parse.c"
        break;
      case 117:
#line 413 "parse.y"
{
  yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-1].minor.yy462, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
}
#line 2234 "parse.c"
        break;
      case 118:
#line 416 "parse.y"
{
  Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0);
  Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384);
  yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-3].minor.yy462, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0);
}
#line 2243 "parse.c"
        break;
      case 121:
#line 428 "parse.y"
{yygotominor.yy384.n = 0;}
#line 2248 "parse.c"
        break;
      case 122:
#line 440 "parse.y"

{yygotominor.yy285 = sqliteMalloc(sizeof(*yygotominor.yy285));}










#line 2253 "parse.c"
        break;
      case 123:
#line 441 "parse.y"








{yygotominor.yy285 = yymsp[0].minor.yy285;}




#line 2258 "parse.c"
        break;
      case 124:
#line 446 "parse.y"
{
   yygotominor.yy285 = yymsp[-1].minor.yy285;
   if( yygotominor.yy285 && yygotominor.yy285->nSrc>0 ) yygotominor.yy285->a[yygotominor.yy285->nSrc-1].jointype = yymsp[0].minor.yy230;
}
#line 2266 "parse.c"
        break;
      case 125:
#line 450 "parse.y"
{yygotominor.yy285 = 0;}
#line 2271 "parse.c"
        break;
      case 126:
#line 451 "parse.y"
{
  yygotominor.yy285 = sqlite3SrcListAppend(yymsp[-5].minor.yy285,&yymsp[-4].minor.yy384,&yymsp[-3].minor.yy384);
  if( yymsp[-2].minor.yy384.n ) sqlite3SrcListAddAlias(yygotominor.yy285,&yymsp[-2].minor.yy384);
  if( yymsp[-1].minor.yy178 ){
    if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pOn = yymsp[-1].minor.yy178; }
    else { sqlite3ExprDelete(yymsp[-1].minor.yy178); }
  }
  if( yymsp[0].minor.yy160 ){
    if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pUsing = yymsp[0].minor.yy160; }
    else { sqlite3IdListDelete(yymsp[0].minor.yy160); }
  }
}
#line 2287 "parse.c"
        break;
      case 127:
#line 465 "parse.y"
{
    yygotominor.yy285 = sqlite3SrcListAppend(yymsp[-6].minor.yy285,0,0);
    yygotominor.yy285->a[yygotominor.yy285->nSrc-1].pSelect = yymsp[-4].minor.yy239;
    if( yymsp[-2].minor.yy384.n ) sqlite3SrcListAddAlias(yygotominor.yy285,&yymsp[-2].minor.yy384);
    if( yymsp[-1].minor.yy178 ){
      if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pOn = yymsp[-1].minor.yy178; }
      else { sqlite3ExprDelete(yymsp[-1].minor.yy178); }
    }
    if( yymsp[0].minor.yy160 ){
      if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pUsing = yymsp[0].minor.yy160; }
      else { sqlite3IdListDelete(yymsp[0].minor.yy160); }
    }
  }
#line 2304 "parse.c"
        break;
      case 129:
#line 486 "parse.y"
{
     yygotominor.yy239 = sqlite3SelectNew(0,yymsp[0].minor.yy285,0,0,0,0,0,0,0);
  }
#line 2311 "parse.c"
        break;
      case 130:





#line 492 "parse.y"
{yygotominor.yy384.z=0; yygotominor.yy384.n=0;}
#line 2316 "parse.c"
        break;
      case 132:
#line 497 "parse.y"
{yygotominor.yy285 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384);}
#line 2321 "parse.c"
        break;
      case 133:








#line 501 "parse.y"
{ yygotominor.yy230 = JT_INNER; }
#line 2326 "parse.c"
        break;
      case 134:






#line 502 "parse.y"
{ yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
#line 2331 "parse.c"
        break;
      case 135:

#line 503 "parse.y"
{ yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy384,0); }
#line 2336 "parse.c"
        break;
      case 136:
#line 505 "parse.y"
{ yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy384,&yymsp[-1].minor.yy384); }
#line 2341 "parse.c"
        break;
      case 137:
      case 145:
      case 154:
      case 161:
      case 175:
      case 200:
      case 223:
      case 225:
      case 229:
#line 509 "parse.y"
{yygotominor.yy178 = yymsp[0].minor.yy178;}
#line 2354 "parse.c"
        break;
      case 138:
      case 153:
      case 160:
      case 201:
      case 224:
      case 226:
      case 230:
#line 510 "parse.y"
{yygotominor.yy178 = 0;}
#line 2365 "parse.c"
        break;
      case 139:
      case 172:
#line 514 "parse.y"


{yygotominor.yy160 = yymsp[-1].minor.yy160;}

#line 2371 "parse.c"
        break;
      case 140:
      case 171:
#line 515 "parse.y"


{yygotominor.yy160 = 0;}

#line 2377 "parse.c"
        break;
      case 142:
      case 152:
#line 526 "parse.y"
{yygotominor.yy462 = yymsp[0].minor.yy462;}
#line 2383 "parse.c"
        break;
      case 143:
#line 527 "parse.y"
{
  yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462,yymsp[-2].minor.yy178,yymsp[-1].minor.yy384.n>0?&yymsp[-1].minor.yy384:0);
  if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230;
}
#line 2391 "parse.c"
        break;
      case 144:
#line 531 "parse.y"
{
  yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy178,yymsp[-1].minor.yy384.n>0?&yymsp[-1].minor.yy384:0);
  if( yygotominor.yy462 && yygotominor.yy462->a ) yygotominor.yy462->a[0].sortOrder = yymsp[0].minor.yy230;
}
#line 2399 "parse.c"
        break;
      case 146:




      case 148:
#line 540 "parse.y"
{yygotominor.yy230 = SQLITE_SO_ASC;}
#line 2405 "parse.c"
        break;
      case 147:
#line 541 "parse.y"
{yygotominor.yy230 = SQLITE_SO_DESC;}
#line 2410 "parse.c"
        break;
      case 149:
#line 543 "parse.y"
{yygotominor.yy384.z = 0; yygotominor.yy384.n = 0;}
#line 2415 "parse.c"
        break;
      case 155:
#line 561 "parse.y"
{yygotominor.yy270.pLimit = 0; yygotominor.yy270.pOffset = 0;}
#line 2420 "parse.c"
        break;
      case 156:
#line 562 "parse.y"
{yygotominor.yy270.pLimit = yymsp[0].minor.yy178; yygotominor.yy270.pOffset = 0;}
#line 2425 "parse.c"
        break;
      case 157:
#line 564 "parse.y"
{yygotominor.yy270.pLimit = yymsp[-2].minor.yy178; yygotominor.yy270.pOffset = yymsp[0].minor.yy178;}
#line 2430 "parse.c"
        break;
      case 158:
#line 566 "parse.y"
{yygotominor.yy270.pOffset = yymsp[-2].minor.yy178; yygotominor.yy270.pLimit = yymsp[0].minor.yy178;}
#line 2435 "parse.c"
        break;
      case 159:
#line 570 "parse.y"
{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy285,yymsp[0].minor.yy178);}
#line 2440 "parse.c"
        break;
      case 162:
#line 581 "parse.y"
{sqlite3Update(pParse,yymsp[-3].minor.yy285,yymsp[-1].minor.yy462,yymsp[0].minor.yy178,yymsp[-4].minor.yy230);}
#line 2445 "parse.c"
        break;
      case 163:
#line 587 "parse.y"
{yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462,yymsp[0].minor.yy178,&yymsp[-2].minor.yy384);}
#line 2450 "parse.c"
        break;
      case 164:
#line 588 "parse.y"
{yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[0].minor.yy178,&yymsp[-2].minor.yy384);}
#line 2455 "parse.c"
        break;
      case 165:

#line 594 "parse.y"
{sqlite3Insert(pParse, yymsp[-5].minor.yy285, yymsp[-1].minor.yy462, 0, yymsp[-4].minor.yy160, yymsp[-7].minor.yy230);}
#line 2460 "parse.c"
        break;
      case 166:

#line 596 "parse.y"
{sqlite3Insert(pParse, yymsp[-2].minor.yy285, 0, yymsp[0].minor.yy239, yymsp[-1].minor.yy160, yymsp[-4].minor.yy230);}
#line 2465 "parse.c"
        break;
      case 169:
      case 227:
#line 606 "parse.y"
{yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-2].minor.yy462,yymsp[0].minor.yy178,0);}
#line 2471 "parse.c"
        break;
      case 170:




      case 228:
#line 607 "parse.y"
{yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[0].minor.yy178,0);}
#line 2477 "parse.c"
        break;
      case 173:




#line 616 "parse.y"
{yygotominor.yy160 = sqlite3IdListAppend(yymsp[-2].minor.yy160,&yymsp[0].minor.yy384);}
#line 2482 "parse.c"
        break;
      case 174:

#line 617 "parse.y"
{yygotominor.yy160 = sqlite3IdListAppend(0,&yymsp[0].minor.yy384);}
#line 2487 "parse.c"
        break;
      case 176:
#line 628 "parse.y"
{yygotominor.yy178 = yymsp[-1].minor.yy178; sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
#line 2492 "parse.c"
        break;
      case 177:
      case 182:
      case 183:
#line 629 "parse.y"
{yygotominor.yy178 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
#line 2499 "parse.c"
        break;
      case 178:
      case 179:
#line 630 "parse.y"
{yygotominor.yy178 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
#line 2505 "parse.c"
        break;
      case 180:
#line 632 "parse.y"
{
  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384);
  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy384);
  yygotominor.yy178 = sqlite3Expr(TK_DOT, temp1, temp2, 0);
}
#line 2514 "parse.c"
        break;
      case 181:
#line 637 "parse.y"
{
  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy384);
  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384);
  Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy384);
  Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0);
  yygotominor.yy178 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
}
#line 2525 "parse.c"














        break;
      case 184:
#line 646 "parse.y"
{yygotominor.yy178 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
#line 2530 "parse.c"
        break;
      case 185:
#line 647 "parse.y"
{
  Token *pToken = &yymsp[0].minor.yy0;
  Expr *pExpr = yygotominor.yy178 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
  sqlite3ExprAssignVarNumber(pParse, pExpr);
}
#line 2539 "parse.c"
        break;
      case 186:
#line 653 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(TK_CAST, yymsp[-3].minor.yy178, 0, &yymsp[-1].minor.yy384);
  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
}
#line 2547 "parse.c"
        break;

      case 187:
#line 658 "parse.y"
{
  yygotominor.yy178 = sqlite3ExprFunction(yymsp[-1].minor.yy462, &yymsp[-4].minor.yy0);
  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
  if( yymsp[-2].minor.yy230 ){
    yygotominor.yy178->flags |= EP_Distinct;
  }
}
#line 2558 "parse.c"
        break;
      case 188:
#line 665 "parse.y"
{
  yygotominor.yy178 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
#line 2566 "parse.c"
        break;
      case 189:
#line 669 "parse.y"
{
  /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
  ** treated as functions that return constants */
  yygotominor.yy178 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0);
  if( yygotominor.yy178 ) yygotominor.yy178->op = TK_CONST_FUNC;  
}
#line 2576 "parse.c"
        break;
      case 190:
      case 191:
      case 192:
      case 193:
      case 194:
      case 195:
      case 196:
      case 197:









#line 675 "parse.y"
{yygotominor.yy178 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy178, yymsp[0].minor.yy178, 0);}
#line 2588 "parse.c"
        break;
      case 198:
#line 685 "parse.y"
{yygotominor.yy440.operator = yymsp[0].minor.yy0; yygotominor.yy440.not = 0;}
#line 2593 "parse.c"
        break;
      case 199:
#line 686 "parse.y"
{yygotominor.yy440.operator = yymsp[0].minor.yy0; yygotominor.yy440.not = 1;}
#line 2598 "parse.c"
        break;
      case 202:
#line 691 "parse.y"
{
  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy178, 0);
  pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy178, 0);
  if( yymsp[0].minor.yy178 ){
    pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy178, 0);
  }




  yygotominor.yy178 = sqlite3ExprFunction(pList, &yymsp[-2].minor.yy440.operator);
  if( yymsp[-2].minor.yy440.not ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0);
  sqlite3ExprSpan(yygotominor.yy178, &yymsp[-3].minor.yy178->span, &yymsp[-1].minor.yy178->span);
}
#line 2612 "parse.c"
        break;
      case 203:
#line 702 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(yymsp[0].major, yymsp[-1].minor.yy178, 0, 0);

  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy178->span,&yymsp[0].minor.yy0);

}
#line 2620 "parse.c"
        break;
      case 204:
#line 706 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy178, 0, 0);
  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy178->span,&yymsp[0].minor.yy0);
}
#line 2628 "parse.c"
        break;
      case 205:
#line 710 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy178, 0, 0);
  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy178->span,&yymsp[0].minor.yy0);
}
#line 2636 "parse.c"
        break;
      case 206:
#line 714 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy178, 0, 0);
  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy178->span,&yymsp[0].minor.yy0);
}
#line 2644 "parse.c"
        break;
      case 207:
#line 718 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy178, 0, 0);
  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span);
}
#line 2652 "parse.c"
        break;
      case 208:
#line 722 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy178, 0, 0);
  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span);
}
#line 2660 "parse.c"
        break;
      case 209:
#line 726 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy178, 0, 0);
  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span);
}
#line 2668 "parse.c"
        break;
      case 212:
#line 733 "parse.y"
{
  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy178, 0);
  pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy178, 0);
  yygotominor.yy178 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy178, 0, 0);
  if( yygotominor.yy178 ){
    yygotominor.yy178->pList = pList;
  }else{
    sqlite3ExprListDelete(pList);
  } 






  if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0);
  sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy178->span);
}
#line 2684 "parse.c"
        break;
      case 215:
#line 749 "parse.y"
{
    yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy178, 0, 0);
    if( yygotominor.yy178 ){
      yygotominor.yy178->pList = yymsp[-1].minor.yy462;
    }else{
      sqlite3ExprListDelete(yymsp[-1].minor.yy462);
    }





    if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0);
    sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy0);
  }
#line 2698 "parse.c"
        break;
      case 216:
#line 759 "parse.y"
{
    yygotominor.yy178 = sqlite3Expr(TK_SELECT, 0, 0, 0);
    if( yygotominor.yy178 ){
      yygotominor.yy178->pSelect = yymsp[-1].minor.yy239;
    }else{

      sqlite3SelectDelete(yymsp[-1].minor.yy239);
    }



    sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
  }
#line 2711 "parse.c"
        break;
      case 217:
#line 768 "parse.y"
{
    yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy178, 0, 0);
    if( yygotominor.yy178 ){
      yygotominor.yy178->pSelect = yymsp[-1].minor.yy239;
    }else{
      sqlite3SelectDelete(yymsp[-1].minor.yy239);
    }





    if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0);

    sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy0);
  }
#line 2725 "parse.c"
        break;
      case 218:
#line 778 "parse.y"
{
    SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384);
    yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy178, 0, 0);
    if( yygotominor.yy178 ){
      yygotominor.yy178->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0);
    }else{
      sqlite3SrcListDelete(pSrc);
    }
    if( yymsp[-2].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0);
    sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy178->span,yymsp[0].minor.yy384.z?&yymsp[0].minor.yy384:&yymsp[-1].minor.yy384);
  }
#line 2740 "parse.c"
        break;
      case 219:
#line 789 "parse.y"
{

    Expr *p = yygotominor.yy178 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
    if( p ){
      p->pSelect = yymsp[-1].minor.yy239;
      sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
    }else{
      sqlite3SelectDelete(yymsp[-1].minor.yy239);
    }
  }
#line 2753 "parse.c"
        break;
      case 220:
#line 801 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy178, yymsp[-1].minor.yy178, 0);
  if( yygotominor.yy178 ){
    yygotominor.yy178->pList = yymsp[-2].minor.yy462;
  }else{
    sqlite3ExprListDelete(yymsp[-2].minor.yy462);
  }
  sqlite3ExprSpan(yygotominor.yy178, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
}
#line 2766 "parse.c"
        break;
      case 221:
#line 812 "parse.y"
{

  yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462, yymsp[-2].minor.yy178, 0);
  yygotominor.yy462 = sqlite3ExprListAppend(yygotominor.yy462, yymsp[0].minor.yy178, 0);
}
#line 2774 "parse.c"
        break;
      case 222:
#line 816 "parse.y"
{
  yygotominor.yy462 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy178, 0);
  yygotominor.yy462 = sqlite3ExprListAppend(yygotominor.yy462, yymsp[0].minor.yy178, 0);
}
#line 2782 "parse.c"
        break;
      case 231:
#line 843 "parse.y"
{
  if( yymsp[-10].minor.yy230!=OE_None ) yymsp[-10].minor.yy230 = yymsp[0].minor.yy230;
  if( yymsp[-10].minor.yy230==OE_Default) yymsp[-10].minor.yy230 = OE_Abort;
  sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy384, &yymsp[-6].minor.yy384, sqlite3SrcListAppend(0,&yymsp[-4].minor.yy384,0), yymsp[-2].minor.yy462, yymsp[-10].minor.yy230,
                      &yymsp[-11].minor.yy0, &yymsp[-1].minor.yy0, SQLITE_SO_ASC, yymsp[-8].minor.yy230);
}
#line 2792 "parse.c"
        break;
      case 232:
      case 277:
#line 851 "parse.y"
{yygotominor.yy230 = OE_Abort;}
#line 2798 "parse.c"
        break;
      case 233:
#line 852 "parse.y"










{yygotominor.yy230 = OE_None;}
#line 2803 "parse.c"
        break;
      case 236:
#line 862 "parse.y"
{
  Expr *p = 0;
  if( yymsp[-1].minor.yy384.n>0 ){
    p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy384.z, yymsp[-1].minor.yy384.n);
  }
  yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462, p, &yymsp[-2].minor.yy384);
  if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230;
}
#line 2816 "parse.c"
        break;
      case 237:
#line 871 "parse.y"
{
  Expr *p = 0;
  if( yymsp[-1].minor.yy384.n>0 ){
    p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy384.z, yymsp[-1].minor.yy384.n);
  }
  yygotominor.yy462 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy384);
  if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230;
}
#line 2829 "parse.c"
        break;
      case 239:
#line 885 "parse.y"


{sqlite3DropIndex(pParse, yymsp[0].minor.yy285, yymsp[-1].minor.yy230);}
#line 2834 "parse.c"
        break;
      case 240:
      case 241:
#line 889 "parse.y"

{sqlite3Vacuum(pParse,0);}

#line 2840 "parse.c"
        break;
      case 242:
      case 244:
#line 895 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy384,0);}
#line 2846 "parse.c"
        break;
      case 243:
#line 896 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy0,0);}
#line 2851 "parse.c"
        break;
      case 245:
#line 898 "parse.y"
{
  sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy384,1);
}
#line 2858 "parse.c"
        break;
      case 246:

#line 901 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy384,&yymsp[-3].minor.yy384,&yymsp[-1].minor.yy384,0);}
#line 2863 "parse.c"
        break;
      case 247:
#line 902 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384,0,0);}
#line 2868 "parse.c"
        break;
      case 253:
#line 914 "parse.y"
{
  Token all;
  all.z = yymsp[-3].minor.yy384.z;
  all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy384.z) + yymsp[0].minor.yy0.n;
  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy247, &all);
}
#line 2878 "parse.c"
        break;
      case 254:
#line 923 "parse.y"
{
  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy384, &yymsp[-6].minor.yy384, yymsp[-5].minor.yy230, yymsp[-4].minor.yy132.a, yymsp[-4].minor.yy132.b, yymsp[-2].minor.yy285, yymsp[-1].minor.yy230, yymsp[0].minor.yy178, yymsp[-9].minor.yy230);
  yygotominor.yy384 = (yymsp[-6].minor.yy384.n==0?yymsp[-7].minor.yy384:yymsp[-6].minor.yy384);
}
#line 2886 "parse.c"
        break;
      case 255:
      case 258:
#line 929 "parse.y"
{ yygotominor.yy230 = TK_BEFORE; }
#line 2892 "parse.c"
        break;
      case 256:
#line 930 "parse.y"


{ yygotominor.yy230 = TK_AFTER;  }



#line 2897 "parse.c"
        break;
      case 257:
#line 931 "parse.y"


{ yygotominor.yy230 = TK_INSTEAD;}

#line 2902 "parse.c"
        break;
      case 259:
      case 260:
#line 936 "parse.y"
{yygotominor.yy132.a = yymsp[0].major; yygotominor.yy132.b = 0;}
#line 2908 "parse.c"
        break;
      case 261:
#line 938 "parse.y"
{yygotominor.yy132.a = TK_UPDATE; yygotominor.yy132.b = yymsp[0].minor.yy160;}
#line 2913 "parse.c"
        break;
      case 262:
      case 263:
#line 941 "parse.y"
{ yygotominor.yy230 = TK_ROW; }
#line 2919 "parse.c"
        break;
      case 264:
#line 943 "parse.y"
{ yygotominor.yy230 = TK_STATEMENT; }
#line 2924 "parse.c"
        break;
      case 265:


#line 947 "parse.y"
{ yygotominor.yy178 = 0; }
#line 2929 "parse.c"
        break;
      case 266:
#line 948 "parse.y"
{ yygotominor.yy178 = yymsp[0].minor.yy178; }
#line 2934 "parse.c"
        break;
      case 267:

#line 952 "parse.y"
{
  yymsp[-2].minor.yy247->pNext = yymsp[0].minor.yy247;
  yygotominor.yy247 = yymsp[-2].minor.yy247;
}
#line 2942 "parse.c"
        break;
      case 268:
#line 956 "parse.y"
{ yygotominor.yy247 = 0; }
#line 2947 "parse.c"
        break;
      case 269:
#line 962 "parse.y"
{ yygotominor.yy247 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy384, yymsp[-1].minor.yy462, yymsp[0].minor.yy178, yymsp[-4].minor.yy230); }
#line 2952 "parse.c"
        break;
      case 270:
#line 967 "parse.y"
{yygotominor.yy247 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy384, yymsp[-4].minor.yy160, yymsp[-1].minor.yy462, 0, yymsp[-7].minor.yy230);}
#line 2957 "parse.c"
        break;
      case 271:
#line 970 "parse.y"

{yygotominor.yy247 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy384, yymsp[-1].minor.yy160, 0, yymsp[0].minor.yy239, yymsp[-4].minor.yy230);}


#line 2962 "parse.c"
        break;
      case 272:
#line 974 "parse.y"
{yygotominor.yy247 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy384, yymsp[0].minor.yy178);}
#line 2967 "parse.c"
        break;
      case 273:
#line 977 "parse.y"
{yygotominor.yy247 = sqlite3TriggerSelectStep(yymsp[0].minor.yy239); }
#line 2972 "parse.c"
        break;
      case 274:
#line 980 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(TK_RAISE, 0, 0, 0); 
  yygotominor.yy178->iColumn = OE_Ignore;
  sqlite3ExprSpan(yygotominor.yy178, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
}
#line 2981 "parse.c"
        break;
      case 275:
#line 985 "parse.y"
{
  yygotominor.yy178 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy384); 
  yygotominor.yy178->iColumn = yymsp[-3].minor.yy230;
  sqlite3ExprSpan(yygotominor.yy178, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
}
#line 2990 "parse.c"
        break;
      case 276:
#line 993 "parse.y"
{yygotominor.yy230 = OE_Rollback;}
#line 2995 "parse.c"
        break;
      case 278:
#line 995 "parse.y"
{yygotominor.yy230 = OE_Fail;}
#line 3000 "parse.c"
        break;
      case 279:
#line 1000 "parse.y"
{

  sqlite3DropTrigger(pParse,yymsp[0].minor.yy285);

}
#line 3007 "parse.c"
        break;
      case 280:
#line 1006 "parse.y"
{

  sqlite3Attach(pParse, yymsp[-3].minor.yy178, yymsp[-1].minor.yy178, yymsp[0].minor.yy292);

}
#line 3014 "parse.c"
        break;
      case 281:
#line 1011 "parse.y"
{ yygotominor.yy292 = 0; }
#line 3019 "parse.c"
        break;
      case 282:
#line 1012 "parse.y"
{ yygotominor.yy292 = yymsp[0].minor.yy178; }
#line 3024 "parse.c"
        break;
      case 285:
#line 1018 "parse.y"
{
  sqlite3Detach(pParse, yymsp[0].minor.yy178);
}
#line 3031 "parse.c"
        break;
      case 286:
#line 1024 "parse.y"

{sqlite3Reindex(pParse, 0, 0);}

#line 3036 "parse.c"
        break;
      case 287:
#line 1025 "parse.y"
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy384, &yymsp[0].minor.yy384);}
#line 3041 "parse.c"
        break;
      case 288:
#line 1030 "parse.y"
{sqlite3Analyze(pParse, 0, 0);}
#line 3046 "parse.c"
        break;
      case 289:
#line 1031 "parse.y"
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy384, &yymsp[0].minor.yy384);}
#line 3051 "parse.c"
        break;
      case 290:
#line 1036 "parse.y"
{
  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy285,&yymsp[0].minor.yy384);
}
#line 3058 "parse.c"
        break;
      case 291:
#line 1039 "parse.y"
{




  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy384);
}
#line 3065 "parse.c"
        break;
      case 292:
#line 1042 "parse.y"
{
  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy285);
}
#line 3072 "parse.c"
        break;
  };
  yygoto = yyRuleInfo[yyruleno].lhs;
  yysize = yyRuleInfo[yyruleno].nrhs;
  yypParser->yyidx -= yysize;
  yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto);
  if( yyact < YYNSTATE ){







|

|


|

|


|

|


|
|
|

|
|
|
|


>
>
>
>
>
|
|
|

<
<

<
<
<
<
<
<

<
|

|

|
|

|

|
|

|

|
>
>
>
>
>
>
>
>
>
>


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


>
>
>
>
>
>

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

<
<
<
<
<
<
<
|
|

|

|
|
<
|
<
<
|

>
>

<
<
<
<
<
<
<



|
<
|
|
|
|

|
|
|
|

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

|
|
<
|
<
<
|

|
|
|
|

|
|
|
|

|
>
|
|
|

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

|
|

|


|
>
>
>
>
>

>
>
>
>
>

|
<
|
<
<
|


|
>
>
>
>
>
|
|

<
<
<
<
<

|
|
|

|
|
|
|

|
|
|
|

|
|
|
|

|
|
|
|


|
|
|


|
|
|


|
|
|


|
|
|


|
|
|


|
|
|


<
<
<
<

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

|
<
<
|
|
|
|

|
|
<
<
<
<
<
|
|

|
|
|
|

|
|
>
>
|
>
|


>
|
>
>
>
>
>
|
|

|
>
|
>
>
>
>
>

<
|

|

|
<
|
<
>
>
>
|


|
>
|
>
|


<
|
<
<
<
<
<

|
>

|

>
|
|
<
|
<
|

|
|

|
>
>
|
>
>
|

|
|
<
<
|
<
|


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

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


|
<
|
<
|

|

|
|
|
|

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

|
<
<
<
|
|
|

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

<
|
|

|

|
|
|
|

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

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


|

|
<
|
|



|
|

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

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

|
<
|
<
|


>
>
>
>
>
|
|
|


|
|
|


>
>
>
>
>
>
>
>
|
|
|


>
>
>
>
>
>
|
|
|


>
|
|
|


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


|
<
<
<
<
<
|
|
|


<
|
>
>
|
>
|


<
|
>
>
|
>
|


|
|
|
|


|
<
<
|
<
|

|
|
<
<
|
<
|

|
>
>
>
>
|
|
|
|

|
|
|
|

|
|
|
|


|
<
<
<
<
<
|
|

<
<
<
<
<

|
|
|


|
|
|

|
|
|
|

|
|
|
|

|
|
|
|


>
|
|
|


>
|
|
|


<
|
|
|


>
>
>
>
|
|
|
|


>
>
>
>
|
|
|


>
|
|
|


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

|
|
|

|

|
|

|
|
|

|

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


|
<
<
<
<
<

|
|
<

|

|
|

|
|

|

>

<
<
<
<
<
<
<
<
<
<

|
<
|
<
<
|


<
<
<
<
<
<
<
<
<








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

|
|
|
|

|
|
|
|

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

|
|

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

|

|
|

|
|

|

|
|

|
|

|

|
|

|
|

|

|
|

|
|

|

|
|

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

|

|
|

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

|
|

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

|
|

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

|

|
|

<
|
|
<
<
<
<
|
|

|

|
|

>
|
<
|
|
<
|
|
<
|

|
|

|
|
|
<
|
|
<
|
|

|
|

>
|
|

|

|
|

|
|

|

|
|

<
<
|
|

<
<
<
<
<
<
|

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

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

|
|


|

|

|
<

|

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

|
<
|
|
|

|
<
<
<
<
|
|
<
|
<
|

|
>
|
|
|

|
|
|
|

|
|

<
|
<
<

|

|
|
<
|
<
<
|

|
<
|
|
|

|
|
>
>
|
>
>
>
|

|
|
>
>
|
>
|

|
|
|
|
|

|
|
<
<
<
<
<
<
|
|

|
|
|
|

|
>
>
|
|
|

|
|
|
|

|
>
|
<
<
|
<
|

|
|
|
|

|
|
|
|

|
|
|
|

|
|
>
|
>
>
|

|
|
|
|

|
|
|
|

|
|
<
<
|
<
<
|

|
|
<
<
|
<
<
|

|
|
|
|

|
|
|
|

|
|

>
|
>

|

|
|

>
|
>

|

|
|
|
|

|
|
|
|

|
|

|

|

|
|
>
|
>
|

|
|
|
|

|
|
|
|

|
|
|
|

|
|

|

|

|
|
|
>
>
>
>
|
<
|

|
|

|

|







1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936


1937






1938

1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966

1967
1968
1969
1970
1971

1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985











1986
1987







1988
1989
1990
1991
1992
1993
1994

1995


1996
1997
1998
1999
2000







2001
2002
2003
2004

2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029

2030
2031



2032
2033

2034


2035
2036
2037
2038

2039


2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058

2059
2060
2061




2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085

2086


2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098





2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154




2155




2156




2157






2158
2159


2160
2161
2162
2163
2164
2165
2166





2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202

2203
2204
2205
2206
2207

2208

2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221

2222





2223
2224
2225
2226
2227
2228
2229
2230
2231

2232

2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247


2248

2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289

2290

2291
2292
2293
2294
2295
2296
2297
2298
2299
2300








2301
2302
2303
2304
2305



2306
2307
2308
2309
2310
2311














2312

2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359

2360
2361
2362
2363
2364
2365
2366
2367
2368
2369

2370










2371
2372
2373
















2374
2375

2376

2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424




2425








2426
2427
2428
2429
2430
2431





2432
2433
2434
2435
2436

2437
2438
2439
2440
2441
2442
2443
2444

2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459


2460

2461
2462
2463
2464


2465

2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489





2490
2491
2492





2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530

2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561


















2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595





2596
2597
2598

2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611










2612
2613

2614


2615
2616
2617









2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650



2651


2652
2653
2654
2655
2656



2657
2658
2659
2660
2661
2662
2663
2664
2665
2666





2667
2668






2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708



2709
2710


2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727



2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741




2742
2743

2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756

2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772

2773
2774




2775
2776
2777
2778
2779
2780
2781
2782
2783
2784

2785
2786

2787
2788

2789
2790
2791
2792
2793
2794
2795
2796

2797
2798

2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821


2822
2823
2824






2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843


2844






2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855

2856
2857
2858
2859
2860
2861
2862
2863


2864
2865

2866
2867
2868
2869
2870
2871

2872
2873
2874
2875
2876




2877
2878

2879

2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895

2896


2897
2898
2899
2900
2901

2902


2903
2904
2905

2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935






2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958


2959

2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996


2997


2998
2999
3000
3001


3002


3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086

3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
  **   case 0:
  **  #line <lineno> <grammarfile>
  **     { ... }           // User supplied code
  **  #line <lineno> <thisfile>
  **     break;
  */
      case 3:
#line 84 "parse.y"
{ sqlite3FinishCoding(pParse); }
#line 1907 "parse.c"
        break;
      case 6:
#line 87 "parse.y"
{ sqlite3BeginParse(pParse, 0); }
#line 1912 "parse.c"
        break;
      case 7:
#line 89 "parse.y"
{ sqlite3BeginParse(pParse, 1); }
#line 1917 "parse.c"
        break;
      case 8:
#line 95 "parse.y"
{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy60);}
#line 1922 "parse.c"
        break;
      case 12:
#line 100 "parse.y"
{yygotominor.yy60 = TK_DEFERRED;}
#line 1927 "parse.c"
        break;
      case 13:
      case 14:
      case 15:
      case 101:
      case 103:
      case 104:
#line 101 "parse.y"
{yygotominor.yy60 = yymsp[0].major;}
#line 1937 "parse.c"
        break;


      case 16:






      case 17:

#line 104 "parse.y"
{sqlite3CommitTransaction(pParse);}
#line 1943 "parse.c"
        break;
      case 18:
#line 106 "parse.y"
{sqlite3RollbackTransaction(pParse);}
#line 1948 "parse.c"
        break;
      case 20:
#line 111 "parse.y"
{
   sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406,yymsp[-3].minor.yy60,0);
}
#line 1955 "parse.c"
        break;
      case 21:
      case 60:
      case 74:
      case 106:
      case 224:
      case 227:
#line 115 "parse.y"
{yygotominor.yy60 = 1;}
#line 1965 "parse.c"
        break;
      case 22:
      case 59:

      case 73:
      case 75:
      case 86:
      case 107:
      case 108:

      case 223:
      case 226:
#line 116 "parse.y"
{yygotominor.yy60 = 0;}
#line 1978 "parse.c"
        break;
      case 23:
#line 117 "parse.y"
{
  sqlite3EndTable(pParse,&yymsp[0].minor.yy0,0);
}
#line 1985 "parse.c"
        break;
      case 24:











#line 120 "parse.y"
{







  sqlite3EndTable(pParse,0,yymsp[0].minor.yy331);
  sqlite3SelectDelete(yymsp[0].minor.yy331);
}
#line 1993 "parse.c"
        break;
      case 28:
#line 132 "parse.y"

{sqlite3AddColumn(pParse,&yymsp[0].minor.yy406);}


#line 1998 "parse.c"
        break;
      case 29:
      case 30:
      case 31:







      case 32:
      case 33:
      case 34:
      case 263:

      case 264:
#line 138 "parse.y"
{yygotominor.yy406 = yymsp[0].minor.yy0;}
#line 2010 "parse.c"
        break;
      case 36:
#line 193 "parse.y"
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy406,&yymsp[0].minor.yy406);}
#line 2015 "parse.c"
        break;
      case 37:
#line 194 "parse.y"
{sqlite3AddColumnType(pParse,&yymsp[-3].minor.yy406,&yymsp[0].minor.yy0);}
#line 2020 "parse.c"
        break;
      case 38:
#line 196 "parse.y"
{sqlite3AddColumnType(pParse,&yymsp[-5].minor.yy406,&yymsp[0].minor.yy0);}
#line 2025 "parse.c"
        break;
      case 39:
      case 114:
      case 115:
      case 126:
      case 146:

      case 251:
      case 261:



      case 262:
#line 198 "parse.y"

{yygotominor.yy406 = yymsp[0].minor.yy406;}


#line 2037 "parse.c"
        break;
      case 40:
#line 199 "parse.y"

{yygotominor.yy406.z=yymsp[-1].minor.yy406.z; yygotominor.yy406.n=yymsp[0].minor.yy406.n+(yymsp[0].minor.yy406.z-yymsp[-1].minor.yy406.z);}


#line 2042 "parse.c"
        break;
      case 41:
#line 201 "parse.y"
{ yygotominor.yy60 = atoi(yymsp[0].minor.yy406.z); }
#line 2047 "parse.c"
        break;
      case 42:
#line 202 "parse.y"
{ yygotominor.yy60 = -atoi(yymsp[0].minor.yy406.z); }
#line 2052 "parse.c"
        break;
      case 47:
      case 48:
#line 207 "parse.y"
{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454);}
#line 2058 "parse.c"
        break;
      case 49:

#line 209 "parse.y"
{
  Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy454, 0, 0);




  sqlite3AddDefaultValue(pParse,p);
}
#line 2066 "parse.c"
        break;
      case 50:
#line 213 "parse.y"
{
  Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy406);
  sqlite3AddDefaultValue(pParse,p);
}
#line 2074 "parse.c"
        break;
      case 52:
#line 222 "parse.y"
{sqlite3AddNotNull(pParse, yymsp[0].minor.yy60);}
#line 2079 "parse.c"
        break;
      case 53:
#line 224 "parse.y"
{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy60,yymsp[0].minor.yy60);}
#line 2084 "parse.c"
        break;
      case 54:
#line 225 "parse.y"

{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy60,0,0);}


#line 2089 "parse.c"
        break;
      case 56:
#line 228 "parse.y"
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy406,yymsp[-1].minor.yy266,yymsp[0].minor.yy60);}
#line 2094 "parse.c"
        break;
      case 57:
#line 229 "parse.y"
{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy60);}
#line 2099 "parse.c"
        break;





      case 58:
#line 230 "parse.y"
{sqlite3AddCollateType(pParse, yymsp[0].minor.yy406.z, yymsp[0].minor.yy406.n);}
#line 2104 "parse.c"
        break;
      case 61:
#line 243 "parse.y"
{ yygotominor.yy60 = OE_Restrict * 0x010101; }
#line 2109 "parse.c"
        break;
      case 62:
#line 244 "parse.y"
{ yygotominor.yy60 = (yymsp[-1].minor.yy60 & yymsp[0].minor.yy243.mask) | yymsp[0].minor.yy243.value; }
#line 2114 "parse.c"
        break;
      case 63:
#line 246 "parse.y"
{ yygotominor.yy243.value = 0;     yygotominor.yy243.mask = 0x000000; }
#line 2119 "parse.c"
        break;
      case 64:
#line 247 "parse.y"
{ yygotominor.yy243.value = yymsp[0].minor.yy60;     yygotominor.yy243.mask = 0x0000ff; }
#line 2124 "parse.c"
        break;
      case 65:
#line 248 "parse.y"
{ yygotominor.yy243.value = yymsp[0].minor.yy60<<8;  yygotominor.yy243.mask = 0x00ff00; }
#line 2129 "parse.c"
        break;
      case 66:
#line 249 "parse.y"
{ yygotominor.yy243.value = yymsp[0].minor.yy60<<16; yygotominor.yy243.mask = 0xff0000; }
#line 2134 "parse.c"
        break;
      case 67:
#line 251 "parse.y"
{ yygotominor.yy60 = OE_SetNull; }
#line 2139 "parse.c"
        break;
      case 68:
#line 252 "parse.y"
{ yygotominor.yy60 = OE_SetDflt; }
#line 2144 "parse.c"
        break;
      case 69:
#line 253 "parse.y"
{ yygotominor.yy60 = OE_Cascade; }
#line 2149 "parse.c"
        break;
      case 70:
#line 254 "parse.y"
{ yygotominor.yy60 = OE_Restrict; }
#line 2154 "parse.c"
        break;
      case 71:




      case 72:




      case 87:




      case 89:






      case 91:
      case 92:


      case 163:
#line 256 "parse.y"
{yygotominor.yy60 = yymsp[0].minor.yy60;}
#line 2165 "parse.c"
        break;
      case 82:
#line 273 "parse.y"





{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy266,yymsp[0].minor.yy60,yymsp[-2].minor.yy60);}
#line 2170 "parse.c"
        break;
      case 83:
#line 275 "parse.y"
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy266,yymsp[0].minor.yy60,0,0);}
#line 2175 "parse.c"
        break;
      case 85:
#line 278 "parse.y"
{
    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy266, &yymsp[-3].minor.yy406, yymsp[-2].minor.yy266, yymsp[-1].minor.yy60);
    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy60);
}
#line 2183 "parse.c"
        break;
      case 88:
      case 90:
#line 292 "parse.y"
{yygotominor.yy60 = OE_Default;}
#line 2189 "parse.c"
        break;
      case 93:
#line 297 "parse.y"
{yygotominor.yy60 = OE_Ignore;}
#line 2194 "parse.c"
        break;
      case 94:
      case 164:
#line 298 "parse.y"
{yygotominor.yy60 = OE_Replace;}
#line 2200 "parse.c"
        break;
      case 95:
#line 302 "parse.y"
{

  sqlite3DropTable(pParse, yymsp[0].minor.yy427, 0);
}
#line 2207 "parse.c"
        break;
      case 96:

#line 309 "parse.y"

{
  sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy406, &yymsp[-2].minor.yy406, yymsp[0].minor.yy331, yymsp[-5].minor.yy60);
}
#line 2214 "parse.c"
        break;
      case 97:
#line 312 "parse.y"
{
  sqlite3DropTable(pParse, yymsp[0].minor.yy427, 1);
}
#line 2221 "parse.c"
        break;
      case 98:

#line 319 "parse.y"





{
  sqlite3Select(pParse, yymsp[0].minor.yy331, SRT_Callback, 0, 0, 0, 0, 0);
  sqlite3SelectDelete(yymsp[0].minor.yy331);
}
#line 2229 "parse.c"
        break;
      case 99:
      case 123:
#line 329 "parse.y"

{yygotominor.yy331 = yymsp[0].minor.yy331;}

#line 2235 "parse.c"
        break;
      case 100:
#line 331 "parse.y"
{
  if( yymsp[0].minor.yy331 ){
    yymsp[0].minor.yy331->op = yymsp[-1].minor.yy60;
    yymsp[0].minor.yy331->pPrior = yymsp[-2].minor.yy331;
  }
  yygotominor.yy331 = yymsp[0].minor.yy331;
}
#line 2246 "parse.c"
        break;
      case 102:
#line 340 "parse.y"


{yygotominor.yy60 = TK_ALL;}

#line 2251 "parse.c"
        break;
      case 105:
#line 345 "parse.y"
{
  yygotominor.yy331 = sqlite3SelectNew(yymsp[-6].minor.yy266,yymsp[-5].minor.yy427,yymsp[-4].minor.yy454,yymsp[-3].minor.yy266,yymsp[-2].minor.yy454,yymsp[-1].minor.yy266,yymsp[-7].minor.yy60,yymsp[0].minor.yy348.pLimit,yymsp[0].minor.yy348.pOffset);
}
#line 2258 "parse.c"
        break;
      case 109:
      case 248:
#line 366 "parse.y"
{yygotominor.yy266 = yymsp[-1].minor.yy266;}
#line 2264 "parse.c"
        break;
      case 110:
      case 137:
      case 147:
      case 247:
#line 367 "parse.y"
{yygotominor.yy266 = 0;}
#line 2272 "parse.c"
        break;
      case 111:
#line 368 "parse.y"
{
   yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-2].minor.yy266,yymsp[-1].minor.yy454,yymsp[0].minor.yy406.n?&yymsp[0].minor.yy406:0);
}
#line 2279 "parse.c"
        break;
      case 112:
#line 371 "parse.y"
{
  yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-1].minor.yy266, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
}
#line 2286 "parse.c"
        break;
      case 113:
#line 374 "parse.y"
{
  Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0);

  Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy406);

  yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-3].minor.yy266, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0);
}
#line 2295 "parse.c"
        break;
      case 116:
#line 386 "parse.y"
{yygotominor.yy406.n = 0;}
#line 2300 "parse.c"
        break;
      case 117:








#line 398 "parse.y"
{yygotominor.yy427 = sqliteMalloc(sizeof(*yygotominor.yy427));}
#line 2305 "parse.c"
        break;
      case 118:



#line 399 "parse.y"
{yygotominor.yy427 = yymsp[0].minor.yy427;}
#line 2310 "parse.c"
        break;
      case 119:
#line 404 "parse.y"














{

   yygotominor.yy427 = yymsp[-1].minor.yy427;
   if( yygotominor.yy427 && yygotominor.yy427->nSrc>0 ) yygotominor.yy427->a[yygotominor.yy427->nSrc-1].jointype = yymsp[0].minor.yy60;
}
#line 2318 "parse.c"
        break;
      case 120:
#line 408 "parse.y"
{yygotominor.yy427 = 0;}
#line 2323 "parse.c"
        break;
      case 121:
#line 409 "parse.y"
{
  yygotominor.yy427 = sqlite3SrcListAppend(yymsp[-5].minor.yy427,&yymsp[-4].minor.yy406,&yymsp[-3].minor.yy406);
  if( yymsp[-2].minor.yy406.n ) sqlite3SrcListAddAlias(yygotominor.yy427,&yymsp[-2].minor.yy406);
  if( yymsp[-1].minor.yy454 ){
    if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pOn = yymsp[-1].minor.yy454; }
    else { sqlite3ExprDelete(yymsp[-1].minor.yy454); }
  }
  if( yymsp[0].minor.yy272 ){
    if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pUsing = yymsp[0].minor.yy272; }
    else { sqlite3IdListDelete(yymsp[0].minor.yy272); }
  }
}
#line 2339 "parse.c"
        break;
      case 122:
#line 423 "parse.y"
{
    yygotominor.yy427 = sqlite3SrcListAppend(yymsp[-6].minor.yy427,0,0);
    yygotominor.yy427->a[yygotominor.yy427->nSrc-1].pSelect = yymsp[-4].minor.yy331;
    if( yymsp[-2].minor.yy406.n ) sqlite3SrcListAddAlias(yygotominor.yy427,&yymsp[-2].minor.yy406);
    if( yymsp[-1].minor.yy454 ){
      if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pOn = yymsp[-1].minor.yy454; }
      else { sqlite3ExprDelete(yymsp[-1].minor.yy454); }
    }
    if( yymsp[0].minor.yy272 ){
      if( yygotominor.yy427 && yygotominor.yy427->nSrc>1 ){ yygotominor.yy427->a[yygotominor.yy427->nSrc-2].pUsing = yymsp[0].minor.yy272; }
      else { sqlite3IdListDelete(yymsp[0].minor.yy272); }
    }
  }
#line 2356 "parse.c"
        break;
      case 124:
#line 444 "parse.y"
{
     yygotominor.yy331 = sqlite3SelectNew(0,yymsp[0].minor.yy427,0,0,0,0,0,0,0);

  }
#line 2363 "parse.c"
        break;
      case 125:
#line 450 "parse.y"
{yygotominor.yy406.z=0; yygotominor.yy406.n=0;}
#line 2368 "parse.c"
        break;
      case 127:
#line 455 "parse.y"

{yygotominor.yy427 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406);}










#line 2373 "parse.c"
        break;
      case 128:
















      case 129:
#line 459 "parse.y"

{ yygotominor.yy60 = JT_INNER; }

#line 2379 "parse.c"
        break;
      case 130:
#line 461 "parse.y"
{ yygotominor.yy60 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
#line 2384 "parse.c"
        break;
      case 131:
#line 462 "parse.y"
{ yygotominor.yy60 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy406,0); }
#line 2389 "parse.c"
        break;
      case 132:
#line 464 "parse.y"
{ yygotominor.yy60 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy406,&yymsp[-1].minor.yy406); }
#line 2394 "parse.c"
        break;
      case 133:
      case 141:
      case 150:
      case 157:
      case 171:
      case 211:
      case 236:
      case 238:
      case 242:
#line 468 "parse.y"
{yygotominor.yy454 = yymsp[0].minor.yy454;}
#line 2407 "parse.c"
        break;
      case 134:
      case 149:
      case 156:
      case 212:
      case 237:
      case 239:
      case 243:
#line 469 "parse.y"
{yygotominor.yy454 = 0;}
#line 2418 "parse.c"
        break;
      case 135:
      case 168:
#line 473 "parse.y"
{yygotominor.yy272 = yymsp[-1].minor.yy272;}
#line 2424 "parse.c"
        break;
      case 136:




      case 167:








#line 474 "parse.y"
{yygotominor.yy272 = 0;}
#line 2430 "parse.c"
        break;
      case 138:
      case 148:





#line 485 "parse.y"
{yygotominor.yy266 = yymsp[0].minor.yy266;}
#line 2436 "parse.c"
        break;
      case 139:

#line 486 "parse.y"
{
  yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266,yymsp[-2].minor.yy454,yymsp[-1].minor.yy406.n>0?&yymsp[-1].minor.yy406:0);
  if( yygotominor.yy266 ) yygotominor.yy266->a[yygotominor.yy266->nExpr-1].sortOrder = yymsp[0].minor.yy60;
}
#line 2444 "parse.c"
        break;
      case 140:

#line 490 "parse.y"
{
  yygotominor.yy266 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy454,yymsp[-1].minor.yy406.n>0?&yymsp[-1].minor.yy406:0);
  if( yygotominor.yy266 && yygotominor.yy266->a ) yygotominor.yy266->a[0].sortOrder = yymsp[0].minor.yy60;
}
#line 2452 "parse.c"
        break;
      case 142:
      case 144:
#line 499 "parse.y"
{yygotominor.yy60 = SQLITE_SO_ASC;}
#line 2458 "parse.c"
        break;
      case 143:
#line 500 "parse.y"


{yygotominor.yy60 = SQLITE_SO_DESC;}

#line 2463 "parse.c"
        break;
      case 145:
#line 502 "parse.y"


{yygotominor.yy406.z = 0; yygotominor.yy406.n = 0;}

#line 2468 "parse.c"
        break;
      case 151:
#line 520 "parse.y"
{yygotominor.yy348.pLimit = 0; yygotominor.yy348.pOffset = 0;}
#line 2473 "parse.c"
        break;
      case 152:
#line 521 "parse.y"
{yygotominor.yy348.pLimit = yymsp[0].minor.yy454; yygotominor.yy348.pOffset = 0;}
#line 2478 "parse.c"
        break;
      case 153:
#line 523 "parse.y"
{yygotominor.yy348.pLimit = yymsp[-2].minor.yy454; yygotominor.yy348.pOffset = yymsp[0].minor.yy454;}
#line 2483 "parse.c"
        break;
      case 154:
#line 525 "parse.y"
{yygotominor.yy348.pOffset = yymsp[-2].minor.yy454; yygotominor.yy348.pLimit = yymsp[0].minor.yy454;}
#line 2488 "parse.c"
        break;
      case 155:
#line 529 "parse.y"





{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy427,yymsp[0].minor.yy454);}
#line 2493 "parse.c"
        break;





      case 158:
#line 543 "parse.y"
{sqlite3Update(pParse,yymsp[-3].minor.yy427,yymsp[-1].minor.yy266,yymsp[0].minor.yy454,yymsp[-4].minor.yy60);}
#line 2498 "parse.c"
        break;
      case 159:
#line 546 "parse.y"
{yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266,yymsp[0].minor.yy454,&yymsp[-2].minor.yy406);}
#line 2503 "parse.c"
        break;
      case 160:
#line 547 "parse.y"
{yygotominor.yy266 = sqlite3ExprListAppend(0,yymsp[0].minor.yy454,&yymsp[-2].minor.yy406);}
#line 2508 "parse.c"
        break;
      case 161:
#line 553 "parse.y"
{sqlite3Insert(pParse, yymsp[-5].minor.yy427, yymsp[-1].minor.yy266, 0, yymsp[-4].minor.yy272, yymsp[-7].minor.yy60);}
#line 2513 "parse.c"
        break;
      case 162:
#line 555 "parse.y"
{sqlite3Insert(pParse, yymsp[-2].minor.yy427, 0, yymsp[0].minor.yy331, yymsp[-1].minor.yy272, yymsp[-4].minor.yy60);}
#line 2518 "parse.c"
        break;
      case 165:
      case 240:
#line 565 "parse.y"
{yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-2].minor.yy266,yymsp[0].minor.yy454,0);}
#line 2524 "parse.c"
        break;
      case 166:
      case 241:
#line 566 "parse.y"
{yygotominor.yy266 = sqlite3ExprListAppend(0,yymsp[0].minor.yy454,0);}
#line 2530 "parse.c"
        break;
      case 169:

#line 575 "parse.y"
{yygotominor.yy272 = sqlite3IdListAppend(yymsp[-2].minor.yy272,&yymsp[0].minor.yy406);}
#line 2535 "parse.c"
        break;
      case 170:
#line 576 "parse.y"
{yygotominor.yy272 = sqlite3IdListAppend(0,&yymsp[0].minor.yy406);}
#line 2540 "parse.c"
        break;
      case 172:
#line 587 "parse.y"
{yygotominor.yy454 = yymsp[-1].minor.yy454; sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
#line 2545 "parse.c"
        break;
      case 173:
      case 178:
      case 179:
      case 180:
      case 181:
#line 588 "parse.y"
{yygotominor.yy454 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
#line 2554 "parse.c"
        break;
      case 174:
      case 175:
#line 589 "parse.y"
{yygotominor.yy454 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
#line 2560 "parse.c"
        break;
      case 176:
#line 591 "parse.y"


















{
  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy406);
  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy406);
  yygotominor.yy454 = sqlite3Expr(TK_DOT, temp1, temp2, 0);
}
#line 2569 "parse.c"
        break;
      case 177:
#line 596 "parse.y"
{
  Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy406);
  Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy406);
  Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy406);
  Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0);
  yygotominor.yy454 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
}
#line 2580 "parse.c"
        break;
      case 182:
#line 607 "parse.y"
{yygotominor.yy454 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
#line 2585 "parse.c"
        break;
      case 183:
#line 608 "parse.y"
{
  Token *pToken = &yymsp[0].minor.yy0;
  Expr *pExpr = yygotominor.yy454 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
  sqlite3ExprAssignVarNumber(pParse, pExpr);
}
#line 2594 "parse.c"
        break;
      case 184:
#line 613 "parse.y"





{
  yygotominor.yy454 = sqlite3ExprFunction(yymsp[-1].minor.yy266, &yymsp[-3].minor.yy0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);

}
#line 2602 "parse.c"
        break;
      case 185:
#line 617 "parse.y"
{
  yygotominor.yy454 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
#line 2610 "parse.c"
        break;
      case 186:
      case 187:










      case 188:
#line 621 "parse.y"

{yygotominor.yy454 = sqlite3Expr(yymsp[0].major,0,0,0);}


#line 2617 "parse.c"
        break;
      case 189:









      case 190:
      case 191:
      case 192:
      case 193:
      case 194:
      case 195:
      case 196:
      case 197:
      case 198:
      case 199:
      case 200:
      case 201:
      case 202:
      case 203:
      case 204:
      case 205:
      case 206:
#line 624 "parse.y"
{yygotominor.yy454 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy454, yymsp[0].minor.yy454, 0);}
#line 2639 "parse.c"
        break;
      case 207:
#line 643 "parse.y"
{yygotominor.yy258.opcode = TK_LIKE; yygotominor.yy258.not = 0;}
#line 2644 "parse.c"
        break;
      case 208:
#line 644 "parse.y"
{yygotominor.yy258.opcode = TK_GLOB; yygotominor.yy258.not = 0;}
#line 2649 "parse.c"
        break;
      case 209:
#line 645 "parse.y"



{yygotominor.yy258.opcode = TK_LIKE; yygotominor.yy258.not = 1;}


#line 2654 "parse.c"
        break;
      case 210:
#line 646 "parse.y"
{yygotominor.yy258.opcode = TK_GLOB; yygotominor.yy258.not = 1;}



#line 2659 "parse.c"
        break;
      case 213:
#line 650 "parse.y"
{
  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy454, 0);
  pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy454, 0);
  if( yymsp[0].minor.yy454 ){
    pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy454, 0);
  }





  yygotominor.yy454 = sqlite3ExprFunction(pList, 0);
  if( yygotominor.yy454 ) yygotominor.yy454->op = yymsp[-2].minor.yy258.opcode;






  if( yymsp[-2].minor.yy258.not ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454, &yymsp[-3].minor.yy454->span, &yymsp[-1].minor.yy454->span);
}
#line 2674 "parse.c"
        break;
      case 214:
#line 662 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy454->span,&yymsp[0].minor.yy0);
}
#line 2682 "parse.c"
        break;
      case 215:
#line 666 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy454->span,&yymsp[0].minor.yy0);
}
#line 2690 "parse.c"
        break;
      case 216:
#line 670 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy454->span,&yymsp[0].minor.yy0);
}
#line 2698 "parse.c"
        break;
      case 217:
#line 674 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy454->span,&yymsp[0].minor.yy0);
}
#line 2706 "parse.c"
        break;
      case 218:
#line 678 "parse.y"
{



  yygotominor.yy454 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy454->span,&yymsp[0].minor.yy0);


}
#line 2714 "parse.c"
        break;
      case 219:
      case 220:
#line 682 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy454->span);
}
#line 2723 "parse.c"
        break;
      case 221:
#line 690 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy454->span);



}
#line 2731 "parse.c"
        break;
      case 222:
#line 694 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy454->span);
}
#line 2739 "parse.c"
        break;
      case 225:
#line 701 "parse.y"
{




  ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy454, 0);
  pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy454, 0);

  yygotominor.yy454 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy454, 0, 0);
  if( yygotominor.yy454 ) yygotominor.yy454->pList = pList;
  if( yymsp[-3].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0);
  sqlite3ExprSpan(yygotominor.yy454,&yymsp[-4].minor.yy454->span,&yymsp[0].minor.yy454->span);
}
#line 2751 "parse.c"
        break;
      case 228:
#line 713 "parse.y"
{
    yygotominor.yy454 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy454, 0, 0);
    if( yygotominor.yy454 ) yygotominor.yy454->pList = yymsp[-1].minor.yy266;
    if( yymsp[-3].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0);

    sqlite3ExprSpan(yygotominor.yy454,&yymsp[-4].minor.yy454->span,&yymsp[0].minor.yy0);
  }
#line 2761 "parse.c"
        break;
      case 229:
#line 719 "parse.y"
{
    yygotominor.yy454 = sqlite3Expr(TK_SELECT, 0, 0, 0);
    if( yygotominor.yy454 ) yygotominor.yy454->pSelect = yymsp[-1].minor.yy331;
    sqlite3ExprSpan(yygotominor.yy454,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
  }
#line 2770 "parse.c"
        break;
      case 230:
#line 724 "parse.y"
{

    yygotominor.yy454 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy454, 0, 0);
    if( yygotominor.yy454 ) yygotominor.yy454->pSelect = yymsp[-1].minor.yy331;




    if( yymsp[-3].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0);
    sqlite3ExprSpan(yygotominor.yy454,&yymsp[-4].minor.yy454->span,&yymsp[0].minor.yy0);
  }
#line 2780 "parse.c"
        break;
      case 231:
#line 730 "parse.y"
{
    SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406);
    yygotominor.yy454 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy454, 0, 0);

    if( yygotominor.yy454 ) yygotominor.yy454->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0);
    if( yymsp[-2].minor.yy60 ) yygotominor.yy454 = sqlite3Expr(TK_NOT, yygotominor.yy454, 0, 0);

    sqlite3ExprSpan(yygotominor.yy454,&yymsp[-3].minor.yy454->span,yymsp[0].minor.yy406.z?&yymsp[0].minor.yy406:&yymsp[-1].minor.yy406);
  }

#line 2791 "parse.c"
        break;
      case 232:
#line 737 "parse.y"
{
    Expr *p = yygotominor.yy454 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
    if( p ){
      p->pSelect = yymsp[-1].minor.yy331;

      sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
    }

  }
#line 2802 "parse.c"
        break;
      case 233:
#line 747 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, 0);
  if( yygotominor.yy454 ) yygotominor.yy454->pList = yymsp[-2].minor.yy266;
  sqlite3ExprSpan(yygotominor.yy454, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
}
#line 2811 "parse.c"
        break;
      case 234:
#line 754 "parse.y"
{
  yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266, yymsp[-2].minor.yy454, 0);
  yygotominor.yy266 = sqlite3ExprListAppend(yygotominor.yy266, yymsp[0].minor.yy454, 0);
}
#line 2819 "parse.c"
        break;
      case 235:
#line 758 "parse.y"
{


  yygotominor.yy266 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy454, 0);
  yygotominor.yy266 = sqlite3ExprListAppend(yygotominor.yy266, yymsp[0].minor.yy454, 0);
}






#line 2827 "parse.c"
        break;
      case 244:
#line 783 "parse.y"
{
  if( yymsp[-9].minor.yy60!=OE_None ) yymsp[-9].minor.yy60 = yymsp[0].minor.yy60;
  if( yymsp[-9].minor.yy60==OE_Default) yymsp[-9].minor.yy60 = OE_Abort;
  sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy406, &yymsp[-6].minor.yy406, sqlite3SrcListAppend(0,&yymsp[-4].minor.yy406,0),yymsp[-2].minor.yy266,yymsp[-9].minor.yy60, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0);
}
#line 2836 "parse.c"
        break;
      case 245:
      case 292:
#line 790 "parse.y"
{yygotominor.yy60 = OE_Abort;}
#line 2842 "parse.c"
        break;
      case 246:
#line 791 "parse.y"


{yygotominor.yy60 = OE_None;}






#line 2847 "parse.c"
        break;
      case 249:
#line 801 "parse.y"
{
  Expr *p = 0;
  if( yymsp[-1].minor.yy406.n>0 ){
    p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy406.z, yymsp[-1].minor.yy406.n);
  }
  yygotominor.yy266 = sqlite3ExprListAppend(yymsp[-4].minor.yy266, p, &yymsp[-2].minor.yy406);

}
#line 2859 "parse.c"
        break;
      case 250:
#line 809 "parse.y"
{
  Expr *p = 0;
  if( yymsp[-1].minor.yy406.n>0 ){


    p = sqlite3Expr(TK_COLUMN, 0, 0, 0);
    if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy406.z, yymsp[-1].minor.yy406.n);

  }
  yygotominor.yy266 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy406);
}
#line 2871 "parse.c"
        break;
      case 252:

#line 822 "parse.y"
{sqlite3DropIndex(pParse, yymsp[0].minor.yy427);}
#line 2876 "parse.c"
        break;
      case 253:




      case 254:
#line 826 "parse.y"

{sqlite3Vacuum(pParse,0);}

#line 2882 "parse.c"
        break;
      case 255:
      case 257:
#line 832 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy406,&yymsp[-2].minor.yy406,&yymsp[0].minor.yy406,0);}
#line 2888 "parse.c"
        break;
      case 256:
#line 833 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy406,&yymsp[-2].minor.yy406,&yymsp[0].minor.yy0,0);}
#line 2893 "parse.c"
        break;
      case 258:
#line 835 "parse.y"
{

  sqlite3Pragma(pParse,&yymsp[-3].minor.yy406,&yymsp[-2].minor.yy406,&yymsp[0].minor.yy406,1);


}
#line 2900 "parse.c"
        break;
      case 259:
#line 838 "parse.y"

{sqlite3Pragma(pParse,&yymsp[-4].minor.yy406,&yymsp[-3].minor.yy406,&yymsp[-1].minor.yy406,0);}


#line 2905 "parse.c"
        break;
      case 260:

#line 839 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy406,&yymsp[0].minor.yy406,0,0);}
#line 2910 "parse.c"
        break;
      case 267:
#line 852 "parse.y"
{
  Token all;
  all.z = yymsp[-3].minor.yy406.z;
  all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy406.z) + yymsp[0].minor.yy0.n;
  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy455, &all);
}
#line 2920 "parse.c"
        break;
      case 268:
#line 861 "parse.y"
{
  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy406, &yymsp[-6].minor.yy406, yymsp[-5].minor.yy60, yymsp[-4].minor.yy62.a, yymsp[-4].minor.yy62.b, yymsp[-2].minor.yy427, yymsp[-1].minor.yy60, yymsp[0].minor.yy454, yymsp[-9].minor.yy60);
  yygotominor.yy406 = (yymsp[-6].minor.yy406.n==0?yymsp[-7].minor.yy406:yymsp[-6].minor.yy406);
}
#line 2928 "parse.c"
        break;
      case 269:
      case 272:
#line 867 "parse.y"
{ yygotominor.yy60 = TK_BEFORE; }
#line 2934 "parse.c"
        break;
      case 270:
#line 868 "parse.y"






{ yygotominor.yy60 = TK_AFTER;  }
#line 2939 "parse.c"
        break;
      case 271:
#line 869 "parse.y"
{ yygotominor.yy60 = TK_INSTEAD;}
#line 2944 "parse.c"
        break;
      case 273:
      case 274:
      case 275:
#line 874 "parse.y"
{yygotominor.yy62.a = yymsp[0].major; yygotominor.yy62.b = 0;}
#line 2951 "parse.c"
        break;
      case 276:
#line 877 "parse.y"
{yygotominor.yy62.a = TK_UPDATE; yygotominor.yy62.b = yymsp[0].minor.yy272;}
#line 2956 "parse.c"
        break;
      case 277:
      case 278:
#line 880 "parse.y"


{ yygotominor.yy60 = TK_ROW; }

#line 2962 "parse.c"
        break;
      case 279:
#line 882 "parse.y"
{ yygotominor.yy60 = TK_STATEMENT; }
#line 2967 "parse.c"
        break;
      case 280:
#line 885 "parse.y"
{ yygotominor.yy454 = 0; }
#line 2972 "parse.c"
        break;
      case 281:
#line 886 "parse.y"
{ yygotominor.yy454 = yymsp[0].minor.yy454; }
#line 2977 "parse.c"
        break;
      case 282:
#line 890 "parse.y"
{
  yymsp[-2].minor.yy455->pNext = yymsp[0].minor.yy455;
  yygotominor.yy455 = yymsp[-2].minor.yy455;
}
#line 2985 "parse.c"
        break;
      case 283:
#line 894 "parse.y"
{ yygotominor.yy455 = 0; }
#line 2990 "parse.c"
        break;
      case 284:
#line 900 "parse.y"
{ yygotominor.yy455 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy406, yymsp[-1].minor.yy266, yymsp[0].minor.yy454, yymsp[-4].minor.yy60); }
#line 2995 "parse.c"
        break;
      case 285:
#line 905 "parse.y"


{yygotominor.yy455 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy406, yymsp[-4].minor.yy272, yymsp[-1].minor.yy266, 0, yymsp[-7].minor.yy60);}


#line 3000 "parse.c"
        break;
      case 286:
#line 908 "parse.y"


{yygotominor.yy455 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy406, yymsp[-1].minor.yy272, 0, yymsp[0].minor.yy331, yymsp[-4].minor.yy60);}


#line 3005 "parse.c"
        break;
      case 287:
#line 912 "parse.y"
{yygotominor.yy455 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy406, yymsp[0].minor.yy454);}
#line 3010 "parse.c"
        break;
      case 288:
#line 915 "parse.y"
{yygotominor.yy455 = sqlite3TriggerSelectStep(yymsp[0].minor.yy331); }
#line 3015 "parse.c"
        break;
      case 289:
#line 918 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_RAISE, 0, 0, 0); 
  yygotominor.yy454->iColumn = OE_Ignore;
  sqlite3ExprSpan(yygotominor.yy454, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
}
#line 3024 "parse.c"
        break;
      case 290:
#line 923 "parse.y"
{
  yygotominor.yy454 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy406); 
  yygotominor.yy454->iColumn = yymsp[-3].minor.yy60;
  sqlite3ExprSpan(yygotominor.yy454, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
}
#line 3033 "parse.c"
        break;
      case 291:
#line 931 "parse.y"
{yygotominor.yy60 = OE_Rollback;}
#line 3038 "parse.c"
        break;
      case 293:
#line 933 "parse.y"
{yygotominor.yy60 = OE_Fail;}
#line 3043 "parse.c"
        break;
      case 294:
#line 938 "parse.y"
{
  sqlite3DropTrigger(pParse,yymsp[0].minor.yy427);
}
#line 3050 "parse.c"
        break;
      case 295:
#line 944 "parse.y"
{
  sqlite3Attach(pParse, &yymsp[-3].minor.yy406, &yymsp[-1].minor.yy406, yymsp[0].minor.yy40.type, &yymsp[0].minor.yy40.key);
}
#line 3057 "parse.c"
        break;
      case 296:
#line 948 "parse.y"
{ yygotominor.yy40.type = 0; }
#line 3062 "parse.c"
        break;
      case 297:
#line 949 "parse.y"
{ yygotominor.yy40.type=1; yygotominor.yy40.key = yymsp[0].minor.yy406; }
#line 3067 "parse.c"
        break;
      case 298:
#line 950 "parse.y"
{ yygotominor.yy40.type=2; yygotominor.yy40.key = yymsp[0].minor.yy0; }
#line 3072 "parse.c"
        break;
      case 301:
#line 956 "parse.y"
{
  sqlite3Detach(pParse, &yymsp[0].minor.yy406);
}
#line 3079 "parse.c"
        break;
      case 302:
#line 962 "parse.y"
{sqlite3Reindex(pParse, 0, 0);}
#line 3084 "parse.c"
        break;
      case 303:
#line 963 "parse.y"
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy406, &yymsp[0].minor.yy406);}

#line 3089 "parse.c"
        break;
      case 304:
#line 968 "parse.y"
{
  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy427,&yymsp[0].minor.yy406);
}
#line 3096 "parse.c"
        break;
  };
  yygoto = yyRuleInfo[yyruleno].lhs;
  yysize = yyRuleInfo[yyruleno].nrhs;
  yypParser->yyidx -= yysize;
  yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto);
  if( yyact < YYNSTATE ){
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
static void yy_syntax_error(
  yyParser *yypParser,           /* The parser */
  int yymajor,                   /* The major type of the error token */
  YYMINORTYPE yyminor            /* The minor type of the error token */
){
  sqlite3ParserARG_FETCH;
#define TOKEN (yyminor.yy0)
#line 34 "parse.y"

  if( pParse->zErrMsg==0 ){
    if( TOKEN.z[0] ){
      sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
    }else{
      sqlite3ErrorMsg(pParse, "incomplete SQL statement");
    }
  }
#line 3139 "parse.c"
  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}

/*
** The following is executed when the parser accepts
*/
static void yy_accept(







|








|







3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
static void yy_syntax_error(
  yyParser *yypParser,           /* The parser */
  int yymajor,                   /* The major type of the error token */
  YYMINORTYPE yyminor            /* The minor type of the error token */
){
  sqlite3ParserARG_FETCH;
#define TOKEN (yyminor.yy0)
#line 23 "parse.y"

  if( pParse->zErrMsg==0 ){
    if( TOKEN.z[0] ){
      sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
    }else{
      sqlite3ErrorMsg(pParse, "incomplete SQL statement");
    }
  }
#line 3163 "parse.c"
  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}

/*
** The following is executed when the parser accepts
*/
static void yy_accept(
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
  int yyendofinput;     /* True if we are at the end of input */
  int yyerrorhit = 0;   /* True if yymajor has invoked an error */
  yyParser *yypParser;  /* The parser */

  /* (re)initialize the parser, if necessary */
  yypParser = (yyParser*)yyp;
  if( yypParser->yyidx<0 ){
    /* if( yymajor==0 ) return; // not sure why this was here... */
    yypParser->yyidx = 0;
    yypParser->yyerrcnt = -1;
    yypParser->yystack[0].stateno = 0;
    yypParser->yystack[0].major = 0;
  }
  yyminorunion.yy0 = yyminor;
  yyendofinput = (yymajor==0);







|







3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
  int yyendofinput;     /* True if we are at the end of input */
  int yyerrorhit = 0;   /* True if yymajor has invoked an error */
  yyParser *yypParser;  /* The parser */

  /* (re)initialize the parser, if necessary */
  yypParser = (yyParser*)yyp;
  if( yypParser->yyidx<0 ){
    if( yymajor==0 ) return;
    yypParser->yyidx = 0;
    yypParser->yyerrcnt = -1;
    yypParser->yystack[0].stateno = 0;
    yypParser->yystack[0].major = 0;
  }
  yyminorunion.yy0 = yyminor;
  yyendofinput = (yymajor==0);
Changes to SQLite.Interop/src/parse.h.








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56


57
58

59
60

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151








#define TK_SEMI                            1
#define TK_EXPLAIN                         2
#define TK_QUERY                           3
#define TK_PLAN                            4
#define TK_BEGIN                           5
#define TK_TRANSACTION                     6
#define TK_DEFERRED                        7
#define TK_IMMEDIATE                       8
#define TK_EXCLUSIVE                       9
#define TK_COMMIT                         10
#define TK_END                            11
#define TK_ROLLBACK                       12
#define TK_CREATE                         13
#define TK_TABLE                          14
#define TK_IF                             15
#define TK_NOT                            16
#define TK_EXISTS                         17
#define TK_TEMP                           18
#define TK_LP                             19
#define TK_RP                             20
#define TK_AS                             21
#define TK_COMMA                          22
#define TK_ID                             23
#define TK_ABORT                          24
#define TK_AFTER                          25
#define TK_ANALYZE                        26
#define TK_ASC                            27
#define TK_ATTACH                         28
#define TK_BEFORE                         29
#define TK_CASCADE                        30
#define TK_CAST                           31
#define TK_CONFLICT                       32
#define TK_DATABASE                       33
#define TK_DESC                           34
#define TK_DETACH                         35
#define TK_EACH                           36
#define TK_FAIL                           37
#define TK_FOR                            38

#define TK_IGNORE                         39
#define TK_INITIALLY                      40
#define TK_INSTEAD                        41
#define TK_LIKE_KW                        42
#define TK_MATCH                          43
#define TK_KEY                            44
#define TK_OF                             45
#define TK_OFFSET                         46
#define TK_PRAGMA                         47
#define TK_RAISE                          48
#define TK_REPLACE                        49
#define TK_RESTRICT                       50
#define TK_ROW                            51
#define TK_STATEMENT                      52
#define TK_TRIGGER                        53
#define TK_VACUUM                         54
#define TK_VIEW                           55
#define TK_REINDEX                        56


#define TK_RENAME                         57
#define TK_CTIME_KW                       58

#define TK_OR                             59
#define TK_AND                            60

#define TK_IS                             61
#define TK_BETWEEN                        62
#define TK_IN                             63
#define TK_ISNULL                         64
#define TK_NOTNULL                        65
#define TK_NE                             66
#define TK_EQ                             67
#define TK_GT                             68
#define TK_LE                             69
#define TK_LT                             70
#define TK_GE                             71
#define TK_ESCAPE                         72
#define TK_BITAND                         73
#define TK_BITOR                          74
#define TK_LSHIFT                         75
#define TK_RSHIFT                         76
#define TK_PLUS                           77
#define TK_MINUS                          78
#define TK_STAR                           79
#define TK_SLASH                          80
#define TK_REM                            81
#define TK_CONCAT                         82
#define TK_UMINUS                         83
#define TK_UPLUS                          84
#define TK_BITNOT                         85
#define TK_STRING                         86
#define TK_JOIN_KW                        87
#define TK_CONSTRAINT                     88
#define TK_DEFAULT                        89
#define TK_NULL                           90
#define TK_PRIMARY                        91
#define TK_UNIQUE                         92
#define TK_CHECK                          93
#define TK_REFERENCES                     94
#define TK_COLLATE                        95
#define TK_AUTOINCR                       96
#define TK_ON                             97
#define TK_DELETE                         98
#define TK_UPDATE                         99
#define TK_INSERT                         100
#define TK_SET                            101
#define TK_DEFERRABLE                     102
#define TK_FOREIGN                        103
#define TK_DROP                           104
#define TK_UNION                          105
#define TK_ALL                            106
#define TK_EXCEPT                         107
#define TK_INTERSECT                      108

#define TK_SELECT                         109
#define TK_DISTINCT                       110
#define TK_DOT                            111
#define TK_FROM                           112
#define TK_JOIN                           113
#define TK_USING                          114
#define TK_ORDER                          115
#define TK_BY                             116
#define TK_GROUP                          117
#define TK_HAVING                         118
#define TK_LIMIT                          119
#define TK_WHERE                          120
#define TK_INTO                           121
#define TK_VALUES                         122
#define TK_INTEGER                        123
#define TK_FLOAT                          124
#define TK_BLOB                           125
#define TK_REGISTER                       126
#define TK_VARIABLE                       127

#define TK_CASE                           128
#define TK_WHEN                           129
#define TK_THEN                           130
#define TK_ELSE                           131
#define TK_INDEX                          132
#define TK_ALTER                          133
#define TK_TO                             134
#define TK_ADD                            135
#define TK_COLUMNKW                       136
#define TK_TO_TEXT                        137
#define TK_TO_BLOB                        138
#define TK_TO_NUMERIC                     139
#define TK_TO_INT                         140
#define TK_TO_REAL                        141
#define TK_END_OF_FILE                    142
#define TK_ILLEGAL                        143
#define TK_SPACE                          144
#define TK_UNCLOSED_STRING                145
#define TK_COMMENT                        146
#define TK_FUNCTION                       147
#define TK_COLUMN                         148
#define TK_AGG_FUNCTION                   149
#define TK_AGG_COLUMN                     150
#define TK_CONST_FUNC                     151
>
>
>
>
>
>
>
>
|
|
<
<
|
|
|
|
|
|
|
|
|
|
<
<
<
|
|
|
|
|
|
|
|
<
|
|
|
|
<
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
|
|
>
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1
2
3
4
5
6
7
8
9
10


11
12
13
14
15
16
17
18
19
20



21
22
23
24
25
26
27
28

29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140

















#define TK_END_OF_FILE                     1
#define TK_ILLEGAL                         2
#define TK_SPACE                           3
#define TK_UNCLOSED_STRING                 4
#define TK_COMMENT                         5
#define TK_FUNCTION                        6
#define TK_COLUMN                          7
#define TK_AGG_FUNCTION                    8
#define TK_SEMI                            9
#define TK_EXPLAIN                        10


#define TK_BEGIN                          11
#define TK_TRANSACTION                    12
#define TK_DEFERRED                       13
#define TK_IMMEDIATE                      14
#define TK_EXCLUSIVE                      15
#define TK_COMMIT                         16
#define TK_END                            17
#define TK_ROLLBACK                       18
#define TK_CREATE                         19
#define TK_TABLE                          20



#define TK_TEMP                           21
#define TK_LP                             22
#define TK_RP                             23
#define TK_AS                             24
#define TK_COMMA                          25
#define TK_ID                             26
#define TK_ABORT                          27
#define TK_AFTER                          28

#define TK_ASC                            29
#define TK_ATTACH                         30
#define TK_BEFORE                         31
#define TK_CASCADE                        32

#define TK_CONFLICT                       33
#define TK_DATABASE                       34
#define TK_DESC                           35
#define TK_DETACH                         36
#define TK_EACH                           37
#define TK_FAIL                           38
#define TK_FOR                            39
#define TK_GLOB                           40
#define TK_IGNORE                         41
#define TK_INITIALLY                      42
#define TK_INSTEAD                        43
#define TK_LIKE                           44
#define TK_MATCH                          45
#define TK_KEY                            46
#define TK_OF                             47
#define TK_OFFSET                         48
#define TK_PRAGMA                         49
#define TK_RAISE                          50
#define TK_REPLACE                        51
#define TK_RESTRICT                       52
#define TK_ROW                            53
#define TK_STATEMENT                      54
#define TK_TRIGGER                        55
#define TK_VACUUM                         56
#define TK_VIEW                           57
#define TK_REINDEX                        58
#define TK_RENAME                         59
#define TK_CDATE                          60
#define TK_CTIME                          61
#define TK_CTIMESTAMP                     62
#define TK_ALTER                          63
#define TK_OR                             64
#define TK_AND                            65
#define TK_NOT                            66
#define TK_IS                             67
#define TK_BETWEEN                        68
#define TK_IN                             69
#define TK_ISNULL                         70
#define TK_NOTNULL                        71
#define TK_NE                             72
#define TK_EQ                             73
#define TK_GT                             74
#define TK_LE                             75
#define TK_LT                             76
#define TK_GE                             77
#define TK_ESCAPE                         78
#define TK_BITAND                         79
#define TK_BITOR                          80
#define TK_LSHIFT                         81
#define TK_RSHIFT                         82
#define TK_PLUS                           83
#define TK_MINUS                          84
#define TK_STAR                           85
#define TK_SLASH                          86
#define TK_REM                            87
#define TK_CONCAT                         88
#define TK_UMINUS                         89
#define TK_UPLUS                          90
#define TK_BITNOT                         91
#define TK_STRING                         92
#define TK_JOIN_KW                        93
#define TK_CONSTRAINT                     94
#define TK_DEFAULT                        95
#define TK_NULL                           96
#define TK_PRIMARY                        97
#define TK_UNIQUE                         98
#define TK_CHECK                          99
#define TK_REFERENCES                     100
#define TK_COLLATE                        101
#define TK_AUTOINCR                       102
#define TK_ON                             103
#define TK_DELETE                         104
#define TK_UPDATE                         105
#define TK_INSERT                         106
#define TK_SET                            107
#define TK_DEFERRABLE                     108
#define TK_FOREIGN                        109
#define TK_DROP                           110
#define TK_UNION                          111
#define TK_ALL                            112

#define TK_INTERSECT                      113
#define TK_EXCEPT                         114
#define TK_SELECT                         115
#define TK_DISTINCT                       116
#define TK_DOT                            117
#define TK_FROM                           118
#define TK_JOIN                           119
#define TK_USING                          120
#define TK_ORDER                          121
#define TK_BY                             122
#define TK_GROUP                          123
#define TK_HAVING                         124
#define TK_LIMIT                          125
#define TK_WHERE                          126
#define TK_INTO                           127
#define TK_VALUES                         128
#define TK_INTEGER                        129
#define TK_FLOAT                          130
#define TK_BLOB                           131
#define TK_REGISTER                       132
#define TK_VARIABLE                       133
#define TK_EXISTS                         134
#define TK_CASE                           135
#define TK_WHEN                           136
#define TK_THEN                           137
#define TK_ELSE                           138
#define TK_INDEX                          139

#define TK_TO                             140

















Changes to SQLite.Interop/src/pragma.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
** 2003 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER)

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
#endif

/*
** Interpret the given string as a safety level.  Return 0 for OFF,
** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or 
** unrecognized string argument.
**
** Note that the values returned are one less that the values that
** should be passed into sqlite3BtreeSetSafetyLevel().  The is done
** to support legacy SQL code.  The safety level used to be boolean
** and older scripts may have used numbers 0 for OFF and 1 for ON.
*/
static int getSafetyLevel(const char *z){
                             /* 123456789 123456789 */
  static const char zText[] = "onoffalseyestruefull";
  static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
  static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
  static const u8 iValue[] =  {1, 0, 0, 0, 1, 1, 2};
  int i, n;
  if( isdigit(*z) ){













|







|
















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
** 2003 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.1 2005/03/01 16:04:34 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
#ifndef SQLITE_OMIT_PRAGMA

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
#endif

/*
** Interpret the given string as a safety level.  Return 0 for OFF,
** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or 
** unrecognized string argument.
**
** Note that the values returned are one less that the values that
** should be passed into sqlite3BtreeSetSafetyLevel().  The is done
** to support legacy SQL code.  The safety level used to be boolean
** and older scripts may have used numbers 0 for OFF and 1 for ON.
*/
static int getSafetyLevel(const u8 *z){
                             /* 123456789 123456789 */
  static const char zText[] = "onoffalseyestruefull";
  static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
  static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
  static const u8 iValue[] =  {1, 0, 0, 0, 1, 1, 2};
  int i, n;
  if( isdigit(*z) ){
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  }
  return 1;
}

/*
** Interpret the given string as a boolean value.
*/
static int getBoolean(const char *z){
  return getSafetyLevel(z)&1;
}

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
** Interpret the given string as a temp db location. Return 1 for file
** backed temporary databases, 2 for the Red-Black tree in memory database
** and 0 to use the compile-time default.
*/
static int getTempStore(const char *z){
  if( z[0]>='0' && z[0]<='2' ){
    return z[0] - '0';
  }else if( sqlite3StrICmp(z, "file")==0 ){
    return 1;
  }else if( sqlite3StrICmp(z, "memory")==0 ){
    return 2;
  }else{
    return 0;
  }
}
#endif /* SQLITE_PAGER_PRAGMAS */

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
** Invalidate temp storage, either when the temp storage is changed
** from default, or when 'file' and the temp_store_directory has changed
*/
static int invalidateTempStorage(Parse *pParse){
  sqlite3 *db = pParse->db;
  if( db->aDb[1].pBt!=0 ){
    if( db->flags & SQLITE_InTrans ){
      sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
        "from within a transaction");
      return SQLITE_ERROR;
    }
    sqlite3BtreeClose(db->aDb[1].pBt);
    db->aDb[1].pBt = 0;
    sqlite3ResetInternalSchema(db, 0);
  }
  return SQLITE_OK;
}
#endif /* SQLITE_PAGER_PRAGMAS */

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
** If the TEMP database is open, close it and mark the database schema
** as needing reloading.  This must be done when using the TEMP_STORE
** or DEFAULT_TEMP_STORE pragmas.
*/
static int changeTempStorage(Parse *pParse, const char *zStorageType){
  int ts = getTempStore(zStorageType);
  sqlite3 *db = pParse->db;
  if( db->temp_store==ts ) return SQLITE_OK;
  if( invalidateTempStorage( pParse ) != SQLITE_OK ){
    return SQLITE_ERROR;
  }
  db->temp_store = ts;
  return SQLITE_OK;
}
#endif /* SQLITE_PAGER_PRAGMAS */

/*
** Generate code to return a single integer value.
*/
static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
  Vdbe *v = sqlite3GetVdbe(pParse);
  sqlite3VdbeAddOp(v, OP_Integer, value, 0);
  if( pParse->explain==0 ){
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
  }
  sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
}

#ifndef SQLITE_OMIT_FLAG_PRAGMAS
/*
** Check to see if zRight and zLeft refer to a pragma that queries
** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
** Also, implement the pragma.
*/
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
  static const struct sPragmaType {
    const char *zName;  /* Name of the pragma */
    int mask;           /* Mask for the db->flags value */
  } aPragma[] = {
    { "vdbe_trace",               SQLITE_VdbeTrace     },
    { "sql_trace",                SQLITE_SqlTrace      },
    { "vdbe_listing",             SQLITE_VdbeListing   },
    { "full_column_names",        SQLITE_FullColNames  },
    { "short_column_names",       SQLITE_ShortColNames },
    { "count_changes",            SQLITE_CountRows     },
    { "empty_result_callbacks",   SQLITE_NullCallback  },
    { "legacy_file_format",       SQLITE_LegacyFileFmt },
#ifndef SQLITE_OMIT_CHECK
    { "ignore_check_constraints", SQLITE_IgnoreChecks  },
#endif
    /* The following is VERY experimental */
    { "writable_schema",          SQLITE_WriteSchema   },
    { "omit_readlock",            SQLITE_NoReadlock    },

    /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
    ** flag if there are any active statements. */
    { "read_uncommitted",         SQLITE_ReadUncommitted },
  };
  int i;
  const struct sPragmaType *p;
  for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){
    if( sqlite3StrICmp(zLeft, p->zName)==0 ){
      sqlite3 *db = pParse->db;
      Vdbe *v;







|




















<

<


















<

<















|














<

















<
<
<
<



<
<
<
<







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

101

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148




149
150
151




152
153
154
155
156
157
158
  }
  return 1;
}

/*
** Interpret the given string as a boolean value.
*/
static int getBoolean(const u8 *z){
  return getSafetyLevel(z)&1;
}

#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
** Interpret the given string as a temp db location. Return 1 for file
** backed temporary databases, 2 for the Red-Black tree in memory database
** and 0 to use the compile-time default.
*/
static int getTempStore(const char *z){
  if( z[0]>='0' && z[0]<='2' ){
    return z[0] - '0';
  }else if( sqlite3StrICmp(z, "file")==0 ){
    return 1;
  }else if( sqlite3StrICmp(z, "memory")==0 ){
    return 2;
  }else{
    return 0;
  }
}



/*
** Invalidate temp storage, either when the temp storage is changed
** from default, or when 'file' and the temp_store_directory has changed
*/
static int invalidateTempStorage(Parse *pParse){
  sqlite3 *db = pParse->db;
  if( db->aDb[1].pBt!=0 ){
    if( db->flags & SQLITE_InTrans ){
      sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
        "from within a transaction");
      return SQLITE_ERROR;
    }
    sqlite3BtreeClose(db->aDb[1].pBt);
    db->aDb[1].pBt = 0;
    sqlite3ResetInternalSchema(db, 0);
  }
  return SQLITE_OK;
}



/*
** If the TEMP database is open, close it and mark the database schema
** as needing reloading.  This must be done when using the TEMP_STORE
** or DEFAULT_TEMP_STORE pragmas.
*/
static int changeTempStorage(Parse *pParse, const char *zStorageType){
  int ts = getTempStore(zStorageType);
  sqlite3 *db = pParse->db;
  if( db->temp_store==ts ) return SQLITE_OK;
  if( invalidateTempStorage( pParse ) != SQLITE_OK ){
    return SQLITE_ERROR;
  }
  db->temp_store = ts;
  return SQLITE_OK;
}
#endif

/*
** Generate code to return a single integer value.
*/
static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
  Vdbe *v = sqlite3GetVdbe(pParse);
  sqlite3VdbeAddOp(v, OP_Integer, value, 0);
  if( pParse->explain==0 ){
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
  }
  sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
}


/*
** Check to see if zRight and zLeft refer to a pragma that queries
** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
** Also, implement the pragma.
*/
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
  static const struct sPragmaType {
    const char *zName;  /* Name of the pragma */
    int mask;           /* Mask for the db->flags value */
  } aPragma[] = {
    { "vdbe_trace",               SQLITE_VdbeTrace     },
    { "sql_trace",                SQLITE_SqlTrace      },
    { "vdbe_listing",             SQLITE_VdbeListing   },
    { "full_column_names",        SQLITE_FullColNames  },
    { "short_column_names",       SQLITE_ShortColNames },
    { "count_changes",            SQLITE_CountRows     },
    { "empty_result_callbacks",   SQLITE_NullCallback  },




    /* The following is VERY experimental */
    { "writable_schema",          SQLITE_WriteSchema   },
    { "omit_readlock",            SQLITE_NoReadlock    },




  };
  int i;
  const struct sPragmaType *p;
  for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){
    if( sqlite3StrICmp(zLeft, p->zName)==0 ){
      sqlite3 *db = pParse->db;
      Vdbe *v;
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
        sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
      }
      return 1;
    }
  }
  return 0;
}
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */

/*
** Process a pragma statement.  
**
** Pragmas are of this form:
**
**      PRAGMA [database.]id [= value]







<







173
174
175
176
177
178
179

180
181
182
183
184
185
186
        sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
      }
      return 1;
    }
  }
  return 0;
}


/*
** Process a pragma statement.  
**
** Pragmas are of this form:
**
**      PRAGMA [database.]id [= value]
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
      sqlite3BeginWriteOperation(pParse, 0, iDb);
      sqlite3VdbeAddOp(v, OP_Integer, size, 0);
      sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);
      addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
      sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
      sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
      pDb->pSchema->cache_size = size;
      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
    }
  }else

  /*
  **  PRAGMA [database.]page_size
  **  PRAGMA [database.]page_size=N
  **







|
|







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
      sqlite3BeginWriteOperation(pParse, 0, iDb);
      sqlite3VdbeAddOp(v, OP_Integer, size, 0);
      sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);
      addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
      sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
      sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
      pDb->cache_size = size;
      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
    }
  }else

  /*
  **  PRAGMA [database.]page_size
  **  PRAGMA [database.]page_size=N
  **
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
  ** cache size stored on the disk so the cache size will revert
  ** to its default value when the database is closed and reopened.
  ** N should be a positive integer.
  */
  if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;
      pDb->pSchema->cache_size = size;
      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
    }
  }else

  /*
  **   PRAGMA temp_store
  **   PRAGMA temp_store = "default"|"memory"|"file"
  **







|



|
|







332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
  ** cache size stored on the disk so the cache size will revert
  ** to its default value when the database is closed and reopened.
  ** N should be a positive integer.
  */
  if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    if( !zRight ){
      returnSingleInt(pParse, "cache_size", pDb->cache_size);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;
      pDb->cache_size = size;
      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
    }
  }else

  /*
  **   PRAGMA temp_store
  **   PRAGMA temp_store = "default"|"memory"|"file"
  **
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
        pDb->safety_level = getSafetyLevel(zRight)+1;
        sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level);
      }
    }
  }else
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */

#ifndef SQLITE_OMIT_FLAG_PRAGMAS
  if( flagPragma(pParse, zLeft, zRight) ){
    /* The flagPragma() subroutine also generates any necessary code
    ** there is nothing more to do here */
  }else
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */

#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
  /*
  **   PRAGMA table_info(<table>)
  **
  ** Return a single row for each column of the named table. The columns of
  ** the returned data set are:







<




<







424
425
426
427
428
429
430

431
432
433
434

435
436
437
438
439
440
441
        pDb->safety_level = getSafetyLevel(zRight)+1;
        sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level);
      }
    }
  }else
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */


  if( flagPragma(pParse, zLeft, zRight) ){
    /* The flagPragma() subroutine also generates any necessary code
    ** there is nothing more to do here */
  }else


#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
  /*
  **   PRAGMA table_info(<table>)
  **
  ** Return a single row for each column of the named table. The columns of
  ** the returned data set are:
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635








636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700

701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724

725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
        sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
        sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
        sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
        sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
        while(pFK){
          int j;
          for(j=0; j<pFK->nCol; j++){
            char *zCol = pFK->aCol[j].zCol;
            sqlite3VdbeAddOp(v, OP_Integer, i, 0);
            sqlite3VdbeAddOp(v, OP_Integer, j, 0);
            sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->zTo, 0);
            sqlite3VdbeOp3(v, OP_String8, 0, 0,
                             pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
            sqlite3VdbeOp3(v, zCol ? OP_String8 : OP_Null, 0, 0, zCol, 0);
            sqlite3VdbeAddOp(v, OP_Callback, 5, 0);
          }
          ++i;
          pFK = pFK->pNextFrom;
        }
      }
    }
  }else
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */

#ifndef NDEBUG
  if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
    extern void sqlite3ParserTrace(FILE*, char *);
    if( zRight ){
      if( getBoolean(zRight) ){
        sqlite3ParserTrace(stderr, "parser: ");
      }else{
        sqlite3ParserTrace(0, 0);
      }
    }
  }else
#endif

  /* Reinstall the LIKE and GLOB functions.  The variant of LIKE
  ** used will be case sensitive or not depending on the RHS.
  */
  if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){
    if( zRight ){
      sqlite3RegisterLikeFunctions(db, getBoolean(zRight));
    }
  }else

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
  if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){
    int i, j, addr;









    /* Code that appears at the end of the integrity check.  If no error
    ** messages have been generated, output OK.  Otherwise output the
    ** error message
    */
    static const VdbeOpList endCode[] = {
      { OP_MemLoad,     0, 0,        0},
      { OP_Integer,     0, 0,        0},
      { OP_Ne,          0, 0,        0},    /* 2 */
      { OP_String8,     0, 0,        "ok"},
      { OP_Callback,    1, 0,        0},
    };

    /* Initialize the VDBE program */
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
    sqlite3VdbeAddOp(v, OP_MemInt, 0, 0);  /* Initialize error count to 0 */

    /* Do an integrity check on each database file */
    for(i=0; i<db->nDb; i++){
      HashElem *x;
      Hash *pTbls;
      int cnt = 0;

      if( OMIT_TEMPDB && i==1 ) continue;

      sqlite3CodeVerifySchema(pParse, i);

      /* Do an integrity check of the B-Tree
      */
      pTbls = &db->aDb[i].pSchema->tblHash;
      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0);
        cnt++;
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){

          sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
          cnt++;
        }
      }
      assert( cnt>0 );
      sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
      addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+7);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
         sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
         P3_DYNAMIC);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_Concat, 0, 1);
      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
      sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);

      /* Make sure all the indices are constructed correctly.
      */
      sqlite3CodeVerifySchema(pParse, i);
      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        int loopTop;

        if( pTab->pIndex==0 ) continue;
        sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);

        sqlite3VdbeAddOp(v, OP_MemInt, 0, 1);
        loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
        sqlite3VdbeAddOp(v, OP_MemIncr, 1, 1);
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          int jmp2;
          static const VdbeOpList idxErr[] = {
            { OP_MemIncr,     1,  0,  0},
            { OP_String8,     0,  0,  "rowid "},
            { OP_Rowid,       1,  0,  0},
            { OP_String8,     0,  0,  " missing from index "},
            { OP_String8,     0,  0,  0},    /* 4 */
            { OP_Concat,      2,  0,  0},
            { OP_Callback,    1,  0,  0},
          };
          sqlite3GenerateIndexKey(v, pIdx, 1);
          jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
          sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
          sqlite3VdbeJumpHere(v, jmp2);
        }
        sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
        sqlite3VdbeJumpHere(v, loopTop);
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          static const VdbeOpList cntIdx[] = {

             { OP_MemInt,       0,  2,  0},
             { OP_Rewind,       0,  0,  0},  /* 1 */
             { OP_MemIncr,      1,  2,  0},
             { OP_Next,         0,  0,  0},  /* 3 */
             { OP_MemLoad,      1,  0,  0},
             { OP_MemLoad,      2,  0,  0},
             { OP_Eq,           0,  0,  0},  /* 6 */
             { OP_MemIncr,      1,  0,  0},
             { OP_String8,      0,  0,  "wrong # of entries in index "},
             { OP_String8,      0,  0,  0},  /* 9 */
             { OP_Concat,       0,  0,  0},
             { OP_Callback,     1,  0,  0},
          };
          if( pIdx->tnum==0 ) continue;
          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
          sqlite3VdbeChangeP1(v, addr+1, j+2);
          sqlite3VdbeChangeP2(v, addr+1, addr+4);
          sqlite3VdbeChangeP1(v, addr+3, j+2);
          sqlite3VdbeChangeP2(v, addr+3, addr+2);
          sqlite3VdbeJumpHere(v, addr+6);
          sqlite3VdbeChangeP3(v, addr+9, pIdx->zName, P3_STATIC);
        }
      } 
    }
    addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
    sqlite3VdbeJumpHere(v, addr+2);
  }else
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_UTF16
  /*
  **   PRAGMA encoding
  **   PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"







<





|













<
|
|
|
|
<




<
<
<
<
<
<
<
<
<



>
>
>
>
>
>
>
>

















|




<


<
<




<
|





>








|






<




|






>
|

|



|

|









|


|


>
|
|
|
|


|
|

|





|
|
|
|
|
|




|







571
572
573
574
575
576
577

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596

597
598
599
600

601
602
603
604









605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637

638
639


640
641
642
643

644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665

666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
        sqlite3VdbeSetColName(v, 1, "seq", P3_STATIC);
        sqlite3VdbeSetColName(v, 2, "table", P3_STATIC);
        sqlite3VdbeSetColName(v, 3, "from", P3_STATIC);
        sqlite3VdbeSetColName(v, 4, "to", P3_STATIC);
        while(pFK){
          int j;
          for(j=0; j<pFK->nCol; j++){

            sqlite3VdbeAddOp(v, OP_Integer, i, 0);
            sqlite3VdbeAddOp(v, OP_Integer, j, 0);
            sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->zTo, 0);
            sqlite3VdbeOp3(v, OP_String8, 0, 0,
                             pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
            sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->aCol[j].zCol, 0);
            sqlite3VdbeAddOp(v, OP_Callback, 5, 0);
          }
          ++i;
          pFK = pFK->pNextFrom;
        }
      }
    }
  }else
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */

#ifndef NDEBUG
  if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
    extern void sqlite3ParserTrace(FILE*, char *);

    if( getBoolean(zRight) ){
      sqlite3ParserTrace(stdout, "parser: ");
    }else{
      sqlite3ParserTrace(0, 0);

    }
  }else
#endif










#ifndef SQLITE_OMIT_INTEGRITY_CHECK
  if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){
    int i, j, addr;

    /* Code that initializes the integrity check program.  Set the
    ** error count 0
    */
    static const VdbeOpList initCode[] = {
      { OP_Integer,     0, 0,        0},
      { OP_MemStore,    0, 1,        0},
    };

    /* Code that appears at the end of the integrity check.  If no error
    ** messages have been generated, output OK.  Otherwise output the
    ** error message
    */
    static const VdbeOpList endCode[] = {
      { OP_MemLoad,     0, 0,        0},
      { OP_Integer,     0, 0,        0},
      { OP_Ne,          0, 0,        0},    /* 2 */
      { OP_String8,     0, 0,        "ok"},
      { OP_Callback,    1, 0,        0},
    };

    /* Initialize the VDBE program */
    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, "integrity_check", P3_STATIC);
    sqlite3VdbeAddOpList(v, ArraySize(initCode), initCode);

    /* Do an integrity check on each database file */
    for(i=0; i<db->nDb; i++){
      HashElem *x;

      int cnt = 0;



      sqlite3CodeVerifySchema(pParse, i);

      /* Do an integrity check of the B-Tree
      */

      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0);
        cnt++;
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto pragma_out;
          sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0);
          cnt++;
        }
      }
      assert( cnt>0 );
      sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 1);
      addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Eq, 0, addr+6);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
         sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName),
         P3_DYNAMIC);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_Concat, 0, 1);
      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);


      /* Make sure all the indices are constructed correctly.
      */
      sqlite3CodeVerifySchema(pParse, i);
      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        int loopTop;

        if( pTab->pIndex==0 ) continue;
        sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
        sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
        sqlite3VdbeAddOp(v, OP_MemStore, 1, 1);
        loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0);
        sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0);
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          int jmp2;
          static const VdbeOpList idxErr[] = {
            { OP_MemIncr,     0,  0,  0},
            { OP_String8,     0,  0,  "rowid "},
            { OP_Recno,       1,  0,  0},
            { OP_String8,     0,  0,  " missing from index "},
            { OP_String8,     0,  0,  0},    /* 4 */
            { OP_Concat,      2,  0,  0},
            { OP_Callback,    1,  0,  0},
          };
          sqlite3GenerateIndexKey(v, pIdx, 1);
          jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0);
          addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
          sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
          sqlite3VdbeChangeP2(v, jmp2, sqlite3VdbeCurrentAddr(v));
        }
        sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1);
        sqlite3VdbeChangeP2(v, loopTop, sqlite3VdbeCurrentAddr(v));
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          static const VdbeOpList cntIdx[] = {
             { OP_Integer,      0,  0,  0},
             { OP_MemStore,     2,  1,  0},
             { OP_Rewind,       0,  0,  0},  /* 2 */
             { OP_MemIncr,      2,  0,  0},
             { OP_Next,         0,  0,  0},  /* 4 */
             { OP_MemLoad,      1,  0,  0},
             { OP_MemLoad,      2,  0,  0},
             { OP_Eq,           0,  0,  0},  /* 7 */
             { OP_MemIncr,      0,  0,  0},
             { OP_String8,      0,  0,  "wrong # of entries in index "},
             { OP_String8,      0,  0,  0},  /* 10 */
             { OP_Concat,       0,  0,  0},
             { OP_Callback,     1,  0,  0},
          };
          if( pIdx->tnum==0 ) continue;
          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
          sqlite3VdbeChangeP1(v, addr+2, j+2);
          sqlite3VdbeChangeP2(v, addr+2, addr+5);
          sqlite3VdbeChangeP1(v, addr+4, j+2);
          sqlite3VdbeChangeP2(v, addr+4, addr+3);
          sqlite3VdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
          sqlite3VdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
        }
      } 
    }
    addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
    sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
  }else
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

#ifndef SQLITE_OMIT_UTF16
  /*
  **   PRAGMA encoding
  **   PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
    encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
    if( !zRight ){    /* "PRAGMA encoding" */
      if( sqlite3ReadSchema(pParse) ) goto pragma_out;
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
        if( pEnc->enc==ENC(pParse->db) ){
          sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
          break;
        }
      }
      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
    }else{                        /* "PRAGMA encoding = XXX" */
      /* Only change the value of sqlite.enc if the database handle is not
      ** initialized. If the main database exists, the new sqlite.enc value
      ** will be overwritten when the schema is next loaded. If it does not
      ** already exists, it will be created to use the new encoding value.
      */
      if( 
        !(DbHasProperty(db, 0, DB_SchemaLoaded)) || 
        DbHasProperty(db, 0, DB_Empty) 
      ){
        for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
          if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
            ENC(pParse->db) = pEnc->enc;
            break;
          }
        }
        if( !pEnc->zName ){
          sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
        }
      }







|











|
<
<
<


|







771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790



791
792
793
794
795
796
797
798
799
800
    encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
    if( !zRight ){    /* "PRAGMA encoding" */
      if( sqlite3ReadSchema(pParse) ) goto pragma_out;
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
        if( pEnc->enc==pParse->db->enc ){
          sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC);
          break;
        }
      }
      sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
    }else{                        /* "PRAGMA encoding = XXX" */
      /* Only change the value of sqlite.enc if the database handle is not
      ** initialized. If the main database exists, the new sqlite.enc value
      ** will be overwritten when the schema is next loaded. If it does not
      ** already exists, it will be created to use the new encoding value.
      */
      if( !(pParse->db->flags&SQLITE_Initialized) ){



        for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
          if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
            pParse->db->enc = pEnc->enc;
            break;
          }
        }
        if( !pEnc->zName ){
          sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
        }
      }
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
    sqlite3VdbeSetNumCols(v, 2);
    sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);
    sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);
    for(i=0; i<db->nDb; i++){
      Btree *pBt;
      Pager *pPager;
      if( db->aDb[i].zName==0 ) continue;
      sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, P3_STATIC);
      pBt = db->aDb[i].pBt;
      if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
        sqlite3VdbeOp3(v, OP_String8, 0, 0, "closed", P3_STATIC);
      }else{
        int j = sqlite3pager_lockstate(pPager);
        sqlite3VdbeOp3(v, OP_String8, 0, 0, 
            (j>=0 && j<=4) ? azLockName[j] : "unknown", P3_STATIC);
      }
      sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
    }
  }else
#endif

#ifdef SQLITE_SSE
  /*
  ** Check to see if the sqlite_statements table exists.  Create it
  ** if it does not.
  */
  if( sqlite3StrICmp(zLeft, "create_sqlite_statement_table")==0 ){
    extern int sqlite3CreateStatementsTable(Parse*);
    sqlite3CreateStatementsTable(pParse);
  }else
#endif

#if SQLITE_HAS_CODEC
  if( sqlite3StrICmp(zLeft, "key")==0 ){
    sqlite3_key(db, zRight, strlen(zRight));
  }else
#endif

  {}

  if( v ){
    /* Code an OP_Expire at the end of each PRAGMA program to cause
    ** the VDBE implementing the pragma to expire. Most (all?) pragmas
    ** are only valid for a single execution.
    */
    sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
  }
pragma_out:
  sqliteFree(zLeft);
  sqliteFree(zRight);
}

#endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */







|


|


|







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














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

















898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
    sqlite3VdbeSetNumCols(v, 2);
    sqlite3VdbeSetColName(v, 0, "database", P3_STATIC);
    sqlite3VdbeSetColName(v, 1, "status", P3_STATIC);
    for(i=0; i<db->nDb; i++){
      Btree *pBt;
      Pager *pPager;
      if( db->aDb[i].zName==0 ) continue;
      sqlite3VdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, P3_STATIC);
      pBt = db->aDb[i].pBt;
      if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
        sqlite3VdbeOp3(v, OP_String, 0, 0, "closed", P3_STATIC);
      }else{
        int j = sqlite3pager_lockstate(pPager);
        sqlite3VdbeOp3(v, OP_String, 0, 0, 
            (j>=0 && j<=4) ? azLockName[j] : "unknown", P3_STATIC);
      }
      sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
    }
  }else
#endif


















  {}

  if( v ){
    /* Code an OP_Expire at the end of each PRAGMA program to cause
    ** the VDBE implementing the pragma to expire. Most (all?) pragmas
    ** are only valid for a single execution.
    */
    sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
  }
pragma_out:
  sqliteFree(zLeft);
  sqliteFree(zRight);
}

#endif /* SQLITE_OMIT_PRAGMA */
Deleted SQLite.Interop/src/prepare.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
/*
** 2005 May 25
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.11 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
*/
static void corruptSchema(InitData *pData, const char *zExtra){
  if( !sqlite3ThreadDataReadOnly()->mallocFailed ){
    sqlite3SetString(pData->pzErrMsg, "malformed database schema",
       zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
  }
}

/*
** This is the callback routine for the code that initializes the
** database.  See sqlite3Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
**
** Each callback contains the following information:
**
**     argv[0] = name of thing being created
**     argv[1] = root page number for table or index.  NULL for trigger or view.
**     argv[2] = SQL text for the CREATE statement.
**     argv[3] = "1" for temporary files, "0" for main database, "2" or more
**               for auxiliary database files.
**
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
  InitData *pData = (InitData*)pInit;
  sqlite3 *db = pData->db;
  int iDb;

  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    return SQLITE_NOMEM;
  }

  assert( argc==4 );
  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
  if( argv[1]==0 || argv[3]==0 ){
    corruptSchema(pData, 0);
    return 1;
  }
  iDb = atoi(argv[3]);
  assert( iDb>=0 && iDb<db->nDb );
  if( argv[2] && argv[2][0] ){
    /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    ** But because db->init.busy is set to 1, no VDBE code is generated
    ** or executed.  All the parser does is build the internal data
    ** structures that describe the table, index, or view.
    */
    char *zErr;
    int rc;
    assert( db->init.busy );
    db->init.iDb = iDb;
    db->init.newTnum = atoi(argv[1]);
    rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
    db->init.iDb = 0;
    if( SQLITE_OK!=rc ){
      if( rc==SQLITE_NOMEM ){
          sqlite3ThreadData()->mallocFailed = 1;
      }else{
          corruptSchema(pData, zErr);
      }
      sqlite3_free(zErr);
      return rc;
    }
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
    ** been created when we processed the CREATE TABLE.  All we have
    ** to do here is record the root page number for that index.
    */
    Index *pIndex;
    pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName);
    if( pIndex==0 || pIndex->tnum!=0 ){
      /* This can occur if there exists an index on a TEMP table which
      ** has the same name as another index on a permanent index.  Since
      ** the permanent table is hidden by the TEMP table, we can also
      ** safely ignore the index on the permanent table.
      */
      /* Do Nothing */;
    }else{
      pIndex->tnum = atoi(argv[1]);
    }
  }
  return 0;
}

/*
** Attempt to read the database schema and initialize internal
** data structures for a single database file.  The index of the
** database file is given by iDb.  iDb==0 is used for the main
** database.  iDb==1 should never be used.  iDb>=2 is used for
** auxiliary databases.  Return one of the SQLITE_ error codes to
** indicate success or failure.
*/
static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
  int rc;
  BtCursor *curMain;
  int size;
  Table *pTab;
  Db *pDb;
  char const *azArg[5];
  char zDbNum[30];
  int meta[10];
  InitData initData;
  char const *zMasterSchema;
  char const *zMasterName = SCHEMA_TABLE(iDb);

  /*
  ** The master database table has a structure like this
  */
  static const char master_schema[] = 
     "CREATE TABLE sqlite_master(\n"
     "  type text,\n"
     "  name text,\n"
     "  tbl_name text,\n"
     "  rootpage integer,\n"
     "  sql text\n"
     ")"
  ;
#ifndef SQLITE_OMIT_TEMPDB
  static const char temp_master_schema[] = 
     "CREATE TEMP TABLE sqlite_temp_master(\n"
     "  type text,\n"
     "  name text,\n"
     "  tbl_name text,\n"
     "  rootpage integer,\n"
     "  sql text\n"
     ")"
  ;
#else
  #define temp_master_schema 0
#endif

  assert( iDb>=0 && iDb<db->nDb );
  assert( db->aDb[iDb].pSchema );

  /* zMasterSchema and zInitScript are set to point at the master schema
  ** and initialisation script appropriate for the database being
  ** initialised. zMasterName is the name of the master table.
  */
  if( !OMIT_TEMPDB && iDb==1 ){
    zMasterSchema = temp_master_schema;
  }else{
    zMasterSchema = master_schema;
  }
  zMasterName = SCHEMA_TABLE(iDb);

  /* Construct the schema tables.  */
  sqlite3SafetyOff(db);
  azArg[0] = zMasterName;
  azArg[1] = "1";
  azArg[2] = zMasterSchema;
  sprintf(zDbNum, "%d", iDb);
  azArg[3] = zDbNum;
  azArg[4] = 0;
  initData.db = db;
  initData.pzErrMsg = pzErrMsg;
  rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0);
  if( rc!=SQLITE_OK ){
    sqlite3SafetyOn(db);
    return rc;
  }
  pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
  if( pTab ){
    pTab->readOnly = 1;
  }
  sqlite3SafetyOn(db);

  /* Create a cursor to hold the database open
  */
  pDb = &db->aDb[iDb];
  if( pDb->pBt==0 ){
    if( !OMIT_TEMPDB && iDb==1 ){
      DbSetProperty(db, 1, DB_SchemaLoaded);
    }
    return SQLITE_OK;
  }
  rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain);
  if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
    sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
    return rc;
  }

  /* Get the database meta information.
  **
  ** Meta values are as follows:
  **    meta[0]   Schema cookie.  Changes with each schema change.
  **    meta[1]   File format of schema layer.
  **    meta[2]   Size of the page cache.
  **    meta[3]   Use freelist if 0.  Autovacuum if greater than zero.
  **    meta[4]   Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE
  **    meta[5]   The user cookie. Used by the application.
  **    meta[6]   
  **    meta[7]
  **    meta[8]
  **    meta[9]
  **
  ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to
  ** the possible values of meta[4].
  */
  if( rc==SQLITE_OK ){
    int i;
    for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
      rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
    }
    if( rc ){
      sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
      sqlite3BtreeCloseCursor(curMain);
      return rc;
    }
  }else{
    memset(meta, 0, sizeof(meta));
  }
  pDb->pSchema->schema_cookie = meta[0];

  /* If opening a non-empty database, check the text encoding. For the
  ** main database, set sqlite3.enc to the encoding of the main database.
  ** For an attached db, it is an error if the encoding is not the same
  ** as sqlite3.enc.
  */
  if( meta[4] ){  /* text encoding */
    if( iDb==0 ){
      /* If opening the main database, set ENC(db). */
      ENC(db) = (u8)meta[4];
      db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0);
    }else{
      /* If opening an attached database, the encoding much match ENC(db) */
      if( meta[4]!=ENC(db) ){
        sqlite3BtreeCloseCursor(curMain);
        sqlite3SetString(pzErrMsg, "attached databases must use the same"
            " text encoding as main database", (char*)0);
        return SQLITE_ERROR;
      }
    }
  }else{
    DbSetProperty(db, iDb, DB_Empty);
  }
  pDb->pSchema->enc = ENC(db);

  size = meta[2];
  if( size==0 ){ size = MAX_PAGES; }
  pDb->pSchema->cache_size = size;
  sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);

  /*
  ** file_format==1    Version 3.0.0.
  ** file_format==2    Version 3.1.3.  // ALTER TABLE ADD COLUMN
  ** file_format==3    Version 3.1.4.  // ditto but with non-NULL defaults
  ** file_format==4    Version 3.3.0.  // DESC indices.  Boolean constants
  */
  pDb->pSchema->file_format = meta[1];
  if( pDb->pSchema->file_format==0 ){
    pDb->pSchema->file_format = 1;
  }
  if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
    sqlite3BtreeCloseCursor(curMain);
    sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
    return SQLITE_ERROR;
  }


  /* Read the schema information out of the schema tables
  */
  assert( db->init.busy );
  if( rc==SQLITE_EMPTY ){
    /* For an empty database, there is nothing to read */
    rc = SQLITE_OK;
  }else{
    char *zSql;
    zSql = sqlite3MPrintf(
        "SELECT name, rootpage, sql, '%s' FROM '%q'.%s",
        zDbNum, db->aDb[iDb].zName, zMasterName);
    sqlite3SafetyOff(db);
    rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
    sqlite3SafetyOn(db);
    sqliteFree(zSql);
#ifndef SQLITE_OMIT_ANALYZE
    if( rc==SQLITE_OK ){
      sqlite3AnalysisLoad(db, iDb);
    }
#endif
    sqlite3BtreeCloseCursor(curMain);
  }
  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
    rc = SQLITE_NOMEM;
    sqlite3ResetInternalSchema(db, 0);
  }
  if( rc==SQLITE_OK ){
    DbSetProperty(db, iDb, DB_SchemaLoaded);
  }else{
    sqlite3ResetInternalSchema(db, iDb);
  }
  return rc;
}

/*
** Initialize all database files - the main database file, the file
** used to store temporary tables, and any additional database files
** created using ATTACH statements.  Return a success code.  If an
** error occurs, write an error message into *pzErrMsg.
**
** After a database is initialized, the DB_SchemaLoaded bit is set
** bit is set in the flags field of the Db structure. If the database
** file was of zero-length, then the DB_Empty flag is also set.
*/
int sqlite3Init(sqlite3 *db, char **pzErrMsg){
  int i, rc;
  int called_initone = 0;
  
  if( db->init.busy ) return SQLITE_OK;
  rc = SQLITE_OK;
  db->init.busy = 1;
  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
    if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
    rc = sqlite3InitOne(db, i, pzErrMsg);
    if( rc ){
      sqlite3ResetInternalSchema(db, i);
    }
    called_initone = 1;
  }

  /* Once all the other databases have been initialised, load the schema
  ** for the TEMP database. This is loaded last, as the TEMP database
  ** schema may contain references to objects in other databases.
  */
#ifndef SQLITE_OMIT_TEMPDB
  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
    rc = sqlite3InitOne(db, 1, pzErrMsg);
    if( rc ){
      sqlite3ResetInternalSchema(db, 1);
    }
    called_initone = 1;
  }
#endif

  db->init.busy = 0;
  if( rc==SQLITE_OK && called_initone ){
    sqlite3CommitInternalChanges(db);
  }

  return rc; 
}

/*
** This routine is a no-op if the database schema is already initialised.
** Otherwise, the schema is loaded. An error code is returned.
*/
int sqlite3ReadSchema(Parse *pParse){
  int rc = SQLITE_OK;
  sqlite3 *db = pParse->db;
  if( !db->init.busy ){
    rc = sqlite3Init(db, &pParse->zErrMsg);
  }
  if( rc!=SQLITE_OK ){
    pParse->rc = rc;
    pParse->nErr++;
  }
  return rc;
}


/*
** Check schema cookies in all databases.  If any cookie is out
** of date, return 0.  If all schema cookies are current, return 1.
*/
static int schemaIsValid(sqlite3 *db){
  int iDb;
  int rc;
  BtCursor *curTemp;
  int cookie;
  int allOk = 1;

  for(iDb=0; allOk && iDb<db->nDb; iDb++){
    Btree *pBt;
    pBt = db->aDb[iDb].pBt;
    if( pBt==0 ) continue;
    rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp);
    if( rc==SQLITE_OK ){
      rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie);
      if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){
        allOk = 0;
      }
      sqlite3BtreeCloseCursor(curTemp);
    }
  }
  return allOk;
}

/*
** Free all resources held by the schema structure. The void* argument points
** at a Schema struct. This function does not call sqliteFree() on the 
** pointer itself, it just cleans up subsiduary resources (i.e. the contents
** of the schema hash tables).
*/
void sqlite3SchemaFree(void *p){
  Hash temp1;
  Hash temp2;
  HashElem *pElem;
  Schema *pSchema = (Schema *)p;

  temp1 = pSchema->tblHash;
  temp2 = pSchema->trigHash;
  sqlite3HashInit(&pSchema->trigHash, SQLITE_HASH_STRING, 0);
  sqlite3HashClear(&pSchema->aFKey);
  sqlite3HashClear(&pSchema->idxHash);
  for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
    sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
  }
  sqlite3HashClear(&temp2);
  sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0);
  for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
    Table *pTab = sqliteHashData(pElem);
    sqlite3DeleteTable(0, pTab);
  }
  sqlite3HashClear(&temp1);
  pSchema->pSeqTab = 0;
  pSchema->flags &= ~DB_SchemaLoaded;
}

Schema *sqlite3SchemaGet(Btree *pBt){
  Schema * p;
  if( pBt ){
    p = (Schema *)sqlite3BtreeSchema(pBt,sizeof(Schema),sqlite3SchemaFree);
  }else{
    p = (Schema *)sqliteMalloc(sizeof(Schema));
  }
  if( p && 0==p->file_format ){
    sqlite3HashInit(&p->tblHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1);
  }
  return p;
}

int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
  int i = -1000000;

  /* If pSchema is NULL, then return -1000000. This happens when code in 
  ** expr.c is trying to resolve a reference to a transient table (i.e. one
  ** created by a sub-select). In this case the return value of this 
  ** function should never be used.
  **
  ** We return -1000000 instead of the more usual -1 simply because using
  ** -1000000 as incorrectly using -1000000 index into db->aDb[] is much 
  ** more likely to cause a segfault than -1 (of course there are assert()
  ** statements too, but it never hurts to play the odds).
  */
  if( pSchema ){
    for(i=0; i<db->nDb; i++){
      if( db->aDb[i].pSchema==pSchema ){
        break;
      }
    }
    assert( i>=0 &&i>=0 &&  i<db->nDb );
  }
  return i;
}

/*
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
*/
int sqlite3_prepare(
  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char** pzTail       /* OUT: End of parsed string */
){
  Parse sParse;
  char *zErrMsg = 0;
  int rc = SQLITE_OK;
  int i;

  /* Assert that malloc() has not failed */
  assert( !sqlite3ThreadDataReadOnly()->mallocFailed );

  assert( ppStmt );
  *ppStmt = 0;
  if( sqlite3SafetyOn(db) ){
    return SQLITE_MISUSE;
  }

  /* If any attached database schemas are locked, do not proceed with
  ** compilation. Instead return SQLITE_LOCKED immediately.
  */
  for(i=0; i<db->nDb; i++) {
    Btree *pBt = db->aDb[i].pBt;
    if( pBt && sqlite3BtreeSchemaLocked(pBt) ){
      const char *zDb = db->aDb[i].zName;
      sqlite3Error(db, SQLITE_LOCKED, "database schema is locked: %s", zDb);
      sqlite3SafetyOff(db);
      return SQLITE_LOCKED;
    }
  }
  
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sParse.pTsd = sqlite3ThreadData();
  sParse.pTsd->nRef++;
  sqlite3RunParser(&sParse, zSql, &zErrMsg);

  if( sParse.pTsd->mallocFailed ){
    sParse.rc = SQLITE_NOMEM;
  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.checkSchema && !schemaIsValid(db) ){
    sParse.rc = SQLITE_SCHEMA;
  }
  if( sParse.rc==SQLITE_SCHEMA ){
    sqlite3ResetInternalSchema(db, 0);
  }
  if( pzTail ) *pzTail = sParse.zTail;
  rc = sParse.rc;

#ifndef SQLITE_OMIT_EXPLAIN
  if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
    if( sParse.explain==2 ){
      sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
      sqlite3VdbeSetColName(sParse.pVdbe, 0, "order", P3_STATIC);
      sqlite3VdbeSetColName(sParse.pVdbe, 1, "from", P3_STATIC);
      sqlite3VdbeSetColName(sParse.pVdbe, 2, "detail", P3_STATIC);
    }else{
      sqlite3VdbeSetNumCols(sParse.pVdbe, 5);
      sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC);
      sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC);
      sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC);
      sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC);
      sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC);
    }
  } 
#endif

  if( sqlite3SafetyOff(db) ){
    rc = SQLITE_MISUSE;
  }
  if( rc==SQLITE_OK ){
    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
  }else if( sParse.pVdbe ){
    sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
  }

  if( zErrMsg ){
    sqlite3Error(db, rc, "%s", zErrMsg);
    sqliteFree(zErrMsg);
  }else{
    sqlite3Error(db, rc, 0);
  }

  /* We must check for malloc failure last of all, in case malloc() failed
  ** inside of the sqlite3Error() call above or something.
  */
  if( sParse.pTsd->mallocFailed ){
    rc = SQLITE_NOMEM;
    sqlite3Error(db, rc, 0);
  }

  sParse.pTsd->nRef--;
  sqlite3MallocClearFailed();
  sqlite3ReleaseThreadData();
  return rc;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
*/
int sqlite3_prepare16(
  sqlite3 *db,              /* Database handle. */ 
  const void *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const void **pzTail       /* OUT: End of parsed string */
){
  /* This function currently works by first transforming the UTF-16
  ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
  ** tricky bit is figuring out the pointer to return in *pzTail.
  */
  char *zSql8 = 0;
  const char *zTail8 = 0;
  int rc;

  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }
  zSql8 = sqlite3utf16to8(zSql, nBytes);
  if( !zSql8 ){
    sqlite3Error(db, SQLITE_NOMEM, 0);
    return SQLITE_NOMEM;
  }
  rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8);

  if( zTail8 && pzTail ){
    /* If sqlite3_prepare returns a tail pointer, we calculate the
    ** equivalent pointer into the UTF-16 string by counting the unicode
    ** characters between zSql8 and zTail8, and then returning a pointer
    ** the same number of characters into the UTF-16 string.
    */
    int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8);
    *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed);
  }
  sqliteFree(zSql8); 
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to SQLite.Interop/src/printf.c.
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
** most frequently used conversion types first.
*/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
  {  'd', 10, 1, etRADIX,      0,  0 },
  {  's',  0, 4, etSTRING,     0,  0 },
  {  'g',  0, 1, etGENERIC,    30, 0 },
  {  'z',  0, 6, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
  {  'c',  0, 0, etCHARX,      0,  0 },
  {  'o',  8, 0, etRADIX,      0,  2 },
  {  'u', 10, 0, etRADIX,      0,  0 },
  {  'x', 16, 0, etRADIX,      16, 1 },
  {  'X', 16, 0, etRADIX,      0,  4 },
#ifndef SQLITE_OMIT_FLOATING_POINT
  {  'f',  0, 1, etFLOAT,      0,  0 },
  {  'e',  0, 1, etEXP,        30, 0 },
  {  'E',  0, 1, etEXP,        14, 0 },

  {  'G',  0, 1, etGENERIC,    14, 0 },
#endif
  {  'i', 10, 1, etRADIX,      0,  0 },
  {  'n',  0, 0, etSIZE,       0,  0 },
  {  '%',  0, 0, etPERCENT,    0,  0 },
  {  'p', 16, 0, etPOINTER,    0,  1 },
  {  'T',  0, 2, etTOKEN,      0,  0 },
  {  'S',  0, 2, etSRCLIST,    0,  0 },
};
#define etNINFO  (sizeof(fmtinfo)/sizeof(fmtinfo[0]))

/*
** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
** conversions will work.
*/
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** "*val" is a double such that 0.1 <= *val < 10.0
** Return the ascii code for the leading digit of *val, then
** multiply "*val" by 10.0 to renormalize.
**
** Example:
**     input:     *val = 3.14159







<








<



>

<










|


|







107
108
109
110
111
112
113

114
115
116
117
118
119
120
121

122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
** most frequently used conversion types first.
*/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
  {  'd', 10, 1, etRADIX,      0,  0 },
  {  's',  0, 4, etSTRING,     0,  0 },

  {  'z',  0, 6, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
  {  'c',  0, 0, etCHARX,      0,  0 },
  {  'o',  8, 0, etRADIX,      0,  2 },
  {  'u', 10, 0, etRADIX,      0,  0 },
  {  'x', 16, 0, etRADIX,      16, 1 },
  {  'X', 16, 0, etRADIX,      0,  4 },

  {  'f',  0, 1, etFLOAT,      0,  0 },
  {  'e',  0, 1, etEXP,        30, 0 },
  {  'E',  0, 1, etEXP,        14, 0 },
  {  'g',  0, 1, etGENERIC,    30, 0 },
  {  'G',  0, 1, etGENERIC,    14, 0 },

  {  'i', 10, 1, etRADIX,      0,  0 },
  {  'n',  0, 0, etSIZE,       0,  0 },
  {  '%',  0, 0, etPERCENT,    0,  0 },
  {  'p', 16, 0, etPOINTER,    0,  1 },
  {  'T',  0, 2, etTOKEN,      0,  0 },
  {  'S',  0, 2, etSRCLIST,    0,  0 },
};
#define etNINFO  (sizeof(fmtinfo)/sizeof(fmtinfo[0]))

/*
** If NOFLOATINGPOINT is defined, then none of the floating point
** conversions will work.
*/
#ifndef etNOFLOATINGPOINT
/*
** "*val" is a double such that 0.1 <= *val < 10.0
** Return the ascii code for the leading digit of *val, then
** multiply "*val" by 10.0 to renormalize.
**
** Example:
**     input:     *val = 3.14159
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
  if( (*cnt)++ >= 16 ) return '0';
  digit = (int)*val;
  d = digit;
  digit += '0';
  *val = (*val - d)*10.0;
  return digit;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */

/*
** On machines with a small stack size, you can redefine the
** SQLITE_PRINT_BUF_SIZE to be less than 350.  But beware - for
** smaller values some %f conversions may go into an infinite loop.
*/
#ifndef SQLITE_PRINT_BUF_SIZE
# define SQLITE_PRINT_BUF_SIZE 350
#endif
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE  /* Size of the output buffer */

/*
** The root program.  All variations call this core.
**
** INPUTS:
**   func   This is a pointer to a function taking three arguments
**            1. A pointer to anything.  Same as the "arg" parameter.







|

<
<
<
<
<
<
<
<
|







157
158
159
160
161
162
163
164
165








166
167
168
169
170
171
172
173
  if( (*cnt)++ >= 16 ) return '0';
  digit = (int)*val;
  d = digit;
  digit += '0';
  *val = (*val - d)*10.0;
  return digit;
}
#endif









#define etBUFSIZE 1000  /* Size of the output buffer */

/*
** The root program.  All variations call this core.
**
** INPUTS:
**   func   This is a pointer to a function taking three arguments
**            1. A pointer to anything.  Same as the "arg" parameter.
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
  int idx;                   /* A general purpose loop counter */
  int count;                 /* Total number of characters output */
  int width;                 /* Width of the current field */
  etByte flag_leftjustify;   /* True if "-" flag is present */
  etByte flag_plussign;      /* True if "+" flag is present */
  etByte flag_blanksign;     /* True if " " flag is present */
  etByte flag_alternateform; /* True if "#" flag is present */
  etByte flag_altform2;      /* True if "!" flag is present */
  etByte flag_zeropad;       /* True if field width constant starts with zero */
  etByte flag_long;          /* True if "l" flag is present */
  etByte flag_longlong;      /* True if the "ll" flag is present */
  etByte done;               /* Loop termination flag */
  UINT64_TYPE longvalue;     /* Value for integer types */
  LONGDOUBLE_TYPE realvalue; /* Value for real types */
  const et_info *infop;      /* Pointer to the appropriate info structure */
  char buf[etBUFSIZE];       /* Conversion buffer */
  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
  etByte errorflag = 0;      /* True if an error is encountered */
  etByte xtype;              /* Conversion paradigm */
  char *zExtra;              /* Extra memory used for etTCLESCAPE conversions */
  static const char spaces[] =
   "                                                                         ";
#define etSPACESIZE (sizeof(spaces)-1)
#ifndef SQLITE_OMIT_FLOATING_POINT
  int  exp, e2;              /* exponent of real numbers */
  double rounder;            /* Used for rounding floating point values */
  etByte flag_dp;            /* True if decimal point should be shown */
  etByte flag_rtz;           /* True if trailing zeros should be removed */
  etByte flag_exp;           /* True to force display of the exponent */
  int nsd;                   /* Number of significant digits returned */
#endif








<



<











|
|







206
207
208
209
210
211
212

213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
  int idx;                   /* A general purpose loop counter */
  int count;                 /* Total number of characters output */
  int width;                 /* Width of the current field */
  etByte flag_leftjustify;   /* True if "-" flag is present */
  etByte flag_plussign;      /* True if "+" flag is present */
  etByte flag_blanksign;     /* True if " " flag is present */
  etByte flag_alternateform; /* True if "#" flag is present */

  etByte flag_zeropad;       /* True if field width constant starts with zero */
  etByte flag_long;          /* True if "l" flag is present */
  etByte flag_longlong;      /* True if the "ll" flag is present */

  UINT64_TYPE longvalue;     /* Value for integer types */
  LONGDOUBLE_TYPE realvalue; /* Value for real types */
  const et_info *infop;      /* Pointer to the appropriate info structure */
  char buf[etBUFSIZE];       /* Conversion buffer */
  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
  etByte errorflag = 0;      /* True if an error is encountered */
  etByte xtype;              /* Conversion paradigm */
  char *zExtra;              /* Extra memory used for etTCLESCAPE conversions */
  static const char spaces[] =
   "                                                                         ";
#define etSPACESIZE (sizeof(spaces)-1)
#ifndef etNOFLOATINGPOINT
  int  exp;                  /* exponent of real numbers */
  double rounder;            /* Used for rounding floating point values */
  etByte flag_dp;            /* True if decimal point should be shown */
  etByte flag_rtz;           /* True if trailing zeros should be removed */
  etByte flag_exp;           /* True to force display of the exponent */
  int nsd;                   /* Number of significant digits returned */
#endif

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
      errorflag = 1;
      (*func)(arg,"%",1);
      count++;
      break;
    }
    /* Find out what flags are present */
    flag_leftjustify = flag_plussign = flag_blanksign = 
     flag_alternateform = flag_altform2 = flag_zeropad = 0;
    done = 0;
    do{
      switch( c ){
        case '-':   flag_leftjustify = 1;     break;
        case '+':   flag_plussign = 1;        break;
        case ' ':   flag_blanksign = 1;       break;
        case '#':   flag_alternateform = 1;   break;
        case '!':   flag_altform2 = 1;        break;
        case '0':   flag_zeropad = 1;         break;
        default:    done = 1;                 break;
      }
    }while( !done && (c=(*++fmt))!=0 );
    /* Get the field width */
    width = 0;
    if( c=='*' ){
      width = va_arg(ap,int);
      if( width<0 ){
        flag_leftjustify = 1;
        width = -width;







|
<


|
|
|
|
<
|
|

|







250
251
252
253
254
255
256
257

258
259
260
261
262
263

264
265
266
267
268
269
270
271
272
273
274
      errorflag = 1;
      (*func)(arg,"%",1);
      count++;
      break;
    }
    /* Find out what flags are present */
    flag_leftjustify = flag_plussign = flag_blanksign = 
     flag_alternateform = flag_zeropad = 0;

    do{
      switch( c ){
        case '-':   flag_leftjustify = 1;     c = 0;   break;
        case '+':   flag_plussign = 1;        c = 0;   break;
        case ' ':   flag_blanksign = 1;       c = 0;   break;
        case '#':   flag_alternateform = 1;   c = 0;   break;

        case '0':   flag_zeropad = 1;         c = 0;   break;
        default:                                       break;
      }
    }while( c==0 && (c=(*++fmt))!=0 );
    /* Get the field width */
    width = 0;
    if( c=='*' ){
      width = va_arg(ap,int);
      if( width<0 ){
        flag_leftjustify = 1;
        width = -width;
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
      precision = etBUFSIZE-40;
    }

    /*
    ** At this point, variables are initialized as follows:
    **
    **   flag_alternateform          TRUE if a '#' is present.
    **   flag_altform2               TRUE if a '!' is present.
    **   flag_plussign               TRUE if a '+' is present.
    **   flag_leftjustify            TRUE if a '-' is present or if the
    **                               field width was negative.
    **   flag_zeropad                TRUE if the width began with 0.
    **   flag_long                   TRUE if the letter 'l' (ell) prefixed
    **                               the conversion character.
    **   flag_longlong               TRUE if the letter 'll' (ell ell) prefixed







<







332
333
334
335
336
337
338

339
340
341
342
343
344
345
      precision = etBUFSIZE-40;
    }

    /*
    ** At this point, variables are initialized as follows:
    **
    **   flag_alternateform          TRUE if a '#' is present.

    **   flag_plussign               TRUE if a '+' is present.
    **   flag_leftjustify            TRUE if a '-' is present or if the
    **                               field width was negative.
    **   flag_zeropad                TRUE if the width began with 0.
    **   flag_long                   TRUE if the letter 'l' (ell) prefixed
    **                               the conversion character.
    **   flag_longlong               TRUE if the letter 'll' (ell ell) prefixed
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
        }
        length = &buf[etBUFSIZE-1]-bufpt;
        break;
      case etFLOAT:
      case etEXP:
      case etGENERIC:
        realvalue = va_arg(ap,double);
#ifndef SQLITE_OMIT_FLOATING_POINT
        if( precision<0 ) precision = 6;         /* Set default precision */
        if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10;
        if( realvalue<0.0 ){
          realvalue = -realvalue;
          prefix = '-';
        }else{
          if( flag_plussign )          prefix = '+';
          else if( flag_blanksign )    prefix = ' ';
          else                         prefix = 0;
        }
        if( xtype==etGENERIC && precision>0 ) precision--;

#if 0
        /* Rounding works like BSD when the constant 0.4999 is used.  Wierd! */
        for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
#else
        /* It makes more sense to use 0.5 */
        for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
#endif
        if( xtype==etFLOAT ) realvalue += rounder;
        /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
        exp = 0;
        if( realvalue>0.0 ){
          while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
          while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
          while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
          if( exp>350 || exp<-350 ){
            bufpt = "NaN";
            length = 3;







|

|








|
>







|



<







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

439
440
441
442
443
444
445
        }
        length = &buf[etBUFSIZE-1]-bufpt;
        break;
      case etFLOAT:
      case etEXP:
      case etGENERIC:
        realvalue = va_arg(ap,double);
#ifndef etNOFLOATINGPOINT
        if( precision<0 ) precision = 6;         /* Set default precision */
        if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10;
        if( realvalue<0.0 ){
          realvalue = -realvalue;
          prefix = '-';
        }else{
          if( flag_plussign )          prefix = '+';
          else if( flag_blanksign )    prefix = ' ';
          else                         prefix = 0;
        }
        if( infop->type==etGENERIC && precision>0 ) precision--;
        rounder = 0.0;
#if 0
        /* Rounding works like BSD when the constant 0.4999 is used.  Wierd! */
        for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
#else
        /* It makes more sense to use 0.5 */
        for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
#endif
        if( infop->type==etFLOAT ) realvalue += rounder;
        /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
        exp = 0;
        if( realvalue>0.0 ){

          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
          while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
          while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
          if( exp>350 || exp<-350 ){
            bufpt = "NaN";
            length = 3;
478
479
480
481
482
483
484

485
486
487
488
489

490

491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514



515
516
517








518
519
520
521
522
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
          }else{
            precision = precision - exp;
            xtype = etFLOAT;
          }
        }else{
          flag_rtz = 0;
        }

        if( xtype==etEXP ){
          e2 = 0;
        }else{
          e2 = exp;
        }

        nsd = 0;

        flag_dp = (precision>0) | flag_alternateform | flag_altform2;
        /* The sign in front of the number */
        if( prefix ){
          *(bufpt++) = prefix;
        }
        /* Digits prior to the decimal point */
        if( e2<0 ){
          *(bufpt++) = '0';
        }else{
          for(; e2>=0; e2--){
            *(bufpt++) = et_getdigit(&realvalue,&nsd);
          }
        }
        /* The decimal point */
        if( flag_dp ){
          *(bufpt++) = '.';
        }
        /* "0" digits after the decimal point but before the first
        ** significant digit of the number */
        for(e2++; e2<0 && precision>0; precision--, e2++){
          *(bufpt++) = '0';
        }
        /* Significant digits after the decimal point */
        while( (precision--)>0 ){



          *(bufpt++) = et_getdigit(&realvalue,&nsd);
        }
        /* Remove trailing zeros and the "." if no digits follow the "." */








        if( flag_rtz && flag_dp ){
          while( bufpt[-1]=='0' ) *(--bufpt) = 0;
          assert( bufpt>buf );
          if( bufpt[-1]=='.' ){
            if( flag_altform2 ){
              *(bufpt++) = '0';
            }else{
              *(--bufpt) = 0;
            }
          }
        }
        /* Add the "eNNN" suffix */

        if( flag_exp || (xtype==etEXP && exp) ){
          *(bufpt++) = aDigits[infop->charset];
          if( exp<0 ){
            *(bufpt++) = '-'; exp = -exp;
          }else{
            *(bufpt++) = '+';
          }
          if( exp>=100 ){
            *(bufpt++) = (exp/100)+'0';                /* 100's digit */
            exp %= 100;
          }
          *(bufpt++) = exp/10+'0';                     /* 10's digit */
          *(bufpt++) = exp%10+'0';                     /* 1's digit */
        }
        *bufpt = 0;

        /* The converted number is in buf[] and zero terminated. Output it.
        ** Note that the number is in the usual order, not reversed as with
        ** integer conversions. */
        length = bufpt-buf;
        bufpt = buf;

        /* Special case:  Add leading zeros if the flag_zeropad flag is







>
|
<
|
<
<
>

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







463
464
465
466
467
468
469
470
471

472


473
474
475
476

477




478


479


480





481
482
483

484
485
486
487
488
489

490
491
492
493
494
495
496
497
498
499

500




501



502
503
504

505

506

507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
          }else{
            precision = precision - exp;
            xtype = etFLOAT;
          }
        }else{
          flag_rtz = 0;
        }
        /*
        ** The "exp+precision" test causes output to be of type etEXP if

        ** the precision is too large to fit in buf[].


        */
        nsd = 0;
        if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){
          flag_dp = (precision>0 || flag_alternateform);

          if( prefix ) *(bufpt++) = prefix;         /* Sign */




          if( exp<0 )  *(bufpt++) = '0';            /* Digits before "." */


          else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd);


          if( flag_dp ) *(bufpt++) = '.';           /* The decimal point */





          for(exp++; exp<0 && precision>0; precision--, exp++){
            *(bufpt++) = '0';
          }

          while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
          *(bufpt--) = 0;                           /* Null terminate */
          if( flag_rtz && flag_dp ){     /* Remove trailing zeros and "." */
            while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
            if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
          }

          bufpt++;                            /* point to next free slot */
        }else{    /* etEXP or etGENERIC */
          flag_dp = (precision>0 || flag_alternateform);
          if( prefix ) *(bufpt++) = prefix;   /* Sign */
          *(bufpt++) = et_getdigit(&realvalue,&nsd);  /* First digit */
          if( flag_dp ) *(bufpt++) = '.';     /* Decimal point */
          while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
          bufpt--;                            /* point to last digit */
          if( flag_rtz && flag_dp ){          /* Remove tail zeros */
            while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;

            if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;




          }



          bufpt++;                            /* point to next free slot */
          if( exp || flag_exp ){
            *(bufpt++) = aDigits[infop->charset];

            if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */

            else       { *(bufpt++) = '+'; }

            if( exp>=100 ){
              *(bufpt++) = (exp/100)+'0';                /* 100's digit */
              exp %= 100;
            }
            *(bufpt++) = exp/10+'0';                     /* 10's digit */
            *(bufpt++) = exp%10+'0';                     /* 1's digit */
          }

        }
        /* The converted number is in buf[] and zero terminated. Output it.
        ** Note that the number is in the usual order, not reversed as with
        ** integer conversions. */
        length = bufpt-buf;
        bufpt = buf;

        /* Special case:  Add leading zeros if the flag_zeropad flag is
591
592
593
594
595
596
597
598

599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626

627
628
629
630
631
632
633
634
635
636
637
        }else if( xtype==etDYNSTRING ){
          zExtra = bufpt;
        }
        length = strlen(bufpt);
        if( precision>=0 && precision<length ) length = precision;
        break;
      case etSQLESCAPE:
      case etSQLESCAPE2: {

        int i, j, n, c, isnull;
        int needQuote;
        char *arg = va_arg(ap,char*);
        isnull = arg==0;
        if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
        for(i=n=0; (c=arg[i])!=0; i++){
          if( c=='\'' )  n++;
        }
        needQuote = !isnull && xtype==etSQLESCAPE2;
        n += i + 1 + needQuote*2;
        if( n>etBUFSIZE ){
          bufpt = zExtra = sqliteMalloc( n );
          if( bufpt==0 ) return -1;
        }else{
          bufpt = buf;
        }
        j = 0;
        if( needQuote ) bufpt[j++] = '\'';
        for(i=0; (c=arg[i])!=0; i++){
          bufpt[j++] = c;
          if( c=='\'' ) bufpt[j++] = c;
        }
        if( needQuote ) bufpt[j++] = '\'';
        bufpt[j] = 0;
        length = j;
        if( precision>=0 && precision<length ) length = precision;
        break;
      }

      case etTOKEN: {
        Token *pToken = va_arg(ap, Token*);
        if( pToken && pToken->z ){
          (*func)(arg, (char*)pToken->z, pToken->n);
        }
        length = width = 0;
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc = va_arg(ap, SrcList*);
        int k = va_arg(ap, int);







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



|







560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594

595
596
597
598
599
600
601
602
603
604
605
606
607
        }else if( xtype==etDYNSTRING ){
          zExtra = bufpt;
        }
        length = strlen(bufpt);
        if( precision>=0 && precision<length ) length = precision;
        break;
      case etSQLESCAPE:
      case etSQLESCAPE2:
        {
          int i, j, n, c, isnull;
          int needQuote;
          char *arg = va_arg(ap,char*);
          isnull = arg==0;
          if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
          for(i=n=0; (c=arg[i])!=0; i++){
            if( c=='\'' )  n++;
          }
          needQuote = !isnull && xtype==etSQLESCAPE2;
          n += i + 1 + needQuote*2;
          if( n>etBUFSIZE ){
            bufpt = zExtra = sqliteMalloc( n );
            if( bufpt==0 ) return -1;
          }else{
            bufpt = buf;
          }
          j = 0;
          if( needQuote ) bufpt[j++] = '\'';
          for(i=0; (c=arg[i])!=0; i++){
            bufpt[j++] = c;
            if( c=='\'' ) bufpt[j++] = c;
          }
          if( needQuote ) bufpt[j++] = '\'';
          bufpt[j] = 0;
          length = j;
          if( precision>=0 && precision<length ) length = precision;

        }
        break;
      case etTOKEN: {
        Token *pToken = va_arg(ap, Token*);
        if( pToken && pToken->z ){
          (*func)(arg, pToken->z, pToken->n);
        }
        length = width = 0;
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc = va_arg(ap, SrcList*);
        int k = va_arg(ap, int);
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
      pM->nAlloc = pM->nChar + nNewChar*2 + 1;
      if( pM->zText==pM->zBase ){
        pM->zText = pM->xRealloc(0, pM->nAlloc);
        if( pM->zText && pM->nChar ){
          memcpy(pM->zText, pM->zBase, pM->nChar);
        }
      }else{
        char *zNew;
        zNew = pM->xRealloc(pM->zText, pM->nAlloc);
        if( zNew ){
          pM->zText = zNew;
        }
      }
    }
  }
  if( pM->zText ){
    if( nNewChar>0 ){
      memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
      pM->nChar += nNewChar;







<
|
<
<
<







694
695
696
697
698
699
700

701



702
703
704
705
706
707
708
      pM->nAlloc = pM->nChar + nNewChar*2 + 1;
      if( pM->zText==pM->zBase ){
        pM->zText = pM->xRealloc(0, pM->nAlloc);
        if( pM->zText && pM->nChar ){
          memcpy(pM->zText, pM->zBase, pM->nChar);
        }
      }else{

        pM->zText = pM->xRealloc(pM->zText, pM->nAlloc);



      }
    }
  }
  if( pM->zText ){
    if( nNewChar>0 ){
      memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
      pM->nChar += nNewChar;
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
  if( xRealloc ){
    if( sM.zText==sM.zBase ){
      sM.zText = xRealloc(0, sM.nChar+1);
      if( sM.zText ){
        memcpy(sM.zText, sM.zBase, sM.nChar+1);
      }
    }else if( sM.nAlloc>sM.nChar+10 ){
      char *zNew = xRealloc(sM.zText, sM.nChar+1);
      if( zNew ){
        sM.zText = zNew;
      }
    }
  }
  return sM.zText;
}

/*
** Realloc that is a real function, not a macro.
*/
static void *printf_realloc(void *old, int size){
  return sqliteRealloc(old,size);
}

/*
** Print into memory obtained from sqliteMalloc().  Use the internal
** %-conversion extensions.
*/
char *sqlite3VMPrintf(const char *zFormat, va_list ap){
  char zBase[SQLITE_PRINT_BUF_SIZE];
  return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
}

/*
** Print into memory obtained from sqliteMalloc().  Use the internal
** %-conversion extensions.
*/
char *sqlite3MPrintf(const char *zFormat, ...){
  va_list ap;
  char *z;
  char zBase[SQLITE_PRINT_BUF_SIZE];
  va_start(ap, zFormat);
  z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
  va_end(ap);
  return z;
}

/*







|
<
<
<

















|










|







732
733
734
735
736
737
738
739



740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
  if( xRealloc ){
    if( sM.zText==sM.zBase ){
      sM.zText = xRealloc(0, sM.nChar+1);
      if( sM.zText ){
        memcpy(sM.zText, sM.zBase, sM.nChar+1);
      }
    }else if( sM.nAlloc>sM.nChar+10 ){
      sM.zText = xRealloc(sM.zText, sM.nChar+1);



    }
  }
  return sM.zText;
}

/*
** Realloc that is a real function, not a macro.
*/
static void *printf_realloc(void *old, int size){
  return sqliteRealloc(old,size);
}

/*
** Print into memory obtained from sqliteMalloc().  Use the internal
** %-conversion extensions.
*/
char *sqlite3VMPrintf(const char *zFormat, va_list ap){
  char zBase[1000];
  return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
}

/*
** Print into memory obtained from sqliteMalloc().  Use the internal
** %-conversion extensions.
*/
char *sqlite3MPrintf(const char *zFormat, ...){
  va_list ap;
  char *z;
  char zBase[1000];
  va_start(ap, zFormat);
  z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
  va_end(ap);
  return z;
}

/*
Changes to SQLite.Interop/src/random.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
*************************************************************************
** This file contains code to implement a pseudo-random number
** generator (PRNG) for SQLite.
**
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"


/*
** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
** must be held while executing this routine.
**
** Why not just use a library random generator like lrand48() for this?
** Because the OP_NewRowid opcode in the VDBE depends on having a very
** good source of random numbers.  The lrand48() library function may
** well be good enough.  But maybe not.  Or maybe lrand48() has some
** subtle problems on some systems that could cause problems.  It is hard
** to know.  To minimize the risk of problems due to bad lrand48()
** implementations, SQLite uses this random number generator based
** on RC4, which we know works very well.
**
** (Later):  Actually, OP_NewRowid does not depend on a good source of
** randomness any more.  But we will leave this code in all the same.
*/
static int randomByte(){
  unsigned char t;

  /* All threads share a single random number generator.
  ** This structure is the current state of the generator.
  */







|










|






<
<
<







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35



36
37
38
39
40
41
42
*************************************************************************
** This file contains code to implement a pseudo-random number
** generator (PRNG) for SQLite.
**
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.1 2005/03/01 16:04:34 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"


/*
** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
** must be held while executing this routine.
**
** Why not just use a library random generator like lrand48() for this?
** Because the OP_NewRecno opcode in the VDBE depends on having a very
** good source of random numbers.  The lrand48() library function may
** well be good enough.  But maybe not.  Or maybe lrand48() has some
** subtle problems on some systems that could cause problems.  It is hard
** to know.  To minimize the risk of problems due to bad lrand48()
** implementations, SQLite uses this random number generator based
** on RC4, which we know works very well.



*/
static int randomByte(){
  unsigned char t;

  /* All threads share a single random number generator.
  ** This structure is the current state of the generator.
  */
94
95
96
97
98
99
100



  unsigned char *zBuf = pBuf;
  sqlite3OsEnterMutex();
  while( N-- ){
    *(zBuf++) = randomByte();
  }
  sqlite3OsLeaveMutex();
}










>
>
>
91
92
93
94
95
96
97
98
99
100
  unsigned char *zBuf = pBuf;
  sqlite3OsEnterMutex();
  while( N-- ){
    *(zBuf++) = randomByte();
  }
  sqlite3OsLeaveMutex();
}



Changes to SQLite.Interop/src/select.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.16 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
Select *sqlite3SelectNew(
  ExprList *pEList,     /* which columns to include in the result */







|


|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.1 2005/03/01 16:04:35 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "../interop.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
Select *sqlite3SelectNew(
  ExprList *pEList,     /* which columns to include in the result */
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    pNew->pOrderBy = pOrderBy;
    pNew->isDistinct = isDistinct;
    pNew->op = TK_SELECT;
    pNew->pLimit = pLimit;
    pNew->pOffset = pOffset;
    pNew->iLimit = -1;
    pNew->iOffset = -1;
    pNew->addrOpenVirt[0] = -1;
    pNew->addrOpenVirt[1] = -1;
    pNew->addrOpenVirt[2] = -1;
  }
  return pNew;
}

/*
** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
** type of join.  Return an integer constant that expresses that type
** in terms of the following bit values:
**
**     JT_INNER
**     JT_CROSS
**     JT_OUTER
**     JT_NATURAL
**     JT_LEFT
**     JT_RIGHT
**
** A full outer join is the combination of JT_LEFT and JT_RIGHT.
**
** If an illegal or unsupported join type is seen, then still return
** a join type, but put an error in the pParse structure.
*/
int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
  int jointype = 0;
  Token *apAll[3];
  Token *p;
  static const struct {
    const char zKeyword[8];
    u8 nChar;
    u8 code;
  } keywords[] = {
    { "natural", 7, JT_NATURAL },
    { "left",    4, JT_LEFT|JT_OUTER },
    { "right",   5, JT_RIGHT|JT_OUTER },
    { "full",    4, JT_LEFT|JT_RIGHT|JT_OUTER },
    { "outer",   5, JT_OUTER },
    { "inner",   5, JT_INNER },
    { "cross",   5, JT_INNER|JT_CROSS },
  };
  int i, j;
  apAll[0] = pA;
  apAll[1] = pB;
  apAll[2] = pC;
  for(i=0; i<3 && apAll[i]; i++){
    p = apAll[i];
    for(j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++){
      if( p->n==keywords[j].nChar 
          && sqlite3StrNICmp((char*)p->z, keywords[j].zKeyword, p->n)==0 ){
        jointype |= keywords[j].code;
        break;
      }
    }
    if( j>=sizeof(keywords)/sizeof(keywords[0]) ){
      jointype |= JT_ERROR;
      break;







<
<
<










<















|









|









|







56
57
58
59
60
61
62



63
64
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    pNew->pOrderBy = pOrderBy;
    pNew->isDistinct = isDistinct;
    pNew->op = TK_SELECT;
    pNew->pLimit = pLimit;
    pNew->pOffset = pOffset;
    pNew->iLimit = -1;
    pNew->iOffset = -1;



  }
  return pNew;
}

/*
** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
** type of join.  Return an integer constant that expresses that type
** in terms of the following bit values:
**
**     JT_INNER

**     JT_OUTER
**     JT_NATURAL
**     JT_LEFT
**     JT_RIGHT
**
** A full outer join is the combination of JT_LEFT and JT_RIGHT.
**
** If an illegal or unsupported join type is seen, then still return
** a join type, but put an error in the pParse structure.
*/
int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
  int jointype = 0;
  Token *apAll[3];
  Token *p;
  static const struct {
    const char *zKeyword;
    u8 nChar;
    u8 code;
  } keywords[] = {
    { "natural", 7, JT_NATURAL },
    { "left",    4, JT_LEFT|JT_OUTER },
    { "right",   5, JT_RIGHT|JT_OUTER },
    { "full",    4, JT_LEFT|JT_RIGHT|JT_OUTER },
    { "outer",   5, JT_OUTER },
    { "inner",   5, JT_INNER },
    { "cross",   5, JT_INNER },
  };
  int i, j;
  apAll[0] = pA;
  apAll[1] = pB;
  apAll[2] = pC;
  for(i=0; i<3 && apAll[i]; i++){
    p = apAll[i];
    for(j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++){
      if( p->n==keywords[j].nChar 
          && sqlite3StrNICmp(p->z, keywords[j].zKeyword, p->n)==0 ){
        jointype |= keywords[j].code;
        break;
      }
    }
    if( j>=sizeof(keywords)/sizeof(keywords[0]) ){
      jointype |= JT_ERROR;
      break;
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

185
186
187
188
189

190
191
192
193
194

195
196
197
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
  return -1;
}

/*
** Set the value of a token to a '\000'-terminated string.
*/
static void setToken(Token *p, const char *z){
  p->z = (u8*)z;
  p->n = z ? strlen(z) : 0;
  p->dyn = 0;
}

/*
** Create an expression node for an identifier with the name of zName
*/
static Expr *createIdExpr(const char *zName){
  Token dummy;
  setToken(&dummy, zName);
  return sqlite3Expr(TK_ID, 0, 0, &dummy);
}


/*
** Add a term to the WHERE expression in *ppExpr that requires the
** zCol column to be equal in the two tables pTab1 and pTab2.
*/
static void addWhereTerm(
  const char *zCol,        /* Name of the column */
  const Table *pTab1,      /* First table */
  const char *zAlias1,     /* Alias for first table.  May be NULL */
  const Table *pTab2,      /* Second table */
  const char *zAlias2,     /* Alias for second table.  May be NULL */
  int iRightJoinTable,     /* VDBE cursor for the right table */
  Expr **ppExpr            /* Add the equality term to this expression */
){

  Expr *pE1a, *pE1b, *pE1c;
  Expr *pE2a, *pE2b, *pE2c;
  Expr *pE;

  pE1a = createIdExpr(zCol);

  pE2a = createIdExpr(zCol);
  if( zAlias1==0 ){
    zAlias1 = pTab1->zName;
  }
  pE1b = createIdExpr(zAlias1);

  if( zAlias2==0 ){
    zAlias2 = pTab2->zName;
  }
  pE2b = createIdExpr(zAlias2);

  pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0);
  pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0);
  pE = sqlite3Expr(TK_EQ, pE1c, pE2c, 0);
  ExprSetProperty(pE, EP_FromJoin);
  pE->iRightJoinTable = iRightJoinTable;
  *ppExpr = sqlite3ExprAnd(*ppExpr, pE);
}

/*
** Set the EP_FromJoin property on all terms of the given expression.
** And set the Expr.iRightJoinTable to iTable for every term in the
** expression.
**
** The EP_FromJoin property is used on terms of an expression to tell
** the LEFT OUTER JOIN processing logic that this term is part of the
** join restriction specified in the ON or USING clause and not a part
** of the more general WHERE clause.  These terms are moved over to the
** WHERE clause during join processing but we need to remember that they
** originated in the ON or USING clause.
**
** The Expr.iRightJoinTable tells the WHERE clause processing that the
** expression depends on table iRightJoinTable even if that table is not
** explicitly mentioned in the expression.  That information is needed
** for cases like this:
**
**    SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
**
** The where clause needs to defer the handling of the t1.x=5
** term until after the t2 loop of the join.  In that way, a
** NULL t2 row will be inserted whenever t1.x!=5.  If we do not
** defer the handling of t1.x=5, it will be processed immediately
** after the t1 loop and rows with t1.x!=5 will never appear in
** the output, which is incorrect.
*/
static void setJoinExpr(Expr *p, int iTable){
  while( p ){
    ExprSetProperty(p, EP_FromJoin);
    p->iRightJoinTable = iTable;
    setJoinExpr(p->pLeft, iTable);
    p = p->pRight;
  } 
}

/*
** This routine processes the join information for a SELECT statement.
** ON and USING clauses are converted into extra terms of the WHERE clause.







|
|



<
<
<
<
<
<
<
<
<











<


>




|
>
|



|
>



|
>




<





<
<







<
<
<
<
<
<
<
<
<
<
<
<
<
<

|


<
|







146
147
148
149
150
151
152
153
154
155
156
157









158
159
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197


198
199
200
201
202
203
204














205
206
207
208

209
210
211
212
213
214
215
216
  return -1;
}

/*
** Set the value of a token to a '\000'-terminated string.
*/
static void setToken(Token *p, const char *z){
  p->z = z;
  p->n = strlen(z);
  p->dyn = 0;
}











/*
** Add a term to the WHERE expression in *ppExpr that requires the
** zCol column to be equal in the two tables pTab1 and pTab2.
*/
static void addWhereTerm(
  const char *zCol,        /* Name of the column */
  const Table *pTab1,      /* First table */
  const char *zAlias1,     /* Alias for first table.  May be NULL */
  const Table *pTab2,      /* Second table */
  const char *zAlias2,     /* Alias for second table.  May be NULL */

  Expr **ppExpr            /* Add the equality term to this expression */
){
  Token dummy;
  Expr *pE1a, *pE1b, *pE1c;
  Expr *pE2a, *pE2b, *pE2c;
  Expr *pE;

  setToken(&dummy, zCol);
  pE1a = sqlite3Expr(TK_ID, 0, 0, &dummy);
  pE2a = sqlite3Expr(TK_ID, 0, 0, &dummy);
  if( zAlias1==0 ){
    zAlias1 = pTab1->zName;
  }
  setToken(&dummy, zAlias1);
  pE1b = sqlite3Expr(TK_ID, 0, 0, &dummy);
  if( zAlias2==0 ){
    zAlias2 = pTab2->zName;
  }
  setToken(&dummy, zAlias2);
  pE2b = sqlite3Expr(TK_ID, 0, 0, &dummy);
  pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0);
  pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0);
  pE = sqlite3Expr(TK_EQ, pE1c, pE2c, 0);
  ExprSetProperty(pE, EP_FromJoin);

  *ppExpr = sqlite3ExprAnd(*ppExpr, pE);
}

/*
** Set the EP_FromJoin property on all terms of the given expression.


**
** The EP_FromJoin property is used on terms of an expression to tell
** the LEFT OUTER JOIN processing logic that this term is part of the
** join restriction specified in the ON or USING clause and not a part
** of the more general WHERE clause.  These terms are moved over to the
** WHERE clause during join processing but we need to remember that they
** originated in the ON or USING clause.














*/
static void setJoinExpr(Expr *p){
  while( p ){
    ExprSetProperty(p, EP_FromJoin);

    setJoinExpr(p->pLeft);
    p = p->pRight;
  } 
}

/*
** This routine processes the join information for a SELECT statement.
** ON and USING clauses are converted into extra terms of the WHERE clause.
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
           "an ON or USING clause", 0);
        return 1;
      }
      for(j=0; j<pLeftTab->nCol; j++){
        char *zName = pLeftTab->aCol[j].zName;
        if( columnIndex(pRightTab, zName)>=0 ){
          addWhereTerm(zName, pLeftTab, pLeft->zAlias, 
                              pRightTab, pRight->zAlias,
                              pRight->iCursor, &p->pWhere);
          
        }
      }
    }

    /* Disallow both ON and USING clauses in the same join
    */
    if( pLeft->pOn && pLeft->pUsing ){
      sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
        "clauses in the same join");
      return 1;
    }

    /* Add the ON clause to the end of the WHERE clause, connected by
    ** an AND operator.
    */
    if( pLeft->pOn ){
      setJoinExpr(pLeft->pOn, pRight->iCursor);
      p->pWhere = sqlite3ExprAnd(p->pWhere, pLeft->pOn);
      pLeft->pOn = 0;
    }

    /* Create extra terms on the WHERE clause for each column named
    ** in the USING clause.  Example: If the two tables to be joined are 
    ** A and B and the USING clause names X, Y, and Z, then add this







|
<
<
















|







249
250
251
252
253
254
255
256


257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
           "an ON or USING clause", 0);
        return 1;
      }
      for(j=0; j<pLeftTab->nCol; j++){
        char *zName = pLeftTab->aCol[j].zName;
        if( columnIndex(pRightTab, zName)>=0 ){
          addWhereTerm(zName, pLeftTab, pLeft->zAlias, 
                              pRightTab, pRight->zAlias, &p->pWhere);


        }
      }
    }

    /* Disallow both ON and USING clauses in the same join
    */
    if( pLeft->pOn && pLeft->pUsing ){
      sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
        "clauses in the same join");
      return 1;
    }

    /* Add the ON clause to the end of the WHERE clause, connected by
    ** an AND operator.
    */
    if( pLeft->pOn ){
      setJoinExpr(pLeft->pOn);
      p->pWhere = sqlite3ExprAnd(p->pWhere, pLeft->pOn);
      pLeft->pOn = 0;
    }

    /* Create extra terms on the WHERE clause for each column named
    ** in the USING clause.  Example: If the two tables to be joined are 
    ** A and B and the USING clause names X, Y, and Z, then add this
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
        char *zName = pList->a[j].zName;
        if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
          sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
            "not present in both tables", zName);
          return 1;
        }
        addWhereTerm(zName, pLeftTab, pLeft->zAlias, 
                            pRightTab, pRight->zAlias,
                            pRight->iCursor, &p->pWhere);
      }
    }
  }
  return 0;
}

/*







|
<







288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
        char *zName = pList->a[j].zName;
        if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
          sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
            "not present in both tables", zName);
          return 1;
        }
        addWhereTerm(zName, pLeftTab, pLeft->zAlias, 
                            pRightTab, pRight->zAlias, &p->pWhere);

      }
    }
  }
  return 0;
}

/*
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

385
386
387
388

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
  sqliteFree(p);
}

/*
** Insert code into "v" that will push the record on the top of the
** stack into the sorter.
*/
static void pushOntoSorter(
  Parse *pParse,         /* Parser context */
  ExprList *pOrderBy,    /* The ORDER BY clause */
  Select *pSelect        /* The whole SELECT statement */
){
  Vdbe *v = pParse->pVdbe;
  sqlite3ExprCodeExprList(pParse, pOrderBy);
  sqlite3VdbeAddOp(v, OP_Sequence, pOrderBy->iECursor, 0);
  sqlite3VdbeAddOp(v, OP_Pull, pOrderBy->nExpr + 1, 0);

  sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr + 2, 0);
  sqlite3VdbeAddOp(v, OP_IdxInsert, pOrderBy->iECursor, 0);
  if( pSelect->iLimit>=0 ){
    int addr1, addr2;
    addr1 = sqlite3VdbeAddOp(v, OP_IfMemZero, pSelect->iLimit+1, 0);
    sqlite3VdbeAddOp(v, OP_MemIncr, -1, pSelect->iLimit+1);
    addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp(v, OP_Last, pOrderBy->iECursor, 0);
    sqlite3VdbeAddOp(v, OP_Delete, pOrderBy->iECursor, 0);
    sqlite3VdbeJumpHere(v, addr2);
    pSelect->iLimit = -1;
  }
}

/*
** Add code to implement the OFFSET
*/
static void codeOffset(
  Vdbe *v,          /* Generate code into this VM */
  Select *p,        /* The SELECT statement being coded */
  int iContinue,    /* Jump here to skip the current record */

  int nPop          /* Number of times to pop stack when jumping */
){
  if( p->iOffset>=0 && iContinue!=0 ){
    int addr;

    sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iOffset);
    addr = sqlite3VdbeAddOp(v, OP_IfMemNeg, p->iOffset, 0);
    if( nPop>0 ){
      sqlite3VdbeAddOp(v, OP_Pop, nPop, 0);
    }
    sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
    VdbeComment((v, "# skip OFFSET records"));
    sqlite3VdbeJumpHere(v, addr);
  }
}

/*
** Add code that will check to make sure the top N elements of the
** stack are distinct.  iTab is a sorting index that holds previously
** seen combinations of the N values.  A new entry is made in iTab
** if the current N values are new.
**
** A jump to addrRepeat is made and the K values are popped from the
** stack if the top N elements are not distinct.
*/
static void codeDistinct(
  Vdbe *v,           /* Generate code into this VM */
  int iTab,          /* A sorting index used to test for distinctness */
  int addrRepeat,    /* Jump to here if not distinct */
  int N,             /* The top N elements of the stack must be distinct */
  int K              /* Pop K elements from the stack if indistinct */
){
#if NULL_ALWAYS_DISTINCT
  sqlite3VdbeAddOp(v, OP_IsNull, -N, sqlite3VdbeCurrentAddr(v)+6);
#endif
  sqlite3VdbeAddOp(v, OP_MakeRecord, -N, 0);
  sqlite3VdbeAddOp(v, OP_Distinct, iTab, sqlite3VdbeCurrentAddr(v)+3);
  sqlite3VdbeAddOp(v, OP_Pop, K, 0);
  sqlite3VdbeAddOp(v, OP_Goto, 0, addrRepeat);
  VdbeComment((v, "# skip indistinct records"));
  sqlite3VdbeAddOp(v, OP_IdxInsert, iTab, 0);
}


/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
**
** If srcTab and nColumn are both zero, then the pEList expressions
** are evaluated in order to get the data for this row.  If nColumn>0







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

|

|



>


|
|
>
|
|





<

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







316
317
318
319
320
321
322
323
324
325



326


327
328







329



330
331

332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351

352

353





















354

355

356
357
358
359
360
361
362
363
364
  sqliteFree(p);
}

/*
** Insert code into "v" that will push the record on the top of the
** stack into the sorter.
*/
static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
  int i;
  for(i=0; i<pOrderBy->nExpr; i++){



    sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr);


  }
  sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0);







  sqlite3VdbeAddOp(v, OP_SortPut, 0, 0);



}


/*
** Add code to implement the OFFSET and LIMIT
*/
static void codeLimiter(
  Vdbe *v,          /* Generate code into this VM */
  Select *p,        /* The SELECT statement being coded */
  int iContinue,    /* Jump here to skip the current record */
  int iBreak,       /* Jump here to end the loop */
  int nPop          /* Number of times to pop stack when jumping */
){
  if( p->iOffset>=0 ){
    int addr = sqlite3VdbeCurrentAddr(v) + 3;
    if( nPop>0 ) addr++;
    sqlite3VdbeAddOp(v, OP_MemIncr, p->iOffset, 0);
    sqlite3VdbeAddOp(v, OP_IfMemPos, p->iOffset, addr);
    if( nPop>0 ){
      sqlite3VdbeAddOp(v, OP_Pop, nPop, 0);
    }
    sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
    VdbeComment((v, "# skip OFFSET records"));

  }

  if( p->iLimit>=0 ){





















    sqlite3VdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);

    VdbeComment((v, "# exit when LIMIT reached"));

  }
}

/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
**
** If srcTab and nColumn are both zero, then the pEList expressions
** are evaluated in order to get the data for this row.  If nColumn>0
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473

474

475
476
477
478
479
480
481







482
483



484
485
486
487
488
489

490
491
492
493
494
495
496
497
498
499

500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594










595

596

597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684


685



686













687
688


689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

708
709

710
711
712
713
714
715
716
717
718
719
720
  assert( pEList!=0 );

  /* If there was a LIMIT clause on the SELECT statement, then do the check
  ** to see if this row should be output.
  */
  hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
  if( pOrderBy==0 && !hasDistinct ){
    codeOffset(v, p, iContinue, 0);
  }

  /* Pull the requested columns.
  */
  if( nColumn>0 ){
    for(i=0; i<nColumn; i++){
      sqlite3VdbeAddOp(v, OP_Column, srcTab, i);
    }
  }else{
    nColumn = pEList->nExpr;

    sqlite3ExprCodeExprList(pParse, pEList);

  }

  /* If the DISTINCT keyword was present on the SELECT statement
  ** and this row has been seen before, then do not make this row
  ** part of the result.
  */
  if( hasDistinct ){







    int n = pEList->nExpr;
    codeDistinct(v, distinct, iContinue, n, n+1);



    if( pOrderBy==0 ){
      codeOffset(v, p, iContinue, nColumn);
    }
  }

  switch( eDest ){

    /* In this mode, write each query result to the key of the temporary
    ** table iParm.
    */
#ifndef SQLITE_OMIT_COMPOUND_SELECT
    case SRT_Union: {
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
      if( aff ){
        sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
      }
      sqlite3VdbeAddOp(v, OP_IdxInsert, iParm, 0);

      break;
    }

    /* Construct a record from the query result, but instead of
    ** saving that record, use it as a key to delete elements from
    ** the temporary table iParm.
    */
    case SRT_Except: {
      int addr;
      addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
      sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
      sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3);
      sqlite3VdbeAddOp(v, OP_Delete, iParm, 0);
      break;
    }
#endif

    /* Store the result as data using a unique key.
    */
    case SRT_Table:
    case SRT_VirtualTab: {
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
      if( pOrderBy ){
        pushOntoSorter(pParse, pOrderBy, p);
      }else{
        sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
        sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
        sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
      }
      break;
    }

#ifndef SQLITE_OMIT_SUBQUERY
    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
    ** then there should be a single item on the stack.  Write this
    ** item into the set table with bogus data.
    */
    case SRT_Set: {
      int addr1 = sqlite3VdbeCurrentAddr(v);
      int addr2;

      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_NotNull, -1, addr1+3);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
      if( pOrderBy ){
        /* At first glance you would think we could optimize out the
        ** ORDER BY in this case since the order of entries in the set
        ** does not matter.  But there might be a LIMIT clause, in which
        ** case the order does matter */
        pushOntoSorter(pParse, pOrderBy, p);
      }else{
        char aff = (iParm>>16)&0xFF;
        aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
        sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1);
        sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
      }
      sqlite3VdbeJumpHere(v, addr2);
      break;
    }

    /* If any row exists in the result set, record that fact and abort.
    */
    case SRT_Exists: {
      sqlite3VdbeAddOp(v, OP_MemInt, 1, iParm);
      sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
      /* The LIMIT clause will terminate the loop for us */
      break;
    }

    /* If this is a scalar select that is part of an expression, then
    ** store the results in the appropriate memory cell and break out
    ** of the scan loop.
    */

    case SRT_Mem: {
      assert( nColumn==1 );
      if( pOrderBy ){
        pushOntoSorter(pParse, pOrderBy, p);
      }else{
        sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
        /* The LIMIT clause will jump out of the loop for us */
      }
      break;
    }
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */

    /* Send the data to the callback function or to a subroutine.  In the
    ** case of a subroutine, the subroutine itself is responsible for
    ** popping the data from the stack.
    */
    case SRT_Subroutine:
    case SRT_Callback: {
      if( pOrderBy ){
        sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
        pushOntoSorter(pParse, pOrderBy, p);










      }else if( eDest==SRT_Subroutine ){

        sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);

      }else{
        sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
      }
      break;
    }

#if !defined(SQLITE_OMIT_TRIGGER)
    /* Discard the results.  This is used for SELECT statements inside
    ** the body of a TRIGGER.  The purpose of such selects is to call
    ** user-defined functions that have side effects.  We do not care
    ** about the actual results of the select.
    */
    default: {
      assert( eDest==SRT_Discard );
      sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
      break;
    }
#endif
  }

  /* Jump to the end of the loop if the LIMIT is reached.
  */
  if( p->iLimit>=0 && pOrderBy==0 ){
    sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iLimit);
    sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, iBreak);
  }
  return 0;
}

/*
** Given an expression list, generate a KeyInfo structure that records
** the collating sequence for each expression in that expression list.
**
** If the ExprList is an ORDER BY or GROUP BY clause then the resulting
** KeyInfo structure is appropriate for initializing a virtual index to
** implement that clause.  If the ExprList is the result set of a SELECT
** then the KeyInfo structure is appropriate for initializing a virtual
** index to implement a DISTINCT test.
**
** Space to hold the KeyInfo structure is obtain from malloc.  The calling
** function is responsible for seeing that this structure is eventually
** freed.  Add the KeyInfo structure to the P3 field of an opcode using
** P3_KEYINFO_HANDOFF is the usual way of dealing with this.
*/
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
  sqlite3 *db = pParse->db;
  int nExpr;
  KeyInfo *pInfo;
  struct ExprList_item *pItem;
  int i;

  nExpr = pList->nExpr;
  pInfo = sqliteMalloc( sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
  if( pInfo ){
    pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
    pInfo->nField = nExpr;
    pInfo->enc = ENC(db);
    for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
      CollSeq *pColl;
      pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
      if( !pColl ){
        pColl = db->pDfltColl;
      }
      pInfo->aColl[i] = pColl;
      pInfo->aSortOrder[i] = pItem->sortOrder;
    }
  }
  return pInfo;
}


/*
** If the inner loop was generated using a non-null pOrderBy argument,
** then the results were placed in a sorter.  After the loop is terminated
** we need to run the sorter and output the results.  The following
** routine generates the code needed to do that.
*/
static void generateSortTail(
  Parse *pParse,   /* The parsing context */
  Select *p,       /* The SELECT statement */
  Vdbe *v,         /* Generate code into this VDBE */
  int nColumn,     /* Number of columns of data */
  int eDest,       /* Write the sorted results here */
  int iParm        /* Optional parameter associated with eDest */
){
  int brk = sqlite3VdbeMakeLabel(v);
  int cont = sqlite3VdbeMakeLabel(v);
  int addr;


  int iTab;



  ExprList *pOrderBy = p->pOrderBy;














  iTab = pOrderBy->iECursor;


  addr = 1 + sqlite3VdbeAddOp(v, OP_Sort, iTab, brk);
  codeOffset(v, p, cont, 0);
  sqlite3VdbeAddOp(v, OP_Column, iTab, pOrderBy->nExpr + 1);
  switch( eDest ){
    case SRT_Table:
    case SRT_VirtualTab: {
      sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case SRT_Set: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "c", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);

      break;
    }

    case SRT_Mem: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
      /* The LIMIT clause will terminate the loop for us */
      break;
    }
#endif
    case SRT_Callback:
    case SRT_Subroutine: {
      int i;
      sqlite3VdbeAddOp(v, OP_Integer, p->pEList->nExpr, 0);







|










>
|
>







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

|




>



<


<
|
<
|
>




















|


|

|

|


















<
<
<
<
|




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







>



|


|





|
<
<

|
|


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

|

















<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<















|
|

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


|
|

|








|
|
>


>



|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436

437
438

439

440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487




488
489
490
491
492
493

494

495
496






497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517


518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556







557
558










































559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602

603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
  assert( pEList!=0 );

  /* If there was a LIMIT clause on the SELECT statement, then do the check
  ** to see if this row should be output.
  */
  hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
  if( pOrderBy==0 && !hasDistinct ){
    codeLimiter(v, p, iContinue, iBreak, 0);
  }

  /* Pull the requested columns.
  */
  if( nColumn>0 ){
    for(i=0; i<nColumn; i++){
      sqlite3VdbeAddOp(v, OP_Column, srcTab, i);
    }
  }else{
    nColumn = pEList->nExpr;
    for(i=0; i<pEList->nExpr; i++){
      sqlite3ExprCode(pParse, pEList->a[i].pExpr);
    }
  }

  /* If the DISTINCT keyword was present on the SELECT statement
  ** and this row has been seen before, then do not make this row
  ** part of the result.
  */
  if( hasDistinct ){
#if NULL_ALWAYS_DISTINCT
    sqlite3VdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqlite3VdbeCurrentAddr(v)+7);
#endif
    /* Deliberately leave the affinity string off of the following
    ** OP_MakeRecord */
    sqlite3VdbeAddOp(v, OP_MakeRecord, pEList->nExpr * -1, 0);
    sqlite3VdbeAddOp(v, OP_Distinct, distinct, sqlite3VdbeCurrentAddr(v)+3);
    sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
    sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
    VdbeComment((v, "# skip indistinct records"));
    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
    sqlite3VdbeAddOp(v, OP_PutStrKey, distinct, 0);
    if( pOrderBy==0 ){
      codeLimiter(v, p, iContinue, iBreak, nColumn);
    }
  }

  switch( eDest ){
#ifndef SQLITE_OMIT_COMPOUND_SELECT
    /* In this mode, write each query result to the key of the temporary
    ** table iParm.
    */

    case SRT_Union: {
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);

      sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);

      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_PutStrKey, iParm, 0);
      break;
    }

    /* Construct a record from the query result, but instead of
    ** saving that record, use it as a key to delete elements from
    ** the temporary table iParm.
    */
    case SRT_Except: {
      int addr;
      addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
      sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
      sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3);
      sqlite3VdbeAddOp(v, OP_Delete, iParm, 0);
      break;
    }
#endif

    /* Store the result as data using a unique key.
    */
    case SRT_Table:
    case SRT_TempTable: {
      sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
      if( pOrderBy ){
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        sqlite3VdbeAddOp(v, OP_NewRecno, iParm, 0);
        sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
        sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0);
      }
      break;
    }

#ifndef SQLITE_OMIT_SUBQUERY
    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
    ** then there should be a single item on the stack.  Write this
    ** item into the set table with bogus data.
    */
    case SRT_Set: {
      int addr1 = sqlite3VdbeCurrentAddr(v);
      int addr2;

      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_NotNull, -1, addr1+3);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
      if( pOrderBy ){




        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        char aff = (iParm>>16)&0xFF;
        aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
        sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1);
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);

        sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);

      }
      sqlite3VdbeChangeP2(v, addr2, sqlite3VdbeCurrentAddr(v));






      break;
    }

    /* If this is a scalar select that is part of an expression, then
    ** store the results in the appropriate memory cell and break out
    ** of the scan loop.
    */
    case SRT_Exists:
    case SRT_Mem: {
      assert( nColumn==1 );
      if( pOrderBy ){
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
        sqlite3VdbeAddOp(v, OP_Goto, 0, iBreak);
      }
      break;
    }
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */

    /* Send the data to the callback function.


    */
    case SRT_Callback:
    case SRT_Sorter: {
      if( pOrderBy ){
        sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        assert( eDest==SRT_Callback );
        sqlite3VdbeAddOp(v, OP_Callback, nColumn, 0);
      }
      break;
    }

    /* Invoke a subroutine to handle the results.  The subroutine itself
    ** is responsible for popping the results off of the stack.
    */
    case SRT_Subroutine: {
      if( pOrderBy ){
        sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
        pushOntoSorter(pParse, v, pOrderBy);
      }else{
        sqlite3VdbeAddOp(v, OP_Gosub, 0, iParm);
      }
      break;
    }

#if !defined(SQLITE_OMIT_TRIGGER)
    /* Discard the results.  This is used for SELECT statements inside
    ** the body of a TRIGGER.  The purpose of such selects is to call
    ** user-defined functions that have side effects.  We do not care
    ** about the actual results of the select.
    */
    default: {
      assert( eDest==SRT_Discard );
      sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
      break;
    }
#endif
  }







  return 0;
}











































/*
** If the inner loop was generated using a non-null pOrderBy argument,
** then the results were placed in a sorter.  After the loop is terminated
** we need to run the sorter and output the results.  The following
** routine generates the code needed to do that.
*/
static void generateSortTail(
  Parse *pParse,   /* The parsing context */
  Select *p,       /* The SELECT statement */
  Vdbe *v,         /* Generate code into this VDBE */
  int nColumn,     /* Number of columns of data */
  int eDest,       /* Write the sorted results here */
  int iParm        /* Optional parameter associated with eDest */
){
  int end1 = sqlite3VdbeMakeLabel(v);
  int end2 = sqlite3VdbeMakeLabel(v);
  int addr;
  KeyInfo *pInfo;
  ExprList *pOrderBy;
  int nCol, i;
  sqlite3 *db = pParse->db;

  if( eDest==SRT_Sorter ) return;
  pOrderBy = p->pOrderBy;
  nCol = pOrderBy->nExpr;
  pInfo = sqliteMalloc( sizeof(*pInfo) + nCol*(sizeof(CollSeq*)+1) );
  if( pInfo==0 ) return;
  pInfo->aSortOrder = (char*)&pInfo->aColl[nCol];
  pInfo->nField = nCol;
  for(i=0; i<nCol; i++){
    /* If a collation sequence was specified explicity, then it
    ** is stored in pOrderBy->a[i].zName. Otherwise, use the default
    ** collation type for the expression.
    */
    pInfo->aColl[i] = sqlite3ExprCollSeq(pParse, pOrderBy->a[i].pExpr);
    if( !pInfo->aColl[i] ){
      pInfo->aColl[i] = db->pDfltColl;
    }
    pInfo->aSortOrder[i] = pOrderBy->a[i].sortOrder;
  }
  sqlite3VdbeOp3(v, OP_Sort, 0, 0, (char*)pInfo, P3_KEYINFO_HANDOFF);
  addr = sqlite3VdbeAddOp(v, OP_SortNext, 0, end1);
  codeLimiter(v, p, addr, end2, 1);

  switch( eDest ){
    case SRT_Table:
    case SRT_TempTable: {
      sqlite3VdbeAddOp(v, OP_NewRecno, iParm, 0);
      sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0);
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case SRT_Set: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
      sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
      break;
    }
    case SRT_Exists:
    case SRT_Mem: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
      sqlite3VdbeAddOp(v, OP_Goto, 0, end1);
      break;
    }
#endif
    case SRT_Callback:
    case SRT_Subroutine: {
      int i;
      sqlite3VdbeAddOp(v, OP_Integer, p->pEList->nExpr, 0);
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750

751
752
753
754
755
756
757
      break;
    }
    default: {
      /* Do nothing */
      break;
    }
  }

  /* Jump to the end of the loop when the LIMIT is reached
  */
  if( p->iLimit>=0 ){
    sqlite3VdbeAddOp(v, OP_MemIncr, -1, p->iLimit);
    sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, brk);
  }

  /* The bottom of the loop
  */
  sqlite3VdbeResolveLabel(v, cont);
  sqlite3VdbeAddOp(v, OP_Next, iTab, addr);
  sqlite3VdbeResolveLabel(v, brk);

}

/*
** Return a pointer to a string containing the 'declaration type' of the
** expression pExpr. The string may be treated as static by the caller.
**
** If the declaration type is the exact datatype definition extracted from







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







644
645
646
647
648
649
650




651





652
653
654
655
656
657
658
659
660
661
662
      break;
    }
    default: {
      /* Do nothing */
      break;
    }
  }




  sqlite3VdbeAddOp(v, OP_Goto, 0, addr);





  sqlite3VdbeResolveLabel(v, end2);
  sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
  sqlite3VdbeResolveLabel(v, end1);
  sqlite3VdbeAddOp(v, OP_SortReset, 0, 0);
}

/*
** Return a pointer to a string containing the 'declaration type' of the
** expression pExpr. The string may be treated as static by the caller.
**
** If the declaration type is the exact datatype definition extracted from
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
        for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
        if( j<pTabList->nSrc ){
          pTab = pTabList->a[j].pTab;
        }else{
          pNC = pNC->pNext;
        }
      }
      if( pTab==0 ){
        /* FIX ME:
        ** This can occurs if you have something like "SELECT new.x;" inside
        ** a trigger.  In other words, if you reference the special "new"
        ** table in the result set of a select.  We do not have a good way
        ** to find the actual table type, so call it "TEXT".  This is really
        ** something of a bug, but I do not know how to fix it.
        **
        ** This code does not produce the correct answer - it just prevents
        ** a segfault.  See ticket #1229.
        */
        zType = "TEXT";
        break;
      }
      assert( pTab );
      if( iCol<0 ) iCol = pTab->iPKey;
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zType = "INTEGER";
      }else{
        zType = pTab->aCol[iCol].zType;







<
<
<
<
<
<
<
<
<
<
<
<
<
<







685
686
687
688
689
690
691














692
693
694
695
696
697
698
        for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
        if( j<pTabList->nSrc ){
          pTab = pTabList->a[j].pTab;
        }else{
          pNC = pNC->pNext;
        }
      }














      assert( pTab );
      if( iCol<0 ) iCol = pTab->iPKey;
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zType = "INTEGER";
      }else{
        zType = pTab->aCol[iCol].zType;
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
  /* If this is an EXPLAIN, skip this step */
  if( pParse->explain ){
    return;
  }
#endif

  assert( v!=0 );
  if( pParse->colNamesSet || v==0
     || sqlite3ThreadDataReadOnly()->mallocFailed ) return;
  pParse->colNamesSet = 1;
  fullNames = (db->flags & SQLITE_FullColNames)!=0;
  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
  sqlite3VdbeSetNumCols(v, pEList->nExpr);
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    p = pEList->a[i].pExpr;







|
<







759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
  /* If this is an EXPLAIN, skip this step */
  if( pParse->explain ){
    return;
  }
#endif

  assert( v!=0 );
  if( pParse->colNamesSet || v==0 || sqlite3_malloc_failed ) return;

  pParse->colNamesSet = 1;
  fullNames = (db->flags & SQLITE_FullColNames)!=0;
  shortNames = (db->flags & SQLITE_ShortColNames)!=0;
  sqlite3VdbeSetNumCols(v, pEList->nExpr);
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    p = pEList->a[i].pExpr;
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zCol = "rowid";
      }else{
        zCol = pTab->aCol[iCol].zName;
      }
      if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
        sqlite3VdbeSetColName(v, i, (char*)p->span.z, p->span.n);
      }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
        char *zName = 0;
        char *zTab;
 
        zTab = pTabList->a[j].zAlias;
        if( fullNames || zTab==0 ) zTab = pTab->zName;
        sqlite3SetString(&zName, zTab, ".", zCol, (char*)0);
        sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
      }else{
        sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
      }
    }else if( p->span.z && p->span.z[0] ){
      sqlite3VdbeSetColName(v, i, (char*)p->span.z, p->span.n);
      /* sqlite3VdbeCompressSpace(v, addr); */
    }else{
      char zName[30];
      assert( p->op!=TK_COLUMN || pTabList==0 );
      sprintf(zName, "column%d", i+1);
      sqlite3VdbeSetColName(v, i, zName, 0);
    }







|






|





|







788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
      assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
      if( iCol<0 ){
        zCol = "rowid";
      }else{
        zCol = pTab->aCol[iCol].zName;
      }
      if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
        sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
      }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
        char *zName = 0;
        char *zTab;
 
        zTab = pTabList->a[j].zAlias;
        if( fullNames || zTab==0 ) zTab = pTab->zName;
        sqlite3SetString(&zName, zTab, ".", zCol, 0);
        sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC);
      }else{
        sqlite3VdbeSetColName(v, i, zCol, strlen(zCol));
      }
    }else if( p->span.z && p->span.z[0] ){
      sqlite3VdbeSetColName(v, i, p->span.z, p->span.n);
      /* sqlite3VdbeCompressSpace(v, addr); */
    }else{
      char zName[30];
      assert( p->op!=TK_COLUMN || pTabList==0 );
      sprintf(zName, "column%d", i+1);
      sqlite3VdbeSetColName(v, i, zName, 0);
    }
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
  if( sqlite3SelectResolve(pParse, pSelect, 0) ){
    return 0;
  }
  pTab = sqliteMalloc( sizeof(Table) );
  if( pTab==0 ){
    return 0;
  }
  pTab->nRef = 1;
  pTab->zName = zTabName ? sqliteStrDup(zTabName) : 0;
  pEList = pSelect->pEList;
  pTab->nCol = pEList->nExpr;
  assert( pTab->nCol>0 );
  pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
  for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
    Expr *p, *pR;
    char *zType;
    char *zName;
    char *zBasename;
    CollSeq *pColl;
    int cnt;
    NameContext sNC;
    
    /* Get an appropriate name for the column
    */
    p = pEList->a[i].pExpr;
    assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );







<










<







854
855
856
857
858
859
860

861
862
863
864
865
866
867
868
869
870

871
872
873
874
875
876
877
  if( sqlite3SelectResolve(pParse, pSelect, 0) ){
    return 0;
  }
  pTab = sqliteMalloc( sizeof(Table) );
  if( pTab==0 ){
    return 0;
  }

  pTab->zName = zTabName ? sqliteStrDup(zTabName) : 0;
  pEList = pSelect->pEList;
  pTab->nCol = pEList->nExpr;
  assert( pTab->nCol>0 );
  pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
  for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
    Expr *p, *pR;
    char *zType;
    char *zName;
    char *zBasename;

    int cnt;
    NameContext sNC;
    
    /* Get an appropriate name for the column
    */
    p = pEList->a[i].pExpr;
    assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
      /* Use the original text of the column expression as its name */
      zName = sqlite3MPrintf("%T", &p->span);
    }else{
      /* If all else fails, make up a name */
      zName = sqlite3MPrintf("column%d", i+1);
    }
    sqlite3Dequote(zName);
    if( sqlite3ThreadDataReadOnly()->mallocFailed ){
      sqliteFree(zName);
      sqlite3DeleteTable(0, pTab);
      return 0;
    }

    /* Make sure the column name is unique.  If the name is not unique,
    ** append a integer to the name so that it becomes unique.
    */
    zBasename = zName;
    for(j=cnt=0; j<i; j++){
      if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
        zName = sqlite3MPrintf("%s:%d", zBasename, ++cnt);
        j = -1;
        if( zName==0 ) break;
      }
    }
    if( zBasename!=zName ){
      sqliteFree(zBasename);
    }
    pCol->zName = zName;

    /* Get the typename, type affinity, and collating sequence for the
    ** column.
    */
    memset(&sNC, 0, sizeof(sNC));
    sNC.pSrcList = pSelect->pSrc;
    zType = sqliteStrDup(columnType(&sNC, p));
    pCol->zType = zType;
    pCol->affinity = sqlite3ExprAffinity(p);
    pColl = sqlite3ExprCollSeq(pParse, p);
    if( pColl ){
      pCol->zColl = sqliteStrDup(pColl->zName);
    }
  }
  pTab->iPKey = -1;
  return pTab;
}

/*







<
<
<
<
<









<










<




|
|
|







886
887
888
889
890
891
892





893
894
895
896
897
898
899
900
901

902
903
904
905
906
907
908
909
910
911

912
913
914
915
916
917
918
919
920
921
922
923
924
925
      /* Use the original text of the column expression as its name */
      zName = sqlite3MPrintf("%T", &p->span);
    }else{
      /* If all else fails, make up a name */
      zName = sqlite3MPrintf("column%d", i+1);
    }
    sqlite3Dequote(zName);






    /* Make sure the column name is unique.  If the name is not unique,
    ** append a integer to the name so that it becomes unique.
    */
    zBasename = zName;
    for(j=cnt=0; j<i; j++){
      if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
        zName = sqlite3MPrintf("%s:%d", zBasename, ++cnt);
        j = -1;

      }
    }
    if( zBasename!=zName ){
      sqliteFree(zBasename);
    }
    pCol->zName = zName;

    /* Get the typename, type affinity, and collating sequence for the
    ** column.
    */

    sNC.pSrcList = pSelect->pSrc;
    zType = sqliteStrDup(columnType(&sNC, p));
    pCol->zType = zType;
    pCol->affinity = sqlite3ExprAffinity(p);
    pCol->pColl = sqlite3ExprCollSeq(pParse, p);
    if( !pCol->pColl ){
      pCol->pColl = pParse->db->pDfltColl;
    }
  }
  pTab->iPKey = -1;
  return pTab;
}

/*
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
static int prepSelectStmt(Parse *pParse, Select *p){
  int i, j, k, rc;
  SrcList *pTabList;
  ExprList *pEList;
  Table *pTab;
  struct SrcList_item *pFrom;

  if( p==0 || p->pSrc==0 || sqlite3ThreadDataReadOnly()->mallocFailed ){
    return 1;
  }
  pTabList = p->pSrc;
  pEList = p->pEList;

  /* Make sure cursor numbers have been assigned to all entries in
  ** the FROM clause of the SELECT statement.
  */
  sqlite3SrcListAssignCursors(pParse, p->pSrc);







|
<
<







951
952
953
954
955
956
957
958


959
960
961
962
963
964
965
static int prepSelectStmt(Parse *pParse, Select *p){
  int i, j, k, rc;
  SrcList *pTabList;
  ExprList *pEList;
  Table *pTab;
  struct SrcList_item *pFrom;

  if( p==0 || p->pSrc==0 ) return 1;


  pTabList = p->pSrc;
  pEList = p->pEList;

  /* Make sure cursor numbers have been assigned to all entries in
  ** the FROM clause of the SELECT statement.
  */
  sqlite3SrcListAssignCursors(pParse, p->pSrc);
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
#ifndef SQLITE_OMIT_SUBQUERY
      /* A sub-query in the FROM clause of a SELECT */
      assert( pFrom->pSelect!=0 );
      if( pFrom->zAlias==0 ){
        pFrom->zAlias =
          sqlite3MPrintf("sqlite_subquery_%p_", (void*)pFrom->pSelect);
      }
      assert( pFrom->pTab==0 );
      pFrom->pTab = pTab = 
        sqlite3ResultSetOfSelect(pParse, pFrom->zAlias, pFrom->pSelect);
      if( pTab==0 ){
        return 1;
      }
      /* The isTransient flag indicates that the Table structure has been
      ** dynamically allocated and may be freed at any time.  In other words,
      ** pTab is not pointing to a persistent table structure that defines
      ** part of the schema. */
      pTab->isTransient = 1;
#endif
    }else{
      /* An ordinary table or view name in the FROM clause */
      assert( pFrom->pTab==0 );
      pFrom->pTab = pTab = 
        sqlite3LocateTable(pParse,pFrom->zName,pFrom->zDatabase);
      if( pTab==0 ){
        return 1;
      }
      pTab->nRef++;
#ifndef SQLITE_OMIT_VIEW
      if( pTab->pSelect ){
        /* We reach here if the named table is a really a view */
        if( sqlite3ViewGetColumnNames(pParse, pTab) ){
          return 1;
        }
        /* If pFrom->pSelect!=0 it means we are dealing with a







<













<





<







979
980
981
982
983
984
985

986
987
988
989
990
991
992
993
994
995
996
997
998

999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
#ifndef SQLITE_OMIT_SUBQUERY
      /* A sub-query in the FROM clause of a SELECT */
      assert( pFrom->pSelect!=0 );
      if( pFrom->zAlias==0 ){
        pFrom->zAlias =
          sqlite3MPrintf("sqlite_subquery_%p_", (void*)pFrom->pSelect);
      }

      pFrom->pTab = pTab = 
        sqlite3ResultSetOfSelect(pParse, pFrom->zAlias, pFrom->pSelect);
      if( pTab==0 ){
        return 1;
      }
      /* The isTransient flag indicates that the Table structure has been
      ** dynamically allocated and may be freed at any time.  In other words,
      ** pTab is not pointing to a persistent table structure that defines
      ** part of the schema. */
      pTab->isTransient = 1;
#endif
    }else{
      /* An ordinary table or view name in the FROM clause */

      pFrom->pTab = pTab = 
        sqlite3LocateTable(pParse,pFrom->zName,pFrom->zDatabase);
      if( pTab==0 ){
        return 1;
      }

#ifndef SQLITE_OMIT_VIEW
      if( pTab->pSelect ){
        /* We reach here if the named table is a really a view */
        if( sqlite3ViewGetColumnNames(pParse, pTab) ){
          return 1;
        }
        /* If pFrom->pSelect!=0 it means we are dealing with a
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
    /*
    ** If we get here it means the result set contains one or more "*"
    ** operators that need to be expanded.  Loop through each expression
    ** in the result set and expand them one by one.
    */
    struct ExprList_item *a = pEList->a;
    ExprList *pNew = 0;
    int flags = pParse->db->flags;
    int longNames = (flags & SQLITE_FullColNames)!=0 &&
                      (flags & SQLITE_ShortColNames)==0;

    for(k=0; k<pEList->nExpr; k++){
      Expr *pE = a[k].pExpr;
      if( pE->op!=TK_ALL &&
           (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
        /* This particular expression does not need to be expanded.
        */
        pNew = sqlite3ExprListAppend(pNew, a[k].pExpr, 0);
        if( pNew ){
          pNew->a[pNew->nExpr-1].zName = a[k].zName;
        }else{
          rc = 1;
        }
        a[k].pExpr = 0;
        a[k].zName = 0;
      }else{
        /* This expression is a "*" or a "TABLE.*" and needs to be
        ** expanded. */
        int tableSeen = 0;      /* Set to 1 when TABLE matches */
        char *zTName;            /* text of name of TABLE */







<
<
<
<







<
|
<
<
<







1045
1046
1047
1048
1049
1050
1051




1052
1053
1054
1055
1056
1057
1058

1059



1060
1061
1062
1063
1064
1065
1066
    /*
    ** If we get here it means the result set contains one or more "*"
    ** operators that need to be expanded.  Loop through each expression
    ** in the result set and expand them one by one.
    */
    struct ExprList_item *a = pEList->a;
    ExprList *pNew = 0;




    for(k=0; k<pEList->nExpr; k++){
      Expr *pE = a[k].pExpr;
      if( pE->op!=TK_ALL &&
           (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
        /* This particular expression does not need to be expanded.
        */
        pNew = sqlite3ExprListAppend(pNew, a[k].pExpr, 0);

        pNew->a[pNew->nExpr-1].zName = a[k].zName;



        a[k].pExpr = 0;
        a[k].zName = 0;
      }else{
        /* This expression is a "*" or a "TABLE.*" and needs to be
        ** expanded. */
        int tableSeen = 0;      /* Set to 1 when TABLE matches */
        char *zTName;            /* text of name of TABLE */
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273


































1274
1275
1276
1277
1278
1279
1280
                ** using clause from the table on the right. */
                continue;
              }
            }
            pRight = sqlite3Expr(TK_ID, 0, 0, 0);
            if( pRight==0 ) break;
            setToken(&pRight->token, zName);
            if( zTabName && (longNames || pTabList->nSrc>1) ){
              pLeft = sqlite3Expr(TK_ID, 0, 0, 0);
              pExpr = sqlite3Expr(TK_DOT, pLeft, pRight, 0);
              if( pExpr==0 ) break;
              setToken(&pLeft->token, zTabName);
              setToken(&pExpr->span, sqlite3MPrintf("%s.%s", zTabName, zName));
              pExpr->span.dyn = 1;
              pExpr->token.z = 0;
              pExpr->token.n = 0;
              pExpr->token.dyn = 0;
            }else{
              pExpr = pRight;
              pExpr->span = pExpr->token;
            }
            if( longNames ){
              pNew = sqlite3ExprListAppend(pNew, pExpr, &pExpr->span);
            }else{
              pNew = sqlite3ExprListAppend(pNew, pExpr, &pRight->token);
            }
          }
        }
        if( !tableSeen ){
          if( zTName ){
            sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
          }else{
            sqlite3ErrorMsg(pParse, "no tables specified");
          }
          rc = 1;
        }
        sqliteFree(zTName);
      }
    }
    sqlite3ExprListDelete(pEList);
    p->pEList = pNew;
  }
  return rc;
}



































#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** This routine associates entries in an ORDER BY expression list with
** columns in a result.  For each ORDER BY expression, the opcode of
** the top-level node is changed to TK_COLUMN and the iColumn value of
** the top-level node is filled in with column number and the iTable
** value of the top-level node is filled with iTable parameter.







|













<
<
<
|
<



















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







1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117



1118

1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
                ** using clause from the table on the right. */
                continue;
              }
            }
            pRight = sqlite3Expr(TK_ID, 0, 0, 0);
            if( pRight==0 ) break;
            setToken(&pRight->token, zName);
            if( zTabName && pTabList->nSrc>1 ){
              pLeft = sqlite3Expr(TK_ID, 0, 0, 0);
              pExpr = sqlite3Expr(TK_DOT, pLeft, pRight, 0);
              if( pExpr==0 ) break;
              setToken(&pLeft->token, zTabName);
              setToken(&pExpr->span, sqlite3MPrintf("%s.%s", zTabName, zName));
              pExpr->span.dyn = 1;
              pExpr->token.z = 0;
              pExpr->token.n = 0;
              pExpr->token.dyn = 0;
            }else{
              pExpr = pRight;
              pExpr->span = pExpr->token;
            }



            pNew = sqlite3ExprListAppend(pNew, pExpr, &pRight->token);

          }
        }
        if( !tableSeen ){
          if( zTName ){
            sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
          }else{
            sqlite3ErrorMsg(pParse, "no tables specified");
          }
          rc = 1;
        }
        sqliteFree(zTName);
      }
    }
    sqlite3ExprListDelete(pEList);
    p->pEList = pNew;
  }
  return rc;
}

/*
** This routine recursively unlinks the Select.pSrc.a[].pTab pointers
** in a select structure.  It just sets the pointers to NULL.  This
** routine is recursive in the sense that if the Select.pSrc.a[].pSelect
** pointer is not NULL, this routine is called recursively on that pointer.
**
** This routine is called on the Select structure that defines a
** VIEW in order to undo any bindings to tables.  This is necessary
** because those tables might be DROPed by a subsequent SQL command.
** If the bindings are not removed, then the Select.pSrc->a[].pTab field
** will be left pointing to a deallocated Table structure after the
** DROP and a coredump will occur the next time the VIEW is used.
*/
#if 0
void sqlite3SelectUnbind(Select *p){
  int i;
  SrcList *pSrc = p->pSrc;
  struct SrcList_item *pItem;
  Table *pTab;
  if( p==0 ) return;
  for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
    if( (pTab = pItem->pTab)!=0 ){
      if( pTab->isTransient ){
        sqlite3DeleteTable(0, pTab);
      }
      pItem->pTab = 0;
      if( pItem->pSelect ){
        sqlite3SelectUnbind(pItem->pSelect);
      }
    }
  }
}
#endif

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** This routine associates entries in an ORDER BY expression list with
** columns in a result.  For each ORDER BY expression, the opcode of
** the top-level node is changed to TK_COLUMN and the iColumn value of
** the top-level node is filled in with column number and the iTable
** value of the top-level node is filled with iTable parameter.
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409

1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438

1439
1440
1441
1442








1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462




1463

1464














1465






1466



1467






1468

1469

1470
1471
1472
1473
1474
1475
1476
  Vdbe *v = pParse->pVdbe;
  if( v==0 ){
    v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
  }
  return v;
}


/*
** Compute the iLimit and iOffset fields of the SELECT based on the
** pLimit and pOffset expressions.  pLimit and pOffset hold the expressions
** that appear in the original SQL statement after the LIMIT and OFFSET
** keywords.  Or NULL if those keywords are omitted. iLimit and iOffset 
** are the integer memory register numbers for counters used to compute 
** the limit and offset.  If there is no limit and/or offset, then 
** iLimit and iOffset are negative.
**
** This routine changes the values of iLimit and iOffset only if
** a limit or offset is defined by pLimit and pOffset.  iLimit and
** iOffset should have been preset to appropriate default values
** (usually but not always -1) prior to calling this routine.
** Only if pLimit!=0 or pOffset!=0 do the limit registers get
** redefined.  The UNION ALL operator uses this property to force
** the reuse of the same limit and offset registers across multiple
** SELECT statements.
*/
static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
  Vdbe *v;
  int iLimit;
  int iOffset;
  int addr1, addr2;

  /* 
  ** "LIMIT -1" always shows all rows.  There is some
  ** contraversy about what the correct behavior should be.
  ** The current implementation interprets "LIMIT 0" to mean
  ** no rows.
  */
  if( p->pLimit ){
    p->iLimit = iLimit = pParse->nMem;
    pParse->nMem += 2;
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3ExprCode(pParse, p->pLimit);
    sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);

    sqlite3VdbeAddOp(v, OP_MemStore, iLimit, 0);
    VdbeComment((v, "# LIMIT counter"));
    sqlite3VdbeAddOp(v, OP_IfMemZero, iLimit, iBreak);
  }
  if( p->pOffset ){
    p->iOffset = iOffset = pParse->nMem++;
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3ExprCode(pParse, p->pOffset);
    sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iOffset, p->pLimit==0);
    VdbeComment((v, "# OFFSET counter"));
    addr1 = sqlite3VdbeAddOp(v, OP_IfMemPos, iOffset, 0);
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
    sqlite3VdbeJumpHere(v, addr1);
    if( p->pLimit ){
      sqlite3VdbeAddOp(v, OP_Add, 0, 0);
    }
  }
  if( p->pLimit ){
    addr1 = sqlite3VdbeAddOp(v, OP_IfMemPos, iLimit, 0);
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp(v, OP_MemInt, -1, iLimit+1);
    addr2 = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp(v, OP_MemStore, iLimit+1, 1);
    VdbeComment((v, "# LIMIT+OFFSET"));
    sqlite3VdbeJumpHere(v, addr2);

  }
}

/*








** Allocate a virtual index to use for sorting.
*/
static void createSortingIndex(Parse *pParse, Select *p, ExprList *pOrderBy){
  if( pOrderBy ){
    int addr;
    assert( pOrderBy->iECursor==0 );
    pOrderBy->iECursor = pParse->nTab++;
    addr = sqlite3VdbeAddOp(pParse->pVdbe, OP_OpenVirtual,
                            pOrderBy->iECursor, pOrderBy->nExpr+1);
    assert( p->addrOpenVirt[2] == -1 );
    p->addrOpenVirt[2] = addr;
  }
}

/*
** The opcode at addr is an OP_OpenVirtual that created a sorting
** index tha we ended up not needing.  This routine changes that
** opcode to OP_Noop.
*/
static void uncreateSortingIndex(Parse *pParse, int addr){




  Vdbe *v = pParse->pVdbe;

  VdbeOp *pOp = sqlite3VdbeGetOp(v, addr);














  sqlite3VdbeChangeP3(v, addr, 0, 0);






  pOp->opcode = OP_Noop;



  pOp->p1 = 0;






  pOp->p2 = 0;

}


#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** Return the appropriate collating sequence for the iCol-th column of
** the result set for the compound-select statement "p".  Return NULL if
** the column has no default collating sequence.
**







<


|






|
|


|




|
<
<
<
<
<







<
|
|



>
|

|


|
|



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




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

|
>
>
>
>

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

>







1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288





1289
1290
1291
1292
1293
1294
1295

1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311



1312












1313
1314

1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329











1330
1331
1332


1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
  Vdbe *v = pParse->pVdbe;
  if( v==0 ){
    v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
  }
  return v;
}


/*
** Compute the iLimit and iOffset fields of the SELECT based on the
** pLimit and pOffset expressions.  nLimit and nOffset hold the expressions
** that appear in the original SQL statement after the LIMIT and OFFSET
** keywords.  Or NULL if those keywords are omitted. iLimit and iOffset 
** are the integer memory register numbers for counters used to compute 
** the limit and offset.  If there is no limit and/or offset, then 
** iLimit and iOffset are negative.
**
** This routine changes the values if iLimit and iOffset only if
** a limit or offset is defined by nLimit and nOffset.  iLimit and
** iOffset should have been preset to appropriate default values
** (usually but not always -1) prior to calling this routine.
** Only if nLimit>=0 or nOffset>0 do the limit registers get
** redefined.  The UNION ALL operator uses this property to force
** the reuse of the same limit and offset registers across multiple
** SELECT statements.
*/
static void computeLimitRegisters(Parse *pParse, Select *p){





  /* 
  ** "LIMIT -1" always shows all rows.  There is some
  ** contraversy about what the correct behavior should be.
  ** The current implementation interprets "LIMIT 0" to mean
  ** no rows.
  */
  if( p->pLimit ){

    int iMem = pParse->nMem++;
    Vdbe *v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3ExprCode(pParse, p->pLimit);
    sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
    VdbeComment((v, "# LIMIT counter"));
    p->iLimit = iMem;
  }
  if( p->pOffset ){
    int iMem = pParse->nMem++;
    Vdbe *v = sqlite3GetVdbe(pParse);
    if( v==0 ) return;
    sqlite3ExprCode(pParse, p->pOffset);
    sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);



    sqlite3VdbeAddOp(v, OP_Negative, 0, 0);












    sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1);
    VdbeComment((v, "# OFFSET counter"));

    p->iOffset = iMem;
  }
}

/*
** Generate VDBE instructions that will open a transient table that
** will be used for an index or to store keyed results for a compound
** select.  In other words, open a transient table that needs a
** KeyInfo structure.  The number of columns in the KeyInfo is determined
** by the result set of the SELECT statement in the second argument.
**
** Specifically, this routine is called to open an index table for
** DISTINCT, UNION, INTERSECT and EXCEPT select statements (but not 
** UNION ALL).
**











** Make the new table a KeyAsData table if keyAsData is true.
**
** The value returned is the address of the OP_OpenTemp instruction.


*/
static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){
  KeyInfo *pKeyInfo;
  int nColumn;
  sqlite3 *db = pParse->db;
  int i;
  Vdbe *v = pParse->pVdbe;
  int addr;

  if( prepSelectStmt(pParse, p) ){
    return 0;
  }
  nColumn = p->pEList->nExpr;
  pKeyInfo = sqliteMalloc( sizeof(*pKeyInfo)+nColumn*sizeof(CollSeq*) );
  if( pKeyInfo==0 ) return 0;
  pKeyInfo->enc = db->enc;
  pKeyInfo->nField = nColumn;
  for(i=0; i<nColumn; i++){
    pKeyInfo->aColl[i] = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr);
    if( !pKeyInfo->aColl[i] ){
      pKeyInfo->aColl[i] = db->pDfltColl;
    }
  }
  addr = sqlite3VdbeOp3(v, OP_OpenTemp, iTab, 0, 
      (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
  if( keyAsData ){
    sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1);
  }
  return addr;
}

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** Add the address "addr" to the set of all OpenTemp opcode addresses
** that are being accumulated in p->ppOpenTemp.
*/
static int multiSelectOpenTempAddr(Select *p, int addr){
  IdList *pList = *p->ppOpenTemp = sqlite3IdListAppend(*p->ppOpenTemp, 0);
  if( pList==0 ){
    return SQLITE_NOMEM;
  }
  pList->a[pList->nId-1].idx = addr;
  return SQLITE_OK;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** Return the appropriate collating sequence for the iCol-th column of
** the result set for the compound-select statement "p".  Return NULL if
** the column has no default collating sequence.
**
1528
1529
1530
1531
1532
1533
1534



1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569











1570
1571
1572
1573
1574

1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620

1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633

1634
1635
1636
1637
1638
1639
1640
1641

1642
1643

1644
1645
1646

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

1667
1668
1669
1670
1671
1672
1673
1674
1675
  int eDest,            /* \___  Store query results as specified */
  int iParm,            /* /     by these two parameters.         */
  char *aff             /* If eDest is SRT_Union, the affinity string */
){
  int rc = SQLITE_OK;   /* Success code from a subroutine */
  Select *pPrior;       /* Another SELECT immediately to our left */
  Vdbe *v;              /* Generate code to this VDBE */



  int nCol;             /* Number of columns in the result set */
  ExprList *pOrderBy;   /* The ORDER BY clause on p */
  int aSetP2[2];        /* Set P2 value of these op to number of columns */
  int nSetP2 = 0;       /* Number of slots in aSetP2[] used */

  /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
  ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
  */
  if( p==0 || p->pPrior==0 ){
    rc = 1;
    goto multi_select_end;
  }
  pPrior = p->pPrior;
  assert( pPrior->pRightmost!=pPrior );
  assert( pPrior->pRightmost==p->pRightmost );
  if( pPrior->pOrderBy ){
    sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
      selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }
  if( pPrior->pLimit ){
    sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
      selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }

  /* Make sure we have a valid query engine.  If not, create a new one.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    rc = 1;
    goto multi_select_end;
  }












  /* Create the destination temporary table if necessary
  */
  if( eDest==SRT_VirtualTab ){
    assert( p->pEList );

    assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
    aSetP2[nSetP2++] = sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, 0);
    eDest = SRT_Table;
  }

  /* Generate code for the left and right SELECT statements.
  */
  pOrderBy = p->pOrderBy;
  switch( p->op ){
    case TK_ALL: {
      if( pOrderBy==0 ){
        int addr = 0;
        assert( !pPrior->pLimit );
        pPrior->pLimit = p->pLimit;
        pPrior->pOffset = p->pOffset;
        rc = sqlite3Select(pParse, pPrior, eDest, iParm, 0, 0, 0, aff);
        p->pLimit = 0;
        p->pOffset = 0;
        if( rc ){
          goto multi_select_end;
        }
        p->pPrior = 0;
        p->iLimit = pPrior->iLimit;
        p->iOffset = pPrior->iOffset;
        if( p->iLimit>=0 ){
          addr = sqlite3VdbeAddOp(v, OP_IfMemZero, p->iLimit, 0);
          VdbeComment((v, "# Jump ahead if LIMIT reached"));
        }
        rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff);
        p->pPrior = pPrior;
        if( rc ){
          goto multi_select_end;
        }
        if( addr ){
          sqlite3VdbeJumpHere(v, addr);
        }
        break;
      }
      /* For UNION ALL ... ORDER BY fall through to the next case */
    }
    case TK_EXCEPT:
    case TK_UNION: {
      int unionTab;    /* Cursor number of the temporary table holding result */
      int op = 0;      /* One of the SRT_ operations to apply to self */
      int priorOp;     /* The SRT_ operation to apply to prior selects */
      Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */

      int addr;

      priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union;
      if( eDest==priorOp && pOrderBy==0 && !p->pLimit && !p->pOffset ){
        /* We can reuse a temporary table generated by a SELECT to our
        ** right.
        */
        unionTab = iParm;
      }else{
        /* We will need to create our own temporary table to hold the
        ** intermediate results.
        */
        unionTab = pParse->nTab++;

        if( pOrderBy && matchOrderbyToColumn(pParse, p, pOrderBy, unionTab,1) ){
          rc = 1;
          goto multi_select_end;
        }
        addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, unionTab, 0);
        if( priorOp==SRT_Table ){
          assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
          aSetP2[nSetP2++] = addr;

        }else{
          assert( p->addrOpenVirt[0] == -1 );

          p->addrOpenVirt[0] = addr;
          p->pRightmost->usesVirt = 1;
        }

        createSortingIndex(pParse, p, pOrderBy);
        assert( p->pEList );
      }

      /* Code the SELECT statements to our left
      */
      assert( !pPrior->pOrderBy );
      rc = sqlite3Select(pParse, pPrior, priorOp, unionTab, 0, 0, 0, aff);
      if( rc ){
        goto multi_select_end;
      }

      /* Code the current SELECT statement
      */
      switch( p->op ){
         case TK_EXCEPT:  op = SRT_Except;   break;
         case TK_UNION:   op = SRT_Union;    break;
         case TK_ALL:     op = SRT_Table;    break;
      }
      p->pPrior = 0;

      p->pOrderBy = 0;
      p->disallowOrderBy = pOrderBy!=0;
      pLimit = p->pLimit;
      p->pLimit = 0;
      pOffset = p->pOffset;
      p->pOffset = 0;
      rc = sqlite3Select(pParse, p, op, unionTab, 0, 0, 0, aff);
      p->pPrior = pPrior;
      p->pOrderBy = pOrderBy;







>
>
>

<
<
<









<
<




















>
>
>
>
>
>
>
>
>
>
>



|

>
|
|





<


|
<




<
<






|
|
<
<





<
<
<










>



|









>
|



|
|
<
|
>
|
<
>
|
<

>
|



















>

<







1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446



1447
1448
1449
1450
1451
1452
1453
1454
1455


1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499

1500
1501
1502

1503
1504
1505
1506


1507
1508
1509
1510
1511
1512
1513
1514


1515
1516
1517
1518
1519



1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550

1551
1552
1553

1554
1555

1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579

1580
1581
1582
1583
1584
1585
1586
  int eDest,            /* \___  Store query results as specified */
  int iParm,            /* /     by these two parameters.         */
  char *aff             /* If eDest is SRT_Union, the affinity string */
){
  int rc = SQLITE_OK;   /* Success code from a subroutine */
  Select *pPrior;       /* Another SELECT immediately to our left */
  Vdbe *v;              /* Generate code to this VDBE */
  IdList *pOpenTemp = 0;/* OP_OpenTemp opcodes that need a KeyInfo */
  int aAddr[5];         /* Addresses of SetNumColumns operators */
  int nAddr = 0;        /* Number used */
  int nCol;             /* Number of columns in the result set */




  /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
  ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
  */
  if( p==0 || p->pPrior==0 ){
    rc = 1;
    goto multi_select_end;
  }
  pPrior = p->pPrior;


  if( pPrior->pOrderBy ){
    sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
      selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }
  if( pPrior->pLimit ){
    sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
      selectOpName(p->op));
    rc = 1;
    goto multi_select_end;
  }

  /* Make sure we have a valid query engine.  If not, create a new one.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ){
    rc = 1;
    goto multi_select_end;
  }

  /* If *p this is the right-most select statement, then initialize
  ** p->ppOpenTemp to point to pOpenTemp.  If *p is not the right most
  ** statement then p->ppOpenTemp will have already been initialized
  ** by a prior call to this same procedure.  Pass along the pOpenTemp
  ** pointer to pPrior, the next statement to our left.
  */
  if( p->ppOpenTemp==0 ){
    p->ppOpenTemp = &pOpenTemp;
  }
  pPrior->ppOpenTemp = p->ppOpenTemp;

  /* Create the destination temporary table if necessary
  */
  if( eDest==SRT_TempTable ){
    assert( p->pEList );
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);
    assert( nAddr==0 );
    aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, 0);
    eDest = SRT_Table;
  }

  /* Generate code for the left and right SELECT statements.
  */

  switch( p->op ){
    case TK_ALL: {
      if( p->pOrderBy==0 ){

        assert( !pPrior->pLimit );
        pPrior->pLimit = p->pLimit;
        pPrior->pOffset = p->pOffset;
        rc = sqlite3Select(pParse, pPrior, eDest, iParm, 0, 0, 0, aff);


        if( rc ){
          goto multi_select_end;
        }
        p->pPrior = 0;
        p->iLimit = pPrior->iLimit;
        p->iOffset = pPrior->iOffset;
        p->pLimit = 0;
        p->pOffset = 0;


        rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff);
        p->pPrior = pPrior;
        if( rc ){
          goto multi_select_end;
        }



        break;
      }
      /* For UNION ALL ... ORDER BY fall through to the next case */
    }
    case TK_EXCEPT:
    case TK_UNION: {
      int unionTab;    /* Cursor number of the temporary table holding result */
      int op = 0;      /* One of the SRT_ operations to apply to self */
      int priorOp;     /* The SRT_ operation to apply to prior selects */
      Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
      ExprList *pOrderBy;     /* The ORDER BY clause for the right SELECT */
      int addr;

      priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union;
      if( eDest==priorOp && p->pOrderBy==0 && !p->pLimit && !p->pOffset ){
        /* We can reuse a temporary table generated by a SELECT to our
        ** right.
        */
        unionTab = iParm;
      }else{
        /* We will need to create our own temporary table to hold the
        ** intermediate results.
        */
        unionTab = pParse->nTab++;
        if( p->pOrderBy 
        && matchOrderbyToColumn(pParse, p, p->pOrderBy, unionTab, 1) ){
          rc = 1;
          goto multi_select_end;
        }
        addr = sqlite3VdbeAddOp(v, OP_OpenTemp, unionTab, 0);
        if( p->op!=TK_ALL ){

          rc = multiSelectOpenTempAddr(p, addr);
          if( rc!=SQLITE_OK ){
            goto multi_select_end;

          }
          sqlite3VdbeAddOp(v, OP_KeyAsData, unionTab, 1);

        }
	assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
        aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, unionTab, 0);
        assert( p->pEList );
      }

      /* Code the SELECT statements to our left
      */
      assert( !pPrior->pOrderBy );
      rc = sqlite3Select(pParse, pPrior, priorOp, unionTab, 0, 0, 0, aff);
      if( rc ){
        goto multi_select_end;
      }

      /* Code the current SELECT statement
      */
      switch( p->op ){
         case TK_EXCEPT:  op = SRT_Except;   break;
         case TK_UNION:   op = SRT_Union;    break;
         case TK_ALL:     op = SRT_Table;    break;
      }
      p->pPrior = 0;
      pOrderBy = p->pOrderBy;
      p->pOrderBy = 0;

      pLimit = p->pLimit;
      p->pLimit = 0;
      pOffset = p->pOffset;
      p->pOffset = 0;
      rc = sqlite3Select(pParse, p, op, unionTab, 0, 0, 0, aff);
      p->pPrior = pPrior;
      p->pOrderBy = pOrderBy;
1690
1691
1692
1693
1694
1695
1696
1697
1698

1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
        int iCont, iBreak, iStart;
        assert( p->pEList );
        if( eDest==SRT_Callback ){
          generateColumnNames(pParse, 0, p->pEList);
        }
        iBreak = sqlite3VdbeMakeLabel(v);
        iCont = sqlite3VdbeMakeLabel(v);
        computeLimitRegisters(pParse, p, iBreak);
        sqlite3VdbeAddOp(v, OP_Rewind, unionTab, iBreak);

        iStart = sqlite3VdbeCurrentAddr(v);
        rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
                             pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak, 0);
        if( rc ){
          rc = 1;
          goto multi_select_end;
        }
        sqlite3VdbeResolveLabel(v, iCont);
        sqlite3VdbeAddOp(v, OP_Next, unionTab, iStart);







<

>


|







1601
1602
1603
1604
1605
1606
1607

1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
        int iCont, iBreak, iStart;
        assert( p->pEList );
        if( eDest==SRT_Callback ){
          generateColumnNames(pParse, 0, p->pEList);
        }
        iBreak = sqlite3VdbeMakeLabel(v);
        iCont = sqlite3VdbeMakeLabel(v);

        sqlite3VdbeAddOp(v, OP_Rewind, unionTab, iBreak);
        computeLimitRegisters(pParse, p);
        iStart = sqlite3VdbeCurrentAddr(v);
        rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak, 0);
        if( rc ){
          rc = 1;
          goto multi_select_end;
        }
        sqlite3VdbeResolveLabel(v, iCont);
        sqlite3VdbeAddOp(v, OP_Next, unionTab, iStart);
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733

1734
1735




1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747





1748
1749

1750
1751
1752
1753
1754
1755
1756

      /* INTERSECT is different from the others since it requires
      ** two temporary tables.  Hence it has its own case.  Begin
      ** by allocating the tables we will need.
      */
      tab1 = pParse->nTab++;
      tab2 = pParse->nTab++;
      if( pOrderBy && matchOrderbyToColumn(pParse,p,pOrderBy,tab1,1) ){
        rc = 1;
        goto multi_select_end;
      }
      createSortingIndex(pParse, p, pOrderBy);

      addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, tab1, 0);
      assert( p->addrOpenVirt[0] == -1 );

      p->addrOpenVirt[0] = addr;
      p->pRightmost->usesVirt = 1;




      assert( p->pEList );

      /* Code the SELECTs to our left into temporary table "tab1".
      */
      rc = sqlite3Select(pParse, pPrior, SRT_Union, tab1, 0, 0, 0, aff);
      if( rc ){
        goto multi_select_end;
      }

      /* Code the current SELECT into temporary table "tab2"
      */
      addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, tab2, 0);





      assert( p->addrOpenVirt[1] == -1 );
      p->addrOpenVirt[1] = addr;

      p->pPrior = 0;
      pLimit = p->pLimit;
      p->pLimit = 0;
      pOffset = p->pOffset;
      p->pOffset = 0;
      rc = sqlite3Select(pParse, p, SRT_Union, tab2, 0, 0, 0, aff);
      p->pPrior = pPrior;







|



<

|
|
>
|
<
>
>
>
>











|
>
>
>
>
>
|
<
>







1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640

1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667

1668
1669
1670
1671
1672
1673
1674
1675

      /* INTERSECT is different from the others since it requires
      ** two temporary tables.  Hence it has its own case.  Begin
      ** by allocating the tables we will need.
      */
      tab1 = pParse->nTab++;
      tab2 = pParse->nTab++;
      if( p->pOrderBy && matchOrderbyToColumn(pParse,p,p->pOrderBy,tab1,1) ){
        rc = 1;
        goto multi_select_end;
      }


      addr = sqlite3VdbeAddOp(v, OP_OpenTemp, tab1, 0);
      rc = multiSelectOpenTempAddr(p, addr);
      if( rc!=SQLITE_OK ){
        goto multi_select_end;

      }
      sqlite3VdbeAddOp(v, OP_KeyAsData, tab1, 1);
      assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
      aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab1, 0);
      assert( p->pEList );

      /* Code the SELECTs to our left into temporary table "tab1".
      */
      rc = sqlite3Select(pParse, pPrior, SRT_Union, tab1, 0, 0, 0, aff);
      if( rc ){
        goto multi_select_end;
      }

      /* Code the current SELECT into temporary table "tab2"
      */
      addr = sqlite3VdbeAddOp(v, OP_OpenTemp, tab2, 0);
      rc = multiSelectOpenTempAddr(p, addr);
      if( rc!=SQLITE_OK ){
        goto multi_select_end;
      }
      sqlite3VdbeAddOp(v, OP_KeyAsData, tab2, 1);
      assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );

      aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab2, 0);
      p->pPrior = 0;
      pLimit = p->pLimit;
      p->pLimit = 0;
      pOffset = p->pOffset;
      p->pOffset = 0;
      rc = sqlite3Select(pParse, p, SRT_Union, tab2, 0, 0, 0, aff);
      p->pPrior = pPrior;
1766
1767
1768
1769
1770
1771
1772
1773
1774

1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
      */
      assert( p->pEList );
      if( eDest==SRT_Callback ){
        generateColumnNames(pParse, 0, p->pEList);
      }
      iBreak = sqlite3VdbeMakeLabel(v);
      iCont = sqlite3VdbeMakeLabel(v);
      computeLimitRegisters(pParse, p, iBreak);
      sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak);

      iStart = sqlite3VdbeAddOp(v, OP_RowKey, tab1, 0);
      sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont);
      rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
                             pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak, 0);
      if( rc ){
        rc = 1;
        goto multi_select_end;
      }
      sqlite3VdbeResolveLabel(v, iCont);
      sqlite3VdbeAddOp(v, OP_Next, tab1, iStart);







<

>
|


|







1685
1686
1687
1688
1689
1690
1691

1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
      */
      assert( p->pEList );
      if( eDest==SRT_Callback ){
        generateColumnNames(pParse, 0, p->pEList);
      }
      iBreak = sqlite3VdbeMakeLabel(v);
      iCont = sqlite3VdbeMakeLabel(v);

      sqlite3VdbeAddOp(v, OP_Rewind, tab1, iBreak);
      computeLimitRegisters(pParse, p);
      iStart = sqlite3VdbeAddOp(v, OP_FullKey, tab1, 0);
      sqlite3VdbeAddOp(v, OP_NotFound, tab2, iCont);
      rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak, 0);
      if( rc ){
        rc = 1;
        goto multi_select_end;
      }
      sqlite3VdbeResolveLabel(v, iCont);
      sqlite3VdbeAddOp(v, OP_Next, tab1, iStart);
1800
1801
1802
1803
1804
1805
1806
1807

1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872

1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889


1890

1891
1892
1893




1894
1895
1896
1897
1898
1899
1900
    rc = 1;
    goto multi_select_end;
  }

  /* Set the number of columns in temporary tables
  */
  nCol = p->pEList->nExpr;
  while( nSetP2 ){

    sqlite3VdbeChangeP2(v, aSetP2[--nSetP2], nCol);
  }

  /* Compute collating sequences used by either the ORDER BY clause or
  ** by any temporary tables needed to implement the compound select.
  ** Attach the KeyInfo structure to all temporary tables.  Invoke the
  ** ORDER BY processing if there is an ORDER BY clause.
  **
  ** This section is run by the right-most SELECT statement only.
  ** SELECT statements to the left always skip this part.  The right-most
  ** SELECT might also skip this part if it has no ORDER BY clause and
  ** no temp tables are required.
  */
  if( pOrderBy || p->usesVirt ){
    int i;                        /* Loop counter */
    KeyInfo *pKeyInfo;            /* Collating sequence for the result set */
    Select *pLoop;                /* For looping through SELECT statements */
    CollSeq **apColl;
    CollSeq **aCopy;

    assert( p->pRightmost==p );
    pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nCol*2*sizeof(CollSeq*) + nCol);
    if( !pKeyInfo ){
      rc = SQLITE_NOMEM;
      goto multi_select_end;
    }

    pKeyInfo->enc = ENC(pParse->db);
    pKeyInfo->nField = nCol;

    for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
      *apColl = multiSelectCollSeq(pParse, p, i);
      if( 0==*apColl ){
        *apColl = pParse->db->pDfltColl;
      }
    }

    for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
      for(i=0; i<2; i++){
        int addr = pLoop->addrOpenVirt[i];
        if( addr<0 ){
          /* If [0] is unused then [1] is also unused.  So we can
          ** always safely abort as soon as the first unused slot is found */
          assert( pLoop->addrOpenVirt[1]<0 );
          break;
        }
        sqlite3VdbeChangeP2(v, addr, nCol);
        sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO);
      }
    }

    if( pOrderBy ){
      struct ExprList_item *pOTerm = pOrderBy->a;
      int nOrderByExpr = pOrderBy->nExpr;
      int addr;
      u8 *pSortOrder;

      aCopy = (CollSeq**)&pKeyInfo[1];
      pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nCol];
      memcpy(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*));
      apColl = pKeyInfo->aColl;
      for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){
        Expr *pExpr = pOTerm->pExpr;
        char *zName = pOTerm->zName;
        assert( pExpr->op==TK_COLUMN && pExpr->iColumn<nCol );

        if( zName ){
          *apColl = sqlite3LocateCollSeq(pParse, zName, -1);
        }else{
          *apColl = aCopy[pExpr->iColumn];
        }
        *pSortOrder = pOTerm->sortOrder;
      }
      assert( p->pRightmost==p );
      assert( p->addrOpenVirt[2]>=0 );
      addr = p->addrOpenVirt[2];
      sqlite3VdbeChangeP2(v, addr, p->pEList->nExpr+2);
      pKeyInfo->nField = nOrderByExpr;
      sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
      pKeyInfo = 0;
      generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm);
    }



    sqliteFree(pKeyInfo);

  }

multi_select_end:




  return rc;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

#ifndef SQLITE_OMIT_VIEW
/*
** Scan through the expression pExpr.  Replace every reference to







|
>
|












|


<
<
<

|
|





|


|
|
|
|



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

>

|

|

<

<
<
<
<
<
<
<



>
>
|
>



>
>
>
>







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



1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761

1762











1763



1764
1765
1766
1767
1768

1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779

1780







1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
    rc = 1;
    goto multi_select_end;
  }

  /* Set the number of columns in temporary tables
  */
  nCol = p->pEList->nExpr;
  while( nAddr>0 ){
    nAddr--;
    sqlite3VdbeChangeP2(v, aAddr[nAddr], nCol);
  }

  /* Compute collating sequences used by either the ORDER BY clause or
  ** by any temporary tables needed to implement the compound select.
  ** Attach the KeyInfo structure to all temporary tables.  Invoke the
  ** ORDER BY processing if there is an ORDER BY clause.
  **
  ** This section is run by the right-most SELECT statement only.
  ** SELECT statements to the left always skip this part.  The right-most
  ** SELECT might also skip this part if it has no ORDER BY clause and
  ** no temp tables are required.
  */
  if( p->pOrderBy || (pOpenTemp && pOpenTemp->nId>0) ){
    int i;                        /* Loop counter */
    KeyInfo *pKeyInfo;            /* Collating sequence for the result set */




    assert( p->ppOpenTemp == &pOpenTemp );
    pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nCol*sizeof(CollSeq*));
    if( !pKeyInfo ){
      rc = SQLITE_NOMEM;
      goto multi_select_end;
    }

    pKeyInfo->enc = pParse->db->enc;
    pKeyInfo->nField = nCol;

    for(i=0; i<nCol; i++){
      pKeyInfo->aColl[i] = multiSelectCollSeq(pParse, p, i);
      if( !pKeyInfo->aColl[i] ){
        pKeyInfo->aColl[i] = pParse->db->pDfltColl;
      }
    }


    for(i=0; pOpenTemp && i<pOpenTemp->nId; i++){











      int p3type = (i==0?P3_KEYINFO_HANDOFF:P3_KEYINFO);



      int addr = pOpenTemp->a[i].idx;
      sqlite3VdbeChangeP3(v, addr, (char *)pKeyInfo, p3type);
    }

    if( p->pOrderBy ){

      struct ExprList_item *pOrderByTerm = p->pOrderBy->a;
      for(i=0; i<p->pOrderBy->nExpr; i++, pOrderByTerm++){
        Expr *pExpr = pOrderByTerm->pExpr;
        char *zName = pOrderByTerm->zName;
        assert( pExpr->op==TK_COLUMN && pExpr->iColumn<nCol );
        /* assert( !pExpr->pColl ); */
        if( zName ){
          pExpr->pColl = sqlite3LocateCollSeq(pParse, zName, -1);
        }else{
          pExpr->pColl = pKeyInfo->aColl[pExpr->iColumn];
        }

      }







      generateSortTail(pParse, p, v, p->pEList->nExpr, eDest, iParm);
    }

    if( !pOpenTemp ){
      /* This happens for UNION ALL ... ORDER BY */
      sqliteFree(pKeyInfo);
    }
  }

multi_select_end:
  if( pOpenTemp ){
    sqlite3IdListDelete(pOpenTemp);
  }
  p->ppOpenTemp = 0;
  return rc;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

#ifndef SQLITE_OMIT_VIEW
/*
** Scan through the expression pExpr.  Replace every reference to
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
  if( (pSub->pLimit && p->pLimit) || pSub->pOffset || 
      (pSub->pLimit && isAgg) ) return 0;
  if( pSubSrc->nSrc==0 ) return 0;
  if( pSub->isDistinct && (pSrc->nSrc>1 || isAgg) ){
     return 0;
  }
  if( p->isDistinct && subqueryIsAgg ) return 0;
  if( (p->disallowOrderBy || p->pOrderBy) && pSub->pOrderBy ) return 0;

  /* Restriction 3:  If the subquery is a join, make sure the subquery is 
  ** not used as the right operand of an outer join.  Examples of why this
  ** is not allowed:
  **
  **         t1 LEFT OUTER JOIN (t2 JOIN t3)
  **







|







1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
  if( (pSub->pLimit && p->pLimit) || pSub->pOffset || 
      (pSub->pLimit && isAgg) ) return 0;
  if( pSubSrc->nSrc==0 ) return 0;
  if( pSub->isDistinct && (pSrc->nSrc>1 || isAgg) ){
     return 0;
  }
  if( p->isDistinct && subqueryIsAgg ) return 0;
  if( p->pOrderBy && pSub->pOrderBy ) return 0;

  /* Restriction 3:  If the subquery is a join, make sure the subquery is 
  ** not used as the right operand of an outer join.  Examples of why this
  ** is not allowed:
  **
  **         t1 LEFT OUTER JOIN (t2 JOIN t3)
  **
2114
2115
2116
2117
2118
2119
2120

2121

2122

2123
2124
2125
2126
2127
2128
2129
  ** those references with expressions that resolve to the subquery FROM
  ** elements we are now copying in.
  */
  iParent = pSubitem->iCursor;
  {
    int nSubSrc = pSubSrc->nSrc;
    int jointype = pSubitem->jointype;



    sqlite3DeleteTable(0, pSubitem->pTab);

    sqliteFree(pSubitem->zDatabase);
    sqliteFree(pSubitem->zName);
    sqliteFree(pSubitem->zAlias);
    if( nSubSrc>1 ){
      int extra = nSubSrc - 1;
      for(i=1; i<nSubSrc; i++){
        pSrc = sqlite3SrcListAppend(pSrc, 0, 0);







>

>
|
>







2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
  ** those references with expressions that resolve to the subquery FROM
  ** elements we are now copying in.
  */
  iParent = pSubitem->iCursor;
  {
    int nSubSrc = pSubSrc->nSrc;
    int jointype = pSubitem->jointype;
    Table *pTab = pSubitem->pTab;

    if( pTab && pTab->isTransient ){
      sqlite3DeleteTable(0, pSubitem->pTab);
    }
    sqliteFree(pSubitem->zDatabase);
    sqliteFree(pSubitem->zName);
    sqliteFree(pSubitem->zAlias);
    if( nSubSrc>1 ){
      int extra = nSubSrc - 1;
      for(i=1; i<nSubSrc; i++){
        pSrc = sqlite3SrcListAppend(pSrc, 0, 0);
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
  ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
  */
  substExprList(p->pEList, iParent, pSub->pEList);
  pList = p->pEList;
  for(i=0; i<pList->nExpr; i++){
    Expr *pExpr;
    if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
      pList->a[i].zName = sqliteStrNDup((char*)pExpr->span.z, pExpr->span.n);
    }
  }
  if( isAgg ){
    substExprList(p->pGroupBy, iParent, pSub->pEList);
    substExpr(p->pHaving, iParent, pSub->pEList);
  }
  if( pSub->pOrderBy ){







|







2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
  ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
  */
  substExprList(p->pEList, iParent, pSub->pEList);
  pList = p->pEList;
  for(i=0; i<pList->nExpr; i++){
    Expr *pExpr;
    if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
      pList->a[i].zName = sqliteStrNDup(pExpr->span.z, pExpr->span.n);
    }
  }
  if( isAgg ){
    substExprList(p->pGroupBy, iParent, pSub->pEList);
    substExpr(p->pHaving, iParent, pSub->pEList);
  }
  if( pSub->pOrderBy ){
2234
2235
2236
2237
2238
2239
2240

2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303

2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320

2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
  Expr *pExpr;
  int iCol;
  Table *pTab;
  Index *pIdx;
  int base;
  Vdbe *v;
  int seekOp;

  ExprList *pEList, *pList, eList;
  struct ExprList_item eListItem;
  SrcList *pSrc;
  int brk;
  int iDb;

  /* Check to see if this query is a simple min() or max() query.  Return
  ** zero if it is  not.
  */
  if( p->pGroupBy || p->pHaving || p->pWhere ) return 0;
  pSrc = p->pSrc;
  if( pSrc->nSrc!=1 ) return 0;
  pEList = p->pEList;
  if( pEList->nExpr!=1 ) return 0;
  pExpr = pEList->a[0].pExpr;
  if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
  pList = pExpr->pList;
  if( pList==0 || pList->nExpr!=1 ) return 0;
  if( pExpr->token.n!=3 ) return 0;
  if( sqlite3StrNICmp((char*)pExpr->token.z,"min",3)==0 ){
    seekOp = OP_Rewind;
  }else if( sqlite3StrNICmp((char*)pExpr->token.z,"max",3)==0 ){
    seekOp = OP_Last;
  }else{
    return 0;
  }
  pExpr = pList->a[0].pExpr;
  if( pExpr->op!=TK_COLUMN ) return 0;
  iCol = pExpr->iColumn;
  pTab = pSrc->a[0].pTab;


  /* If we get to here, it means the query is of the correct form.
  ** Check to make sure we have an index and make pIdx point to the
  ** appropriate index.  If the min() or max() is on an INTEGER PRIMARY
  ** key column, no index is necessary so set pIdx to NULL.  If no
  ** usable index is found, return 0.
  */
  if( iCol<0 ){
    pIdx = 0;
  }else{
    CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      assert( pIdx->nColumn>=1 );
      if( pIdx->aiColumn[0]==iCol && 
          0==sqlite3StrICmp(pIdx->azColl[0], pColl->zName) ){
        break;
      }
    }
    if( pIdx==0 ) return 0;
  }

  /* Identify column types if we will be using the callback.  This
  ** step is skipped if the output is going to a table or a memory cell.
  ** The column names have already been generated in the calling function.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return 0;

  /* If the output is destined for a temporary table, open that table.
  */
  if( eDest==SRT_VirtualTab ){
    sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, 1);

  }

  /* Generating code to find the min or the max.  Basically all we have
  ** to do is find the first or the last entry in the chosen index.  If
  ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
  ** or last entry in the main table.
  */
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  assert( iDb>=0 || pTab->isTransient );
  sqlite3CodeVerifySchema(pParse, iDb);
  sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
  base = pSrc->a[0].iCursor;
  brk = sqlite3VdbeMakeLabel(v);
  computeLimitRegisters(pParse, p, brk);
  if( pSrc->a[0].pSelect==0 ){
    sqlite3OpenTable(pParse, base, iDb, pTab, OP_OpenRead);
  }

  if( pIdx==0 ){
    sqlite3VdbeAddOp(v, seekOp, base, 0);
  }else{
    /* Even though the cursor used to open the index here is closed
    ** as soon as a single value has been read from it, allocate it
    ** using (pParse->nTab++) to prevent the cursor id from being 
    ** reused. This is important for statements of the form 
    ** "INSERT INTO x SELECT max() FROM x".
    */
    int iIdx;
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
    iIdx = pParse->nTab++;
    assert( pIdx->pSchema==pTab->pSchema );
    sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum, 
        (char*)pKey, P3_KEYINFO_HANDOFF);
    if( seekOp==OP_Rewind ){
      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
      sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0);
      seekOp = OP_MoveGt;
    }
    sqlite3VdbeAddOp(v, seekOp, iIdx, 0);
    sqlite3VdbeAddOp(v, OP_IdxRowid, iIdx, 0);
    sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
    sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
  }
  eList.nExpr = 1;
  memset(&eListItem, 0, sizeof(eListItem));
  eList.a = &eListItem;
  eList.a[0].pExpr = pExpr;
  selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, brk, brk, 0);
  sqlite3VdbeResolveLabel(v, brk);
  sqlite3VdbeAddOp(v, OP_Close, base, 0);
  
  return 1;
}

/*
** Analyze and ORDER BY or GROUP BY clause in a SELECT statement.  Return







>



<
<














|

|








<













|
<
<
<













|
|
>







<
<
|
<

<
|

|

>










<

<
|
|
|

|




|







|
|







2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148


2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173

2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187



2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210


2211

2212

2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227

2228

2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
  Expr *pExpr;
  int iCol;
  Table *pTab;
  Index *pIdx;
  int base;
  Vdbe *v;
  int seekOp;
  int cont;
  ExprList *pEList, *pList, eList;
  struct ExprList_item eListItem;
  SrcList *pSrc;



  /* Check to see if this query is a simple min() or max() query.  Return
  ** zero if it is  not.
  */
  if( p->pGroupBy || p->pHaving || p->pWhere ) return 0;
  pSrc = p->pSrc;
  if( pSrc->nSrc!=1 ) return 0;
  pEList = p->pEList;
  if( pEList->nExpr!=1 ) return 0;
  pExpr = pEList->a[0].pExpr;
  if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
  pList = pExpr->pList;
  if( pList==0 || pList->nExpr!=1 ) return 0;
  if( pExpr->token.n!=3 ) return 0;
  if( sqlite3StrNICmp(pExpr->token.z,"min",3)==0 ){
    seekOp = OP_Rewind;
  }else if( sqlite3StrNICmp(pExpr->token.z,"max",3)==0 ){
    seekOp = OP_Last;
  }else{
    return 0;
  }
  pExpr = pList->a[0].pExpr;
  if( pExpr->op!=TK_COLUMN ) return 0;
  iCol = pExpr->iColumn;
  pTab = pSrc->a[0].pTab;


  /* If we get to here, it means the query is of the correct form.
  ** Check to make sure we have an index and make pIdx point to the
  ** appropriate index.  If the min() or max() is on an INTEGER PRIMARY
  ** key column, no index is necessary so set pIdx to NULL.  If no
  ** usable index is found, return 0.
  */
  if( iCol<0 ){
    pIdx = 0;
  }else{
    CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      assert( pIdx->nColumn>=1 );
      if( pIdx->aiColumn[0]==iCol && pIdx->keyInfo.aColl[0]==pColl ) break;



    }
    if( pIdx==0 ) return 0;
  }

  /* Identify column types if we will be using the callback.  This
  ** step is skipped if the output is going to a table or a memory cell.
  ** The column names have already been generated in the calling function.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return 0;

  /* If the output is destined for a temporary table, open that table.
  */
  if( eDest==SRT_TempTable ){
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, 1);
  }

  /* Generating code to find the min or the max.  Basically all we have
  ** to do is find the first or the last entry in the chosen index.  If
  ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
  ** or last entry in the main table.
  */


  sqlite3CodeVerifySchema(pParse, pTab->iDb);

  base = pSrc->a[0].iCursor;

  computeLimitRegisters(pParse, p);
  if( pSrc->a[0].pSelect==0 ){
    sqlite3OpenTableForReading(v, base, pTab);
  }
  cont = sqlite3VdbeMakeLabel(v);
  if( pIdx==0 ){
    sqlite3VdbeAddOp(v, seekOp, base, 0);
  }else{
    /* Even though the cursor used to open the index here is closed
    ** as soon as a single value has been read from it, allocate it
    ** using (pParse->nTab++) to prevent the cursor id from being 
    ** reused. This is important for statements of the form 
    ** "INSERT INTO x SELECT max() FROM x".
    */
    int iIdx;

    iIdx = pParse->nTab++;

    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum,
                   (char*)&pIdx->keyInfo, P3_KEYINFO);
    if( seekOp==OP_Rewind ){
      sqlite3VdbeAddOp(v, OP_String, 0, 0);
      sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0);
      seekOp = OP_MoveGt;
    }
    sqlite3VdbeAddOp(v, seekOp, iIdx, 0);
    sqlite3VdbeAddOp(v, OP_IdxRecno, iIdx, 0);
    sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
    sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
  }
  eList.nExpr = 1;
  memset(&eListItem, 0, sizeof(eListItem));
  eList.a = &eListItem;
  eList.a[0].pExpr = pExpr;
  selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, cont, cont, 0);
  sqlite3VdbeResolveLabel(v, cont);
  sqlite3VdbeAddOp(v, OP_Close, base, 0);
  
  return 1;
}

/*
** Analyze and ORDER BY or GROUP BY clause in a SELECT statement.  Return
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
  Parse *pParse,         /* The parser context */
  Select *p,             /* The SELECT statement being coded. */
  NameContext *pOuterNC  /* The outer name context. May be NULL. */
){
  ExprList *pEList;          /* Result set. */
  int i;                     /* For-loop variable used in multiple places */
  NameContext sNC;           /* Local name-context */
  ExprList *pGroupBy;        /* The group by clause */

  /* If this routine has run before, return immediately. */
  if( p->isResolved ){
    assert( !pOuterNC );
    return SQLITE_OK;
  }
  p->isResolved = 1;







<







2305
2306
2307
2308
2309
2310
2311

2312
2313
2314
2315
2316
2317
2318
  Parse *pParse,         /* The parser context */
  Select *p,             /* The SELECT statement being coded. */
  NameContext *pOuterNC  /* The outer name context. May be NULL. */
){
  ExprList *pEList;          /* Result set. */
  int i;                     /* For-loop variable used in multiple places */
  NameContext sNC;           /* Local name-context */


  /* If this routine has run before, return immediately. */
  if( p->isResolved ){
    assert( !pOuterNC );
    return SQLITE_OK;
  }
  p->isResolved = 1;
2434
2435
2436
2437
2438
2439
2440
2441
2442







2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453












2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517

2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553

2554
2555
2556
2557
2558
2559
2560
2561
2562

2563
2564
2565
2566
2567



2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
  if( prepSelectStmt(pParse, p) ){
    return SQLITE_ERROR;
  }

  /* Resolve the expressions in the LIMIT and OFFSET clauses. These
  ** are not allowed to refer to any names, so pass an empty NameContext.
  */
  memset(&sNC, 0, sizeof(sNC));
  sNC.pParse = pParse;







  if( sqlite3ExprResolveNames(&sNC, p->pLimit) ||
      sqlite3ExprResolveNames(&sNC, p->pOffset) ){
    return SQLITE_ERROR;
  }

  /* Set up the local name-context to pass to ExprResolveNames() to
  ** resolve the expression-list.
  */
  sNC.allowAgg = 1;
  sNC.pSrcList = p->pSrc;
  sNC.pNext = pOuterNC;













  /* Resolve names in the result set. */
  pEList = p->pEList;
  if( !pEList ) return SQLITE_ERROR;
  for(i=0; i<pEList->nExpr; i++){
    Expr *pX = pEList->a[i].pExpr;
    if( sqlite3ExprResolveNames(&sNC, pX) ){
      return SQLITE_ERROR;
    }
  }

  /* If there are no aggregate functions in the result-set, and no GROUP BY 
  ** expression, do not allow aggregates in any of the other expressions.
  */
  assert( !p->isAgg );
  pGroupBy = p->pGroupBy;
  if( pGroupBy || sNC.hasAgg ){
    p->isAgg = 1;
  }else{
    sNC.allowAgg = 0;
  }

  /* If a HAVING clause is present, then there must be a GROUP BY clause.
  */
  if( p->pHaving && !pGroupBy ){
    sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
    return SQLITE_ERROR;
  }

  /* Add the expression list to the name-context before parsing the
  ** other expressions in the SELECT statement. This is so that
  ** expressions in the WHERE clause (etc.) can refer to expressions by
  ** aliases in the result set.
  **
  ** Minor point: If this is the case, then the expression will be
  ** re-evaluated for each reference to it.
  */
  sNC.pEList = p->pEList;
  if( sqlite3ExprResolveNames(&sNC, p->pWhere) ||
      sqlite3ExprResolveNames(&sNC, p->pHaving) ||
      processOrderGroupBy(&sNC, p->pOrderBy, "ORDER") ||
      processOrderGroupBy(&sNC, pGroupBy, "GROUP")
  ){
    return SQLITE_ERROR;
  }

  /* Make sure the GROUP BY clause does not contain aggregate functions.
  */
  if( pGroupBy ){
    struct ExprList_item *pItem;
  
    for(i=0, pItem=pGroupBy->a; i<pGroupBy->nExpr; i++, pItem++){
      if( ExprHasProperty(pItem->pExpr, EP_Agg) ){
        sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in "
            "the GROUP BY clause");
        return SQLITE_ERROR;
      }
    }
  }

  return SQLITE_OK;
}

/*

** Reset the aggregate accumulator.
**
** The aggregate accumulator is a set of memory cells that hold
** intermediate results while calculating an aggregate.  This
** routine simply stores NULLs in all of those memory cells.
*/
static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
  Vdbe *v = pParse->pVdbe;
  int i;
  struct AggInfo_func *pFunc;
  if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){
    return;
  }
  for(i=0; i<pAggInfo->nColumn; i++){
    sqlite3VdbeAddOp(v, OP_MemNull, pAggInfo->aCol[i].iMem, 0);
  }
  for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
    sqlite3VdbeAddOp(v, OP_MemNull, pFunc->iMem, 0);
    if( pFunc->iDistinct>=0 ){
      Expr *pE = pFunc->pExpr;
      if( pE->pList==0 || pE->pList->nExpr!=1 ){
        sqlite3ErrorMsg(pParse, "DISTINCT in aggregate must be followed "
           "by an expression");
        pFunc->iDistinct = -1;
      }else{
        KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->pList);
        sqlite3VdbeOp3(v, OP_OpenVirtual, pFunc->iDistinct, 0, 
                          (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
      }
    }
  }
}

/*
** Invoke the OP_AggFinalize opcode for every aggregate function
** in the AggInfo structure.

*/
static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
  Vdbe *v = pParse->pVdbe;
  int i;
  struct AggInfo_func *pF;
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
    ExprList *pList = pF->pExpr->pList;
    sqlite3VdbeOp3(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0,
                      (void*)pF->pFunc, P3_FUNCDEF);

  }
}

/*
** Update the accumulator memory cells for an aggregate based on



** the current cursor position.
*/
static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
  Vdbe *v = pParse->pVdbe;
  int i;
  struct AggInfo_func *pF;
  struct AggInfo_col *pC;

  pAggInfo->directMode = 1;
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
    int nArg;
    int addrNext = 0;
    ExprList *pList = pF->pExpr->pList;
    if( pList ){
      nArg = pList->nExpr;
      sqlite3ExprCodeExprList(pParse, pList);
    }else{
      nArg = 0;
    }
    if( pF->iDistinct>=0 ){
      addrNext = sqlite3VdbeMakeLabel(v);
      assert( nArg==1 );
      codeDistinct(v, pF->iDistinct, addrNext, 1, 2);
    }
    if( pF->pFunc->needCollSeq ){
      CollSeq *pColl = 0;
      struct ExprList_item *pItem;
      int j;
      for(j=0, pItem=pList->a; !pColl && j<pList->nExpr; j++, pItem++){
        pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
      }
      if( !pColl ){
        pColl = pParse->db->pDfltColl;
      }
      sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);
    }
    sqlite3VdbeOp3(v, OP_AggStep, pF->iMem, nArg, (void*)pF->pFunc, P3_FUNCDEF);
    if( addrNext ){
      sqlite3VdbeResolveLabel(v, addrNext);
    }
  }
  for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
    sqlite3ExprCode(pParse, pC->pExpr);
    sqlite3VdbeAddOp(v, OP_MemStore, pC->iMem, 1);
  }
  pAggInfo->directMode = 0;
}


/*
** Generate code for the given SELECT statement.
**
** The results are distributed in various ways depending on the
** value of eDest and iParm.
**
**     eDest Value       Result







<

>
>
>
>
>
>
>











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















<
|







|
















|




<
<
<
<
<
<
<
<
<
<
<
<
<
<




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

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

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







2328
2329
2330
2331
2332
2333
2334

2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380

2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410














2411
2412
2413
2414
2415
2416

2417
2418

2419
2420

2421
2422


2423








2424






2425




2426
2427
2428
2429
2430
2431
2432

2433

2434


2435
2436



2437
2438
2439
2440
2441
2442
2443
2444



2445
























2446
2447

2448













2449
2450
2451
2452
2453
2454
2455
  if( prepSelectStmt(pParse, p) ){
    return SQLITE_ERROR;
  }

  /* Resolve the expressions in the LIMIT and OFFSET clauses. These
  ** are not allowed to refer to any names, so pass an empty NameContext.
  */

  sNC.pParse = pParse;
  sNC.hasAgg = 0;
  sNC.nErr = 0;
  sNC.nRef = 0;
  sNC.pEList = 0;
  sNC.allowAgg = 0;
  sNC.pSrcList = 0;
  sNC.pNext = 0;
  if( sqlite3ExprResolveNames(&sNC, p->pLimit) ||
      sqlite3ExprResolveNames(&sNC, p->pOffset) ){
    return SQLITE_ERROR;
  }

  /* Set up the local name-context to pass to ExprResolveNames() to
  ** resolve the expression-list.
  */
  sNC.allowAgg = 1;
  sNC.pSrcList = p->pSrc;
  sNC.pNext = pOuterNC;

  /* NameContext.nDepth stores the depth of recursion for this query. For
  ** an outer query (e.g. SELECT * FROM sqlite_master) this is 1. For
  ** a subquery it is 2. For a subquery of a subquery, 3. And so on. 
  ** Parse.nMaxDepth is the maximum depth for any subquery resolved so
  ** far. This is used to determine the number of aggregate contexts
  ** required at runtime.
  */
  sNC.nDepth = (pOuterNC?pOuterNC->nDepth+1:1);
  if( sNC.nDepth>pParse->nMaxDepth ){
    pParse->nMaxDepth = sNC.nDepth;
  }

  /* Resolve names in the result set. */
  pEList = p->pEList;
  if( !pEList ) return SQLITE_ERROR;
  for(i=0; i<pEList->nExpr; i++){
    Expr *pX = pEList->a[i].pExpr;
    if( sqlite3ExprResolveNames(&sNC, pX) ){
      return SQLITE_ERROR;
    }
  }

  /* If there are no aggregate functions in the result-set, and no GROUP BY 
  ** expression, do not allow aggregates in any of the other expressions.
  */
  assert( !p->isAgg );

  if( p->pGroupBy || sNC.hasAgg ){
    p->isAgg = 1;
  }else{
    sNC.allowAgg = 0;
  }

  /* If a HAVING clause is present, then there must be a GROUP BY clause.
  */
  if( p->pHaving && !p->pGroupBy ){
    sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
    return SQLITE_ERROR;
  }

  /* Add the expression list to the name-context before parsing the
  ** other expressions in the SELECT statement. This is so that
  ** expressions in the WHERE clause (etc.) can refer to expressions by
  ** aliases in the result set.
  **
  ** Minor point: If this is the case, then the expression will be
  ** re-evaluated for each reference to it.
  */
  sNC.pEList = p->pEList;
  if( sqlite3ExprResolveNames(&sNC, p->pWhere) ||
      sqlite3ExprResolveNames(&sNC, p->pHaving) ||
      processOrderGroupBy(&sNC, p->pOrderBy, "ORDER") ||
      processOrderGroupBy(&sNC, p->pGroupBy, "GROUP")
  ){
    return SQLITE_ERROR;
  }















  return SQLITE_OK;
}

/*
** An instance of the following struct is used by sqlite3Select()
** to save aggregate related information from the Parse object

** at the start of each call and to restore it at the end. See
** saveAggregateInfo() and restoreAggregateInfo().

*/ 
struct AggregateInfo {

  int nAgg;
  AggExpr *aAgg;


};








typedef struct AggregateInfo AggregateInfo;











/* 
** Copy aggregate related information from the Parse structure
** into the AggregateInfo structure. Zero the aggregate related
** values in the Parse struct.
*/
static void saveAggregateInfo(Parse *pParse, AggregateInfo *pInfo){
  pInfo->aAgg = pParse->aAgg;

  pInfo->nAgg = pParse->nAgg;

  pParse->aAgg = 0;


  pParse->nAgg = 0;
}




/*
** Copy aggregate related information from the AggregateInfo struct
** back into the Parse structure. The aggregate related information
** currently stored in the Parse structure is deleted.
*/
static void restoreAggregateInfo(Parse *pParse, AggregateInfo *pInfo){
  sqliteFree(pParse->aAgg);



  pParse->aAgg = pInfo->aAgg;
























  pParse->nAgg = pInfo->nAgg;
}

  













/*
** Generate code for the given SELECT statement.
**
** The results are distributed in various ways depending on the
** value of eDest and iParm.
**
**     eDest Value       Result
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715

2716
2717
2718
2719
2720
2721
2722
2723
2724
  int eDest,             /* How to dispose of the results */
  int iParm,             /* A parameter used by the eDest disposal method */
  Select *pParent,       /* Another SELECT for which this is a sub-query */
  int parentTab,         /* Index in pParent->pSrc of this query */
  int *pParentAgg,       /* True if pParent uses aggregate functions */
  char *aff              /* If eDest is SRT_Union, the affinity string */
){
  int i, j;              /* Loop counters */
  WhereInfo *pWInfo;     /* Return from sqlite3WhereBegin() */
  Vdbe *v;               /* The virtual machine under construction */
  int isAgg;             /* True for select lists like "count(*)" */
  ExprList *pEList;      /* List of columns to extract. */
  SrcList *pTabList;     /* List of tables to select from */
  Expr *pWhere;          /* The WHERE clause.  May be NULL */
  ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
  ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
  Expr *pHaving;         /* The HAVING clause.  May be NULL */
  int isDistinct;        /* True if the DISTINCT keyword is present */
  int distinct;          /* Table to use for the distinct set */
  int rc = 1;            /* Value to return from this function */
  int addrSortIndex;     /* Address of an OP_OpenVirtual instruction */
  AggInfo sAggInfo;      /* Information used by aggregate queries */
  int iEnd;              /* Address of the end of the query */

  if( p==0 || sqlite3ThreadDataReadOnly()->mallocFailed || pParse->nErr ){
    return 1;
  }
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
  memset(&sAggInfo, 0, sizeof(sAggInfo));

#ifndef SQLITE_OMIT_COMPOUND_SELECT
  /* If there is are a sequence of queries, do the earlier ones first.
  */
  if( p->pPrior ){
    if( p->pRightmost==0 ){
      Select *pLoop;
      for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
        pLoop->pRightmost = p;
      }
    }
    return multiSelect(pParse, p, eDest, iParm, aff);
  }
#endif


  pOrderBy = p->pOrderBy;
  if( IgnorableOrderby(eDest) ){
    p->pOrderBy = 0;
  }
  if( sqlite3SelectResolve(pParse, p, 0) ){
    goto select_end;
  }
  p->pOrderBy = pOrderBy;








|
|
|










<
|
<

|
<
<

<





<
<
<
<
<
<




>

|







2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523

2524

2525
2526


2527

2528
2529
2530
2531
2532






2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
  int eDest,             /* How to dispose of the results */
  int iParm,             /* A parameter used by the eDest disposal method */
  Select *pParent,       /* Another SELECT for which this is a sub-query */
  int parentTab,         /* Index in pParent->pSrc of this query */
  int *pParentAgg,       /* True if pParent uses aggregate functions */
  char *aff              /* If eDest is SRT_Union, the affinity string */
){
  int i;
  WhereInfo *pWInfo;
  Vdbe *v;
  int isAgg;             /* True for select lists like "count(*)" */
  ExprList *pEList;      /* List of columns to extract. */
  SrcList *pTabList;     /* List of tables to select from */
  Expr *pWhere;          /* The WHERE clause.  May be NULL */
  ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
  ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
  Expr *pHaving;         /* The HAVING clause.  May be NULL */
  int isDistinct;        /* True if the DISTINCT keyword is present */
  int distinct;          /* Table to use for the distinct set */
  int rc = 1;            /* Value to return from this function */

  AggregateInfo sAggInfo;


  if( sqlite3_malloc_failed || pParse->nErr || p==0 ) return 1;


  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;


#ifndef SQLITE_OMIT_COMPOUND_SELECT
  /* If there is are a sequence of queries, do the earlier ones first.
  */
  if( p->pPrior ){






    return multiSelect(pParse, p, eDest, iParm, aff);
  }
#endif

  saveAggregateInfo(pParse, &sAggInfo);
  pOrderBy = p->pOrderBy;
  if( eDest==SRT_Union || eDest==SRT_Except || eDest==SRT_Discard ){
    p->pOrderBy = 0;
  }
  if( sqlite3SelectResolve(pParse, p, 0) ){
    goto select_end;
  }
  p->pOrderBy = pOrderBy;

2738
2739
2740
2741
2742
2743
2744

2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755



2756



2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
  ** errors before this routine starts.
  */
  if( pParse->nErr>0 ) goto select_end;

  /* If writing to memory or generating a set
  ** only a single column may be output.
  */

#ifndef SQLITE_OMIT_SUBQUERY
  if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
    sqlite3ErrorMsg(pParse, "only a single result allowed for "
       "a SELECT that is part of an expression");
    goto select_end;
  }
#endif

  /* ORDER BY is ignored for some destinations.
  */
  if( IgnorableOrderby(eDest) ){



    pOrderBy = 0;



  }

  /* Begin generating code.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto select_end;

  /* Identify column names if we will be using them in a callback.  This
  ** step is skipped if the output is going to some other destination.
  */
  if( eDest==SRT_Callback ){
    generateColumnNames(pParse, pTabList, pEList);
  }

  /* Generate code for all sub-queries in the FROM clause
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  for(i=0; i<pTabList->nSrc; i++){
    const char *zSavedAuthContext = 0;
    int needRestoreContext;
    struct SrcList_item *pItem = &pTabList->a[i];

    if( pItem->pSelect==0 ) continue;
    if( pItem->zName!=0 ){
      zSavedAuthContext = pParse->zAuthContext;
      pParse->zAuthContext = pItem->zName;
      needRestoreContext = 1;
    }else{
      needRestoreContext = 0;
    }
    sqlite3Select(pParse, pItem->pSelect, SRT_VirtualTab, 
                 pItem->iCursor, p, i, &isAgg, 0);
    if( needRestoreContext ){
      pParse->zAuthContext = zSavedAuthContext;
    }
    pTabList = p->pSrc;
    pWhere = p->pWhere;
    if( !IgnorableOrderby(eDest) ){
      pOrderBy = p->pOrderBy;
    }
    pGroupBy = p->pGroupBy;
    pHaving = p->pHaving;
    isDistinct = p->isDistinct;
  }
#endif







>










|
>
>
>
|
>
>
>




















<

|
|

|




|
|





|







2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605

2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
  ** errors before this routine starts.
  */
  if( pParse->nErr>0 ) goto select_end;

  /* If writing to memory or generating a set
  ** only a single column may be output.
  */
  assert( eDest!=SRT_Exists || pEList->nExpr==1 );
#ifndef SQLITE_OMIT_SUBQUERY
  if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
    sqlite3ErrorMsg(pParse, "only a single result allowed for "
       "a SELECT that is part of an expression");
    goto select_end;
  }
#endif

  /* ORDER BY is ignored for some destinations.
  */
  switch( eDest ){
    case SRT_Union:
    case SRT_Except:
    case SRT_Discard:
      pOrderBy = 0;
      break;
    default:
      break;
  }

  /* Begin generating code.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto select_end;

  /* Identify column names if we will be using them in a callback.  This
  ** step is skipped if the output is going to some other destination.
  */
  if( eDest==SRT_Callback ){
    generateColumnNames(pParse, pTabList, pEList);
  }

  /* Generate code for all sub-queries in the FROM clause
  */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  for(i=0; i<pTabList->nSrc; i++){
    const char *zSavedAuthContext = 0;
    int needRestoreContext;


    if( pTabList->a[i].pSelect==0 ) continue;
    if( pTabList->a[i].zName!=0 ){
      zSavedAuthContext = pParse->zAuthContext;
      pParse->zAuthContext = pTabList->a[i].zName;
      needRestoreContext = 1;
    }else{
      needRestoreContext = 0;
    }
    sqlite3Select(pParse, pTabList->a[i].pSelect, SRT_TempTable, 
                 pTabList->a[i].iCursor, p, i, &isAgg, 0);
    if( needRestoreContext ){
      pParse->zAuthContext = zSavedAuthContext;
    }
    pTabList = p->pSrc;
    pWhere = p->pWhere;
    if( eDest!=SRT_Union && eDest!=SRT_Except && eDest!=SRT_Discard ){
      pOrderBy = p->pOrderBy;
    }
    pGroupBy = p->pGroupBy;
    pHaving = p->pHaving;
    isDistinct = p->isDistinct;
  }
#endif
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835

2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936

2937
2938
2939



2940
2941


2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960

2961






2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977

2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988




2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999

3000
3001
3002


3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023


3024
3025


3026
3027
3028
3029
3030
3031
3032
3033
3034

3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049

3050
3051
3052
3053



3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074

3075
3076
3077
3078
3079
3080


3081


3082
3083
3084
3085
3086

3087

3088
3089
3090

3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107

3108
3109
3110
3111


3112
3113







3114
3115
3116
3117
3118
3119

3120
3121
3122

3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134

3135

3136

3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150

3151
3152
3153
3154
3155
3156
3157
3158

3159

3160

3161
3162
3163
3164
3165
3166
3167
3168
3169
      flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
    if( isAgg ) *pParentAgg = 1;
    goto select_end;
  }
#endif

  /* If there is an ORDER BY clause, resolve any collation sequences
  ** names that have been explicitly specified and create a sorting index.
  **
  ** This sorting index might end up being unused if the data can be 
  ** extracted in pre-sorted order.  If that is the case, then the
  ** OP_OpenVirtual instruction will be changed to an OP_Noop once
  ** we figure out that the sorting index is not needed.  The addrSortIndex
  ** variable is used to facilitate that change.
  */
  if( pOrderBy ){
    struct ExprList_item *pTerm;
    KeyInfo *pKeyInfo;
    for(i=0, pTerm=pOrderBy->a; i<pOrderBy->nExpr; i++, pTerm++){
      if( pTerm->zName ){

        pTerm->pExpr->pColl = sqlite3LocateCollSeq(pParse, pTerm->zName, -1);
      }
    }
    if( pParse->nErr ){
      goto select_end;
    }
    pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
    pOrderBy->iECursor = pParse->nTab++;
    p->addrOpenVirt[2] = addrSortIndex =
       sqlite3VdbeOp3(v, OP_OpenVirtual, pOrderBy->iECursor, pOrderBy->nExpr+2, 
                        (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
  }else{
    addrSortIndex = -1;
  }

  /* Set the limiter.
  */
  iEnd = sqlite3VdbeMakeLabel(v);
  computeLimitRegisters(pParse, p, iEnd);

  /* If the output is destined for a temporary table, open that table.
  */
  if( eDest==SRT_VirtualTab ){
    sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, pEList->nExpr);
  }

  /* Open a virtual index to use for the distinct set.
  */
  if( isDistinct ){
    KeyInfo *pKeyInfo;
    distinct = pParse->nTab++;
    pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
    sqlite3VdbeOp3(v, OP_OpenVirtual, distinct, 0, 
                        (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
  }else{
    distinct = -1;
  }

  /* Aggregate and non-aggregate queries are handled differently */
  if( !isAgg && pGroupBy==0 ){
    /* This case is for non-aggregate queries
    ** Begin the database scan
    */
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy);
    if( pWInfo==0 ) goto select_end;

    /* If sorting index that was created by a prior OP_OpenVirtual 
    ** instruction ended up not being needed, then change the OP_OpenVirtual
    ** into an OP_Noop.
    */
    if( addrSortIndex>=0 && pOrderBy==0 ){
      uncreateSortingIndex(pParse, addrSortIndex);
      p->addrOpenVirt[2] = -1;
    }

    /* Use the standard inner loop
    */
    if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
                    iParm, pWInfo->iContinue, pWInfo->iBreak, aff) ){
       goto select_end;
    }

    /* End the database scan loop.
    */
    sqlite3WhereEnd(pWInfo);
  }else{
    /* This is the processing for aggregate queries */
    NameContext sNC;    /* Name context for processing aggregate information */
    int iAMem;          /* First Mem address for storing current GROUP BY */
    int iBMem;          /* First Mem address for previous GROUP BY */
    int iUseFlag;       /* Mem address holding flag indicating that at least
                        ** one row of the input to the aggregator has been
                        ** processed */
    int iAbortFlag;     /* Mem address which causes query abort if positive */
    int groupBySort;    /* Rows come from source in GROUP BY order */


    /* The following variables hold addresses or labels for parts of the
    ** virtual machine program we are putting together */
    int addrOutputRow;      /* Start of subroutine that outputs a result row */
    int addrSetAbort;       /* Set the abort flag and return */
    int addrInitializeLoop; /* Start of code that initializes the input loop */
    int addrTopOfLoop;      /* Top of the input loop */
    int addrGroupByChange;  /* Code that runs when any GROUP BY term changes */
    int addrProcessRow;     /* Code to process a single input row */
    int addrEnd;            /* End of all processing */
    int addrSortingIdx;     /* The OP_OpenVirtual for the sorting index */
    int addrReset;          /* Subroutine for resetting the accumulator */

    addrEnd = sqlite3VdbeMakeLabel(v);

    /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
    ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
    ** SELECT statement.
    */
    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;
    sNC.pSrcList = pTabList;
    sNC.pAggInfo = &sAggInfo;
    sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
    sAggInfo.pGroupBy = pGroupBy;

    if( sqlite3ExprAnalyzeAggList(&sNC, pEList) ){
      goto select_end;
    }



    if( sqlite3ExprAnalyzeAggList(&sNC, pOrderBy) ){
      goto select_end;


    }
    if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){
      goto select_end;
    }
    sAggInfo.nAccumulator = sAggInfo.nColumn;
    for(i=0; i<sAggInfo.nFunc; i++){
      if( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList) ){
        goto select_end;
      }
    }
    if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto select_end;

    /* Processing for aggregates with GROUP BY is very different and
    ** much more complex tha aggregates without a GROUP BY.
    */
    if( pGroupBy ){
      KeyInfo *pKeyInfo;  /* Keying information for the group by clause */

      /* Create labels that we will be needing

      */






     
      addrInitializeLoop = sqlite3VdbeMakeLabel(v);
      addrGroupByChange = sqlite3VdbeMakeLabel(v);
      addrProcessRow = sqlite3VdbeMakeLabel(v);

      /* If there is a GROUP BY clause we might need a sorting index to
      ** implement it.  Allocate that sorting index now.  If it turns out
      ** that we do not need it after all, the OpenVirtual instruction
      ** will be converted into a Noop.  
      */
      sAggInfo.sortingIdx = pParse->nTab++;
      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
      addrSortingIdx =
          sqlite3VdbeOp3(v, OP_OpenVirtual, sAggInfo.sortingIdx,
                         sAggInfo.nSortingColumn,
                         (char*)pKeyInfo, P3_KEYINFO_HANDOFF);


      /* Initialize memory locations used by GROUP BY aggregate processing
      */
      iUseFlag = pParse->nMem++;
      iAbortFlag = pParse->nMem++;
      iAMem = pParse->nMem;
      pParse->nMem += pGroupBy->nExpr;
      iBMem = pParse->nMem;
      pParse->nMem += pGroupBy->nExpr;
      sqlite3VdbeAddOp(v, OP_MemInt, 0, iAbortFlag);
      VdbeComment((v, "# clear abort flag"));




      sqlite3VdbeAddOp(v, OP_MemInt, 0, iUseFlag);
      VdbeComment((v, "# indicate accumulator empty"));
      sqlite3VdbeAddOp(v, OP_Goto, 0, addrInitializeLoop);

      /* Generate a subroutine that outputs a single row of the result
      ** set.  This subroutine first looks at the iUseFlag.  If iUseFlag
      ** is less than or equal to zero, the subroutine is a no-op.  If
      ** the processing calls for the query to abort, this subroutine
      ** increments the iAbortFlag memory location before returning in
      ** order to signal the caller to abort.
      */

      addrSetAbort = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp(v, OP_MemInt, 1, iAbortFlag);
      VdbeComment((v, "# set abort flag"));


      sqlite3VdbeAddOp(v, OP_Return, 0, 0);
      addrOutputRow = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp(v, OP_IfMemPos, iUseFlag, addrOutputRow+2);
      VdbeComment((v, "# Groupby result generator entry point"));
      sqlite3VdbeAddOp(v, OP_Return, 0, 0);
      finalizeAggFunctions(pParse, &sAggInfo);
      if( pHaving ){
        sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, 1);
      }
      rc = selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
                           distinct, eDest, iParm, 
                           addrOutputRow+1, addrSetAbort, aff);
      if( rc ){
        goto select_end;
      }
      sqlite3VdbeAddOp(v, OP_Return, 0, 0);
      VdbeComment((v, "# end groupby result generator"));

      /* Generate a subroutine that will reset the group-by accumulator
      */
      addrReset = sqlite3VdbeCurrentAddr(v);


      resetAccumulator(pParse, &sAggInfo);
      sqlite3VdbeAddOp(v, OP_Return, 0, 0);



      /* Begin a loop that will extract all source rows in GROUP BY order.
      ** This might involve two separate loops with an OP_Sort in between, or
      ** it might be a single loop that uses an index to extract information
      ** in the right order to begin with.
      */
      sqlite3VdbeResolveLabel(v, addrInitializeLoop);
      sqlite3VdbeAddOp(v, OP_Gosub, 0, addrReset);
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy);

      if( pWInfo==0 ) goto select_end;
      if( pGroupBy==0 ){
        /* The optimizer is able to deliver rows in group by order so
        ** we do not have to sort.  The OP_OpenVirtual table will be
        ** cancelled later because we still need to use the pKeyInfo
        */
        pGroupBy = p->pGroupBy;
        groupBySort = 0;
      }else{
        /* Rows are coming out in undetermined order.  We have to push
        ** each row into a sorting index, terminate the first loop,
        ** then loop over the sorting index in order to get the output
        ** in sorted order
        */
        groupBySort = 1;

        sqlite3ExprCodeExprList(pParse, pGroupBy);
        sqlite3VdbeAddOp(v, OP_Sequence, sAggInfo.sortingIdx, 0);
        j = pGroupBy->nExpr+1;
        for(i=0; i<sAggInfo.nColumn; i++){



          struct AggInfo_col *pCol = &sAggInfo.aCol[i];
          if( pCol->iSorterColumn<j ) continue;
          if( pCol->iColumn<0 ){
            sqlite3VdbeAddOp(v, OP_Rowid, pCol->iTable, 0);
          }else{
            sqlite3VdbeAddOp(v, OP_Column, pCol->iTable, pCol->iColumn);
          }
          j++;
        }
        sqlite3VdbeAddOp(v, OP_MakeRecord, j, 0);
        sqlite3VdbeAddOp(v, OP_IdxInsert, sAggInfo.sortingIdx, 0);
        sqlite3WhereEnd(pWInfo);
        sqlite3VdbeAddOp(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
        VdbeComment((v, "# GROUP BY sort"));
        sAggInfo.useSortingIdx = 1;
      }

      /* Evaluate the current GROUP BY terms and store in b0, b1, b2...
      ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
      ** Then compare the current GROUP BY terms against the GROUP BY terms
      ** from the previous row currently stored in a0, a1, a2...

      */
      addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
      for(j=0; j<pGroupBy->nExpr; j++){
        if( groupBySort ){
          sqlite3VdbeAddOp(v, OP_Column, sAggInfo.sortingIdx, j);
        }else{


          sAggInfo.directMode = 1;


          sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr);
        }
        sqlite3VdbeAddOp(v, OP_MemStore, iBMem+j, j<pGroupBy->nExpr-1);
      }
      for(j=pGroupBy->nExpr-1; j>=0; j--){

        if( j<pGroupBy->nExpr-1 ){

          sqlite3VdbeAddOp(v, OP_MemLoad, iBMem+j, 0);
        }
        sqlite3VdbeAddOp(v, OP_MemLoad, iAMem+j, 0);

        if( j==0 ){
          sqlite3VdbeAddOp(v, OP_Eq, 0x200, addrProcessRow);
        }else{
          sqlite3VdbeAddOp(v, OP_Ne, 0x200, addrGroupByChange);
        }
        sqlite3VdbeChangeP3(v, -1, (void*)pKeyInfo->aColl[j], P3_COLLSEQ);
      }

      /* Generate code that runs whenever the GROUP BY changes.
      ** Change in the GROUP BY are detected by the previous code
      ** block.  If there were no changes, this block is skipped.
      **
      ** This code copies current group by terms in b0,b1,b2,...
      ** over to a0,a1,a2.  It then calls the output subroutine
      ** and resets the aggregate accumulator registers in preparation
      ** for the next GROUP BY batch.
      */

      sqlite3VdbeResolveLabel(v, addrGroupByChange);
      for(j=0; j<pGroupBy->nExpr; j++){
        sqlite3VdbeAddOp(v, OP_MemMove, iAMem+j, iBMem+j);
      }


      sqlite3VdbeAddOp(v, OP_Gosub, 0, addrOutputRow);
      VdbeComment((v, "# output one row"));







      sqlite3VdbeAddOp(v, OP_IfMemPos, iAbortFlag, addrEnd);
      VdbeComment((v, "# check abort flag"));
      sqlite3VdbeAddOp(v, OP_Gosub, 0, addrReset);
      VdbeComment((v, "# reset accumulator"));

      /* Update the aggregate accumulators based on the content of

      ** the current row
      */
      sqlite3VdbeResolveLabel(v, addrProcessRow);

      updateAccumulator(pParse, &sAggInfo);
      sqlite3VdbeAddOp(v, OP_MemInt, 1, iUseFlag);
      VdbeComment((v, "# indicate data in accumulator"));

      /* End of the loop
      */
      if( groupBySort ){
        sqlite3VdbeAddOp(v, OP_Next, sAggInfo.sortingIdx, addrTopOfLoop);
      }else{
        sqlite3WhereEnd(pWInfo);
        uncreateSortingIndex(pParse, addrSortingIdx);
      }



      /* Output the final row of result

      */
      sqlite3VdbeAddOp(v, OP_Gosub, 0, addrOutputRow);
      VdbeComment((v, "# output final row"));
      
    } /* endif pGroupBy */
    else {
      /* This case runs if the aggregate has no GROUP BY clause.  The
      ** processing is much simpler since there is only a single row
      ** of output.
      */
      resetAccumulator(pParse, &sAggInfo);
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
      if( pWInfo==0 ) goto select_end;
      updateAccumulator(pParse, &sAggInfo);

      sqlite3WhereEnd(pWInfo);
      finalizeAggFunctions(pParse, &sAggInfo);
      pOrderBy = 0;
      if( pHaving ){
        sqlite3ExprIfFalse(pParse, pHaving, addrEnd, 1);
      }
      selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, 
                      eDest, iParm, addrEnd, addrEnd, aff);

    }

    sqlite3VdbeResolveLabel(v, addrEnd);

    
  } /* endif aggregate query */

  /* If there is an ORDER BY clause, then we need to sort the results
  ** and send them to the callback one by one.
  */
  if( pOrderBy ){
    generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm);
  }







|
<
<
<
<
<
<


<
<
|
|
>
|





<
<
<
<
<
<
<




<
|



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


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



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




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

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

>
|
>
|
<







2644
2645
2646
2647
2648
2649
2650
2651






2652
2653


2654
2655
2656
2657
2658
2659
2660
2661
2662







2663
2664
2665
2666

2667
2668
2669
2670
2671
2672

2673










2674
2675







2676



2677




2678












2679



























2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706

2707





2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718



2719






2720
2721
2722

2723
2724
2725




2726
2727

2728
2729

2730
2731
2732
2733
2734


2735







2736
2737
2738

2739
2740
2741



2742



2743





2744


2745

2746

2747
2748
2749

2750
2751
2752
2753


2754
2755


2756
2757
2758
2759


2760







2761
2762

2763
2764


2765
2766
2767
2768






2769









2770




2771
2772




2773
2774
2775
2776
2777
2778
2779
2780


2781
2782
2783
2784
2785
2786

2787
2788
2789

2790
2791


2792









2793
2794


2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807

2808

2809

2810
2811


2812
2813


2814


2815
2816



2817
2818
2819
2820
2821
2822
2823
2824

2825

2826
2827


2828
2829
2830


2831
2832


2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843

2844
2845
2846
2847
2848
2849
2850
      flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
    if( isAgg ) *pParentAgg = 1;
    goto select_end;
  }
#endif

  /* If there is an ORDER BY clause, resolve any collation sequences
  ** names that have been explicitly specified.






  */
  if( pOrderBy ){


    for(i=0; i<pOrderBy->nExpr; i++){
      if( pOrderBy->a[i].zName ){
        pOrderBy->a[i].pExpr->pColl = 
            sqlite3LocateCollSeq(pParse, pOrderBy->a[i].zName, -1);
      }
    }
    if( pParse->nErr ){
      goto select_end;
    }







  }

  /* Set the limiter.
  */

  computeLimitRegisters(pParse, p);

  /* If the output is destined for a temporary table, open that table.
  */
  if( eDest==SRT_TempTable ){
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);

    sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, pEList->nExpr);










  }








  /* Do an analysis of aggregate expressions.



  */




  if( isAgg || pGroupBy ){












    NameContext sNC;



























    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;
    sNC.pSrcList = pTabList;

    assert( pParse->nAgg==0 );
    isAgg = 1;
    for(i=0; i<pEList->nExpr; i++){
      if( sqlite3ExprAnalyzeAggregates(&sNC, pEList->a[i].pExpr) ){
        goto select_end;
      }
    }
    if( pGroupBy ){
      for(i=0; i<pGroupBy->nExpr; i++){
        if( sqlite3ExprAnalyzeAggregates(&sNC, pGroupBy->a[i].pExpr) ){
          goto select_end;
        }
      }
    }
    if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){
      goto select_end;
    }
    if( pOrderBy ){
      for(i=0; i<pOrderBy->nExpr; i++){
        if( sqlite3ExprAnalyzeAggregates(&sNC, pOrderBy->a[i].pExpr) ){
          goto select_end;
        }
      }

    }





  }

  /* Reset the aggregator
  */
  if( isAgg ){
    int addr = sqlite3VdbeAddOp(v, OP_AggReset, (pGroupBy?0:1), pParse->nAgg);
    for(i=0; i<pParse->nAgg; i++){
      FuncDef *pFunc;
      if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){
        sqlite3VdbeOp3(v, OP_AggInit, 0, i, (char*)pFunc, P3_FUNCDEF);
      }



    }






    if( pGroupBy ){
      int sz = sizeof(KeyInfo) + pGroupBy->nExpr*sizeof(CollSeq*);
      KeyInfo *pKey = (KeyInfo *)sqliteMalloc(sz);

      if( 0==pKey ){
        goto select_end;
      }




      pKey->enc = pParse->db->enc;
      pKey->nField = pGroupBy->nExpr;

      for(i=0; i<pGroupBy->nExpr; i++){
        pKey->aColl[i] = sqlite3ExprCollSeq(pParse, pGroupBy->a[i].pExpr);

        if( !pKey->aColl[i] ){
          pKey->aColl[i] = pParse->db->pDfltColl;
        }
      }
      sqlite3VdbeChangeP3(v, addr, (char *)pKey, P3_KEYINFO_HANDOFF);


    }







  }

  /* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists

  */
  if( eDest==SRT_Mem || eDest==SRT_Exists ){
    sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_String8 : OP_Integer, 0, 0);



    sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);



  }








  /* Open a temporary table to use for the distinct set.

  */

  if( isDistinct ){
    distinct = pParse->nTab++;
    openTempIndex(pParse, p, distinct, 0);

  }else{
    distinct = -1;
  }



  /* Begin the database scan
  */


  pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,
                             pGroupBy ? 0 : &pOrderBy, p->pFetch);
  if( pWInfo==0 ) goto select_end;



  /* Use the standard inner loop if we are not dealing with







  ** aggregates
  */

  if( !isAgg ){
    if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,


                    iParm, pWInfo->iContinue, pWInfo->iBreak, aff) ){
       goto select_end;
    }
  }
















  /* If we are dealing with aggregates, then do the special aggregate




  ** processing.  
  */




  else{
    AggExpr *pAgg;
    int lbl1 = 0;
    pParse->fillAgg = 1;
    if( pGroupBy ){
      for(i=0; i<pGroupBy->nExpr; i++){
        sqlite3ExprCode(pParse, pGroupBy->a[i].pExpr);
      }


      /* No affinity string is attached to the following OP_MakeRecord 
      ** because we do not need to do any coercion of datatypes. */
      sqlite3VdbeAddOp(v, OP_MakeRecord, pGroupBy->nExpr, 0);
      lbl1 = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp(v, OP_AggFocus, 0, lbl1);
    }

    for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
      if( pAgg->isAgg ) continue;
      sqlite3ExprCode(pParse, pAgg->pExpr);

      sqlite3VdbeAddOp(v, OP_AggSet, 0, i);
    }


    pParse->fillAgg = 0;









    if( lbl1<0 ){
      sqlite3VdbeResolveLabel(v, lbl1);


    }
    for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
      Expr *pE;
      int nExpr;
      FuncDef *pDef;
      if( !pAgg->isAgg ) continue;
      assert( pAgg->pFunc!=0 );
      assert( pAgg->pFunc->xStep!=0 );
      pDef = pAgg->pFunc;
      pE = pAgg->pExpr;
      assert( pE!=0 );
      assert( pE->op==TK_AGG_FUNCTION );
      nExpr = sqlite3ExprCodeExprList(pParse, pE->pList);

      sqlite3VdbeAddOp(v, OP_Integer, i, 0);

      if( pDef->needCollSeq ){

        CollSeq *pColl = 0;
        int j;


        for(j=0; !pColl && j<nExpr; j++){
          pColl = sqlite3ExprCollSeq(pParse, pE->pList->a[j].pExpr);


        }


        if( !pColl ) pColl = pParse->db->pDfltColl;
        sqlite3VdbeOp3(v, OP_CollSeq, 0, 0, (char *)pColl, P3_COLLSEQ);



      }
      sqlite3VdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_POINTER);
    }
  }

  /* End the database scan loop.
  */
  sqlite3WhereEnd(pWInfo);



  /* If we are processing aggregates, we need to set up a second loop
  ** over all of the aggregate values and process them.


  */
  if( isAgg ){
    int endagg = sqlite3VdbeMakeLabel(v);


    int startagg;
    startagg = sqlite3VdbeAddOp(v, OP_AggNext, 0, endagg);


    if( pHaving ){
      sqlite3ExprIfFalse(pParse, pHaving, startagg, 1);
    }
    if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
                    iParm, startagg, endagg, aff) ){
      goto select_end;
    }
    sqlite3VdbeAddOp(v, OP_Goto, 0, startagg);
    sqlite3VdbeResolveLabel(v, endagg);
    sqlite3VdbeAddOp(v, OP_Noop, 0, 0);
  }


  /* If there is an ORDER BY clause, then we need to sort the results
  ** and send them to the callback one by one.
  */
  if( pOrderBy ){
    generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm);
  }
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
    assert( pParent->pSrc->nSrc>parentTab );
    assert( pParent->pSrc->a[parentTab].pSelect==p );
    sqlite3SelectDelete(p);
    pParent->pSrc->a[parentTab].pSelect = 0;
  }
#endif

  /* Jump here to skip this query
  */
  sqlite3VdbeResolveLabel(v, iEnd);

  /* The SELECT was successfully coded.   Set the return code to 0
  ** to indicate no errors.
  */
  rc = 0;

  /* Control jumps to here if an error is encountered above, or upon
  ** successful coding of the SELECT.
  */
select_end:
  sqliteFree(sAggInfo.aCol);
  sqliteFree(sAggInfo.aFunc);
  return rc;
}







<
<
<
<









|
<


2859
2860
2861
2862
2863
2864
2865




2866
2867
2868
2869
2870
2871
2872
2873
2874
2875

2876
2877
    assert( pParent->pSrc->nSrc>parentTab );
    assert( pParent->pSrc->a[parentTab].pSelect==p );
    sqlite3SelectDelete(p);
    pParent->pSrc->a[parentTab].pSelect = 0;
  }
#endif





  /* The SELECT was successfully coded.   Set the return code to 0
  ** to indicate no errors.
  */
  rc = 0;

  /* Control jumps to here if an error is encountered above, or upon
  ** successful coding of the SELECT.
  */
select_end:
  restoreAggregateInfo(pParse, &sAggInfo);

  return rc;
}
Deleted SQLite.Interop/src/server.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
/*
** 2006 January 07
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains demonstration code.  Nothing in this file gets compiled
** or linked into the SQLite library unless you use a non-standard option:
**
**      -DSQLITE_SERVER=1
**
** The configure script will never generate a Makefile with the option
** above.  You will need to manually modify the Makefile if you want to
** include any of the code from this file in your project.  Or, at your
** option, you may copy and paste the code from this file and
** thereby avoiding a recompile of SQLite.
**
**
** This source file demonstrates how to use SQLite to create an SQL database 
** server thread in a multiple-threaded program.  One or more client threads
** send messages to the server thread and the server thread processes those
** messages in the order received and returns the results to the client.
**
** One might ask:  "Why bother?  Why not just let each thread connect
** to the database directly?"  There are a several of reasons to
** prefer the client/server approach.
**
**    (1)  Some systems (ex: Redhat9) have broken threading implementations
**         that prevent SQLite database connections from being used in
**         a thread different from the one where they were created.  With
**         the client/server approach, all database connections are created
**         and used within the server thread.  Client calls to the database
**         can be made from multiple threads (though not at the same time!)
**
**    (2)  Beginning with SQLite version 3.3.0, when two or more 
**         connections to the same database occur within the same thread,
**         they can optionally share their database cache.  This reduces
**         I/O and memory requirements.  Cache shared is controlled using
**         the sqlite3_enable_shared_cache() API.
**
**    (3)  Database connections on a shared cache use table-level locking
**         instead of file-level locking for improved concurrency.
**
**    (4)  Database connections on a shared cache can by optionally
**         set to READ UNCOMMITTED isolation.  (The default isolation for
**         SQLite is SERIALIZABLE.)  When this occurs, readers will
**         never be blocked by a writer and writers will not be
**         blocked by readers.  There can still only be a single writer
**         at a time, but multiple readers can simultaneously exist with
**         that writer.  This is a huge increase in concurrency.
**
** To summarize the rational for using a client/server approach: prior
** to SQLite version 3.3.0 it probably was not worth the trouble.  But
** with SQLite version 3.3.0 and beyond you can get significant performance
** and concurrency improvements and memory usage reductions by going
** client/server.
**
** Note:  The extra features of version 3.3.0 described by points (2)
** through (4) above are only available if you compile without the
** option -DSQLITE_OMIT_SHARED_CACHE. 
**
** Here is how the client/server approach works:  The database server
** thread is started on this procedure:
**
**       void *sqlite3_server(void *NotUsed);
**
** The sqlite_server procedure runs as long as the g.serverHalt variable
** is false.  A mutex is used to make sure no more than one server runs
** at a time.  The server waits for messages to arrive on a message
** queue and processes the messages in order.
**
** Two convenience routines are provided for starting and stopping the
** server thread:
**
**       void sqlite3_server_start(void);
**       void sqlite3_server_stop(void);
**
** Both of the convenience routines return immediately.  Neither will
** ever give an error.  If a server is already started or already halted,
** then the routines are effectively no-ops.
**
** Clients use the following interfaces:
**
**       sqlite3_client_open
**       sqlite3_client_prepare
**       sqlite3_client_step
**       sqlite3_client_reset
**       sqlite3_client_finalize
**       sqlite3_client_close
**
** These interfaces work exactly like the standard core SQLite interfaces
** having the same names without the "_client_" infix.  Many other SQLite
** interfaces can be used directly without having to send messages to the
** server as long as SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined.
** The following interfaces fall into this second category:
**
**       sqlite3_bind_*
**       sqlite3_changes
**       sqlite3_clear_bindings
**       sqlite3_column_*
**       sqlite3_complete
**       sqlite3_create_collation
**       sqlite3_create_function
**       sqlite3_data_count
**       sqlite3_db_handle
**       sqlite3_errcode
**       sqlite3_errmsg
**       sqlite3_last_insert_rowid
**       sqlite3_total_changes
**       sqlite3_transfer_bindings
**
** A single SQLite connection (an sqlite3* object) or an SQLite statement
** (an sqlite3_stmt* object) should only be passed to a single interface
** function at a time.  The connections and statements can be passed from
** any thread to any of the functions listed in the second group above as
** long as the same connection is not in use by two threads at once and
** as long as SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined.  Additional
** information about the SQLITE_ENABLE_MEMORY_MANAGEMENT constraint is
** below.
**
** The busy handler for all database connections should remain turned
** off.  That means that any lock contention will cause the associated
** sqlite3_client_step() call to return immediately with an SQLITE_BUSY
** error code.  If a busy handler is enabled and lock contention occurs,
** then the entire server thread will block.  This will cause not only
** the requesting client to block but every other database client as
** well.  It is possible to enhance the code below so that lock
** contention will cause the message to be placed back on the top of
** the queue to be tried again later.  But such enhanced processing is
** not included here, in order to keep the example simple.
**
** This example code assumes the use of pthreads.  Pthreads
** implementations are available for windows.  (See, for example
** http://sourceware.org/pthreads-win32/announcement.html.)  Or, you
** can translate the locking and thread synchronization code to use
** windows primitives easily enough.  The details are left as an
** exercise to the reader.
**
**** Restrictions Associated With SQLITE_ENABLE_MEMORY_MANAGEMENT ****
**
** If you compile with SQLITE_ENABLE_MEMORY_MANAGEMENT defined, then
** SQLite includes code that tracks how much memory is being used by
** each thread.  These memory counts can become confused if memory
** is allocated by one thread and then freed by another.  For that
** reason, when SQLITE_ENABLE_MEMORY_MANAGEMENT is used, all operations
** that might allocate or free memory should be performanced in the same
** thread that originally created the database connection.  In that case,
** many of the operations that are listed above as safe to be performed
** in separate threads would need to be sent over to the server to be
** done there.  If SQLITE_ENABLE_MEMORY_MANAGEMENT is defined, then
** the following functions can be used safely from different threads
** without messing up the allocation counts:
**
**       sqlite3_bind_parameter_name
**       sqlite3_bind_parameter_index
**       sqlite3_changes
**       sqlite3_column_blob
**       sqlite3_column_count
**       sqlite3_complete
**       sqlite3_data_count
**       sqlite3_db_handle
**       sqlite3_errcode
**       sqlite3_errmsg
**       sqlite3_last_insert_rowid
**       sqlite3_total_changes
**
** The remaining functions are not thread-safe when memory management
** is enabled.  So one would have to define some new interface routines
** along the following lines:
**
**       sqlite3_client_bind_*
**       sqlite3_client_clear_bindings
**       sqlite3_client_column_*
**       sqlite3_client_create_collation
**       sqlite3_client_create_function
**       sqlite3_client_transfer_bindings
**
** The example code in this file is intended for use with memory
** management turned off.  So the implementation of these additional
** client interfaces is left as an exercise to the reader.
**
** It may seem surprising to the reader that the list of safe functions
** above does not include things like sqlite3_bind_int() or
** sqlite3_column_int().  But those routines might, in fact, allocate
** or deallocate memory.  In the case of sqlite3_bind_int(), if the
** parameter was previously bound to a string that string might need
** to be deallocated before the new integer value is inserted.  In
** the case of sqlite3_column_int(), the value of the column might be
** a UTF-16 string which will need to be converted to UTF-8 then into
** an integer.
*/

/*
** Only compile the code in this file on UNIX with a THREADSAFE build
** and only if the SQLITE_SERVER macro is defined.
*/
#ifdef SQLITE_SERVER
#if defined(OS_UNIX) && OS_UNIX && defined(THREADSAFE) && THREADSAFE

/*
** We require only pthreads and the public interface of SQLite.
*/
#include <pthread.h>
#include "sqlite3.h"

/*
** Messages are passed from client to server and back again as 
** instances of the following structure.
*/
typedef struct SqlMessage SqlMessage;
struct SqlMessage {
  int op;                      /* Opcode for the message */
  sqlite3 *pDb;                /* The SQLite connection */
  sqlite3_stmt *pStmt;         /* A specific statement */
  int errCode;                 /* Error code returned */
  const char *zIn;             /* Input filename or SQL statement */
  int nByte;                   /* Size of the zIn parameter for prepare() */
  const char *zOut;            /* Tail of the SQL statement */
  SqlMessage *pNext;           /* Next message in the queue */
  SqlMessage *pPrev;           /* Previous message in the queue */
  pthread_mutex_t clientMutex; /* Hold this mutex to access the message */
  pthread_cond_t clientWakeup; /* Signal to wake up the client */
};

/*
** Legal values for SqlMessage.op
*/
#define MSG_Open       1  /* sqlite3_open(zIn, &pDb) */
#define MSG_Prepare    2  /* sqlite3_prepare(pDb, zIn, nByte, &pStmt, &zOut) */
#define MSG_Step       3  /* sqlite3_step(pStmt) */
#define MSG_Reset      4  /* sqlite3_reset(pStmt) */
#define MSG_Finalize   5  /* sqlite3_finalize(pStmt) */
#define MSG_Close      6  /* sqlite3_close(pDb) */
#define MSG_Done       7  /* Server has finished with this message */


/*
** State information about the server is stored in a static variable
** named "g" as follows:
*/
static struct ServerState {
  pthread_mutex_t queueMutex;   /* Hold this mutex to access the msg queue */
  pthread_mutex_t serverMutex;  /* Held by the server while it is running */
  pthread_cond_t serverWakeup;  /* Signal this condvar to wake up the server */
  volatile int serverHalt;      /* Server halts itself when true */
  SqlMessage *pQueueHead;       /* Head of the message queue */
  SqlMessage *pQueueTail;       /* Tail of the message queue */
} g = {
  PTHREAD_MUTEX_INITIALIZER,
  PTHREAD_MUTEX_INITIALIZER,
  PTHREAD_COND_INITIALIZER,
};

/*
** Send a message to the server.  Block until we get a reply.
**
** The mutex and condition variable in the message are uninitialized
** when this routine is called.  This routine takes care of 
** initializing them and destroying them when it has finished.
*/
static void sendToServer(SqlMessage *pMsg){
  /* Initialize the mutex and condition variable on the message
  */
  pthread_mutex_init(&pMsg->clientMutex, 0);
  pthread_cond_init(&pMsg->clientWakeup, 0);

  /* Add the message to the head of the server's message queue.
  */
  pthread_mutex_lock(&g.queueMutex);
  pMsg->pNext = g.pQueueHead;
  if( g.pQueueHead==0 ){
    g.pQueueTail = pMsg;
  }else{
    g.pQueueHead->pPrev = pMsg;
  }
  pMsg->pPrev = 0;
  g.pQueueHead = pMsg;
  pthread_mutex_unlock(&g.queueMutex);

  /* Signal the server that the new message has be queued, then
  ** block waiting for the server to process the message.
  */
  pthread_mutex_lock(&pMsg->clientMutex);
  pthread_cond_signal(&g.serverWakeup);
  while( pMsg->op!=MSG_Done ){
    pthread_cond_wait(&pMsg->clientWakeup, &pMsg->clientMutex);
  }
  pthread_mutex_unlock(&pMsg->clientMutex);

  /* Destroy the mutex and condition variable of the message.
  */
  pthread_mutex_destroy(&pMsg->clientMutex);
  pthread_cond_destroy(&pMsg->clientWakeup);
}

/*
** The following 6 routines are client-side implementations of the
** core SQLite interfaces:
**
**        sqlite3_open
**        sqlite3_prepare
**        sqlite3_step
**        sqlite3_reset
**        sqlite3_finalize
**        sqlite3_close
**
** Clients should use the following client-side routines instead of 
** the core routines above.
**
**        sqlite3_client_open
**        sqlite3_client_prepare
**        sqlite3_client_step
**        sqlite3_client_reset
**        sqlite3_client_finalize
**        sqlite3_client_close
**
** Each of these routines creates a message for the desired operation,
** sends that message to the server, waits for the server to process
** then message and return a response.
*/
int sqlite3_client_open(const char *zDatabaseName, sqlite3 **ppDb){
  SqlMessage msg;
  msg.op = MSG_Open;
  msg.zIn = zDatabaseName;
  sendToServer(&msg);
  *ppDb = msg.pDb;
  return msg.errCode;
}
int sqlite3_client_prepare(
  sqlite3 *pDb,
  const char *zSql,
  int nByte,
  sqlite3_stmt **ppStmt,
  const char **pzTail
){
  SqlMessage msg;
  msg.op = MSG_Prepare;
  msg.pDb = pDb;
  msg.zIn = zSql;
  msg.nByte = nByte;
  sendToServer(&msg);
  *ppStmt = msg.pStmt;
  if( pzTail ) *pzTail = msg.zOut;
  return msg.errCode;
}
int sqlite3_client_step(sqlite3_stmt *pStmt){
  SqlMessage msg;
  msg.op = MSG_Step;
  msg.pStmt = pStmt;
  sendToServer(&msg);
  return msg.errCode;
}
int sqlite3_client_reset(sqlite3_stmt *pStmt){
  SqlMessage msg;
  msg.op = MSG_Reset;
  msg.pStmt = pStmt;
  sendToServer(&msg);
  return msg.errCode;
}
int sqlite3_client_finalize(sqlite3_stmt *pStmt){
  SqlMessage msg;
  msg.op = MSG_Finalize;
  msg.pStmt = pStmt;
  sendToServer(&msg);
  return msg.errCode;
}
int sqlite3_client_close(sqlite3 *pDb){
  SqlMessage msg;
  msg.op = MSG_Close;
  msg.pDb = pDb;
  sendToServer(&msg);
  return msg.errCode;
}

/*
** This routine implements the server.  To start the server, first
** make sure g.serverHalt is false, then create a new detached thread
** on this procedure.  See the sqlite3_server_start() routine below
** for an example.  This procedure loops until g.serverHalt becomes
** true.
*/
void *sqlite3_server(void *NotUsed){
  sqlite3_enable_shared_cache(1);
  if( pthread_mutex_trylock(&g.serverMutex) ){
    sqlite3_enable_shared_cache(0);
    return 0;  /* Another server is already running */
  }
  while( !g.serverHalt ){
    SqlMessage *pMsg;

    /* Remove the last message from the message queue.
    */
    pthread_mutex_lock(&g.queueMutex);
    while( g.pQueueTail==0 && g.serverHalt==0 ){
      pthread_cond_wait(&g.serverWakeup, &g.queueMutex);
    }
    pMsg = g.pQueueTail;
    if( pMsg ){
      if( pMsg->pPrev ){
        pMsg->pPrev->pNext = 0;
      }else{
        g.pQueueHead = 0;
      }
      g.pQueueTail = pMsg->pPrev;
    }
    pthread_mutex_unlock(&g.queueMutex);
    if( pMsg==0 ) break;

    /* Process the message just removed
    */
    pthread_mutex_lock(&pMsg->clientMutex);
    switch( pMsg->op ){
      case MSG_Open: {
        pMsg->errCode = sqlite3_open(pMsg->zIn, &pMsg->pDb);
        break;
      }
      case MSG_Prepare: {
        pMsg->errCode = sqlite3_prepare(pMsg->pDb, pMsg->zIn, pMsg->nByte,
                                        &pMsg->pStmt, &pMsg->zOut);
        break;
      }
      case MSG_Step: {
        pMsg->errCode = sqlite3_step(pMsg->pStmt);
        break;
      }
      case MSG_Reset: {
        pMsg->errCode = sqlite3_reset(pMsg->pStmt);
        break;
      }
      case MSG_Finalize: {
        pMsg->errCode = sqlite3_finalize(pMsg->pStmt);
        break;
      }
      case MSG_Close: {
        pMsg->errCode = sqlite3_close(pMsg->pDb);
        break;
      }
    }

    /* Signal the client that the message has been processed.
    */
    pMsg->op = MSG_Done;
    pthread_mutex_unlock(&pMsg->clientMutex);
    pthread_cond_signal(&pMsg->clientWakeup);
  }
  pthread_mutex_unlock(&g.serverMutex);
  sqlite3_thread_cleanup();
  return 0;
}

/*
** Start a server thread if one is not already running.  If there
** is aleady a server thread running, the new thread will quickly
** die and this routine is effectively a no-op.
*/
void sqlite3_server_start(void){
  pthread_t x;
  int rc;
  g.serverHalt = 0;
  rc = pthread_create(&x, 0, sqlite3_server, 0);
  if( rc==0 ){
    pthread_detach(x);
  }
}

/*
** If a server thread is running, then stop it.  If no server is
** running, this routine is effectively a no-op.
**
** This routine returns immediately without waiting for the server
** thread to stop.  But be assured that the server will eventually stop.
*/
void sqlite3_server_stop(void){
  g.serverHalt = 1;
  pthread_cond_broadcast(&g.serverWakeup);
}

#endif /* defined(OS_UNIX) && OS_UNIX && defined(THREADSAFE) && THREADSAFE */
#endif /* defined(SQLITE_SERVER) */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to SQLite.Interop/src/shell.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "sqlite3.h"
#include <ctype.h>







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.1 2005/03/01 16:04:35 rmsimpson Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "sqlite3.h"
#include <ctype.h>
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */


/*
** Determines if a string is a number of not.
*/
static int isNumber(const char *z, int *realnum){
  if( *z=='-' || *z=='+' ) z++;
  if( !isdigit(*z) ){
    return 0;
  }
  z++;
  if( realnum ) *realnum = 0;
  while( isdigit(*z) ){ z++; }







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */


/*
** Determines if a string is a number of not.
*/
static int isNumber(const unsigned char *z, int *realnum){
  if( *z=='-' || *z=='+' ) z++;
  if( !isdigit(*z) ){
    return 0;
  }
  z++;
  if( realnum ) *realnum = 0;
  while( isdigit(*z) ){ z++; }
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
    }else if( c=='\n' ){
      fputc('\\', out);
      fputc('n', out);
    }else if( c=='\r' ){
      fputc('\\', out);
      fputc('r', out);
    }else if( !isprint(c) ){
      fprintf(out, "\\%03o", c&0xff);
    }else{
      fputc(c, out);
    }
  }
  fputc('"', out);
}








|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
    }else if( c=='\n' ){
      fputc('\\', out);
      fputc('n', out);
    }else if( c=='\r' ){
      fputc('\\', out);
      fputc('r', out);
    }else if( !isprint(c) ){
      fprintf(out, "\\%03o", c);
    }else{
      fputc(c, out);
    }
  }
  fputc('"', out);
}

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
  struct callback_data *p = (struct callback_data *)pArg;

  if( nArg!=3 ) return 1;
  zTable = azArg[0];
  zType = azArg[1];
  zSql = azArg[2];
  
  if( strcmp(zTable, "sqlite_sequence")==0 ){
    fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
  }else if( strcmp(zTable, "sqlite_stat1")==0 ){
    fprintf(p->out, "ANALYZE sqlite_master;\n");
  }else if( strncmp(zTable, "sqlite_", 7)==0 ){
    return 0;
  }else{
    fprintf(p->out, "%s;\n", zSql);
  }

  if( strcmp(zType, "table")==0 ){
    sqlite3_stmt *pTableInfo = 0;
    char *zSelect = 0;
    char *zTableInfo = 0;
    char *zTmp = 0;







|
<
<
|
<
<

|







652
653
654
655
656
657
658
659


660


661
662
663
664
665
666
667
668
669
  struct callback_data *p = (struct callback_data *)pArg;

  if( nArg!=3 ) return 1;
  zTable = azArg[0];
  zType = azArg[1];
  zSql = azArg[2];
  
  if( strcasecmp(zTable,"sqlite_sequence")!=0 ){


    fprintf(p->out, "%s;\n", zSql);


  }else{
    fprintf(p->out, "DELETE FROM sqlite_sequence;\n");
  }

  if( strcmp(zType, "table")==0 ){
    sqlite3_stmt *pTableInfo = 0;
    char *zSelect = 0;
    char *zTableInfo = 0;
    char *zTmp = 0;
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
    zTmp = appendText(zTmp, zTable, '"');
    if( zTmp ){
      zSelect = appendText(zSelect, zTmp, '\'');
    }
    zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
    rc = sqlite3_step(pTableInfo);
    while( rc==SQLITE_ROW ){
      const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
      zSelect = appendText(zSelect, "quote(", 0);
      zSelect = appendText(zSelect, zText, '"');
      rc = sqlite3_step(pTableInfo);
      if( rc==SQLITE_ROW ){
        zSelect = appendText(zSelect, ") || ', ' || ", 0);
      }else{
        zSelect = appendText(zSelect, ") ", 0);
      }
    }







<

|







682
683
684
685
686
687
688

689
690
691
692
693
694
695
696
697
    zTmp = appendText(zTmp, zTable, '"');
    if( zTmp ){
      zSelect = appendText(zSelect, zTmp, '\'');
    }
    zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
    rc = sqlite3_step(pTableInfo);
    while( rc==SQLITE_ROW ){

      zSelect = appendText(zSelect, "quote(", 0);
      zSelect = appendText(zSelect, sqlite3_column_text(pTableInfo, 1), '"');
      rc = sqlite3_step(pTableInfo);
      if( rc==SQLITE_ROW ){
        zSelect = appendText(zSelect, ") || ', ' || ", 0);
      }else{
        zSelect = appendText(zSelect, ") ", 0);
      }
    }
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
      if( c=='n' ){
        c = '\n';
      }else if( c=='t' ){
        c = '\t';
      }else if( c=='r' ){
        c = '\r';
      }else if( c>='0' && c<='7' ){
        c -= '0';
        if( z[i+1]>='0' && z[i+1]<='7' ){
          i++;
          c = (c<<3) + z[i] - '0';
          if( z[i+1]>='0' && z[i+1]<='7' ){
            i++;
            c = (c<<3) + z[i] - '0';
          }







|







821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
      if( c=='n' ){
        c = '\n';
      }else if( c=='t' ){
        c = '\t';
      }else if( c=='r' ){
        c = '\r';
      }else if( c>='0' && c<='7' ){
        c =- '0';
        if( z[i+1]>='0' && z[i+1]<='7' ){
          i++;
          c = (c<<3) + z[i] - '0';
          if( z[i+1]>='0' && z[i+1]<='7' ){
            i++;
            c = (c<<3) + z[i] - '0';
          }
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
      ** did an .explain followed by a .width, .mode or .header
      ** command.
      */
      p->mode = MODE_Column;
      p->showHeader = 1;
      memset(p->colWidth,0,ArraySize(p->colWidth));
      p->colWidth[0] = 4;
      p->colWidth[1] = 14;
      p->colWidth[2] = 10;
      p->colWidth[3] = 10;
      p->colWidth[4] = 33;
    }else if (p->explainPrev.valid) {
      p->explainPrev.valid = 0;
      p->mode = p->explainPrev.mode;
      p->showHeader = p->explainPrev.showHeader;
      memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
    }
  }else







|


|







980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
      ** did an .explain followed by a .width, .mode or .header
      ** command.
      */
      p->mode = MODE_Column;
      p->showHeader = 1;
      memset(p->colWidth,0,ArraySize(p->colWidth));
      p->colWidth[0] = 4;
      p->colWidth[1] = 12;
      p->colWidth[2] = 10;
      p->colWidth[3] = 10;
      p->colWidth[4] = 35;
    }else if (p->explainPrev.valid) {
      p->explainPrev.valid = 0;
      p->mode = p->explainPrev.mode;
      p->showHeader = p->explainPrev.showHeader;
      memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
    }
  }else
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
          i++;
          if( i<nCol ){
            azCol[i] = &z[nSep];
            z += nSep-1;
          }
        }
      }
      *z = 0;
      if( i+1!=nCol ){
        fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
           zFile, lineno, nCol, i+1);
        zCommit = "ROLLBACK";
        break;
      }
      for(i=0; i<nCol; i++){







<







1089
1090
1091
1092
1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
          i++;
          if( i<nCol ){
            azCol[i] = &z[nSep];
            z += nSep-1;
          }
        }
      }

      if( i+1!=nCol ){
        fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
           zFile, lineno, nCol, i+1);
        zCommit = "ROLLBACK";
        break;
      }
      for(i=0; i<nCol; i++){
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
        zShellStatic = 0;
      }
    }else{
      sqlite3_exec(p->db,
         "SELECT sql FROM "
         "  (SELECT * FROM sqlite_master UNION ALL"
         "   SELECT * FROM sqlite_temp_master) "
         "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
         "ORDER BY substr(type,2,1), name",
         callback, &data, &zErrMsg
      );
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);







|







1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
        zShellStatic = 0;
      }
    }else{
      sqlite3_exec(p->db,
         "SELECT sql FROM "
         "  (SELECT * FROM sqlite_master UNION ALL"
         "   SELECT * FROM sqlite_temp_master) "
         "WHERE type!='meta' AND sql NOTNULL "
         "ORDER BY substr(type,2,1), name",
         callback, &data, &zErrMsg
      );
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
    char **azResult;
    int nRow, rc;
    char *zErrMsg;
    open_db(p);
    if( nArg==1 ){
      rc = sqlite3_get_table(p->db,
        "SELECT name FROM sqlite_master "
        "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type IN ('table','view') "
        "ORDER BY 1",
        &azResult, &nRow, 0, &zErrMsg
      );
    }else{







|







1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
    char **azResult;
    int nRow, rc;
    char *zErrMsg;
    open_db(p);
    if( nArg==1 ){
      rc = sqlite3_get_table(p->db,
        "SELECT name FROM sqlite_master "
        "WHERE type IN ('table','view') "
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type IN ('table','view') "
        "ORDER BY 1",
        &azResult, &nRow, 0, &zErrMsg
      );
    }else{
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
#endif
  }
  if( i<argc ){
    zFirstCmd = argv[i++];
  }
  data.out = stdout;

#ifdef SQLITE_OMIT_MEMORYDB
  if( data.zDbFilename==0 ){
    fprintf(stderr,"%s: no database filename specified\n", argv[0]);
    exit(1);
  }
#endif

  /* Go ahead and open the database file if it already exists.  If the
  ** file does not exist, delay opening it.  This prevents empty database
  ** files from being created if a user mistypes the database name argument
  ** to the sqlite command-line tool.
  */
  if( access(data.zDbFilename, 0)==0 ){
    open_db(&data);







<
<
<
<
<
<
<







1693
1694
1695
1696
1697
1698
1699







1700
1701
1702
1703
1704
1705
1706
#endif
  }
  if( i<argc ){
    zFirstCmd = argv[i++];
  }
  data.out = stdout;








  /* Go ahead and open the database file if it already exists.  If the
  ** file does not exist, delay opening it.  This prevents empty database
  ** files from being created if a user mistypes the database name argument
  ** to the sqlite command-line tool.
  */
  if( access(data.zDbFilename, 0)==0 ){
    open_db(&data);
Changes to SQLite.Interop/src/sqlite3.def.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
sqlite3_complete
sqlite3_complete16
sqlite3_create_collation
sqlite3_create_collation16
sqlite3_create_function
sqlite3_create_function16
sqlite3_data_count
sqlite3_db_handle
sqlite3_enable_shared_cache
sqlite3_errcode
sqlite3_errmsg
sqlite3_errmsg16
sqlite3_exec
sqlite3_expired
sqlite3_finalize
sqlite3_free
sqlite3_free_table
sqlite3_get_autocommit
sqlite3_get_auxdata
sqlite3_get_table
sqlite3_global_recover
sqlite3_interrupt
sqlite3_last_insert_rowid
sqlite3_libversion
sqlite3_libversion_number
sqlite3_mprintf
sqlite3_open
sqlite3_open16
sqlite3_prepare
sqlite3_prepare16
sqlite3_progress_handler
sqlite3_reset
sqlite3_result_blob
sqlite3_result_double
sqlite3_result_error
sqlite3_result_error16
sqlite3_result_int
sqlite3_result_int64
sqlite3_result_null
sqlite3_result_text
sqlite3_result_text16
sqlite3_result_text16be
sqlite3_result_text16le
sqlite3_result_value
sqlite3_rollback_hook
sqlite3_set_authorizer
sqlite3_set_auxdata
sqlite3_snprintf
sqlite3_step
sqlite3_thread_cleanup
sqlite3_total_changes
sqlite3_trace
sqlite3_transfer_bindings
sqlite3_update_hook
sqlite3_user_data
sqlite3_value_blob
sqlite3_value_bytes
sqlite3_value_bytes16
sqlite3_value_double
sqlite3_value_int
sqlite3_value_int64
sqlite3_value_text
sqlite3_value_text16
sqlite3_value_text16be
sqlite3_value_text16le
sqlite3_value_type
sqlite3_vmprintf







<
<




<



<


<



<



















<




<


<
<













35
36
37
38
39
40
41


42
43
44
45

46
47
48

49
50

51
52
53

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

73
74
75
76

77
78


79
80
81
82
83
84
85
86
87
88
89
90
91
sqlite3_complete
sqlite3_complete16
sqlite3_create_collation
sqlite3_create_collation16
sqlite3_create_function
sqlite3_create_function16
sqlite3_data_count


sqlite3_errcode
sqlite3_errmsg
sqlite3_errmsg16
sqlite3_exec

sqlite3_finalize
sqlite3_free
sqlite3_free_table

sqlite3_get_auxdata
sqlite3_get_table

sqlite3_interrupt
sqlite3_last_insert_rowid
sqlite3_libversion

sqlite3_mprintf
sqlite3_open
sqlite3_open16
sqlite3_prepare
sqlite3_prepare16
sqlite3_progress_handler
sqlite3_reset
sqlite3_result_blob
sqlite3_result_double
sqlite3_result_error
sqlite3_result_error16
sqlite3_result_int
sqlite3_result_int64
sqlite3_result_null
sqlite3_result_text
sqlite3_result_text16
sqlite3_result_text16be
sqlite3_result_text16le
sqlite3_result_value

sqlite3_set_authorizer
sqlite3_set_auxdata
sqlite3_snprintf
sqlite3_step

sqlite3_total_changes
sqlite3_trace


sqlite3_user_data
sqlite3_value_blob
sqlite3_value_bytes
sqlite3_value_bytes16
sqlite3_value_double
sqlite3_value_int
sqlite3_value_int64
sqlite3_value_text
sqlite3_value_text16
sqlite3_value_text16be
sqlite3_value_text16le
sqlite3_value_type
sqlite3_vmprintf
Changes to SQLite.Interop/src/sqlite3.h.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite3.h,v 1.16 2006/01/16 15:51:47 rmsimpson Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif

/*
** The version of the SQLite library.
*/
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#endif
#define SQLITE_VERSION         "3.3.1"

/*
** The format of the version string is "X.Y.Z<trailing string>", where
** X is the major version number, Y is the minor version number and Z
** is the release number. The trailing string is often "alpha" or "beta".
** For example "3.1.1beta".
**
** The SQLITE_VERSION_NUMBER is an integer with the value 
** (X*100000 + Y*1000 + Z). For example, for version "3.1.1beta", 
** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using 
** version 3.1.1 or greater at compile time, programs may use the test 
** (SQLITE_VERSION_NUMBER>=3001001).
*/
#ifdef SQLITE_VERSION_NUMBER
# undef SQLITE_VERSION_NUMBER
#endif
#define SQLITE_VERSION_NUMBER 3003001

/*
** The version string is also compiled into the library so that a program
** can check to make sure that the lib*.a file and the *.h file are from
** the same version.  The sqlite3_libversion() function returns a pointer
** to the sqlite3_version variable - useful in DLLs which cannot access
** global variables.







|


















|
















|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite3.h,v 1.1 2005/03/01 16:04:36 rmsimpson Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif

/*
** The version of the SQLite library.
*/
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#endif
#define SQLITE_VERSION         "3.1.3"

/*
** The format of the version string is "X.Y.Z<trailing string>", where
** X is the major version number, Y is the minor version number and Z
** is the release number. The trailing string is often "alpha" or "beta".
** For example "3.1.1beta".
**
** The SQLITE_VERSION_NUMBER is an integer with the value 
** (X*100000 + Y*1000 + Z). For example, for version "3.1.1beta", 
** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using 
** version 3.1.1 or greater at compile time, programs may use the test 
** (SQLITE_VERSION_NUMBER>=3001001).
*/
#ifdef SQLITE_VERSION_NUMBER
# undef SQLITE_VERSION_NUMBER
#endif
#define SQLITE_VERSION_NUMBER 3001003

/*
** The version string is also compiled into the library so that a program
** can check to make sure that the lib*.a file and the *.h file are from
** the same version.  The sqlite3_libversion() function returns a pointer
** to the sqlite3_version variable - useful in DLLs which cannot access
** global variables.
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  typedef __int64 sqlite_int64;
  typedef unsigned __int64 sqlite_uint64;
#else
  typedef long long int sqlite_int64;
  typedef unsigned long long int sqlite_uint64;
#endif

/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# define double sqlite_int64
#endif

/*
** A function to close the database.
**
** Call this function with a pointer to a structure that was previously
** returned from sqlite3_open() and the corresponding database will by closed.
**







<
<
<
<
<
<
<







82
83
84
85
86
87
88







89
90
91
92
93
94
95
  typedef __int64 sqlite_int64;
  typedef unsigned __int64 sqlite_uint64;
#else
  typedef long long int sqlite_int64;
  typedef unsigned long long int sqlite_uint64;
#endif









/*
** A function to close the database.
**
** Call this function with a pointer to a structure that was previously
** returned from sqlite3_open() and the corresponding database will by closed.
**
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
);

/*
** Return values for sqlite3_exec() and sqlite3_step()
*/
#define SQLITE_OK           0   /* Successful result */
#define SQLITE_ERROR        1   /* SQL error or missing database */
#define SQLITE_INTERNAL     2   /* NOT USED. Internal logic error in SQLite */
#define SQLITE_PERM         3   /* Access permission denied */
#define SQLITE_ABORT        4   /* Callback routine requested an abort */
#define SQLITE_BUSY         5   /* The database file is locked */
#define SQLITE_LOCKED       6   /* A table in the database is locked */
#define SQLITE_NOMEM        7   /* A malloc() failed */
#define SQLITE_READONLY     8   /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite3_interrupt()*/
#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT     11   /* The database disk image is malformed */
#define SQLITE_NOTFOUND    12   /* NOT USED. Table or record not found */
#define SQLITE_FULL        13   /* Insertion failed because database is full */
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* Database is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* NOT USED. Too much data for one row */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */
#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE_AUTH        23   /* Authorization denied */
#define SQLITE_FORMAT      24   /* Auxiliary database format error */
#define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB      26   /* File opened that is not a database file */
#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite3_step() has finished executing */
/* end-of-return-codes */

/*
** Each entry in an SQLite table has a unique integer key.  (The key is
** the value of the INTEGER PRIMARY KEY column if there is such a column,
** otherwise the key is generated at random.  The unique key is always
** available as the ROWID, OID, or _ROWID_ column.)  The following routine
** returns the integer key of the most recent insert in the database.







|









|





|










<







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
);

/*
** Return values for sqlite3_exec() and sqlite3_step()
*/
#define SQLITE_OK           0   /* Successful result */
#define SQLITE_ERROR        1   /* SQL error or missing database */
#define SQLITE_INTERNAL     2   /* An internal logic error in SQLite */
#define SQLITE_PERM         3   /* Access permission denied */
#define SQLITE_ABORT        4   /* Callback routine requested an abort */
#define SQLITE_BUSY         5   /* The database file is locked */
#define SQLITE_LOCKED       6   /* A table in the database is locked */
#define SQLITE_NOMEM        7   /* A malloc() failed */
#define SQLITE_READONLY     8   /* Attempt to write a readonly database */
#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite3_interrupt()*/
#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT     11   /* The database disk image is malformed */
#define SQLITE_NOTFOUND    12   /* (Internal Only) Table or record not found */
#define SQLITE_FULL        13   /* Insertion failed because database is full */
#define SQLITE_CANTOPEN    14   /* Unable to open the database file */
#define SQLITE_PROTOCOL    15   /* Database lock protocol error */
#define SQLITE_EMPTY       16   /* Database is empty */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* Too much data for one row of a table */
#define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */
#define SQLITE_MISMATCH    20   /* Data type mismatch */
#define SQLITE_MISUSE      21   /* Library used incorrectly */
#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */
#define SQLITE_AUTH        23   /* Authorization denied */
#define SQLITE_FORMAT      24   /* Auxiliary database format error */
#define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB      26   /* File opened that is not a database file */
#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite3_step() has finished executing */


/*
** Each entry in an SQLite table has a unique integer key.  (The key is
** the value of the INTEGER PRIMARY KEY column if there is such a column,
** otherwise the key is generated at random.  The unique key is always
** available as the ROWID, OID, or _ROWID_ column.)  The following routine
** returns the integer key of the most recent insert in the database.
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
**
** For example, so some string variable contains text as follows:
**
**      char *zText = "It's a happy day!";
**
** We can use this text in an SQL statement as follows:
**
**      char *z = sqlite3_mprintf("INSERT INTO TABLES('%q')", zText);
**      sqlite3_exec(db, z, callback1, 0, 0);
**      sqlite3_free(z);
**
** Because the %q format string is used, the '\'' character in zText
** is escaped and the SQL generated is as follows:
**
**      INSERT INTO table1 VALUES('It''s a happy day!')
**
** This is correct.  Had we used %s instead of %q, the generated SQL







<
|
|







369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
**
** For example, so some string variable contains text as follows:
**
**      char *zText = "It's a happy day!";
**
** We can use this text in an SQL statement as follows:
**

**      sqlite3_exec_printf(db, "INSERT INTO table VALUES('%q')",
**          callback1, 0, 0, zText);
**
** Because the %q format string is used, the '\'' character in zText
** is escaped and the SQL generated is as follows:
**
**      INSERT INTO table1 VALUES('It''s a happy day!')
**
** This is correct.  Had we used %s instead of %q, the generated SQL
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
#define SQLITE_SELECT               21   /* NULL            NULL            */
#define SQLITE_TRANSACTION          22   /* NULL            NULL            */
#define SQLITE_UPDATE               23   /* Table Name      Column Name     */
#define SQLITE_ATTACH               24   /* Filename        NULL            */
#define SQLITE_DETACH               25   /* Database Name   NULL            */
#define SQLITE_ALTER_TABLE          26   /* Database Name   Table Name      */
#define SQLITE_REINDEX              27   /* Index Name      NULL            */
#define SQLITE_ANALYZE              28   /* Table Name      NULL            */


/*
** The return value of the authorization function should be one of the
** following constants:
*/
/* #define SQLITE_OK  0   // Allow access (This is actually defined above) */
#define SQLITE_DENY   1   /* Abort the SQL statement with an error */
#define SQLITE_IGNORE 2   /* Don't allow access, but don't generate an error */

/*
** Register a function for tracing SQL command evaluation.  The function
** registered by sqlite3_trace() is invoked at the first sqlite3_step()
** for the evaluation of an SQL statement.  The function registered by
** sqlite3_profile() runs at the end of each SQL statement and includes
** information on how long that statement ran.
**
** The sqlite3_profile() API is currently considered experimental and
** is subject to change.
*/
void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
void *sqlite3_profile(sqlite3*,
   void(*xProfile)(void*,const char*,sqlite_uint64), void*);

/*
** This routine configures a callback function - the progress callback - that
** is invoked periodically during long running calls to sqlite3_exec(),
** sqlite3_step() and sqlite3_get_table(). An example use for this API is to 
** keep a GUI updated during a large query.
**







<











|
|
|
<
<
<
<
<


<
<







448
449
450
451
452
453
454

455
456
457
458
459
460
461
462
463
464
465
466
467
468





469
470


471
472
473
474
475
476
477
#define SQLITE_SELECT               21   /* NULL            NULL            */
#define SQLITE_TRANSACTION          22   /* NULL            NULL            */
#define SQLITE_UPDATE               23   /* Table Name      Column Name     */
#define SQLITE_ATTACH               24   /* Filename        NULL            */
#define SQLITE_DETACH               25   /* Database Name   NULL            */
#define SQLITE_ALTER_TABLE          26   /* Database Name   Table Name      */
#define SQLITE_REINDEX              27   /* Index Name      NULL            */



/*
** The return value of the authorization function should be one of the
** following constants:
*/
/* #define SQLITE_OK  0   // Allow access (This is actually defined above) */
#define SQLITE_DENY   1   /* Abort the SQL statement with an error */
#define SQLITE_IGNORE 2   /* Don't allow access, but don't generate an error */

/*
** Register a function that is called at every invocation of sqlite3_exec()
** or sqlite3_prepare().  This function can be used (for example) to generate
** a log file of all SQL executed against a database.





*/
void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);



/*
** This routine configures a callback function - the progress callback - that
** is invoked periodically during long running calls to sqlite3_exec(),
** sqlite3_step() and sqlite3_get_table(). An example use for this API is to 
** keep a GUI updated during a large query.
**
701
702
703
704
705
706
707


708
709
710
711
712
713
714
** must match exactly.  If no parameter with the given name is found,
** return 0.
*/
int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);

/*
** Set all the parameters in the compiled SQL statement to NULL.


*/
int sqlite3_clear_bindings(sqlite3_stmt*);

/*
** Return the number of columns in the result set returned by the compiled
** SQL statement. This routine returns 0 if pStmt is an SQL statement
** that does not return data (for example an UPDATE).







>
>







684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
** must match exactly.  If no parameter with the given name is found,
** return 0.
*/
int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);

/*
** Set all the parameters in the compiled SQL statement to NULL.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_clear_bindings(sqlite3_stmt*);

/*
** Return the number of columns in the result set returned by the compiled
** SQL statement. This routine returns 0 if pStmt is an SQL statement
** that does not return data (for example an UPDATE).
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024

1025
1026
1027
1028
1029
1030
1031
** of the aggregate can use the returned buffer to accumulate data.
**
** The buffer allocated is freed automatically by SQLite.
*/
void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);

/*
** The pUserData parameter to the sqlite3_create_function()
** routine used to register user functions is available to
** the implementation of the function using this call.

*/
void *sqlite3_user_data(sqlite3_context*);

/*
** The following two functions may be used by scalar user functions to
** associate meta-data with argument values. If the same value is passed to
** multiple invocations of the user-function during query execution, under







|
|
|
>







1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
** of the aggregate can use the returned buffer to accumulate data.
**
** The buffer allocated is freed automatically by SQLite.
*/
void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);

/*
** The pUserData parameter to the sqlite3_create_function() and
** sqlite3_create_aggregate() routines used to register user functions
** is available to the implementation of the function using this
** call.
*/
void *sqlite3_user_data(sqlite3_context*);

/*
** The following two functions may be used by scalar user functions to
** associate meta-data with argument values. If the same value is passed to
** multiple invocations of the user-function during query execution, under
1201
1202
1203
1204
1205
1206
1207


1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218

1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
** Sleep for a little while. The second parameter is the number of
** miliseconds to sleep for. 
**
** If the operating system does not support sleep requests with 
** milisecond time resolution, then the time will be rounded up to 
** the nearest second. The number of miliseconds of sleep actually 
** requested from the operating system is returned.


*/
int sqlite3_sleep(int);

/*
** Return TRUE (non-zero) if the statement supplied as an argument needs
** to be recompiled.  A statement needs to be recompiled whenever the
** execution environment changes in a way that would alter the program
** that sqlite3_prepare() generates.  For example, if new functions or
** collating sequences are registered or if an authorizer function is
** added or changed.
**

*/
int sqlite3_expired(sqlite3_stmt*);

/*
** Move all bindings from the first prepared statement over to the second.
** This routine is useful, for example, if the first prepared statement
** fails with an SQLITE_SCHEMA error.  The same SQL can be prepared into
** the second prepared statement then all of the bindings transfered over
** to the second statement before the first statement is finalized.
*/
int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);

/*
** If the following global variable is made to point to a
** string which is the name of a directory, then all temporary files
** created by SQLite will be placed in that directory.  If this variable
** is NULL pointer, then SQLite does a search for an appropriate temporary
** file directory.
**
** Once sqlite3_open() has been called, changing this variable will invalidate
** the current temporary database, if any.
*/
extern char *sqlite3_temp_directory;

/*
** This function is called to recover from a malloc() failure that occured
** within the SQLite library. Normally, after a single malloc() fails the 
** library refuses to function (all major calls return SQLITE_NOMEM).
** This function restores the library state so that it can be used again.
**
** All existing statements (sqlite3_stmt pointers) must be finalized or
** reset before this call is made. Otherwise, SQLITE_BUSY is returned.
** If any in-memory databases are in use, either as a main or TEMP
** database, SQLITE_ERROR is returned. In either of these cases, the 
** library is not reset and remains unusable.
**
** This function is *not* threadsafe. Calling this from within a threaded
** application when threads other than the caller have used SQLite is
** dangerous and will almost certainly result in malfunctions.
**
** This functionality can be omitted from a build by defining the 
** SQLITE_OMIT_GLOBALRECOVER at compile time.
*/
int sqlite3_global_recover(void);

/*
** Test to see whether or not the database connection is in autocommit
** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on
** by default.  Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
*/
int sqlite3_get_autocommit(sqlite3*);

/*
** Return the sqlite3* database handle to which the prepared statement given
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);

/*
** Register a callback function with the database connection identified by the 
** first argument to be invoked whenever a row is updated, inserted or deleted.
** Any callback set by a previous call to this function for the same 
** database connection is overridden.
**
** The second argument is a pointer to the function to invoke when a 
** row is updated, inserted or deleted. The first argument to the callback is
** a copy of the third argument to sqlite3_update_hook. The second callback 
** argument is one of SQLITE_INSERT, SQLITE_DELETE or SQLITE_UPDATE, depending
** on the operation that caused the callback to be invoked. The third and 
** fourth arguments to the callback contain pointers to the database and 
** table name containing the affected row. The final callback parameter is 
** the rowid of the row. In the case of an update, this is the rowid after 
** the update takes place.
**
** The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).
**
** If another function was previously registered, its pArg value is returned.
** Otherwise NULL is returned.
*/
void *sqlite3_update_hook(
  sqlite3*, 
  void(*)(void *,int ,char const *,char const *,sqlite_int64),
  void*
);

/*
** Register a callback to be invoked whenever a transaction is rolled
** back. 
**
** The new callback function overrides any existing rollback-hook
** callback. If there was an existing callback, then it's pArg value 
** (the third argument to sqlite3_rollback_hook() when it was registered) 
** is returned. Otherwise, NULL is returned.
**
** For the purposes of this API, a transaction is said to have been 
** rolled back if an explicit "ROLLBACK" statement is executed, or
** an error or constraint causes an implicit rollback to occur. The 
** callback is not invoked if a transaction is automatically rolled
** back because the database connection is closed.
*/
void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);

/*
** This function is only available if the library is compiled without
** the SQLITE_OMIT_SHARED_CACHE macro defined. It is used to enable or
** disable (if the argument is true or false, respectively) the 
** "shared pager" feature.
*/
int sqlite3_enable_shared_cache(int);

/*
** Attempt to free N bytes of heap memory by deallocating non-essential
** memory allocations held by the database library (example: memory 
** used to cache database pages to improve performance).
**
** This function is not a part of standard builds.  It is only created
** if SQLite is compiled with the SQLITE_ENABLE_MEMORY_MANAGEMENT macro.
*/
int sqlite3_release_memory(int);

/*
** Place a "soft" limit on the amount of heap memory that may be allocated by
** SQLite within the current thread. If an internal allocation is requested 
** that would exceed the specified limit, sqlite3_release_memory() is invoked
** one or more times to free up some space before the allocation is made.
**
** The limit is called "soft", because if sqlite3_release_memory() cannot free
** sufficient memory to prevent the limit from being exceeded, the memory is
** allocated anyway and the current operation proceeds.
**
** This function is only available if the library was compiled with the 
** SQLITE_ENABLE_MEMORY_MANAGEMENT option set.
** memory-management has been enabled.
*/
void sqlite3_soft_heap_limit(int);

/*
** This routine makes sure that all thread-local storage has been
** deallocated for the current thread.
**
** This routine is not technically necessary.  All thread-local storage
** will be automatically deallocated once memory-management and
** shared-cache are disabled and the soft heap limit has been set
** to zero.  This routine is provided as a convenience for users who
** want to make absolutely sure they have not forgotten something
** prior to killing off a thread.
*/
void sqlite3_thread_cleanup(void);

/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif







>
>




|






>



<
<
<
<
<
<
<
<
<







|
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210









1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222









































































































































1223
1224
1225
1226
** Sleep for a little while. The second parameter is the number of
** miliseconds to sleep for. 
**
** If the operating system does not support sleep requests with 
** milisecond time resolution, then the time will be rounded up to 
** the nearest second. The number of miliseconds of sleep actually 
** requested from the operating system is returned.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_sleep(int);

/*
** Return TRUE (non-zero) of the statement supplied as an argument needs
** to be recompiled.  A statement needs to be recompiled whenever the
** execution environment changes in a way that would alter the program
** that sqlite3_prepare() generates.  For example, if new functions or
** collating sequences are registered or if an authorizer function is
** added or changed.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_expired(sqlite3_stmt*);










/*
** If the following global variable is made to point to a
** string which is the name of a directory, then all temporary files
** created by SQLite will be placed in that directory.  If this variable
** is NULL pointer, then SQLite does a search for an appropriate temporary
** file directory.
**
** Once sqlite3_open() has been called, changing this variable will invalidate the
** current temporary database, if any.
*/
extern char *sqlite3_temp_directory;










































































































































#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif
Changes to SQLite.Interop/src/sqliteInt.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
#ifdef SQLITE_EXTRA
# include "sqliteExtra.h"
#endif

/*
** Many people are failing to set -DNDEBUG=1 when compiling SQLite.
** Setting NDEBUG makes the code smaller and run faster.  So the following
** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1
** option is set.  Thus NDEBUG becomes an opt-in rather than an opt-out
** feature.
*/
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif

/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
**
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
** on the compiler command line.  This is necessary if you are compiling













|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


















19
20
21
22
23
24
25
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.1 2005/03/01 16:04:36 rmsimpson Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_



















/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it.  If the OS lacks
** large file support, or if the OS is windows, these should be no-ops.
**
** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
** on the compiler command line.  This is necessary if you are compiling
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# define _LARGE_FILE       1
# ifndef _FILE_OFFSET_BITS
#   define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif


#include "sqlite3.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>

/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# define double sqlite_int64
# define LONGDOUBLE_TYPE sqlite_int64
# define SQLITE_BIG_DBL (0x7fffffffffffffff)
# define SQLITE_OMIT_DATETIME_FUNCS 1
# define SQLITE_OMIT_TRACE 1
#endif

/*
** The maximum number of in-memory pages to use for the main database
** table and for temporary tables. Internally, the MAX_PAGES and 
** TEMP_PAGES macros are used. To override the default values at
** compilation time, the SQLITE_DEFAULT_CACHE_SIZE and 
** SQLITE_DEFAULT_TEMP_CACHE_SIZE macros should be set.
*/
#ifdef SQLITE_DEFAULT_CACHE_SIZE
# define MAX_PAGES SQLITE_DEFAULT_CACHE_SIZE
#else
# define MAX_PAGES   2000
#endif
#ifdef SQLITE_DEFAULT_TEMP_CACHE_SIZE
# define TEMP_PAGES SQLITE_DEFAULT_TEMP_CACHE_SIZE
#else
# define TEMP_PAGES   500
#endif

/*
** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0
** afterward. Having this macro allows us to cause the C compiler 
** to omit code used by TEMP tables without messy #ifndef statements.
*/
#ifdef SQLITE_OMIT_TEMPDB
#define OMIT_TEMPDB 1
#else
#define OMIT_TEMPDB 0
#endif

/*
** If the following macro is set to 1, then NULL values are considered
** distinct for the SELECT DISTINCT statement and for UNION or EXCEPT
** compound queries.  No other SQL database engine (among those tested) 
** works this way except for OCELOT.  But the SQL92 spec implies that
** this is how things should work.
**







>









<
<
<
<
<
<
<
<
<
<
<
<


















<
<
<
<
<
<
<
<
<
<
<







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51












52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69











70
71
72
73
74
75
76
# define _LARGE_FILE       1
# ifndef _FILE_OFFSET_BITS
#   define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>













/*
** The maximum number of in-memory pages to use for the main database
** table and for temporary tables. Internally, the MAX_PAGES and 
** TEMP_PAGES macros are used. To override the default values at
** compilation time, the SQLITE_DEFAULT_CACHE_SIZE and 
** SQLITE_DEFAULT_TEMP_CACHE_SIZE macros should be set.
*/
#ifdef SQLITE_DEFAULT_CACHE_SIZE
# define MAX_PAGES SQLITE_DEFAULT_CACHE_SIZE
#else
# define MAX_PAGES   2000
#endif
#ifdef SQLITE_DEFAULT_TEMP_CACHE_SIZE
# define TEMP_PAGES SQLITE_DEFAULT_TEMP_CACHE_SIZE
#else
# define TEMP_PAGES   500
#endif












/*
** If the following macro is set to 1, then NULL values are considered
** distinct for the SELECT DISTINCT statement and for UNION or EXCEPT
** compound queries.  No other SQL database engine (among those tested) 
** works this way except for OCELOT.  But the SQL92 spec implies that
** this is how things should work.
**
144
145
146
147
148
149
150
151
152
153
154

155
156
157
158
159



160
161
162
163
164
165
166

/*
** The maximum value of a ?nnn wildcard that the parser will accept.
*/
#define SQLITE_MAX_VARIABLE_NUMBER 999

/*
** The "file format" number is an integer that is incremented whenever
** the VDBE-level file format changes.  The following macros define the
** the default file format for new databases and the maximum file format
** that the library can read.

*/
#define SQLITE_MAX_FILE_FORMAT 4
#ifndef SQLITE_DEFAULT_FILE_FORMAT
# define SQLITE_DEFAULT_FILE_FORMAT 4
#endif




/*
** Provide a default value for TEMP_STORE in case it is not specified
** on the command-line
*/
#ifndef TEMP_STORE
# define TEMP_STORE 1







|
|
<
|
>

|
|
|
|
>
>
>







104
105
106
107
108
109
110
111
112

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

/*
** The maximum value of a ?nnn wildcard that the parser will accept.
*/
#define SQLITE_MAX_VARIABLE_NUMBER 999

/*
** When building SQLite for embedded systems where memory is scarce,
** you can define one or more of the following macros to omit extra

** features of the library and thus keep the size of the library to
** a minimum.
*/
/* #define SQLITE_OMIT_AUTHORIZATION  1 */
/* #define SQLITE_OMIT_MEMORYDB     1 */
/* #define SQLITE_OMIT_VACUUM         1 */
/* #define SQLITE_OMIT_DATETIME_FUNCS 1 */
/* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */
/* #define SQLITE_OMIT_AUTOVACUUM */
/* #define SQLITE_OMIT_ALTERTABLE */

/*
** Provide a default value for TEMP_STORE in case it is not specified
** on the command-line
*/
#ifndef TEMP_STORE
# define TEMP_STORE 1
201
202
203
204
205
206
207














208
209
210
211
212
213
214
215


216
217
218
219
220
221
222
# define UINT8_TYPE unsigned char
#endif
#ifndef INT8_TYPE
# define INT8_TYPE signed char
#endif
#ifndef LONGDOUBLE_TYPE
# define LONGDOUBLE_TYPE long double














#endif
typedef sqlite_int64 i64;          /* 8-byte signed integer */
typedef UINT64_TYPE u64;           /* 8-byte unsigned integer */
typedef UINT32_TYPE u32;           /* 4-byte unsigned integer */
typedef UINT16_TYPE u16;           /* 2-byte unsigned integer */
typedef INT16_TYPE i16;            /* 2-byte signed integer */
typedef UINT8_TYPE u8;             /* 1-byte unsigned integer */
typedef UINT8_TYPE i8;             /* 1-byte signed integer */



/*
** Macros to determine whether the machine is big or little endian,
** evaluated at runtime.
*/
extern const int sqlite3one;
#define SQLITE_BIGENDIAN    (*(char *)(&sqlite3one)==0)







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








>
>







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# define UINT8_TYPE unsigned char
#endif
#ifndef INT8_TYPE
# define INT8_TYPE signed char
#endif
#ifndef LONGDOUBLE_TYPE
# define LONGDOUBLE_TYPE long double
#endif
#ifndef INTPTR_TYPE
# if SQLITE_PTR_SZ==4
#   define INTPTR_TYPE int
# else
#   define INTPTR_TYPE sqlite_int64
# endif
#endif
#ifndef UINTPTR_TYPE
# if SQLITE_PTR_SZ==4
#   define UINTPTR_TYPE unsigned int
# else
#   define UINTPTR_TYPE sqlite_uint64
# endif
#endif
typedef sqlite_int64 i64;          /* 8-byte signed integer */
typedef UINT64_TYPE u64;           /* 8-byte unsigned integer */
typedef UINT32_TYPE u32;           /* 4-byte unsigned integer */
typedef UINT16_TYPE u16;           /* 2-byte unsigned integer */
typedef INT16_TYPE i16;            /* 2-byte signed integer */
typedef UINT8_TYPE u8;             /* 1-byte unsigned integer */
typedef UINT8_TYPE i8;             /* 1-byte signed integer */
typedef INTPTR_TYPE ptr;           /* Big enough to hold a pointer */
typedef UINTPTR_TYPE uptr;         /* Big enough to hold a pointer */

/*
** Macros to determine whether the machine is big or little endian,
** evaluated at runtime.
*/
extern const int sqlite3one;
#define SQLITE_BIGENDIAN    (*(char *)(&sqlite3one)==0)
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254














255















256






257
258
259

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406


407



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
** handle is passed a pointer to sqlite.busyHandler. The busy-handler
** callback is currently invoked only from within pager.c.
*/
typedef struct BusyHandler BusyHandler;
struct BusyHandler {
  int (*xFunc)(void *,int);  /* The busy callback */
  void *pArg;                /* First arg to busy callback */
  int nBusy;                 /* Incremented with each busy call */
};

/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and 
** "BusyHandler typedefs.
*/
#include "vdbe.h"
#include "btree.h"
#include "pager.h"

/*
** This macro casts a pointer to an integer.  Useful for doing
** pointer arithmetic.
*/
#define Addr(X)  ((uptr)X)















#ifdef SQLITE_MEMDEBUG















/*






** The following global variables are used for testing and debugging
** only.  They only work if SQLITE_MEMDEBUG is defined.
*/

extern int sqlite3_nMalloc;      /* Number of sqliteMalloc() calls */
extern int sqlite3_nFree;        /* Number of sqliteFree() calls */
extern int sqlite3_iMallocFail;  /* Fail sqliteMalloc() after this many calls */
extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
#define ENTER_MALLOC (\
  sqlite3ThreadData()->zFile = __FILE__, sqlite3ThreadData()->iLine = __LINE__ \
)
#define sqliteMalloc(x)          (ENTER_MALLOC, sqlite3Malloc(x))
#define sqliteMallocRaw(x)       (ENTER_MALLOC, sqlite3MallocRaw(x))
#define sqliteRealloc(x,y)       (ENTER_MALLOC, sqlite3Realloc(x,y))
#define sqliteStrDup(x)          (ENTER_MALLOC, sqlite3StrDup(x))
#define sqliteStrNDup(x,y)       (ENTER_MALLOC, sqlite3StrNDup(x,y))
#define sqliteReallocOrFree(x,y) (ENTER_MALLOC, sqlite3ReallocOrFree(x,y))

#else

#define sqliteMalloc(x)          sqlite3Malloc(x)
#define sqliteMallocRaw(x)       sqlite3MallocRaw(x)
#define sqliteRealloc(x,y)       sqlite3Realloc(x,y)
#define sqliteStrDup(x)          sqlite3StrDup(x)
#define sqliteStrNDup(x,y)       sqlite3StrNDup(x,y)
#define sqliteReallocOrFree(x,y) sqlite3ReallocOrFree(x,y)

#endif

#define sqliteFree(x)          sqlite3FreeX(x)
#define sqliteAllocSize(x)     sqlite3AllocSize(x)


/*
** An instance of this structure might be allocated to store information
** specific to a single thread.
**
** To avoid a memory leak on windows, the content of this structure is
** checked at the conclusion of each API call.  If it is all zero, it
** is deallocated.
*/
struct ThreadData {
  int mallocFailed;        /* True after a malloc() has failed */
  int nRef;                /* Number of users */

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  int nSoftHeapLimit;      /* Suggested max mem allocation.  No limit if <0 */
  int nAlloc;              /* Number of bytes currently allocated */
  Pager *pPager;           /* Linked list of all pagers in this thread */
#endif

#ifndef SQLITE_OMIT_SHARED_CACHE
  u8 useSharedData;        /* True if shared pagers and schemas are enabled */
  BtShared *pBtree;        /* Linked list of all currently open BTrees */
#endif

#ifdef SQLITE_MEMDEBUG
  int nMaxAlloc;           /* High water mark of ThreadData.nAlloc */
  int mallocDisallowed;    /* assert() in sqlite3Malloc() if set */
  int isFail;              /* True if all malloc() calls should fail */
  const char *zFile;       /* Filename to associate debugging info with */
  int iLine;               /* Line number to associate debugging info with */
  void *pFirst;            /* Pointer to linked list of allocations */
#endif
};

/*
** Name of the master database table.  The master database table
** is a special table that holds the names and attributes of all
** user tables and indices.
*/
#define MASTER_NAME       "sqlite_master"
#define TEMP_MASTER_NAME  "sqlite_temp_master"

/*
** The root-page of the master database table.
*/
#define MASTER_ROOT       1

/*
** The name of the schema table.
*/
#define SCHEMA_TABLE(x)  ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME)

/*
** A convenience macro that returns the number of elements in
** an array.
*/
#define ArraySize(X)    (sizeof(X)/sizeof(X[0]))

/*
** Forward references to structures
*/
typedef struct AggInfo AggInfo;
typedef struct AuthContext AuthContext;
typedef struct CollSeq CollSeq;
typedef struct Column Column;
typedef struct Db Db;
typedef struct Schema Schema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct FKey FKey;
typedef struct FuncDef FuncDef;
typedef struct IdList IdList;
typedef struct Index Index;
typedef struct KeyClass KeyClass;
typedef struct KeyInfo KeyInfo;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct Select Select;
typedef struct SrcList SrcList;
typedef struct ThreadData ThreadData;
typedef struct Table Table;
typedef struct TableLock TableLock;
typedef struct Token Token;
typedef struct TriggerStack TriggerStack;
typedef struct TriggerStep TriggerStep;
typedef struct Trigger Trigger;
typedef struct WhereInfo WhereInfo;

typedef struct WhereLevel WhereLevel;

/*
** Each database file to be accessed by the system is an instance
** of the following structure.  There are normally two of these structures
** in the sqlite.aDb[] array.  aDb[0] is the main database file and
** aDb[1] is the database file used to hold temporary tables.  Additional
** databases may be attached.
*/
struct Db {
  char *zName;         /* Name of this database */
  Btree *pBt;          /* The B*Tree structure for this database file */
  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
  u8 safety_level;     /* How aggressive at synching data to disk */
  void *pAux;               /* Auxiliary data.  Usually NULL */
  void (*xFreeAux)(void*);  /* Routine to free pAux */
  Schema *pSchema;     /* Pointer to database schema (possibly shared) */
};

/*
** An instance of the following structure stores a database schema.
*/
struct Schema {
  int schema_cookie;   /* Database schema version number for this file */
  Hash tblHash;        /* All tables indexed by name */
  Hash idxHash;        /* All (named) indices indexed by name */
  Hash trigHash;       /* All triggers indexed by name */
  Hash aFKey;          /* Foreign keys indexed by to-table */
  Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
  u8 file_format;      /* Schema format version for this file */
  u8 enc;              /* Text encoding used by this database */
  u16 flags;           /* Flags associated with this schema */


  int cache_size;      /* Number of pages to use in the cache */



};

/*
** These macros can be used to test, set, or clear bits in the 
** Db.flags field.
*/
#define DbHasProperty(D,I,P)     (((D)->aDb[I].pSchema->flags&(P))==(P))
#define DbHasAnyProperty(D,I,P)  (((D)->aDb[I].pSchema->flags&(P))!=0)
#define DbSetProperty(D,I,P)     (D)->aDb[I].pSchema->flags|=(P)
#define DbClearProperty(D,I,P)   (D)->aDb[I].pSchema->flags&=~(P)

/*
** Allowed values for the DB.flags field.
**
** The DB_SchemaLoaded flag is set after the database schema has been
** read into internal hash tables.
**
** DB_UnresetViews means that one or more views have column names that
** have been filled out.  If the schema changes, these column names might
** changes and so the view will need to be reset.
*/
#define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
#define DB_UnresetViews    0x0002  /* Some views have defined column names */
#define DB_Empty           0x0004  /* The file is empty (length 0 bytes) */

#define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)

/*
** Each database is an instance of the following structure.
**
** The sqlite.lastRowid records the last insert rowid generated by an







<








<







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

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

>
>
>
>
>
>

|

>




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















|










<
<
|
|
|
|


|
|

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











<
<
<
<
<
<
<
<
<
<
<





<
<
<
|
>
>

>
>
>






|
|
|
|













<







210
211
212
213
214
215
216

217
218
219
220
221
222
223
224

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276



















277





































278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305


306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342











343
344
345
346
347



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377

378
379
380
381
382
383
384
** handle is passed a pointer to sqlite.busyHandler. The busy-handler
** callback is currently invoked only from within pager.c.
*/
typedef struct BusyHandler BusyHandler;
struct BusyHandler {
  int (*xFunc)(void *,int);  /* The busy callback */
  void *pArg;                /* First arg to busy callback */

};

/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and 
** "BusyHandler typedefs.
*/
#include "vdbe.h"
#include "btree.h"


/*
** This macro casts a pointer to an integer.  Useful for doing
** pointer arithmetic.
*/
#define Addr(X)  ((uptr)X)

/*
** If memory allocation problems are found, recompile with
**
**      -DSQLITE_DEBUG=1
**
** to enable some sanity checking on malloc() and free().  To
** check for memory leaks, recompile with
**
**      -DSQLITE_DEBUG=2
**
** and a line of text will be written to standard error for
** each malloc() and free().  This output can be analyzed
** by an AWK script to determine if there are any leaks.
*/
#ifdef SQLITE_MEMDEBUG
# define sqliteMalloc(X)    sqlite3Malloc_(X,1,__FILE__,__LINE__)
# define sqliteMallocRaw(X) sqlite3Malloc_(X,0,__FILE__,__LINE__)
# define sqliteFree(X)      sqlite3Free_(X,__FILE__,__LINE__)
# define sqliteRealloc(X,Y) sqlite3Realloc_(X,Y,__FILE__,__LINE__)
# define sqliteStrDup(X)    sqlite3StrDup_(X,__FILE__,__LINE__)
# define sqliteStrNDup(X,Y) sqlite3StrNDup_(X,Y,__FILE__,__LINE__)
#else
# define sqliteFree          sqlite3FreeX
# define sqliteMalloc        sqlite3Malloc
# define sqliteMallocRaw     sqlite3MallocRaw
# define sqliteRealloc       sqlite3Realloc
# define sqliteStrDup        sqlite3StrDup
# define sqliteStrNDup       sqlite3StrNDup
#endif

/*
** This variable gets set if malloc() ever fails.  After it gets set,
** the SQLite library shuts down permanently.
*/
extern int sqlite3_malloc_failed;

/*
** The following global variables are used for testing and debugging
** only.  They only work if SQLITE_DEBUG is defined.
*/
#ifdef SQLITE_MEMDEBUG
extern int sqlite3_nMalloc;      /* Number of sqliteMalloc() calls */
extern int sqlite3_nFree;        /* Number of sqliteFree() calls */
extern int sqlite3_iMallocFail;  /* Fail sqliteMalloc() after this many calls */
extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */



















#endif






































/*
** Name of the master database table.  The master database table
** is a special table that holds the names and attributes of all
** user tables and indices.
*/
#define MASTER_NAME       "sqlite_master"
#define TEMP_MASTER_NAME  "sqlite_temp_master"

/*
** The root-page of the master database table.
*/
#define MASTER_ROOT       1

/*
** The name of the schema table.
*/
#define SCHEMA_TABLE(x)  (x==1?TEMP_MASTER_NAME:MASTER_NAME)

/*
** A convenience macro that returns the number of elements in
** an array.
*/
#define ArraySize(X)    (sizeof(X)/sizeof(X[0]))

/*
** Forward references to structures
*/


typedef struct Column Column;
typedef struct Table Table;
typedef struct Index Index;
typedef struct Instruction Instruction;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct Parse Parse;
typedef struct Token Token;
typedef struct IdList IdList;
typedef struct SrcList SrcList;
typedef struct WhereInfo WhereInfo;
typedef struct WhereLevel WhereLevel;
typedef struct Select Select;
typedef struct AggExpr AggExpr;
typedef struct FuncDef FuncDef;
typedef struct Trigger Trigger;
typedef struct TriggerStep TriggerStep;
typedef struct TriggerStack TriggerStack;
typedef struct FKey FKey;
typedef struct Db Db;
typedef struct AuthContext AuthContext;
typedef struct KeyClass KeyClass;
typedef struct CollSeq CollSeq;
typedef struct KeyInfo KeyInfo;
typedef struct NameContext NameContext;
typedef struct Fetch Fetch;

/*
** Each database file to be accessed by the system is an instance
** of the following structure.  There are normally two of these structures
** in the sqlite.aDb[] array.  aDb[0] is the main database file and
** aDb[1] is the database file used to hold temporary tables.  Additional
** databases may be attached.
*/
struct Db {
  char *zName;         /* Name of this database */
  Btree *pBt;          /* The B*Tree structure for this database file */











  int schema_cookie;   /* Database schema version number for this file */
  Hash tblHash;        /* All tables indexed by name */
  Hash idxHash;        /* All (named) indices indexed by name */
  Hash trigHash;       /* All triggers indexed by name */
  Hash aFKey;          /* Foreign keys indexed by to-table */



  u16 flags;           /* Flags associated with this database */
  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
  u8 safety_level;     /* How aggressive at synching data to disk */
  int cache_size;      /* Number of pages to use in the cache */
  Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
  void *pAux;               /* Auxiliary data.  Usually NULL */
  void (*xFreeAux)(void*);  /* Routine to free pAux */
};

/*
** These macros can be used to test, set, or clear bits in the 
** Db.flags field.
*/
#define DbHasProperty(D,I,P)     (((D)->aDb[I].flags&(P))==(P))
#define DbHasAnyProperty(D,I,P)  (((D)->aDb[I].flags&(P))!=0)
#define DbSetProperty(D,I,P)     (D)->aDb[I].flags|=(P)
#define DbClearProperty(D,I,P)   (D)->aDb[I].flags&=~(P)

/*
** Allowed values for the DB.flags field.
**
** The DB_SchemaLoaded flag is set after the database schema has been
** read into internal hash tables.
**
** DB_UnresetViews means that one or more views have column names that
** have been filled out.  If the schema changes, these column names might
** changes and so the view will need to be reset.
*/
#define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
#define DB_UnresetViews    0x0002  /* Some views have defined column names */


#define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)

/*
** Each database is an instance of the following structure.
**
** The sqlite.lastRowid records the last insert rowid generated by an
457
458
459
460
461
462
463

464
465
466
467
468





469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512



513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530

531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566

567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
** store the most recent error code and, if applicable, string. The
** internal function sqlite3Error() is used to set these variables
** consistently.
*/
struct sqlite3 {
  int nDb;                      /* Number of backends currently in use */
  Db *aDb;                      /* All backends */

  int flags;                    /* Miscellanous flags. See below */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  u8 autoCommit;                /* The auto-commit flag. */
  u8 temp_store;                /* 1: file 2: memory 0: default */
  int nTable;                   /* Number of tables in the database */





  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 priorNewRowid;            /* Last randomly generated ROWID */
  int magic;                    /* Magic number for detect library misuse */
  int nChange;                  /* Value returned by sqlite3_changes() */
  int nTotalChange;             /* Value returned by sqlite3_total_changes() */
  struct sqlite3InitInfo {      /* Information used during initialization */
    int iDb;                    /* When back is being initialized */
    int newTnum;                /* Rootpage of table being initialized */
    u8 busy;                    /* TRUE if currently initializing */
  } init;
  struct Vdbe *pVdbe;           /* List of active virtual machines */
  int activeVdbeCnt;            /* Number of vdbes currently executing */
  void (*xTrace)(void*,const char*);        /* Trace function */
  void *pTraceArg;                          /* Argument to the trace function */
  void (*xProfile)(void*,const char*,u64);  /* Profiling function */
  void *pProfileArg;                        /* Argument to profile function */
  void *pCommitArg;                 /* Argument to xCommitCallback() */   
  int (*xCommitCallback)(void*);    /* Invoked at every commit. */
  void *pRollbackArg;               /* Argument to xRollbackCallback() */   
  void (*xRollbackCallback)(void*); /* Invoked at every commit. */
  void *pUpdateArg;
  void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
  void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
  void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
  void *pCollNeededArg;
  sqlite3_value *pErr;          /* Most recent error message */
  char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */
  char *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */
#ifndef SQLITE_OMIT_AUTHORIZATION
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
                                /* Access authorization function */
  void *pAuthArg;               /* 1st argument to the access auth function */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int (*xProgress)(void *);     /* The progress callback */
  void *pProgressArg;           /* Argument to the progress callback */
  int nProgressOps;             /* Number of opcodes for progress callback */
#endif
#ifndef SQLITE_OMIT_GLOBALRECOVER
  sqlite3 *pNext;               /* Linked list of open db handles. */
#endif
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  Hash aCollSeq;                /* All collating sequences */



  BusyHandler busyHandler;      /* Busy callback */
  int busyTimeout;             /* Busy handler timeout, in msec */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
#ifdef SQLITE_SSE
  sqlite3_stmt *pFetch;         /* Used by SSE to fetch stored statements */
#endif
};

#define ENC(db) ((db)->aDb[0].pSchema->enc)

/*
** Possible values for the sqlite.flags and or Db.flags fields.
**
** On sqlite.flags, the SQLITE_InTrans value means that we have
** executed a BEGIN.  On Db.flags, SQLITE_InTrans means a statement
** transaction is active on that particular database file.
*/
#define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */

#define SQLITE_Interrupt      0x00000004  /* Cancel current operation */
#define SQLITE_InTrans        0x00000008  /* True if in a transaction */
#define SQLITE_InternChanges  0x00000010  /* Uncommitted Hash table changes */
#define SQLITE_FullColNames   0x00000020  /* Show full column names on SELECT */
#define SQLITE_ShortColNames  0x00000040  /* Show short columns names */
#define SQLITE_CountRows      0x00000080  /* Count rows changed by INSERT, */
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000100  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_SqlTrace       0x00000200  /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    0x00000400  /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema    0x00000800  /* OK to update SQLITE_MASTER */
#define SQLITE_NoReadlock     0x00001000  /* Readlocks are omitted when 
                                          ** accessing read-only databases */
#define SQLITE_IgnoreChecks   0x00002000  /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x00004000  /* For shared-cache mode */
#define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */

/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */
#define SQLITE_MAGIC_CLOSED   0x9f3c2d33  /* Database is closed */
#define SQLITE_MAGIC_BUSY     0xf03b7906  /* Database currently in use */
#define SQLITE_MAGIC_ERROR    0xb5357930  /* An SQLITE_MISUSE error occurred */

/*
** Each SQL function is defined by an instance of the following
** structure.  A pointer to this structure is stored in the sqlite.aFunc
** hash table.  When multiple functions have the same name, the hash table
** points to a linked list of these structures.
*/
struct FuncDef {

  i16 nArg;            /* Number of arguments.  -1 means unlimited */
  u8 iPrefEnc;         /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */
  u8 needCollSeq;      /* True if sqlite3GetFuncCollSeq() might be called */
  u8 flags;            /* Some combination of SQLITE_FUNC_* */
  void *pUserData;     /* User data parameter */
  FuncDef *pNext;      /* Next function with same name */
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
  void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
  void (*xFinalize)(sqlite3_context*);                /* Aggregate finializer */
  char zName[1];       /* SQL name of the function.  MUST BE LAST */
};

/*
** Possible values for FuncDef.flags
*/
#define SQLITE_FUNC_LIKE   0x01  /* Candidate for the LIKE optimization */
#define SQLITE_FUNC_CASE   0x02  /* Case-sensitive LIKE-type function */

/*
** information about each column of an SQL table is held in an instance
** of this structure.
*/
struct Column {
  char *zName;     /* Name of this column */
  Expr *pDflt;     /* Default value of this column */
  char *zType;     /* Data type for this column */
  char *zColl;     /* Collating sequence.  If NULL, use the default */
  u8 notNull;      /* True if there is a NOT NULL constraint */
  u8 isPrimKey;    /* True if this column is part of the PRIMARY KEY */
  char affinity;   /* One of the SQLITE_AFF_... values */
};

/*
** A "Collating Sequence" is defined by an instance of the following
** structure. Conceptually, a collating sequence consists of a name and
** a comparison routine that defines the order of that sequence.
**
** There may two seperate implementations of the collation function, one
** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
** native byte order. When a collation sequence is invoked, SQLite selects
** the version that will require the least expensive encoding
** translations, if any.
**
** The CollSeq.pUser member variable is an extra parameter that passed in
** as the first argument to the UTF-8 comparison function, xCmp.
** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
** xCmp16.
**
** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
** collating sequence is undefined.  Indices built on an undefined
** collating sequence may not be read or written.
*/
struct CollSeq {
  char *zName;         /* Name of the collating sequence, UTF-8 encoded */
  u8 enc;              /* Text encoding handled by xCmp() */
  u8 type;             /* One of the SQLITE_COLL_... values below */
  void *pUser;         /* First argument to xCmp() */
  int (*xCmp)(void*,int, const void*, int, const void*);
};

/*
** Allowed values of CollSeq flags:
*/
#define SQLITE_COLL_BINARY  1  /* The default memcmp() collating sequence */
#define SQLITE_COLL_NOCASE  2  /* The built-in NOCASE collating sequence */
#define SQLITE_COLL_REVERSE 3  /* The built-in REVERSE collating sequence */
#define SQLITE_COLL_USER    0  /* Any other user-defined collating sequence */

/*
** A sort order can be either ASC or DESC.
*/
#define SQLITE_SO_ASC       0  /* Sort in ascending order */
#define SQLITE_SO_DESC      1  /* Sort in ascending order */

/*
** Column affinity types.
**
** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and
** 't' for SQLITE_AFF_TEXT.  But we can save a little space and improve
** the speed a little by number the values consecutively.  
**
** But rather than start with 0 or 1, we begin with 'a'.  That way,
** when multiple affinity types are concatenated into a string and
** used as the P3 operand, they will be more readable.
**
** Note also that the numeric types are grouped together so that testing
** for a numeric type is a single comparison.
*/
#define SQLITE_AFF_TEXT     'a'
#define SQLITE_AFF_NONE     'b'
#define SQLITE_AFF_NUMERIC  'c'
#define SQLITE_AFF_INTEGER  'd'
#define SQLITE_AFF_REAL     'e'

#define sqlite3IsNumericAffinity(X)  ((X)>=SQLITE_AFF_NUMERIC)

/*
** Each SQL table is represented in memory by an instance of the
** following structure.
**
** Table.zName is the name of the table.  The case of the original
** CREATE TABLE statement is stored, but case is not significant for







>

<
|


>
>
>
>
>













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










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


<
<








>















<
<
<


















>
|

<
<





|


<
<
<
<
<
<








|















|













<




<
<
<
<
<
<
<
<








<
<
<
<
<
<
<
<
<
<
<

|
|
|
|
<

<







403
404
405
406
407
408
409
410
411

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














435
436
437
438
439
440
441
442
443
444

445

446
447
448
449
450
451
452
453

454

455
456


457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480



481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501


502
503
504
505
506
507
508
509






510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547

548
549
550
551








552
553
554
555
556
557
558
559











560
561
562
563
564

565

566
567
568
569
570
571
572
** store the most recent error code and, if applicable, string. The
** internal function sqlite3Error() is used to set these variables
** consistently.
*/
struct sqlite3 {
  int nDb;                      /* Number of backends currently in use */
  Db *aDb;                      /* All backends */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
  int flags;                    /* Miscellanous flags. See below */

  u8 file_format;               /* What file format version is this database? */
  u8 temp_store;                /* 1: file 2: memory 0: default */
  int nTable;                   /* Number of tables in the database */
  BusyHandler busyHandler;      /* Busy callback */
  void *pCommitArg;             /* Argument to xCommitCallback() */   
  int (*xCommitCallback)(void*);/* Invoked at every commit. */
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  Hash aCollSeq;                /* All collating sequences */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 priorNewRowid;            /* Last randomly generated ROWID */
  int magic;                    /* Magic number for detect library misuse */
  int nChange;                  /* Value returned by sqlite3_changes() */
  int nTotalChange;             /* Value returned by sqlite3_total_changes() */
  struct sqlite3InitInfo {      /* Information used during initialization */
    int iDb;                    /* When back is being initialized */
    int newTnum;                /* Rootpage of table being initialized */
    u8 busy;                    /* TRUE if currently initializing */
  } init;
  struct Vdbe *pVdbe;           /* List of active virtual machines */
  int activeVdbeCnt;            /* Number of vdbes currently executing */
  void (*xTrace)(void*,const char*);     /* Trace function */
  void *pTraceArg;                       /* Argument to the trace function */














#ifndef SQLITE_OMIT_AUTHORIZATION
  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
                                /* Access authorization function */
  void *pAuthArg;               /* 1st argument to the access auth function */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int (*xProgress)(void *);     /* The progress callback */
  void *pProgressArg;           /* Argument to the progress callback */
  int nProgressOps;             /* Number of opcodes for progress callback */
#endif

  int errCode;                  /* Most recent error code (SQLITE_*) */

  u8 enc;                       /* Text encoding for this database. */
  u8 autoCommit;                /* The auto-commit flag. */
  void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
  void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
  void *pCollNeededArg;
  sqlite3_value *pValue;        /* Value used for transient conversions */
  sqlite3_value *pErr;          /* Most recent error message */
  char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */

  char *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */

};



/*
** Possible values for the sqlite.flags and or Db.flags fields.
**
** On sqlite.flags, the SQLITE_InTrans value means that we have
** executed a BEGIN.  On Db.flags, SQLITE_InTrans means a statement
** transaction is active on that particular database file.
*/
#define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
#define SQLITE_Initialized    0x00000002  /* True after initialization */
#define SQLITE_Interrupt      0x00000004  /* Cancel current operation */
#define SQLITE_InTrans        0x00000008  /* True if in a transaction */
#define SQLITE_InternChanges  0x00000010  /* Uncommitted Hash table changes */
#define SQLITE_FullColNames   0x00000020  /* Show full column names on SELECT */
#define SQLITE_ShortColNames  0x00000040  /* Show short columns names */
#define SQLITE_CountRows      0x00000080  /* Count rows changed by INSERT, */
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000100  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_SqlTrace       0x00000200  /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    0x00000400  /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema    0x00000800  /* OK to update SQLITE_MASTER */
#define SQLITE_NoReadlock     0x00001000  /* Readlocks are omitted when 
                                          ** accessing read-only databases */




/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */
#define SQLITE_MAGIC_CLOSED   0x9f3c2d33  /* Database is closed */
#define SQLITE_MAGIC_BUSY     0xf03b7906  /* Database currently in use */
#define SQLITE_MAGIC_ERROR    0xb5357930  /* An SQLITE_MISUSE error occurred */

/*
** Each SQL function is defined by an instance of the following
** structure.  A pointer to this structure is stored in the sqlite.aFunc
** hash table.  When multiple functions have the same name, the hash table
** points to a linked list of these structures.
*/
struct FuncDef {
  char *zName;         /* SQL name of the function */
  int nArg;            /* Number of arguments.  -1 means unlimited */
  u8 iPrefEnc;         /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */


  void *pUserData;     /* User data parameter */
  FuncDef *pNext;      /* Next function with same name */
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
  void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
  void (*xFinalize)(sqlite3_context*);                /* Aggregate finializer */
  u8 needCollSeq;      /* True if sqlite3GetFuncCollSeq() might be called */
};







/*
** information about each column of an SQL table is held in an instance
** of this structure.
*/
struct Column {
  char *zName;     /* Name of this column */
  Expr *pDflt;     /* Default value of this column */
  char *zType;     /* Data type for this column */
  CollSeq *pColl;  /* Collating sequence.  If NULL, use the default */
  u8 notNull;      /* True if there is a NOT NULL constraint */
  u8 isPrimKey;    /* True if this column is part of the PRIMARY KEY */
  char affinity;   /* One of the SQLITE_AFF_... values */
};

/*
** A "Collating Sequence" is defined by an instance of the following
** structure. Conceptually, a collating sequence consists of a name and
** a comparison routine that defines the order of that sequence.
**
** There may two seperate implementations of the collation function, one
** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
** native byte order. When a collation sequence is invoked, SQLite selects
** the version that will require the least expensive encoding
** transalations, if any.
**
** The CollSeq.pUser member variable is an extra parameter that passed in
** as the first argument to the UTF-8 comparison function, xCmp.
** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
** xCmp16.
**
** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
** collating sequence is undefined.  Indices built on an undefined
** collating sequence may not be read or written.
*/
struct CollSeq {
  char *zName;         /* Name of the collating sequence, UTF-8 encoded */
  u8 enc;              /* Text encoding handled by xCmp() */

  void *pUser;         /* First argument to xCmp() */
  int (*xCmp)(void*,int, const void*, int, const void*);
};









/*
** A sort order can be either ASC or DESC.
*/
#define SQLITE_SO_ASC       0  /* Sort in ascending order */
#define SQLITE_SO_DESC      1  /* Sort in ascending order */

/*
** Column affinity types.











*/
#define SQLITE_AFF_INTEGER  'i'
#define SQLITE_AFF_NUMERIC  'n'
#define SQLITE_AFF_TEXT     't'
#define SQLITE_AFF_NONE     'o'




/*
** Each SQL table is represented in memory by an instance of the
** following structure.
**
** Table.zName is the name of the table.  The case of the original
** CREATE TABLE statement is stored, but case is not significant for
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
  int nCol;        /* Number of columns in this table */
  Column *aCol;    /* Information about each column */
  int iPKey;       /* If not less then 0, use aCol[iPKey] as the primary key */
  Index *pIndex;   /* List of SQL indexes on this table. */
  int tnum;        /* Root BTree node for this table (see note above) */
  Select *pSelect; /* NULL for tables.  Points to definition if a view. */
  u8 readOnly;     /* True if this table should not be written by the user */
// u8 iDb;          /* Index into sqlite.aDb[] of the backend for this table */
  u8 isTransient;  /* True if automatically deleted when VDBE finishes */
  u8 hasPrimKey;   /* True if there exists a primary key */
  u8 keyConf;      /* What to do in case of uniqueness conflict on iPKey */
  u8 autoInc;      /* True if the integer primary key is autoincrement */
  int nRef;          /* Number of pointers to this Table */
  Trigger *pTrigger; /* List of SQL triggers on this table */
  FKey *pFKey;       /* Linked list of all foreign keys in this table */
  char *zColAff;     /* String defining the affinity of each column */
#ifndef SQLITE_OMIT_CHECK
  Expr *pCheck;      /* The AND of all CHECK constraints */
#endif
#ifndef SQLITE_OMIT_ALTERTABLE
  int addColOffset;  /* Offset in CREATE TABLE statement to add a new column */
#endif
  Schema *pSchema;
};

/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables.  The "from" table is
** the table that contains the REFERENCES clause that creates the foreign







|




<



<
<
<
<
<
<
<







599
600
601
602
603
604
605
606
607
608
609
610

611
612
613







614
615
616
617
618
619
620
  int nCol;        /* Number of columns in this table */
  Column *aCol;    /* Information about each column */
  int iPKey;       /* If not less then 0, use aCol[iPKey] as the primary key */
  Index *pIndex;   /* List of SQL indexes on this table. */
  int tnum;        /* Root BTree node for this table (see note above) */
  Select *pSelect; /* NULL for tables.  Points to definition if a view. */
  u8 readOnly;     /* True if this table should not be written by the user */
  u8 iDb;          /* Index into sqlite.aDb[] of the backend for this table */
  u8 isTransient;  /* True if automatically deleted when VDBE finishes */
  u8 hasPrimKey;   /* True if there exists a primary key */
  u8 keyConf;      /* What to do in case of uniqueness conflict on iPKey */
  u8 autoInc;      /* True if the integer primary key is autoincrement */

  Trigger *pTrigger; /* List of SQL triggers on this table */
  FKey *pFKey;       /* Linked list of all foreign keys in this table */
  char *zColAff;     /* String defining the affinity of each column */







};

/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables.  The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816

/*
** An instance of the following structure is passed as the first
** argument to sqlite3VdbeKeyCompare and is used to control the 
** comparison of the two index keys.
**
** If the KeyInfo.incrKey value is true and the comparison would
** otherwise be equal, then return a result as if the second key
** were larger.
*/
struct KeyInfo {
  u8 enc;             /* Text encoding - one of the TEXT_Utf* values */
  u8 incrKey;         /* Increase 2nd key by epsilon before comparison */
  int nField;         /* Number of entries in aColl[] */
  u8 *aSortOrder;     /* If defined an aSortOrder[i] is true, sort DESC */
  CollSeq *aColl[1];  /* Collating sequence for each term of the key */







|
<







696
697
698
699
700
701
702
703

704
705
706
707
708
709
710

/*
** An instance of the following structure is passed as the first
** argument to sqlite3VdbeKeyCompare and is used to control the 
** comparison of the two index keys.
**
** If the KeyInfo.incrKey value is true and the comparison would
** otherwise be equal, then return a result as if the second key larger.

*/
struct KeyInfo {
  u8 enc;             /* Text encoding - one of the TEXT_Utf* values */
  u8 incrKey;         /* Increase 2nd key by epsilon before comparison */
  int nField;         /* Number of entries in aColl[] */
  u8 *aSortOrder;     /* If defined an aSortOrder[i] is true, sort DESC */
  CollSeq *aColl[1];  /* Collating sequence for each term of the key */
842
843
844
845
846
847
848
849
850
851
852
853

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
*/
struct Index {
  char *zName;     /* Name of this index */
  int nColumn;     /* Number of columns in the table used by this index */
  int *aiColumn;   /* Which columns are used by this index.  1st is 0 */
  unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
  Table *pTable;   /* The SQL table being indexed */
  int tnum;        /* Page containing root of this index in database file */
  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */

  char *zColAff;   /* String defining the affinity of each column */
  Index *pNext;    /* The next index associated with the same table */
  Schema *pSchema; /* Schema containing this index */
  u8 *aSortOrder;  /* Array of size Index.nColumn. True==DESC, False==ASC */
  char **azColl;   /* Array of collation sequence names for index */
};

/*
** Each token coming out of the lexer is an instance of
** this structure.  Tokens are also used as part of an expression.
**
** Note if Token.z==0 then Token.dyn and Token.n are undefined and
** may contain random values.  Do not make any assuptions about Token.dyn
** and Token.n when Token.z==0.
*/
struct Token {
  const unsigned char *z; /* Text of the token.  Not NULL-terminated! */
  unsigned dyn  : 1;      /* True for malloced memory, false for static */
  unsigned n    : 31;     /* Number of characters in this token */
};

/*
** An instance of this structure contains information needed to generate
** code for a SELECT that contains aggregate functions.
**
** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
** pointer to this structure.  The Expr.iColumn field is the index in
** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
** code for that node.
**
** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the
** original Select structure that describes the SELECT statement.  These
** fields do not need to be freed when deallocating the AggInfo structure.
*/
struct AggInfo {
  u8 directMode;          /* Direct rendering mode means take data directly
                          ** from source tables rather than from accumulators */
  u8 useSortingIdx;       /* In direct mode, reference the sorting index rather
                          ** than the source table */
  int sortingIdx;         /* Cursor number of the sorting index */
  ExprList *pGroupBy;     /* The group by clause */
  int nSortingColumn;     /* Number of columns in the sorting index */
  struct AggInfo_col {    /* For each column used in source tables */
    int iTable;              /* Cursor number of the source table */
    int iColumn;             /* Column number within the source table */
    int iSorterColumn;       /* Column number in the sorting index */
    int iMem;                /* Memory location that acts as accumulator */
    Expr *pExpr;             /* The original expression */
  } *aCol;
  int nColumn;            /* Number of used entries in aCol[] */
  int nColumnAlloc;       /* Number of slots allocated for aCol[] */
  int nAccumulator;       /* Number of columns that show through to the output.
                          ** Additional columns are used only as parameters to
                          ** aggregate functions */
  struct AggInfo_func {   /* For each aggregate function */
    Expr *pExpr;             /* Expression encoding the function */
    FuncDef *pFunc;          /* The aggregate function implementation */
    int iMem;                /* Memory location that acts as accumulator */
    int iDistinct;           /* Virtual table used to enforce DISTINCT */
  } *aFunc;
  int nFunc;              /* Number of entries in aFunc[] */
  int nFuncAlloc;         /* Number of slots allocated for aFunc[] */
};

/*
** Each node of an expression in the parse tree is an instance
** of this structure.
**
** Expr.op is the opcode.  The integer parser token codes are reused
** as opcodes here.  For example, the parser defines TK_GE to be an integer
** code representing the ">=" operator.  This same integer code is reused







<




>


<
|
<
















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







736
737
738
739
740
741
742

743
744
745
746
747
748
749

750

751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766











































767
768
769
770
771
772
773
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
*/
struct Index {
  char *zName;     /* Name of this index */
  int nColumn;     /* Number of columns in the table used by this index */
  int *aiColumn;   /* Which columns are used by this index.  1st is 0 */

  Table *pTable;   /* The SQL table being indexed */
  int tnum;        /* Page containing root of this index in database file */
  u8 onError;      /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  u8 autoIndex;    /* True if is automatically created (ex: by UNIQUE) */
  u8 iDb;          /* Index in sqlite.aDb[] of where this index is stored */
  char *zColAff;   /* String defining the affinity of each column */
  Index *pNext;    /* The next index associated with the same table */

  KeyInfo keyInfo; /* Info on how to order keys.  MUST BE LAST */

};

/*
** Each token coming out of the lexer is an instance of
** this structure.  Tokens are also used as part of an expression.
**
** Note if Token.z==0 then Token.dyn and Token.n are undefined and
** may contain random values.  Do not make any assuptions about Token.dyn
** and Token.n when Token.z==0.
*/
struct Token {
  const unsigned char *z; /* Text of the token.  Not NULL-terminated! */
  unsigned dyn  : 1;      /* True for malloced memory, false for static */
  unsigned n    : 31;     /* Number of characters in this token */
};












































/*
** Each node of an expression in the parse tree is an instance
** of this structure.
**
** Expr.op is the opcode.  The integer parser token codes are reused
** as opcodes here.  For example, the parser defines TK_GE to be an integer
** code representing the ">=" operator.  This same integer code is reused
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978

979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
** gives a different answer at different times during statement processing
** then iTable is the address of a subroutine that computes the subquery.
**
** The Expr.pSelect field points to a SELECT statement.  The SELECT might
** be the right operand of an IN operator.  Or, if a scalar SELECT appears
** in an expression the opcode is TK_SELECT and Expr.pSelect is the only
** operand.
**
** If the Expr is of type OP_Column, and the table it is selecting from
** is a disk table or the "old.*" pseudo-table, then pTab points to the
** corresponding table definition.
*/
struct Expr {
  u8 op;                 /* Operation performed by this node */
  char affinity;         /* The affinity of the column or 0 if not a column */
//u8 iDb;                /* Database referenced by this expression */
  u8 flags;              /* Various flags.  See below */
  CollSeq *pColl;        /* The collation type of the column or 0 */
  Expr *pLeft, *pRight;  /* Left and right subnodes */
  ExprList *pList;       /* A list of expressions used as function arguments
                         ** or in "<expr> IN (<expr-list)" */
  Token token;           /* An operand token */
  Token span;            /* Complete text of the expression */
  int iTable, iColumn;   /* When op==TK_COLUMN, then this expr node means the
                         ** iColumn-th field of the iTable-th table. */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  int iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */

  int iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  Select *pSelect;       /* When the expression is a sub-select.  Also the
                         ** right side of "<expr> IN (<select>)" */
  Table *pTab;           /* Table for OP_Column expressions. */
  Schema *pSchema;
};

/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin     0x01  /* Originated in ON or USING clause of a join */
#define EP_Agg          0x02  /* Contains one or more aggregate functions */
#define EP_Resolved     0x04  /* IDs have been resolved to COLUMNs */
#define EP_Error        0x08  /* Expression contains one or more errors */
#define EP_Distinct     0x10  /* Aggregate function with DISTINCT keyword */
#define EP_VarSelect    0x20  /* pSelect is correlated, not constant */
#define EP_Dequoted     0x40  /* True if the string has been dequoted */

/*
** These macros can be used to test, set, or clear bits in the 
** Expr.flags field.
*/
#define ExprHasProperty(E,P)     (((E)->flags&(P))==(P))
#define ExprHasAnyProperty(E,P)  (((E)->flags&(P))!=0)







<
<
<
<




|









<
|
>
|


<
<





|
|
|
|
|
|
<







801
802
803
804
805
806
807




808
809
810
811
812
813
814
815
816
817
818
819
820
821

822
823
824
825
826


827
828
829
830
831
832
833
834
835
836
837

838
839
840
841
842
843
844
** gives a different answer at different times during statement processing
** then iTable is the address of a subroutine that computes the subquery.
**
** The Expr.pSelect field points to a SELECT statement.  The SELECT might
** be the right operand of an IN operator.  Or, if a scalar SELECT appears
** in an expression the opcode is TK_SELECT and Expr.pSelect is the only
** operand.




*/
struct Expr {
  u8 op;                 /* Operation performed by this node */
  char affinity;         /* The affinity of the column or 0 if not a column */
  u8 iDb;                /* Database referenced by this expression */
  u8 flags;              /* Various flags.  See below */
  CollSeq *pColl;        /* The collation type of the column or 0 */
  Expr *pLeft, *pRight;  /* Left and right subnodes */
  ExprList *pList;       /* A list of expressions used as function arguments
                         ** or in "<expr> IN (<expr-list)" */
  Token token;           /* An operand token */
  Token span;            /* Complete text of the expression */
  int iTable, iColumn;   /* When op==TK_COLUMN, then this expr node means the
                         ** iColumn-th field of the iTable-th table. */

  int iAgg;              /* When op==TK_COLUMN and pParse->fillAgg==FALSE, pull
                         ** result from the iAgg-th element of the aggregator */
  int iAggCtx;           /* The value to pass as P1 of OP_AggGet. */
  Select *pSelect;       /* When the expression is a sub-select.  Also the
                         ** right side of "<expr> IN (<select>)" */


};

/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin     0x0001  /* Originated in ON or USING clause of a join */
#define EP_Agg          0x0002  /* Contains one or more aggregate functions */
#define EP_Resolved     0x0004  /* IDs have been resolved to COLUMNs */
#define EP_Error        0x0008  /* Expression contains one or more errors */
#define EP_Not          0x0010  /* Operator preceeded by NOT */
#define EP_VarSelect    0x0020  /* pSelect is correlated, not constant */


/*
** These macros can be used to test, set, or clear bits in the 
** Expr.flags field.
*/
#define ExprHasProperty(E,P)     (((E)->flags&(P))==(P))
#define ExprHasAnyProperty(E,P)  (((E)->flags&(P))!=0)
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
** list of "ID = expr" items in an UPDATE.  A list of expressions can
** also be used as the argument to a function, in which case the a.zName
** field is not used.
*/
struct ExprList {
  int nExpr;             /* Number of expressions on the list */
  int nAlloc;            /* Number of entries allocated below */
  int iECursor;          /* VDBE Cursor associated with this ExprList */
  struct ExprList_item {
    Expr *pExpr;           /* The list of expressions */
    char *zName;           /* Token associated with this expression */
    u8 sortOrder;          /* 1 for DESC or 0 for ASC */
    u8 isAgg;              /* True if this is an aggregate like count(*) */
    u8 done;               /* A flag to indicate when processing is finished */
  } *a;                  /* One entry for each expression */







<







852
853
854
855
856
857
858

859
860
861
862
863
864
865
** list of "ID = expr" items in an UPDATE.  A list of expressions can
** also be used as the argument to a function, in which case the a.zName
** field is not used.
*/
struct ExprList {
  int nExpr;             /* Number of expressions on the list */
  int nAlloc;            /* Number of entries allocated below */

  struct ExprList_item {
    Expr *pExpr;           /* The list of expressions */
    char *zName;           /* Token associated with this expression */
    u8 sortOrder;          /* 1 for DESC or 0 for ASC */
    u8 isAgg;              /* True if this is an aggregate like count(*) */
    u8 done;               /* A flag to indicate when processing is finished */
  } *a;                  /* One entry for each expression */
1036
1037
1038
1039
1040
1041
1042


1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
** column names after a table name in an INSERT statement.  In the statement
**
**     INSERT INTO t(a,b,c) ...
**
** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
*/
struct IdList {


  struct IdList_item {
    char *zName;      /* Name of the identifier */
    int idx;          /* Index in some Table.aCol[] of a column named zName */
  } *a;
  int nId;         /* Number of identifiers on the list */
  int nAlloc;      /* Number of entries allocated for a[] below */
};

/*
** The bitmask datatype defined below is used for various optimizations.
*/
typedef unsigned int Bitmask;








>
>




<
<







877
878
879
880
881
882
883
884
885
886
887
888
889


890
891
892
893
894
895
896
** column names after a table name in an INSERT statement.  In the statement
**
**     INSERT INTO t(a,b,c) ...
**
** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
*/
struct IdList {
  int nId;         /* Number of identifiers on the list */
  int nAlloc;      /* Number of entries allocated for a[] below */
  struct IdList_item {
    char *zName;      /* Name of the identifier */
    int idx;          /* Index in some Table.aCol[] of a column named zName */
  } *a;


};

/*
** The bitmask datatype defined below is used for various optimizations.
*/
typedef unsigned int Bitmask;

1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108

1109
1110
1111
1112

1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
  i16 nAlloc;      /* Number of entries allocated in a[] below */
  struct SrcList_item {
    char *zDatabase;  /* Name of database holding this table */
    char *zName;      /* Name of the table */
    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
    Table *pTab;      /* An SQL table corresponding to zName */
    Select *pSelect;  /* A SELECT statement used in place of a table name */
    u8 jointype;      /* Type of join between this table and the next */
    i16 iCursor;      /* The VDBE cursor number used to access this table */
    Expr *pOn;        /* The ON clause of a join */
    IdList *pUsing;   /* The USING clause of a join */
    Bitmask colUsed;  /* Bit N (1<<N) set if column N or pTab is used */
  } a[1];             /* One entry for each identifier on the list */
};

/*
** Permitted values of the SrcList.a.jointype field
*/
#define JT_INNER     0x0001    /* Any kind of inner or cross join */
#define JT_CROSS     0x0002    /* Explicit use of the CROSS keyword */
#define JT_NATURAL   0x0004    /* True for a "natural" join */
#define JT_LEFT      0x0008    /* Left outer join */
#define JT_RIGHT     0x0010    /* Right outer join */
#define JT_OUTER     0x0020    /* The "OUTER" keyword is present */
#define JT_ERROR     0x0040    /* unknown or unsupported join type */

/*
** For each nested loop in a WHERE clause implementation, the WhereInfo
** structure contains a single instance of this structure.  This structure
** is intended to be private the the where.c module and should not be
** access or modified by other modules.
*/
struct WhereLevel {
  int iFrom;            /* Which entry in the FROM clause */
  int flags;            /* Flags associated with this level */
  int iMem;             /* First memory cell used by this level */
  int iLeftJoin;        /* Memory cell used to implement LEFT OUTER JOIN */
  Index *pIdx;          /* Index used.  NULL if no index */
  int iTabCur;          /* The VDBE cursor used to access the table */
  int iIdxCur;          /* The VDBE cursor used to acesss pIdx */

  int brk;              /* Jump here to break out of the loop */
  int cont;             /* Jump here to continue with the next loop cycle */
  int top;              /* First instruction of interior of the loop */
  int op, p1, p2;       /* Opcode used to terminate the loop */

  int nEq;              /* Number of == or IN constraints on this loop */
  int nIn;              /* Number of IN operators constraining this loop */
  int *aInLoop;         /* Loop terminators for IN operators */
};

/*
** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
** this structure is returned by the first half and passed







|
|










<
|
|
|
|
|








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







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

929
930
931
932
933
934
935
936
937
938
939
940
941


942

943
944
945
946
947
948

949
950
951
952
953
954
955
956
957
958
959
960
  i16 nAlloc;      /* Number of entries allocated in a[] below */
  struct SrcList_item {
    char *zDatabase;  /* Name of database holding this table */
    char *zName;      /* Name of the table */
    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
    Table *pTab;      /* An SQL table corresponding to zName */
    Select *pSelect;  /* A SELECT statement used in place of a table name */
    int jointype;     /* Type of join between this table and the next */
    int iCursor;      /* The VDBE cursor number used to access this table */
    Expr *pOn;        /* The ON clause of a join */
    IdList *pUsing;   /* The USING clause of a join */
    Bitmask colUsed;  /* Bit N (1<<N) set if column N or pTab is used */
  } a[1];             /* One entry for each identifier on the list */
};

/*
** Permitted values of the SrcList.a.jointype field
*/
#define JT_INNER     0x0001    /* Any kind of inner or cross join */

#define JT_NATURAL   0x0002    /* True for a "natural" join */
#define JT_LEFT      0x0004    /* Left outer join */
#define JT_RIGHT     0x0008    /* Right outer join */
#define JT_OUTER     0x0010    /* The "OUTER" keyword is present */
#define JT_ERROR     0x0020    /* unknown or unsupported join type */

/*
** For each nested loop in a WHERE clause implementation, the WhereInfo
** structure contains a single instance of this structure.  This structure
** is intended to be private the the where.c module and should not be
** access or modified by other modules.
*/
struct WhereLevel {


  int iMem;            /* Memory cell used by this level */

  Index *pIdx;         /* Index used.  NULL if no index */
  int iTabCur;         /* The VDBE cursor used to access the table */
  int iIdxCur;         /* The VDBE cursor used to acesss pIdx */
  int score;           /* How well this index scored */
  int brk;             /* Jump here to break out of the loop */
  int cont;            /* Jump here to continue with the next loop cycle */

  int op, p1, p2;      /* Opcode used to terminate the loop */
  int iLeftJoin;       /* Memory cell used to implement LEFT OUTER JOIN */
  int top;             /* First instruction of interior of the loop */
  int inOp, inP1, inP2;/* Opcode used to implement an IN operator */
  int bRev;            /* Do the scan in the reverse direction */
};

/*
** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
** this structure is returned by the first half and passed
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208



1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223


1224


1225
1226
1227

























1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264

1265
1266
1267

1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285



1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321


1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
struct NameContext {
  Parse *pParse;       /* The parser */
  SrcList *pSrcList;   /* One or more tables used to resolve names */
  ExprList *pEList;    /* Optional list of named expressions */
  int nRef;            /* Number of names resolved by this context */
  int nErr;            /* Number of errors encountered while resolving names */
  u8 allowAgg;         /* Aggregate functions allowed here */
  u8 hasAgg;           /* True if aggregates are seen */
  u8 isCheck;          /* True if resolving names in a CHECK constraint */
  int nDepth;          /* Depth of subquery recursion. 1 for no recursion */
  AggInfo *pAggInfo;   /* Information about aggregates at this level */
  NameContext *pNext;  /* Next outer name context.  NULL for outermost */
};

/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause.  nOffset is set to 0.
** If there is a LIMIT clause, the parser sets nLimit to the value of the
** limit and nOffset to the value of the offset (or 0 if there is not
** offset).  But later on, nLimit and nOffset become the memory locations
** in the VDBE that record the limit and offset counters.
**
** addrOpenVirt[] entries contain the address of OP_OpenVirtual opcodes.
** These addresses must be stored so that we can go back and fill in
** the P3_KEYINFO and P2 parameters later.  Neither the KeyInfo nor
** the number of columns in P2 can be computed at the same time
** as the OP_OpenVirtual instruction is coded because not
** enough information about the compound query is known at that point.
** The KeyInfo for addrOpenVirt[0] and [1] contains collating sequences
** for the result set.  The KeyInfo for addrOpenVirt[2] contains collating
** sequences for the ORDER BY clause.
*/
struct Select {
  ExprList *pEList;      /* The fields of the result */
  u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
  u8 isDistinct;         /* True if the DISTINCT keyword is present */
  u8 isResolved;         /* True once sqlite3SelectResolve() has run. */
  u8 isAgg;              /* True if this is an aggregate query */
  u8 usesVirt;           /* True if uses an OpenVirtual opcode */
  u8 disallowOrderBy;    /* Do not allow an ORDER BY to be attached if TRUE */
  SrcList *pSrc;         /* The FROM clause */
  Expr *pWhere;          /* The WHERE clause */
  ExprList *pGroupBy;    /* The GROUP BY clause */
  Expr *pHaving;         /* The HAVING clause */
  ExprList *pOrderBy;    /* The ORDER BY clause */
  Select *pPrior;        /* Prior select in a compound select statement */
  Select *pRightmost;    /* Right-most select in a compound select statement */
  Expr *pLimit;          /* LIMIT expression. NULL means not used. */
  Expr *pOffset;         /* OFFSET expression. NULL means not used. */
  int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
  int addrOpenVirt[3];   /* OP_OpenVirtual opcodes related to this select */



};

/*
** The results of a select can be distributed in several ways.
*/
#define SRT_Union        1  /* Store result as keys in an index */
#define SRT_Except       2  /* Remove result from a UNION index */
#define SRT_Discard      3  /* Do not save the results anywhere */

/* The ORDER BY clause is ignored for all of the above */
#define IgnorableOrderby(X) (X<=SRT_Discard)

#define SRT_Callback     4  /* Invoke a callback with each row of result */
#define SRT_Mem          5  /* Store result in a memory cell */
#define SRT_Set          6  /* Store non-null results as keys in an index */


#define SRT_Table        7  /* Store result as data with an automatic rowid */


#define SRT_VirtualTab   8  /* Create virtual table and store like SRT_Table */
#define SRT_Subroutine   9  /* Call a subroutine to handle results */
#define SRT_Exists      10  /* Store 1 if the result is not empty */


























/*
** An SQL parser context.  A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.
**
** The structure is divided into two parts.  When the parser and code
** generate call themselves recursively, the first part of the structure
** is constant but the second part is reset at the beginning and end of
** each recursion.
**
** The nTableLock and aTableLock variables are only used if the shared-cache 
** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are
** used to store the set of table-locks required by the statement being
** compiled. Function sqlite3TableLock() is used to add entries to the
** list.
*/
struct Parse {
  sqlite3 *db;         /* The main database structure */
  int rc;              /* Return code from execution */
  char *zErrMsg;       /* An error message */
  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
  u8 nameClash;        /* A permanent table name clashes with temp table name */
  u8 checkSchema;      /* Causes schema cookie check after an error */
  u8 nested;           /* Number of nested calls to the parser/code generator */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int ckOffset;        /* Stack offset to data used by CHECK constraints */
  u32 writeMask;       /* Start a write transaction on these databases */
  u32 cookieMask;      /* Bitmask of schema verified databases */
  ThreadData *pTsd;    /* Thread specific data for this thread */
  int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  int cookieValue[MAX_ATTACHED+2];  /* Values of cookies to verify */
#ifndef SQLITE_OMIT_SHARED_CACHE

  int nTableLock;        /* Number of locks in aTableLock */
  TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif


  /* Above is constant between recursions.  Below is reset before and after
  ** each recursion */

  int nVar;            /* Number of '?' variables seen in the SQL so far */
  int nVarExpr;        /* Number of used slots in apVarExpr[] */
  int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
  Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */
  u8 explain;          /* True if the EXPLAIN flag is found on the query */
  Token sErrToken;     /* The token at which the error occurred */
  Token sNameToken;    /* Token with unqualified schema object name */
  Token sLastToken;    /* The last token parsed */
  const char *zSql;    /* All SQL text */
  const char *zTail;   /* All SQL text past the last semicolon parsed */
  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  TriggerStack *trigStack;  /* Trigger actions being coded */
  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */



};

/*
** An instance of the following structure can be declared on a stack and used
** to save the Parse.zAuthContext value so that it can be restored later.
*/
struct AuthContext {
  const char *zAuthContext;   /* Put saved Parse.zAuthContext here */
  Parse *pParse;              /* The Parse structure */
};

/*
** Bitfield flags for P2 value in OP_Insert and OP_Delete
*/
#define OPFLAG_NCHANGE   1    /* Set to update db->nChange */
#define OPFLAG_LASTROWID 2    /* Set to update db->lastRowid */
#define OPFLAG_ISUPDATE  4    /* This OP_Insert is an sql UPDATE */

/*
 * Each trigger present in the database schema is stored as an instance of
 * struct Trigger. 
 *
 * Pointers to instances of struct Trigger are stored in two ways.
 * 1. In the "trigHash" hash table (part of the sqlite3* that represents the 
 *    database). This allows Trigger structures to be retrieved by name.
 * 2. All triggers associated with a single table form a linked list, using the
 *    pNext member of struct Trigger. A pointer to the first element of the
 *    linked list is stored as the "pTrigger" member of the associated
 *    struct Table.
 *
 * The "step_list" member points to the first element of a linked list
 * containing the SQL statements specified as the trigger program.
 */
struct Trigger {
  char *name;             /* The name of the trigger                        */
  char *table;            /* The table or view to which the trigger applies */


  u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
  u8 tr_tm;               /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
  Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
  IdList *pColumns;       /* If this is an UPDATE OF <column-list> trigger,
                             the <column-list> is stored here */
  int foreach;            /* One of TK_ROW or TK_STATEMENT */
  Token nameToken;        /* Token containing zName. Use during parsing only */
  Schema *pSchema;        /* Schema containing the trigger */
  Schema *pTabSchema;     /* Schema containing the table */
  TriggerStep *step_list; /* Link list of trigger program steps             */
  Trigger *pNext;         /* Next trigger associated with the table */
};

/*
** A trigger is either a BEFORE or an AFTER trigger.  The following constants
** determine which. 







|
<

<












<
<
<
<
<
<
<
<
<
<





<
<
<
<






<



|
>
>
>





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










<
<
<
<
<
<














<
<

<
<

<
>
|
<
<
>


















>
>
>












|



<



















>
>







|
<







994
995
996
997
998
999
1000
1001

1002

1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014










1015
1016
1017
1018
1019




1020
1021
1022
1023
1024
1025

1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037







1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083






1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097


1098


1099

1100
1101


1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139

1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168

1169
1170
1171
1172
1173
1174
1175
struct NameContext {
  Parse *pParse;       /* The parser */
  SrcList *pSrcList;   /* One or more tables used to resolve names */
  ExprList *pEList;    /* Optional list of named expressions */
  int nRef;            /* Number of names resolved by this context */
  int nErr;            /* Number of errors encountered while resolving names */
  u8 allowAgg;         /* Aggregate functions allowed here */
  u8 hasAgg;

  int nDepth;          /* Depth of subquery recursion. 1 for no recursion */

  NameContext *pNext;  /* Next outer name context.  NULL for outermost */
};

/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause.  nOffset is set to 0.
** If there is a LIMIT clause, the parser sets nLimit to the value of the
** limit and nOffset to the value of the offset (or 0 if there is not
** offset).  But later on, nLimit and nOffset become the memory locations
** in the VDBE that record the limit and offset counters.










*/
struct Select {
  ExprList *pEList;      /* The fields of the result */
  u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
  u8 isDistinct;         /* True if the DISTINCT keyword is present */




  SrcList *pSrc;         /* The FROM clause */
  Expr *pWhere;          /* The WHERE clause */
  ExprList *pGroupBy;    /* The GROUP BY clause */
  Expr *pHaving;         /* The HAVING clause */
  ExprList *pOrderBy;    /* The ORDER BY clause */
  Select *pPrior;        /* Prior select in a compound select statement */

  Expr *pLimit;          /* LIMIT expression. NULL means not used. */
  Expr *pOffset;         /* OFFSET expression. NULL means not used. */
  int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
  IdList **ppOpenTemp;   /* OP_OpenTemp addresses used by multi-selects */
  Fetch *pFetch;         /* If this stmt is part of a FETCH command */
  u8 isResolved;         /* True once sqlite3SelectResolve() has run. */
  u8 isAgg;              /* True if this is an aggregate query */
};

/*
** The results of a select can be distributed in several ways.
*/







#define SRT_Callback     1  /* Invoke a callback with each row of result */
#define SRT_Mem          2  /* Store result in a memory cell */
#define SRT_Set          3  /* Store result as unique keys in a table */
#define SRT_Union        5  /* Store result as keys in a table */
#define SRT_Except       6  /* Remove result from a UNION table */
#define SRT_Table        7  /* Store result as data with a unique key */
#define SRT_TempTable    8  /* Store result in a trasient table */
#define SRT_Discard      9  /* Do not save the results anywhere */
#define SRT_Sorter      10  /* Store results in the sorter */
#define SRT_Subroutine  11  /* Call a subroutine to handle results */
#define SRT_Exists      12  /* Put 0 or 1 in a memory cell */

/*
** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")
** we have to do some additional analysis of expressions.  An instance
** of the following structure holds information about a single subexpression
** somewhere in the SELECT statement.  An array of these structures holds
** all the information we need to generate code for aggregate
** expressions.
**
** Note that when analyzing a SELECT containing aggregates, both
** non-aggregate field variables and aggregate functions are stored
** in the AggExpr array of the Parser structure.
**
** The pExpr field points to an expression that is part of either the
** field list, the GROUP BY clause, the HAVING clause or the ORDER BY
** clause.  The expression will be freed when those clauses are cleaned
** up.  Do not try to delete the expression attached to AggExpr.pExpr.
**
** If AggExpr.pExpr==0, that means the expression is "count(*)".
*/
struct AggExpr {
  int isAgg;        /* if TRUE contains an aggregate function */
  Expr *pExpr;      /* The expression */
  FuncDef *pFunc;   /* Information about the aggregate function */
};

/*
** An SQL parser context.  A copy of this structure is passed through
** the parser and down into all the parser action routine in order to
** carry around information that is global to the entire parse.
**
** The structure is divided into two parts.  When the parser and code
** generate call themselves recursively, the first part of the structure
** is constant but the second part is reset at the beginning and end of
** each recursion.






*/
struct Parse {
  sqlite3 *db;         /* The main database structure */
  int rc;              /* Return code from execution */
  char *zErrMsg;       /* An error message */
  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
  u8 nameClash;        /* A permanent table name clashes with temp table name */
  u8 checkSchema;      /* Causes schema cookie check after an error */
  u8 nested;           /* Number of nested calls to the parser/code generator */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */


  u32 cookieMask;      /* Bitmask of schema verified databases */


  int cookieValue[MAX_ATTACHED+2];  /* Values of cookies to verify */

  int cookieGoto;      /* Address of OP_Goto to cookie verifier subroutine */
  u32 writeMask;       /* Start a write transaction on these databases */


  u8 fillAgg;          /* If true, ignore the Expr.iAgg field. Normally false */

  /* Above is constant between recursions.  Below is reset before and after
  ** each recursion */

  int nVar;            /* Number of '?' variables seen in the SQL so far */
  int nVarExpr;        /* Number of used slots in apVarExpr[] */
  int nVarExprAlloc;   /* Number of allocated slots in apVarExpr[] */
  Expr **apVarExpr;    /* Pointers to :aaa and $aaaa wildcard expressions */
  u8 explain;          /* True if the EXPLAIN flag is found on the query */
  Token sErrToken;     /* The token at which the error occurred */
  Token sNameToken;    /* Token with unqualified schema object name */
  Token sLastToken;    /* The last token parsed */
  const char *zSql;    /* All SQL text */
  const char *zTail;   /* All SQL text past the last semicolon parsed */
  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
  Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
  TriggerStack *trigStack;  /* Trigger actions being coded */
  const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
  int nAgg;            /* Number of aggregate expressions */
  AggExpr *aAgg;       /* An array of aggregate expressions */
  int nMaxDepth;       /* Maximum depth of subquery recursion */
};

/*
** An instance of the following structure can be declared on a stack and used
** to save the Parse.zAuthContext value so that it can be restored later.
*/
struct AuthContext {
  const char *zAuthContext;   /* Put saved Parse.zAuthContext here */
  Parse *pParse;              /* The Parse structure */
};

/*
** Bitfield flags for P2 value in OP_PutIntKey and OP_Delete
*/
#define OPFLAG_NCHANGE   1    /* Set to update db->nChange */
#define OPFLAG_LASTROWID 2    /* Set to update db->lastRowid */


/*
 * Each trigger present in the database schema is stored as an instance of
 * struct Trigger. 
 *
 * Pointers to instances of struct Trigger are stored in two ways.
 * 1. In the "trigHash" hash table (part of the sqlite3* that represents the 
 *    database). This allows Trigger structures to be retrieved by name.
 * 2. All triggers associated with a single table form a linked list, using the
 *    pNext member of struct Trigger. A pointer to the first element of the
 *    linked list is stored as the "pTrigger" member of the associated
 *    struct Table.
 *
 * The "step_list" member points to the first element of a linked list
 * containing the SQL statements specified as the trigger program.
 */
struct Trigger {
  char *name;             /* The name of the trigger                        */
  char *table;            /* The table or view to which the trigger applies */
  u8 iDb;                 /* Database containing this trigger               */
  u8 iTabDb;              /* Database containing Trigger.table              */
  u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
  u8 tr_tm;               /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
  Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
  IdList *pColumns;       /* If this is an UPDATE OF <column-list> trigger,
                             the <column-list> is stored here */
  int foreach;            /* One of TK_ROW or TK_STATEMENT */
  Token nameToken;        /* Token containing zName. Use during parsing only */


  TriggerStep *step_list; /* Link list of trigger program steps             */
  Trigger *pNext;         /* Next trigger associated with the table */
};

/*
** A trigger is either a BEFORE or an AFTER trigger.  The following constants
** determine which. 
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488







1489
1490
1491
1492
1493
1494
1495
1496

1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570

1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
/*
 * This global flag is set for performance testing of triggers. When it is set
 * SQLite will perform the overhead of building new and old trigger references 
 * even when no triggers exist
 */
extern int sqlite3_always_code_trigger_setup;

/*
** The SQLITE_CORRUPT_BKPT macro can be either a constant (for production
** builds) or a function call (for debugging).  If it is a function call,
** it allows the operator to set a breakpoint at the spot where database
** corruption is first detected.
*/
#ifdef SQLITE_DEBUG
  extern int sqlite3Corrupt(void);
# define SQLITE_CORRUPT_BKPT sqlite3Corrupt()
#else
# define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT
#endif

/*
** Internal function prototypes
*/
int sqlite3StrICmp(const char *, const char *);
int sqlite3StrNICmp(const char *, const char *, int);
int sqlite3HashNoCase(const char *, int);
int sqlite3IsNumber(const char*, int*, u8);
int sqlite3Compare(const char *, const char *);
int sqlite3SortCompare(const char *, const char *);
void sqlite3RealToSortable(double r, char *);








void *sqlite3Malloc(int);
void *sqlite3MallocRaw(int);
void sqlite3Free(void*);
void *sqlite3Realloc(void*,int);
char *sqlite3StrDup(const char*);
char *sqlite3StrNDup(const char*, int);
# define sqlite3CheckMemory(a,b)
void sqlite3ReallocOrFree(void**,int);

void sqlite3FreeX(void*);
void *sqlite3MallocX(int);
int sqlite3AllocSize(void *);

char *sqlite3MPrintf(const char*, ...);
char *sqlite3VMPrintf(const char*, va_list);
void sqlite3DebugPrintf(const char*, ...);
void *sqlite3TextToPtr(const char*);
void sqlite3SetString(char **, ...);
void sqlite3ErrorMsg(Parse*, const char*, ...);
void sqlite3ErrorClear(Parse*);
void sqlite3Dequote(char*);
void sqlite3DequoteExpr(Expr*);
int sqlite3KeywordCode(const unsigned char*, int);
int sqlite3RunParser(Parse*, const char*, char **);
void sqlite3FinishCoding(Parse*);
Expr *sqlite3Expr(int, Expr*, Expr*, const Token*);
Expr *sqlite3RegisterExpr(Parse*,Token*);
Expr *sqlite3ExprAnd(Expr*, Expr*);
void sqlite3ExprSpan(Expr*,Token*,Token*);
Expr *sqlite3ExprFunction(ExprList*, Token*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*);
void sqlite3ExprDelete(Expr*);
ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
void sqlite3ExprListDelete(ExprList*);
int sqlite3Init(sqlite3*, char**);
int sqlite3InitCallback(void*, int, char**, char**);
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
void sqlite3ResetInternalSchema(sqlite3*, int);
void sqlite3BeginParse(Parse*,int);
void sqlite3RollbackInternalChanges(sqlite3*);
void sqlite3CommitInternalChanges(sqlite3*);
Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
void sqlite3OpenMasterTable(Parse *, int);
void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int,int);
void sqlite3AddColumn(Parse*,Token*);
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
void sqlite3AddCheckConstraint(Parse*, Expr*);
void sqlite3AddColumnType(Parse*,Token*);
void sqlite3AddDefaultValue(Parse*,Expr*);
void sqlite3AddCollateType(Parse*, const char*, int);
void sqlite3EndTable(Parse*,Token*,Token*,Select*);

#ifndef SQLITE_OMIT_VIEW
  void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int);
  int sqlite3ViewGetColumnNames(Parse*,Table*);
#else
# define sqlite3ViewGetColumnNames(A,B) 0
#endif

void sqlite3DropTable(Parse*, SrcList*, int, int);
void sqlite3DeleteTable(sqlite3*, Table*);
void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
int sqlite3ArrayAllocate(void**,int,int);
IdList *sqlite3IdListAppend(IdList*, Token*);
int sqlite3IdListIndex(IdList*,const char*);
SrcList *sqlite3SrcListAppend(SrcList*, Token*, Token*);
void sqlite3SrcListAddAlias(SrcList*, Token*);
void sqlite3SrcListAssignCursors(Parse*, SrcList*);
void sqlite3IdListDelete(IdList*);
void sqlite3SrcListDelete(SrcList*);
void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                        Token*, int, int);
void sqlite3DropIndex(Parse*, SrcList*, int);
void sqlite3AddKeyType(Vdbe*, ExprList*);
void sqlite3AddIdxKeyType(Vdbe*, Index*);
int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff);
Select *sqlite3SelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
                        int,Expr*,Expr*);
void sqlite3SelectDelete(Select*);
void sqlite3SelectUnbind(Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);

void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**);
void sqlite3WhereEnd(WhereInfo*);
void sqlite3ExprCode(Parse*, Expr*);
void sqlite3ExprCodeAndCache(Parse*, Expr*);
int sqlite3ExprCodeExprList(Parse*, ExprList*);
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
void sqlite3NextedParse(Parse*, const char*, ...);
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
Table *sqlite3LocateTable(Parse*,const char*, const char*);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
void sqlite3Vacuum(Parse*, Token*);
int sqlite3RunVacuum(char**, sqlite3*);
char *sqlite3NameFromToken(Token*);
int sqlite3ExprCheck(Parse*, Expr*, int, int*);
int sqlite3ExprCompare(Expr*, Expr*);
int sqliteFuncId(Token*);
int sqlite3ExprResolveNames(NameContext *, Expr *);
int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
int sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
Vdbe *sqlite3GetVdbe(Parse*);
void sqlite3Randomness(int, void*);
void sqlite3RollbackAll(sqlite3*);
void sqlite3CodeVerifySchema(Parse*, int);
void sqlite3BeginTransaction(Parse*, int);
void sqlite3CommitTransaction(Parse*);
void sqlite3RollbackTransaction(Parse*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int);
void sqlite3GenerateRowIndexDelete(sqlite3*, Vdbe*, Table*, int, char*);
void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);







<
<
<
<
<
<
<
<
<
<
<
<
<










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

<
>

<
<
<




|

<

<
|



















|
|


|
<
|


|








|


<








|
|









>
|


|




















<








<







1296
1297
1298
1299
1300
1301
1302













1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327

1328
1329



1330
1331
1332
1333
1334
1335

1336

1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361

1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376

1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420

1421
1422
1423
1424
1425
1426
1427
1428

1429
1430
1431
1432
1433
1434
1435
/*
 * This global flag is set for performance testing of triggers. When it is set
 * SQLite will perform the overhead of building new and old trigger references 
 * even when no triggers exist
 */
extern int sqlite3_always_code_trigger_setup;














/*
** Internal function prototypes
*/
int sqlite3StrICmp(const char *, const char *);
int sqlite3StrNICmp(const char *, const char *, int);
int sqlite3HashNoCase(const char *, int);
int sqlite3IsNumber(const char*, int*, u8);
int sqlite3Compare(const char *, const char *);
int sqlite3SortCompare(const char *, const char *);
void sqlite3RealToSortable(double r, char *);
#ifdef SQLITE_MEMDEBUG
  void *sqlite3Malloc_(int,int,char*,int);
  void sqlite3Free_(void*,char*,int);
  void *sqlite3Realloc_(void*,int,char*,int);
  char *sqlite3StrDup_(const char*,char*,int);
  char *sqlite3StrNDup_(const char*, int,char*,int);
  void sqlite3CheckMemory(void*,int);
#else
  void *sqlite3Malloc(int);
  void *sqlite3MallocRaw(int);
  void sqlite3Free(void*);
  void *sqlite3Realloc(void*,int);
  char *sqlite3StrDup(const char*);
  char *sqlite3StrNDup(const char*, int);
# define sqlite3CheckMemory(a,b)

#endif
void sqlite3FreeX(void*);



char *sqlite3MPrintf(const char*, ...);
char *sqlite3VMPrintf(const char*, va_list);
void sqlite3DebugPrintf(const char*, ...);
void *sqlite3TextToPtr(const char*);
void sqlite3SetString(char **, const char *, ...);
void sqlite3ErrorMsg(Parse*, const char*, ...);

void sqlite3Dequote(char*);

int sqlite3KeywordCode(const char*, int);
int sqlite3RunParser(Parse*, const char*, char **);
void sqlite3FinishCoding(Parse*);
Expr *sqlite3Expr(int, Expr*, Expr*, const Token*);
Expr *sqlite3RegisterExpr(Parse*,Token*);
Expr *sqlite3ExprAnd(Expr*, Expr*);
void sqlite3ExprSpan(Expr*,Token*,Token*);
Expr *sqlite3ExprFunction(ExprList*, Token*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*);
void sqlite3ExprDelete(Expr*);
ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
void sqlite3ExprListDelete(ExprList*);
int sqlite3Init(sqlite3*, char**);
int sqlite3InitCallback(void*, int, char**, char**);
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
void sqlite3ResetInternalSchema(sqlite3*, int);
void sqlite3BeginParse(Parse*,int);
void sqlite3RollbackInternalChanges(sqlite3*);
void sqlite3CommitInternalChanges(sqlite3*);
Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
void sqlite3OpenMasterTable(Vdbe *v, int);
void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);
void sqlite3AddColumn(Parse*,Token*);
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int);

void sqlite3AddColumnType(Parse*,Token*,Token*);
void sqlite3AddDefaultValue(Parse*,Expr*);
void sqlite3AddCollateType(Parse*, const char*, int);
void sqlite3EndTable(Parse*,Token*,Select*);

#ifndef SQLITE_OMIT_VIEW
  void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int);
  int sqlite3ViewGetColumnNames(Parse*,Table*);
#else
# define sqlite3ViewGetColumnNames(A,B) 0
#endif

void sqlite3DropTable(Parse*, SrcList*, int);
void sqlite3DeleteTable(sqlite3*, Table*);
void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);

IdList *sqlite3IdListAppend(IdList*, Token*);
int sqlite3IdListIndex(IdList*,const char*);
SrcList *sqlite3SrcListAppend(SrcList*, Token*, Token*);
void sqlite3SrcListAddAlias(SrcList*, Token*);
void sqlite3SrcListAssignCursors(Parse*, SrcList*);
void sqlite3IdListDelete(IdList*);
void sqlite3SrcListDelete(SrcList*);
void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                        Token*);
void sqlite3DropIndex(Parse*, SrcList*);
void sqlite3AddKeyType(Vdbe*, ExprList*);
void sqlite3AddIdxKeyType(Vdbe*, Index*);
int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff);
Select *sqlite3SelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
                        int,Expr*,Expr*);
void sqlite3SelectDelete(Select*);
void sqlite3SelectUnbind(Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);
void sqlite3OpenTableForReading(Vdbe*, int iCur, Table*);
void sqlite3OpenTable(Vdbe*, int iCur, Table*, int);
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, Fetch*);
void sqlite3WhereEnd(WhereInfo*);
void sqlite3ExprCode(Parse*, Expr*);
void sqlite3ExprCodeAndCache(Parse*, Expr*);
int sqlite3ExprCodeExprList(Parse*, ExprList*);
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
void sqlite3NextedParse(Parse*, const char*, ...);
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
Table *sqlite3LocateTable(Parse*,const char*, const char*);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
void sqlite3Vacuum(Parse*, Token*);
int sqlite3RunVacuum(char**, sqlite3*);
char *sqlite3NameFromToken(Token*);
int sqlite3ExprCheck(Parse*, Expr*, int, int*);
int sqlite3ExprCompare(Expr*, Expr*);
int sqliteFuncId(Token*);
int sqlite3ExprResolveNames(NameContext *, Expr *);
int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);

Vdbe *sqlite3GetVdbe(Parse*);
void sqlite3Randomness(int, void*);
void sqlite3RollbackAll(sqlite3*);
void sqlite3CodeVerifySchema(Parse*, int);
void sqlite3BeginTransaction(Parse*, int);
void sqlite3CommitTransaction(Parse*);
void sqlite3RollbackTransaction(Parse*);
int sqlite3ExprIsConstant(Expr*);

int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int);
void sqlite3GenerateRowIndexDelete(sqlite3*, Vdbe*, Table*, int, char*);
void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
  void sqlite3AuthContextPop(AuthContext*);
#else
# define sqlite3AuthRead(a,b,c)
# define sqlite3AuthCheck(a,b,c,d,e)    SQLITE_OK
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a)  ((void)(a))
#endif
void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
void sqlite3Detach(Parse*, Expr*);
int sqlite3BtreeFactory(const sqlite3 *db, const char *zFilename,
                       int omitJournal, int nCache, Btree **ppBtree);
int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
int sqlite3AtoF(const char *z, double*);
char *sqlite3_snprintf(int,char*,const char*,...);
int sqlite3GetInt32(const char *, int*);
int sqlite3FitsIn64Bits(const char *);
int sqlite3utf16ByteLen(const void *pData, int nChar);
int sqlite3utf8CharLen(const char *pData, int nByte);
int sqlite3ReadUtf8(const unsigned char *);
int sqlite3PutVarint(unsigned char *, u64);







|
|








|







1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
  void sqlite3AuthContextPop(AuthContext*);
#else
# define sqlite3AuthRead(a,b,c)
# define sqlite3AuthCheck(a,b,c,d,e)    SQLITE_OK
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a)  ((void)(a))
#endif
void sqlite3Attach(Parse*, Token*, Token*, int, Token*);
void sqlite3Detach(Parse*, Token*);
int sqlite3BtreeFactory(const sqlite3 *db, const char *zFilename,
                       int omitJournal, int nCache, Btree **ppBtree);
int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
double sqlite3AtoF(const char *z, const char **);
char *sqlite3_snprintf(int,char*,const char*,...);
int sqlite3GetInt32(const char *, int*);
int sqlite3FitsIn64Bits(const char *);
int sqlite3utf16ByteLen(const void *pData, int nChar);
int sqlite3utf8CharLen(const char *pData, int nByte);
int sqlite3ReadUtf8(const unsigned char *);
int sqlite3PutVarint(unsigned char *, u64);
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
void sqlite3VdbeSetChanges(sqlite3 *, int);
void sqlite3utf16Substr(sqlite3_context *,int,sqlite3_value **);

const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3_value*, u8);
void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*));
void sqlite3ValueFree(sqlite3_value*);
sqlite3_value *sqlite3ValueNew(void);
char *sqlite3utf16to8(const void*, int);
int sqlite3ValueFromExpr(Expr *, u8, u8, sqlite3_value **);
void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
extern const unsigned char sqlite3UpperToLower[];
void sqlite3RootPageMoved(Db*, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(sqlite3*);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
void sqlite3CodeSubselect(Parse *, Expr *);
int sqlite3SelectResolve(Parse *, Select *, NameContext *);
void sqlite3ColumnDefault(Vdbe *, Table *, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
const char *sqlite3TestErrorName(int);
CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int);
char sqlite3AffinityType(const Token*);
void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*);
int sqlite3FindDb(sqlite3*, Token*);
void sqlite3AnalysisLoad(sqlite3*,int iDB);
void sqlite3DefaultRowEst(Index*);
void sqlite3RegisterLikeFunctions(sqlite3*, int);
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
ThreadData *sqlite3ThreadData(void);
const ThreadData *sqlite3ThreadDataReadOnly(void);
void sqlite3ReleaseThreadData(void);
void sqlite3AttachFunctions(sqlite3 *);
void sqlite3MinimumFileFormat(Parse*, int, int);
void sqlite3SchemaFree(void *);
Schema *sqlite3SchemaGet(Btree *);
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);

#ifndef SQLITE_OMIT_SHARED_CACHE
  void sqlite3TableLock(Parse *, int, int, u8, const char *);
#else
  #define sqlite3TableLock(v,w,x,y,z)
#endif

void sqlite3MallocClearFailed();
#ifndef SQLITE_MEMDEBUG
  #define sqlite3MallocDisallow()
  #define sqlite3MallocAllow()
#else
  void sqlite3MallocDisallow();
  void sqlite3MallocAllow();
#endif

#ifdef SQLITE_SSE
#include "sseInt.h"
#endif

#endif







|
<
<
|










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1530
1531
1532
1533
1534
1535
1536
1537


1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548






















1549




1550















void sqlite3VdbeSetChanges(sqlite3 *, int);
void sqlite3utf16Substr(sqlite3_context *,int,sqlite3_value **);

const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3_value*, u8);
void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*));
void sqlite3ValueFree(sqlite3_value*);
sqlite3_value *sqlite3ValueNew();


sqlite3_value *sqlite3GetTransientValue(sqlite3*db);
extern const unsigned char sqlite3UpperToLower[];
void sqlite3RootPageMoved(Db*, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(sqlite3*);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
void sqlite3CodeSubselect(Parse *, Expr *);
int sqlite3SelectResolve(Parse *, Select *, NameContext *);



























#endif















Changes to SQLite.Interop/src/table.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
** This file contains the sqlite3_get_table() and sqlite3_free_table()
** interface routines.  These are just wrappers around the main
** interface routine of sqlite3_exec().
**
** These routines are in a separate files so that they will not be linked
** if they are not used.
*/
#include "sqliteInt.h"
#include <stdlib.h>
#include <string.h>

#ifndef SQLITE_OMIT_GET_TABLE

/*
** This structure is used to pass data from sqlite3_get_table() through
** to the callback function is uses to build the result.
*/
typedef struct TabResult {
  char **azResult;







<


|
<







12
13
14
15
16
17
18

19
20
21

22
23
24
25
26
27
28
** This file contains the sqlite3_get_table() and sqlite3_free_table()
** interface routines.  These are just wrappers around the main
** interface routine of sqlite3_exec().
**
** These routines are in a separate files so that they will not be linked
** if they are not used.
*/

#include <stdlib.h>
#include <string.h>
#include "sqliteInt.h"


/*
** This structure is used to pass data from sqlite3_get_table() through
** to the callback function is uses to build the result.
*/
typedef struct TabResult {
  char **azResult;
191
192
193
194
195
196
197
198
199
    azResult--;
    if( azResult==0 ) return;
    n = (int)azResult[0];
    for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
    free(azResult);
  }
}

#endif /* SQLITE_OMIT_GET_TABLE */







<
<
189
190
191
192
193
194
195


    azResult--;
    if( azResult==0 ) return;
    n = (int)azResult[0];
    for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
    free(azResult);
  }
}


Changes to SQLite.Interop/src/tclsqlite.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>

/*
 * Windows needs to know which symbols to export.  Unix does not.
 * BUILD_sqlite should be undefined for Unix.
 */

#ifdef BUILD_sqlite
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif /* BUILD_sqlite */

#define NUM_PREPARED_STMTS 10
#define MAX_PREPARED_STMTS 100

/*
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
** have to do a translation when going between the two.  Set the 













|









<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23











24
25
26
27
28
29
30
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.1 2005/03/01 16:04:36 rmsimpson Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>












#define NUM_PREPARED_STMTS 10
#define MAX_PREPARED_STMTS 100

/*
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
** have to do a translation when going between the two.  Set the 
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
** New SQL functions can be created as TCL scripts.  Each such function
** is described by an instance of the following structure.
*/
typedef struct SqlFunc SqlFunc;
struct SqlFunc {
  Tcl_Interp *interp;   /* The TCL interpret to execute the function */
  Tcl_Obj *pScript;     /* The Tcl_Obj representation of the script */
  int useEvalObjv;      /* True if it is safe to use Tcl_EvalObjv */
  char *zName;          /* Name of this function */
  SqlFunc *pNext;       /* Next function on the list of them all */
};

/*
** New collation sequences function can be created as TCL scripts.  Each such
** function is described by an instance of the following structure.
*/
typedef struct SqlCollate SqlCollate;
struct SqlCollate {
  Tcl_Interp *interp;   /* The TCL interpret to execute the function */
  char *zScript;        /* The script to be run */
  SqlCollate *pNext;    /* Next function on the list of them all */
};

/*
** Prepared statements are cached for faster execution.  Each prepared
** statement is described by an instance of the following structure.
*/
typedef struct SqlPreparedStmt SqlPreparedStmt;







|
<
<











|







38
39
40
41
42
43
44
45


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
** New SQL functions can be created as TCL scripts.  Each such function
** is described by an instance of the following structure.
*/
typedef struct SqlFunc SqlFunc;
struct SqlFunc {
  Tcl_Interp *interp;   /* The TCL interpret to execute the function */
  char *zScript;        /* The script to be run */


  SqlFunc *pNext;       /* Next function on the list of them all */
};

/*
** New collation sequences function can be created as TCL scripts.  Each such
** function is described by an instance of the following structure.
*/
typedef struct SqlCollate SqlCollate;
struct SqlCollate {
  Tcl_Interp *interp;   /* The TCL interpret to execute the function */
  char *zScript;        /* The script to be run */
  SqlCollate *pNext;       /* Next function on the list of them all */
};

/*
** Prepared statements are cached for faster execution.  Each prepared
** statement is described by an instance of the following structure.
*/
typedef struct SqlPreparedStmt SqlPreparedStmt;
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

/*
** There is one instance of this structure for each SQLite database
** that has been opened by the SQLite TCL interface.
*/
typedef struct SqliteDb SqliteDb;
struct SqliteDb {
  sqlite3 *db;               /* The "real" database structure. MUST BE FIRST */
  Tcl_Interp *interp;        /* The interpreter used for this database */
  char *zBusy;               /* The busy callback routine */
  char *zCommit;             /* The commit hook callback routine */
  char *zTrace;              /* The trace callback routine */
  char *zProfile;            /* The profile callback routine */
  char *zProgress;           /* The progress callback routine */
  char *zAuth;               /* The authorization callback routine */
  char *zNull;               /* Text to substitute for an SQL NULL value */
  SqlFunc *pFunc;            /* List of SQL functions */
  Tcl_Obj *pUpdateHook;      /* Update hook script (if any) */
  Tcl_Obj *pRollbackHook;    /* Rollback hook script (if any) */
  SqlCollate *pCollate;      /* List of SQL collation functions */
  int rc;                    /* Return code of most recent sqlite3_exec() */
  Tcl_Obj *pCollateNeeded;   /* Collation needed script */
  SqlPreparedStmt *stmtList; /* List of prepared statements*/
  SqlPreparedStmt *stmtLast; /* Last statement in the list */
  int maxStmt;               /* The next maximum number of stmtList */
  int nStmt;                 /* Number of statements in stmtList */
};

/*
** Look at the script prefix in pCmd.  We will be executing this script
** after first appending one or more arguments.  This routine analyzes
** the script to see if it is safe to use Tcl_EvalObjv() on the script
** rather than the more general Tcl_EvalEx().  Tcl_EvalObjv() is much
** faster.
**
** Scripts that are safe to use with Tcl_EvalObjv() consists of a
** command name followed by zero or more arguments with no [...] or $
** or {...} or ; to be seen anywhere.  Most callback scripts consist
** of just a single procedure name and they meet this requirement.
*/
static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){
  /* We could try to do something with Tcl_Parse().  But we will instead
  ** just do a search for forbidden characters.  If any of the forbidden
  ** characters appear in pCmd, we will report the string as unsafe.
  */
  const char *z;
  int n;
  z = Tcl_GetStringFromObj(pCmd, &n);
  while( n-- > 0 ){
    int c = *(z++);
    if( c=='$' || c=='[' || c==';' ) return 0;
  }
  return 1;
}

/*
** Find an SqlFunc structure with the given name.  Or create a new
** one if an existing one cannot be found.  Return a pointer to the
** structure.
*/
static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
  SqlFunc *p, *pNew;
  int i;
  pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen(zName) + 1 );
  pNew->zName = (char*)&pNew[1];
  for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); }
  pNew->zName[i] = 0;
  for(p=pDb->pFunc; p; p=p->pNext){ 
    if( strcmp(p->zName, pNew->zName)==0 ){
      Tcl_Free((char*)pNew);
      return p;
    }
  }
  pNew->interp = pDb->interp;
  pNew->pScript = 0;
  pNew->pNext = pDb->pFunc;
  pDb->pFunc = pNew;
  return pNew;
}

/*
** Finalize and free a list of prepared statements
*/
static void flushStmtCache( SqliteDb *pDb ){
  SqlPreparedStmt *pPreStmt;

  while(  pDb->stmtList ){







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






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







72
73
74
75
76
77
78
79
80
81
82
83

84
85

86


87
88
89
90
91
92
93
94
95




















































96
97
98
99
100
101
102

/*
** There is one instance of this structure for each SQLite database
** that has been opened by the SQLite TCL interface.
*/
typedef struct SqliteDb SqliteDb;
struct SqliteDb {
  sqlite3 *db;          /* The "real" database structure */
  Tcl_Interp *interp;   /* The interpreter used for this database */
  char *zBusy;          /* The busy callback routine */
  char *zCommit;        /* The commit hook callback routine */
  char *zTrace;         /* The trace callback routine */

  char *zProgress;      /* The progress callback routine */
  char *zAuth;          /* The authorization callback routine */

  SqlFunc *pFunc;       /* List of SQL functions */


  SqlCollate *pCollate; /* List of SQL collation functions */
  int rc;               /* Return code of most recent sqlite3_exec() */
  Tcl_Obj *pCollateNeeded;  /* Collation needed script */
  SqlPreparedStmt *stmtList; /* List of prepared statements*/
  SqlPreparedStmt *stmtLast; /* Last statement in the list */
  int maxStmt;               /* The next maximum number of stmtList */
  int nStmt;                 /* Number of statements in stmtList */
};





















































/*
** Finalize and free a list of prepared statements
*/
static void flushStmtCache( SqliteDb *pDb ){
  SqlPreparedStmt *pPreStmt;

  while(  pDb->stmtList ){
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234


235


236


237

238
239
240
241
242
243
244
static void DbDeleteCmd(void *db){
  SqliteDb *pDb = (SqliteDb*)db;
  flushStmtCache(pDb);
  sqlite3_close(pDb->db);
  while( pDb->pFunc ){
    SqlFunc *pFunc = pDb->pFunc;
    pDb->pFunc = pFunc->pNext;
    Tcl_DecrRefCount(pFunc->pScript);
    Tcl_Free((char*)pFunc);
  }
  while( pDb->pCollate ){
    SqlCollate *pCollate = pDb->pCollate;
    pDb->pCollate = pCollate->pNext;
    Tcl_Free((char*)pCollate);
  }
  if( pDb->zBusy ){
    Tcl_Free(pDb->zBusy);
  }
  if( pDb->zTrace ){
    Tcl_Free(pDb->zTrace);
  }
  if( pDb->zProfile ){
    Tcl_Free(pDb->zProfile);
  }
  if( pDb->zAuth ){
    Tcl_Free(pDb->zAuth);
  }
  if( pDb->zNull ){
    Tcl_Free(pDb->zNull);
  }
  if( pDb->pUpdateHook ){
    Tcl_DecrRefCount(pDb->pUpdateHook);
  }
  if( pDb->pRollbackHook ){
    Tcl_DecrRefCount(pDb->pRollbackHook);
  }
  if( pDb->pCollateNeeded ){
    Tcl_DecrRefCount(pDb->pCollateNeeded);
  }
  Tcl_Free((char*)pDb);
}

/*
** This routine is called when a database file is locked while trying
** to execute SQL.
*/
static int DbBusyHandler(void *cd, int nTries){
  SqliteDb *pDb = (SqliteDb*)cd;
  int rc;
  char zVal[30];





  sprintf(zVal, "%d", nTries);


  rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0);

  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
    return 0;
  }
  return 1;
}

/*







<













<
<
<



<
<
<
<
<
<
<
<
<
<
<
<











>
>

>
>

>
>
|
>







116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135



136
137
138












139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
static void DbDeleteCmd(void *db){
  SqliteDb *pDb = (SqliteDb*)db;
  flushStmtCache(pDb);
  sqlite3_close(pDb->db);
  while( pDb->pFunc ){
    SqlFunc *pFunc = pDb->pFunc;
    pDb->pFunc = pFunc->pNext;

    Tcl_Free((char*)pFunc);
  }
  while( pDb->pCollate ){
    SqlCollate *pCollate = pDb->pCollate;
    pDb->pCollate = pCollate->pNext;
    Tcl_Free((char*)pCollate);
  }
  if( pDb->zBusy ){
    Tcl_Free(pDb->zBusy);
  }
  if( pDb->zTrace ){
    Tcl_Free(pDb->zTrace);
  }



  if( pDb->zAuth ){
    Tcl_Free(pDb->zAuth);
  }












  Tcl_Free((char*)pDb);
}

/*
** This routine is called when a database file is locked while trying
** to execute SQL.
*/
static int DbBusyHandler(void *cd, int nTries){
  SqliteDb *pDb = (SqliteDb*)cd;
  int rc;
  char zVal[30];
  char *zCmd;
  Tcl_DString cmd;

  Tcl_DStringInit(&cmd);
  Tcl_DStringAppend(&cmd, pDb->zBusy, -1);
  sprintf(zVal, "%d", nTries);
  Tcl_DStringAppendElement(&cmd, zVal);
  zCmd = Tcl_DStringValue(&cmd);
  rc = Tcl_Eval(pDb->interp, zCmd);
  Tcl_DStringFree(&cmd);
  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
    return 0;
  }
  return 1;
}

/*
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
  Tcl_DStringAppend(&str, pDb->zTrace, -1);
  Tcl_DStringAppendElement(&str, zSql);
  Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
  Tcl_DStringFree(&str);
  Tcl_ResetResult(pDb->interp);
}

/*
** This routine is called by the SQLite profile handler after a statement
** SQL has executed.  The TCL script in pDb->zProfile is evaluated.
*/
static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){
  SqliteDb *pDb = (SqliteDb*)cd;
  Tcl_DString str;
  char zTm[100];

  sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);
  Tcl_DStringInit(&str);
  Tcl_DStringAppend(&str, pDb->zProfile, -1);
  Tcl_DStringAppendElement(&str, zSql);
  Tcl_DStringAppendElement(&str, zTm);
  Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
  Tcl_DStringFree(&str);
  Tcl_ResetResult(pDb->interp);
}

/*
** This routine is called when a transaction is committed.  The
** TCL script in pDb->zCommit is executed.  If it returns non-zero or
** if it throws an exception, the transaction is rolled back instead
** of being committed.
*/
static int DbCommitHandler(void *cd){
  SqliteDb *pDb = (SqliteDb*)cd;
  int rc;

  rc = Tcl_Eval(pDb->interp, pDb->zCommit);
  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
    return 1;
  }
  return 0;
}

static void DbRollbackHandler(void *clientData){
  SqliteDb *pDb = (SqliteDb*)clientData;
  assert(pDb->pRollbackHook);
  if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){
    Tcl_BackgroundError(pDb->interp);
  }
}

static void DbUpdateHandler(
  void *p, 
  int op,
  const char *zDb, 
  const char *zTbl, 
  sqlite_int64 rowid
){
  SqliteDb *pDb = (SqliteDb *)p;
  Tcl_Obj *pCmd;

  assert( pDb->pUpdateHook );
  assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );

  pCmd = Tcl_DuplicateObj(pDb->pUpdateHook);
  Tcl_IncrRefCount(pCmd);
  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(
    ( (op==SQLITE_INSERT)?"INSERT":(op==SQLITE_UPDATE)?"UPDATE":"DELETE"), -1));
  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid));
  Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
}

static void tclCollateNeeded(
  void *pCtx,
  sqlite3 *db,
  int enc,
  const char *zName
){
  SqliteDb *pDb = (SqliteDb *)pCtx;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







190
191
192
193
194
195
196



















197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213































214
215
216
217
218
219
220
  Tcl_DStringAppend(&str, pDb->zTrace, -1);
  Tcl_DStringAppendElement(&str, zSql);
  Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
  Tcl_DStringFree(&str);
  Tcl_ResetResult(pDb->interp);
}




















/*
** This routine is called when a transaction is committed.  The
** TCL script in pDb->zCommit is executed.  If it returns non-zero or
** if it throws an exception, the transaction is rolled back instead
** of being committed.
*/
static int DbCommitHandler(void *cd){
  SqliteDb *pDb = (SqliteDb*)cd;
  int rc;

  rc = Tcl_Eval(pDb->interp, pDb->zCommit);
  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
    return 1;
  }
  return 0;
}
































static void tclCollateNeeded(
  void *pCtx,
  sqlite3 *db,
  int enc,
  const char *zName
){
  SqliteDb *pDb = (SqliteDb *)pCtx;
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
  SqlCollate *p = (SqlCollate *)pCtx;
  Tcl_Obj *pCmd;

  pCmd = Tcl_NewStringObj(p->zScript, -1);
  Tcl_IncrRefCount(pCmd);
  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
  Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
  Tcl_DecrRefCount(pCmd);
  return (atoi(Tcl_GetStringResult(p->interp)));
}

/*
** This routine is called to evaluate an SQL function implemented
** using TCL script.
*/
static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
  SqlFunc *p = sqlite3_user_data(context);
  Tcl_Obj *pCmd;
  int i;
  int rc;

  if( argc==0 ){
    /* If there are no arguments to the function, call Tcl_EvalObjEx on the
    ** script object directly.  This allows the TCL compiler to generate
    ** bytecode for the command on the first invocation and thus make
    ** subsequent invocations much faster. */
    pCmd = p->pScript;
    Tcl_IncrRefCount(pCmd);
    rc = Tcl_EvalObjEx(p->interp, pCmd, 0);
    Tcl_DecrRefCount(pCmd);
  }else{
    /* If there are arguments to the function, make a shallow copy of the
    ** script object, lappend the arguments, then evaluate the copy.
    **
    ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated.
    ** The new Tcl_Obj contains pointers to the original list elements. 
    ** That way, when Tcl_EvalObjv() is run and shimmers the first element
    ** of the list to tclCmdNameType, that alternate representation will
    ** be preserved and reused on the next invocation.
    */
    Tcl_Obj **aArg;
    int nArg;
    if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
      sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 
      return;
    }     
    pCmd = Tcl_NewListObj(nArg, aArg);
    Tcl_IncrRefCount(pCmd);
    for(i=0; i<argc; i++){
      sqlite3_value *pIn = argv[i];
      Tcl_Obj *pVal;
            
      /* Set pVal to contain the i'th column of this row. */
      switch( sqlite3_value_type(pIn) ){
        case SQLITE_BLOB: {
          int bytes = sqlite3_value_bytes(pIn);
          pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes);
          break;
        }
        case SQLITE_INTEGER: {
          sqlite_int64 v = sqlite3_value_int64(pIn);
          if( v>=-2147483647 && v<=2147483647 ){
            pVal = Tcl_NewIntObj(v);
          }else{
            pVal = Tcl_NewWideIntObj(v);
          }
          break;
        }
        case SQLITE_FLOAT: {
          double r = sqlite3_value_double(pIn);
          pVal = Tcl_NewDoubleObj(r);
          break;
        }
        case SQLITE_NULL: {
          pVal = Tcl_NewStringObj("", 0);
          break;
        }
        default: {
          int bytes = sqlite3_value_bytes(pIn);
          pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes);
          break;
        }
      }
      rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
      if( rc ){
        Tcl_DecrRefCount(pCmd);
        sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 
        return;
      }
    }
    if( !p->useEvalObjv ){
      /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd
      ** is a list without a string representation.  To prevent this from
      ** happening, make sure pCmd has a valid string representation */
      Tcl_GetString(pCmd);
    }
    rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
    Tcl_DecrRefCount(pCmd);
  }

  if( rc && rc!=TCL_RETURN ){
    sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 
  }else{
    Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
    int n;
    u8 *data;
    char *zType = pVar->typePtr ? pVar->typePtr->name : "";
    char c = zType[0];
    if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
      /* Only return a BLOB type if the Tcl variable is a bytearray and
      ** has no string representation. */
      data = Tcl_GetByteArrayFromObj(pVar, &n);
      sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
    }else if( (c=='b' && strcmp(zType,"boolean")==0) ||
          (c=='i' && strcmp(zType,"int")==0) ){
      Tcl_GetIntFromObj(0, pVar, &n);
      sqlite3_result_int(context, n);
    }else if( c=='d' && strcmp(zType,"double")==0 ){
      double r;
      Tcl_GetDoubleFromObj(0, pVar, &r);
      sqlite3_result_double(context, r);
    }else if( c=='w' && strcmp(zType,"wideInt")==0 ){
      Tcl_WideInt v;
      Tcl_GetWideIntFromObj(0, pVar, &v);
      sqlite3_result_int64(context, v);
    }else{
      data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
      sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
    }
  }
}

#ifndef SQLITE_OMIT_AUTHORIZATION
/*
** This is the authentication function.  It appends the authentication
** type code and the two arguments to zCmd[] then invokes the result







|










|



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

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







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260








261










262







263
264

265
























266

267


268
269
270
271

272















273
274








275
















276
277
278
279
280
281
282
  SqlCollate *p = (SqlCollate *)pCtx;
  Tcl_Obj *pCmd;

  pCmd = Tcl_NewStringObj(p->zScript, -1);
  Tcl_IncrRefCount(pCmd);
  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
  Tcl_EvalObjEx(p->interp, pCmd, 0);
  Tcl_DecrRefCount(pCmd);
  return (atoi(Tcl_GetStringResult(p->interp)));
}

/*
** This routine is called to evaluate an SQL function implemented
** using TCL script.
*/
static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
  SqlFunc *p = sqlite3_user_data(context);
  Tcl_DString cmd;
  int i;
  int rc;









  Tcl_DStringInit(&cmd);










  Tcl_DStringAppend(&cmd, p->zScript, -1);







  for(i=0; i<argc; i++){
    if( SQLITE_NULL==sqlite3_value_type(argv[i]) ){

      Tcl_DStringAppendElement(&cmd, "");
























    }else{

      Tcl_DStringAppendElement(&cmd, sqlite3_value_text(argv[i]));


    }
  }
  rc = Tcl_Eval(p->interp, Tcl_DStringValue(&cmd));
  if( rc ){

    sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 















  }else{
    sqlite3_result_text(context, Tcl_GetStringResult(p->interp), -1, 








        SQLITE_TRANSIENT);
















  }
}

#ifndef SQLITE_OMIT_AUTHORIZATION
/*
** This is the authentication function.  It appends the authentication
** type code and the two arguments to zCmd[] then invokes the result
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
    case SQLITE_SELECT            : zCode="SQLITE_SELECT"; break;
    case SQLITE_TRANSACTION       : zCode="SQLITE_TRANSACTION"; break;
    case SQLITE_UPDATE            : zCode="SQLITE_UPDATE"; break;
    case SQLITE_ATTACH            : zCode="SQLITE_ATTACH"; break;
    case SQLITE_DETACH            : zCode="SQLITE_DETACH"; break;
    case SQLITE_ALTER_TABLE       : zCode="SQLITE_ALTER_TABLE"; break;
    case SQLITE_REINDEX           : zCode="SQLITE_REINDEX"; break;
    case SQLITE_ANALYZE           : zCode="SQLITE_ANALYZE"; break;
    default                       : zCode="????"; break;
  }
  Tcl_DStringInit(&str);
  Tcl_DStringAppend(&str, pDb->zAuth, -1);
  Tcl_DStringAppendElement(&str, zCode);
  Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
  Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");







<







322
323
324
325
326
327
328

329
330
331
332
333
334
335
    case SQLITE_SELECT            : zCode="SQLITE_SELECT"; break;
    case SQLITE_TRANSACTION       : zCode="SQLITE_TRANSACTION"; break;
    case SQLITE_UPDATE            : zCode="SQLITE_UPDATE"; break;
    case SQLITE_ATTACH            : zCode="SQLITE_ATTACH"; break;
    case SQLITE_DETACH            : zCode="SQLITE_DETACH"; break;
    case SQLITE_ALTER_TABLE       : zCode="SQLITE_ALTER_TABLE"; break;
    case SQLITE_REINDEX           : zCode="SQLITE_REINDEX"; break;

    default                       : zCode="????"; break;
  }
  Tcl_DStringInit(&str);
  Tcl_DStringAppend(&str, pDb->zAuth, -1);
  Tcl_DStringAppendElement(&str, zCode);
  Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
  Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
  int choice;
  int rc = TCL_OK;
  static const char *DB_strs[] = {
    "authorizer",         "busy",              "cache",
    "changes",            "close",             "collate",
    "collation_needed",   "commit_hook",       "complete",
    "copy",               "errorcode",         "eval",
    "exists",             "function",          "last_insert_rowid",
    "nullvalue",          "onecolumn",         "profile",
    "progress",           "rekey",             "rollback_hook",
    "timeout",            "total_changes",     "trace",
    "transaction",        "update_hook",       "version",
    0                    
  };
  enum DB_enum {
    DB_AUTHORIZER,        DB_BUSY,             DB_CACHE,
    DB_CHANGES,           DB_CLOSE,            DB_COLLATE,
    DB_COLLATION_NEEDED,  DB_COMMIT_HOOK,      DB_COMPLETE,
    DB_COPY,              DB_ERRORCODE,        DB_EVAL,
    DB_EXISTS,            DB_FUNCTION,         DB_LAST_INSERT_ROWID,
    DB_NULLVALUE,         DB_ONECOLUMN,        DB_PROFILE,
    DB_PROGRESS,          DB_REKEY,            DB_ROLLBACK_HOOK,
    DB_TIMEOUT,           DB_TOTAL_CHANGES,    DB_TRACE,
    DB_TRANSACTION,       DB_UPDATE_HOOK,      DB_VERSION
  };
  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
    return TCL_ERROR;
  }







|
<
|
|
<







|
<
|
|
<







437
438
439
440
441
442
443
444

445
446

447
448
449
450
451
452
453
454

455
456

457
458
459
460
461
462
463
  int choice;
  int rc = TCL_OK;
  static const char *DB_strs[] = {
    "authorizer",         "busy",              "cache",
    "changes",            "close",             "collate",
    "collation_needed",   "commit_hook",       "complete",
    "copy",               "errorcode",         "eval",
    "function",           "last_insert_rowid", "onecolumn",

    "progress",           "rekey",             "timeout",
    "total_changes",      "trace",             "version",

    0                    
  };
  enum DB_enum {
    DB_AUTHORIZER,        DB_BUSY,             DB_CACHE,
    DB_CHANGES,           DB_CLOSE,            DB_COLLATE,
    DB_COLLATION_NEEDED,  DB_COMMIT_HOOK,      DB_COMPLETE,
    DB_COPY,              DB_ERRORCODE,        DB_EVAL,
    DB_FUNCTION,          DB_LAST_INSERT_ROWID,DB_ONECOLUMN,

    DB_PROGRESS,          DB_REKEY,            DB_TIMEOUT,
    DB_TOTAL_CHANGES,     DB_TRACE,            DB_VERSION

  };
  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
    return TCL_ERROR;
  }
853
854
855
856
857
858
859






































860
861
862
863
864
865
866
  **
  ** Shutdown the database
  */
  case DB_CLOSE: {
    Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
    break;
  }







































  /*
  **     $db collate NAME SCRIPT
  **
  ** Create a new SQL collation function called NAME.  Whenever
  ** that function is called, invoke SCRIPT to evaluate the function.
  */







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







627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
  **
  ** Shutdown the database
  */
  case DB_CLOSE: {
    Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
    break;
  }

  /*    $db commit_hook ?CALLBACK?
  **
  ** Invoke the given callback just before committing every SQL transaction.
  ** If the callback throws an exception or returns non-zero, then the
  ** transaction is aborted.  If CALLBACK is an empty string, the callback
  ** is disabled.
  */
  case DB_COMMIT_HOOK: {
    if( objc>3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zCommit ){
        Tcl_AppendResult(interp, pDb->zCommit, 0);
      }
    }else{
      char *zCommit;
      int len;
      if( pDb->zCommit ){
        Tcl_Free(pDb->zCommit);
      }
      zCommit = Tcl_GetStringFromObj(objv[2], &len);
      if( zCommit && len>0 ){
        pDb->zCommit = Tcl_Alloc( len + 1 );
        strcpy(pDb->zCommit, zCommit);
      }else{
        pDb->zCommit = 0;
      }
      if( pDb->zCommit ){
        pDb->interp = interp;
        sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
      }else{
        sqlite3_commit_hook(pDb->db, 0, 0);
      }
    }
    break;
  }

  /*
  **     $db collate NAME SCRIPT
  **
  ** Create a new SQL collation function called NAME.  Whenever
  ** that function is called, invoke SCRIPT to evaluate the function.
  */
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967



































































































































































































































































































































































































































































































968
969
970






































































971
972
973
974
975
976
977
    }
    pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
    Tcl_IncrRefCount(pDb->pCollateNeeded);
    sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
    break;
  }

  /*    $db commit_hook ?CALLBACK?
  **
  ** Invoke the given callback just before committing every SQL transaction.
  ** If the callback throws an exception or returns non-zero, then the
  ** transaction is aborted.  If CALLBACK is an empty string, the callback
  ** is disabled.
  */
  case DB_COMMIT_HOOK: {
    if( objc>3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zCommit ){
        Tcl_AppendResult(interp, pDb->zCommit, 0);
      }
    }else{
      char *zCommit;
      int len;
      if( pDb->zCommit ){
        Tcl_Free(pDb->zCommit);
      }
      zCommit = Tcl_GetStringFromObj(objv[2], &len);
      if( zCommit && len>0 ){
        pDb->zCommit = Tcl_Alloc( len + 1 );
        strcpy(pDb->zCommit, zCommit);
      }else{
        pDb->zCommit = 0;
      }
      if( pDb->zCommit ){
        pDb->interp = interp;
        sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
      }else{
        sqlite3_commit_hook(pDb->db, 0, 0);
      }
    }
    break;
  }

  /*    $db complete SQL
  **
  ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
  ** additional lines of input are needed.  This is similar to the
  ** built-in "info complete" command of Tcl.
  */
  case DB_COMPLETE: {
#ifndef SQLITE_OMIT_COMPLETE
    Tcl_Obj *pResult;
    int isComplete;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "SQL");
      return TCL_ERROR;
    }
    isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetBooleanObj(pResult, isComplete);



































































































































































































































































































































































































































































































#endif
    break;
  }







































































  /*    $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
  **
  ** Copy data into table from filename, optionally using SEPARATOR
  ** as column separators.  If a column contains a null string, or the
  ** value of NULLINDICATOR, a NULL is inserted for the column.
  ** conflict-algorithm is one of the sqlite conflict algorithms:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







<









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



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







718
719
720
721
722
723
724






































725
726
727
728
729
730
731

732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
    }
    pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
    Tcl_IncrRefCount(pDb->pCollateNeeded);
    sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
    break;
  }







































  /*    $db complete SQL
  **
  ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
  ** additional lines of input are needed.  This is similar to the
  ** built-in "info complete" command of Tcl.
  */
  case DB_COMPLETE: {

    Tcl_Obj *pResult;
    int isComplete;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "SQL");
      return TCL_ERROR;
    }
    isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetBooleanObj(pResult, isComplete);
    break;
  }

  /*
  **    $db errorcode
  **
  ** Return the numeric error code that was returned by the most recent
  ** call to sqlite3_exec().
  */
  case DB_ERRORCODE: {
    Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
    break;
  }
   
  /*
  **    $db eval $sql ?array? ?{  ...code... }?
  **    $db onecolumn $sql
  **
  ** The SQL statement in $sql is evaluated.  For each row, the values are
  ** placed in elements of the array named "array" and ...code... is executed.
  ** If "array" and "code" are omitted, then no callback is every invoked.
  ** If "array" is an empty string, then the values are placed in variables
  ** that have the same name as the fields extracted by the query.
  **
  ** The onecolumn method is the equivalent of:
  **     lindex [$db eval $sql] 0
  */
  case DB_ONECOLUMN:
  case DB_EVAL: {
    char const *zSql;      /* Next SQL statement to execute */
    char const *zLeft;     /* What is left after first stmt in zSql */
    sqlite3_stmt *pStmt;   /* Compiled SQL statment */
    Tcl_Obj *pArray;       /* Name of array into which results are written */
    Tcl_Obj *pScript;      /* Script to run for each result set */
    Tcl_Obj **apParm;      /* Parameters that need a Tcl_DecrRefCount() */
    int nParm;             /* Number of entries used in apParm[] */
    Tcl_Obj *aParm[10];    /* Static space for apParm[] in the common case */
    Tcl_Obj *pRet;         /* Value to be returned */
    SqlPreparedStmt *pPreStmt;  /* Pointer to a prepared statement */
    int rc2;

    if( choice==DB_ONECOLUMN ){
      if( objc!=3 ){
        Tcl_WrongNumArgs(interp, 2, objv, "SQL");
        return TCL_ERROR;
      }
      pRet = 0;
    }else{
      if( objc<3 || objc>5 ){
        Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
        return TCL_ERROR;
      }
      pRet = Tcl_NewObj();
      Tcl_IncrRefCount(pRet);
    }
    if( objc==3 ){
      pArray = pScript = 0;
    }else if( objc==4 ){
      pArray = 0;
      pScript = objv[3];
    }else{
      pArray = objv[3];
      if( Tcl_GetString(pArray)[0]==0 ) pArray = 0;
      pScript = objv[4];
    }

    Tcl_IncrRefCount(objv[2]);
    zSql = Tcl_GetStringFromObj(objv[2], 0);
    while( rc==TCL_OK && zSql[0] ){
      int i;                     /* Loop counter */
      int nVar;                  /* Number of bind parameters in the pStmt */
      int nCol;                  /* Number of columns in the result set */
      Tcl_Obj **apColName = 0;   /* Array of column names */
      int len;                   /* String length of zSql */
  
      /* Try to find a SQL statement that has already been compiled and
      ** which matches the next sequence of SQL.
      */
      pStmt = 0;
      pPreStmt = pDb->stmtList;
      len = strlen(zSql);
      if( pPreStmt && sqlite3_expired(pPreStmt->pStmt) ){
        flushStmtCache(pDb);
        pPreStmt = 0;
      }
      for(; pPreStmt; pPreStmt=pPreStmt->pNext){
        int n = pPreStmt->nSql;
        if( len>=n 
            && memcmp(pPreStmt->zSql, zSql, n)==0
            && (zSql[n]==0 || zSql[n-1]==';')
        ){
          pStmt = pPreStmt->pStmt;
          zLeft = &zSql[pPreStmt->nSql];

          /* When a prepared statement is found, unlink it from the
          ** cache list.  It will later be added back to the beginning
          ** of the cache list in order to implement LRU replacement.
          */
          if( pPreStmt->pPrev ){
            pPreStmt->pPrev->pNext = pPreStmt->pNext;
          }else{
            pDb->stmtList = pPreStmt->pNext;
          }
          if( pPreStmt->pNext ){
            pPreStmt->pNext->pPrev = pPreStmt->pPrev;
          }else{
            pDb->stmtLast = pPreStmt->pPrev;
          }
          pDb->nStmt--;
          break;
        }
      }
  
      /* If no prepared statement was found.  Compile the SQL text
      */
      if( pStmt==0 ){
        if( SQLITE_OK!=sqlite3_prepare(pDb->db, zSql, -1, &pStmt, &zLeft) ){
          Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
          rc = TCL_ERROR;
          break;
        }
        if( pStmt==0 ){
          if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
            /* A compile-time error in the statement
            */
            Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
            rc = TCL_ERROR;
            break;
          }else{
            /* The statement was a no-op.  Continue to the next statement
            ** in the SQL string.
            */
            zSql = zLeft;
            continue;
          }
        }
        assert( pPreStmt==0 );
      }

      /* Bind values to parameters that begin with $ or :
      */  
      nVar = sqlite3_bind_parameter_count(pStmt);
      nParm = 0;
      if( nVar>sizeof(aParm)/sizeof(aParm[0]) ){
        apParm = (Tcl_Obj**)Tcl_Alloc(nVar*sizeof(apParm[0]));
      }else{
        apParm = aParm;
      }
      for(i=1; i<=nVar; i++){
        const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
        if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':') ){
          Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
          if( pVar ){
            int n;
            u8 *data;
            char *zType = pVar->typePtr ? pVar->typePtr->name : "";
            char c = zType[0];
            if( c=='b' && strcmp(zType,"bytearray")==0 ){
              data = Tcl_GetByteArrayFromObj(pVar, &n);
              sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
              Tcl_IncrRefCount(pVar);
              apParm[nParm++] = pVar;
            }else if( (c=='b' && strcmp(zType,"boolean")==0) ||
                  (c=='i' && strcmp(zType,"int")==0) ){
              Tcl_GetIntFromObj(interp, pVar, &n);
              sqlite3_bind_int(pStmt, i, n);
            }else if( c=='d' && strcmp(zType,"double")==0 ){
              double r;
              Tcl_GetDoubleFromObj(interp, pVar, &r);
              sqlite3_bind_double(pStmt, i, r);
            }else{
              data = Tcl_GetStringFromObj(pVar, &n);
              sqlite3_bind_text(pStmt, i, data, n, SQLITE_STATIC);
              Tcl_IncrRefCount(pVar);
              apParm[nParm++] = pVar;
            }
          }else{
            sqlite3_bind_null( pStmt, i );
          }
        }
      }

      /* Compute column names */
      nCol = sqlite3_column_count(pStmt);
      if( pScript ){
        apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
        if( apColName==0 ) break;
        for(i=0; i<nCol; i++){
          apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
          Tcl_IncrRefCount(apColName[i]);
        }
      }

      /* If results are being stored in an array variable, then create
      ** the array(*) entry for that array
      */
      if( pArray ){
        Tcl_Obj *pColList = Tcl_NewObj();
        Tcl_IncrRefCount(pColList);
        for(i=0; i<nCol; i++){
          Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
        }
        Tcl_ObjSetVar2(interp, pArray, Tcl_NewStringObj("*",-1), pColList,0);
      }

      /* Execute the SQL
      */
      while( rc==TCL_OK && pStmt && SQLITE_ROW==sqlite3_step(pStmt) ){
        for(i=0; i<nCol; i++){
          Tcl_Obj *pVal;
          
          /* Set pVal to contain the i'th column of this row. */
          switch( sqlite3_column_type(pStmt, i) ){
            case SQLITE_BLOB: {
              int bytes = sqlite3_column_bytes(pStmt, i);
              pVal = Tcl_NewByteArrayObj(sqlite3_column_blob(pStmt, i), bytes);
              break;
            }
            case SQLITE_INTEGER: {
              sqlite_int64 v = sqlite3_column_int64(pStmt, i);
              if( v>=-2147483647 && v<=2147483647 ){
                pVal = Tcl_NewIntObj(v);
              }else{
                pVal = Tcl_NewWideIntObj(v);
              }
              break;
            }
            case SQLITE_FLOAT: {
              double r = sqlite3_column_double(pStmt, i);
              pVal = Tcl_NewDoubleObj(r);
              break;
            }
            default: {
              pVal = dbTextToObj(sqlite3_column_text(pStmt, i));
              break;
            }
          }
  
          if( pScript ){
            if( pArray==0 ){
              Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);
            }else{
              Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
            }
          }else if( choice==DB_ONECOLUMN ){
            if( pRet==0 ){
              pRet = pVal;
              Tcl_IncrRefCount(pRet);
            }
            rc = TCL_BREAK;
          }else{
            Tcl_ListObjAppendElement(interp, pRet, pVal);
          }
        }
  
        if( pScript ){
          rc = Tcl_EvalObjEx(interp, pScript, 0);
          if( rc==TCL_CONTINUE ){
            rc = TCL_OK;
          }
        }
      }
      if( rc==TCL_BREAK ){
        rc = TCL_OK;
      }

      /* Free the column name objects */
      if( pScript ){
        for(i=0; i<nCol; i++){
          Tcl_DecrRefCount(apColName[i]);
        }
        Tcl_Free((char*)apColName);
      }

      /* Free the bound string and blob parameters */
      for(i=0; i<nParm; i++){
        Tcl_DecrRefCount(apParm[i]);
      }
      if( apParm!=aParm ){
        Tcl_Free((char*)apParm);
      }

      /* Reset the statement.  If the result code is SQLITE_SCHEMA, then
      ** flush the statement cache and try the statement again.
      */
      rc2 = sqlite3_reset(pStmt);
      if( SQLITE_SCHEMA==rc2 ){
        /* After a schema change, flush the cache and try to run the
        ** statement again
        */
        flushStmtCache( pDb );
        sqlite3_finalize(pStmt);
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        continue;
      }else if( SQLITE_OK!=rc2 ){
        /* If a run-time error occurs, report the error and stop reading
        ** the SQL
        */
        Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
        sqlite3_finalize(pStmt);
        rc = TCL_ERROR;
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        break;
      }else if( pDb->maxStmt<=0 ){
        /* If the cache is turned off, deallocated the statement */
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        sqlite3_finalize(pStmt);
      }else{
        /* Everything worked and the cache is operational.
        ** Create a new SqlPreparedStmt structure if we need one.
        ** (If we already have one we can just reuse it.)
        */
        if( pPreStmt==0 ){
          len = zLeft - zSql;
          pPreStmt = (SqlPreparedStmt*)Tcl_Alloc( sizeof(*pPreStmt) + len );
          if( pPreStmt==0 ) return TCL_ERROR;
          pPreStmt->pStmt = pStmt;
          pPreStmt->nSql = len;
          memcpy(pPreStmt->zSql, zSql, len);
          pPreStmt->zSql[len] = 0;
        }

        /* Add the prepared statement to the beginning of the cache list
        */
        pPreStmt->pNext = pDb->stmtList;
        pPreStmt->pPrev = 0;
        if( pDb->stmtList ){
         pDb->stmtList->pPrev = pPreStmt;
        }
        pDb->stmtList = pPreStmt;
        if( pDb->stmtLast==0 ){
          assert( pDb->nStmt==0 );
          pDb->stmtLast = pPreStmt;
        }else{
          assert( pDb->nStmt>0 );
        }
        pDb->nStmt++;
   
        /* If we have too many statement in cache, remove the surplus from the
        ** end of the cache list.
        */
        while( pDb->nStmt>pDb->maxStmt ){
          sqlite3_finalize(pDb->stmtLast->pStmt);
          pDb->stmtLast = pDb->stmtLast->pPrev;
          Tcl_Free((char*)pDb->stmtLast->pNext);
          pDb->stmtLast->pNext = 0;
          pDb->nStmt--;
        }
      }

      /* Proceed to the next statement */
      zSql = zLeft;
    }
    Tcl_DecrRefCount(objv[2]);

    if( pRet ){
      if( rc==TCL_OK ){
        Tcl_SetObjResult(interp, pRet);
      }
      Tcl_DecrRefCount(pRet);
    }
    break;
  }

  /*
  **     $db function NAME SCRIPT
  **
  ** Create a new SQL function called NAME.  Whenever that function is
  ** called, invoke SCRIPT to evaluate the function.
  */
  case DB_FUNCTION: {
    SqlFunc *pFunc;
    char *zName;
    char *zScript;
    int nScript;
    if( objc!=4 ){
      Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
      return TCL_ERROR;
    }
    zName = Tcl_GetStringFromObj(objv[2], 0);
    zScript = Tcl_GetStringFromObj(objv[3], &nScript);
    pFunc = (SqlFunc*)Tcl_Alloc( sizeof(*pFunc) + nScript + 1 );
    if( pFunc==0 ) return TCL_ERROR;
    pFunc->interp = interp;
    pFunc->pNext = pDb->pFunc;
    pFunc->zScript = (char*)&pFunc[1];
    pDb->pFunc = pFunc;
    strcpy(pFunc->zScript, zScript);
    rc = sqlite3_create_function(pDb->db, zName, -1, SQLITE_UTF8,
        pFunc, tclSqlFunc, 0, 0);
    if( rc!=SQLITE_OK ){
      rc = TCL_ERROR;
      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
    }else{
      /* Must flush any cached statements */
      flushStmtCache( pDb );
    }
    break;
  }

  /*
  **     $db last_insert_rowid 
  **
  ** Return an integer which is the ROWID for the most recent insert.
  */
  case DB_LAST_INSERT_ROWID: {
    Tcl_Obj *pResult;
    int rowid;
    if( objc!=2 ){
      Tcl_WrongNumArgs(interp, 2, objv, "");
      return TCL_ERROR;
    }
    rowid = sqlite3_last_insert_rowid(pDb->db);
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetIntObj(pResult, rowid);
    break;
  }

  /*
  ** The DB_ONECOLUMN method is implemented together with DB_EVAL.
  */

  /*    $db progress ?N CALLBACK?
  ** 
  ** Invoke the given callback every N virtual machine opcodes while executing
  ** queries.
  */
  case DB_PROGRESS: {
    if( objc==2 ){
      if( pDb->zProgress ){
        Tcl_AppendResult(interp, pDb->zProgress, 0);
      }
    }else if( objc==4 ){
      char *zProgress;
      int len;
      int N;
      if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
	return TCL_ERROR;
      };
      if( pDb->zProgress ){
        Tcl_Free(pDb->zProgress);
      }
      zProgress = Tcl_GetStringFromObj(objv[3], &len);
      if( zProgress && len>0 ){
        pDb->zProgress = Tcl_Alloc( len + 1 );
        strcpy(pDb->zProgress, zProgress);
      }else{
        pDb->zProgress = 0;
      }
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
      if( pDb->zProgress ){
        pDb->interp = interp;
        sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
      }else{
        sqlite3_progress_handler(pDb->db, 0, 0, 0);
      }
#endif
    }else{
      Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
      return TCL_ERROR;
    }
    break;
  }

  /*
  **     $db rekey KEY
  **
  ** Change the encryption key on the currently open database.
  */
  case DB_REKEY: {
    int nKey;
    void *pKey;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "KEY");
      return TCL_ERROR;
    }
    pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
#ifdef SQLITE_HAS_CODEC
    rc = sqlite3_rekey(pDb->db, pKey, nKey);
    if( rc ){
      Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
      rc = TCL_ERROR;
    }
#endif
    break;
  }

  /*
  **     $db timeout MILLESECONDS
  **
  ** Delay for the number of milliseconds specified when a file is locked.
  */
  case DB_TIMEOUT: {
    int ms;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
      return TCL_ERROR;
    }
    if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
    sqlite3_busy_timeout(pDb->db, ms);
    break;
  }

  /*
  **     $db total_changes
  **
  ** Return the number of rows that were modified, inserted, or deleted 
  ** since the database handle was created.
  */
  case DB_TOTAL_CHANGES: {
    Tcl_Obj *pResult;
    if( objc!=2 ){
      Tcl_WrongNumArgs(interp, 2, objv, "");
      return TCL_ERROR;
    }
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
    break;
  }

  /*    $db trace ?CALLBACK?
  **
  ** Make arrangements to invoke the CALLBACK routine for each SQL statement
  ** that is executed.  The text of the SQL is appended to CALLBACK before
  ** it is executed.
  */
  case DB_TRACE: {
    if( objc>3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zTrace ){
        Tcl_AppendResult(interp, pDb->zTrace, 0);
      }
    }else{
      char *zTrace;
      int len;
      if( pDb->zTrace ){
        Tcl_Free(pDb->zTrace);
      }
      zTrace = Tcl_GetStringFromObj(objv[2], &len);
      if( zTrace && len>0 ){
        pDb->zTrace = Tcl_Alloc( len + 1 );
        strcpy(pDb->zTrace, zTrace);
      }else{
        pDb->zTrace = 0;
      }
      if( pDb->zTrace ){
        pDb->interp = interp;
        sqlite3_trace(pDb->db, DbTraceHandler, pDb);
      }else{
        sqlite3_trace(pDb->db, 0, 0);
      }
    }
    break;
  }

  /*    $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
  **
  ** Copy data into table from filename, optionally using SEPARATOR
  ** as column separators.  If a column contains a null string, or the
  ** value of NULLINDICATOR, a NULL is inserted for the column.
  ** conflict-algorithm is one of the sqlite conflict algorithms:
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
      sprintf(zLineNum,"%d",lineno);
      Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0);
      rc = TCL_ERROR;
    }
    break;
  }

  /*
  **    $db errorcode
  **
  ** Return the numeric error code that was returned by the most recent
  ** call to sqlite3_exec().
  */
  case DB_ERRORCODE: {
    Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
    break;
  }
   
  /*
  **    $db eval $sql ?array? ?{  ...code... }?
  **    $db onecolumn $sql
  **
  ** The SQL statement in $sql is evaluated.  For each row, the values are
  ** placed in elements of the array named "array" and ...code... is executed.
  ** If "array" and "code" are omitted, then no callback is every invoked.
  ** If "array" is an empty string, then the values are placed in variables
  ** that have the same name as the fields extracted by the query.
  **
  ** The onecolumn method is the equivalent of:
  **     lindex [$db eval $sql] 0
  */
  case DB_ONECOLUMN:
  case DB_EVAL:
  case DB_EXISTS: {
    char const *zSql;      /* Next SQL statement to execute */
    char const *zLeft;     /* What is left after first stmt in zSql */
    sqlite3_stmt *pStmt;   /* Compiled SQL statment */
    Tcl_Obj *pArray;       /* Name of array into which results are written */
    Tcl_Obj *pScript;      /* Script to run for each result set */
    Tcl_Obj **apParm;      /* Parameters that need a Tcl_DecrRefCount() */
    int nParm;             /* Number of entries used in apParm[] */
    Tcl_Obj *aParm[10];    /* Static space for apParm[] in the common case */
    Tcl_Obj *pRet;         /* Value to be returned */
    SqlPreparedStmt *pPreStmt;  /* Pointer to a prepared statement */
    int rc2;

    if( choice==DB_EVAL ){
      if( objc<3 || objc>5 ){
        Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
        return TCL_ERROR;
      }
      pRet = Tcl_NewObj();
      Tcl_IncrRefCount(pRet);
    }else{
      if( objc!=3 ){
        Tcl_WrongNumArgs(interp, 2, objv, "SQL");
        return TCL_ERROR;
      }
      if( choice==DB_EXISTS ){
        pRet = Tcl_NewBooleanObj(0);
        Tcl_IncrRefCount(pRet);
      }else{
        pRet = 0;
      }
    }
    if( objc==3 ){
      pArray = pScript = 0;
    }else if( objc==4 ){
      pArray = 0;
      pScript = objv[3];
    }else{
      pArray = objv[3];
      if( Tcl_GetString(pArray)[0]==0 ) pArray = 0;
      pScript = objv[4];
    }

    Tcl_IncrRefCount(objv[2]);
    zSql = Tcl_GetStringFromObj(objv[2], 0);
    while( rc==TCL_OK && zSql[0] ){
      int i;                     /* Loop counter */
      int nVar;                  /* Number of bind parameters in the pStmt */
      int nCol;                  /* Number of columns in the result set */
      Tcl_Obj **apColName = 0;   /* Array of column names */
      int len;                   /* String length of zSql */
  
      /* Try to find a SQL statement that has already been compiled and
      ** which matches the next sequence of SQL.
      */
      pStmt = 0;
      pPreStmt = pDb->stmtList;
      len = strlen(zSql);
      if( pPreStmt && sqlite3_expired(pPreStmt->pStmt) ){
        flushStmtCache(pDb);
        pPreStmt = 0;
      }
      for(; pPreStmt; pPreStmt=pPreStmt->pNext){
        int n = pPreStmt->nSql;
        if( len>=n 
            && memcmp(pPreStmt->zSql, zSql, n)==0
            && (zSql[n]==0 || zSql[n-1]==';')
        ){
          pStmt = pPreStmt->pStmt;
          zLeft = &zSql[pPreStmt->nSql];

          /* When a prepared statement is found, unlink it from the
          ** cache list.  It will later be added back to the beginning
          ** of the cache list in order to implement LRU replacement.
          */
          if( pPreStmt->pPrev ){
            pPreStmt->pPrev->pNext = pPreStmt->pNext;
          }else{
            pDb->stmtList = pPreStmt->pNext;
          }
          if( pPreStmt->pNext ){
            pPreStmt->pNext->pPrev = pPreStmt->pPrev;
          }else{
            pDb->stmtLast = pPreStmt->pPrev;
          }
          pDb->nStmt--;
          break;
        }
      }
  
      /* If no prepared statement was found.  Compile the SQL text
      */
      if( pStmt==0 ){
        if( SQLITE_OK!=sqlite3_prepare(pDb->db, zSql, -1, &pStmt, &zLeft) ){
          Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
          rc = TCL_ERROR;
          break;
        }
        if( pStmt==0 ){
          if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
            /* A compile-time error in the statement
            */
            Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
            rc = TCL_ERROR;
            break;
          }else{
            /* The statement was a no-op.  Continue to the next statement
            ** in the SQL string.
            */
            zSql = zLeft;
            continue;
          }
        }
        assert( pPreStmt==0 );
      }

      /* Bind values to parameters that begin with $ or :
      */  
      nVar = sqlite3_bind_parameter_count(pStmt);
      nParm = 0;
      if( nVar>sizeof(aParm)/sizeof(aParm[0]) ){
        apParm = (Tcl_Obj**)Tcl_Alloc(nVar*sizeof(apParm[0]));
      }else{
        apParm = aParm;
      }
      for(i=1; i<=nVar; i++){
        const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
        if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':') ){
          Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
          if( pVar ){
            int n;
            u8 *data;
            char *zType = pVar->typePtr ? pVar->typePtr->name : "";
            char c = zType[0];
            if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
              /* Only load a BLOB type if the Tcl variable is a bytearray and
              ** has no string representation. */
              data = Tcl_GetByteArrayFromObj(pVar, &n);
              sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
              Tcl_IncrRefCount(pVar);
              apParm[nParm++] = pVar;
            }else if( (c=='b' && strcmp(zType,"boolean")==0) ||
                  (c=='i' && strcmp(zType,"int")==0) ){
              Tcl_GetIntFromObj(interp, pVar, &n);
              sqlite3_bind_int(pStmt, i, n);
            }else if( c=='d' && strcmp(zType,"double")==0 ){
              double r;
              Tcl_GetDoubleFromObj(interp, pVar, &r);
              sqlite3_bind_double(pStmt, i, r);
            }else if( c=='w' && strcmp(zType,"wideInt")==0 ){
              Tcl_WideInt v;
              Tcl_GetWideIntFromObj(interp, pVar, &v);
              sqlite3_bind_int64(pStmt, i, v);
            }else{
              data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
              sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
              Tcl_IncrRefCount(pVar);
              apParm[nParm++] = pVar;
            }
          }else{
            sqlite3_bind_null( pStmt, i );
          }
        }
      }

      /* Compute column names */
      nCol = sqlite3_column_count(pStmt);
      if( pScript ){
        apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
        if( apColName==0 ) break;
        for(i=0; i<nCol; i++){
          apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
          Tcl_IncrRefCount(apColName[i]);
        }
      }

      /* If results are being stored in an array variable, then create
      ** the array(*) entry for that array
      */
      if( pArray ){
        Tcl_Obj *pColList = Tcl_NewObj();
        Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);
        Tcl_IncrRefCount(pColList);
        for(i=0; i<nCol; i++){
          Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
        }
        Tcl_ObjSetVar2(interp, pArray, pStar, pColList,0);
        Tcl_DecrRefCount(pColList);
        Tcl_DecrRefCount(pStar);
      }

      /* Execute the SQL
      */
      while( rc==TCL_OK && pStmt && SQLITE_ROW==sqlite3_step(pStmt) ){
        for(i=0; i<nCol; i++){
          Tcl_Obj *pVal;
          
          /* Set pVal to contain the i'th column of this row. */
          switch( sqlite3_column_type(pStmt, i) ){
            case SQLITE_BLOB: {
              int bytes = sqlite3_column_bytes(pStmt, i);
              pVal = Tcl_NewByteArrayObj(sqlite3_column_blob(pStmt, i), bytes);
              break;
            }
            case SQLITE_INTEGER: {
              sqlite_int64 v = sqlite3_column_int64(pStmt, i);
              if( v>=-2147483647 && v<=2147483647 ){
                pVal = Tcl_NewIntObj(v);
              }else{
                pVal = Tcl_NewWideIntObj(v);
              }
              break;
            }
            case SQLITE_FLOAT: {
              double r = sqlite3_column_double(pStmt, i);
              pVal = Tcl_NewDoubleObj(r);
              break;
            }
            case SQLITE_NULL: {
              pVal = dbTextToObj(pDb->zNull);
              break;
            }
            default: {
              pVal = dbTextToObj((char *)sqlite3_column_text(pStmt, i));
              break;
            }
          }
  
          if( pScript ){
            if( pArray==0 ){
              Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);
            }else{
              Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
            }
          }else if( choice==DB_ONECOLUMN ){
            assert( pRet==0 );
            if( pRet==0 ){
              pRet = pVal;
              Tcl_IncrRefCount(pRet);
            }
            rc = TCL_BREAK;
            i = nCol;
          }else if( choice==DB_EXISTS ){
            Tcl_DecrRefCount(pRet);
            pRet = Tcl_NewBooleanObj(1);
            Tcl_IncrRefCount(pRet);
            rc = TCL_BREAK;
            i = nCol;
          }else{
            Tcl_ListObjAppendElement(interp, pRet, pVal);
          }
        }
  
        if( pScript ){
          rc = Tcl_EvalObjEx(interp, pScript, 0);
          if( rc==TCL_CONTINUE ){
            rc = TCL_OK;
          }
        }
      }
      if( rc==TCL_BREAK ){
        rc = TCL_OK;
      }

      /* Free the column name objects */
      if( pScript ){
        for(i=0; i<nCol; i++){
          Tcl_DecrRefCount(apColName[i]);
        }
        Tcl_Free((char*)apColName);
      }

      /* Free the bound string and blob parameters */
      for(i=0; i<nParm; i++){
        Tcl_DecrRefCount(apParm[i]);
      }
      if( apParm!=aParm ){
        Tcl_Free((char*)apParm);
      }

      /* Reset the statement.  If the result code is SQLITE_SCHEMA, then
      ** flush the statement cache and try the statement again.
      */
      rc2 = sqlite3_reset(pStmt);
      if( SQLITE_SCHEMA==rc2 ){
        /* After a schema change, flush the cache and try to run the
        ** statement again
        */
        flushStmtCache( pDb );
        sqlite3_finalize(pStmt);
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        continue;
      }else if( SQLITE_OK!=rc2 ){
        /* If a run-time error occurs, report the error and stop reading
        ** the SQL
        */
        Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
        sqlite3_finalize(pStmt);
        rc = TCL_ERROR;
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        break;
      }else if( pDb->maxStmt<=0 ){
        /* If the cache is turned off, deallocated the statement */
        if( pPreStmt ) Tcl_Free((char*)pPreStmt);
        sqlite3_finalize(pStmt);
      }else{
        /* Everything worked and the cache is operational.
        ** Create a new SqlPreparedStmt structure if we need one.
        ** (If we already have one we can just reuse it.)
        */
        if( pPreStmt==0 ){
          len = zLeft - zSql;
          pPreStmt = (SqlPreparedStmt*)Tcl_Alloc( sizeof(*pPreStmt) + len );
          if( pPreStmt==0 ) return TCL_ERROR;
          pPreStmt->pStmt = pStmt;
          pPreStmt->nSql = len;
          memcpy(pPreStmt->zSql, zSql, len);
          pPreStmt->zSql[len] = 0;
        }

        /* Add the prepared statement to the beginning of the cache list
        */
        pPreStmt->pNext = pDb->stmtList;
        pPreStmt->pPrev = 0;
        if( pDb->stmtList ){
         pDb->stmtList->pPrev = pPreStmt;
        }
        pDb->stmtList = pPreStmt;
        if( pDb->stmtLast==0 ){
          assert( pDb->nStmt==0 );
          pDb->stmtLast = pPreStmt;
        }else{
          assert( pDb->nStmt>0 );
        }
        pDb->nStmt++;
   
        /* If we have too many statement in cache, remove the surplus from the
        ** end of the cache list.
        */
        while( pDb->nStmt>pDb->maxStmt ){
          sqlite3_finalize(pDb->stmtLast->pStmt);
          pDb->stmtLast = pDb->stmtLast->pPrev;
          Tcl_Free((char*)pDb->stmtLast->pNext);
          pDb->stmtLast->pNext = 0;
          pDb->nStmt--;
        }
      }

      /* Proceed to the next statement */
      zSql = zLeft;
    }
    Tcl_DecrRefCount(objv[2]);

    if( pRet ){
      if( rc==TCL_OK ){
        Tcl_SetObjResult(interp, pRet);
      }
      Tcl_DecrRefCount(pRet);
    }
    break;
  }

  /*
  **     $db function NAME SCRIPT
  **
  ** Create a new SQL function called NAME.  Whenever that function is
  ** called, invoke SCRIPT to evaluate the function.
  */
  case DB_FUNCTION: {
    SqlFunc *pFunc;
    Tcl_Obj *pScript;
    char *zName;
    if( objc!=4 ){
      Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
      return TCL_ERROR;
    }
    zName = Tcl_GetStringFromObj(objv[2], 0);
    pScript = objv[3];
    pFunc = findSqlFunc(pDb, zName);
    if( pFunc==0 ) return TCL_ERROR;
    if( pFunc->pScript ){
      Tcl_DecrRefCount(pFunc->pScript);
    }
    pFunc->pScript = pScript;
    Tcl_IncrRefCount(pScript);
    pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
    rc = sqlite3_create_function(pDb->db, zName, -1, SQLITE_UTF8,
        pFunc, tclSqlFunc, 0, 0);
    if( rc!=SQLITE_OK ){
      rc = TCL_ERROR;
      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
    }else{
      /* Must flush any cached statements */
      flushStmtCache( pDb );
    }
    break;
  }

  /*
  **     $db nullvalue ?STRING?
  **
  ** Change text used when a NULL comes back from the database. If ?STRING?
  ** is not present, then the current string used for NULL is returned.
  ** If STRING is present, then STRING is returned.
  **
  */
  case DB_NULLVALUE: {
    if( objc!=2 && objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE");
      return TCL_ERROR;
    }
    if( objc==3 ){
      int len;
      char *zNull = Tcl_GetStringFromObj(objv[2], &len);
      if( pDb->zNull ){
        Tcl_Free(pDb->zNull);
      }
      if( zNull && len>0 ){
        pDb->zNull = Tcl_Alloc( len + 1 );
        strncpy(pDb->zNull, zNull, len);
        pDb->zNull[len] = '\0';
      }else{
        pDb->zNull = 0;
      }
    }
    Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull));
    break;
  }

  /*
  **     $db last_insert_rowid 
  **
  ** Return an integer which is the ROWID for the most recent insert.
  */
  case DB_LAST_INSERT_ROWID: {
    Tcl_Obj *pResult;
    int rowid;
    if( objc!=2 ){
      Tcl_WrongNumArgs(interp, 2, objv, "");
      return TCL_ERROR;
    }
    rowid = sqlite3_last_insert_rowid(pDb->db);
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetIntObj(pResult, rowid);
    break;
  }

  /*
  ** The DB_ONECOLUMN method is implemented together with DB_EVAL.
  */

  /*    $db progress ?N CALLBACK?
  ** 
  ** Invoke the given callback every N virtual machine opcodes while executing
  ** queries.
  */
  case DB_PROGRESS: {
    if( objc==2 ){
      if( pDb->zProgress ){
        Tcl_AppendResult(interp, pDb->zProgress, 0);
      }
    }else if( objc==4 ){
      char *zProgress;
      int len;
      int N;
      if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
	return TCL_ERROR;
      };
      if( pDb->zProgress ){
        Tcl_Free(pDb->zProgress);
      }
      zProgress = Tcl_GetStringFromObj(objv[3], &len);
      if( zProgress && len>0 ){
        pDb->zProgress = Tcl_Alloc( len + 1 );
        strcpy(pDb->zProgress, zProgress);
      }else{
        pDb->zProgress = 0;
      }
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
      if( pDb->zProgress ){
        pDb->interp = interp;
        sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
      }else{
        sqlite3_progress_handler(pDb->db, 0, 0, 0);
      }
#endif
    }else{
      Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
      return TCL_ERROR;
    }
    break;
  }

  /*    $db profile ?CALLBACK?
  **
  ** Make arrangements to invoke the CALLBACK routine after each SQL statement
  ** that has run.  The text of the SQL and the amount of elapse time are
  ** appended to CALLBACK before the script is run.
  */
  case DB_PROFILE: {
    if( objc>3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zProfile ){
        Tcl_AppendResult(interp, pDb->zProfile, 0);
      }
    }else{
      char *zProfile;
      int len;
      if( pDb->zProfile ){
        Tcl_Free(pDb->zProfile);
      }
      zProfile = Tcl_GetStringFromObj(objv[2], &len);
      if( zProfile && len>0 ){
        pDb->zProfile = Tcl_Alloc( len + 1 );
        strcpy(pDb->zProfile, zProfile);
      }else{
        pDb->zProfile = 0;
      }
#ifndef SQLITE_OMIT_TRACE
      if( pDb->zProfile ){
        pDb->interp = interp;
        sqlite3_profile(pDb->db, DbProfileHandler, pDb);
      }else{
        sqlite3_profile(pDb->db, 0, 0);
      }
#endif
    }
    break;
  }

  /*
  **     $db rekey KEY
  **
  ** Change the encryption key on the currently open database.
  */
  case DB_REKEY: {
    int nKey;
    void *pKey;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "KEY");
      return TCL_ERROR;
    }
    pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
#ifdef SQLITE_HAS_CODEC
    rc = sqlite3_rekey(pDb->db, pKey, nKey);
    if( rc ){
      Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
      rc = TCL_ERROR;
    }
#endif
    break;
  }

  /*
  **     $db timeout MILLESECONDS
  **
  ** Delay for the number of milliseconds specified when a file is locked.
  */
  case DB_TIMEOUT: {
    int ms;
    if( objc!=3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
      return TCL_ERROR;
    }
    if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
    sqlite3_busy_timeout(pDb->db, ms);
    break;
  }
  
  /*
  **     $db total_changes
  **
  ** Return the number of rows that were modified, inserted, or deleted 
  ** since the database handle was created.
  */
  case DB_TOTAL_CHANGES: {
    Tcl_Obj *pResult;
    if( objc!=2 ){
      Tcl_WrongNumArgs(interp, 2, objv, "");
      return TCL_ERROR;
    }
    pResult = Tcl_GetObjResult(interp);
    Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
    break;
  }

  /*    $db trace ?CALLBACK?
  **
  ** Make arrangements to invoke the CALLBACK routine for each SQL statement
  ** that is executed.  The text of the SQL is appended to CALLBACK before
  ** it is executed.
  */
  case DB_TRACE: {
    if( objc>3 ){
      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
      return TCL_ERROR;
    }else if( objc==2 ){
      if( pDb->zTrace ){
        Tcl_AppendResult(interp, pDb->zTrace, 0);
      }
    }else{
      char *zTrace;
      int len;
      if( pDb->zTrace ){
        Tcl_Free(pDb->zTrace);
      }
      zTrace = Tcl_GetStringFromObj(objv[2], &len);
      if( zTrace && len>0 ){
        pDb->zTrace = Tcl_Alloc( len + 1 );
        strcpy(pDb->zTrace, zTrace);
      }else{
        pDb->zTrace = 0;
      }
#ifndef SQLITE_OMIT_TRACE
      if( pDb->zTrace ){
        pDb->interp = interp;
        sqlite3_trace(pDb->db, DbTraceHandler, pDb);
      }else{
        sqlite3_trace(pDb->db, 0, 0);
      }
#endif
    }
    break;
  }

  /*    $db transaction [-deferred|-immediate|-exclusive] SCRIPT
  **
  ** Start a new transaction (if we are not already in the midst of a
  ** transaction) and execute the TCL script SCRIPT.  After SCRIPT
  ** completes, either commit the transaction or roll it back if SCRIPT
  ** throws an exception.  Or if no new transation was started, do nothing.
  ** pass the exception on up the stack.
  **
  ** This command was inspired by Dave Thomas's talk on Ruby at the
  ** 2005 O'Reilly Open Source Convention (OSCON).
  */
  case DB_TRANSACTION: {
    int inTrans;
    Tcl_Obj *pScript;
    const char *zBegin = "BEGIN";
    if( objc!=3 && objc!=4 ){
      Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
      return TCL_ERROR;
    }
    if( objc==3 ){
      pScript = objv[2];
    } else {
      static const char *TTYPE_strs[] = {
        "deferred",   "exclusive",  "immediate", 0
      };
      enum TTYPE_enum {
        TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
      };
      int ttype;
      if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type",
                              0, &ttype) ){
        return TCL_ERROR;
      }
      switch( (enum TTYPE_enum)ttype ){
        case TTYPE_DEFERRED:    /* no-op */;                 break;
        case TTYPE_EXCLUSIVE:   zBegin = "BEGIN EXCLUSIVE";  break;
        case TTYPE_IMMEDIATE:   zBegin = "BEGIN IMMEDIATE";  break;
      }
      pScript = objv[3];
    }
    inTrans = !sqlite3_get_autocommit(pDb->db);
    if( !inTrans ){
      sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
    }
    rc = Tcl_EvalObjEx(interp, pScript, 0);
    if( !inTrans ){
      const char *zEnd;
      if( rc==TCL_ERROR ){
        zEnd = "ROLLBACK";
      } else {
        zEnd = "COMMIT";
      }
      sqlite3_exec(pDb->db, zEnd, 0, 0, 0);
    }
    break;
  }

  /*
  **    $db update_hook ?script?
  **    $db rollback_hook ?script?
  */
  case DB_UPDATE_HOOK: 
  case DB_ROLLBACK_HOOK: {

    /* set ppHook to point at pUpdateHook or pRollbackHook, depending on 
    ** whether [$db update_hook] or [$db rollback_hook] was invoked.
    */
    Tcl_Obj **ppHook; 
    if( choice==DB_UPDATE_HOOK ){
      ppHook = &pDb->pUpdateHook;
    }else{
      ppHook = &pDb->pRollbackHook;
    }

    if( objc!=2 && objc!=3 ){
       Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
       return TCL_ERROR;
    }
    if( *ppHook ){
      Tcl_SetObjResult(interp, *ppHook);
      if( objc==3 ){
        Tcl_DecrRefCount(*ppHook);
        *ppHook = 0;
      }
    }
    if( objc==3 ){
      assert( !(*ppHook) );
      if( Tcl_GetCharLength(objv[2])>0 ){
        *ppHook = objv[2];
        Tcl_IncrRefCount(*ppHook);
      }
    }

    sqlite3_update_hook(pDb->db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
    sqlite3_rollback_hook(pDb->db,(pDb->pRollbackHook?DbRollbackHandler:0),pDb);

    break;
  }

  /*    $db version
  **
  ** Return the version string for this database.
  */
  case DB_VERSION: {
    Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
    break;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1477
1478
1479
1480
1481
1482
1483
















































































































































































































































































































































































































































































































































































































































































































































































1484
1485
1486
1487
1488
1489
1490
      sprintf(zLineNum,"%d",lineno);
      Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0);
      rc = TCL_ERROR;
    }
    break;
  }

















































































































































































































































































































































































































































































































































































































































































































































































  /*    $db version
  **
  ** Return the version string for this database.
  */
  case DB_VERSION: {
    Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
    break;
1955
1956
1957
1958
1959
1960
1961

1962
1963
1964
1965
1966
1967
1968
static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
  SqliteDb *p;
  void *pKey = 0;
  int nKey = 0;
  const char *zArg;
  char *zErrMsg;
  const char *zFile;

  if( objc==2 ){
    zArg = Tcl_GetStringFromObj(objv[1], 0);
    if( strcmp(zArg,"-version")==0 ){
      Tcl_AppendResult(interp,sqlite3_version,0);
      return TCL_OK;
    }
    if( strcmp(zArg,"-has-codec")==0 ){







>







1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
  SqliteDb *p;
  void *pKey = 0;
  int nKey = 0;
  const char *zArg;
  char *zErrMsg;
  const char *zFile;
  char zBuf[80];
  if( objc==2 ){
    zArg = Tcl_GetStringFromObj(objv[1], 0);
    if( strcmp(zArg,"-version")==0 ){
      Tcl_AppendResult(interp,sqlite3_version,0);
      return TCL_OK;
    }
    if( strcmp(zArg,"-has-codec")==0 ){
2021
2022
2023
2024
2025
2026
2027








2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
    Tcl_Free((char*)p);
    free(zErrMsg);
    return TCL_ERROR;
  }
  p->maxStmt = NUM_PREPARED_STMTS;
  zArg = Tcl_GetStringFromObj(objv[1], 0);
  Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);









  /* If compiled with SQLITE_TEST turned on, then register the "md5sum"
  ** SQL function.
  */
#ifdef SQLITE_TEST
  {
    extern void Md5_Register(sqlite3*);
#ifdef SQLITE_MEMDEBUG
    int mallocfail = sqlite3_iMallocFail;
    sqlite3_iMallocFail = 0;
#endif
    Md5_Register(p->db);
#ifdef SQLITE_MEMDEBUG
    sqlite3_iMallocFail = mallocfail;
#endif
  }
#endif  
  p->interp = interp;
  return TCL_OK;
}

/*
** Provide a dummy Tcl_InitStubs if we are using this as a static
** library.
*/
#ifndef USE_TCL_STUBS
# undef  Tcl_InitStubs
# define Tcl_InitStubs(a,b,c)
#endif

/*
** Make sure we have a PACKAGE_VERSION macro defined.  This will be
** defined automatically by the TEA makefile.  But other makefiles
** do not define it.
*/
#ifndef PACKAGE_VERSION
# define PACKAGE_VERSION SQLITE_VERSION
#endif

/*
** Initialize this module.
**
** This Tcl module contains only a single new Tcl command named "sqlite".
** (Hence there is no namespace.  There is no point in using a namespace
** if the extension only supplies one new name!)  The "sqlite" command is
** used to open a new SQLite database.  See the DbMain() routine above
** for additional information.
*/
EXTERN int Sqlite3_Init(Tcl_Interp *interp){
  Tcl_InitStubs(interp, "8.4", 0);
  Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
  Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  Tcl_PkgProvide(interp, "sqlite", PACKAGE_VERSION);
  return TCL_OK;
}
EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
EXTERN int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }

#ifndef SQLITE_3_SUFFIX_ONLY
EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
EXTERN int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
#endif

#ifdef TCLSH
/*****************************************************************************
** The code that follows is used to build standalone TCL interpreters
*/








>
>
>
>
>
>
>
>















|














<
<
<
<
<
<
<
<
<









|


|

|


|
|
|


|
|
|
|







1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640









1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
    Tcl_Free((char*)p);
    free(zErrMsg);
    return TCL_ERROR;
  }
  p->maxStmt = NUM_PREPARED_STMTS;
  zArg = Tcl_GetStringFromObj(objv[1], 0);
  Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);

  /* The return value is the value of the sqlite* pointer
  */
  sprintf(zBuf, "%p", p->db);
  if( strncmp(zBuf,"0x",2) ){
    sprintf(zBuf, "0x%p", p->db);
  }
  Tcl_AppendResult(interp, zBuf, 0);

  /* If compiled with SQLITE_TEST turned on, then register the "md5sum"
  ** SQL function.
  */
#ifdef SQLITE_TEST
  {
    extern void Md5_Register(sqlite3*);
#ifdef SQLITE_MEMDEBUG
    int mallocfail = sqlite3_iMallocFail;
    sqlite3_iMallocFail = 0;
#endif
    Md5_Register(p->db);
#ifdef SQLITE_MEMDEBUG
    sqlite3_iMallocFail = mallocfail;
#endif
   }
#endif  
  p->interp = interp;
  return TCL_OK;
}

/*
** Provide a dummy Tcl_InitStubs if we are using this as a static
** library.
*/
#ifndef USE_TCL_STUBS
# undef  Tcl_InitStubs
# define Tcl_InitStubs(a,b,c)
#endif










/*
** Initialize this module.
**
** This Tcl module contains only a single new Tcl command named "sqlite".
** (Hence there is no namespace.  There is no point in using a namespace
** if the extension only supplies one new name!)  The "sqlite" command is
** used to open a new SQLite database.  See the DbMain() routine above
** for additional information.
*/
int Sqlite3_Init(Tcl_Interp *interp){
  Tcl_InitStubs(interp, "8.4", 0);
  Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  Tcl_PkgProvide(interp, "sqlite3", "3.0");
  Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  Tcl_PkgProvide(interp, "sqlite", "3.0");
  return TCL_OK;
}
int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }

#ifndef SQLITE_3_SUFFIX_ONLY
int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
#endif

#ifdef TCLSH
/*****************************************************************************
** The code that follows is used to build standalone TCL interpreters
*/

2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
#ifdef SQLITE_TEST
  {
    extern int Sqlitetest1_Init(Tcl_Interp*);
    extern int Sqlitetest2_Init(Tcl_Interp*);
    extern int Sqlitetest3_Init(Tcl_Interp*);
    extern int Sqlitetest4_Init(Tcl_Interp*);
    extern int Sqlitetest5_Init(Tcl_Interp*);
    extern int Sqlitetest6_Init(Tcl_Interp*);
    extern int Sqlitetest7_Init(Tcl_Interp*);
    extern int Md5_Init(Tcl_Interp*);
    extern int Sqlitetestsse_Init(Tcl_Interp*);
    extern int Sqlitetestasync_Init(Tcl_Interp*);

    Sqlitetest1_Init(interp);
    Sqlitetest2_Init(interp);
    Sqlitetest3_Init(interp);
    Sqlitetest4_Init(interp);
    Sqlitetest5_Init(interp);
    Sqlitetest6_Init(interp);
    Sqlitetest7_Init(interp);
    Sqlitetestasync_Init(interp);
    Md5_Init(interp);
#ifdef SQLITE_SSE
    Sqlitetestsse_Init(interp);
#endif
  }
#endif
  if( argc>=2 || TCLSH==2 ){
    int i;
    Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
    for(i=3-TCLSH; i<argc; i++){







<
<

<
<
<





<
<
<

<
<
<







1720
1721
1722
1723
1724
1725
1726


1727



1728
1729
1730
1731
1732



1733



1734
1735
1736
1737
1738
1739
1740
#ifdef SQLITE_TEST
  {
    extern int Sqlitetest1_Init(Tcl_Interp*);
    extern int Sqlitetest2_Init(Tcl_Interp*);
    extern int Sqlitetest3_Init(Tcl_Interp*);
    extern int Sqlitetest4_Init(Tcl_Interp*);
    extern int Sqlitetest5_Init(Tcl_Interp*);


    extern int Md5_Init(Tcl_Interp*);



    Sqlitetest1_Init(interp);
    Sqlitetest2_Init(interp);
    Sqlitetest3_Init(interp);
    Sqlitetest4_Init(interp);
    Sqlitetest5_Init(interp);



    Md5_Init(interp);



  }
#endif
  if( argc>=2 || TCLSH==2 ){
    int i;
    Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
    Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
    for(i=3-TCLSH; i<argc; i++){
Changes to SQLite.Interop/src/tokenize.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.19 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.1 2005/03/01 16:04:37 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
** the #include below.
*/
#include "keywordhash.h"


/*
** If X is a character that can be used in an identifier and
** X&0x80==0 then sqlite3IsIdChar[X] will be 1.  If X&0x80==0x80 then
** X is always an identifier character.  (Hence all UTF-8
** characters can be part of an identifier).  sqlite3IsIdChar[X] will
** be 0 for every character in the lower 128 ASCII characters
** that cannot be used as part of an identifier.
**
** In this implementation, an identifier can be a string of
** alphabetic characters, digits, and "_" plus any character
** with the high-order bit set.  The latter rule means that
** any sequence of UTF-8 characters or characters taken from
** an extended ISO8859 character set can form an identifier.
**
** Ticket #1066.  the SQL standard does not allow '$' in the
** middle of identfiers.  But many SQL implementations do. 
** SQLite will allow '$' in identifiers for compatibility.
** But the feature is undocumented.
*/
const char sqlite3IsIdChar[] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 2x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 3x */
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 4x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  /* 5x */
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 6x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  /* 7x */
};

#define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && sqlite3IsIdChar[c-0x20]))

/*
** Return the length of the token that begins at z[0]. 
** Store the token type in *tokenType before returning.
*/
static int getToken(const unsigned char *z, int *tokenType){
  int i, c;







|

|














|









|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
** the #include below.
*/
#include "keywordhash.h"


/*
** If X is a character that can be used in an identifier and
** X&0x80==0 then isIdChar[X] will be 1.  If X&0x80==0x80 then
** X is always an identifier character.  (Hence all UTF-8
** characters can be part of an identifier).  isIdChar[X] will
** be 0 for every character in the lower 128 ASCII characters
** that cannot be used as part of an identifier.
**
** In this implementation, an identifier can be a string of
** alphabetic characters, digits, and "_" plus any character
** with the high-order bit set.  The latter rule means that
** any sequence of UTF-8 characters or characters taken from
** an extended ISO8859 character set can form an identifier.
**
** Ticket #1066.  the SQL standard does not allow '$' in the
** middle of identfiers.  But many SQL implementations do. 
** SQLite will allow '$' in identifiers for compatibility.
** But the feature is undocumented.
*/
static const char isIdChar[] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 2x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  /* 3x */
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 4x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,  /* 5x */
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* 6x */
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,  /* 7x */
};

#define IdChar(C)  (((c=C)&0x80)!=0 || (c>0x1f && isIdChar[c-0x20]))

/*
** Return the length of the token that begins at z[0]. 
** Store the token type in *tokenType before returning.
*/
static int getToken(const unsigned char *z, int *tokenType){
  int i, c;
179
180
181
182
183
184
185
186




187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
      *tokenType = TK_BITAND;
      return 1;
    }
    case '~': {
      *tokenType = TK_BITNOT;
      return 1;
    }
    case '`':




    case '\'':
    case '"': {
      int delim = z[0];
      for(i=1; (c=z[i])!=0; i++){
        if( c==delim ){
          if( z[i+1]==delim ){
            i++;
          }else{
            break;
          }
        }
      }
      if( c ){
        *tokenType = TK_STRING;
        return i+1;
      }else{
        *tokenType = TK_ILLEGAL;
        return i;
      }
    }
    case '.': {
#ifndef SQLITE_OMIT_FLOATING_POINT
      if( !isdigit(z[1]) )
#endif
      {
        *tokenType = TK_DOT;
        return 1;
      }
      /* If the next character is a digit, this is a floating point
      ** number that begins with ".".  Fall thru into the next case */
    }
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9': {
      *tokenType = TK_INTEGER;
      for(i=0; isdigit(z[i]); i++){}
#ifndef SQLITE_OMIT_FLOATING_POINT
      if( z[i]=='.' ){
        i++;
        while( isdigit(z[i]) ){ i++; }
        *tokenType = TK_FLOAT;
      }
      if( (z[i]=='e' || z[i]=='E') &&
           ( isdigit(z[i+1]) 
            || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
           )







|
>
>
>
>
|
<










|
|
<
<
<
|
|
<

<
<
<
<
|
|
<
<
<




|

|
|







179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200
201
202
203



204
205

206




207
208



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
      *tokenType = TK_BITAND;
      return 1;
    }
    case '~': {
      *tokenType = TK_BITNOT;
      return 1;
    }
    case '#': {
      for(i=1; isdigit(z[i]) || (i==1 && z[1]=='-'); i++){}
      *tokenType = TK_REGISTER;
      return i;
    }
    case '\'': case '"': {

      int delim = z[0];
      for(i=1; (c=z[i])!=0; i++){
        if( c==delim ){
          if( z[i+1]==delim ){
            i++;
          }else{
            break;
          }
        }
      }
      if( c ) i++;
      *tokenType = TK_STRING;



      return i;
    }

    case '.': {




      *tokenType = TK_DOT;
      return 1;



    }
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9': {
      *tokenType = TK_INTEGER;
      for(i=1; isdigit(z[i]); i++){}
#ifndef SQLITE_OMIT_FLOATING_POINT
      if( z[i]=='.' && isdigit(z[i+1]) ){
        i += 2;
        while( isdigit(z[i]) ){ i++; }
        *tokenType = TK_FLOAT;
      }
      if( (z[i]=='e' || z[i]=='E') &&
           ( isdigit(z[i+1]) 
            || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
           )
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262




263

264




265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

290
291

292
293
294
295
296
297
298
      return i;
    }
    case '?': {
      *tokenType = TK_VARIABLE;
      for(i=1; isdigit(z[i]); i++){}
      return i;
    }
    case '#': {
      for(i=1; isdigit(z[i]); i++){}
      if( i>1 ){
        /* Parameters of the form #NNN (where NNN is a number) are used
        ** internally by sqlite3NestedParse.  */
        *tokenType = TK_REGISTER;
        return i;
      }
      /* Fall through into the next case if the '#' is not followed by
      ** a digit. Try to match #AAAA where AAAA is a parameter name. */
    }
#ifndef SQLITE_OMIT_TCL_VARIABLE
    case '$':




#endif

    case '@':




    case ':': {
      int n = 0;
      *tokenType = TK_VARIABLE;
      for(i=1; (c=z[i])!=0; i++){
        if( IdChar(c) ){
          n++;
#ifndef SQLITE_OMIT_TCL_VARIABLE
        }else if( c=='(' && n>0 ){
          do{
            i++;
          }while( (c=z[i])!=0 && !isspace(c) && c!=')' );
          if( c==')' ){
            i++;
          }else{
            *tokenType = TK_ILLEGAL;
          }
          break;
        }else if( c==':' && z[i+1]==':' ){
          i++;
#endif
        }else{
          break;
        }
      }
      if( n==0 ) *tokenType = TK_ILLEGAL;

      return i;
    }

#ifndef SQLITE_OMIT_BLOB_LITERAL
    case 'x': case 'X': {
      if( (c=z[1])=='\'' || c=='"' ){
        int delim = c;
        *tokenType = TK_BLOB;
        for(i=2; (c=z[i])!=0; i++){
          if( c==delim ){







|
|
<
<
<
|
|
|
<
<
<

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


>







235
236
237
238
239
240
241
242
243



244
245
246



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263
264

265
266
267
268
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
      return i;
    }
    case '?': {
      *tokenType = TK_VARIABLE;
      for(i=1; isdigit(z[i]); i++){}
      return i;
    }
    case ':': {
      for(i=1; IdChar(z[i]); i++){}



      *tokenType = i>1 ? TK_VARIABLE : TK_ILLEGAL;
      return i;
    }



#ifndef SQLITE_OMIT_TCL_VARIABLE
    case '$': {
      *tokenType = TK_VARIABLE;
      if( z[1]=='{' ){
        int nBrace = 1;
        for(i=2; (c=z[i])!=0 && nBrace; i++){
          if( c=='{' ){
            nBrace++;
          }else if( c=='}' ){
            nBrace--;
          }
        }
        if( c==0 ) *tokenType = TK_ILLEGAL;
      }else{
        int n = 0;

        for(i=1; (c=z[i])!=0; i++){
          if( isalnum(c) || c=='_' ){
            n++;

          }else if( c=='(' && n>0 ){
            do{
              i++;
            }while( (c=z[i])!=0 && !isspace(c) && c!=')' );
            if( c==')' ){
              i++;
            }else{
              *tokenType = TK_ILLEGAL;
            }
            break;
          }else if( c==':' && z[i+1]==':' ){
            i++;

          }else{
            break;
          }
        }
        if( n==0 ) *tokenType = TK_ILLEGAL;
      }
      return i;
    }
#endif
#ifndef SQLITE_OMIT_BLOB_LITERAL
    case 'x': case 'X': {
      if( (c=z[1])=='\'' || c=='"' ){
        int delim = c;
        *tokenType = TK_BLOB;
        for(i=2; (c=z[i])!=0; i++){
          if( c==delim ){
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
  int nErr = 0;
  int i;
  void *pEngine;
  int tokenType;
  int lastTokenParsed = -1;
  sqlite3 *db = pParse->db;
  ThreadData *pTsd = pParse->pTsd;
  extern void *sqlite3ParserAlloc(void*(*)(int));
  extern void sqlite3ParserFree(void*, void(*)(void*));
  extern int sqlite3Parser(void*, int, Token, Parse*);

  db->flags &= ~SQLITE_Interrupt;
  pParse->rc = SQLITE_OK;
  i = 0;
  pEngine = sqlite3ParserAlloc((void*(*)(int))sqlite3MallocX);
  if( pEngine==0 ){

    return SQLITE_NOMEM;
  }
  assert( pParse->sLastToken.dyn==0 );
  assert( pParse->pNewTable==0 );
  assert( pParse->pNewTrigger==0 );
  assert( pParse->nVar==0 );
  assert( pParse->nVarExpr==0 );
  assert( pParse->nVarExprAlloc==0 );
  assert( pParse->apVarExpr==0 );
  pParse->zTail = pParse->zSql = zSql;
  while( pTsd->mallocFailed==0 && zSql[i]!=0 ){
    assert( i>=0 );
    pParse->sLastToken.z = (u8*)&zSql[i];
    assert( pParse->sLastToken.dyn==0 );
    pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType);
    i += pParse->sLastToken.n;
    switch( tokenType ){
      case TK_SPACE:
      case TK_COMMENT: {
        if( (db->flags & SQLITE_Interrupt)!=0 ){







<







|

>
|









|

|







330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
  int nErr = 0;
  int i;
  void *pEngine;
  int tokenType;
  int lastTokenParsed = -1;
  sqlite3 *db = pParse->db;

  extern void *sqlite3ParserAlloc(void*(*)(int));
  extern void sqlite3ParserFree(void*, void(*)(void*));
  extern int sqlite3Parser(void*, int, Token, Parse*);

  db->flags &= ~SQLITE_Interrupt;
  pParse->rc = SQLITE_OK;
  i = 0;
  pEngine = sqlite3ParserAlloc((void*(*)(int))malloc);
  if( pEngine==0 ){
    sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
    return 1;
  }
  assert( pParse->sLastToken.dyn==0 );
  assert( pParse->pNewTable==0 );
  assert( pParse->pNewTrigger==0 );
  assert( pParse->nVar==0 );
  assert( pParse->nVarExpr==0 );
  assert( pParse->nVarExprAlloc==0 );
  assert( pParse->apVarExpr==0 );
  pParse->zTail = pParse->zSql = zSql;
  while( sqlite3_malloc_failed==0 && zSql[i]!=0 ){
    assert( i>=0 );
    pParse->sLastToken.z = &zSql[i];
    assert( pParse->sLastToken.dyn==0 );
    pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType);
    i += pParse->sLastToken.n;
    switch( tokenType ){
      case TK_SPACE:
      case TK_COMMENT: {
        if( (db->flags & SQLITE_Interrupt)!=0 ){
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444








































































































































































































































  if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
    if( lastTokenParsed!=TK_SEMI ){
      sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
      pParse->zTail = &zSql[i];
    }
    sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
  }
  sqlite3ParserFree(pEngine, sqlite3FreeX);
  if( pTsd->mallocFailed ){
    pParse->rc = SQLITE_NOMEM;
  }
  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0);

  }
  if( pParse->zErrMsg ){
    if( pzErrMsg && *pzErrMsg==0 ){
      *pzErrMsg = pParse->zErrMsg;
    }else{
      sqliteFree(pParse->zErrMsg);
    }
    pParse->zErrMsg = 0;
    if( !nErr ) nErr++;
  }
  if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
    sqlite3VdbeDelete(pParse->pVdbe);
    pParse->pVdbe = 0;
  }
#ifndef SQLITE_OMIT_SHARED_CACHE
  if( pParse->nested==0 ){
    sqliteFree(pParse->aTableLock);
    pParse->aTableLock = 0;
    pParse->nTableLock = 0;
  }
#endif
  sqlite3DeleteTable(pParse->db, pParse->pNewTable);
  sqlite3DeleteTrigger(pParse->pNewTrigger);
  sqliteFree(pParse->apVarExpr);
  if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
    pParse->rc = SQLITE_ERROR;
  }
  return nErr;
}















































































































































































































































|
|



|
>














<
<
<
<
<
<
<








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
  if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
    if( lastTokenParsed!=TK_SEMI ){
      sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
      pParse->zTail = &zSql[i];
    }
    sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
  }
  sqlite3ParserFree(pEngine, free);
  if( sqlite3_malloc_failed ){
    pParse->rc = SQLITE_NOMEM;
  }
  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc),
                    (char*)0);
  }
  if( pParse->zErrMsg ){
    if( pzErrMsg && *pzErrMsg==0 ){
      *pzErrMsg = pParse->zErrMsg;
    }else{
      sqliteFree(pParse->zErrMsg);
    }
    pParse->zErrMsg = 0;
    if( !nErr ) nErr++;
  }
  if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
    sqlite3VdbeDelete(pParse->pVdbe);
    pParse->pVdbe = 0;
  }







  sqlite3DeleteTable(pParse->db, pParse->pNewTable);
  sqlite3DeleteTrigger(pParse->pNewTrigger);
  sqliteFree(pParse->apVarExpr);
  if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
    pParse->rc = SQLITE_ERROR;
  }
  return nErr;
}

/*
** Token types used by the sqlite3_complete() routine.  See the header
** comments on that procedure for additional information.
*/
#define tkSEMI    0
#define tkWS      1
#define tkOTHER   2
#define tkEXPLAIN 3
#define tkCREATE  4
#define tkTEMP    5
#define tkTRIGGER 6
#define tkEND     7

/*
** Return TRUE if the given SQL string ends in a semicolon.
**
** Special handling is require for CREATE TRIGGER statements.
** Whenever the CREATE TRIGGER keywords are seen, the statement
** must end with ";END;".
**
** This implementation uses a state machine with 7 states:
**
**   (0) START     At the beginning or end of an SQL statement.  This routine
**                 returns 1 if it ends in the START state and 0 if it ends
**                 in any other state.
**
**   (1) NORMAL    We are in the middle of statement which ends with a single
**                 semicolon.
**
**   (2) EXPLAIN   The keyword EXPLAIN has been seen at the beginning of 
**                 a statement.
**
**   (3) CREATE    The keyword CREATE has been seen at the beginning of a
**                 statement, possibly preceeded by EXPLAIN and/or followed by
**                 TEMP or TEMPORARY
**
**   (4) TRIGGER   We are in the middle of a trigger definition that must be
**                 ended by a semicolon, the keyword END, and another semicolon.
**
**   (5) SEMI      We've seen the first semicolon in the ";END;" that occurs at
**                 the end of a trigger definition.
**
**   (6) END       We've seen the ";END" of the ";END;" that occurs at the end
**                 of a trigger difinition.
**
** Transitions between states above are determined by tokens extracted
** from the input.  The following tokens are significant:
**
**   (0) tkSEMI      A semicolon.
**   (1) tkWS        Whitespace
**   (2) tkOTHER     Any other SQL token.
**   (3) tkEXPLAIN   The "explain" keyword.
**   (4) tkCREATE    The "create" keyword.
**   (5) tkTEMP      The "temp" or "temporary" keyword.
**   (6) tkTRIGGER   The "trigger" keyword.
**   (7) tkEND       The "end" keyword.
**
** Whitespace never causes a state transition and is always ignored.
**
** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
** to recognize the end of a trigger can be omitted.  All we have to do
** is look for a semicolon that is not part of an string or comment.
*/
int sqlite3_complete(const char *zSql){
  u8 state = 0;   /* Current state, using numbers defined in header comment */
  u8 token;       /* Value of the next token */

#ifndef SQLITE_OMIT_TRIGGER
  /* A complex statement machine used to detect the end of a CREATE TRIGGER
  ** statement.  This is the normal case.
  */
  static const u8 trans[7][8] = {
                     /* Token:                                                */
     /* State:       **  SEMI  WS  OTHER EXPLAIN  CREATE  TEMP  TRIGGER  END  */
     /* 0   START: */ {    0,  0,     1,      2,      3,    1,       1,   1,  },
     /* 1  NORMAL: */ {    0,  1,     1,      1,      1,    1,       1,   1,  },
     /* 2 EXPLAIN: */ {    0,  2,     1,      1,      3,    1,       1,   1,  },
     /* 3  CREATE: */ {    0,  3,     1,      1,      1,    3,       4,   1,  },
     /* 4 TRIGGER: */ {    5,  4,     4,      4,      4,    4,       4,   4,  },
     /* 5    SEMI: */ {    5,  5,     4,      4,      4,    4,       4,   6,  },
     /* 6     END: */ {    0,  6,     4,      4,      4,    4,       4,   4,  },
  };
#else
  /* If triggers are not suppored by this compile then the statement machine
  ** used to detect the end of a statement is much simplier
  */
  static const u8 trans[2][3] = {
                     /* Token:           */
     /* State:       **  SEMI  WS  OTHER */
     /* 0   START: */ {    0,  0,     1, },
     /* 1  NORMAL: */ {    0,  1,     1, },
  };
#endif /* SQLITE_OMIT_TRIGGER */

  while( *zSql ){
    switch( *zSql ){
      case ';': {  /* A semicolon */
        token = tkSEMI;
        break;
      }
      case ' ':
      case '\r':
      case '\t':
      case '\n':
      case '\f': {  /* White space is ignored */
        token = tkWS;
        break;
      }
      case '/': {   /* C-style comments */
        if( zSql[1]!='*' ){
          token = tkOTHER;
          break;
        }
        zSql += 2;
        while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
        if( zSql[0]==0 ) return 0;
        zSql++;
        token = tkWS;
        break;
      }
      case '-': {   /* SQL-style comments from "--" to end of line */
        if( zSql[1]!='-' ){
          token = tkOTHER;
          break;
        }
        while( *zSql && *zSql!='\n' ){ zSql++; }
        if( *zSql==0 ) return state==0;
        token = tkWS;
        break;
      }
      case '[': {   /* Microsoft-style identifiers in [...] */
        zSql++;
        while( *zSql && *zSql!=']' ){ zSql++; }
        if( *zSql==0 ) return 0;
        token = tkOTHER;
        break;
      }
      case '"':     /* single- and double-quoted strings */
      case '\'': {
        int c = *zSql;
        zSql++;
        while( *zSql && *zSql!=c ){ zSql++; }
        if( *zSql==0 ) return 0;
        token = tkOTHER;
        break;
      }
      default: {
        int c;
        if( IdChar((u8)*zSql) ){
          /* Keywords and unquoted identifiers */
          int nId;
          for(nId=1; IdChar(zSql[nId]); nId++){}
#ifdef SQLITE_OMIT_TRIGGER
          token = tkOTHER;
#else
          switch( *zSql ){
            case 'c': case 'C': {
              if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
                token = tkCREATE;
              }else{
                token = tkOTHER;
              }
              break;
            }
            case 't': case 'T': {
              if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
                token = tkTRIGGER;
              }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
                token = tkTEMP;
              }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
                token = tkTEMP;
              }else{
                token = tkOTHER;
              }
              break;
            }
            case 'e':  case 'E': {
              if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
                token = tkEND;
              }else
#ifndef SQLITE_OMIT_EXPLAIN
              if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
                token = tkEXPLAIN;
              }else
#endif
              {
                token = tkOTHER;
              }
              break;
            }
            default: {
              token = tkOTHER;
              break;
            }
          }
#endif /* SQLITE_OMIT_TRIGGER */
          zSql += nId-1;
        }else{
          /* Operators and special symbols */
          token = tkOTHER;
        }
        break;
      }
    }
    state = trans[state][token];
    zSql++;
  }
  return state==0;
}

#ifndef SQLITE_OMIT_UTF16
/*
** This routine is the same as the sqlite3_complete() routine described
** above, except that the parameter is required to be UTF-16 encoded, not
** UTF-8.
*/
int sqlite3_complete16(const void *zSql){
  sqlite3_value *pVal;
  char const *zSql8;
  int rc = 0;

  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
  if( zSql8 ){
    rc = sqlite3_complete(zSql8);
  }
  sqlite3ValueFree(pVal);
  return rc;
}
#endif /* SQLITE_OMIT_UTF16 */
Changes to SQLite.Interop/src/trigger.c.
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  int op,             /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
  IdList *pColumns,   /* column list if this is an UPDATE OF trigger */
  SrcList *pTableName,/* The name of the table/view the trigger applies to */
  int foreach,        /* One of TK_ROW or TK_STATEMENT */
  Expr *pWhen,        /* WHEN clause */
  int isTemp          /* True if the TEMPORARY keyword is present */
){
  Trigger *pTrigger = 0;
  Table *pTab;
  char *zName = 0;        /* Name of the trigger */
  sqlite3 *db = pParse->db;
  int iDb;                /* The database to store the trigger in */
  Token *pName;           /* The unqualified db name */
  DbFixer sFix;
  int iTabDb;

  if( isTemp ){
    /* If TEMP was specified, then the trigger name may not be qualified. */
    if( pName2 && pName2->n>0 ){
      sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
      goto trigger_cleanup;
    }







|






<







47
48
49
50
51
52
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
  int op,             /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
  IdList *pColumns,   /* column list if this is an UPDATE OF trigger */
  SrcList *pTableName,/* The name of the table/view the trigger applies to */
  int foreach,        /* One of TK_ROW or TK_STATEMENT */
  Expr *pWhen,        /* WHEN clause */
  int isTemp          /* True if the TEMPORARY keyword is present */
){
  Trigger *pTrigger;
  Table *pTab;
  char *zName = 0;        /* Name of the trigger */
  sqlite3 *db = pParse->db;
  int iDb;                /* The database to store the trigger in */
  Token *pName;           /* The unqualified db name */
  DbFixer sFix;


  if( isTemp ){
    /* If TEMP was specified, then the trigger name may not be qualified. */
    if( pName2 && pName2->n>0 ){
      sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
      goto trigger_cleanup;
    }
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
  }

  /* If the trigger name was unqualified, and the table is a temp table,
  ** then set iDb to 1 to create the trigger in the temporary database.
  ** If sqlite3SrcListLookup() returns 0, indicating the table does not
  ** exist, the error is caught by the block below.
  */
  if( !pTableName || sqlite3ThreadDataReadOnly()->mallocFailed ){
    goto trigger_cleanup;
  }
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
    iDb = 1;
  }

  /* Ensure the table name matches database name and that the table exists */
  if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto trigger_cleanup;
  assert( pTableName->nSrc==1 );
  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && 
      sqlite3FixSrcList(&sFix, pTableName) ){
    goto trigger_cleanup;
  }
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( !pTab ){
    /* The table does not exist. */
    goto trigger_cleanup;
  }

  /* Check that the trigger name is not reserved and that no trigger of the
  ** specified name exists */
  zName = sqlite3NameFromToken(pName);
  if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
    goto trigger_cleanup;
  }
  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,pName->n+1) ){
    sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
    goto trigger_cleanup;
  }

  /* Do not create a trigger on a system table */
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
    sqlite3ErrorMsg(pParse, "cannot create trigger on system table");







<
|
<

|




|

















|







76
77
78
79
80
81
82

83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  }

  /* If the trigger name was unqualified, and the table is a temp table,
  ** then set iDb to 1 to create the trigger in the temporary database.
  ** If sqlite3SrcListLookup() returns 0, indicating the table does not
  ** exist, the error is caught by the block below.
  */

  if( !pTableName || sqlite3_malloc_failed ) goto trigger_cleanup;

  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( pName2->n==0 && pTab && pTab->iDb==1 ){
    iDb = 1;
  }

  /* Ensure the table name matches database name and that the table exists */
  if( sqlite3_malloc_failed ) goto trigger_cleanup;
  assert( pTableName->nSrc==1 );
  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && 
      sqlite3FixSrcList(&sFix, pTableName) ){
    goto trigger_cleanup;
  }
  pTab = sqlite3SrcListLookup(pParse, pTableName);
  if( !pTab ){
    /* The table does not exist. */
    goto trigger_cleanup;
  }

  /* Check that the trigger name is not reserved and that no trigger of the
  ** specified name exists */
  zName = sqlite3NameFromToken(pName);
  if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
    goto trigger_cleanup;
  }
  if( sqlite3HashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
    sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
    goto trigger_cleanup;
  }

  /* Do not create a trigger on a system table */
  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
    sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
    goto trigger_cleanup;
  }
  if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
    sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
        " trigger on table: %S", pTableName, 0);
    goto trigger_cleanup;
  }
  iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);

#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_CREATE_TRIGGER;
    const char *zDb = db->aDb[iTabDb].zName;
    const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
    if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
    if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
      goto trigger_cleanup;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){
      goto trigger_cleanup;
    }
  }
#endif

  /* INSTEAD OF triggers can only appear on views and BEFORE triggers
  ** cannot appear on views.  So we might as well translate every
  ** INSTEAD OF trigger into a BEFORE trigger.  It simplifies code
  ** elsewhere.
  */
  if (tr_tm == TK_INSTEAD){
    tr_tm = TK_BEFORE;
  }

  /* Build the Trigger object */
  pTrigger = (Trigger*)sqliteMalloc(sizeof(Trigger));
  if( pTrigger==0 ) goto trigger_cleanup;
  pTrigger->name = zName;
  zName = 0;
  pTrigger->table = sqliteStrDup(pTableName->a[0].zName);

  pTrigger->pSchema = db->aDb[iDb].pSchema;
  pTrigger->pTabSchema = pTab->pSchema;
  pTrigger->op = op;
  pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
  pTrigger->pWhen = sqlite3ExprDup(pWhen);
  pTrigger->pColumns = sqlite3IdListDup(pColumns);
  pTrigger->foreach = foreach;
  sqlite3TokenCopy(&pTrigger->nameToken,pName);
  assert( pParse->pNewTrigger==0 );
  pParse->pNewTrigger = pTrigger;

trigger_cleanup:
  sqliteFree(zName);
  sqlite3SrcListDelete(pTableName);
  sqlite3IdListDelete(pColumns);
  sqlite3ExprDelete(pWhen);
  if( !pParse->pNewTrigger ){
    sqlite3DeleteTrigger(pTrigger);
  }else{
    assert( pParse->pNewTrigger==pTrigger );
  }
}

/*
** This routine is called after all of the trigger actions have been parsed
** in order to complete the process of building the trigger.
*/
void sqlite3FinishTrigger(
  Parse *pParse,          /* Parser context */
  TriggerStep *pStepList, /* The triggered program */
  Token *pAll             /* Token that describes the complete CREATE TRIGGER */
){
  Trigger *pTrig = 0;     /* The trigger whose construction is finishing up */
  sqlite3 *db = pParse->db;  /* The database */
  DbFixer sFix;
  int iDb;                   /* Database containing the trigger */


  pTrig = pParse->pNewTrigger;
  pParse->pNewTrigger = 0;
  if( pParse->nErr || !pTrig ) goto triggerfinish_cleanup;
  iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
  pTrig->step_list = pStepList;
  while( pStepList ){
    pStepList->pTrig = pTrig;
    pStepList = pStepList->pNext;
  }
  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &pTrig->nameToken) 
          && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
    goto triggerfinish_cleanup;
  }

  /* if we are not initializing, and this trigger is not on a TEMP table, 
  ** build the sqlite_master entry
  */
  if( !db->init.busy ){
    static const VdbeOpList insertTrig[] = {
      { OP_NewRowid,   0, 0,  0          },
      { OP_String8,    0, 0,  "trigger"  },
      { OP_String8,    0, 0,  0          },  /* 2: trigger name */
      { OP_String8,    0, 0,  0          },  /* 3: table name */
      { OP_Integer,    0, 0,  0          },
      { OP_String8,    0, 0,  "CREATE TRIGGER "},
      { OP_String8,    0, 0,  0          },  /* 6: SQL */
      { OP_Concat,     0, 0,  0          }, 
      { OP_MakeRecord, 5, 0,  "aaada"    },
      { OP_Insert,     0, 0,  0          },
    };
    int addr;
    Vdbe *v;

    /* Make an entry in the sqlite_master table */
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto triggerfinish_cleanup;
    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3OpenMasterTable(pParse, iDb);
    addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
    sqlite3VdbeChangeP3(v, addr+2, pTrig->name, 0); 
    sqlite3VdbeChangeP3(v, addr+3, pTrig->table, 0); 
    sqlite3VdbeChangeP3(v, addr+6, (char*)pAll->z, pAll->n);
    sqlite3ChangeCookie(db, v, iDb);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, 
       sqlite3MPrintf("type='trigger' AND name='%q'", pTrig->name), P3_DYNAMIC);
  }

  if( db->init.busy ){
    int n;
    Table *pTab;
    Trigger *pDel;
    pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash, 
                     pTrig->name, strlen(pTrig->name)+1, pTrig);
    if( pDel ){
      assert( sqlite3ThreadDataReadOnly()->mallocFailed && pDel==pTrig );
      goto triggerfinish_cleanup;
    }
    n = strlen(pTrig->table) + 1;
    pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n);
    assert( pTab!=0 );
    pTrig->pNext = pTab->pTrigger;
    pTab->pTrigger = pTrig;
    pTrig = 0;
  }

triggerfinish_cleanup:







<




|

|



|




















>
|
|














<
<
<
<
<














<

>


<
<





|









|







|
|







|
|



|
|

|




<

<
|

<
<
<
<
<
|







126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180





181
182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

244

245
246





247
248
249
250
251
252
253
254
    goto trigger_cleanup;
  }
  if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
    sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
        " trigger on table: %S", pTableName, 0);
    goto trigger_cleanup;
  }


#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_CREATE_TRIGGER;
    const char *zDb = db->aDb[pTab->iDb].zName;
    const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
    if( pTab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
    if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
      goto trigger_cleanup;
    }
    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(pTab->iDb),0,zDb)){
      goto trigger_cleanup;
    }
  }
#endif

  /* INSTEAD OF triggers can only appear on views and BEFORE triggers
  ** cannot appear on views.  So we might as well translate every
  ** INSTEAD OF trigger into a BEFORE trigger.  It simplifies code
  ** elsewhere.
  */
  if (tr_tm == TK_INSTEAD){
    tr_tm = TK_BEFORE;
  }

  /* Build the Trigger object */
  pTrigger = (Trigger*)sqliteMalloc(sizeof(Trigger));
  if( pTrigger==0 ) goto trigger_cleanup;
  pTrigger->name = zName;
  zName = 0;
  pTrigger->table = sqliteStrDup(pTableName->a[0].zName);
  if( sqlite3_malloc_failed ) goto trigger_cleanup;
  pTrigger->iDb = iDb;
  pTrigger->iTabDb = pTab->iDb;
  pTrigger->op = op;
  pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
  pTrigger->pWhen = sqlite3ExprDup(pWhen);
  pTrigger->pColumns = sqlite3IdListDup(pColumns);
  pTrigger->foreach = foreach;
  sqlite3TokenCopy(&pTrigger->nameToken,pName);
  assert( pParse->pNewTrigger==0 );
  pParse->pNewTrigger = pTrigger;

trigger_cleanup:
  sqliteFree(zName);
  sqlite3SrcListDelete(pTableName);
  sqlite3IdListDelete(pColumns);
  sqlite3ExprDelete(pWhen);





}

/*
** This routine is called after all of the trigger actions have been parsed
** in order to complete the process of building the trigger.
*/
void sqlite3FinishTrigger(
  Parse *pParse,          /* Parser context */
  TriggerStep *pStepList, /* The triggered program */
  Token *pAll             /* Token that describes the complete CREATE TRIGGER */
){
  Trigger *pTrig = 0;     /* The trigger whose construction is finishing up */
  sqlite3 *db = pParse->db;  /* The database */
  DbFixer sFix;


  if( pParse->nErr || pParse->pNewTrigger==0 ) goto triggerfinish_cleanup;
  pTrig = pParse->pNewTrigger;
  pParse->pNewTrigger = 0;


  pTrig->step_list = pStepList;
  while( pStepList ){
    pStepList->pTrig = pTrig;
    pStepList = pStepList->pNext;
  }
  if( sqlite3FixInit(&sFix, pParse, pTrig->iDb, "trigger", &pTrig->nameToken) 
          && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
    goto triggerfinish_cleanup;
  }

  /* if we are not initializing, and this trigger is not on a TEMP table, 
  ** build the sqlite_master entry
  */
  if( !db->init.busy ){
    static const VdbeOpList insertTrig[] = {
      { OP_NewRecno,   0, 0,  0          },
      { OP_String8,    0, 0,  "trigger"  },
      { OP_String8,    0, 0,  0          },  /* 2: trigger name */
      { OP_String8,    0, 0,  0          },  /* 3: table name */
      { OP_Integer,    0, 0,  0          },
      { OP_String8,    0, 0,  "CREATE TRIGGER "},
      { OP_String8,    0, 0,  0          },  /* 6: SQL */
      { OP_Concat,     0, 0,  0          }, 
      { OP_MakeRecord, 5, 0,  "tttit"    },
      { OP_PutIntKey,  0, 0,  0          },
    };
    int addr;
    Vdbe *v;

    /* Make an entry in the sqlite_master table */
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto triggerfinish_cleanup;
    sqlite3BeginWriteOperation(pParse, 0, pTrig->iDb);
    sqlite3OpenMasterTable(v, pTrig->iDb);
    addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
    sqlite3VdbeChangeP3(v, addr+2, pTrig->name, 0); 
    sqlite3VdbeChangeP3(v, addr+3, pTrig->table, 0); 
    sqlite3VdbeChangeP3(v, addr+6, pAll->z, pAll->n);
    sqlite3ChangeCookie(db, v, pTrig->iDb);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeOp3(v, OP_ParseSchema, pTrig->iDb, 0, 
       sqlite3MPrintf("type='trigger' AND name='%q'", pTrig->name), P3_DYNAMIC);
  }

  if( db->init.busy ){

    Table *pTab;

    sqlite3HashInsert(&db->aDb[pTrig->iDb].trigHash, 
                     pTrig->name, strlen(pTrig->name)+1, pTrig);





    pTab = sqlite3LocateTable(pParse,pTrig->table,db->aDb[pTrig->iTabDb].zName);
    assert( pTab!=0 );
    pTrig->pNext = pTab->pTrigger;
    pTab->pTrigger = pTrig;
    pTrig = 0;
  }

triggerfinish_cleanup:
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
** string is ephemeral - it will go away as soon as the sqlite3_exec()
** call that started the parser exits.  This routine makes a persistent
** copy of all the Expr.token.z strings so that the TriggerStep structure
** will be valid even after the sqlite3_exec() call returns.
*/
static void sqlitePersistTriggerStep(TriggerStep *p){
  if( p->target.z ){
    p->target.z = (u8*)sqliteStrNDup((char*)p->target.z, p->target.n);
    p->target.dyn = 1;
  }
  if( p->pSelect ){
    Select *pNew = sqlite3SelectDup(p->pSelect);
    sqlite3SelectDelete(p->pSelect);
    p->pSelect = pNew;
  }







|







265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
** string is ephemeral - it will go away as soon as the sqlite3_exec()
** call that started the parser exits.  This routine makes a persistent
** copy of all the Expr.token.z strings so that the TriggerStep structure
** will be valid even after the sqlite3_exec() call returns.
*/
static void sqlitePersistTriggerStep(TriggerStep *p){
  if( p->target.z ){
    p->target.z = sqliteStrNDup(p->target.z, p->target.n);
    p->target.dyn = 1;
  }
  if( p->pSelect ){
    Select *pNew = sqlite3SelectDup(p->pSelect);
    sqlite3SelectDelete(p->pSelect);
    p->pSelect = pNew;
  }
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
** a trigger step.  Return a pointer to a TriggerStep structure.
**
** The parser calls this routine when it finds a SELECT statement in
** body of a TRIGGER.  
*/
TriggerStep *sqlite3TriggerSelectStep(Select *pSelect){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) {
    sqlite3SelectDelete(pSelect);
    return 0;
  }

  pTriggerStep->op = TK_SELECT;
  pTriggerStep->pSelect = pSelect;
  pTriggerStep->orconf = OE_Default;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;







|
<
<
<







299
300
301
302
303
304
305
306



307
308
309
310
311
312
313
** a trigger step.  Return a pointer to a TriggerStep structure.
**
** The parser calls this routine when it finds a SELECT statement in
** body of a TRIGGER.  
*/
TriggerStep *sqlite3TriggerSelectStep(Select *pSelect){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;




  pTriggerStep->op = TK_SELECT;
  pTriggerStep->pSelect = pSelect;
  pTriggerStep->orconf = OE_Default;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  Token *pTableName,  /* Name of the table into which we insert */
  IdList *pColumn,    /* List of columns in pTableName to insert into */
  ExprList *pEList,   /* The VALUE clause: a list of values to be inserted */
  Select *pSelect,    /* A SELECT statement that supplies values */
  int orconf          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));


  assert(pEList == 0 || pSelect == 0);
  assert(pEList != 0 || pSelect != 0);

  if( pTriggerStep ){
    pTriggerStep->op = TK_INSERT;
    pTriggerStep->pSelect = pSelect;
    pTriggerStep->target  = *pTableName;
    pTriggerStep->pIdList = pColumn;
    pTriggerStep->pExprList = pEList;
    pTriggerStep->orconf = orconf;
    sqlitePersistTriggerStep(pTriggerStep);
  }else{
    sqlite3IdListDelete(pColumn);
    sqlite3ExprListDelete(pEList);
    sqlite3SelectDup(pSelect);
  }

  return pTriggerStep;
}

/*
** Construct a trigger step that implements an UPDATE statement and return
** a pointer to that trigger step.  The parser calls this routine when it







>




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







324
325
326
327
328
329
330
331
332
333
334
335

336
337
338
339
340
341
342





343
344
345
346
347
348
349
  Token *pTableName,  /* Name of the table into which we insert */
  IdList *pColumn,    /* List of columns in pTableName to insert into */
  ExprList *pEList,   /* The VALUE clause: a list of values to be inserted */
  Select *pSelect,    /* A SELECT statement that supplies values */
  int orconf          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
){
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

  assert(pEList == 0 || pSelect == 0);
  assert(pEList != 0 || pSelect != 0);


  pTriggerStep->op = TK_INSERT;
  pTriggerStep->pSelect = pSelect;
  pTriggerStep->target  = *pTableName;
  pTriggerStep->pIdList = pColumn;
  pTriggerStep->pExprList = pEList;
  pTriggerStep->orconf = orconf;
  sqlitePersistTriggerStep(pTriggerStep);






  return pTriggerStep;
}

/*
** Construct a trigger step that implements an UPDATE statement and return
** a pointer to that trigger step.  The parser calls this routine when it
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
  Trigger *pTrigger = 0;
  int i;
  const char *zDb;
  const char *zName;
  int nName;
  sqlite3 *db = pParse->db;

  if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto drop_trigger_cleanup;
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto drop_trigger_cleanup;
  }

  assert( pName->nSrc==1 );
  zDb = pName->a[0].zDatabase;
  zName = pName->a[0].zName;
  nName = strlen(zName);
  for(i=OMIT_TEMPDB; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
    pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName+1);
    if( pTrigger ) break;
  }
  if( !pTrigger ){
    sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
    goto drop_trigger_cleanup;
  }
  sqlite3DropTriggerPtr(pParse, pTrigger, 0);

drop_trigger_cleanup:
  sqlite3SrcListDelete(pName);
}

/*
** Return a pointer to the Table structure for the table that a trigger
** is set on.
*/
static Table *tableOfTrigger(sqlite3 *db, Trigger *pTrigger){
  int n = strlen(pTrigger->table) + 1;
  return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
}


/*
** Drop a trigger given a pointer to that trigger.  If nested is false,
** then also generate code to remove the trigger from the SQLITE_MASTER
** table.
*/
void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
  Table   *pTable;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
  assert( iDb>=0 && iDb<db->nDb );
  pTable = tableOfTrigger(db, pTrigger);
  assert(pTable);
  assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[iDb].zName;
    const char *zTab = SCHEMA_TABLE(iDb);
    if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqlite3AuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||







|








|


|

















|
<














|



|







412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449

450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
  Trigger *pTrigger = 0;
  int i;
  const char *zDb;
  const char *zName;
  int nName;
  sqlite3 *db = pParse->db;

  if( sqlite3_malloc_failed ) goto drop_trigger_cleanup;
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
    goto drop_trigger_cleanup;
  }

  assert( pName->nSrc==1 );
  zDb = pName->a[0].zDatabase;
  zName = pName->a[0].zName;
  nName = strlen(zName);
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
    pTrigger = sqlite3HashFind(&(db->aDb[j].trigHash), zName, nName+1);
    if( pTrigger ) break;
  }
  if( !pTrigger ){
    sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
    goto drop_trigger_cleanup;
  }
  sqlite3DropTriggerPtr(pParse, pTrigger, 0);

drop_trigger_cleanup:
  sqlite3SrcListDelete(pName);
}

/*
** Return a pointer to the Table structure for the table that a trigger
** is set on.
*/
static Table *tableOfTrigger(sqlite3 *db, Trigger *pTrigger){
  return sqlite3FindTable(db,pTrigger->table,db->aDb[pTrigger->iTabDb].zName);

}


/*
** Drop a trigger given a pointer to that trigger.  If nested is false,
** then also generate code to remove the trigger from the SQLITE_MASTER
** table.
*/
void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
  Table   *pTable;
  Vdbe *v;
  sqlite3 *db = pParse->db;
  int iDb;

  iDb = pTrigger->iDb;
  assert( iDb>=0 && iDb<db->nDb );
  pTable = tableOfTrigger(db, pTrigger);
  assert(pTable);
  assert( pTable->iDb==iDb || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[iDb].zName;
    const char *zTab = SCHEMA_TABLE(iDb);
    if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqlite3AuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
      { OP_Column,     0, 0,        0},
      { OP_Ne,         0, ADDR(8),  0},
      { OP_Delete,     0, 0,        0},
      { OP_Next,       0, ADDR(1),  0}, /* 8 */
    };

    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3OpenMasterTable(pParse, iDb);
    base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
    sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0);
    sqlite3ChangeCookie(db, v, iDb);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeOp3(v, OP_DropTrigger, iDb, 0, pTrigger->name, 0);
  }
}

/*
** Remove a trigger from the hash tables of the sqlite* pointer.
*/
void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
  Trigger *pTrigger;
  int nName = strlen(zName);
  pTrigger = sqlite3HashInsert(&(db->aDb[iDb].pSchema->trigHash), zName, nName+1, 0);
  if( pTrigger ){
    Table *pTable = tableOfTrigger(db, pTrigger);
    assert( pTable!=0 );
    if( pTable->pTrigger == pTrigger ){
      pTable->pTrigger = pTrigger->pNext;
    }else{
      Trigger *cc = pTable->pTrigger;







|














|







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
      { OP_Column,     0, 0,        0},
      { OP_Ne,         0, ADDR(8),  0},
      { OP_Delete,     0, 0,        0},
      { OP_Next,       0, ADDR(1),  0}, /* 8 */
    };

    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3OpenMasterTable(v, iDb);
    base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
    sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0);
    sqlite3ChangeCookie(db, v, iDb);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeOp3(v, OP_DropTrigger, iDb, 0, pTrigger->name, 0);
  }
}

/*
** Remove a trigger from the hash tables of the sqlite* pointer.
*/
void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
  Trigger *pTrigger;
  int nName = strlen(zName);
  pTrigger = sqlite3HashInsert(&(db->aDb[iDb].trigHash), zName, nName+1, 0);
  if( pTrigger ){
    Table *pTable = tableOfTrigger(db, pTrigger);
    assert( pTable!=0 );
    if( pTable->pTrigger == pTrigger ){
      pTable->pTrigger = pTrigger->pNext;
    }else{
      Trigger *cc = pTable->pTrigger;
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
  Parse *pParse,       /* The parsing context */
  TriggerStep *pStep   /* The trigger containing the target token */
){
  Token sDb;           /* Dummy database name token */
  int iDb;             /* Index of the database to use */
  SrcList *pSrc;       /* SrcList to be returned */

  iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
  if( iDb==0 || iDb>=2 ){
    assert( iDb<pParse->db->nDb );
    sDb.z = (u8*)pParse->db->aDb[iDb].zName;
    sDb.n = strlen((char*)sDb.z);
    pSrc = sqlite3SrcListAppend(0, &sDb, &pStep->target);
  } else {
    pSrc = sqlite3SrcListAppend(0, &pStep->target, 0);
  }
  return pSrc;
}








|


|
|







599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
  Parse *pParse,       /* The parsing context */
  TriggerStep *pStep   /* The trigger containing the target token */
){
  Token sDb;           /* Dummy database name token */
  int iDb;             /* Index of the database to use */
  SrcList *pSrc;       /* SrcList to be returned */

  iDb = pStep->pTrig->iDb;
  if( iDb==0 || iDb>=2 ){
    assert( iDb<pParse->db->nDb );
    sDb.z = pParse->db->aDb[iDb].zName;
    sDb.n = strlen(sDb.z);
    pSrc = sqlite3SrcListAppend(0, &sDb, &pStep->target);
  } else {
    pSrc = sqlite3SrcListAppend(0, &pStep->target, 0);
  }
  return pSrc;
}

738
739
740
741
742
743
744
745

746
747
748
749
750
751
752
753

754
755
756
757
758
759
760
761
762
763
764
765
766





767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807

808
809
810
811
  int tr_tm,           /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
  Table *pTab,         /* The table to code triggers from */
  int newIdx,          /* The indice of the "new" row to access */
  int oldIdx,          /* The indice of the "old" row to access */
  int orconf,          /* ON CONFLICT policy */
  int ignoreJump       /* Instruction to jump to for RAISE(IGNORE) */
){
  Trigger *p;

  TriggerStack trigStackEntry;

  assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
  assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER );

  assert(newIdx != -1 || oldIdx != -1);

  for(p=pTab->pTrigger; p; p=p->pNext){

    int fire_this = 0;

    /* Determine whether we should code this trigger */
    if( 
      p->op==op && 
      p->tr_tm==tr_tm && 
      (p->pSchema==p->pTabSchema || p->pSchema==pParse->db->aDb[1].pSchema) &&
      (op!=TK_UPDATE||!p->pColumns||checkColumnOverLap(p->pColumns,pChanges))
    ){
      TriggerStack *pS;      /* Pointer to trigger-stack entry */
      for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext);
      if( !pS ){
        fire_this = 1;





      }
    }
 
    if( fire_this ){
      int endTrigger;
      Expr * whenExpr;
      AuthContext sContext;
      NameContext sNC;

      memset(&sNC, 0, sizeof(sNC));
      sNC.pParse = pParse;

      /* Push an entry on to the trigger stack */
      trigStackEntry.pTrigger = p;
      trigStackEntry.newIdx = newIdx;
      trigStackEntry.oldIdx = oldIdx;
      trigStackEntry.pTab = pTab;
      trigStackEntry.pNext = pParse->trigStack;
      trigStackEntry.ignoreJump = ignoreJump;
      pParse->trigStack = &trigStackEntry;
      sqlite3AuthContextPush(pParse, &sContext, p->name);

      /* code the WHEN clause */
      endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
      whenExpr = sqlite3ExprDup(p->pWhen);
      if( sqlite3ExprResolveNames(&sNC, whenExpr) ){
        pParse->trigStack = trigStackEntry.pNext;
        sqlite3ExprDelete(whenExpr);
        return 1;
      }
      sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1);
      sqlite3ExprDelete(whenExpr);

      codeTriggerProgram(pParse, p->step_list, orconf); 

      /* Pop the entry off the trigger stack */
      pParse->trigStack = trigStackEntry.pNext;
      sqlite3AuthContextPop(&sContext);

      sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);
    }

  }
  return 0;
}
#endif /* !defined(SQLITE_OMIT_TRIGGER) */







|
>







|
>


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













|






|



|








|







>




712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732

733
734




735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
  int tr_tm,           /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
  Table *pTab,         /* The table to code triggers from */
  int newIdx,          /* The indice of the "new" row to access */
  int oldIdx,          /* The indice of the "old" row to access */
  int orconf,          /* ON CONFLICT policy */
  int ignoreJump       /* Instruction to jump to for RAISE(IGNORE) */
){
  Trigger *pTrigger;
  TriggerStack *pStack;
  TriggerStack trigStackEntry;

  assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
  assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER );

  assert(newIdx != -1 || oldIdx != -1);

  pTrigger = pTab->pTrigger;
  while( pTrigger ){
    int fire_this = 0;

    /* determine whether we should code this trigger */

    if( pTrigger->op == op && pTrigger->tr_tm == tr_tm ){
      fire_this = 1;




      for(pStack=pParse->trigStack; pStack; pStack=pStack->pNext){
        if( pStack->pTrigger==pTrigger ){
	  fire_this = 0;
	}
      }
      if( op == TK_UPDATE && pTrigger->pColumns &&
          !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
        fire_this = 0;
      }
    }
 
    if( fire_this ){
      int endTrigger;
      Expr * whenExpr;
      AuthContext sContext;
      NameContext sNC;

      memset(&sNC, 0, sizeof(sNC));
      sNC.pParse = pParse;

      /* Push an entry on to the trigger stack */
      trigStackEntry.pTrigger = pTrigger;
      trigStackEntry.newIdx = newIdx;
      trigStackEntry.oldIdx = oldIdx;
      trigStackEntry.pTab = pTab;
      trigStackEntry.pNext = pParse->trigStack;
      trigStackEntry.ignoreJump = ignoreJump;
      pParse->trigStack = &trigStackEntry;
      sqlite3AuthContextPush(pParse, &sContext, pTrigger->name);

      /* code the WHEN clause */
      endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
      whenExpr = sqlite3ExprDup(pTrigger->pWhen);
      if( sqlite3ExprResolveNames(&sNC, whenExpr) ){
        pParse->trigStack = trigStackEntry.pNext;
        sqlite3ExprDelete(whenExpr);
        return 1;
      }
      sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1);
      sqlite3ExprDelete(whenExpr);

      codeTriggerProgram(pParse, pTrigger->step_list, orconf); 

      /* Pop the entry off the trigger stack */
      pParse->trigStack = trigStackEntry.pNext;
      sqlite3AuthContextPop(&sContext);

      sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);
    }
    pTrigger = pTrigger->pNext;
  }
  return 0;
}
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
Changes to SQLite.Interop/src/update.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** The most recently coded instruction was an OP_Column to retrieve the
** i-th column of table pTab. This routine sets the P3 parameter of the 
** OP_Column to the default value, if any.
**
** The default value of a column is specified by a DEFAULT clause in the 
** column definition. This was either supplied by the user when the table
** was created, or added later to the table definition by an ALTER TABLE
** command. If the latter, then the row-records in the table btree on disk
** may not contain a value for the column and the default value, taken
** from the P3 parameter of the OP_Column instruction, is returned instead.
** If the former, then all row-records are guaranteed to include a value
** for the column and the P3 value is not required.
**
** Column definitions created by an ALTER TABLE command may only have 
** literal default values specified: a number, null or a string. (If a more
** complicated default expression value was provided, it is evaluated 
** when the ALTER TABLE is executed and one of the literal values written
** into the sqlite_master table.)
**
** Therefore, the P3 parameter is only required if the default value for
** the column is a literal number, string or null. The sqlite3ValueFromExpr()
** function is capable of transforming these types of expressions into
** sqlite3_value objects.
*/
void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){
  if( pTab && !pTab->pSelect ){
    sqlite3_value *pValue;
    u8 enc = ENC(sqlite3VdbeDb(v));
    Column *pCol = &pTab->aCol[i];
    sqlite3ValueFromExpr(pCol->pDflt, enc, pCol->affinity, &pValue);
    if( pValue ){
      sqlite3VdbeChangeP3(v, -1, (const char *)pValue, P3_MEM);
    }else{
      VdbeComment((v, "# %s.%s", pTab->zName, pCol->zName));
    }
  }
}

/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
**          \_______/ \________/     \______/       \________________/
*            onError   pTabList      pChanges             pWhere
*/







|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







8
9
10
11
12
13
14
15
16
17
18







































19
20
21
22
23
24
25
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.1 2005/03/01 16:04:37 rmsimpson Exp $
*/
#include "sqliteInt.h"








































/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
**          \_______/ \________/     \______/       \________________/
*            onError   pTabList      pChanges             pWhere
*/
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  int iCur;              /* VDBE Cursor number of pTab */
  sqlite3 *db;           /* The database structure */
  Index **apIdx = 0;     /* An array of indices that need updating too */
  char *aIdxUsed = 0;    /* aIdxUsed[i]==1 if the i-th index is used */
  int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                         ** an expression for the i-th column of the table.
                         ** aXRef[i]==-1 if the i-th column is not changed. */
  int chngRowid;         /* True if the record number is being changed */
  Expr *pRowidExpr = 0;  /* Expression defining the new record number */
  int openAll = 0;       /* True if all indices need to be opened */
  AuthContext sContext;  /* The authorization context */
  NameContext sNC;       /* The name-context to resolve expressions in */
  int iDb;               /* Database containing the table being updated */

#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* Trying to update a view */
  int triggers_exist = 0;      /* True if any row triggers exist */
#endif

  int newIdx      = -1;  /* index of trigger "new" temp table       */
  int oldIdx      = -1;  /* index of trigger "old" temp table       */

  sContext.pParse = 0;
  if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
    goto update_cleanup;
  }
  db = pParse->db;
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to update. 
  */
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 ) goto update_cleanup;
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);

  /* Figure out if we have any triggers and if the table being
  ** updated is a view
  */
#ifndef SQLITE_OMIT_TRIGGER
  triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges);
  isView = pTab->pSelect!=0;







|
|



<










<
|
<







<







41
42
43
44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60
61
62

63

64
65
66
67
68
69
70

71
72
73
74
75
76
77
  int iCur;              /* VDBE Cursor number of pTab */
  sqlite3 *db;           /* The database structure */
  Index **apIdx = 0;     /* An array of indices that need updating too */
  char *aIdxUsed = 0;    /* aIdxUsed[i]==1 if the i-th index is used */
  int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                         ** an expression for the i-th column of the table.
                         ** aXRef[i]==-1 if the i-th column is not changed. */
  int chngRecno;         /* True if the record number is being changed */
  Expr *pRecnoExpr = 0;  /* Expression defining the new record number */
  int openAll = 0;       /* True if all indices need to be opened */
  AuthContext sContext;  /* The authorization context */
  NameContext sNC;       /* The name-context to resolve expressions in */


#ifndef SQLITE_OMIT_TRIGGER
  int isView;                  /* Trying to update a view */
  int triggers_exist = 0;      /* True if any row triggers exist */
#endif

  int newIdx      = -1;  /* index of trigger "new" temp table       */
  int oldIdx      = -1;  /* index of trigger "old" temp table       */

  sContext.pParse = 0;

  if( pParse->nErr || sqlite3_malloc_failed ) goto update_cleanup;

  db = pParse->db;
  assert( pTabList->nSrc==1 );

  /* Locate the table which we want to update. 
  */
  pTab = sqlite3SrcListLookup(pParse, pTabList);
  if( pTab==0 ) goto update_cleanup;


  /* Figure out if we have any triggers and if the table being
  ** updated is a view
  */
#ifndef SQLITE_OMIT_TRIGGER
  triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges);
  isView = pTab->pSelect!=0;
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241
242
243
244

  /* Resolve the column names in all the expressions of the
  ** of the UPDATE statement.  Also find the column index
  ** for each column to be updated in the pChanges array.  For each
  ** column to be updated, make sure we have authorization to change
  ** that column.
  */
  chngRowid = 0;
  for(i=0; i<pChanges->nExpr; i++){
    if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){
      goto update_cleanup;
    }
    for(j=0; j<pTab->nCol; j++){
      if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
        if( j==pTab->iPKey ){
          chngRowid = 1;
          pRowidExpr = pChanges->a[i].pExpr;
        }
        aXRef[j] = i;
        break;
      }
    }
    if( j>=pTab->nCol ){
      if( sqlite3IsRowid(pChanges->a[i].zName) ){
        chngRowid = 1;
        pRowidExpr = pChanges->a[i].pExpr;
      }else{
        sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
        goto update_cleanup;
      }
    }
#ifndef SQLITE_OMIT_AUTHORIZATION
    {
      int rc;
      rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
                           pTab->aCol[j].zName, db->aDb[iDb].zName);
      if( rc==SQLITE_DENY ){
        goto update_cleanup;
      }else if( rc==SQLITE_IGNORE ){
        aXRef[j] = -1;
      }
    }
#endif
  }

  /* Allocate memory for the array apIdx[] and fill it with pointers to every
  ** index that needs to be updated.  Indices only need updating if their
  ** key includes one of the columns named in pChanges or if the record
  ** number of the original table entry is changing.
  */
  for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
    if( chngRowid ){
      i = 0;
    }else {
      for(i=0; i<pIdx->nColumn; i++){
        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
      }
    }
    if( i<pIdx->nColumn ) nIdx++;
  }
  if( nIdxTotal>0 ){
    apIdx = sqliteMallocRaw( sizeof(Index*) * nIdx + nIdxTotal );
    if( apIdx==0 ) goto update_cleanup;
    aIdxUsed = (char*)&apIdx[nIdx];
  }
  for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
    if( chngRowid ){
      i = 0;
    }else{
      for(i=0; i<pIdx->nColumn; i++){
        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
      }
    }
    if( i<pIdx->nColumn ){

      apIdx[nIdx++] = pIdx;
      aIdxUsed[j] = 1;
    }else{
      aIdxUsed[j] = 0;
    }
  }








|







|
|







|
|









|















|














|







>







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

  /* Resolve the column names in all the expressions of the
  ** of the UPDATE statement.  Also find the column index
  ** for each column to be updated in the pChanges array.  For each
  ** column to be updated, make sure we have authorization to change
  ** that column.
  */
  chngRecno = 0;
  for(i=0; i<pChanges->nExpr; i++){
    if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){
      goto update_cleanup;
    }
    for(j=0; j<pTab->nCol; j++){
      if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
        if( j==pTab->iPKey ){
          chngRecno = 1;
          pRecnoExpr = pChanges->a[i].pExpr;
        }
        aXRef[j] = i;
        break;
      }
    }
    if( j>=pTab->nCol ){
      if( sqlite3IsRowid(pChanges->a[i].zName) ){
        chngRecno = 1;
        pRecnoExpr = pChanges->a[i].pExpr;
      }else{
        sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
        goto update_cleanup;
      }
    }
#ifndef SQLITE_OMIT_AUTHORIZATION
    {
      int rc;
      rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
                           pTab->aCol[j].zName, db->aDb[pTab->iDb].zName);
      if( rc==SQLITE_DENY ){
        goto update_cleanup;
      }else if( rc==SQLITE_IGNORE ){
        aXRef[j] = -1;
      }
    }
#endif
  }

  /* Allocate memory for the array apIdx[] and fill it with pointers to every
  ** index that needs to be updated.  Indices only need updating if their
  ** key includes one of the columns named in pChanges or if the record
  ** number of the original table entry is changing.
  */
  for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
    if( chngRecno ){
      i = 0;
    }else {
      for(i=0; i<pIdx->nColumn; i++){
        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
      }
    }
    if( i<pIdx->nColumn ) nIdx++;
  }
  if( nIdxTotal>0 ){
    apIdx = sqliteMallocRaw( sizeof(Index*) * nIdx + nIdxTotal );
    if( apIdx==0 ) goto update_cleanup;
    aIdxUsed = (char*)&apIdx[nIdx];
  }
  for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
    if( chngRecno ){
      i = 0;
    }else{
      for(i=0; i<pIdx->nColumn; i++){
        if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
      }
    }
    if( i<pIdx->nColumn ){
      if( sqlite3CheckIndexCollSeq(pParse, pIdx) ) goto update_cleanup;
      apIdx[nIdx++] = pIdx;
      aIdxUsed[j] = 1;
    }else{
      aIdxUsed[j] = 0;
    }
  }

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
  }

  /* Begin generating code.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto update_cleanup;
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, 1, iDb);

  /* If we are trying to update a view, realize that view into
  ** a ephemeral table.
  */
  if( isView ){
    Select *pView;
    pView = sqlite3SelectDup(pTab->pSelect);
    sqlite3Select(pParse, pView, SRT_VirtualTab, iCur, 0, 0, 0, 0);
    sqlite3SelectDelete(pView);
  }

  /* Begin the database scan
  */
  pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
  if( pWInfo==0 ) goto update_cleanup;

  /* Remember the index of every item to be updated.
  */
  sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
  sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);

  /* End the database scan loop.
  */
  sqlite3WhereEnd(pWInfo);

  /* Initialize the count of updated rows
  */







|

|
|




|





|




|
|







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  }

  /* Begin generating code.
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) goto update_cleanup;
  if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
  sqlite3BeginWriteOperation(pParse, 1, pTab->iDb);

  /* If we are trying to update a view, construct that view into
  ** a temporary table.
  */
  if( isView ){
    Select *pView;
    pView = sqlite3SelectDup(pTab->pSelect);
    sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0, 0);
    sqlite3SelectDelete(pView);
  }

  /* Begin the database scan
  */
  pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0);
  if( pWInfo==0 ) goto update_cleanup;

  /* Remember the index of every item to be updated.
  */
  sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
  sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);

  /* End the database scan loop.
  */
  sqlite3WhereEnd(pWInfo);

  /* Initialize the count of updated rows
  */
298
299
300
301
302
303
304

305
306
307
308
309
310
311
312


313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368

369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
    sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
    sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);

    /* The top of the update loop for when there are triggers.
    */

    addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);

    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      /* Open a cursor and make it point to the record that is
      ** being updated.
      */


      sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
    }
    sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);

    /* Generate the OLD table
    */
    sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
    sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
    sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);

    /* Generate the NEW table
    */
    if( chngRowid ){
      sqlite3ExprCodeAndCache(pParse, pRowidExpr);
    }else{
      sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
    }
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
        continue;
      }
      j = aXRef[i];
      if( j<0 ){
        sqlite3VdbeAddOp(v, OP_Column, iCur, i);
        sqlite3ColumnDefault(v, pTab, i);
      }else{
        sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr);
      }
    }
    sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
    }
    if( pParse->nErr ) goto update_cleanup;
    sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }

    /* Fire the BEFORE and INSTEAD OF triggers
    */
    if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
          newIdx, oldIdx, onError, addr) ){
      goto update_cleanup;
    }
  }

  if( !isView ){
    /* 
    ** Open every index that needs updating.  Note that if any
    ** index could potentially invoke a REPLACE conflict resolution 
    ** action, then we need to open all indices because we might need
    ** to be deleting some records.
    */

    sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); 

    if( onError==OE_Replace ){
      openAll = 1;
    }else{
      openAll = 0;
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
        if( pIdx->onError==OE_Replace ){
          openAll = 1;
          break;
        }
      }
    }
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      if( openAll || aIdxUsed[i] ){
        KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
        sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
        sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum,
                       (char*)pKey, P3_KEYINFO_HANDOFF);
        assert( pParse->nTab>iCur+i+1 );
      }
    }

    /* Loop over every record that needs updating.  We have to load
    ** the old data for each record to be updated because some columns
    ** might not change and we will need to copy the old value.
    ** Also, the old data is needed to delete the old index entires.
    ** So make the cursor point at the old record.
    */
    if( !triggers_exist ){

      addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    }
    sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);

    /* If the record number will change, push the record number as it
    ** will be after the update. (The old record number is currently
    ** on top of the stack.)
    */
    if( chngRowid ){
      sqlite3ExprCode(pParse, pRowidExpr);
      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    }

    /* Compute new data for this record.  
    */
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
        continue;
      }
      j = aXRef[i];
      if( j<0 ){
        sqlite3VdbeAddOp(v, OP_Column, iCur, i);
        sqlite3ColumnDefault(v, pTab, i);
      }else{
        sqlite3ExprCode(pParse, pChanges->a[j].pExpr);
      }
    }

    /* Do constraint checks
    */
    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRowid, 1,
                                   onError, addr);

    /* Delete the old indices for the current record.
    */
    sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);

    /* If changing the record number, delete the old record.
    */
    if( chngRowid ){
      sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
    }

    /* Create the new index entries and the new record.
    */
    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1);
  }

  /* Increment the row counter 
  */
  if( db->flags & SQLITE_CountRows && !pParse->trigStack){
    sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
  }







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





|

|



|
|

|



|





<









|



















>
|
>













<
|

|











>
|








|
|







|





<







|








|





|







256
257
258
259
260
261
262
263
264


265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
    sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);

    /* The top of the update loop for when there are triggers.
    */
    sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
    addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0);


    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);

    /* Open a cursor and make it point to the record that is
    ** being updated.
    */
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    if( !isView ){
      sqlite3OpenTableForReading(v, iCur, pTab);
    }
    sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);

    /* Generate the OLD table
    */
    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);

    /* Generate the NEW table
    */
    if( chngRecno ){
      sqlite3ExprCodeAndCache(pParse, pRecnoExpr);
    }else{
      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    }
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
        continue;
      }
      j = aXRef[i];
      if( j<0 ){
        sqlite3VdbeAddOp(v, OP_Column, iCur, i);

      }else{
        sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr);
      }
    }
    sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
    }
    if( pParse->nErr ) goto update_cleanup;
    sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }

    /* Fire the BEFORE and INSTEAD OF triggers
    */
    if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
          newIdx, oldIdx, onError, addr) ){
      goto update_cleanup;
    }
  }

  if( !isView ){
    /* 
    ** Open every index that needs updating.  Note that if any
    ** index could potentially invoke a REPLACE conflict resolution 
    ** action, then we need to open all indices because we might need
    ** to be deleting some records.
    */
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
    if( onError==OE_Replace ){
      openAll = 1;
    }else{
      openAll = 0;
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
        if( pIdx->onError==OE_Replace ){
          openAll = 1;
          break;
        }
      }
    }
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      if( openAll || aIdxUsed[i] ){

        sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
        sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum,
                       (char*)&pIdx->keyInfo, P3_KEYINFO);
        assert( pParse->nTab>iCur+i+1 );
      }
    }

    /* Loop over every record that needs updating.  We have to load
    ** the old data for each record to be updated because some columns
    ** might not change and we will need to copy the old value.
    ** Also, the old data is needed to delete the old index entires.
    ** So make the cursor point at the old record.
    */
    if( !triggers_exist ){
      sqlite3VdbeAddOp(v, OP_ListRewind, 0, 0);
      addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, 0);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    }
    sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);

    /* If the record number will change, push the record number as it
    ** will be after the update. (The old record number is currently
    ** on top of the stack.)
    */
    if( chngRecno ){
      sqlite3ExprCode(pParse, pRecnoExpr);
      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
    }

    /* Compute new data for this record.  
    */
    for(i=0; i<pTab->nCol; i++){
      if( i==pTab->iPKey ){
        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
        continue;
      }
      j = aXRef[i];
      if( j<0 ){
        sqlite3VdbeAddOp(v, OP_Column, iCur, i);

      }else{
        sqlite3ExprCode(pParse, pChanges->a[j].pExpr);
      }
    }

    /* Do constraint checks
    */
    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
                                   onError, addr);

    /* Delete the old indices for the current record.
    */
    sqlite3GenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);

    /* If changing the record number, delete the old record.
    */
    if( chngRecno ){
      sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
    }

    /* Create the new index entries and the new record.
    */
    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, -1);
  }

  /* Increment the row counter 
  */
  if( db->flags & SQLITE_CountRows && !pParse->trigStack){
    sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
  }
467
468
469
470
471
472
473

474
475
476
477
478
479
480
481
    }
  }

  /* Repeat the above with the next record to be updated, until
  ** all record selected by the WHERE clause have been updated.
  */
  sqlite3VdbeAddOp(v, OP_Goto, 0, addr);

  sqlite3VdbeJumpHere(v, addr);

  /* Close all tables if there were no FOR EACH ROW triggers */
  if( !triggers_exist ){
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      if( openAll || aIdxUsed[i] ){
        sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
      }







>
|







426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
    }
  }

  /* Repeat the above with the next record to be updated, until
  ** all record selected by the WHERE clause have been updated.
  */
  sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
  sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
  sqlite3VdbeAddOp(v, OP_ListReset, 0, 0);

  /* Close all tables if there were no FOR EACH ROW triggers */
  if( !triggers_exist ){
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      if( openAll || aIdxUsed[i] ){
        sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
      }
Changes to SQLite.Interop/src/utf.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.1 2005/03/01 16:04:37 rmsimpson Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
    u8 temp;
    int rc;
    rc = sqlite3VdbeMemMakeWriteable(pMem);
    if( rc!=SQLITE_OK ){
      assert( rc==SQLITE_NOMEM );
      return SQLITE_NOMEM;
    }
    zIn = (u8*)pMem->z;
    zTerm = &zIn[pMem->n];
    while( zIn<zTerm ){
      temp = *zIn;
      *zIn = *(zIn+1);
      zIn++;
      *zIn++ = temp;
    }







|







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
    u8 temp;
    int rc;
    rc = sqlite3VdbeMemMakeWriteable(pMem);
    if( rc!=SQLITE_OK ){
      assert( rc==SQLITE_NOMEM );
      return SQLITE_NOMEM;
    }
    zIn = pMem->z;
    zTerm = &zIn[pMem->n];
    while( zIn<zTerm ){
      temp = *zIn;
      *zIn = *(zIn+1);
      zIn++;
      *zIn++ = temp;
    }
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  /* Set zIn to point at the start of the input buffer and zTerm to point 1
  ** byte past the end.
  **
  ** Variable zOut is set to point at the output buffer. This may be space
  ** obtained from malloc(), or Mem.zShort, if it large enough and not in
  ** use, or the zShort array on the stack (see above).
  */
  zIn = (u8*)pMem->z;
  zTerm = &zIn[pMem->n];
  if( len>NBFS ){
    zOut = sqliteMallocRaw(len);
    if( !zOut ) return SQLITE_NOMEM;
  }else{
    zOut = zShort;
  }







|







304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  /* Set zIn to point at the start of the input buffer and zTerm to point 1
  ** byte past the end.
  **
  ** Variable zOut is set to point at the output buffer. This may be space
  ** obtained from malloc(), or Mem.zShort, if it large enough and not in
  ** use, or the zShort array on the stack (see above).
  */
  zIn = pMem->z;
  zTerm = &zIn[pMem->n];
  if( len>NBFS ){
    zOut = sqliteMallocRaw(len);
    if( !zOut ) return SQLITE_NOMEM;
  }else{
    zOut = zShort;
  }
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );

  sqlite3VdbeMemRelease(pMem);
  pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
  pMem->enc = desiredEnc;
  if( zOut==zShort ){
    memcpy(pMem->zShort, zOut, len);
    zOut = (u8*)pMem->zShort;
    pMem->flags |= (MEM_Term|MEM_Short);
  }else{
    pMem->flags |= (MEM_Term|MEM_Dyn);
  }
  pMem->z = (char*)zOut;

translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
  {
    char zBuf[100];
    sqlite3VdbeMemPrettyPrint(pMem, zBuf, 100);
    fprintf(stderr, "OUTPUT: %s\n", zBuf);







|




|







356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );

  sqlite3VdbeMemRelease(pMem);
  pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
  pMem->enc = desiredEnc;
  if( zOut==zShort ){
    memcpy(pMem->zShort, zOut, len);
    zOut = pMem->zShort;
    pMem->flags |= (MEM_Term|MEM_Short);
  }else{
    pMem->flags |= (MEM_Term|MEM_Dyn);
  }
  pMem->z = zOut;

translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
  {
    char zBuf[100];
    sqlite3VdbeMemPrettyPrint(pMem, zBuf, 100);
    fprintf(stderr, "OUTPUT: %s\n", zBuf);
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
    SKIP_UTF8(z);
    r++;
  }
  return r;
}

#ifndef SQLITE_OMIT_UTF16
/*
** Convert a UTF-16 string in the native encoding into a UTF-8 string.
** Memory to hold the UTF-8 string is obtained from malloc and must be
** freed by the calling function.
**
** NULL is returned if there is an allocation error.
*/
char *sqlite3utf16to8(const void *z, int nByte){
  Mem m;
  memset(&m, 0, sizeof(m));
  sqlite3VdbeMemSetStr(&m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC);
  sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8);
  assert( m.flags & MEM_Term );
  assert( m.flags & MEM_Str );
  return (m.flags & MEM_Dyn)!=0 ? m.z : sqliteStrDup(m.z);
}

/*
** pZ is a UTF-16 encoded unicode string. If nChar is less than zero,
** return the number of bytes up to (but not including), the first pair
** of consecutive 0x00 bytes in pZ. If nChar is not less than zero,
** then return the number of bytes in the first nChar unicode characters
** in pZ (or up until the first pair of 0x00 bytes, whichever comes first).
*/







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







446
447
448
449
450
451
452

















453
454
455
456
457
458
459
    SKIP_UTF8(z);
    r++;
  }
  return r;
}

#ifndef SQLITE_OMIT_UTF16

















/*
** pZ is a UTF-16 encoded unicode string. If nChar is less than zero,
** return the number of bytes up to (but not including), the first pair
** of consecutive 0x00 bytes in pZ. If nChar is not less than zero,
** then return the number of bytes in the first nChar unicode characters
** in pZ (or up until the first pair of 0x00 bytes, whichever comes first).
*/
Changes to SQLite.Interop/src/util.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183


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



198
199
200
201
202
203
204
205
206
207








208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241


242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314

315

316
317
318
319




320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337



338


339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

358
359

360
361
362
363





364
365
366
367
368
369
370
371
372
373
374
375
376

377
378

379
380
381
382
383
384
385
386
387
388
389
390
391

392

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416


417
418

419
420
421
422
423
424

425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

448
449
450
451
452
453

454
455
456
457


458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496







497
498
499

500
501
502
503
504


505
506
507
508
509
510
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526
527
528



529
530
531
532
533
534
535
536
537
538
539
540
541
542

543
544

545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629


630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679

680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705

706
707
708
709
710
711
712





713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.16 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>

/*
** MALLOC WRAPPER ARCHITECTURE
**
** The sqlite code accesses dynamic memory allocation/deallocation by invoking
** the following four APIs (which may be implemented as macros).
**
**     sqlite3Malloc()
**     sqlite3MallocRaw()
**     sqlite3Realloc()
**     sqlite3ReallocOrFree()
**     sqlite3Free()
**     sqlite3AllocSize()
**
** The function sqlite3FreeX performs the same task as sqlite3Free and is
** guaranteed to be a real function. The same holds for sqlite3MallocX
**
** The above APIs are implemented in terms of the functions provided at the Os
** level (not in this file). The Os level interface is never accessed directly
** by code outside of this file.
**
**     sqlite3OsMalloc()
**     sqlite3OsRealloc()
**     sqlite3OsFree()
**     sqlite3OsAllocationSize()
**
** Functions sqlite3MallocRaw() and sqlite3Realloc() may invoke 
** sqlite3_release_memory() if a call to sqlite3OsMalloc() or
** sqlite3OsRealloc() fails (or if the soft-heap-limit for the thread is
** exceeded). Function sqlite3Malloc() usually invokes
** sqlite3MallocRaw().
**
** MALLOC TEST WRAPPER ARCHITECTURE
**
** The test wrapper provides extra test facilities to ensure the library 
** does not leak memory and handles the failure of the underlying (Os level)
** allocation system correctly. It is only present if the library is 
** compiled with the SQLITE_MEMDEBUG macro set.
**
**     * Guardposts to detect overwrites.
**     * Ability to cause a specific Malloc() or Realloc() to fail.
**     * Audit outstanding memory allocations (i.e check for leaks).
*/

#define MAX(x,y) ((x)>(y)?(x):(y))

#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
/*
** Set the soft heap-size limit for the current thread. Passing a negative
** value indicates no limit.
*/
void sqlite3_soft_heap_limit(int n){
  sqlite3ThreadData()->nSoftHeapLimit = n;
  sqlite3ReleaseThreadData();
}

/*
** Release memory held by SQLite instances created by the current thread.
*/
int sqlite3_release_memory(int n){
  return sqlite3pager_release_memory(n);


}
#else
/* If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, then define a version
** of sqlite3_release_memory() to be used by other code in this file.
** This is done for no better reason than to reduce the number of 
** pre-processor #ifndef statements.
*/
#define sqlite3_release_memory(x) 0    /* 0 == no memory freed */
#endif

#ifdef SQLITE_MEMDEBUG
/*--------------------------------------------------------------------------
** Begin code for memory allocation system test layer.
**
** Memory debugging is turned on by defining the SQLITE_MEMDEBUG macro.
**
** SQLITE_MEMDEBUG==1    -> Fence-posting only (thread safe) 
** SQLITE_MEMDEBUG==2    -> Fence-posting + linked list of allocations (not ts)
** SQLITE_MEMDEBUG==3    -> Above + backtraces (not thread safe, req. glibc)
*/

/* Figure out whether or not to store backtrace() information for each malloc.
** The backtrace() function is only used if SQLITE_MEMDEBUG is set to 2 or 
** greater and glibc is in use. If we don't want to use backtrace(), then just
** define it as an empty macro and set the amount of space reserved to 0.
*/
#if defined(__GLIBC__) && SQLITE_MEMDEBUG>2
  extern int backtrace(void **, int);
  #define TESTALLOC_STACKSIZE 128
  #define TESTALLOC_STACKFRAMES ((TESTALLOC_STACKSIZE-8)/sizeof(void*))
#else
  #define backtrace(x, y)
  #define TESTALLOC_STACKSIZE 0
  #define TESTALLOC_STACKFRAMES 0
#endif

/*
** Number of 32-bit guard words.  This should probably be a multiple of
** 2 since on 64-bit machines we want the value returned by sqliteMalloc()
** to be 8-byte aligned.
*/
#ifndef TESTALLOC_NGUARD
# define TESTALLOC_NGUARD 2
#endif

/*
** Size reserved for storing file-name along with each malloc()ed blob.
*/
#define TESTALLOC_FILESIZE 64

/*
** Size reserved for storing the user string. Each time a Malloc() or Realloc()
** call succeeds, up to TESTALLOC_USERSIZE bytes of the string pointed to by
** sqlite3_malloc_id are stored along with the other test system metadata.
*/
#define TESTALLOC_USERSIZE 64
const char *sqlite3_malloc_id = 0;

/*
** Blocks used by the test layer have the following format:
**
**        <sizeof(void *) pNext pointer>
**        <sizeof(void *) pPrev pointer>
**        <TESTALLOC_NGUARD 32-bit guard words>
**            <The application level allocation>
**        <TESTALLOC_NGUARD 32-bit guard words>
**        <32-bit line number>
**        <TESTALLOC_FILESIZE bytes containing null-terminated file name>
**        <TESTALLOC_STACKSIZE bytes of backtrace() output>
*/ 

#define TESTALLOC_OFFSET_GUARD1(p)    (sizeof(void *) * 2)
#define TESTALLOC_OFFSET_DATA(p) ( \
  TESTALLOC_OFFSET_GUARD1(p) + sizeof(u32) * TESTALLOC_NGUARD \
)
#define TESTALLOC_OFFSET_GUARD2(p) ( \
  TESTALLOC_OFFSET_DATA(p) + sqlite3OsAllocationSize(p) - TESTALLOC_OVERHEAD \
)
#define TESTALLOC_OFFSET_LINENUMBER(p) ( \
  TESTALLOC_OFFSET_GUARD2(p) + sizeof(u32) * TESTALLOC_NGUARD \
)
#define TESTALLOC_OFFSET_FILENAME(p) ( \
  TESTALLOC_OFFSET_LINENUMBER(p) + sizeof(u32) \
)
#define TESTALLOC_OFFSET_USER(p) ( \
  TESTALLOC_OFFSET_FILENAME(p) + TESTALLOC_FILESIZE \
)
#define TESTALLOC_OFFSET_STACK(p) ( \
  TESTALLOC_OFFSET_USER(p) + TESTALLOC_USERSIZE + 8 - \
  (TESTALLOC_OFFSET_USER(p) % 8) \
)

#define TESTALLOC_OVERHEAD ( \
  sizeof(void *)*2 +                   /* pPrev and pNext pointers */   \
  TESTALLOC_NGUARD*sizeof(u32)*2 +              /* Guard words */       \
  sizeof(u32) + TESTALLOC_FILESIZE +   /* File and line number */       \
  TESTALLOC_USERSIZE +                 /* User string */                \
  TESTALLOC_STACKSIZE                  /* backtrace() stack */          \
)




/*
** For keeping track of the number of mallocs and frees.   This
** is used to check for memory leaks.  The iMallocFail and iMallocReset
** values are used to simulate malloc() failures during testing in 
** order to verify that the library correctly handles an out-of-memory
** condition.
*/
int sqlite3_nMalloc;         /* Number of sqliteMalloc() calls */
int sqlite3_nFree;           /* Number of sqliteFree() calls */
int sqlite3_memUsed;         /* TODO Total memory obtained from malloc */
int sqlite3_memMax;          /* TODO Mem usage high-water mark */
int sqlite3_iMallocFail;     /* Fail sqliteMalloc() after this many calls */
int sqlite3_iMallocReset = -1; /* When iMallocFail reaches 0, set to this */




/*
** Check for a simulated memory allocation failure.  Return true if
** the failure should be simulated.  Return false to proceed as normal.
*/
static int failMalloc(){
  ThreadData *pTsd = sqlite3ThreadData();
  if( pTsd->isFail ){
    return 1;
  }








  if( sqlite3_iMallocFail>=0 ){
    sqlite3_iMallocFail--;
    if( sqlite3_iMallocFail==0 ){
      sqlite3_iMallocFail = sqlite3_iMallocReset;
      pTsd->isFail = 1;
      return 1;
    }
  }
  return 0;
}

/*
** The argument is a pointer returned by sqlite3OsMalloc() or xRealloc().
** assert() that the first and last (TESTALLOC_NGUARD*4) bytes are set to the
** values set by the applyGuards() function.
*/
static void checkGuards(u32 *p)
{
  int i;
  char *zAlloc = (char *)p;
  char *z;

  /* First set of guard words */
  z = &zAlloc[TESTALLOC_OFFSET_GUARD1(p)];
  for(i=0; i<TESTALLOC_NGUARD; i++){
    assert(((u32 *)z)[i]==0xdead1122);
  }

  /* Second set of guard words */
  z = &zAlloc[TESTALLOC_OFFSET_GUARD2(p)];
  for(i=0; i<TESTALLOC_NGUARD; i++){
    u32 guard = 0;
    memcpy(&guard, &z[i*sizeof(u32)], sizeof(u32));
    assert(guard==0xdead3344);


  }
}

/*
** The argument is a pointer returned by sqlite3OsMalloc() or Realloc(). The
** first and last (TESTALLOC_NGUARD*4) bytes are set to known values for use as 
** guard-posts.
*/
static void applyGuards(u32 *p)
{
  int i;
  char *z;
  char *zAlloc = (char *)p;

  /* First set of guard words */
  z = &zAlloc[TESTALLOC_OFFSET_GUARD1(p)];
  for(i=0; i<TESTALLOC_NGUARD; i++){
    ((u32 *)z)[i] = 0xdead1122;
  }

  /* Second set of guard words */

  z = &zAlloc[TESTALLOC_OFFSET_GUARD2(p)];
  for(i=0; i<TESTALLOC_NGUARD; i++){
    static const int guard = 0xdead3344;
    memcpy(&z[i*sizeof(u32)], &guard, sizeof(u32));
  }


  /* Line number */
  z = &((char *)z)[TESTALLOC_NGUARD*sizeof(u32)];             /* Guard words */
  z = &zAlloc[TESTALLOC_OFFSET_LINENUMBER(p)];
  memcpy(z, &sqlite3ThreadData()->iLine, sizeof(u32));

  /* File name */
  z = &zAlloc[TESTALLOC_OFFSET_FILENAME(p)];
  strncpy(z, sqlite3ThreadData()->zFile, TESTALLOC_FILESIZE);
  z[TESTALLOC_FILESIZE - 1] = '\0';

  /* User string */
  z = &zAlloc[TESTALLOC_OFFSET_USER(p)];
  z[0] = 0;
  if( sqlite3_malloc_id ){
    strncpy(z, sqlite3_malloc_id, TESTALLOC_USERSIZE);
    z[TESTALLOC_USERSIZE-1] = 0;
  }

  /* backtrace() stack */
  z = &zAlloc[TESTALLOC_OFFSET_STACK(p)];
  backtrace((void **)z, TESTALLOC_STACKFRAMES);

  /* Sanity check to make sure checkGuards() is working */
  checkGuards(p);
}

/*
** The argument is a malloc()ed pointer as returned by the test-wrapper.
** Return a pointer to the Os level allocation.
*/
static void *getOsPointer(void *p)
{
  char *z = (char *)p;
  return (void *)(&z[-1 * TESTALLOC_OFFSET_DATA(p)]);
}


#if SQLITE_MEMDEBUG>1
/*
** The argument points to an Os level allocation. Link it into the threads list
** of allocations.

*/
static void linkAlloc(void *p){
  ThreadData *pTsd = sqlite3ThreadData();
  void **pp = (void **)p;
  pp[0] = 0;

  pp[1] = pTsd->pFirst;

  if( pTsd->pFirst ){
    ((void **)pTsd->pFirst)[0] = p;
  }
  pTsd->pFirst = p;




}

/*
** The argument points to an Os level allocation. Unlinke it from the threads
** list of allocations.
*/
static void unlinkAlloc(void *p)
{
  ThreadData *pTsd = sqlite3ThreadData();
  void **pp = (void **)p;
  if( p==pTsd->pFirst ){
    assert(!pp[0]);
    assert(!pp[1] || ((void **)(pp[1]))[0]==p);
    pTsd->pFirst = pp[1];
    if( pTsd->pFirst ){
      ((void **)pTsd->pFirst)[0] = 0;
    }
  }else{



    void **pprev = pp[0];


    void **pnext = pp[1];
    assert(pprev);
    assert(pprev[1]==p);
    pprev[1] = (void *)pnext;
    if( pnext ){
      assert(pnext[0]==p);
      pnext[0] = (void *)pprev;
    }
  }
}

/*
** Pointer p is a pointer to an OS level allocation that has just been
** realloc()ed. Set the list pointers that point to this entry to it's new
** location.
*/
static void relinkAlloc(void *p)
{
  void **pp = (void **)p;

  if( pp[0] ){
    ((void **)(pp[0]))[1] = p;

  }else{
    ThreadData *pTsd = sqlite3ThreadData();
    pTsd->pFirst = p;
  }





  if( pp[1] ){
    ((void **)(pp[1]))[0] = p;
  }
}
#else
#define linkAlloc(x)
#define relinkAlloc(x)
#define unlinkAlloc(x)
#endif

/*
** This function sets the result of the Tcl interpreter passed as an argument
** to a list containing an entry for each currently outstanding call made to 

** sqliteMalloc and friends by the current thread. Each list entry is itself a
** list, consisting of the following (in order):

**
**     * The number of bytes allocated
**     * The __FILE__ macro at the time of the sqliteMalloc() call.
**     * The __LINE__ macro ...
**     * The value of the sqlite3_malloc_id variable ...
**     * The output of backtrace() (if available) ...
**
** Todo: We could have a version of this function that outputs to stdout, 
** to debug memory leaks when Tcl is not available.
*/
#ifdef TCLSH
#include <tcl.h>
int sqlite3OutstandingMallocs(Tcl_Interp *interp){

  void *p;

  ThreadData *pTsd = sqlite3ThreadData();
  Tcl_Obj *pRes = Tcl_NewObj();
  Tcl_IncrRefCount(pRes);

  for(p=pTsd->pFirst; p; p=((void **)p)[1]){
    Tcl_Obj *pEntry = Tcl_NewObj();
    Tcl_Obj *pStack = Tcl_NewObj();
    char *z;
    u32 iLine;
    int nBytes = sqlite3OsAllocationSize(p) - TESTALLOC_OVERHEAD;
    char *zAlloc = (char *)p;
    int i;

    Tcl_ListObjAppendElement(0, pEntry, Tcl_NewIntObj(nBytes));

    z = &zAlloc[TESTALLOC_OFFSET_FILENAME(p)];
    Tcl_ListObjAppendElement(0, pEntry, Tcl_NewStringObj(z, -1));

    z = &zAlloc[TESTALLOC_OFFSET_LINENUMBER(p)];
    memcpy(&iLine, z, sizeof(u32));
    Tcl_ListObjAppendElement(0, pEntry, Tcl_NewIntObj(iLine));

    z = &zAlloc[TESTALLOC_OFFSET_USER(p)];
    Tcl_ListObjAppendElement(0, pEntry, Tcl_NewStringObj(z, -1));



    z = &zAlloc[TESTALLOC_OFFSET_STACK(p)];

    for(i=0; i<TESTALLOC_STACKFRAMES; i++){
      char zHex[128];
      sprintf(zHex, "%p", ((void **)z)[i]);
      Tcl_ListObjAppendElement(0, pStack, Tcl_NewStringObj(zHex, -1));
    }


    Tcl_ListObjAppendElement(0, pEntry, pStack);
    Tcl_ListObjAppendElement(0, pRes, pEntry);
  }

  Tcl_ResetResult(interp);
  Tcl_SetObjResult(interp, pRes);
  Tcl_DecrRefCount(pRes);

  return TCL_OK;
}
#endif

/*
** This is the test layer's wrapper around sqlite3OsMalloc().
*/
static void * OSMALLOC(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  ThreadData *pTsd = sqlite3ThreadData();
  pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc);
#endif
  assert( !sqlite3ThreadData()->mallocDisallowed );
  if( !failMalloc() ){
    u32 *p;
    p = (u32 *)sqlite3OsMalloc(n + TESTALLOC_OVERHEAD);

    assert(p);
    sqlite3_nMalloc++;
    applyGuards(p);
    linkAlloc(p);
    return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]);
  }

  return 0;
}

static int OSSIZEOF(void *p){


  if( p ){
    u32 *pOs = (u32 *)getOsPointer(p);
    return sqlite3OsAllocationSize(pOs) - TESTALLOC_OVERHEAD;
  }
  return 0;
}

/*
** This is the test layer's wrapper around sqlite3OsFree(). The argument is a
** pointer to the space allocated for the application to use.
*/
static void OSFREE(void *pFree){
  u32 *p = (u32 *)getOsPointer(pFree);   /* p points to Os level allocation */
  checkGuards(p);
  unlinkAlloc(p);
  memset(pFree, 0x55, OSSIZEOF(pFree));
  sqlite3OsFree(p);
  sqlite3_nFree++;
}

/*
** This is the test layer's wrapper around sqlite3OsRealloc().

*/
static void * OSREALLOC(void *pRealloc, int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  ThreadData *pTsd = sqlite3ThreadData();
  pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc);
#endif
  assert( !sqlite3ThreadData()->mallocDisallowed );
  if( !failMalloc() ){
    u32 *p = (u32 *)getOsPointer(pRealloc);
    checkGuards(p);
    p = sqlite3OsRealloc(p, n + TESTALLOC_OVERHEAD);
    applyGuards(p);
    relinkAlloc(p);
    return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]);
  }

  return 0;
}








static void OSMALLOC_FAILED(){
  sqlite3ThreadData()->isFail = 0;

}

#else
/* Define macros to call the sqlite3OsXXX interface directly if 
** the SQLITE_MEMDEBUG macro is not defined.


*/
#define OSMALLOC(x)        sqlite3OsMalloc(x)
#define OSREALLOC(x,y)     sqlite3OsRealloc(x,y)
#define OSFREE(x)          sqlite3OsFree(x)
#define OSSIZEOF(x)        sqlite3OsAllocationSize(x)
#define OSMALLOC_FAILED()

#endif  /* SQLITE_MEMDEBUG */
/*
** End code for memory allocation system test layer.
**--------------------------------------------------------------------------*/

/*
** The handleSoftLimit() function is called before each call to 

** sqlite3OsMalloc() or xRealloc(). The parameter 'n' is the number of
** extra bytes about to be allocated (for Realloc() this means the size of the
** new allocation less the size of the old allocation). If the extra allocation
** means that the total memory allocated to SQLite in this thread would exceed
** the limit set by sqlite3_soft_heap_limit(), then sqlite3_release_memory() is
** called to try to avoid this. No indication of whether or not this is
** successful is returned to the caller.
**
** If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, this routine is
** a no-op



*/
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
static void handleSoftLimit(int n){
  ThreadData *pTsd = sqlite3ThreadData();
  pTsd->nAlloc += n;
  assert( pTsd->nAlloc>=0 );
  if( n>0 && pTsd->nSoftHeapLimit>0 ){
    while( pTsd->nAlloc>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) );
  }else if( pTsd->nAlloc==0 && pTsd->nSoftHeapLimit==0 ){
    sqlite3ReleaseThreadData();
  }
}
#else
#define handleSoftLimit(x)

#endif


/*
** Allocate and return N bytes of uninitialised memory by calling
** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory 
** by calling sqlite3_release_memory().
*/
void *sqlite3MallocRaw(int n){
  void *p = 0;
  if( n>0 && !sqlite3ThreadDataReadOnly()->mallocFailed ){
    handleSoftLimit(n);
    while( !(p = OSMALLOC(n)) && sqlite3_release_memory(n) );
    if( !p ){
      /* If the allocation failed, call handleSoftLimit() again, this time
      ** with the additive inverse of the argument passed to 
      ** handleSoftLimit() above. This is so the ThreadData.nAlloc variable is
      ** still correct after a malloc() failure. 
      */
      handleSoftLimit(n * -1);
      sqlite3ThreadData()->mallocFailed = 1;
      OSMALLOC_FAILED();
    }
  }
  return p;
}

/*
** Resize the allocation at p to n bytes by calling sqlite3OsRealloc(). The
** pointer to the new allocation is returned.  If the Realloc() call fails,
** attempt to free memory by calling sqlite3_release_memory().
*/
void *sqlite3Realloc(void *p, int n){
  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    return 0;
  }

  if( !p ){
    return sqlite3Malloc(n);
  }else{
    void *np = 0;
    handleSoftLimit(n - OSSIZEOF(p));
    while( !(np = OSREALLOC(p, n)) && sqlite3_release_memory(n) );
    if( !np ){
      /* If the allocation failed, call handleSoftLimit() again, this time
      ** with the additive inverse of the argument passed to 
      ** handleSoftLimit() above. This is so the ThreadData.nAlloc variable is
      ** still correct after a malloc() failure. 
      */
      handleSoftLimit(OSSIZEOF(p) - n);
      sqlite3ThreadData()->mallocFailed = 1;
      OSMALLOC_FAILED();
    }
    return np;
  }
}

/*
** Free the memory pointed to by p. p must be either a NULL pointer or a 
** value returned by a previous call to sqlite3Malloc() or sqlite3Realloc().
*/
void sqlite3FreeX(void *p){
  handleSoftLimit(0 - OSSIZEOF(p));
  if( p ){
    OSFREE(p);
  }
}

/*
** A version of sqliteMalloc() that is always a function, not a macro.
** Currently, this is used only to alloc to allocate the parser engine.
*/
void *sqlite3MallocX(int n){
  return sqliteMalloc(n);
}

/*
** sqlite3Malloc
** sqlite3ReallocOrFree
**
** These two are implemented as wrappers around sqlite3MallocRaw(), 
** sqlite3Realloc() and sqlite3Free().
*/ 
void *sqlite3Malloc(int n){
  void *p = sqlite3MallocRaw(n);
  if( p ){
    memset(p, 0, n);
  }


  return p;
}
void sqlite3ReallocOrFree(void **pp, int n){
  void *p = sqlite3Realloc(*pp, n);
  if( !p ){
    sqlite3FreeX(*pp);
  }
  *pp = p;
}

/*
** Return the number of bytes allocated at location p. p must be either 
** a NULL pointer (in which case 0 is returned) or a pointer returned by 
** sqlite3Malloc(), sqlite3Realloc() or sqlite3ReallocOrFree().
**
** The number of bytes allocated does not include any overhead inserted by 
** any malloc() wrapper functions that may be called. So the value returned
** is the number of bytes that were available to SQLite using pointer p, 
** regardless of how much memory was actually allocated.
*/
#if 0          /* This is never actually used */
int sqlite3AllocSize(void *p){
  return OSSIZEOF(p);
}
#endif

/*
** Make a copy of a string in memory obtained from sqliteMalloc(). These 
** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This
** is because when memory debugging is turned on, these two functions are 
** called via macros that record the current file and line number in the
** ThreadData structure.
*/
char *sqlite3StrDup(const char *z){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqlite3MallocRaw(strlen(z)+1);
  if( zNew ) strcpy(zNew, z);
  return zNew;
}
char *sqlite3StrNDup(const char *z, int n){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqlite3MallocRaw(n+1);
  if( zNew ){
    memcpy(zNew, z, n);
    zNew[n] = 0;
  }
  return zNew;
}


/*
** Create a string from the 2nd and subsequent arguments (up to the
** first NULL argument), store the string in memory obtained from
** sqliteMalloc() and make the pointer indicated by the 1st argument
** point to that string.  The 1st argument must either be NULL or 
** point to memory obtained from sqliteMalloc().
*/
void sqlite3SetString(char **pz, ...){
  va_list ap;
  int nByte;
  const char *z;
  char *zResult;

  if( pz==0 ) return;
  nByte = 1;
  va_start(ap, pz);
  while( (z = va_arg(ap, const char*))!=0 ){
    nByte += strlen(z);
  }
  va_end(ap);
  sqliteFree(*pz);
  *pz = zResult = sqliteMallocRaw( nByte );
  if( zResult==0 ){
    return;
  }

  *zResult = 0;
  va_start(ap, pz);
  while( (z = va_arg(ap, const char*))!=0 ){
    strcpy(zResult, z);
    zResult += strlen(zResult);
  }
  va_end(ap);





}

/*
** Set the most recent error code and error string for the sqlite
** handle "db". The error code is set to "err_code".
**
** If it is not NULL, string zFormat specifies the format of the
** error string in the style of the printf functions: The following
** format characters are allowed:
**
**      %s      Insert a string
**      %z      A string that should be freed after use
**      %d      Insert an integer
**      %T      Insert a token
**      %S      Insert the first element of a SrcList
**
** zFormat and any string tokens that follow it are assumed to be
** encoded in UTF-8.
**
** To clear the most recent error for sqlite handle "db", sqlite3Error
** should be called with err_code set to SQLITE_OK and zFormat set
** to NULL.
*/
void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
  if( db && (db->pErr || (db->pErr = sqlite3ValueNew()))!=0 ){
    db->errCode = err_code;
    if( zFormat ){
      char *z;
      va_list ap;
      va_start(ap, zFormat);
      z = sqlite3VMPrintf(zFormat, ap);
      va_end(ap);







|


<



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

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



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










<
<


>
>
>


<
|

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



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

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

<
<
<
<
<
<
<
<

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

|
<
<
|
>
|
>
|
<

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


<
<
<
<
<


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

<
<
|
>

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

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

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

<
>

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

>
>
>
>
>
>
>
|
<
<
>


<
<
<
>
>

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

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

|
|
<


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





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

<

|



<
<
<
<
<
<
<
<

|
|
<
<
|
|
|
|
|
|

>
>
|
|
<
|
|
|

|

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

|
<
<
<
<




|






|






>








|






|
|









>
|
|





>
>
>
>
>



















|




|







10
11
12
13
14
15
16
17
18
19

20
21
22




































23





24

25

26

27

28


29
30





31
32
33








34










35









36




37







38
39
40



41







42











43
44



45
















46
47






48
49
50
51
52
53
54
55
56
57
58
59
60


61
62
63
64
65
66
67

68
69
70



71
72
73
74
75
76
77
78
79
80
81
82







83










84





85




86
87
88
89
90
91
92







93

94
95

96

97
98
99

100
101
102
103


104
105
106



107
108



109


110



111
112








113

114






115
116

117


118
119
120


121
122
123
124
125

126
127
128
129
130
131
132
133














134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150







151
152
153

154
155


156
157
158
159
160
161
162
163
164
165





166
167


168
169

170









171


172
173
174
175
176


177



178
179


180
181

182


183



184


185
186
187
188
189
190




191
192
193
194
195
196
197
198
199
200
201
202

203





204






205
206
207
208
209

210
211
212

213
214
215
216
217



218
219












220

221

222
223


224

225

226


227




228
229
230
231
232
233
234
235
236
237
238


239
240
241



242
243
244
245

246


247
248





249
250
251





252
253
254
255
256
257
258
259

260
261
262




263


264
265
266
267
268
269
270
271
272

273
274
275



276






277


278
279
280
281
282








283











284












285

286
287
288
289
290








291
292
293


294
295
296
297
298
299
300
301
302
303
304

305
306
307
308
309
310














311


312
313




314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.1 2005/03/01 16:04:37 rmsimpson Exp $
*/
#include "sqliteInt.h"

#include <stdarg.h>
#include <ctype.h>





































#if SQLITE_MEMDEBUG>2 && defined(__GLIBC__)





#include <execinfo.h>

void print_stack_trace(){

  void *bt[30];

  int i;

  int n = backtrace(bt, 30);



  fprintf(stderr, "STACK: ");





  for(i=0; i<n;i++){
    fprintf(stderr, "%p ", bt[i]);
  }








  fprintf(stderr, "\n");










}









#else




#define print_stack_trace()







#endif

/*



** If malloc() ever fails, this global variable gets set to 1.







** This causes the library to abort and never again function.











*/
int sqlite3_malloc_failed = 0;




















/*
** If SQLITE_MEMDEBUG is defined, then use versions of malloc() and






** free() that track memory usage and check for buffer overruns.
*/
#ifdef SQLITE_MEMDEBUG

/*
** For keeping track of the number of mallocs and frees.   This
** is used to check for memory leaks.  The iMallocFail and iMallocReset
** values are used to simulate malloc() failures during testing in 
** order to verify that the library correctly handles an out-of-memory
** condition.
*/
int sqlite3_nMalloc;         /* Number of sqliteMalloc() calls */
int sqlite3_nFree;           /* Number of sqliteFree() calls */


int sqlite3_iMallocFail;     /* Fail sqliteMalloc() after this many calls */
int sqlite3_iMallocReset = -1; /* When iMallocFail reaches 0, set to this */
#if SQLITE_MEMDEBUG>1
static int memcnt = 0;
#endif

/*

** Number of 32-bit guard words
*/
#define N_GUARD 1




/*
** Allocate new memory and set it to zero.  Return NULL if
** no memory is available.
*/
void *sqlite3Malloc_(int n, int bZero, char *zFile, int line){
  void *p;
  int *pi;
  int i, k;
  if( sqlite3_iMallocFail>=0 ){
    sqlite3_iMallocFail--;
    if( sqlite3_iMallocFail==0 ){







      sqlite3_malloc_failed++;










#if SQLITE_MEMDEBUG>1





      fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n",




              n, zFile,line);
#endif
      sqlite3_iMallocFail = sqlite3_iMallocReset;
      return 0;
    }
  }
  if( n==0 ) return 0;







  k = (n+sizeof(int)-1)/sizeof(int);

  pi = malloc( (N_GUARD*2+1+k)*sizeof(int));
  if( pi==0 ){

    if( n>0 ) sqlite3_malloc_failed++;

    return 0;
  }
  sqlite3_nMalloc++;

  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
  pi[N_GUARD] = n;
  for(i=0; i<N_GUARD; i++) pi[k+1+N_GUARD+i] = 0xdead3344;
  p = &pi[N_GUARD+1];


  memset(p, bZero==0, n);
#if SQLITE_MEMDEBUG>1
  print_stack_trace();



  fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n",
      ++memcnt, n, (int)p, zFile,line);



#endif


  return p;



}









/*

** Check to see if the given pointer was obtained from sqliteMalloc()






** and is able to hold at least N bytes.  Raise an exception if this
** is not the case.

**


** This routine is used for testing purposes only.
*/
void sqlite3CheckMemory(void *p, int N){


  int *pi = p;
  int n, i, k;
  pi -= N_GUARD+1;
  for(i=0; i<N_GUARD; i++){
    assert( pi[i]==0xdead1122 );

  }
  n = pi[N_GUARD];
  assert( N>=0 && N<n );
  k = (n+sizeof(int)-1)/sizeof(int);
  for(i=0; i<N_GUARD; i++){
    assert( pi[k+N_GUARD+1+i]==0xdead3344 );
  }
}
















/*
** Free memory previously obtained from sqliteMalloc()
*/
void sqlite3Free_(void *p, char *zFile, int line){
  if( p ){
    int *pi, i, k, n;
    pi = p;
    pi -= N_GUARD+1;
    sqlite3_nFree++;
    for(i=0; i<N_GUARD; i++){
      if( pi[i]!=0xdead1122 ){
        fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);
        return;
      }
    }

    n = pi[N_GUARD];







    k = (n+sizeof(int)-1)/sizeof(int);
    for(i=0; i<N_GUARD; i++){
      if( pi[k+N_GUARD+1+i]!=0xdead3344 ){

        fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p);
        return;


      }
    }
    memset(pi, 0xff, (k+N_GUARD*2+1)*sizeof(int));
#if SQLITE_MEMDEBUG>1
    fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n",
         ++memcnt, n, (int)p, zFile,line);
#endif
    free(pi);
  }
}






/*


** Resize a prior allocation.  If p==0, then this routine
** works just like sqliteMalloc().  If n==0, then this routine

** works just like sqliteFree().









*/


void *sqlite3Realloc_(void *oldP, int n, char *zFile, int line){
  int *oldPi, *pi, i, k, oldN, oldK;
  void *p;
  if( oldP==0 ){
    return sqlite3Malloc_(n,1,zFile,line);


  }



  if( n==0 ){
    sqlite3Free_(oldP,zFile,line);


    return 0;
  }

  oldPi = oldP;


  oldPi -= N_GUARD+1;



  if( oldPi[0]!=0xdead1122 ){


    fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)oldP);
    return 0;
  }
  oldN = oldPi[N_GUARD];
  oldK = (oldN+sizeof(int)-1)/sizeof(int);
  for(i=0; i<N_GUARD; i++){




    if( oldPi[oldK+N_GUARD+1+i]!=0xdead3344 ){
      fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n",
              (int)oldP);
      return 0;
    }
  }
  k = (n + sizeof(int) - 1)/sizeof(int);
  pi = malloc( (k+N_GUARD*2+1)*sizeof(int) );
  if( pi==0 ){
    if( n>0 ) sqlite3_malloc_failed++;
    return 0;
  }

  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;





  pi[N_GUARD] = n;






  for(i=0; i<N_GUARD; i++) pi[k+N_GUARD+1+i] = 0xdead3344;
  p = &pi[N_GUARD+1];
  memcpy(p, oldP, n>oldN ? oldN : n);
  if( n>oldN ){
    memset(&((char*)p)[oldN], 0x55, n-oldN);

  }
  memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int));
  free(oldPi);

#if SQLITE_MEMDEBUG>1
  print_stack_trace();
  fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n",
    ++memcnt, oldN, n, (int)oldP, (int)p, zFile, line);
#endif



  return p;
}














/*

** Make a copy of a string in memory obtained from sqliteMalloc()
*/


char *sqlite3StrDup_(const char *z, char *zFile, int line){

  char *zNew;

  if( z==0 ) return 0;


  zNew = sqlite3Malloc_(strlen(z)+1, 0, zFile, line);




  if( zNew ) strcpy(zNew, z);
  return zNew;
}
char *sqlite3StrNDup_(const char *z, int n, char *zFile, int line){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqlite3Malloc_(n+1, 0, zFile, line);
  if( zNew ){
    memcpy(zNew, z, n);
    zNew[n] = 0;
  }


  return zNew;
}




/*
** A version of sqliteFree that is always a function, not a macro.
*/
void sqlite3FreeX(void *p){

  sqliteFree(p);


}
#endif /* SQLITE_MEMDEBUG */






/*
** The following versions of malloc() and free() are for use in a





** normal build.
*/
#if !defined(SQLITE_MEMDEBUG)

/*
** Allocate new memory and set it to zero.  Return NULL if
** no memory is available.  See also sqliteMallocRaw().
*/

void *sqlite3Malloc(int n){
  void *p;
  if( (p = malloc(n))==0 ){




    if( n>0 ) sqlite3_malloc_failed++;


  }else{
    memset(p, 0, n);
  }
  return p;
}

/*
** Allocate new memory but do not set it to zero.  Return NULL if
** no memory is available.  See also sqliteMalloc().

*/
void *sqlite3MallocRaw(int n){
  void *p;



  if( (p = malloc(n))==0 ){






    if( n>0 ) sqlite3_malloc_failed++;


  }
  return p;
}

/*








** Free memory previously obtained from sqliteMalloc()











*/












void sqlite3FreeX(void *p){

  if( p ){
    free(p);
  }
}









/*
** Resize a prior allocation.  If p==0, then this routine
** works just like sqliteMalloc().  If n==0, then this routine


** works just like sqliteFree().
*/
void *sqlite3Realloc(void *p, int n){
  void *p2;
  if( p==0 ){
    return sqliteMalloc(n);
  }
  if( n==0 ){
    sqliteFree(p);
    return 0;
  }

  p2 = realloc(p, n);
  if( p2==0 ){
    if( n>0 ) sqlite3_malloc_failed++;
  }
  return p2;
}

















/*
** Make a copy of a string in memory obtained from sqliteMalloc()




*/
char *sqlite3StrDup(const char *z){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqliteMallocRaw(strlen(z)+1);
  if( zNew ) strcpy(zNew, z);
  return zNew;
}
char *sqlite3StrNDup(const char *z, int n){
  char *zNew;
  if( z==0 ) return 0;
  zNew = sqliteMallocRaw(n+1);
  if( zNew ){
    memcpy(zNew, z, n);
    zNew[n] = 0;
  }
  return zNew;
}
#endif /* !defined(SQLITE_MEMDEBUG) */

/*
** Create a string from the 2nd and subsequent arguments (up to the
** first NULL argument), store the string in memory obtained from
** sqliteMalloc() and make the pointer indicated by the 1st argument
** point to that string.  The 1st argument must either be NULL or 
** point to memory obtained from sqliteMalloc().
*/
void sqlite3SetString(char **pz, const char *zFirst, ...){
  va_list ap;
  int nByte;
  const char *z;
  char *zResult;

  if( pz==0 ) return;
  nByte = strlen(zFirst) + 1;
  va_start(ap, zFirst);
  while( (z = va_arg(ap, const char*))!=0 ){
    nByte += strlen(z);
  }
  va_end(ap);
  sqliteFree(*pz);
  *pz = zResult = sqliteMallocRaw( nByte );
  if( zResult==0 ){
    return;
  }
  strcpy(zResult, zFirst);
  zResult += strlen(zResult);
  va_start(ap, zFirst);
  while( (z = va_arg(ap, const char*))!=0 ){
    strcpy(zResult, z);
    zResult += strlen(zResult);
  }
  va_end(ap);
#ifdef SQLITE_DEBUG
#if SQLITE_DEBUG>1
  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
#endif
#endif
}

/*
** Set the most recent error code and error string for the sqlite
** handle "db". The error code is set to "err_code".
**
** If it is not NULL, string zFormat specifies the format of the
** error string in the style of the printf functions: The following
** format characters are allowed:
**
**      %s      Insert a string
**      %z      A string that should be freed after use
**      %d      Insert an integer
**      %T      Insert a token
**      %S      Insert the first element of a SrcList
**
** zFormat and any string tokens that follow it are assumed to be
** encoded in UTF-8.
**
** To clear the most recent error for slqite handle "db", sqlite3Error
** should be called with err_code set to SQLITE_OK and zFormat set
** to NULL.
*/
void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
  if( db && (db->pErr || (db->pErr = sqlite3ValueNew())) ){
    db->errCode = err_code;
    if( zFormat ){
      char *z;
      va_list ap;
      va_start(ap, zFormat);
      z = sqlite3VMPrintf(zFormat, ap);
      va_end(ap);
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
  pParse->nErr++;
  sqliteFree(pParse->zErrMsg);
  va_start(ap, zFormat);
  pParse->zErrMsg = sqlite3VMPrintf(zFormat, ap);
  va_end(ap);
}

/*
** Clear the error message in pParse, if any
*/
void sqlite3ErrorClear(Parse *pParse){
  sqliteFree(pParse->zErrMsg);
  pParse->zErrMsg = 0;
  pParse->nErr = 0;
}

/*
** Convert an SQL-style quoted string into a normal string by removing
** the quote characters.  The conversion is done in-place.  If the
** input does not begin with a quote character, then this routine
** is a no-op.
**
** 2002-Feb-14: This routine is extended to remove MS-Access style
** brackets from around identifers.  For example:  "[a-b-c]" becomes
** "a-b-c".
*/
void sqlite3Dequote(char *z){
  int quote;
  int i, j;
  if( z==0 ) return;
  quote = z[0];
  switch( quote ){
    case '\'':  break;
    case '"':   break;
    case '`':   break;                /* For MySQL compatibility */
    case '[':   quote = ']';  break;  /* For MS SqlServer compatibility */
    default:    return;
  }
  for(i=1, j=0; z[i]; i++){
    if( z[i]==quote ){
      if( z[i+1]==quote ){
        z[j++] = quote;
        i++;







<
<
<
<
<
<
<
<
<


















<
|







430
431
432
433
434
435
436









437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454

455
456
457
458
459
460
461
462
  pParse->nErr++;
  sqliteFree(pParse->zErrMsg);
  va_start(ap, zFormat);
  pParse->zErrMsg = sqlite3VMPrintf(zFormat, ap);
  va_end(ap);
}










/*
** Convert an SQL-style quoted string into a normal string by removing
** the quote characters.  The conversion is done in-place.  If the
** input does not begin with a quote character, then this routine
** is a no-op.
**
** 2002-Feb-14: This routine is extended to remove MS-Access style
** brackets from around identifers.  For example:  "[a-b-c]" becomes
** "a-b-c".
*/
void sqlite3Dequote(char *z){
  int quote;
  int i, j;
  if( z==0 ) return;
  quote = z[0];
  switch( quote ){
    case '\'':  break;
    case '"':   break;

    case '[':   quote = ']';  break;
    default:    return;
  }
  for(i=1, j=0; z[i]; i++){
    if( z[i]==quote ){
      if( z[i+1]==quote ){
        z[j++] = quote;
        i++;
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
** is not, the result is undefined.
**
** This routine is used instead of the library atof() function because
** the library atof() might want to use "," as the decimal point instead
** of "." depending on how locale is set.  But that would cause problems
** for SQL.  So this routine always uses "." regardless of locale.
*/
int sqlite3AtoF(const char *z, double *pResult){
#ifndef SQLITE_OMIT_FLOATING_POINT
  int sign = 1;
  const char *zBegin = z;
  LONGDOUBLE_TYPE v1 = 0.0;
  if( *z=='-' ){
    sign = -1;
    z++;
  }else if( *z=='+' ){
    z++;
  }







|
<

<







553
554
555
556
557
558
559
560

561

562
563
564
565
566
567
568
** is not, the result is undefined.
**
** This routine is used instead of the library atof() function because
** the library atof() might want to use "," as the decimal point instead
** of "." depending on how locale is set.  But that would cause problems
** for SQL.  So this routine always uses "." regardless of locale.
*/
double sqlite3AtoF(const char *z, const char **pzEnd){

  int sign = 1;

  LONGDOUBLE_TYPE v1 = 0.0;
  if( *z=='-' ){
    sign = -1;
    z++;
  }else if( *z=='+' ){
    z++;
  }
954
955
956
957
958
959
960

961
962
963
964
965
966
967
968
969
970
971
972
    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
    if( esign<0 ){
      v1 /= scale;
    }else{
      v1 *= scale;
    }
  }

  *pResult = sign<0 ? -v1 : v1;
  return z - zBegin;
#else
  return sqlite3atoi64(z, pResult);
#endif /* SQLITE_OMIT_FLOATING_POINT */
}

/*
** Return TRUE if zNum is a 64-bit signed integer and write
** the value of the integer into *pNum.  If zNum is not an integer
** or is an integer that is too large to be expressed with 64 bits,
** then return false.  If n>0 and the integer is string is not







>
|
<
<
<
<







601
602
603
604
605
606
607
608
609




610
611
612
613
614
615
616
    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
    if( esign<0 ){
      v1 /= scale;
    }else{
      v1 *= scale;
    }
  }
  if( pzEnd ) *pzEnd = z;
  return sign<0 ? -v1 : v1;




}

/*
** Return TRUE if zNum is a 64-bit signed integer and write
** the value of the integer into *pNum.  If zNum is not an integer
** or is an integer that is too large to be expressed with 64 bits,
** then return false.  If n>0 and the integer is string is not
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
** call to sqlite3_close(db) and db has been deallocated.  And we do
** not want to write into deallocated memory.
*/
int sqlite3SafetyOn(sqlite3 *db){
  if( db->magic==SQLITE_MAGIC_OPEN ){
    db->magic = SQLITE_MAGIC_BUSY;
    return 0;
  }else if( db->magic==SQLITE_MAGIC_BUSY ){
    db->magic = SQLITE_MAGIC_ERROR;
    db->flags |= SQLITE_Interrupt;
  }
  return 1;
}

/*
** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN.
** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY
** when this routine is called.
*/
int sqlite3SafetyOff(sqlite3 *db){
  if( db->magic==SQLITE_MAGIC_BUSY ){
    db->magic = SQLITE_MAGIC_OPEN;
    return 0;
  }else if( db->magic==SQLITE_MAGIC_OPEN ){
    db->magic = SQLITE_MAGIC_ERROR;
    db->flags |= SQLITE_Interrupt;
  }
  return 1;
}

/*







|















|







708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
** call to sqlite3_close(db) and db has been deallocated.  And we do
** not want to write into deallocated memory.
*/
int sqlite3SafetyOn(sqlite3 *db){
  if( db->magic==SQLITE_MAGIC_OPEN ){
    db->magic = SQLITE_MAGIC_BUSY;
    return 0;
  }else if( db->magic==SQLITE_MAGIC_BUSY || db->magic==SQLITE_MAGIC_ERROR ){
    db->magic = SQLITE_MAGIC_ERROR;
    db->flags |= SQLITE_Interrupt;
  }
  return 1;
}

/*
** Change the magic from SQLITE_MAGIC_BUSY to SQLITE_MAGIC_OPEN.
** Return an error (non-zero) if the magic was not SQLITE_MAGIC_BUSY
** when this routine is called.
*/
int sqlite3SafetyOff(sqlite3 *db){
  if( db->magic==SQLITE_MAGIC_BUSY ){
    db->magic = SQLITE_MAGIC_OPEN;
    return 0;
  }else if( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ERROR ){
    db->magic = SQLITE_MAGIC_ERROR;
    db->flags |= SQLITE_Interrupt;
  }
  return 1;
}

/*
1210
1211
1212
1213
1214
1215
1216












1217
1218
1219
1220
1221
1222
1223
1224
1225
1226

1227
1228
1229
1230
1231
1232
1233
** Read a 32-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read.  The value is stored in *v.
*/
int sqlite3GetVarint32(const unsigned char *p, u32 *v){
  u32 x;
  int n;
  unsigned char c;












  if( ((signed char*)p)[0]>=0 ){
    *v = p[0];
    return 1;
  }
  x = p[0] & 0x7f;
  if( ((signed char*)p)[1]>=0 ){
    *v = (x<<7) | p[1];
    return 2;
  }
  x = (x<<7) | (p[1] & 0x7f);

  n = 2;
  do{
    x = (x<<7) | ((c = p[n++])&0x7f);
  }while( (c & 0x80)!=0 && n<9 );
  *v = x;
  return n;
}







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










>







854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
** Read a 32-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read.  The value is stored in *v.
*/
int sqlite3GetVarint32(const unsigned char *p, u32 *v){
  u32 x;
  int n;
  unsigned char c;
#if 0
  if( ((c = p[0]) & 0x80)==0 ){
    *v = c;
    return 1;
  }
  x = c & 0x7f;
  if( ((c = p[1]) & 0x80)==0 ){
    *v = (x<<7) | c;
    return 2;
  }
  x = (x<<7) | (c & 0x7f);
#else
  if( ((signed char*)p)[0]>=0 ){
    *v = p[0];
    return 1;
  }
  x = p[0] & 0x7f;
  if( ((signed char*)p)[1]>=0 ){
    *v = (x<<7) | p[1];
    return 2;
  }
  x = (x<<7) | (p[1] & 0x7f);
#endif
  n = 2;
  do{
    x = (x<<7) | ((c = p[n++])&0x7f);
  }while( (c & 0x80)!=0 && n<9 );
  *v = x;
  return n;
}
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
  do{
    i++;
    v >>= 7;
  }while( v!=0 && i<9 );
  return i;
}

#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) \
    || defined(SQLITE_TEST)
/*
** Translate a single byte of Hex into an integer.
*/
static int hexToInt(int h){
  if( h>='0' && h<='9' ){
    return h - '0';
  }else if( h>='a' && h<='f' ){
    return h - 'a' + 10;
  }else{
    assert( h>='A' && h<='F' );
    return h - 'A' + 10;
  }
}
#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC || SQLITE_TEST */

#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
/*
** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
** value.  Return a pointer to its binary value.  Space to hold the
** binary value has been obtained from malloc and must be freed by
** the calling routine.







|














|







898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
  do{
    i++;
    v >>= 7;
  }while( v!=0 && i<9 );
  return i;
}

#if (!defined(SQLITE_OMIT_BLOB_LITERAL) && !defined(SQLITE_HAS_CODEC)) \
    || defined(SQLITE_TEST)
/*
** Translate a single byte of Hex into an integer.
*/
static int hexToInt(int h){
  if( h>='0' && h<='9' ){
    return h - '0';
  }else if( h>='a' && h<='f' ){
    return h - 'a' + 10;
  }else{
    assert( h>='A' && h<='F' );
    return h - 'A' + 10;
  }
}
#endif /* (!SQLITE_OMIT_BLOB_LITERAL && !SQLITE_HAS_CODEC) || SQLITE_TEST */

#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
/*
** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
** value.  Return a pointer to its binary value.  Space to hold the
** binary value has been obtained from malloc and must be freed by
** the calling routine.
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
  }else{
    assert( sizeof(p)==sizeof(v2) );
    v2 = (u32)v;
    p = *(void**)&v2;
  }
  return p;
}
#endif

/*
** Return a pointer to the ThreadData associated with the calling thread.
*/
ThreadData *sqlite3ThreadData(){
  return (ThreadData*)sqlite3OsThreadSpecificData(1);
}

/*
** Return a pointer to the ThreadData associated with the calling thread.
** If no ThreadData has been allocated to this thread yet, return a pointer
** to a substitute ThreadData structure that is all zeros. 
*/
const ThreadData *sqlite3ThreadDataReadOnly(){
  static const ThreadData zeroData;
  const ThreadData *pTd = sqlite3OsThreadSpecificData(0);
  return pTd ? pTd : &zeroData;
}

/*
** Check to see if the ThreadData for this thread is all zero.  If it
** is, then deallocate it. 
*/
void sqlite3ReleaseThreadData(){
  sqlite3OsThreadSpecificData(-1);
}

/*
** Clear the "mallocFailed" flag. This should be invoked before exiting any
** entry points that may have called sqliteMalloc().
*/
void sqlite3MallocClearFailed(){
  ThreadData *pTd = sqlite3OsThreadSpecificData(0);
  if( pTd && pTd->mallocFailed ){
    pTd->mallocFailed = 0;
    sqlite3OsThreadSpecificData(0);
  }
}

#ifndef NDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
*/
void sqlite3MallocDisallow(){
  assert( sqlite3ThreadData()->mallocDisallowed>=0 );
  sqlite3ThreadData()->mallocDisallowed++;
}

/*
** This function clears the flag set in the thread-specific-data structure set
** by sqlite3MallocDisallow().
*/
void sqlite3MallocAllow(){
  assert( sqlite3ThreadData()->mallocDisallowed>0 );
  sqlite3ThreadData()->mallocDisallowed--;
}
#endif








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
962
963
964
965
966
967
968
969


























































  }else{
    assert( sizeof(p)==sizeof(v2) );
    v2 = (u32)v;
    p = *(void**)&v2;
  }
  return p;
}
#endif


























































Changes to SQLite.Interop/src/vacuum.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.16 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
#include "os.h"

#ifndef SQLITE_OMIT_VACUUM
/*
** Generate a random name of 20 character in length.
*/
static void randomName(unsigned char *zBuf){







|


<







10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
**
*************************************************************************
** This file contains code used to implement the VACUUM command.
**
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.1 2005/03/01 16:04:37 rmsimpson Exp $
*/
#include "sqliteInt.h"

#include "os.h"

#ifndef SQLITE_OMIT_VACUUM
/*
** Generate a random name of 20 character in length.
*/
static void randomName(unsigned char *zBuf){
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  sqlite3_stmt *pStmt;
  int rc;

  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
  if( rc!=SQLITE_OK ) return rc;

  while( SQLITE_ROW==sqlite3_step(pStmt) ){
    rc = execSql(db, (char*)sqlite3_column_text(pStmt, 0));
    if( rc!=SQLITE_OK ){
      sqlite3_finalize(pStmt);
      return rc;
    }
  }

  return sqlite3_finalize(pStmt);







|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  sqlite3_stmt *pStmt;
  int rc;

  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
  if( rc!=SQLITE_OK ) return rc;

  while( SQLITE_ROW==sqlite3_step(pStmt) ){
    rc = execSql(db, sqlite3_column_text(pStmt, 0));
    if( rc!=SQLITE_OK ){
      sqlite3_finalize(pStmt);
      return rc;
    }
  }

  return sqlite3_finalize(pStmt);
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#ifndef SQLITE_OMIT_VACUUM
  const char *zFilename;  /* full pathname of the database file */
  int nFilename;          /* number of characters  in zFilename[] */
  char *zTemp = 0;        /* a temporary file in same directory as zFilename */
  Btree *pMain;           /* The database being vacuumed */
  Btree *pTemp;
  char *zSql = 0;
  int saved_flags;       /* Saved value of the db->flags */
  Db *pDb = 0;           /* Database to detach at end of vacuum */

  /* Save the current value of the write-schema flag before setting it. */
  saved_flags = db->flags;
  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;

  if( !db->autoCommit ){
    sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", 
       (char*)0);
    rc = SQLITE_ERROR;
    goto end_of_vacuum;
  }







<
<
<
<
<
<







96
97
98
99
100
101
102






103
104
105
106
107
108
109
#ifndef SQLITE_OMIT_VACUUM
  const char *zFilename;  /* full pathname of the database file */
  int nFilename;          /* number of characters  in zFilename[] */
  char *zTemp = 0;        /* a temporary file in same directory as zFilename */
  Btree *pMain;           /* The database being vacuumed */
  Btree *pTemp;
  char *zSql = 0;







  if( !db->autoCommit ){
    sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", 
       (char*)0);
    rc = SQLITE_ERROR;
    goto end_of_vacuum;
  }
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
    rc = SQLITE_NOMEM;
    goto end_of_vacuum;
  }
  rc = execSql(db, zSql);
  sqliteFree(zSql);
  zSql = 0;
  if( rc!=SQLITE_OK ) goto end_of_vacuum;
  pDb = &db->aDb[db->nDb-1];
  assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
  pTemp = db->aDb[db->nDb-1].pBt;
  sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain),
     sqlite3BtreeGetReserve(pMain));
  assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) );
  rc = execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
  if( rc!=SQLITE_OK ){
    goto end_of_vacuum;
  }

#ifndef SQLITE_OMIT_AUTOVACUUM
  sqlite3BtreeSetAutoVacuum(pTemp, sqlite3BtreeGetAutoVacuum(pMain));
#endif

  /* Begin a transaction */
  rc = execSql(db, "BEGIN EXCLUSIVE;");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Query the schema of the main database. Create a mirror schema
  ** in the temporary database.
  */
  rc = execExecSql(db, 
      "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14,100000000) "







<





|
<
<
<






|







155
156
157
158
159
160
161

162
163
164
165
166
167



168
169
170
171
172
173
174
175
176
177
178
179
180
181
    rc = SQLITE_NOMEM;
    goto end_of_vacuum;
  }
  rc = execSql(db, zSql);
  sqliteFree(zSql);
  zSql = 0;
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 );
  pTemp = db->aDb[db->nDb-1].pBt;
  sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain),
     sqlite3BtreeGetReserve(pMain));
  assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) );
  execSql(db, "PRAGMA vacuum_db.synchronous=OFF");




#ifndef SQLITE_OMIT_AUTOVACUUM
  sqlite3BtreeSetAutoVacuum(pTemp, sqlite3BtreeGetAutoVacuum(pMain));
#endif

  /* Begin a transaction */
  rc = execSql(db, "BEGIN;");
  if( rc!=SQLITE_OK ) goto end_of_vacuum;

  /* Query the schema of the main database. Create a mirror schema
  ** in the temporary database.
  */
  rc = execExecSql(db, 
      "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14,100000000) "
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

318

319
320
321
322
323
324
325
326
327
328
329
  ** transaction open on the vacuum database, but not on the main database.
  ** Open a btree level transaction on the main database. This allows a
  ** call to sqlite3BtreeCopyFile(). The main database btree level
  ** transaction is then committed, so the SQL level never knows it was
  ** opened for writing. This way, the SQL transaction used to create the
  ** temporary database never needs to be committed.
  */
  if( rc==SQLITE_OK ){
    u32 meta;
    int i;

    /* This array determines which meta meta values are preserved in the
    ** vacuum.  Even entries are the meta value number and odd entries
    ** are an increment to apply to the meta value after the vacuum.
    ** The increment is used to increase the schema cookie so that other
    ** connections to the same database will know to reread the schema.
    */
    static const unsigned char aCopy[] = {
       1, 1,    /* Add one to the old schema cookie */
       3, 0,    /* Preserve the default page cache size */
       5, 0,    /* Preserve the default text encoding */
       6, 0,    /* Preserve the user version */
    };

    assert( 1==sqlite3BtreeIsInTrans(pTemp) );
    assert( 1==sqlite3BtreeIsInTrans(pMain) );


    /* Copy Btree meta values */
    for(i=0; i<sizeof(aCopy)/sizeof(aCopy[0]); i+=2){
      rc = sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
      if( rc!=SQLITE_OK ) goto end_of_vacuum;
      rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
      if( rc!=SQLITE_OK ) goto end_of_vacuum;
    }

    rc = sqlite3BtreeCopyFile(pMain, pTemp);
    if( rc!=SQLITE_OK ) goto end_of_vacuum;
    rc = sqlite3BtreeCommit(pTemp);
    if( rc!=SQLITE_OK ) goto end_of_vacuum;
    rc = sqlite3BtreeCommit(pMain);
  }

end_of_vacuum:
  /* Restore the original value of db->flags */
  db->flags = saved_flags;

  /* Currently there is an SQL level transaction open on the vacuum
  ** database. No locks are held on any other files (since the main file
  ** was committed at the btree level). So it safe to end the transaction
  ** by manually setting the autoCommit flag to true and detaching the
  ** vacuum database. The vacuum_db journal file is deleted when the pager
  ** is closed by the DETACH.
  */
  db->autoCommit = 1;

  if( pDb ){
    sqlite3MallocDisallow();
    sqlite3BtreeClose(pDb->pBt);
    sqlite3MallocAllow();
    pDb->pBt = 0;
    pDb->pSchema = 0;
  }

  /* If one of the execSql() calls above returned SQLITE_NOMEM, then the
  ** mallocFailed flag will be clear (because execSql() calls sqlite3_exec()).
  ** Fix this so the flag and return code match.
  */
  if( rc==SQLITE_NOMEM ){
    sqlite3ThreadData()->mallocFailed = 1;

  }


  if( zTemp ){
    sqlite3OsDelete(zTemp);
    sqliteFree(zTemp);
  }
  sqliteFree( zSql );
  sqlite3ResetInternalSchema(db, 0);
#endif

  return rc;
}







|
















|
|
>






<



<
<





<
<
<








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




|


<


238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

271
272
273


274
275
276
277
278



279
280
281
282
283
284
285
286













287

288
289
290
291
292
293
294
295
296
297
298

299
300
  ** transaction open on the vacuum database, but not on the main database.
  ** Open a btree level transaction on the main database. This allows a
  ** call to sqlite3BtreeCopyFile(). The main database btree level
  ** transaction is then committed, so the SQL level never knows it was
  ** opened for writing. This way, the SQL transaction used to create the
  ** temporary database never needs to be committed.
  */
  if( sqlite3BtreeIsInTrans(pTemp) ){
    u32 meta;
    int i;

    /* This array determines which meta meta values are preserved in the
    ** vacuum.  Even entries are the meta value number and odd entries
    ** are an increment to apply to the meta value after the vacuum.
    ** The increment is used to increase the schema cookie so that other
    ** connections to the same database will know to reread the schema.
    */
    static const unsigned char aCopy[] = {
       1, 1,    /* Add one to the old schema cookie */
       3, 0,    /* Preserve the default page cache size */
       5, 0,    /* Preserve the default text encoding */
       6, 0,    /* Preserve the user version */
    };

    assert( 0==sqlite3BtreeIsInTrans(pMain) );
    rc = sqlite3BtreeBeginTrans(pMain, 1);
    if( rc!=SQLITE_OK ) goto end_of_vacuum;

    /* Copy Btree meta values */
    for(i=0; i<sizeof(aCopy)/sizeof(aCopy[0]); i+=2){
      rc = sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
      if( rc!=SQLITE_OK ) goto end_of_vacuum;
      rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);

    }

    rc = sqlite3BtreeCopyFile(pMain, pTemp);


    if( rc!=SQLITE_OK ) goto end_of_vacuum;
    rc = sqlite3BtreeCommit(pMain);
  }

end_of_vacuum:



  /* Currently there is an SQL level transaction open on the vacuum
  ** database. No locks are held on any other files (since the main file
  ** was committed at the btree level). So it safe to end the transaction
  ** by manually setting the autoCommit flag to true and detaching the
  ** vacuum database. The vacuum_db journal file is deleted when the pager
  ** is closed by the DETACH.
  */
  db->autoCommit = 1;













  if( rc==SQLITE_OK ){

    rc = execSql(db, "DETACH vacuum_db;");
  }else{
    execSql(db, "DETACH vacuum_db;");
  }
  if( zTemp ){
    sqlite3OsDelete(zTemp);
    sqliteFree(zTemp);
  }
  if( zSql ) sqliteFree( zSql );
  sqlite3ResetInternalSchema(db, 0);
#endif

  return rc;
}
Changes to SQLite.Interop/src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.16 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.1 2005/03/01 16:04:38 rmsimpson Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

















136
137
138
139
140
141
142
** from sqliteMalloc().  This is different from Stringify() above in that
** Stringify() will use the NBFS bytes of static string space if the string
** will fit but this routine always mallocs for space.
** Return non-zero if we run out of memory.
*/
#define Dynamicify(P,enc) sqlite3VdbeMemDynamicify(P)

/*
** The header of a record consists of a sequence variable-length integers.
** These integers are almost always small and are encoded as a single byte.
** The following macro takes advantage this fact to provide a fast decode
** of the integers in a record header.  It is faster for the common case
** where the integer is a single byte.  It is a little slower when the
** integer is two or more bytes.  But overall it is faster.
**
** The following expressions are equivalent:
**
**     x = sqlite3GetVarint32( A, &B );
**
**     x = GetVarint( A, B );
**
*/
#define GetVarint(A,B)  ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B))

/*
** An ephemeral string value (signified by the MEM_Ephem flag) contains
** a pointer to a dynamically allocated string where some other entity
** is responsible for deallocating that string.  Because the stack entry
** does not control the string, it might be deleted without the stack
** entry knowing it.
**
** This routine converts an ephemeral string into a dynamically allocated
** string that the stack entry itself controls.  In other words, it
** converts an MEM_Ephem string into an MEM_Dyn string.
*/
#define Deephemeralize(P) \
   if( ((P)->flags&MEM_Ephem)!=0 \
       && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}


















/*
** Argument pMem points at a memory cell that will be passed to a
** user-defined function or returned to the user as the result of a query.
** The second argument, 'db_enc' is the text encoding used by the vdbe for
** stack variables.  This routine sets the pMem->enc and pMem->type
** variables used by the sqlite3_value_*() routines.
*/







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















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







97
98
99
100
101
102
103
















104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
** from sqliteMalloc().  This is different from Stringify() above in that
** Stringify() will use the NBFS bytes of static string space if the string
** will fit but this routine always mallocs for space.
** Return non-zero if we run out of memory.
*/
#define Dynamicify(P,enc) sqlite3VdbeMemDynamicify(P)


















/*
** An ephemeral string value (signified by the MEM_Ephem flag) contains
** a pointer to a dynamically allocated string where some other entity
** is responsible for deallocating that string.  Because the stack entry
** does not control the string, it might be deleted without the stack
** entry knowing it.
**
** This routine converts an ephemeral string into a dynamically allocated
** string that the stack entry itself controls.  In other words, it
** converts an MEM_Ephem string into an MEM_Dyn string.
*/
#define Deephemeralize(P) \
   if( ((P)->flags&MEM_Ephem)!=0 \
       && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}

/*
** Convert the given stack entity into a integer if it isn't one
** already.
**
** Any prior string or real representation is invalidated.  
** NULLs are converted into 0.
*/
#define Integerify(P) sqlite3VdbeMemIntegerify(P)

/*
** Convert P so that it has type MEM_Real.
**
** Any prior string or integer representation is invalidated.
** NULLs are converted into 0.0.
*/
#define Realify(P) sqlite3VdbeMemRealify(P)

/*
** Argument pMem points at a memory cell that will be passed to a
** user-defined function or returned to the user as the result of a query.
** The second argument, 'db_enc' is the text encoding used by the vdbe for
** stack variables.  This routine sets the pMem->enc and pMem->type
** variables used by the sqlite3_value_*() routines.
*/
154
155
156
157
158
159
160
































161
162
163
164
165
166
167
168
169
170
171
172
173

































174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211


212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

242



243


244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  }
  else if( flags & MEM_Str ){
    pMem->type = SQLITE_TEXT;
  }else{
    pMem->type = SQLITE_BLOB;
  }
}

































/*
** Pop the stack N times.
*/
static void popStack(Mem **ppTos, int N){
  Mem *pTos = *ppTos;
  while( N>0 ){
    N--;
    Release(pTos);
    pTos--;
  }
  *ppTos = pTos;
}


































/*
** Allocate cursor number iCur.  Return a pointer to it.  Return NULL
** if we run out of memory.
*/
static Cursor *allocateCursor(Vdbe *p, int iCur, int iDb){
  Cursor *pCx;
  assert( iCur<p->nCursor );
  if( p->apCsr[iCur] ){
    sqlite3VdbeFreeCursor(p->apCsr[iCur]);
  }
  p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) );
  if( pCx ){
    pCx->iDb = iDb;
  }
  return pCx;
}

/*

** Processing is determine by the affinity parameter:
**
** SQLITE_AFF_INTEGER:
** SQLITE_AFF_REAL:
** SQLITE_AFF_NUMERIC:
**    Try to convert pRec to an integer representation or a 
**    floating-point representation if an integer representation
**    is not possible.  Note that the integer representation is
**    always preferred, even if the affinity is REAL, because
**    an integer representation is more space efficient on disk.
**
** SQLITE_AFF_TEXT:
**    Convert pRec to a text representation.
**
** SQLITE_AFF_NONE:
**    No-op.  pRec is unchanged.
*/
static void applyAffinity(Mem *pRec, char affinity, u8 enc){
  if( affinity==SQLITE_AFF_TEXT ){


    /* Only attempt the conversion to TEXT if there is an integer or real
    ** representation (blob and NULL do not get converted) but no string
    ** representation.
    */
    if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
      sqlite3VdbeMemStringify(pRec, enc);
    }
    pRec->flags &= ~(MEM_Real|MEM_Int);
  }else if( affinity!=SQLITE_AFF_NONE ){
    assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
             || affinity==SQLITE_AFF_NUMERIC );
    if( 0==(pRec->flags&(MEM_Real|MEM_Int)) ){
      /* pRec does not have a valid integer or real representation. 
      ** Attempt a conversion if pRec has a string representation and
      ** it looks like a number.
      */
      int realnum;
      sqlite3VdbeMemNulTerminate(pRec);
      if( (pRec->flags&MEM_Str)
           && sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){
        i64 value;
        sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
        if( !realnum && sqlite3atoi64(pRec->z, &value) ){
          sqlite3VdbeMemRelease(pRec);
          pRec->i = value;
          pRec->flags = MEM_Int;
        }else{
          sqlite3VdbeMemNumerify(pRec);
        }
      }

    }else if( pRec->flags & MEM_Real ){



      sqlite3VdbeIntegerAffinity(pRec);


    }
  }
}

/*
** Exported version of applyAffinity(). This one works on sqlite3_value*, 
** not the internal Mem* type.
*/
void sqlite3ValueApplyAffinity(sqlite3_value *pVal, u8 affinity, u8 enc){
  applyAffinity((Mem *)pVal, affinity, enc);
}

#ifdef SQLITE_DEBUG
/*
** Write a nice string representation of the contents of cell pMem
** into buffer zBuf, length nBuf.
*/







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













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





|






<
<
<




>
|

|
|
|
<
<
<
<
<
<
|
<

<
<


|
>
>








|
<
<







<
|
<
<
|
|
<
<

|


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







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251



252
253
254
255
256
257
258
259
260
261






262

263


264
265
266
267
268
269
270
271
272
273
274
275
276
277


278
279
280
281
282
283
284

285


286
287


288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303






304
305
306
307
308
309
310
  }
  else if( flags & MEM_Str ){
    pMem->type = SQLITE_TEXT;
  }else{
    pMem->type = SQLITE_BLOB;
  }
}

/*
** Insert a new aggregate element and make it the element that
** has focus.
**
** Return 0 on success and 1 if memory is exhausted.
*/
static int AggInsert(Agg *p, char *zKey, int nKey){
  AggElem *pElem;
  int i;
  int rc;
  pElem = sqliteMalloc( sizeof(AggElem) + nKey +
                        (p->nMem-1)*sizeof(pElem->aMem[0]) );
  if( pElem==0 ) return SQLITE_NOMEM;
  pElem->zKey = (char*)&pElem->aMem[p->nMem];
  memcpy(pElem->zKey, zKey, nKey);
  pElem->nKey = nKey;

  if( p->pCsr ){
    rc = sqlite3BtreeInsert(p->pCsr, zKey, nKey, &pElem, sizeof(AggElem*));
    if( rc!=SQLITE_OK ){
      sqliteFree(pElem);
      return rc;
    }
  }

  for(i=0; i<p->nMem; i++){
    pElem->aMem[i].flags = MEM_Null;
  }
  p->pCurrent = pElem;
  return 0;
}

/*
** Pop the stack N times.
*/
static void popStack(Mem **ppTos, int N){
  Mem *pTos = *ppTos;
  while( N>0 ){
    N--;
    Release(pTos);
    pTos--;
  }
  *ppTos = pTos;
}

/*
** The parameters are pointers to the head of two sorted lists
** of Sorter structures.  Merge these two lists together and return
** a single sorted list.  This routine forms the core of the merge-sort
** algorithm.
**
** In the case of a tie, left sorts in front of right.
*/
static Sorter *Merge(Sorter *pLeft, Sorter *pRight, KeyInfo *pKeyInfo){
  Sorter sHead;
  Sorter *pTail;
  pTail = &sHead;
  pTail->pNext = 0;
  while( pLeft && pRight ){
    int c = sqlite3VdbeRecordCompare(pKeyInfo, pLeft->nKey, pLeft->zKey,
                                     pRight->nKey, pRight->zKey);
    if( c<=0 ){
      pTail->pNext = pLeft;
      pLeft = pLeft->pNext;
    }else{
      pTail->pNext = pRight;
      pRight = pRight->pNext;
    }
    pTail = pTail->pNext;
  }
  if( pLeft ){
    pTail->pNext = pLeft;
  }else if( pRight ){
    pTail->pNext = pRight;
  }
  return sHead.pNext;
}

/*
** Allocate cursor number iCur.  Return a pointer to it.  Return NULL
** if we run out of memory.
*/
static Cursor *allocateCursor(Vdbe *p, int iCur){
  Cursor *pCx;
  assert( iCur<p->nCursor );
  if( p->apCsr[iCur] ){
    sqlite3VdbeFreeCursor(p->apCsr[iCur]);
  }
  p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) );



  return pCx;
}

/*
** Apply any conversion required by the supplied column affinity to
** memory cell pRec. affinity may be one of:
**
** SQLITE_AFF_NUMERIC
** SQLITE_AFF_TEXT
** SQLITE_AFF_NONE






** SQLITE_AFF_INTEGER

**


*/
static void applyAffinity(Mem *pRec, char affinity, u8 enc){
  if( affinity==SQLITE_AFF_NONE ){
    /* do nothing */
  }else if( affinity==SQLITE_AFF_TEXT ){
    /* Only attempt the conversion to TEXT if there is an integer or real
    ** representation (blob and NULL do not get converted) but no string
    ** representation.
    */
    if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
      sqlite3VdbeMemStringify(pRec, enc);
    }
    pRec->flags &= ~(MEM_Real|MEM_Int);
  }else{


    if( 0==(pRec->flags&(MEM_Real|MEM_Int)) ){
      /* pRec does not have a valid integer or real representation. 
      ** Attempt a conversion if pRec has a string representation and
      ** it looks like a number.
      */
      int realnum;
      sqlite3VdbeMemNulTerminate(pRec);

      if( pRec->flags&MEM_Str && sqlite3IsNumber(pRec->z, &realnum, enc) ){


        if( realnum ){
          Realify(pRec);


        }else{
          Integerify(pRec);
        }
      }
    }

    if( affinity==SQLITE_AFF_INTEGER ){
      /* For INTEGER affinity, try to convert a real value to an int */
      if( (pRec->flags&MEM_Real) && !(pRec->flags&MEM_Int) ){
        pRec->i = pRec->r;
        if( ((double)pRec->i)==pRec->r ){
          pRec->flags |= MEM_Int;
        }
      }
    }
  }






}

#ifdef SQLITE_DEBUG
/*
** Write a nice string representation of the contents of cell pMem
** into buffer zBuf, length nBuf.
*/
391
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423


424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
int sqlite3VdbeExec(
  Vdbe *p                    /* The VDBE */
){
  int pc;                    /* The program counter */
  Op *pOp;                   /* Current operation */
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */
  u8 encoding = ENC(db);     /* The database encoding */
  Mem *pTos;                 /* Top entry in the operand stack */

#ifdef VDBE_PROFILE
  unsigned long long start;  /* CPU clock count at start of opcode */
  int origPc;                /* Program counter at start of opcode */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int nProgressOps = 0;      /* Opcodes executed since progress callback. */
#endif
#ifndef NDEBUG
  Mem *pStackLimit;
#endif
  ThreadData *pTsd = sqlite3ThreadData();

  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
  pTsd->nRef++;
  assert( db->magic==SQLITE_MAGIC_BUSY );
  pTos = p->pTos;
  if( p->rc==SQLITE_NOMEM ){
    /* This happens if a malloc() inside a call to sqlite3_column_text() or
    ** sqlite3_column_text16() failed.  */
    goto no_mem;
  }
  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
  p->rc = SQLITE_OK;
  assert( p->explain==0 );


  if( p->popStack ){
    popStack(&pTos, p->popStack);
    p->popStack = 0;
  }
  p->resOnStack = 0;
  db->busyHandler.nBusy = 0;
  CHECK_FOR_INTERRUPT;
  for(pc=p->pc; rc==SQLITE_OK; pc++){
    assert( pc>=0 && pc<p->nOp );
    assert( pTos<=&p->aStack[pc] );
    if( pTsd->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
    origPc = pc;
    start = hwtime();
#endif
    pOp = &p->aOp[pc];

    /* Only allow tracing if SQLITE_DEBUG is defined.







<

>







<
<
<
<


<

<
<
<
<
<
<



>
>





<




<







441
442
443
444
445
446
447

448
449
450
451
452
453
454
455
456




457
458

459






460
461
462
463
464
465
466
467
468
469

470
471
472
473

474
475
476
477
478
479
480
int sqlite3VdbeExec(
  Vdbe *p                    /* The VDBE */
){
  int pc;                    /* The program counter */
  Op *pOp;                   /* Current operation */
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */

  Mem *pTos;                 /* Top entry in the operand stack */
  char zBuf[100];            /* Space to sprintf() an integer */
#ifdef VDBE_PROFILE
  unsigned long long start;  /* CPU clock count at start of opcode */
  int origPc;                /* Program counter at start of opcode */
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int nProgressOps = 0;      /* Opcodes executed since progress callback. */
#endif





  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;

  assert( db->magic==SQLITE_MAGIC_BUSY );






  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
  p->rc = SQLITE_OK;
  assert( p->explain==0 );
  pTos = p->pTos;
  if( sqlite3_malloc_failed ) goto no_mem;
  if( p->popStack ){
    popStack(&pTos, p->popStack);
    p->popStack = 0;
  }
  p->resOnStack = 0;

  CHECK_FOR_INTERRUPT;
  for(pc=p->pc; rc==SQLITE_OK; pc++){
    assert( pc>=0 && pc<p->nOp );
    assert( pTos<=&p->aStack[pc] );

#ifdef VDBE_PROFILE
    origPc = pc;
    start = hwtime();
#endif
    pOp = &p->aOp[pc];

    /* Only allow tracing if SQLITE_DEBUG is defined.
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624





625
626
627

628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646

647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697

698

699
700
701
702
703
704


705

706
707
708
709
710
711

712
713
714
715

716
717

718
719
720
721
722
723
724
725
726
727
        }
        nProgressOps = 0;
      }
      nProgressOps++;
    }
#endif

#ifndef NDEBUG
    /* This is to check that the return value of static function
    ** opcodeNoPush() (see vdbeaux.c) returns values that match the
    ** implementation of the virtual machine in this file. If
    ** opcodeNoPush() returns non-zero, then the stack is guarenteed
    ** not to grow when the opcode is executed. If it returns zero, then
    ** the stack may grow by at most 1.
    **
    ** The global wrapper function sqlite3VdbeOpcodeUsesStack() is not 
    ** available if NDEBUG is defined at build time.
    */ 
    pStackLimit = pTos;
    if( !sqlite3VdbeOpcodeNoPush(pOp->opcode) ){
      pStackLimit++;
    }
#endif

    switch( pOp->opcode ){

/*****************************************************************************
** What follows is a massive switch statement where each case implements a
** separate instruction in the virtual machine.  If we follow the usual
** indentation conventions, each case should be indented by 6 spaces.  But
** that is a lot of wasted space on the left margin.  So the code within
** the switch statement will break with convention and be flush-left. Another
** big comment (similar to this one) will mark the point in the code where
** we transition back to normal indentation.
**
** The formatting of each case is important.  The makefile for SQLite
** generates two C files "opcodes.h" and "opcodes.c" by scanning this
** file looking for lines that begin with "case OP_".  The opcodes.h files
** will be filled with #defines that give unique integer values to each
** opcode and the opcodes.c file is filled with an array of strings where
** each string is the symbolic name for the corresponding opcode.  If the
** case statement is followed by a comment of the form "/# same as ... #/"
** that comment is used to determine the particular value of the opcode.
**
** If a comment on the same line as the "case OP_" construction contains
** the word "no-push", then the opcode is guarenteed not to grow the 
** vdbe stack when it is executed. See function opcode() in
** vdbeaux.c for details.
**
** Documentation about VDBE opcodes is generated by scanning this file
** for lines of that contain "Opcode:".  That line and all subsequent
** comment lines are used in the generation of the opcode.html documentation
** file.
**
** SUMMARY:
**
**     Formatting is important to scripts that scan this file.
**     Do not deviate from the formatting style currently in use.
**
*****************************************************************************/

/* Opcode:  Goto * P2 *
**
** An unconditional jump to address P2.
** The next instruction executed will be 
** the one at index P2 from the beginning of
** the program.
*/
case OP_Goto: {             /* no-push */
  CHECK_FOR_INTERRUPT;
  pc = pOp->p2 - 1;
  break;
}

/* Opcode:  Gosub * P2 *
**
** Push the current address plus 1 onto the return address stack
** and then jump to address P2.
**
** The return address stack is of limited depth.  If too many
** OP_Gosub operations occur without intervening OP_Returns, then
** the return address stack will fill up and processing will abort
** with a fatal error.
*/
case OP_Gosub: {            /* no-push */
  assert( p->returnDepth<sizeof(p->returnStack)/sizeof(p->returnStack[0]) );
  p->returnStack[p->returnDepth++] = pc+1;
  pc = pOp->p2 - 1;
  break;
}

/* Opcode:  Return * * *
**
** Jump immediately to the next instruction after the last unreturned
** OP_Gosub.  If an OP_Return has occurred for all OP_Gosubs, then
** processing aborts with a fatal error.
*/
case OP_Return: {           /* no-push */
  assert( p->returnDepth>0 );
  p->returnDepth--;
  pc = p->returnStack[p->returnDepth] - 1;
  break;
}

/* Opcode:  Halt P1 P2 P3
**
** Exit immediately.  All open cursors, Fifos, etc are closed
** automatically.
**
** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(),
** or sqlite3_finalize().  For a normal halt, this should be SQLITE_OK (0).
** For errors, it can be some other value.  If P1!=0 then P2 will determine
** whether or not to rollback the current transaction.  Do not rollback
** if P2==OE_Fail. Do the rollback if P2==OE_Rollback.  If P2==OE_Abort,
** then back out all changes that have occurred during this execution of the
** VDBE, but do not rollback the transaction. 
**
** If P3 is not null then it is an error message string.
**
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** every program.  So a jump past the last instruction of the program
** is the same as executing Halt.
*/
case OP_Halt: {            /* no-push */
  p->pTos = pTos;
  p->rc = pOp->p1;
  p->pc = pc;
  p->errorAction = pOp->p2;
  if( pOp->p3 ){
    sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
  }
  rc = sqlite3VdbeHalt(p);
  assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
  pTsd->nRef--;
  if( rc==SQLITE_BUSY ){
    p->rc = SQLITE_BUSY;
    return SQLITE_BUSY;
  }
  return p->rc ? SQLITE_ERROR : SQLITE_DONE;
}

/* Opcode: Integer P1 * *
**
** The 32-bit integer value P1 is pushed onto the stack.





*/
case OP_Integer: {
  pTos++;

  pTos->flags = MEM_Int;
  pTos->i = pOp->p1;
  break;
}

/* Opcode: Int64 * * P3
**
** P3 is a string representation of an integer.  Convert that integer
** to a 64-bit value and push it onto the stack.
*/
case OP_Int64: {
  pTos++;
  assert( pOp->p3!=0 );
  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
  pTos->z = pOp->p3;
  pTos->n = strlen(pTos->z);
  pTos->enc = SQLITE_UTF8;
  pTos->i = sqlite3VdbeIntValue(pTos);
  pTos->flags |= MEM_Int;

  break;
}

/* Opcode: Real * * P3
**
** The string value P3 is converted to a real and pushed on to the stack.
*/
case OP_Real: {            /* same as TK_FLOAT, */
  pTos++;
  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
  pTos->z = pOp->p3;
  pTos->n = strlen(pTos->z);
  pTos->enc = SQLITE_UTF8;
  pTos->r = sqlite3VdbeRealValue(pTos);
  pTos->flags |= MEM_Real;
  sqlite3VdbeChangeEncoding(pTos, encoding);
  break;
}

/* Opcode: String8 * * P3
**
** P3 points to a nul terminated UTF-8 string. This opcode is transformed 
** into an OP_String before it is executed for the first time.
*/
case OP_String8: {         /* same as TK_STRING */
  assert( pOp->p3!=0 );
  pOp->opcode = OP_String;
  pOp->p1 = strlen(pOp->p3);

#ifndef SQLITE_OMIT_UTF16
  if( encoding!=SQLITE_UTF8 ){
    pTos++;
    sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
    if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem;
    if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
    pTos->flags &= ~(MEM_Dyn);
    pTos->flags |= MEM_Static;
    if( pOp->p3type==P3_DYNAMIC ){
      sqliteFree(pOp->p3);
    }
    pOp->p3type = P3_DYNAMIC;
    pOp->p3 = pTos->z;
    pOp->p1 = pTos->n;
    break;
  }
#endif
  /* Otherwise fall through to the next case, OP_String */
}
  
/* Opcode: String P1 * P3
**

** The string value P3 of length P1 (bytes) is pushed onto the stack.

*/
case OP_String: {
  pTos++;
  assert( pOp->p3!=0 );
  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
  pTos->z = pOp->p3;


  pTos->n = pOp->p1;

  pTos->enc = encoding;
  break;
}

/* Opcode: Null * * *
**

** Push a NULL onto the stack.
*/
case OP_Null: {
  pTos++;

  pTos->flags = MEM_Null;
  pTos->n = 0;

  break;
}


#ifndef SQLITE_OMIT_BLOB_LITERAL
/* Opcode: HexBlob * * P3
**
** P3 is an UTF-8 SQL hex encoding of a blob. The blob is pushed onto the
** vdbe stack.
**







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















<
<
<
<
<



















|















|












|






|

|










<
<




|









<







|

|
>
>
>
>
>



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







|







|





|



|

<

<
|


|








<






|

>
|
>



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


<







520
521
522
523
524
525
526

















527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546





547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614


615
616
617
618
619
620
621
622
623
624
625
626
627
628

629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649

650









651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684

685

686
687
688
689
690
691
692
693
694
695
696
697

698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719

720
721


722
723

724
725
726
727

728
729
730

731
732
733
734
735
736
737
        }
        nProgressOps = 0;
      }
      nProgressOps++;
    }
#endif


















    switch( pOp->opcode ){

/*****************************************************************************
** What follows is a massive switch statement where each case implements a
** separate instruction in the virtual machine.  If we follow the usual
** indentation conventions, each case should be indented by 6 spaces.  But
** that is a lot of wasted space on the left margin.  So the code within
** the switch statement will break with convention and be flush-left. Another
** big comment (similar to this one) will mark the point in the code where
** we transition back to normal indentation.
**
** The formatting of each case is important.  The makefile for SQLite
** generates two C files "opcodes.h" and "opcodes.c" by scanning this
** file looking for lines that begin with "case OP_".  The opcodes.h files
** will be filled with #defines that give unique integer values to each
** opcode and the opcodes.c file is filled with an array of strings where
** each string is the symbolic name for the corresponding opcode.  If the
** case statement is followed by a comment of the form "/# same as ... #/"
** that comment is used to determine the particular value of the opcode.
**





** Documentation about VDBE opcodes is generated by scanning this file
** for lines of that contain "Opcode:".  That line and all subsequent
** comment lines are used in the generation of the opcode.html documentation
** file.
**
** SUMMARY:
**
**     Formatting is important to scripts that scan this file.
**     Do not deviate from the formatting style currently in use.
**
*****************************************************************************/

/* Opcode:  Goto * P2 *
**
** An unconditional jump to address P2.
** The next instruction executed will be 
** the one at index P2 from the beginning of
** the program.
*/
case OP_Goto: {
  CHECK_FOR_INTERRUPT;
  pc = pOp->p2 - 1;
  break;
}

/* Opcode:  Gosub * P2 *
**
** Push the current address plus 1 onto the return address stack
** and then jump to address P2.
**
** The return address stack is of limited depth.  If too many
** OP_Gosub operations occur without intervening OP_Returns, then
** the return address stack will fill up and processing will abort
** with a fatal error.
*/
case OP_Gosub: {
  assert( p->returnDepth<sizeof(p->returnStack)/sizeof(p->returnStack[0]) );
  p->returnStack[p->returnDepth++] = pc+1;
  pc = pOp->p2 - 1;
  break;
}

/* Opcode:  Return * * *
**
** Jump immediately to the next instruction after the last unreturned
** OP_Gosub.  If an OP_Return has occurred for all OP_Gosubs, then
** processing aborts with a fatal error.
*/
case OP_Return: {
  assert( p->returnDepth>0 );
  p->returnDepth--;
  pc = p->returnStack[p->returnDepth] - 1;
  break;
}

/* Opcode:  Halt P1 P2 *
**
** Exit immediately.  All open cursors, Lists, Sorts, etc are closed
** automatically.
**
** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(),
** or sqlite3_finalize().  For a normal halt, this should be SQLITE_OK (0).
** For errors, it can be some other value.  If P1!=0 then P2 will determine
** whether or not to rollback the current transaction.  Do not rollback
** if P2==OE_Fail. Do the rollback if P2==OE_Rollback.  If P2==OE_Abort,
** then back out all changes that have occurred during this execution of the
** VDBE, but do not rollback the transaction. 
**


** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** every program.  So a jump past the last instruction of the program
** is the same as executing Halt.
*/
case OP_Halt: {
  p->pTos = pTos;
  p->rc = pOp->p1;
  p->pc = pc;
  p->errorAction = pOp->p2;
  if( pOp->p3 ){
    sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
  }
  rc = sqlite3VdbeHalt(p);
  assert( rc==SQLITE_BUSY || rc==SQLITE_OK );

  if( rc==SQLITE_BUSY ){
    p->rc = SQLITE_BUSY;
    return SQLITE_BUSY;
  }
  return p->rc ? SQLITE_ERROR : SQLITE_DONE;
}

/* Opcode: Integer P1 * P3
**
** The integer value P1 is pushed onto the stack.  If P3 is not zero
** then it is assumed to be a string representation of the same integer.
** If P1 is zero and P3 is not zero, then the value is derived from P3.
**
** If the value cannot be represented as a 32-bits then its value
** will be in P3.
*/
case OP_Integer: {
  pTos++;
  if( pOp->p3==0 ){
    pTos->flags = MEM_Int;
    pTos->i = pOp->p1;

  }else{









    pTos->flags = MEM_Str|MEM_Static|MEM_Term;
    pTos->z = pOp->p3;
    pTos->n = strlen(pTos->z);
    pTos->enc = SQLITE_UTF8;
    pTos->i = sqlite3VdbeIntValue(pTos);
    pTos->flags |= MEM_Int;
  }
  break;
}

/* Opcode: Real * * P3
**
** The string value P3 is converted to a real and pushed on to the stack.
*/
case OP_Real: {            /* same as TK_FLOAT */
  pTos++;
  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
  pTos->z = pOp->p3;
  pTos->n = strlen(pTos->z);
  pTos->enc = SQLITE_UTF8;
  pTos->r = sqlite3VdbeRealValue(pTos);
  pTos->flags |= MEM_Real;
  sqlite3VdbeChangeEncoding(pTos, db->enc);
  break;
}

/* Opcode: String8 * * P3
**
** P3 points to a nul terminated UTF-8 string. This opcode is transformed
** into an OP_String before it is executed for the first time.
*/
case OP_String8: {         /* same as TK_STRING */
#ifndef SQLITE_OMIT_UTF16
  pOp->opcode = OP_String;



  if( db->enc!=SQLITE_UTF8 && pOp->p3 ){
    pTos++;
    sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
    if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, db->enc) ) goto no_mem;
    if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
    pTos->flags &= ~(MEM_Dyn);
    pTos->flags |= MEM_Static;
    if( pOp->p3type==P3_DYNAMIC ){
      sqliteFree(pOp->p3);
    }
    pOp->p3type = P3_DYNAMIC;
    pOp->p3 = pTos->z;

    break;
  }
#endif
  /* Otherwise fall through to the next case, OP_String */
}
  
/* Opcode: String * * P3
**
** The string value P3 is pushed onto the stack.  If P3==0 then a
** NULL is pushed onto the stack. P3 is assumed to be a nul terminated
** string encoded with the database native encoding.
*/
case OP_String: {
  pTos++;
  if( pOp->p3 ){
    pTos->flags = MEM_Str|MEM_Static|MEM_Term;
    pTos->z = pOp->p3;
#ifndef SQLITE_OMIT_UTF16
    if( db->enc==SQLITE_UTF8 ){
      pTos->n = strlen(pTos->z);
    }else{
      pTos->n  = sqlite3utf16ByteLen(pTos->z, -1);

    }
#else


    assert( db->enc==SQLITE_UTF8 );
    pTos->n = strlen(pTos->z);

#endif
    pTos->enc = db->enc;
  }else{
    pTos->flags = MEM_Null;

  }
  break;
}


#ifndef SQLITE_OMIT_BLOB_LITERAL
/* Opcode: HexBlob * * P3
**
** P3 is an UTF-8 SQL hex encoding of a blob. The blob is pushed onto the
** vdbe stack.
**
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
  break;
}

/* Opcode: Pop P1 * *
**
** P1 elements are popped off of the top of stack and discarded.
*/
case OP_Pop: {            /* no-push */
  assert( pOp->p1>=0 );
  popStack(&pTos, pOp->p1);
  assert( pTos>=&p->aStack[-1] );
  break;
}

/* Opcode: Dup P1 P2 *







|







794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
  break;
}

/* Opcode: Pop P1 * *
**
** P1 elements are popped off of the top of stack and discarded.
*/
case OP_Pop: {
  assert( pOp->p1>=0 );
  popStack(&pTos, pOp->p1);
  assert( pTos>=&p->aStack[-1] );
  break;
}

/* Opcode: Dup P1 P2 *
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
** the stack and pushed back on top of the stack.  The
** top of the stack is element 0, so "Pull 0 0 0" is
** a no-op.  "Pull 1 0 0" swaps the top two elements of
** the stack.
**
** See also the Dup instruction.
*/
case OP_Pull: {            /* no-push */
  Mem *pFrom = &pTos[-pOp->p1];
  int i;
  Mem ts;

  ts = *pFrom;
  Deephemeralize(pTos);
  for(i=0; i<pOp->p1; i++, pFrom++){







|







837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
** the stack and pushed back on top of the stack.  The
** top of the stack is element 0, so "Pull 0 0 0" is
** a no-op.  "Pull 1 0 0" swaps the top two elements of
** the stack.
**
** See also the Dup instruction.
*/
case OP_Pull: {
  Mem *pFrom = &pTos[-pOp->p1];
  int i;
  Mem ts;

  ts = *pFrom;
  Deephemeralize(pTos);
  for(i=0; i<pOp->p1; i++, pFrom++){
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928

/* Opcode: Push P1 * *
**
** Overwrite the value of the P1-th element down on the
** stack (P1==0 is the top of the stack) with the value
** of the top of the stack.  Then pop the top of the stack.
*/
case OP_Push: {            /* no-push */
  Mem *pTo = &pTos[-pOp->p1];

  assert( pTo>=p->aStack );
  sqlite3VdbeMemMove(pTo, pTos);
  pTos--;
  break;
}

/* Opcode: Callback P1 * *
**
** The top P1 values on the stack represent a single result row from
** a query.  This opcode causes the sqlite3_step() call to terminate
** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
** structure to provide access to the top P1 values as the result
** row.  When the sqlite3_step() function is run again, the top P1
** values will be automatically popped from the stack before the next
** instruction executes.
*/
case OP_Callback: {            /* no-push */
  Mem *pMem;
  Mem *pFirstColumn;
  assert( p->nResColumn==pOp->p1 );

  /* Data in the pager might be moved or changed out from under us
  ** in between the return from this sqlite3_step() call and the
  ** next call to sqlite3_step().  So deephermeralize everything on 
  ** the stack.  Note that ephemeral data is never stored in memory 
  ** cells so we do not have to worry about them.
  */
  pFirstColumn = &pTos[0-pOp->p1];
  for(pMem = p->aStack; pMem<pFirstColumn; pMem++){
    Deephemeralize(pMem);
  }

  /* Invalidate all ephemeral cursor row caches */
  p->cacheCtr = (p->cacheCtr + 2)|1;

  /* Make sure the results of the current row are \000 terminated
  ** and have an assigned type.  The results are deephemeralized as
  ** as side effect.
  */
  for(; pMem<=pTos; pMem++ ){
    sqlite3VdbeMemNulTerminate(pMem);
    storeTypeInfo(pMem, encoding);
  }

  /* Set up the statement structure so that it will pop the current
  ** results from the stack when the statement returns.
  */
  p->resOnStack = 1;
  p->nCallback++;
  p->popStack = pOp->p1;
  p->pc = pc + 1;
  p->pTos = pTos;
  pTsd->nRef--;
  return SQLITE_ROW;
}

/* Opcode: Concat P1 P2 *
**
** Look at the first P1+2 elements of the stack.  Append them all 
** together with the lowest element first.  The original P1+2 elements







|










|
<
<
<
|
<
|

|
|
<


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


<
<
<





<







869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887



888

889
890
891
892

893
894










895


896





897
898
899
900



901
902
903
904
905

906
907
908
909
910
911
912

/* Opcode: Push P1 * *
**
** Overwrite the value of the P1-th element down on the
** stack (P1==0 is the top of the stack) with the value
** of the top of the stack.  Then pop the top of the stack.
*/
case OP_Push: {
  Mem *pTo = &pTos[-pOp->p1];

  assert( pTo>=p->aStack );
  sqlite3VdbeMemMove(pTo, pTos);
  pTos--;
  break;
}

/* Opcode: Callback P1 * *
**
** Pop P1 values off the stack and form them into an array.  Then



** invoke the callback function using the newly formed array as the

** 3rd parameter.
*/
case OP_Callback: {
  int i;

  assert( p->nResColumn==pOp->p1 );











  for(i=0; i<pOp->p1; i++){


    Mem *pVal = &pTos[0-i];





    sqlite3VdbeMemNulTerminate(pVal);
    storeTypeInfo(pVal, db->enc);
  }




  p->resOnStack = 1;
  p->nCallback++;
  p->popStack = pOp->p1;
  p->pc = pc + 1;
  p->pTos = pTos;

  return SQLITE_ROW;
}

/* Opcode: Concat P1 P2 *
**
** Look at the first P1+2 elements of the stack.  Append them all 
** together with the lowest element first.  The original P1+2 elements
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
  nByte = 0;
  for(i=0; i<nField; i++, pTerm++){
    assert( pOp->p2==0 || (pTerm->flags&MEM_Str) );
    if( pTerm->flags&MEM_Null ){
      nByte = -1;
      break;
    }
    Stringify(pTerm, encoding);
    nByte += pTerm->n;
  }

  if( nByte<0 ){
    /* If nByte is less than zero, then there is a NULL value on the stack.
    ** In this case just pop the values off the stack (if required) and
    ** push on a NULL.







|







929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
  nByte = 0;
  for(i=0; i<nField; i++, pTerm++){
    assert( pOp->p2==0 || (pTerm->flags&MEM_Str) );
    if( pTerm->flags&MEM_Null ){
      nByte = -1;
      break;
    }
    Stringify(pTerm, db->enc);
    nByte += pTerm->n;
  }

  if( nByte<0 ){
    /* If nByte is less than zero, then there is a NULL value on the stack.
    ** In this case just pop the values off the stack (if required) and
    ** push on a NULL.
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
    */
    zNew = sqliteMallocRaw( nByte+2 );
    if( zNew==0 ) goto no_mem;
    j = 0;
    pTerm = &pTos[1-nField];
    for(i=j=0; i<nField; i++, pTerm++){
      int n = pTerm->n;
      assert( pTerm->flags & (MEM_Str|MEM_Blob) );
      memcpy(&zNew[j], pTerm->z, n);
      j += n;
    }
    zNew[j] = 0;
    zNew[j+1] = 0;
    assert( j==nByte );

    if( pOp->p2==0 ){
      popStack(&pTos, nField);
    }
    pTos++;
    pTos->n = j;
    pTos->flags = MEM_Str|MEM_Dyn|MEM_Term;
    pTos->xDel = 0;
    pTos->enc = encoding;
    pTos->z = zNew;
  }
  break;
}

/* Opcode: Add * * *
**







|














|







953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
    */
    zNew = sqliteMallocRaw( nByte+2 );
    if( zNew==0 ) goto no_mem;
    j = 0;
    pTerm = &pTos[1-nField];
    for(i=j=0; i<nField; i++, pTerm++){
      int n = pTerm->n;
      assert( pTerm->flags & MEM_Str );
      memcpy(&zNew[j], pTerm->z, n);
      j += n;
    }
    zNew[j] = 0;
    zNew[j+1] = 0;
    assert( j==nByte );

    if( pOp->p2==0 ){
      popStack(&pTos, nField);
    }
    pTos++;
    pTos->n = j;
    pTos->flags = MEM_Str|MEM_Dyn|MEM_Term;
    pTos->xDel = 0;
    pTos->enc = db->enc;
    pTos->z = zNew;
  }
  break;
}

/* Opcode: Add * * *
**
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
** first (what was on top of the stack) from the second (the
** next on stack)
** and push the remainder after division onto the stack.  If either element
** is a string then it is converted to a double using the atof()
** function before the division.  Division by zero returns NULL.
** If either operand is NULL, the result is NULL.
*/
case OP_Add:                   /* same as TK_PLUS, no-push */
case OP_Subtract:              /* same as TK_MINUS, no-push */
case OP_Multiply:              /* same as TK_STAR, no-push */
case OP_Divide:                /* same as TK_SLASH, no-push */
case OP_Remainder: {           /* same as TK_REM, no-push */
  Mem *pNos = &pTos[-1];
  int flags;
  assert( pNos>=p->aStack );
  flags = pTos->flags | pNos->flags;
  if( (flags & MEM_Null)!=0 ){
    Release(pTos);
    pTos--;
    Release(pTos);
    pTos->flags = MEM_Null;
  }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){
    i64 a, b;
    a = pTos->i;







|
|
|
|
|

<

|
<







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

1033
1034

1035
1036
1037
1038
1039
1040
1041
** first (what was on top of the stack) from the second (the
** next on stack)
** and push the remainder after division onto the stack.  If either element
** is a string then it is converted to a double using the atof()
** function before the division.  Division by zero returns NULL.
** If either operand is NULL, the result is NULL.
*/
case OP_Add:                   /* same as TK_PLUS */
case OP_Subtract:              /* same as TK_MINUS */
case OP_Multiply:              /* same as TK_STAR */
case OP_Divide:                /* same as TK_SLASH */
case OP_Remainder: {           /* same as TK_REM */
  Mem *pNos = &pTos[-1];

  assert( pNos>=p->aStack );
  if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){

    Release(pTos);
    pTos--;
    Release(pTos);
    pTos->flags = MEM_Null;
  }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){
    i64 a, b;
    a = pTos->i;
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
      }
    }
    Release(pTos);
    pTos--;
    Release(pTos);
    pTos->r = b;
    pTos->flags = MEM_Real;
    if( (flags & MEM_Real)==0 ){
      sqlite3VdbeIntegerAffinity(pTos);
    }
  }
  break;

divide_by_zero:
  Release(pTos);
  pTos--;
  Release(pTos);







<
<
<







1082
1083
1084
1085
1086
1087
1088



1089
1090
1091
1092
1093
1094
1095
      }
    }
    Release(pTos);
    pTos--;
    Release(pTos);
    pTos->r = b;
    pTos->flags = MEM_Real;



  }
  break;

divide_by_zero:
  Release(pTos);
  pTos--;
  Release(pTos);
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158

1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
** be returned. This is used by the built-in min(), max() and nullif()
** functions.
**
** The interface used by the implementation of the aforementioned functions
** to retrieve the collation sequence set by this opcode is not available
** publicly, only to user functions defined in func.c.
*/
case OP_CollSeq: {             /* no-push */
  assert( pOp->p3type==P3_COLLSEQ );
  break;
}

/* Opcode: Function P1 P2 P3
**
** Invoke a user function (P3 is a pointer to a Function structure that
** defines the function) with P2 arguments taken from the stack.  Pop all
** arguments from the stack and push back the result.
**
** P1 is a 32-bit bitmask indicating whether or not each argument to the 
** function was determined to be constant at compile time. If the first
** argument was constant then bit 0 of P1 is set. This is used to determine
** whether meta data associated with a user function argument using the
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
** See also: AggStep and AggFinal
*/
case OP_Function: {
  int i;
  Mem *pArg;
  sqlite3_context ctx;
  sqlite3_value **apVal;
  int n = pOp->p2;


  apVal = p->apArg;
  assert( apVal || n==0 );

  pArg = &pTos[1-n];
  for(i=0; i<n; i++, pArg++){
    apVal[i] = pArg;
    storeTypeInfo(pArg, encoding);
  }

  assert( pOp->p3type==P3_FUNCDEF || pOp->p3type==P3_VDBEFUNC );
  if( pOp->p3type==P3_FUNCDEF ){
    ctx.pFunc = (FuncDef*)pOp->p3;
    ctx.pVdbeFunc = 0;
  }else{







|







|


|

|




|






|

>






|







1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
** be returned. This is used by the built-in min(), max() and nullif()
** functions.
**
** The interface used by the implementation of the aforementioned functions
** to retrieve the collation sequence set by this opcode is not available
** publicly, only to user functions defined in func.c.
*/
case OP_CollSeq: {
  assert( pOp->p3type==P3_COLLSEQ );
  break;
}

/* Opcode: Function P1 P2 P3
**
** Invoke a user function (P3 is a pointer to a Function structure that
** defines the function) with P1 arguments taken from the stack.  Pop all
** arguments from the stack and push back the result.
**
** P2 is a 32-bit bitmask indicating whether or not each argument to the 
** function was determined to be constant at compile time. If the first
** argument was constant then bit 0 of P2 is set. This is used to determine
** whether meta data associated with a user function argument using the
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
** See also: AggFunc
*/
case OP_Function: {
  int i;
  Mem *pArg;
  sqlite3_context ctx;
  sqlite3_value **apVal;
  int n = pOp->p1;

  n = pOp->p1;
  apVal = p->apArg;
  assert( apVal || n==0 );

  pArg = &pTos[1-n];
  for(i=0; i<n; i++, pArg++){
    apVal[i] = pArg;
    storeTypeInfo(pArg, db->enc);
  }

  assert( pOp->p3type==P3_FUNCDEF || pOp->p3type==P3_VDBEFUNC );
  if( pOp->p3type==P3_FUNCDEF ){
    ctx.pFunc = (FuncDef*)pOp->p3;
    ctx.pVdbeFunc = 0;
  }else{
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
    assert( pOp[-1].p3type==P3_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = (CollSeq *)pOp[-1].p3;
  }
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  (*ctx.pFunc->xFunc)(&ctx, n, apVal);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  if( pTsd->mallocFailed ) goto no_mem;
  popStack(&pTos, n);

  /* If any auxilary data functions have been called by this user function,
  ** immediately call the destructor for any non-static values.
  */
  if( ctx.pVdbeFunc ){
    sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1);
    pOp->p3 = (char *)ctx.pVdbeFunc;
    pOp->p3type = P3_VDBEFUNC;
  }

  /* Copy the result of the function to the top of the stack */
  sqlite3VdbeChangeEncoding(&ctx.s, encoding);
  pTos++;
  pTos->flags = 0;
  sqlite3VdbeMemMove(pTos, &ctx.s);

  /* If the function returned an error, throw an exception */
  if( ctx.isError ){
    if( !(pTos->flags&MEM_Str) ){
      sqlite3SetString(&p->zErrMsg, "user function error", (char*)0);
    }else{
      sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pTos), (char*)0);
      sqlite3VdbeChangeEncoding(pTos, encoding);
    }
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: BitAnd * * *







|






|





|










|







1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
    assert( pOp[-1].p3type==P3_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = (CollSeq *)pOp[-1].p3;
  }
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  (*ctx.pFunc->xFunc)(&ctx, n, apVal);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  if( sqlite3_malloc_failed ) goto no_mem;
  popStack(&pTos, n);

  /* If any auxilary data functions have been called by this user function,
  ** immediately call the destructor for any non-static values.
  */
  if( ctx.pVdbeFunc ){
    sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p2);
    pOp->p3 = (char *)ctx.pVdbeFunc;
    pOp->p3type = P3_VDBEFUNC;
  }

  /* Copy the result of the function to the top of the stack */
  sqlite3VdbeChangeEncoding(&ctx.s, db->enc);
  pTos++;
  pTos->flags = 0;
  sqlite3VdbeMemMove(pTos, &ctx.s);

  /* If the function returned an error, throw an exception */
  if( ctx.isError ){
    if( !(pTos->flags&MEM_Str) ){
      sqlite3SetString(&p->zErrMsg, "user function error", (char*)0);
    }else{
      sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pTos), (char*)0);
      sqlite3VdbeChangeEncoding(pTos, db->enc);
    }
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: BitAnd * * *
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
/* Opcode: ShiftRight * * *
**
** Pop the top two elements from the stack.  Convert both elements
** to integers.  Push back onto the stack the second element shifted
** right by N bits where N is the top element on the stack.
** If either operand is NULL, the result is NULL.
*/
case OP_BitAnd:                 /* same as TK_BITAND, no-push */
case OP_BitOr:                  /* same as TK_BITOR, no-push */
case OP_ShiftLeft:              /* same as TK_LSHIFT, no-push */
case OP_ShiftRight: {           /* same as TK_RSHIFT, no-push */
  Mem *pNos = &pTos[-1];
  i64 a, b;

  assert( pNos>=p->aStack );
  if( (pTos->flags | pNos->flags) & MEM_Null ){
    popStack(&pTos, 2);
    pTos++;
    pTos->flags = MEM_Null;
    break;







|
|
|
|

|







1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
/* Opcode: ShiftRight * * *
**
** Pop the top two elements from the stack.  Convert both elements
** to integers.  Push back onto the stack the second element shifted
** right by N bits where N is the top element on the stack.
** If either operand is NULL, the result is NULL.
*/
case OP_BitAnd:                 /* same as TK_BITAND */
case OP_BitOr:                  /* same as TK_BITOR */
case OP_ShiftLeft:              /* same as TK_LSHIFT */
case OP_ShiftRight: {           /* same as TK_RSHIFT */
  Mem *pNos = &pTos[-1];
  int a, b;

  assert( pNos>=p->aStack );
  if( (pTos->flags | pNos->flags) & MEM_Null ){
    popStack(&pTos, 2);
    pTos++;
    pTos->flags = MEM_Null;
    break;
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
/* Opcode: AddImm  P1 * *
** 
** Add the value P1 to whatever is on top of the stack.  The result
** is always an integer.
**
** To force the top of the stack to be an integer, just add 0.
*/
case OP_AddImm: {            /* no-push */
  assert( pTos>=p->aStack );
  sqlite3VdbeMemIntegerify(pTos);
  pTos->i += pOp->p1;
  break;
}

/* Opcode: ForceInt P1 P2 *
**
** Convert the top of the stack into an integer.  If the current top of
** the stack is not numeric (meaning that is is a NULL or a string that
** does not look like an integer or floating point number) then pop the
** stack and jump to P2.  If the top of the stack is numeric then
** convert it into the least integer that is greater than or equal to its
** current value if P1==0, or to the least integer that is strictly
** greater than its current value if P1==1.
*/
case OP_ForceInt: {            /* no-push */
  i64 v;
  assert( pTos>=p->aStack );
  applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
  if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
    Release(pTos);
    pTos--;
    pc = pOp->p2 - 1;
    break;
  }
  if( pTos->flags & MEM_Int ){
    v = pTos->i + (pOp->p1!=0);
  }else{
    /* FIX ME:  should this not be assert( pTos->flags & MEM_Real ) ??? */
    sqlite3VdbeMemRealify(pTos);
    v = (int)pTos->r;
    if( pTos->r>(double)v ) v++;
    if( pOp->p1 && pTos->r==(double)v ) v++;
  }
  Release(pTos);
  pTos->i = v;
  pTos->flags = MEM_Int;







|

|














|
|

|









<
|







1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296

1297
1298
1299
1300
1301
1302
1303
1304
/* Opcode: AddImm  P1 * *
** 
** Add the value P1 to whatever is on top of the stack.  The result
** is always an integer.
**
** To force the top of the stack to be an integer, just add 0.
*/
case OP_AddImm: {
  assert( pTos>=p->aStack );
  Integerify(pTos);
  pTos->i += pOp->p1;
  break;
}

/* Opcode: ForceInt P1 P2 *
**
** Convert the top of the stack into an integer.  If the current top of
** the stack is not numeric (meaning that is is a NULL or a string that
** does not look like an integer or floating point number) then pop the
** stack and jump to P2.  If the top of the stack is numeric then
** convert it into the least integer that is greater than or equal to its
** current value if P1==0, or to the least integer that is strictly
** greater than its current value if P1==1.
*/
case OP_ForceInt: {
  int v;
  assert( pTos>=p->aStack );
  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
  if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
    Release(pTos);
    pTos--;
    pc = pOp->p2 - 1;
    break;
  }
  if( pTos->flags & MEM_Int ){
    v = pTos->i + (pOp->p1!=0);
  }else{

    Realify(pTos);
    v = (int)pTos->r;
    if( pTos->r>(double)v ) v++;
    if( pOp->p1 && pTos->r==(double)v ) v++;
  }
  Release(pTos);
  pTos->i = v;
  pTos->flags = MEM_Int;
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
** with out data loss, then jump immediately to P2, or if P2==0
** raise an SQLITE_MISMATCH exception.
**
** If the top of the stack is not an integer and P2 is not zero and
** P1 is 1, then the stack is popped.  In all other cases, the depth
** of the stack is unchanged.
*/
case OP_MustBeInt: {            /* no-push */
  assert( pTos>=p->aStack );
  applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
  if( (pTos->flags & MEM_Int)==0 ){
    if( pOp->p2==0 ){
      rc = SQLITE_MISMATCH;
      goto abort_due_to_error;
    }else{
      if( pOp->p1 ) popStack(&pTos, 1);
      pc = pOp->p2 - 1;
    }
  }else{
    Release(pTos);
    pTos->flags = MEM_Int;
  }
  break;
}

/* Opcode: RealAffinity * * *
**
** If the top of the stack is an integer, convert it to a real value.
**
** This opcode is used when extracting information from a column that
** has REAL affinity.  Such column values may still be stored as
** integers, for space efficiency, but after extraction we want them
** to have only a real value.
*/
case OP_RealAffinity: {                  /* no-push */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Int ){
    sqlite3VdbeMemRealify(pTos);
  }
  break;
}

#ifndef SQLITE_OMIT_CAST
/* Opcode: ToText * * *
**
** Force the value on the top of the stack to be text.
** If the value is numeric, convert it to a string using the
** equivalent of printf().  Blob values are unchanged and
** are afterwards simply interpreted as text.
**
** A NULL value is not changed by this routine.  It remains NULL.
*/
case OP_ToText: {                  /* same as TK_TO_TEXT, no-push */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ) break;
  assert( MEM_Str==(MEM_Blob>>3) );
  pTos->flags |= (pTos->flags&MEM_Blob)>>3;
  applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);
  assert( pTos->flags & MEM_Str );
  pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
  break;
}

/* Opcode: ToBlob * * *
**
** Force the value on the top of the stack to be a BLOB.
** If the value is numeric, convert it to a string first.
** Strings are simply reinterpreted as blobs with no change
** to the underlying data.
**
** A NULL value is not changed by this routine.  It remains NULL.
*/
case OP_ToBlob: {                  /* same as TK_TO_BLOB, no-push */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ) break;
  if( (pTos->flags & MEM_Blob)==0 ){
    applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);
    assert( pTos->flags & MEM_Str );
    pTos->flags |= MEM_Blob;
  }
  pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Str);
  break;
}

/* Opcode: ToNumeric * * *
**
** Force the value on the top of the stack to be numeric (either an
** integer or a floating-point number.)
** If the value is text or blob, try to convert it to an using the
** equivalent of atoi() or atof() and store 0 if no such conversion 
** is possible.
**
** A NULL value is not changed by this routine.  It remains NULL.
*/
case OP_ToNumeric: {                  /* same as TK_TO_NUMERIC, no-push */
  assert( pTos>=p->aStack );
  if( (pTos->flags & MEM_Null)==0 ){
    sqlite3VdbeMemNumerify(pTos);
  }
  break;
}
#endif /* SQLITE_OMIT_CAST */

/* Opcode: ToInt * * *
**
** Force the value on the top of the stack to be an integer.  If
** The value is currently a real number, drop its fractional part.
** If the value is text or blob, try to convert it to an integer using the
** equivalent of atoi() and store 0 if no such conversion is possible.
**
** A NULL value is not changed by this routine.  It remains NULL.
*/
case OP_ToInt: {                  /* same as TK_TO_INT, no-push */
  assert( pTos>=p->aStack );
  if( (pTos->flags & MEM_Null)==0 ){
    sqlite3VdbeMemIntegerify(pTos);
  }
  break;
}

#ifndef SQLITE_OMIT_CAST
/* Opcode: ToReal * * *
**
** Force the value on the top of the stack to be a floating point number.
** If The value is currently an integer, convert it.
** If the value is text or blob, try to convert it to an integer using the
** equivalent of atoi() and store 0 if no such conversion is possible.
**
** A NULL value is not changed by this routine.  It remains NULL.
*/
case OP_ToReal: {                  /* same as TK_TO_REAL, no-push */
  assert( pTos>=p->aStack );
  if( (pTos->flags & MEM_Null)==0 ){
    sqlite3VdbeMemRealify(pTos);
  }
  break;
}
#endif /* SQLITE_OMIT_CAST */

/* Opcode: Eq P1 P2 P3
**
** Pop the top two elements from the stack.  If they are equal, then
** jump to instruction P2.  Otherwise, continue to the next instruction.
**
** If the 0x100 bit of P1 is true and either operand is NULL then take the
** jump.  If the 0x100 bit of P1 is clear then fall thru if either operand
** is NULL.
**
** If the 0x200 bit of P1 is set and either operand is NULL then
** both operands are converted to integers prior to comparison.
** NULL operands are converted to zero and non-NULL operands are
** converted to 1.  Thus, for example, with 0x200 set,  NULL==NULL is true
** whereas it would normally be NULL.  Similarly,  NULL==123 is false when
** 0x200 is set but is NULL when the 0x200 bit of P1 is clear.
**
** The least significant byte of P1 (mask 0xff) must be an affinity character -
** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made 
** to coerce both values
** according to the affinity before the comparison is made. If the byte is
** 0x00, then numeric affinity is used.
**
** Once any conversions have taken place, and neither value is NULL, 
** the values are compared. If both values are blobs, or both are text,
** then memcmp() is used to determine the results of the comparison. If
** both values are numeric, then a numeric comparison is used. If the







|

|















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





|
<
<
<
|
<
<
<
<
|

|
<
|







1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336


















































































































1337
1338
1339
1340
1341
1342



1343




1344
1345
1346

1347
1348
1349
1350
1351
1352
1353
1354
** with out data loss, then jump immediately to P2, or if P2==0
** raise an SQLITE_MISMATCH exception.
**
** If the top of the stack is not an integer and P2 is not zero and
** P1 is 1, then the stack is popped.  In all other cases, the depth
** of the stack is unchanged.
*/
case OP_MustBeInt: {
  assert( pTos>=p->aStack );
  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
  if( (pTos->flags & MEM_Int)==0 ){
    if( pOp->p2==0 ){
      rc = SQLITE_MISMATCH;
      goto abort_due_to_error;
    }else{
      if( pOp->p1 ) popStack(&pTos, 1);
      pc = pOp->p2 - 1;
    }
  }else{
    Release(pTos);
    pTos->flags = MEM_Int;
  }
  break;
}



















































































































/* Opcode: Eq P1 P2 P3
**
** Pop the top two elements from the stack.  If they are equal, then
** jump to instruction P2.  Otherwise, continue to the next instruction.
**
** The least significant byte of P1 may be either 0x00 or 0x01. If either



** operand is NULL (and thus if the result is unknown) then take the jump




** only if the least significant byte of P1 is 0x01.
**
** The second least significant byte of P1 must be an affinity character -

** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values
** according to the affinity before the comparison is made. If the byte is
** 0x00, then numeric affinity is used.
**
** Once any conversions have taken place, and neither value is NULL, 
** the values are compared. If both values are blobs, or both are text,
** then memcmp() is used to determine the results of the comparison. If
** both values are numeric, then a numeric comparison is used. If the
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
*/
/* Opcode: Ge P1 P2 P3
**
** This works just like the Eq opcode except that the jump is taken if
** the 2nd element down on the stack is greater than or equal to the
** top of the stack.  See the Eq opcode for additional information.
*/
case OP_Eq:               /* same as TK_EQ, no-push */
case OP_Ne:               /* same as TK_NE, no-push */
case OP_Lt:               /* same as TK_LT, no-push */
case OP_Le:               /* same as TK_LE, no-push */
case OP_Gt:               /* same as TK_GT, no-push */
case OP_Ge: {             /* same as TK_GE, no-push */
  Mem *pNos;
  int flags;
  int res;
  char affinity;

  pNos = &pTos[-1];
  flags = pTos->flags|pNos->flags;

  /* If either value is a NULL P2 is not zero, take the jump if the least
  ** significant byte of P1 is true. If P2 is zero, then push a NULL onto
  ** the stack.
  */
  if( flags&MEM_Null ){
    if( (pOp->p1 & 0x200)!=0 ){
      /* The 0x200 bit of P1 means, roughly "do not treat NULL as the
      ** magic SQL value it normally is - treat it as if it were another
      ** integer".
      **
      ** With 0x200 set, if either operand is NULL then both operands
      ** are converted to integers prior to being passed down into the
      ** normal comparison logic below.  NULL operands are converted to
      ** zero and non-NULL operands are converted to 1.  Thus, for example,
      ** with 0x200 set,  NULL==NULL is true whereas it would normally
      ** be NULL.  Similarly,  NULL!=123 is true.
      */
      sqlite3VdbeMemSetInt64(pTos, (pTos->flags & MEM_Null)==0);
      sqlite3VdbeMemSetInt64(pNos, (pNos->flags & MEM_Null)==0);
    }else{
      /* If the 0x200 bit of P1 is clear and either operand is NULL then
      ** the result is always NULL.  The jump is taken if the 0x100 bit
      ** of P1 is set.
      */
      popStack(&pTos, 2);
      if( pOp->p2 ){
        if( pOp->p1 & 0x100 ){
          pc = pOp->p2-1;
        }
      }else{
        pTos++;
        pTos->flags = MEM_Null;
      }
      break;
    }
  }

  affinity = pOp->p1 & 0xFF;
  if( affinity ){
    applyAffinity(pNos, affinity, encoding);
    applyAffinity(pTos, affinity, encoding);
  }

  assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 );
  res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3);
  switch( pOp->opcode ){
    case OP_Eq:    res = res==0;     break;
    case OP_Ne:    res = res!=0;     break;







|
|
|
|
|
|













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

|
|







1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412



















1413
1414

1415

1416
1417
1418
1419
1420
1421
1422

1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
*/
/* Opcode: Ge P1 P2 P3
**
** This works just like the Eq opcode except that the jump is taken if
** the 2nd element down on the stack is greater than or equal to the
** top of the stack.  See the Eq opcode for additional information.
*/
case OP_Eq:               /* same as TK_EQ */
case OP_Ne:               /* same as TK_NE */
case OP_Lt:               /* same as TK_LT */
case OP_Le:               /* same as TK_LE */
case OP_Gt:               /* same as TK_GT */
case OP_Ge: {             /* same as TK_GE */
  Mem *pNos;
  int flags;
  int res;
  char affinity;

  pNos = &pTos[-1];
  flags = pTos->flags|pNos->flags;

  /* If either value is a NULL P2 is not zero, take the jump if the least
  ** significant byte of P1 is true. If P2 is zero, then push a NULL onto
  ** the stack.
  */
  if( flags&MEM_Null ){



















    popStack(&pTos, 2);
    if( pOp->p2 ){

      if( (pOp->p1&0xFF) ) pc = pOp->p2-1;

    }else{
      pTos++;
      pTos->flags = MEM_Null;
    }
    break;
  }


  affinity = (pOp->p1>>8)&0xFF;
  if( affinity ){
    applyAffinity(pNos, affinity, db->enc);
    applyAffinity(pTos, affinity, db->enc);
  }

  assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 );
  res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3);
  switch( pOp->opcode ){
    case OP_Eq:    res = res==0;     break;
    case OP_Ne:    res = res!=0;     break;
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
*/
/* Opcode: Or * * *
**
** Pop two values off the stack.  Take the logical OR of the
** two values and push the resulting boolean value back onto the
** stack. 
*/
case OP_And:              /* same as TK_AND, no-push */
case OP_Or: {             /* same as TK_OR, no-push */
  Mem *pNos = &pTos[-1];
  int v1, v2;    /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */

  assert( pNos>=p->aStack );
  if( pTos->flags & MEM_Null ){
    v1 = 2;
  }else{
    sqlite3VdbeMemIntegerify(pTos);
    v1 = pTos->i==0;
  }
  if( pNos->flags & MEM_Null ){
    v2 = 2;
  }else{
    sqlite3VdbeMemIntegerify(pNos);
    v2 = pNos->i==0;
  }
  if( pOp->opcode==OP_And ){
    static const unsigned char and_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
    v1 = and_logic[v1*3+v2];
  }else{
    static const unsigned char or_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };







|
|







|





|







1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
*/
/* Opcode: Or * * *
**
** Pop two values off the stack.  Take the logical OR of the
** two values and push the resulting boolean value back onto the
** stack. 
*/
case OP_And:              /* same as TK_AND */
case OP_Or: {             /* same as TK_OR */
  Mem *pNos = &pTos[-1];
  int v1, v2;    /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */

  assert( pNos>=p->aStack );
  if( pTos->flags & MEM_Null ){
    v1 = 2;
  }else{
    Integerify(pTos);
    v1 = pTos->i==0;
  }
  if( pNos->flags & MEM_Null ){
    v2 = 2;
  }else{
    Integerify(pNos);
    v2 = pNos->i==0;
  }
  if( pOp->opcode==OP_And ){
    static const unsigned char and_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
    v1 = and_logic[v1*3+v2];
  }else{
    static const unsigned char or_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697



1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
*/
/* Opcode: AbsValue * * *
**
** Treat the top of the stack as a numeric quantity.  Replace it
** with its absolute value. If the top of the stack is NULL
** its value is unchanged.
*/
case OP_Negative:              /* same as TK_UMINUS, no-push */
case OP_AbsValue: {
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Real ){
    neg_abs_real_case:
    Release(pTos);
    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
      pTos->r = -pTos->r;
    }
    pTos->flags = MEM_Real;
  }else if( pTos->flags & MEM_Int ){
    Release(pTos);
    if( pOp->opcode==OP_Negative || pTos->i<0 ){
      pTos->i = -pTos->i;
    }
    pTos->flags = MEM_Int;
  }else if( pTos->flags & MEM_Null ){
    /* Do nothing */
  }else{
    sqlite3VdbeMemNumerify(pTos);



    goto neg_abs_real_case;
  }
  break;
}

/* Opcode: Not * * *
**
** Interpret the top of the stack as a boolean value.  Replace it
** with its complement.  If the top of the stack is NULL its value
** is unchanged.
*/
case OP_Not: {                /* same as TK_NOT, no-push */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
  sqlite3VdbeMemIntegerify(pTos);
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos->i = !pTos->i;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: BitNot * * *
**
** Interpret the top of the stack as an value.  Replace it
** with its ones-complement.  If the top of the stack is NULL its
** value is unchanged.
*/
case OP_BitNot: {             /* same as TK_BITNOT, no-push */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
  sqlite3VdbeMemIntegerify(pTos);
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos->i = ~pTos->i;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: Noop * * *
**
** Do nothing.  This instruction is often useful as a jump
** destination.
*/
/*
** The magic Explain opcode are only inserted when explain==2 (which
** is to say when the EXPLAIN QUERY PLAN syntax is used.)
** This opcode records information from the optimizer.  It is the
** the same as a no-op.  This opcodesnever appears in a real VM program.
*/
case OP_Explain:
case OP_Noop: {            /* no-push */
  break;
}

/* Opcode: If P1 P2 *
**
** Pop a single boolean from the stack.  If the boolean popped is
** true, then jump to p2.  Otherwise continue to the next instruction.







|



<














|
>
>
>
|










|


|












|


|











<
<
<
<
<
<
<
|







1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516

1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576







1577
1578
1579
1580
1581
1582
1583
1584
*/
/* Opcode: AbsValue * * *
**
** Treat the top of the stack as a numeric quantity.  Replace it
** with its absolute value. If the top of the stack is NULL
** its value is unchanged.
*/
case OP_Negative:              /* same as TK_UMINUS */
case OP_AbsValue: {
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Real ){

    Release(pTos);
    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
      pTos->r = -pTos->r;
    }
    pTos->flags = MEM_Real;
  }else if( pTos->flags & MEM_Int ){
    Release(pTos);
    if( pOp->opcode==OP_Negative || pTos->i<0 ){
      pTos->i = -pTos->i;
    }
    pTos->flags = MEM_Int;
  }else if( pTos->flags & MEM_Null ){
    /* Do nothing */
  }else{
    Realify(pTos);
    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
      pTos->r = -pTos->r;
    }
    pTos->flags = MEM_Real;
  }
  break;
}

/* Opcode: Not * * *
**
** Interpret the top of the stack as a boolean value.  Replace it
** with its complement.  If the top of the stack is NULL its value
** is unchanged.
*/
case OP_Not: {                /* same as TK_NOT */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
  Integerify(pTos);
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos->i = !pTos->i;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: BitNot * * *
**
** Interpret the top of the stack as an value.  Replace it
** with its ones-complement.  If the top of the stack is NULL its
** value is unchanged.
*/
case OP_BitNot: {             /* same as TK_BITNOT */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
  Integerify(pTos);
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos->i = ~pTos->i;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: Noop * * *
**
** Do nothing.  This instruction is often useful as a jump
** destination.
*/







case OP_Noop: {
  break;
}

/* Opcode: If P1 P2 *
**
** Pop a single boolean from the stack.  If the boolean popped is
** true, then jump to p2.  Otherwise continue to the next instruction.
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
** false, then jump to p2.  Otherwise continue to the next instruction.
** An integer is false if zero and true otherwise.  A string is
** false if it has zero length and true otherwise.
**
** If the value popped of the stack is NULL, then take the jump if P1
** is true and fall through if P1 is false.
*/
case OP_If:                 /* no-push */
case OP_IfNot: {            /* no-push */
  int c;
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ){
    c = pOp->p1;
  }else{
#ifdef SQLITE_OMIT_FLOATING_POINT
    c = sqlite3VdbeIntValue(pTos);
#else
    c = sqlite3VdbeRealValue(pTos)!=0.0;
#endif
    if( pOp->opcode==OP_IfNot ) c = !c;
  }
  Release(pTos);
  pTos--;
  if( c ) pc = pOp->p2-1;
  break;
}

/* Opcode: IsNull P1 P2 *
**
** If any of the top abs(P1) values on the stack are NULL, then jump
** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack
** unchanged.
*/
case OP_IsNull: {            /* same as TK_ISNULL, no-push */
  int i, cnt;
  Mem *pTerm;
  cnt = pOp->p1;
  if( cnt<0 ) cnt = -cnt;
  pTerm = &pTos[1-cnt];
  assert( pTerm>=p->aStack );
  for(i=0; i<cnt; i++, pTerm++){







|
|





<

<
<
<














|







1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607

1608



1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
** false, then jump to p2.  Otherwise continue to the next instruction.
** An integer is false if zero and true otherwise.  A string is
** false if it has zero length and true otherwise.
**
** If the value popped of the stack is NULL, then take the jump if P1
** is true and fall through if P1 is false.
*/
case OP_If:
case OP_IfNot: {
  int c;
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ){
    c = pOp->p1;
  }else{

    c = sqlite3VdbeIntValue(pTos);



    if( pOp->opcode==OP_IfNot ) c = !c;
  }
  Release(pTos);
  pTos--;
  if( c ) pc = pOp->p2-1;
  break;
}

/* Opcode: IsNull P1 P2 *
**
** If any of the top abs(P1) values on the stack are NULL, then jump
** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack
** unchanged.
*/
case OP_IsNull: {            /* same as TK_ISNULL */
  int i, cnt;
  Mem *pTerm;
  cnt = pOp->p1;
  if( cnt<0 ) cnt = -cnt;
  pTerm = &pTos[1-cnt];
  assert( pTerm>=p->aStack );
  for(i=0; i<cnt; i++, pTerm++){
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846




1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884

1885


1886
1887
1888
1889
1890
1891
1892

/* Opcode: NotNull P1 P2 *
**
** Jump to P2 if the top P1 values on the stack are all not NULL.  Pop the
** stack if P1 times if P1 is greater than zero.  If P1 is less than
** zero then leave the stack unchanged.
*/
case OP_NotNull: {            /* same as TK_NOTNULL, no-push */
  int i, cnt;
  cnt = pOp->p1;
  if( cnt<0 ) cnt = -cnt;
  assert( &pTos[1-cnt] >= p->aStack );
  for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}
  if( i>=cnt ) pc = pOp->p2-1;
  if( pOp->p1>0 ) popStack(&pTos, cnt);
  break;
}

/* Opcode: SetNumColumns P1 P2 *
**
** Before the OP_Column opcode can be executed on a cursor, this
** opcode must be called to set the number of fields in the table.
**
** This opcode sets the number of columns for cursor P1 to P2.
**
** If OP_KeyAsData is to be applied to cursor P1, it must be executed
** before this op-code.
*/
case OP_SetNumColumns: {       /* no-push */
  Cursor *pC;
  assert( (pOp->p1)<p->nCursor );
  assert( p->apCsr[pOp->p1]!=0 );
  pC = p->apCsr[pOp->p1];
  pC->nField = pOp->p2;




  break;
}

/* Opcode: Column P1 P2 P3
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction.  (See the MakeRecord opcode for additional
** information about the format of the data.) Push onto the stack the value
** of the P2-th column contained in the data. If there are less that (P2+1) 
** values in the record, push a NULL onto the stack.
**
** If the KeyAsData opcode has previously executed on this cursor, then the
** field might be extracted from the key rather than the data.
**
** If P1 is negative, then the record is stored on the stack rather than in
** a table.  For P1==-1, the top of the stack is used.  For P1==-2, the
** next on the stack is used.  And so forth.  The value pushed is always
** just a pointer into the record which is stored further down on the
** stack.  The column value is not copied. The number of columns in the
** record is stored on the stack just above the record itself.
**
** If the column contains fewer than P2 fields, then push a NULL.  Or
** if P3 is of type P3_MEM, then push the P3 value.  The P3 value will
** be default value for a column that has been added using the ALTER TABLE
** ADD COLUMN command.  If P3 is an ordinary string, just push a NULL.
** When P3 is a string it is really just a comment describing the value
** to be pushed, not a default value.
*/
case OP_Column: {
  u32 payloadSize;   /* Number of bytes in the record */
  int p1 = pOp->p1;  /* P1 value of the opcode */
  int p2 = pOp->p2;  /* column number to retrieve */
  Cursor *pC = 0;    /* The VDBE cursor */
  char *zRec;        /* Pointer to complete record-data */
  BtCursor *pCrsr;   /* The BTree cursor */
  u32 *aType;        /* aType[i] holds the numeric type of the i-th column */
  u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
  u32 nField;        /* number of fields in the record */

  int len;           /* The length of the serialized data for the column */


  int i;             /* Loop counter */
  char *zData;       /* Part of the record being decoded */
  Mem sMem;          /* For storing the record being decoded */

  sMem.flags = 0;
  assert( p1<p->nCursor );
  pTos++;







|




















|





>
>
>
>



|
















<
<
<
<
<
<
<











>

>
>







1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696







1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718

/* Opcode: NotNull P1 P2 *
**
** Jump to P2 if the top P1 values on the stack are all not NULL.  Pop the
** stack if P1 times if P1 is greater than zero.  If P1 is less than
** zero then leave the stack unchanged.
*/
case OP_NotNull: {            /* same as TK_NOTNULL */
  int i, cnt;
  cnt = pOp->p1;
  if( cnt<0 ) cnt = -cnt;
  assert( &pTos[1-cnt] >= p->aStack );
  for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}
  if( i>=cnt ) pc = pOp->p2-1;
  if( pOp->p1>0 ) popStack(&pTos, cnt);
  break;
}

/* Opcode: SetNumColumns P1 P2 *
**
** Before the OP_Column opcode can be executed on a cursor, this
** opcode must be called to set the number of fields in the table.
**
** This opcode sets the number of columns for cursor P1 to P2.
**
** If OP_KeyAsData is to be applied to cursor P1, it must be executed
** before this op-code.
*/
case OP_SetNumColumns: {
  Cursor *pC;
  assert( (pOp->p1)<p->nCursor );
  assert( p->apCsr[pOp->p1]!=0 );
  pC = p->apCsr[pOp->p1];
  pC->nField = pOp->p2;
  if( (!pC->keyAsData && pC->zeroData) || (pC->keyAsData && pC->intKey) ){
    rc = SQLITE_CORRUPT;
    goto abort_due_to_error;
  }
  break;
}

/* Opcode: Column P1 P2 *
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction.  (See the MakeRecord opcode for additional
** information about the format of the data.) Push onto the stack the value
** of the P2-th column contained in the data. If there are less that (P2+1) 
** values in the record, push a NULL onto the stack.
**
** If the KeyAsData opcode has previously executed on this cursor, then the
** field might be extracted from the key rather than the data.
**
** If P1 is negative, then the record is stored on the stack rather than in
** a table.  For P1==-1, the top of the stack is used.  For P1==-2, the
** next on the stack is used.  And so forth.  The value pushed is always
** just a pointer into the record which is stored further down on the
** stack.  The column value is not copied. The number of columns in the
** record is stored on the stack just above the record itself.







*/
case OP_Column: {
  u32 payloadSize;   /* Number of bytes in the record */
  int p1 = pOp->p1;  /* P1 value of the opcode */
  int p2 = pOp->p2;  /* column number to retrieve */
  Cursor *pC = 0;    /* The VDBE cursor */
  char *zRec;        /* Pointer to complete record-data */
  BtCursor *pCrsr;   /* The BTree cursor */
  u32 *aType;        /* aType[i] holds the numeric type of the i-th column */
  u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
  u32 nField;        /* number of fields in the record */
  u32 szHdr;         /* Number of bytes in the record header */
  int len;           /* The length of the serialized data for the column */
  int offset = 0;    /* Offset into the data */
  int idx;           /* Index into the header */
  int i;             /* Loop counter */
  char *zData;       /* Part of the record being decoded */
  Mem sMem;          /* For storing the record being decoded */

  sMem.flags = 0;
  assert( p1<p->nCursor );
  pTos++;
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008

2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033



2034
2035
2036




2037
2038
2039
2040
2041
2042
2043

2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
    /* The record is stored in a B-Tree */
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    zRec = 0;
    pCrsr = pC->pCursor;
    if( pC->nullRow ){
      payloadSize = 0;
    }else if( pC->cacheStatus==p->cacheCtr ){
      payloadSize = pC->payloadSize;
      zRec = (char*)pC->aRow;
    }else if( pC->isIndex ){
      i64 payloadSize64;
      sqlite3BtreeKeySize(pCrsr, &payloadSize64);
      payloadSize = payloadSize64;
    }else{
      sqlite3BtreeDataSize(pCrsr, &payloadSize);
    }
    nField = pC->nField;
#ifndef SQLITE_OMIT_TRIGGER
  }else if( pC->pseudoTable ){
    /* The record is the sole entry of a pseudo-table */
    payloadSize = pC->nData;
    zRec = pC->pData;
    pC->cacheStatus = CACHE_STALE;
    assert( payloadSize==0 || zRec!=0 );
    nField = pC->nField;
    pCrsr = 0;
#endif
  }else{
    zRec = 0;
    payloadSize = 0;
    pCrsr = 0;
    nField = 0;
  }

  /* If payloadSize is 0, then just push a NULL onto the stack. */
  if( payloadSize==0 ){
    assert( pTos->flags==MEM_Null );
    break;
  }

  assert( p2<nField );

  /* Read and parse the table header.  Store the results of the parse
  ** into the record header cache fields of the cursor.
  */
  if( pC && pC->cacheStatus==p->cacheCtr ){
    aType = pC->aType;
    aOffset = pC->aOffset;
  }else{
    u8 *zIdx;        /* Index into header */
    u8 *zEndHdr;     /* Pointer to first byte after the header */
    u32 offset;      /* Offset into the data */
    int avail;       /* Number of bytes of available data */
    if( pC && pC->aType ){
      aType = pC->aType;
    }else{
      aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
    }
    aOffset = &aType[nField];
    if( aType==0 ){
      goto no_mem;
    }

    /* Figure out how many bytes are in the header */
    if( zRec ){
      zData = zRec;
    }else{
      if( pC->isIndex ){
        zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);
      }else{
        zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
      }
      /* If KeyFetch()/DataFetch() managed to get the entire payload,
      ** save the payload in the pC->aRow cache.  That will save us from
      ** having to make additional calls to fetch the content portion of
      ** the record.
      */
      if( avail>=payloadSize ){
        zRec = zData;
        pC->aRow = (u8*)zData;
      }else{
        pC->aRow = 0;
      }
    }

    zIdx = (u8 *)GetVarint((u8*)zData, offset);

    /* The KeyFetch() or DataFetch() above are fast and will get the entire
    ** record header in most cases.  But they will fail to get the complete
    ** record header if the record header does not fit on a single page
    ** in the B-Tree.  When that happens, use sqlite3VdbeMemFromBtree() to
    ** acquire the complete header text.
    */
    if( !zRec && avail<offset ){
      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem);
      if( rc!=SQLITE_OK ){
        goto op_column_out;
      }
      zData = sMem.z;
    }
    zEndHdr = (u8 *)zData + offset;
    zIdx = zData + (int)zIdx;

    /* Scan the header and use it to fill in the aType[] and aOffset[]
    ** arrays.  aType[i] will contain the type integer for the i-th
    ** column and aOffset[i] will contain the offset from the beginning
    ** of the record to the start of the data for the i-th column
    */
    for(i=0; i<nField; i++){
      if( zIdx<zEndHdr ){



        aOffset[i] = offset;
        zIdx += GetVarint(zIdx, aType[i]);
        offset += sqlite3VdbeSerialTypeLen(aType[i]);




      }else{
        /* If i is less that nField, then there are less fields in this
        ** record than SetNumColumns indicated there are columns in the
        ** table. Set the offset for any extra columns not present in
        ** the record to 0. This tells code below to push a NULL onto the
        ** stack instead of deserializing a value from the record.
        */

        aOffset[i] = 0;
      }
    }
    Release(&sMem);
    sMem.flags = MEM_Null;

    /* If we have read more header data than was contained in the header,
    ** or if the end of the last field appears to be past the end of the
    ** record, then we must be dealing with a corrupt database.
    */
    if( zIdx>zEndHdr || offset>payloadSize ){
      rc = SQLITE_CORRUPT_BKPT;
      goto op_column_out;
    }

    /* Remember all aType and aColumn information if we have a cursor
    ** to remember it in. */
    if( pC ){
      pC->payloadSize = payloadSize;
      pC->aType = aType;
      pC->aOffset = aOffset;
      pC->cacheStatus = p->cacheCtr;
    }
  }

  /* Get the column information. If aOffset[p2] is non-zero, then 
  ** deserialize the value from the record. If aOffset[p2] is zero,
  ** then there are not enough fields in the record to satisfy the
  ** request.  In this case, set the value NULL or to P3 if P3 is
  ** a pointer to a Mem object.
  */
  if( aOffset[p2] ){
    assert( rc==SQLITE_OK );
    if( zRec ){
      zData = &zRec[aOffset[p2]];
    }else{
      len = sqlite3VdbeSerialTypeLen(aType[p2]);
      rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex,&sMem);
      if( rc!=SQLITE_OK ){
        goto op_column_out;
      }
      zData = sMem.z;
    }
    sqlite3VdbeSerialGet((u8*)zData, aType[p2], pTos);
    pTos->enc = encoding;
  }else{
    if( pOp->p3type==P3_MEM ){
      sqlite3VdbeMemShallowCopy(pTos, (Mem *)(pOp->p3), MEM_Static);
    }else{
      pTos->flags = MEM_Null;
    }
  }

  /* If we dynamically allocated space to hold the data (in the
  ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
  ** dynamically allocated space over to the pTos structure rather.
  ** This prevents a memory copy.
  */







|

|
|












|













|








|



<
<
<
|














|










|
<




>
|







|
|





<
<






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

|
|









|






|
<







|





|
|

<
<
<
|
<







1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799



1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826

1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846


1847
1848
1849
1850
1851
1852

1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874


1875

1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897

1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913



1914

1915
1916
1917
1918
1919
1920
1921
    /* The record is stored in a B-Tree */
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    zRec = 0;
    pCrsr = pC->pCursor;
    if( pC->nullRow ){
      payloadSize = 0;
    }else if( pC->cacheValid ){
      payloadSize = pC->payloadSize;
      zRec = pC->aRow;
    }else if( pC->keyAsData ){
      i64 payloadSize64;
      sqlite3BtreeKeySize(pCrsr, &payloadSize64);
      payloadSize = payloadSize64;
    }else{
      sqlite3BtreeDataSize(pCrsr, &payloadSize);
    }
    nField = pC->nField;
#ifndef SQLITE_OMIT_TRIGGER
  }else if( pC->pseudoTable ){
    /* The record is the sole entry of a pseudo-table */
    payloadSize = pC->nData;
    zRec = pC->pData;
    pC->cacheValid = 0;
    assert( payloadSize==0 || zRec!=0 );
    nField = pC->nField;
    pCrsr = 0;
#endif
  }else{
    zRec = 0;
    payloadSize = 0;
    pCrsr = 0;
    nField = 0;
  }

  /* If payloadSize is 0, then just push a NULL onto the stack. */
  if( payloadSize==0 ){
    pTos->flags = MEM_Null;
    break;
  }

  assert( p2<nField );

  /* Read and parse the table header.  Store the results of the parse
  ** into the record header cache fields of the cursor.
  */
  if( pC && pC->cacheValid ){
    aType = pC->aType;
    aOffset = pC->aOffset;
  }else{



    int avail;    /* Number of bytes of available data */
    if( pC && pC->aType ){
      aType = pC->aType;
    }else{
      aType = sqliteMallocRaw( 2*nField*sizeof(aType) );
    }
    aOffset = &aType[nField];
    if( aType==0 ){
      goto no_mem;
    }

    /* Figure out how many bytes are in the header */
    if( zRec ){
      zData = zRec;
    }else{
      if( pC->keyAsData ){
        zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);
      }else{
        zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
      }
      /* If KeyFetch()/DataFetch() managed to get the entire payload,
      ** save the payload in the pC->aRow cache.  That will save us from
      ** having to make additional calls to fetch the content portion of
      ** the record.
      */
      if( avail>=payloadSize ){
        zRec = pC->aRow = zData;

      }else{
        pC->aRow = 0;
      }
    }
    idx = sqlite3GetVarint32(zData, &szHdr);


    /* The KeyFetch() or DataFetch() above are fast and will get the entire
    ** record header in most cases.  But they will fail to get the complete
    ** record header if the record header does not fit on a single page
    ** in the B-Tree.  When that happens, use sqlite3VdbeMemFromBtree() to
    ** acquire the complete header text.
    */
    if( !zRec && avail<szHdr ){
      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->keyAsData, &sMem);
      if( rc!=SQLITE_OK ){
        goto op_column_out;
      }
      zData = sMem.z;
    }



    /* Scan the header and use it to fill in the aType[] and aOffset[]
    ** arrays.  aType[i] will contain the type integer for the i-th
    ** column and aOffset[i] will contain the offset from the beginning
    ** of the record to the start of the data for the i-th column
    */

    offset = szHdr;
    assert( offset>0 );
    i = 0;
    while( idx<szHdr && i<nField && offset<=payloadSize ){
      aOffset[i] = offset;
      idx += sqlite3GetVarint32(&zData[idx], &aType[i]);
      offset += sqlite3VdbeSerialTypeLen(aType[i]);
      i++;
    }
    Release(&sMem);
    sMem.flags = MEM_Null;

    /* If i is less that nField, then there are less fields in this
    ** record than SetNumColumns indicated there are columns in the
    ** table. Set the offset for any extra columns not present in
    ** the record to 0. This tells code below to push a NULL onto the
    ** stack instead of deserializing a value from the record.
    */
    while( i<nField ){
      aOffset[i++] = 0;
    }



    /* The header should end at the start of data and the data should

    ** end at last byte of the record. If this is not the case then
    ** we are dealing with a malformed record.
    */
    if( idx!=szHdr || offset!=payloadSize ){
      rc = SQLITE_CORRUPT;
      goto op_column_out;
    }

    /* Remember all aType and aColumn information if we have a cursor
    ** to remember it in. */
    if( pC ){
      pC->payloadSize = payloadSize;
      pC->aType = aType;
      pC->aOffset = aOffset;
      pC->cacheValid = 1;
    }
  }

  /* Get the column information. If aOffset[p2] is non-zero, then 
  ** deserialize the value from the record. If aOffset[p2] is zero,
  ** then there are not enough fields in the record to satisfy the
  ** request. The value is NULL in this case.

  */
  if( aOffset[p2] ){
    assert( rc==SQLITE_OK );
    if( zRec ){
      zData = &zRec[aOffset[p2]];
    }else{
      len = sqlite3VdbeSerialTypeLen(aType[p2]);
      rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len,pC->keyAsData,&sMem);
      if( rc!=SQLITE_OK ){
        goto op_column_out;
      }
      zData = sMem.z;
    }
    sqlite3VdbeSerialGet(zData, aType[p2], pTos);
    pTos->enc = db->enc;
  }else{



    pTos->flags = MEM_Null;

  }

  /* If we dynamically allocated space to hold the data (in the
  ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
  ** dynamically allocated space over to the pTos structure rather.
  ** This prevents a memory copy.
  */
2129
2130
2131
2132
2133
2134
2135



2136
2137
2138
2139
2140
2141
2142
2143
2144
2145


2146

2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
** sqlite3VdbeRecordCompare function will correctly compare two encoded
** records.  Refer to source code comments for the details of the record
** format.
**
** The original stack entries are popped from the stack if P1>0 but
** remain on the stack if P1<0.
**



** If P2 is not zero and one or more of the entries are NULL, then jump
** to the address given by P2.  This feature can be used to skip a
** uniqueness test on indices.
**
** P3 may be a string that is P1 characters long.  The nth character of the
** string indicates the column affinity that should be used for the nth
** field of the index key (i.e. the first character of P3 corresponds to the
** lowest element on the stack).
**
** The mapping from character to affinity is given by the SQLITE_AFF_


** macros defined in sqliteInt.h.

**
** If P3 is NULL then all index fields have the affinity NONE.
**
** See also OP_MakeIdxRec
*/
/* Opcode: MakeIdxRec P1 P2 P3
**
** This opcode works just OP_MakeRecord except that it reads an extra
** integer from the stack (thus reading a total of abs(P1+1) entries)
** and appends that extra integer to the end of the record as a varint.
** This results in an index key.
*/
case OP_MakeIdxRec:
case OP_MakeRecord: {
  /* Assuming the record contains N fields, the record format looks
  ** like this:
  **
  ** ------------------------------------------------------------------------
  ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | 
  ** ------------------------------------------------------------------------







>
>
>
|
|
|






|
>
>
|
>


<
<

<
<
<
<
<
<
<
<







1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974


1975








1976
1977
1978
1979
1980
1981
1982
** sqlite3VdbeRecordCompare function will correctly compare two encoded
** records.  Refer to source code comments for the details of the record
** format.
**
** The original stack entries are popped from the stack if P1>0 but
** remain on the stack if P1<0.
**
** The P2 argument is divided into two 16-bit words before it is processed.
** If the hi-word is non-zero, then an extra integer is read from the stack
** and appended to the record as a varint.  If the low-word of P2 is not
** zero and one or more of the entries are NULL, then jump to the value of
** the low-word of P2.  This feature can be used to skip a uniqueness test
** on indices.
**
** P3 may be a string that is P1 characters long.  The nth character of the
** string indicates the column affinity that should be used for the nth
** field of the index key (i.e. the first character of P3 corresponds to the
** lowest element on the stack).
**
** The mapping from character to affinity is as follows:
**    'n' = NUMERIC.
**    'i' = INTEGER.
**    't' = TEXT.
**    'o' = NONE.
**
** If P3 is NULL then all index fields have the affinity NONE.


*/








case OP_MakeRecord: {
  /* Assuming the record contains N fields, the record format looks
  ** like this:
  **
  ** ------------------------------------------------------------------------
  ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | 
  ** ------------------------------------------------------------------------
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
  unsigned char *zNewRecord;
  unsigned char *zCsr;
  Mem *pRec;
  Mem *pRowid = 0;
  int nData = 0;         /* Number of bytes of data space */
  int nHdr = 0;          /* Number of bytes of header space */
  int nByte = 0;         /* Space required for this record */
  int nVarint;           /* Number of bytes in a varint */
  u32 serial_type;       /* Type field */
  int containsNull = 0;  /* True if any of the data fields are NULL */
  char zTemp[NBFS];      /* Space to hold small records */
  Mem *pData0;

  int leaveOnStack;      /* If true, leave the entries on the stack */
  int nField;            /* Number of fields in the record */
  int jumpIfNull;        /* Jump here if non-zero and any entries are NULL. */
  int addRowid;          /* True to append a rowid column at the end */
  char *zAffinity;       /* The affinity string for the record */
  int file_format;       /* File format to use for encoding */

  leaveOnStack = ((pOp->p1<0)?1:0);
  nField = pOp->p1 * (leaveOnStack?-1:1);
  jumpIfNull = pOp->p2;
  addRowid = pOp->opcode==OP_MakeIdxRec;
  zAffinity = pOp->p3;

  pData0 = &pTos[1-nField];
  assert( pData0>=p->aStack );
  containsNull = 0;
  file_format = p->minWriteFileFormat;

  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.
  */
  for(pRec=pData0; pRec<=pTos; pRec++){
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
    }
    if( pRec->flags&MEM_Null ){
      containsNull = 1;
    }
    serial_type = sqlite3VdbeSerialType(pRec, file_format);
    nData += sqlite3VdbeSerialTypeLen(serial_type);
    nHdr += sqlite3VarintLen(serial_type);
  }

  /* If we have to append a varint rowid to this record, set 'rowid'
  ** to the value of the rowid and increase nByte by the amount of space
  ** required to store it and the 0x00 seperator byte.
  */
  if( addRowid ){
    pRowid = &pTos[0-nField];
    assert( pRowid>=p->aStack );
    sqlite3VdbeMemIntegerify(pRowid);
    serial_type = sqlite3VdbeSerialType(pRowid, 0);
    nData += sqlite3VdbeSerialTypeLen(serial_type);
    nHdr += sqlite3VarintLen(serial_type);
  }

  /* Add the initial header varint and total the size */
  nHdr += nVarint = sqlite3VarintLen(nHdr);
  if( nVarint<sqlite3VarintLen(nHdr) ){
    nHdr++;
  }
  nByte = nHdr+nData;

  /* Allocate space for the new record. */
  if( nByte>sizeof(zTemp) ){
    zNewRecord = sqliteMallocRaw(nByte);
    if( !zNewRecord ){
      goto no_mem;
    }
  }else{
    zNewRecord = (u8*)zTemp;
  }

  /* Write the record */
  zCsr = zNewRecord;
  zCsr += sqlite3PutVarint(zCsr, nHdr);
  for(pRec=pData0; pRec<=pTos; pRec++){
    serial_type = sqlite3VdbeSerialType(pRec, file_format);
    zCsr += sqlite3PutVarint(zCsr, serial_type);      /* serial type */
  }
  if( addRowid ){
    zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid, 0));
  }
  for(pRec=pData0; pRec<=pTos; pRec++){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRec, file_format);  /* serial data */
  }
  if( addRowid ){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRowid, 0);
  }
  assert( zCsr==(zNewRecord+nByte) );

  /* Pop entries off the stack if required. Push the new record on. */
  if( !leaveOnStack ){
    popStack(&pTos, nField+addRowid);
  }
  pTos++;
  pTos->n = nByte;
  if( nByte<=sizeof(zTemp) ){
    assert( zNewRecord==(unsigned char *)zTemp );
    pTos->z = pTos->zShort;
    memcpy(pTos->zShort, zTemp, nByte);
    pTos->flags = MEM_Blob | MEM_Short;
  }else{
    assert( zNewRecord!=(unsigned char *)zTemp );
    pTos->z = (char*)zNewRecord;
    pTos->flags = MEM_Blob | MEM_Dyn;
    pTos->xDel = 0;
  }
  pTos->enc = SQLITE_UTF8;  /* In case the blob is ever converted to text */

  /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */
  if( jumpIfNull && containsNull ){
    pc = jumpIfNull - 1;
  }
  break;
}

/* Opcode: Statement P1 * *
**
** Begin an individual statement transaction which is part of a larger
** BEGIN..COMMIT transaction.  This is needed so that the statement
** can be rolled back after an error without having to roll back the
** entire transaction.  The statement transaction will automatically
** commit when the VDBE halts.
**
** The statement is begun on the database file with index P1.  The main
** database file has an index of 0 and the file used for temporary tables
** has an index of 1.
*/
case OP_Statement: {       /* no-push */
  int i = pOp->p1;
  Btree *pBt;
  if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt)!=0 && !(db->autoCommit) ){
    assert( sqlite3BtreeIsInTrans(pBt) );
    if( !sqlite3BtreeIsInStmt(pBt) ){
      rc = sqlite3BtreeBeginStmt(pBt);
    }
  }
  break;
}

/* Opcode: AutoCommit P1 P2 *
**
** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
** back any currently active btree transactions. If there are any active
** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails.
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {       /* no-push */
  u8 i = pOp->p1;
  u8 rollback = pOp->p2;

  assert( i==1 || i==0 );
  assert( i==1 || rollback==0 );

  assert( db->activeVdbeCnt>0 );  /* At least this one VM is active */

  if( db->activeVdbeCnt>1 && i && !db->autoCommit ){
    /* If this instruction implements a COMMIT or ROLLBACK, other VMs are
    ** still running, and a transaction is active, return an error indicating
    ** that the other VMs must complete first. 
    */
    sqlite3SetString(&p->zErrMsg, "cannot ", rollback?"rollback":"commit", 
        " transaction - SQL statements in progress", (char*)0);
    rc = SQLITE_ERROR;
  }else if( i!=db->autoCommit ){
    pTsd->nRef--;
    if( pOp->p2 ){
      assert( i==1 );
      sqlite3RollbackAll(db);
      db->autoCommit = 1;
    }else{
      db->autoCommit = i;
      if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
        p->pTos = pTos;
        p->pc = pc;
        db->autoCommit = 1-i;
        p->rc = SQLITE_BUSY;
        return SQLITE_BUSY;
      }
    }
    return SQLITE_DONE;
  }else{
    sqlite3SetString(&p->zErrMsg,
        (!i)?"cannot start a transaction within a transaction":(
        (rollback)?"cannot rollback - no transaction is active":
                   "cannot commit - no transaction is active"), (char*)0);
         
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: Transaction P1 P2 *







<










<



|
|





<






|




|











|
|





|
<
<
<









|






|



|


|


|
















|



<




















|


|
















|














|


|



<
<
<
|
|
|
|
|
|
<






|







1992
1993
1994
1995
1996
1997
1998

1999
2000
2001
2002
2003
2004
2005
2006
2007
2008

2009
2010
2011
2012
2013
2014
2015
2016
2017
2018

2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049



2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096

2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158



2159
2160
2161
2162
2163
2164

2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
  unsigned char *zNewRecord;
  unsigned char *zCsr;
  Mem *pRec;
  Mem *pRowid = 0;
  int nData = 0;         /* Number of bytes of data space */
  int nHdr = 0;          /* Number of bytes of header space */
  int nByte = 0;         /* Space required for this record */

  u32 serial_type;       /* Type field */
  int containsNull = 0;  /* True if any of the data fields are NULL */
  char zTemp[NBFS];      /* Space to hold small records */
  Mem *pData0;

  int leaveOnStack;      /* If true, leave the entries on the stack */
  int nField;            /* Number of fields in the record */
  int jumpIfNull;        /* Jump here if non-zero and any entries are NULL. */
  int addRowid;          /* True to append a rowid column at the end */
  char *zAffinity;       /* The affinity string for the record */


  leaveOnStack = ((pOp->p1<0)?1:0);
  nField = pOp->p1 * (leaveOnStack?-1:1);
  jumpIfNull = (pOp->p2 & 0x00FFFFFF);
  addRowid = ((pOp->p2>>24) & 0x0000FFFF)?1:0;
  zAffinity = pOp->p3;

  pData0 = &pTos[1-nField];
  assert( pData0>=p->aStack );
  containsNull = 0;


  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.
  */
  for(pRec=pData0; pRec<=pTos; pRec++){
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0], db->enc);
    }
    if( pRec->flags&MEM_Null ){
      containsNull = 1;
    }
    serial_type = sqlite3VdbeSerialType(pRec);
    nData += sqlite3VdbeSerialTypeLen(serial_type);
    nHdr += sqlite3VarintLen(serial_type);
  }

  /* If we have to append a varint rowid to this record, set 'rowid'
  ** to the value of the rowid and increase nByte by the amount of space
  ** required to store it and the 0x00 seperator byte.
  */
  if( addRowid ){
    pRowid = &pTos[0-nField];
    assert( pRowid>=p->aStack );
    Integerify(pRowid);
    serial_type = sqlite3VdbeSerialType(pRowid);
    nData += sqlite3VdbeSerialTypeLen(serial_type);
    nHdr += sqlite3VarintLen(serial_type);
  }

  /* Add the initial header varint and total the size */
  nHdr += sqlite3VarintLen(nHdr);



  nByte = nHdr+nData;

  /* Allocate space for the new record. */
  if( nByte>sizeof(zTemp) ){
    zNewRecord = sqliteMallocRaw(nByte);
    if( !zNewRecord ){
      goto no_mem;
    }
  }else{
    zNewRecord = zTemp;
  }

  /* Write the record */
  zCsr = zNewRecord;
  zCsr += sqlite3PutVarint(zCsr, nHdr);
  for(pRec=pData0; pRec<=pTos; pRec++){
    serial_type = sqlite3VdbeSerialType(pRec);
    zCsr += sqlite3PutVarint(zCsr, serial_type);      /* serial type */
  }
  if( addRowid ){
    zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid));
  }
  for(pRec=pData0; pRec<=pTos; pRec++){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
  }
  if( addRowid ){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRowid);
  }
  assert( zCsr==(zNewRecord+nByte) );

  /* Pop entries off the stack if required. Push the new record on. */
  if( !leaveOnStack ){
    popStack(&pTos, nField+addRowid);
  }
  pTos++;
  pTos->n = nByte;
  if( nByte<=sizeof(zTemp) ){
    assert( zNewRecord==(unsigned char *)zTemp );
    pTos->z = pTos->zShort;
    memcpy(pTos->zShort, zTemp, nByte);
    pTos->flags = MEM_Blob | MEM_Short;
  }else{
    assert( zNewRecord!=(unsigned char *)zTemp );
    pTos->z = zNewRecord;
    pTos->flags = MEM_Blob | MEM_Dyn;
    pTos->xDel = 0;
  }


  /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */
  if( jumpIfNull && containsNull ){
    pc = jumpIfNull - 1;
  }
  break;
}

/* Opcode: Statement P1 * *
**
** Begin an individual statement transaction which is part of a larger
** BEGIN..COMMIT transaction.  This is needed so that the statement
** can be rolled back after an error without having to roll back the
** entire transaction.  The statement transaction will automatically
** commit when the VDBE halts.
**
** The statement is begun on the database file with index P1.  The main
** database file has an index of 0 and the file used for temporary tables
** has an index of 1.
*/
case OP_Statement: {
  int i = pOp->p1;
  Btree *pBt;
  if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt) && !(db->autoCommit) ){
    assert( sqlite3BtreeIsInTrans(pBt) );
    if( !sqlite3BtreeIsInStmt(pBt) ){
      rc = sqlite3BtreeBeginStmt(pBt);
    }
  }
  break;
}

/* Opcode: AutoCommit P1 P2 *
**
** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
** back any currently active btree transactions. If there are any active
** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails.
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
  u8 i = pOp->p1;
  u8 rollback = pOp->p2;

  assert( i==1 || i==0 );
  assert( i==1 || rollback==0 );

  assert( db->activeVdbeCnt>0 );  /* At least this one VM is active */

  if( db->activeVdbeCnt>1 && i && !db->autoCommit ){
    /* If this instruction implements a COMMIT or ROLLBACK, other VMs are
    ** still running, and a transaction is active, return an error indicating
    ** that the other VMs must complete first. 
    */
    sqlite3SetString(&p->zErrMsg, "cannot ", rollback?"rollback":"commit", 
        " transaction - SQL statements in progress", 0);
    rc = SQLITE_ERROR;
  }else if( i!=db->autoCommit ){
    db->autoCommit = i;
    if( pOp->p2 ){
      assert( i==1 );
      sqlite3RollbackAll(db);



    }else if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
      p->pTos = pTos;
      p->pc = pc;
      db->autoCommit = 1-i;
      p->rc = SQLITE_BUSY;
      return SQLITE_BUSY;

    }
    return SQLITE_DONE;
  }else{
    sqlite3SetString(&p->zErrMsg,
        (!i)?"cannot start a transaction within a transaction":(
        (rollback)?"cannot rollback - no transaction is active":
                   "cannot commit - no transaction is active"), 0);
         
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: Transaction P1 P2 *
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
** underway.  Starting a write transaction also creates a rollback journal. A
** write transaction must be started before any changes can be made to the
** database.  If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
** on the file.
**
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {       /* no-push */
  int i = pOp->p1;
  Btree *pBt;

  assert( i>=0 && i<db->nDb );
  pBt = db->aDb[i].pBt;

  if( pBt ){
    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
    if( rc==SQLITE_BUSY ){
      p->pc = pc;
      p->rc = SQLITE_BUSY;
      p->pTos = pTos;
      pTsd->nRef--;
      return SQLITE_BUSY;
    }
    if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){
      goto abort_due_to_error;
    }
  }
  break;







|












<







2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210

2211
2212
2213
2214
2215
2216
2217
** underway.  Starting a write transaction also creates a rollback journal. A
** write transaction must be started before any changes can be made to the
** database.  If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
** on the file.
**
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {
  int i = pOp->p1;
  Btree *pBt;

  assert( i>=0 && i<db->nDb );
  pBt = db->aDb[i].pBt;

  if( pBt ){
    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
    if( rc==SQLITE_BUSY ){
      p->pc = pc;
      p->rc = SQLITE_BUSY;
      p->pTos = pTos;

      return SQLITE_BUSY;
    }
    if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){
      goto abort_due_to_error;
    }
  }
  break;
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
** P2==0 is the schema version.  P2==1 is the database format.
** P2==2 is the recommended pager cache size, and so forth.  P1==0 is
** the main database file and P1==1 is the database file used to store
** temporary tables.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: {       /* no-push */
  Db *pDb;
  assert( pOp->p2<SQLITE_N_BTREE_META );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pDb = &db->aDb[pOp->p1];
  assert( pDb->pBt!=0 );
  assert( pTos>=p->aStack );
  sqlite3VdbeMemIntegerify(pTos);
  /* See note about index shifting on OP_ReadCookie */
  rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pTos->i);
  if( pOp->p2==0 ){
    /* When the schema cookie changes, record the new cookie internally */
    pDb->pSchema->schema_cookie = pTos->i;
    db->flags |= SQLITE_InternChanges;
  }else if( pOp->p2==1 ){
    /* Record changes in the file format */
    pDb->pSchema->file_format = pTos->i;
  }
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  break;
}

/* Opcode: VerifyCookie P1 P2 *







|






|




|

<
<
<







2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274



2275
2276
2277
2278
2279
2280
2281
** P2==0 is the schema version.  P2==1 is the database format.
** P2==2 is the recommended pager cache size, and so forth.  P1==0 is
** the main database file and P1==1 is the database file used to store
** temporary tables.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: {
  Db *pDb;
  assert( pOp->p2<SQLITE_N_BTREE_META );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pDb = &db->aDb[pOp->p1];
  assert( pDb->pBt!=0 );
  assert( pTos>=p->aStack );
  Integerify(pTos);
  /* See note about index shifting on OP_ReadCookie */
  rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pTos->i);
  if( pOp->p2==0 ){
    /* When the schema cookie changes, record the new cookie internally */
    pDb->schema_cookie = pTos->i;
    db->flags |= SQLITE_InternChanges;



  }
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  break;
}

/* Opcode: VerifyCookie P1 P2 *
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
** This operation is used to detect when that the cookie has changed
** and that the current process needs to reread the schema.
**
** Either a transaction needs to have been started or an OP_Open needs
** to be executed (to establish a read lock) before this opcode is
** invoked.
*/
case OP_VerifyCookie: {       /* no-push */
  int iMeta;
  Btree *pBt;
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pBt = db->aDb[pOp->p1].pBt;
  if( pBt ){
    rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta);
  }else{







|







2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
** This operation is used to detect when that the cookie has changed
** and that the current process needs to reread the schema.
**
** Either a transaction needs to have been started or an OP_Open needs
** to be executed (to establish a read lock) before this opcode is
** invoked.
*/
case OP_VerifyCookie: {
  int iMeta;
  Btree *pBt;
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  pBt = db->aDb[pOp->p1].pBt;
  if( pBt ){
    rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta);
  }else{
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589



2590

2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602

2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665







2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
**
** This instruction works just like OpenRead except that it opens the cursor
** in read/write mode.  For a given table, there can be one or more read-only
** cursors or a single read/write cursor but not both.
**
** See also OpenRead.
*/
case OP_OpenRead:          /* no-push */
case OP_OpenWrite: {       /* no-push */
  int i = pOp->p1;
  int p2 = pOp->p2;
  int wrFlag;
  Btree *pX;
  int iDb;
  Cursor *pCur;
  Db *pDb;
  
  assert( pTos>=p->aStack );
  sqlite3VdbeMemIntegerify(pTos);
  iDb = pTos->i;
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  assert( iDb>=0 && iDb<db->nDb );
  pDb = &db->aDb[iDb];
  pX = pDb->pBt;
  assert( pX!=0 );
  if( pOp->opcode==OP_OpenWrite ){
    wrFlag = 1;
    if( pDb->pSchema->file_format < p->minWriteFileFormat ){
      p->minWriteFileFormat = pDb->pSchema->file_format;
    }
  }else{
    wrFlag = 0;
  }
  if( p2<=0 ){
    assert( pTos>=p->aStack );
    sqlite3VdbeMemIntegerify(pTos);
    p2 = pTos->i;
    assert( (pTos->flags & MEM_Dyn)==0 );
    pTos--;
    assert( p2>=2 );



  }

  assert( i>=0 );
  pCur = allocateCursor(p, i, iDb);
  if( pCur==0 ) goto no_mem;
  pCur->nullRow = 1;
  if( pX==0 ) break;
  /* We always provide a key comparison function.  If the table being
  ** opened is of type INTKEY, the comparision function will be ignored. */
  rc = sqlite3BtreeCursor(pX, p2, wrFlag,
           sqlite3VdbeRecordCompare, pOp->p3,
           &pCur->pCursor);
  if( pOp->p3type==P3_KEYINFO ){
    pCur->pKeyInfo = (KeyInfo*)pOp->p3;

    pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
    pCur->pKeyInfo->enc = ENC(p->db);
  }else{
    pCur->pKeyInfo = 0;
    pCur->pIncrKey = &pCur->bogusIncrKey;
  }
  switch( rc ){
    case SQLITE_BUSY: {
      p->pc = pc;
      p->rc = SQLITE_BUSY;
      p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
      pTsd->nRef--;
      return SQLITE_BUSY;
    }
    case SQLITE_OK: {
      int flags = sqlite3BtreeFlags(pCur->pCursor);
      /* Sanity checking.  Only the lower four bits of the flags byte should
      ** be used.  Bit 3 (mask 0x08) is unpreditable.  The lower 3 bits
      ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or
      ** 2 (zerodata for indices).  If these conditions are not met it can
      ** only mean that we are dealing with a corrupt database file
      */
      if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){
        rc = SQLITE_CORRUPT_BKPT;
        goto abort_due_to_error;
      }
      pCur->isTable = (flags & BTREE_INTKEY)!=0;
      pCur->isIndex = (flags & BTREE_ZERODATA)!=0;
      /* If P3==0 it means we are expected to open a table.  If P3!=0 then
      ** we expect to be opening an index.  If this is not what happened,
      ** then the database is corrupt
      */
      if( (pCur->isTable && pOp->p3type==P3_KEYINFO)
       || (pCur->isIndex && pOp->p3type!=P3_KEYINFO) ){
        rc = SQLITE_CORRUPT_BKPT;
        goto abort_due_to_error;
      }
      break;
    }
    case SQLITE_EMPTY: {
      pCur->isTable = pOp->p3type!=P3_KEYINFO;
      pCur->isIndex = !pCur->isTable;
      rc = SQLITE_OK;
      break;
    }
    default: {
      goto abort_due_to_error;
    }
  }
  break;
}

/* Opcode: OpenVirtual P1 P2 P3
**
** Open a new cursor P1 to a transient or virtual table.
** The cursor is always opened read/write even if 
** the main database is read-only.  The transient or virtual
** table is deleted automatically when the cursor is closed.
**
** P2 is the number of columns in the virtual table.
** The cursor points to a BTree table if P3==0 and to a BTree index
** if P3 is not 0.  If P3 is not NULL, it points to a KeyInfo structure
** that defines the format of keys in the index.







*/
case OP_OpenVirtual: {       /* no-push */
  int i = pOp->p1;
  Cursor *pCx;
  assert( i>=0 );
  pCx = allocateCursor(p, i, -1);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
  if( rc==SQLITE_OK ){
    rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
  }
  if( rc==SQLITE_OK ){







|
|






<


|




|
<

|
<
<
<
<
<
<
<


|



|
>
>
>
|
>

|








<
|
>

|

<







<




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



<
<










|

|
|
|
|

<



>
>
>
>
>
>
>

|



|







2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364

2365
2366
2367
2368
2369
2370
2371
2372

2373
2374







2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396

2397
2398
2399
2400
2401

2402
2403
2404
2405
2406
2407
2408

2409
2410
2411
2412










2413
2414









2415
2416
2417


2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434

2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
**
** This instruction works just like OpenRead except that it opens the cursor
** in read/write mode.  For a given table, there can be one or more read-only
** cursors or a single read/write cursor but not both.
**
** See also OpenRead.
*/
case OP_OpenRead:
case OP_OpenWrite: {
  int i = pOp->p1;
  int p2 = pOp->p2;
  int wrFlag;
  Btree *pX;
  int iDb;
  Cursor *pCur;

  
  assert( pTos>=p->aStack );
  Integerify(pTos);
  iDb = pTos->i;
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  assert( iDb>=0 && iDb<db->nDb );
  pX = db->aDb[iDb].pBt;

  assert( pX!=0 );
  wrFlag = pOp->opcode==OP_OpenWrite;







  if( p2<=0 ){
    assert( pTos>=p->aStack );
    Integerify(pTos);
    p2 = pTos->i;
    assert( (pTos->flags & MEM_Dyn)==0 );
    pTos--;
    if( p2<2 ){
      sqlite3SetString(&p->zErrMsg, "root page number less than 2", (char*)0);
      rc = SQLITE_INTERNAL;
      break;
    }
  }
  assert( i>=0 );
  pCur = allocateCursor(p, i);
  if( pCur==0 ) goto no_mem;
  pCur->nullRow = 1;
  if( pX==0 ) break;
  /* We always provide a key comparison function.  If the table being
  ** opened is of type INTKEY, the comparision function will be ignored. */
  rc = sqlite3BtreeCursor(pX, p2, wrFlag,
           sqlite3VdbeRecordCompare, pOp->p3,
           &pCur->pCursor);

  pCur->pKeyInfo = (KeyInfo*)pOp->p3;
  if( pCur->pKeyInfo ){
    pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
    pCur->pKeyInfo->enc = p->db->enc;
  }else{

    pCur->pIncrKey = &pCur->bogusIncrKey;
  }
  switch( rc ){
    case SQLITE_BUSY: {
      p->pc = pc;
      p->rc = SQLITE_BUSY;
      p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */

      return SQLITE_BUSY;
    }
    case SQLITE_OK: {
      int flags = sqlite3BtreeFlags(pCur->pCursor);










      pCur->intKey = (flags & BTREE_INTKEY)!=0;
      pCur->zeroData = (flags & BTREE_ZERODATA)!=0;









      break;
    }
    case SQLITE_EMPTY: {


      rc = SQLITE_OK;
      break;
    }
    default: {
      goto abort_due_to_error;
    }
  }
  break;
}

/* Opcode: OpenTemp P1 * P3
**
** Open a new cursor to a transient table.
** The transient cursor is always opened read/write even if 
** the main database is read-only.  The transient table is deleted
** automatically when the cursor is closed.
**

** The cursor points to a BTree table if P3==0 and to a BTree index
** if P3 is not 0.  If P3 is not NULL, it points to a KeyInfo structure
** that defines the format of keys in the index.
**
** This opcode is used for tables that exist for the duration of a single
** SQL statement only.  Tables created using CREATE TEMPORARY TABLE
** are opened using OP_OpenRead or OP_OpenWrite.  "Temporary" in the
** context of this opcode means for the duration of a single SQL statement
** whereas "Temporary" in the context of CREATE TABLE means for the duration
** of the connection to the database.  Same word; different meanings.
*/
case OP_OpenTemp: {
  int i = pOp->p1;
  Cursor *pCx;
  assert( i>=0 );
  pCx = allocateCursor(p, i);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
  if( rc==SQLITE_OK ){
    rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
  }
  if( rc==SQLITE_OK ){
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
      assert( pOp->p3type==P3_KEYINFO );
      rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); 
      if( rc==SQLITE_OK ){
        assert( pgno==MASTER_ROOT+1 );
        rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare,
            pOp->p3, &pCx->pCursor);
        pCx->pKeyInfo = (KeyInfo*)pOp->p3;
        pCx->pKeyInfo->enc = ENC(p->db);
        pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
      }
      pCx->isTable = 0;
    }else{
      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor);
      pCx->isTable = 1;
      pCx->pIncrKey = &pCx->bogusIncrKey;
    }
  }
  pCx->nField = pOp->p2;
  pCx->isIndex = !pCx->isTable;
  break;
}

#ifndef SQLITE_OMIT_TRIGGER
/* Opcode: OpenPseudo P1 * *
**
** Open a new cursor that points to a fake table that contains a single
** row of data.  Any attempt to write a second row of data causes the
** first row to be deleted.  All data is deleted when the cursor is
** closed.
**
** A pseudo-table created by this opcode is useful for holding the
** NEW or OLD tables in a trigger.
*/
case OP_OpenPseudo: {       /* no-push */
  int i = pOp->p1;
  Cursor *pCx;
  assert( i>=0 );
  pCx = allocateCursor(p, i, -1);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  pCx->pseudoTable = 1;
  pCx->pIncrKey = &pCx->bogusIncrKey;
  pCx->isTable = 1;
  pCx->isIndex = 0;
  break;
}
#endif

/* Opcode: Close P1 * *
**
** Close a cursor previously opened as P1.  If P1 is not
** currently open, this instruction is a no-op.
*/
case OP_Close: {       /* no-push */
  int i = pOp->p1;
  if( i>=0 && i<p->nCursor ){
    sqlite3VdbeFreeCursor(p->apCsr[i]);
    p->apCsr[i] = 0;
  }
  break;
}







|


<


|



<
<














|



|




<
<









|







2465
2466
2467
2468
2469
2470
2471
2472
2473
2474

2475
2476
2477
2478
2479
2480


2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503


2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
      assert( pOp->p3type==P3_KEYINFO );
      rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); 
      if( rc==SQLITE_OK ){
        assert( pgno==MASTER_ROOT+1 );
        rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare,
            pOp->p3, &pCx->pCursor);
        pCx->pKeyInfo = (KeyInfo*)pOp->p3;
        pCx->pKeyInfo->enc = p->db->enc;
        pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
      }

    }else{
      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor);
      pCx->intKey = 1;
      pCx->pIncrKey = &pCx->bogusIncrKey;
    }
  }


  break;
}

#ifndef SQLITE_OMIT_TRIGGER
/* Opcode: OpenPseudo P1 * *
**
** Open a new cursor that points to a fake table that contains a single
** row of data.  Any attempt to write a second row of data causes the
** first row to be deleted.  All data is deleted when the cursor is
** closed.
**
** A pseudo-table created by this opcode is useful for holding the
** NEW or OLD tables in a trigger.
*/
case OP_OpenPseudo: {
  int i = pOp->p1;
  Cursor *pCx;
  assert( i>=0 );
  pCx = allocateCursor(p, i);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  pCx->pseudoTable = 1;
  pCx->pIncrKey = &pCx->bogusIncrKey;


  break;
}
#endif

/* Opcode: Close P1 * *
**
** Close a cursor previously opened as P1.  If P1 is not
** currently open, this instruction is a no-op.
*/
case OP_Close: {
  int i = pOp->p1;
  if( i>=0 && i<p->nCursor ){
    sqlite3VdbeFreeCursor(p->apCsr[i]);
    p->apCsr[i] = 0;
  }
  break;
}
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
** cursor P1 so that it points to the largest entry that is less than
** or equal to the key that was popped from the stack.
** If there are no records less than or eqal to the key and P2 is not zero,
** then jump to P2.
**
** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt
*/
case OP_MoveLt:         /* no-push */
case OP_MoveLe:         /* no-push */
case OP_MoveGe:         /* no-push */
case OP_MoveGt: {       /* no-push */
  int i = pOp->p1;
  Cursor *pC;

  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( pC->pCursor!=0 ){
    int res, oc;
    oc = pOp->opcode;
    pC->nullRow = 0;
    *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe;
    if( pC->isTable ){
      i64 iKey;
      sqlite3VdbeMemIntegerify(pTos);
      iKey = intToKey(pTos->i);
      if( pOp->p2==0 && pOp->opcode==OP_MoveGe ){
        pC->movetoTarget = iKey;
        pC->deferredMoveto = 1;
        assert( (pTos->flags & MEM_Dyn)==0 );
        pTos--;
        break;
      }
      rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, &res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pC->lastRowid = pTos->i;
      pC->rowidIsValid = res==0;
    }else{
      assert( pTos->flags & MEM_Blob );
      /* Stringify(pTos, encoding); */
      rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pC->rowidIsValid = 0;
    }
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
    *pC->pIncrKey = 0;
    sqlite3_search_count++;
    if( oc==OP_MoveGe || oc==OP_MoveGt ){
      if( res<0 ){
        rc = sqlite3BtreeNext(pC->pCursor, &res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        pC->rowidIsValid = 0;
      }else{
        res = 0;
      }
    }else{
      assert( oc==OP_MoveLt || oc==OP_MoveLe );
      if( res>=0 ){
        rc = sqlite3BtreePrevious(pC->pCursor, &res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        pC->rowidIsValid = 0;
      }else{
        /* res might be negative because the table is empty.  Check to
        ** see if this is the case.
        */
        res = sqlite3BtreeEof(pC->pCursor);
      }
    }







|
|
|
|












|

|












|
|

<
|




|


|






|








|







2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595

2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
** cursor P1 so that it points to the largest entry that is less than
** or equal to the key that was popped from the stack.
** If there are no records less than or eqal to the key and P2 is not zero,
** then jump to P2.
**
** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt
*/
case OP_MoveLt:
case OP_MoveLe:
case OP_MoveGe:
case OP_MoveGt: {
  int i = pOp->p1;
  Cursor *pC;

  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( pC->pCursor!=0 ){
    int res, oc;
    oc = pOp->opcode;
    pC->nullRow = 0;
    *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe;
    if( pC->intKey ){
      i64 iKey;
      Integerify(pTos);
      iKey = intToKey(pTos->i);
      if( pOp->p2==0 && pOp->opcode==OP_MoveGe ){
        pC->movetoTarget = iKey;
        pC->deferredMoveto = 1;
        assert( (pTos->flags & MEM_Dyn)==0 );
        pTos--;
        break;
      }
      rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, &res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pC->lastRecno = pTos->i;
      pC->recnoIsValid = res==0;
    }else{

      Stringify(pTos, db->enc);
      rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pC->recnoIsValid = 0;
    }
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
    *pC->pIncrKey = 0;
    sqlite3_search_count++;
    if( oc==OP_MoveGe || oc==OP_MoveGt ){
      if( res<0 ){
        rc = sqlite3BtreeNext(pC->pCursor, &res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        pC->recnoIsValid = 0;
      }else{
        res = 0;
      }
    }else{
      assert( oc==OP_MoveLt || oc==OP_MoveLe );
      if( res>=0 ){
        rc = sqlite3BtreePrevious(pC->pCursor, &res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        pC->recnoIsValid = 0;
      }else{
        /* res might be negative because the table is empty.  Check to
        ** see if this is the case.
        */
        res = sqlite3BtreeEof(pC->pCursor);
      }
    }
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: Distinct P1 P2 *
**
** Use the top of the stack as a record created using MakeRecord.  P1 is a
** cursor on a table that declared as an index.  If that table contains an
** entry that matches the top of the stack fall thru.  If the top of the stack
** matches no entry in P1 then jump to P2.
**
** The cursor is left pointing at the matching entry if it exists.  The
** record on the top of the stack is not popped.
**
** This instruction is similar to NotFound except that this operation
** does not pop the key from the stack.
**
** The instruction is used to implement the DISTINCT operator on SELECT
** statements.  The P1 table is not a true index but rather a record of
** all results that have produced so far.  
**
** See also: Found, NotFound, MoveTo, IsUnique, NotExists
*/
/* Opcode: Found P1 P2 *
**
** Top of the stack holds a blob constructed by MakeRecord.  P1 is an index.
** If an entry that matches the top of the stack exists in P1 then
** jump to P2.  If the top of the stack does not match any entry in P1
** then fall thru.  The P1 cursor is left pointing at the matching entry
** if it exists.  The blob is popped off the top of the stack.
**
** This instruction is used to implement the IN operator where the
** left-hand side is a SELECT statement.  P1 is not a true index but
** is instead a temporary index that holds the results of the SELECT
** statement.  This instruction just checks to see if the left-hand side
** of the IN operator (stored on the top of the stack) exists in the
** result of the SELECT statement.
**
** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists
*/
/* Opcode: NotFound P1 P2 *
**
** The top of the stack holds a blob constructed by MakeRecord.  P1 is
** an index.  If no entry exists in P1 that matches the blob then jump
** to P1.  If an entry does existing, fall through.  The cursor is left
** pointing to the entry that matches.  The blob is popped from the stack.
**
** The difference between this operation and Distinct is that
** Distinct does not pop the key from the stack.
**
** See also: Distinct, Found, MoveTo, NotExists, IsUnique
*/
case OP_Distinct:       /* no-push */
case OP_NotFound:       /* no-push */
case OP_Found: {        /* no-push */
  int i = pOp->p1;
  int alreadyExists = 0;
  Cursor *pC;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
    int res, rx;
    assert( pC->isTable==0 );
    Stringify(pTos, encoding);
    rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
    alreadyExists = rx==SQLITE_OK && res==0;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
  }
  if( pOp->opcode==OP_Found ){
    if( alreadyExists ) pc = pOp->p2 - 1;
  }else{
    if( !alreadyExists ) pc = pOp->p2 - 1;
  }
  if( pOp->opcode!=OP_Distinct ){
    Release(pTos);
    pTos--;
  }
  break;
}

/* Opcode: IsUnique P1 P2 *
**
** The top of the stack is an integer record number.  Call this
** record number R.  The next on the stack is an index key created
** using MakeIdxRec.  Call it K.  This instruction pops R from the
** stack but it leaves K unchanged.
**
** P1 is an index.  So it has no data and its key consists of a
** record generated by OP_MakeRecord where the last field is the 
** rowid of the entry that the index refers to.
** 
** This instruction asks if there is an entry in P1 where the
** fields matches K but the rowid is different from R.
** If there is no such entry, then there is an immediate
** jump to P2.  If any entry does exist where the index string
** matches K but the record number is not R, then the record
** number for that entry is pushed onto the stack and control
** falls through to the next instruction.
**
** See also: Distinct, NotFound, NotExists, Found
*/
case OP_IsUnique: {        /* no-push */
  int i = pOp->p1;
  Mem *pNos = &pTos[-1];
  Cursor *pCx;
  BtCursor *pCrsr;
  i64 R;

  /* Pop the value R off the top of the stack
  */
  assert( pNos>=p->aStack );
  sqlite3VdbeMemIntegerify(pTos);
  R = pTos->i;
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  assert( i>=0 && i<=p->nCursor );
  pCx = p->apCsr[i];
  assert( pCx!=0 );
  pCrsr = pCx->pCursor;
  if( pCrsr!=0 ){
    int res, rc;
    i64 v;         /* The record number on the P1 entry that matches K */
    char *zKey;    /* The value of K */
    int nKey;      /* Number of bytes in K */
    int len;       /* Number of bytes in K without the rowid at the end */
    int szRowid;   /* Size of the rowid column at the end of zKey */

    /* Make sure K is a string and make zKey point to K
    */
    Stringify(pNos, encoding);
    zKey = pNos->z;
    nKey = pNos->n;

    szRowid = sqlite3VdbeIdxRowidLen(nKey, (u8*)zKey);
    len = nKey-szRowid;

    /* Search for an entry in P1 where all but the last four bytes match K.
    ** If there is no such entry, jump immediately to P2.
    */
    assert( pCx->deferredMoveto==0 );
    pCx->cacheStatus = CACHE_STALE;
    rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res);
    if( rc!=SQLITE_OK ) goto abort_due_to_error;
    if( res<0 ){
      rc = sqlite3BtreeNext(pCrsr, &res);
      if( res ){
        pc = pOp->p2 - 1;
        break;
      }
    }
    rc = sqlite3VdbeIdxKeyCompare(pCx, len, (u8*)zKey, &res); 
    if( rc!=SQLITE_OK ) goto abort_due_to_error;
    if( res>0 ){
      pc = pOp->p2 - 1;
      break;
    }

    /* At this point, pCrsr is pointing to an entry in P1 where all but







|
<
<
|
<
|
|

|

<
<
<
<





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





|
|
|
|






|
|
|








|
|



|

















|



|
|











|









|

















|



|






|









|







2636
2637
2638
2639
2640
2641
2642
2643


2644

2645
2646
2647
2648
2649




2650
2651
2652
2653
2654

2655
2656
2657
2658







2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: Distinct P1 P2 *
**
** Use the top of the stack as a string key.  If a record with that key does


** not exist in the table of cursor P1, then jump to P2.  If the record

** does already exist, then fall thru.  The cursor is left pointing
** at the record if it exists. The key is not popped from the stack.
**
** This operation is similar to NotFound except that this operation
** does not pop the key from the stack.




**
** See also: Found, NotFound, MoveTo, IsUnique, NotExists
*/
/* Opcode: Found P1 P2 *
**

** Use the top of the stack as a string key.  If a record with that key
** does exist in table of P1, then jump to P2.  If the record
** does not exist, then fall thru.  The cursor is left pointing
** to the record if it exists.  The key is popped from the stack.







**
** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists
*/
/* Opcode: NotFound P1 P2 *
**
** Use the top of the stack as a string key.  If a record with that key
** does not exist in table of P1, then jump to P2.  If the record
** does exist, then fall thru.  The cursor is left pointing to the
** record if it exists.  The key is popped from the stack.
**
** The difference between this operation and Distinct is that
** Distinct does not pop the key from the stack.
**
** See also: Distinct, Found, MoveTo, NotExists, IsUnique
*/
case OP_Distinct:
case OP_NotFound:
case OP_Found: {
  int i = pOp->p1;
  int alreadyExists = 0;
  Cursor *pC;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
    int res, rx;
    assert( pC->intKey==0 );
    Stringify(pTos, db->enc);
    rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
    alreadyExists = rx==SQLITE_OK && res==0;
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
  }
  if( pOp->opcode==OP_Found ){
    if( alreadyExists ) pc = pOp->p2 - 1;
  }else{
    if( !alreadyExists ) pc = pOp->p2 - 1;
  }
  if( pOp->opcode!=OP_Distinct ){
    Release(pTos);
    pTos--;
  }
  break;
}

/* Opcode: IsUnique P1 P2 *
**
** The top of the stack is an integer record number.  Call this
** record number R.  The next on the stack is an index key created
** using MakeIdxKey.  Call it K.  This instruction pops R from the
** stack but it leaves K unchanged.
**
** P1 is an index.  So it has no data and its key consists of a
** record generated by OP_MakeIdxKey.  This key contains one or more
** fields followed by a ROWID field.
** 
** This instruction asks if there is an entry in P1 where the
** fields matches K but the rowid is different from R.
** If there is no such entry, then there is an immediate
** jump to P2.  If any entry does exist where the index string
** matches K but the record number is not R, then the record
** number for that entry is pushed onto the stack and control
** falls through to the next instruction.
**
** See also: Distinct, NotFound, NotExists, Found
*/
case OP_IsUnique: {
  int i = pOp->p1;
  Mem *pNos = &pTos[-1];
  Cursor *pCx;
  BtCursor *pCrsr;
  i64 R;

  /* Pop the value R off the top of the stack
  */
  assert( pNos>=p->aStack );
  Integerify(pTos);
  R = pTos->i;
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  assert( i>=0 && i<=p->nCursor );
  pCx = p->apCsr[i];
  assert( pCx!=0 );
  pCrsr = pCx->pCursor;
  if( pCrsr!=0 ){
    int res, rc;
    i64 v;         /* The record number on the P1 entry that matches K */
    char *zKey;    /* The value of K */
    int nKey;      /* Number of bytes in K */
    int len;       /* Number of bytes in K without the rowid at the end */
    int szRowid;   /* Size of the rowid column at the end of zKey */

    /* Make sure K is a string and make zKey point to K
    */
    Stringify(pNos, db->enc);
    zKey = pNos->z;
    nKey = pNos->n;

    szRowid = sqlite3VdbeIdxRowidLen(nKey, zKey);
    len = nKey-szRowid;

    /* Search for an entry in P1 where all but the last four bytes match K.
    ** If there is no such entry, jump immediately to P2.
    */
    assert( pCx->deferredMoveto==0 );
    pCx->cacheValid = 0;
    rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res);
    if( rc!=SQLITE_OK ) goto abort_due_to_error;
    if( res<0 ){
      rc = sqlite3BtreeNext(pCrsr, &res);
      if( res ){
        pc = pOp->p2 - 1;
        break;
      }
    }
    rc = sqlite3VdbeIdxKeyCompare(pCx, len, zKey, &res); 
    if( rc!=SQLITE_OK ) goto abort_due_to_error;
    if( res>0 ){
      pc = pOp->p2 - 1;
      break;
    }

    /* At this point, pCrsr is pointing to an entry in P1 where all but
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
**
** Use the top of the stack as a integer key.  If a record with that key
** does not exist in table of P1, then jump to P2.  If the record
** does exist, then fall thru.  The cursor is left pointing to the
** record if it exists.  The integer key is popped from the stack.
**
** The difference between this operation and NotFound is that this
** operation assumes the key is an integer and that P1 is a table whereas
** NotFound assumes key is a blob constructed from MakeRecord and
** P1 is an index.
**
** See also: Distinct, Found, MoveTo, NotFound, IsUnique
*/
case OP_NotExists: {        /* no-push */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int res;
    u64 iKey;
    assert( pTos->flags & MEM_Int );
    assert( p->apCsr[i]->isTable );
    iKey = intToKey(pTos->i);
    rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
    pC->lastRowid = pTos->i;
    pC->rowidIsValid = res==0;
    pC->nullRow = 0;
    pC->cacheStatus = CACHE_STALE;
    if( res!=0 ){
      pc = pOp->p2 - 1;
      pC->rowidIsValid = 0;
    }
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: Sequence P1 * *
**
** Push an integer onto the stack which is the next available
** sequence number for cursor P1.  The sequence number on the
** cursor is incremented after the push.
*/
case OP_Sequence: {
  int i = pOp->p1;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  pTos++;
  pTos->i = p->apCsr[i]->seqCount++;
  pTos->flags = MEM_Int;
  break;
}


/* Opcode: NewRowid P1 P2 *
**
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
** The record number is not previously used as a key in the database
** table that cursor P1 points to.  The new record number is pushed 
** onto the stack.
**
** If P2>0 then P2 is a memory cell that holds the largest previously
** generated record number.  No new record numbers are allowed to be less
** than this value.  When this value reaches its maximum, a SQLITE_FULL
** error is generated.  The P2 memory cell is updated with the generated
** record number.  This P2 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
case OP_NewRowid: {
  int i = pOp->p1;
  i64 v = 0;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pC = p->apCsr[i])->pCursor==0 ){
    /* The zero initialization above is all that is needed */







|
<
|



|










|


|
|

|


|







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

|











|







2807
2808
2809
2810
2811
2812
2813
2814

2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846


















2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
**
** Use the top of the stack as a integer key.  If a record with that key
** does not exist in table of P1, then jump to P2.  If the record
** does exist, then fall thru.  The cursor is left pointing to the
** record if it exists.  The integer key is popped from the stack.
**
** The difference between this operation and NotFound is that this
** operation assumes the key is an integer and NotFound assumes it

** is a string.
**
** See also: Distinct, Found, MoveTo, NotFound, IsUnique
*/
case OP_NotExists: {
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int res;
    u64 iKey;
    assert( pTos->flags & MEM_Int );
    assert( p->apCsr[i]->intKey );
    iKey = intToKey(pTos->i);
    rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
    pC->lastRecno = pTos->i;
    pC->recnoIsValid = res==0;
    pC->nullRow = 0;
    pC->cacheValid = 0;
    if( res!=0 ){
      pc = pOp->p2 - 1;
      pC->recnoIsValid = 0;
    }
  }
  Release(pTos);
  pTos--;
  break;
}



















/* Opcode: NewRecno P1 P2 *
**
** Get a new integer record number used as the key to a table.
** The record number is not previously used as a key in the database
** table that cursor P1 points to.  The new record number is pushed 
** onto the stack.
**
** If P2>0 then P2 is a memory cell that holds the largest previously
** generated record number.  No new record numbers are allowed to be less
** than this value.  When this value reaches its maximum, a SQLITE_FULL
** error is generated.  The P2 memory cell is updated with the generated
** record number.  This P2 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
case OP_NewRecno: {
  int i = pOp->p1;
  i64 v = 0;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pC = p->apCsr[i])->pCursor==0 ){
    /* The zero initialization above is all that is needed */
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
    ** to double the speed of the COPY operation.
    */
    int res, rx=SQLITE_OK, cnt;
    i64 x;
    cnt = 0;
    if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) !=
          BTREE_INTKEY ){
      rc = SQLITE_CORRUPT_BKPT;
      goto abort_due_to_error;
    }
    assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_INTKEY)!=0 );
    assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 );

#ifdef SQLITE_32BIT_ROWID
#   define MAX_ROWID 0x7fffffff
#else
    /* Some compilers complain about constants of the form 0x7fffffffffffffff.
    ** Others complain about 0x7ffffffffffffffffLL.  The following macro seems
    ** to provide the constant while making all compilers happy.
    */
#   define MAX_ROWID  ( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
#endif

    if( !pC->useRandomRowid ){
      if( pC->nextRowidValid ){
        v = pC->nextRowid;
      }else{
        rc = sqlite3BtreeLast(pC->pCursor, &res);
        if( rc!=SQLITE_OK ){
          goto abort_due_to_error;
        }
        if( res ){
          v = 1;
        }else{
          sqlite3BtreeKeySize(pC->pCursor, &v);
          v = keyToInt(v);
          if( v==MAX_ROWID ){
            pC->useRandomRowid = 1;
          }else{
            v++;
          }
        }
      }

#ifndef SQLITE_OMIT_AUTOINCREMENT
      if( pOp->p2 ){
        Mem *pMem;
        assert( pOp->p2>0 && pOp->p2<p->nMem );  /* P2 is a valid memory cell */
        pMem = &p->aMem[pOp->p2];
        sqlite3VdbeMemIntegerify(pMem);
        assert( (pMem->flags & MEM_Int)!=0 );  /* mem(P2) holds an integer */
        if( pMem->i==MAX_ROWID || pC->useRandomRowid ){
          rc = SQLITE_FULL;
          goto abort_due_to_error;
        }
        if( v<pMem->i+1 ){
          v = pMem->i + 1;







|



















|
<
<
<


















|







2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926



2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
    ** to double the speed of the COPY operation.
    */
    int res, rx=SQLITE_OK, cnt;
    i64 x;
    cnt = 0;
    if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) !=
          BTREE_INTKEY ){
      rc = SQLITE_CORRUPT;
      goto abort_due_to_error;
    }
    assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_INTKEY)!=0 );
    assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 );

#ifdef SQLITE_32BIT_ROWID
#   define MAX_ROWID 0x7fffffff
#else
    /* Some compilers complain about constants of the form 0x7fffffffffffffff.
    ** Others complain about 0x7ffffffffffffffffLL.  The following macro seems
    ** to provide the constant while making all compilers happy.
    */
#   define MAX_ROWID  ( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
#endif

    if( !pC->useRandomRowid ){
      if( pC->nextRowidValid ){
        v = pC->nextRowid;
      }else{
        rx = sqlite3BtreeLast(pC->pCursor, &res);



        if( res ){
          v = 1;
        }else{
          sqlite3BtreeKeySize(pC->pCursor, &v);
          v = keyToInt(v);
          if( v==MAX_ROWID ){
            pC->useRandomRowid = 1;
          }else{
            v++;
          }
        }
      }

#ifndef SQLITE_OMIT_AUTOINCREMENT
      if( pOp->p2 ){
        Mem *pMem;
        assert( pOp->p2>0 && pOp->p2<p->nMem );  /* P2 is a valid memory cell */
        pMem = &p->aMem[pOp->p2];
        Integerify(pMem);
        assert( (pMem->flags & MEM_Int)!=0 );  /* mem(P2) holds an integer */
        if( pMem->i==MAX_ROWID || pC->useRandomRowid ){
          rc = SQLITE_FULL;
          goto abort_due_to_error;
        }
        if( v<pMem->i+1 ){
          v = pMem->i + 1;
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274


3275




3276
3277

3278
3279

3280
3281
3282
3283
3284
3285
3286


3287
3288




3289
3290





3291






3292

3293
3294
3295
3296

3297
3298
3299
3300
3301
3302
3303
3304
3305





3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416

















3417
3418
3419
3420
3421
3422
3423
      }while( cnt<1000 && rx==SQLITE_OK && res==0 );
      db->priorNewRowid = v;
      if( rx==SQLITE_OK && res==0 ){
        rc = SQLITE_FULL;
        goto abort_due_to_error;
      }
    }
    pC->rowidIsValid = 0;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
  }
  pTos++;
  pTos->i = v;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: Insert P1 P2 P3
**
** Write an entry into the table of cursor P1.  A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten.  The data is the value on the top of the
** stack.  The key is the next value down on the stack.  The key must
** be an integer.  The stack is popped twice by this instruction.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).  If the OPFLAG_LASTROWID flag of P2 is set,
** then rowid is stored for subsequent return by the
** sqlite3_last_insert_rowid() function (otherwise it's unmodified).


**




** This instruction only works on tables.  The equivalent instruction
** for indices is OP_IdxInsert.

*/
case OP_Insert: {         /* no-push */

  Mem *pNos = &pTos[-1];
  int i = pOp->p1;
  Cursor *pC;
  assert( pNos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){


    i64 iKey;   /* The integer ROWID or key for the record to be inserted */





    assert( pNos->flags & MEM_Int );
    assert( pC->isTable );





    iKey = intToKey(pNos->i);








    if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
    if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
    if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
      pC->nextRowidValid = 0;

    }
    if( pTos->flags & MEM_Null ){
      pTos->z = 0;
      pTos->n = 0;
    }else{
      assert( pTos->flags & (MEM_Blob|MEM_Str) );
    }
#ifndef SQLITE_OMIT_TRIGGER
    if( pC->pseudoTable ){





      sqliteFree(pC->pData);
      pC->iKey = iKey;
      pC->nData = pTos->n;
      if( pTos->flags & MEM_Dyn ){
        pC->pData = pTos->z;
        pTos->flags = MEM_Null;
      }else{
        pC->pData = sqliteMallocRaw( pC->nData+2 );
        if( !pC->pData ) goto no_mem;
        memcpy(pC->pData, pTos->z, pC->nData);
        pC->pData[pC->nData] = 0;
        pC->pData[pC->nData+1] = 0;
      }
      pC->nullRow = 0;
    }else{
#endif
      rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pTos->z, pTos->n);
#ifndef SQLITE_OMIT_TRIGGER
    }
#endif
    
    pC->rowidIsValid = 0;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;

    /* Invoke the update-hook if required. */
    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p3 ){
      const char *zDb = db->aDb[pC->iDb].zName;
      const char *zTbl = pOp->p3;
      int op = ((pOp->p2 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
      assert( pC->isTable );
      db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
      assert( pC->iDb>=0 );
    }
  }
  popStack(&pTos, 2);

  break;
}

/* Opcode: Delete P1 P2 P3
**
** Delete the record at which the P1 cursor is currently pointing.
**
** The cursor will be left pointing at either the next or the previous
** record in the table. If it is left pointing at the next record, then
** the next Next instruction will be a no-op.  Hence it is OK to delete
** a record from within an Next loop.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).
**
** If P1 is a pseudo-table, then this instruction is a no-op.
*/
case OP_Delete: {        /* no-push */
  int i = pOp->p1;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( pC->pCursor!=0 ){
    i64 iKey;

    /* If the update-hook will be invoked, set iKey to the rowid of the
    ** row being deleted.
    */
    if( db->xUpdateCallback && pOp->p3 ){
      assert( pC->isTable );
      if( pC->rowidIsValid ){
        iKey = pC->lastRowid;
      }else{
        rc = sqlite3BtreeKeySize(pC->pCursor, &iKey);
        if( rc ){
          goto abort_due_to_error;
        }
        iKey = keyToInt(iKey);
      }
    }

    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    rc = sqlite3BtreeDelete(pC->pCursor);
    pC->nextRowidValid = 0;
    pC->cacheStatus = CACHE_STALE;

    /* Invoke the update-hook if required. */
    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p3 ){
      const char *zDb = db->aDb[pC->iDb].zName;
      const char *zTbl = pOp->p3;
      db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
      assert( pC->iDb>=0 );
    }
  }
  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
  break;
}

/* Opcode: ResetCount P1 * *
**
** This opcode resets the VMs internal change counter to 0. If P1 is true,
** then the value of the change counter is copied to the database handle
** change counter (returned by subsequent calls to sqlite3_changes())
** before it is reset. This is used by trigger programs.
*/
case OP_ResetCount: {        /* no-push */
  if( pOp->p1 ){
    sqlite3VdbeSetChanges(db, p->nChange);
  }
  p->nChange = 0;
  break;
}


















/* Opcode: RowData P1 * *
**
** Push onto the stack the complete row data for cursor P1.
** There is no interpretation of the data.  It is just copied
** onto the stack exactly as it is found in the database file.
**







|

|







|











>
>

>
>
>
>
|
|
>

|
>







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









>
>
>
>
>
















|




|

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

<



|













|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|
<
<
<
<
<
<
<
<












|






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







2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098










3099

3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123


















3124
3125
3126
3127
3128








3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
      }while( cnt<1000 && rx==SQLITE_OK && res==0 );
      db->priorNewRowid = v;
      if( rx==SQLITE_OK && res==0 ){
        rc = SQLITE_FULL;
        goto abort_due_to_error;
      }
    }
    pC->recnoIsValid = 0;
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
  }
  pTos++;
  pTos->i = v;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: PutIntKey P1 P2 *
**
** Write an entry into the table of cursor P1.  A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten.  The data is the value on the top of the
** stack.  The key is the next value down on the stack.  The key must
** be an integer.  The stack is popped twice by this instruction.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).  If the OPFLAG_LASTROWID flag of P2 is set,
** then rowid is stored for subsequent return by the
** sqlite3_last_insert_rowid() function (otherwise it's unmodified).
*/
/* Opcode: PutStrKey P1 * *
**
** Write an entry into the table of cursor P1.  A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten.  The data is the value on the top of the
** stack.  The key is the next value down on the stack.  The key must
** be a string.  The stack is popped twice by this instruction.
**
** P1 may not be a pseudo-table opened using the OpenPseudo opcode.
*/
case OP_PutIntKey:
case OP_PutStrKey: {
  Mem *pNos = &pTos[-1];
  int i = pOp->p1;
  Cursor *pC;
  assert( pNos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
    char *zKey;
    i64 nKey; 
    i64 iKey;
    if( pOp->opcode==OP_PutStrKey ){
      Stringify(pNos, db->enc);
      nKey = pNos->n;
      zKey = pNos->z;
    }else{
      assert( pNos->flags & MEM_Int );

      /* If the table is an INTKEY table, set nKey to the value of
      ** the integer key, and zKey to NULL. Otherwise, set nKey to
      ** sizeof(i64) and point zKey at iKey. iKey contains the integer
      ** key in the on-disk byte order.
      */
      iKey = intToKey(pNos->i);
      if( pC->intKey ){
        nKey = intToKey(pNos->i);
        zKey = 0;
      }else{
        nKey = sizeof(i64);
        zKey = (char*)&iKey;
      }

      if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
      if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
      if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
        pC->nextRowidValid = 0;
      }
    }
    if( pTos->flags & MEM_Null ){
      pTos->z = 0;
      pTos->n = 0;
    }else{
      assert( pTos->flags & (MEM_Blob|MEM_Str) );
    }
#ifndef SQLITE_OMIT_TRIGGER
    if( pC->pseudoTable ){
      /* PutStrKey does not work for pseudo-tables.
      ** The following assert makes sure we are not trying to use
      ** PutStrKey on a pseudo-table
      */
      assert( pOp->opcode==OP_PutIntKey );
      sqliteFree(pC->pData);
      pC->iKey = iKey;
      pC->nData = pTos->n;
      if( pTos->flags & MEM_Dyn ){
        pC->pData = pTos->z;
        pTos->flags = MEM_Null;
      }else{
        pC->pData = sqliteMallocRaw( pC->nData+2 );
        if( !pC->pData ) goto no_mem;
        memcpy(pC->pData, pTos->z, pC->nData);
        pC->pData[pC->nData] = 0;
        pC->pData[pC->nData+1] = 0;
      }
      pC->nullRow = 0;
    }else{
#endif
      rc = sqlite3BtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n);
#ifndef SQLITE_OMIT_TRIGGER
    }
#endif
    
    pC->recnoIsValid = 0;
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
  }










  popStack(&pTos, 2);

  break;
}

/* Opcode: Delete P1 P2 *
**
** Delete the record at which the P1 cursor is currently pointing.
**
** The cursor will be left pointing at either the next or the previous
** record in the table. If it is left pointing at the next record, then
** the next Next instruction will be a no-op.  Hence it is OK to delete
** a record from within an Next loop.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).
**
** If P1 is a pseudo-table, then this instruction is a no-op.
*/
case OP_Delete: {
  int i = pOp->p1;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( pC->pCursor!=0 ){


















    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    rc = sqlite3BtreeDelete(pC->pCursor);
    pC->nextRowidValid = 0;
    pC->cacheValid = 0;








  }
  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
  break;
}

/* Opcode: ResetCount P1 * *
**
** This opcode resets the VMs internal change counter to 0. If P1 is true,
** then the value of the change counter is copied to the database handle
** change counter (returned by subsequent calls to sqlite3_changes())
** before it is reset. This is used by trigger programs.
*/
case OP_ResetCount: {
  if( pOp->p1 ){
    sqlite3VdbeSetChanges(db, p->nChange);
  }
  p->nChange = 0;
  break;
}

/* Opcode: KeyAsData P1 P2 *
**
** Turn the key-as-data mode for cursor P1 either on (if P2==1) or
** off (if P2==0).  In key-as-data mode, the OP_Column opcode pulls
** data off of the key rather than the data.  This is used for
** processing compound selects.
*/
case OP_KeyAsData: {
  int i = pOp->p1;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  pC->keyAsData = pOp->p2;
  break;
}

/* Opcode: RowData P1 * *
**
** Push onto the stack the complete row data for cursor P1.
** There is no interpretation of the data.  It is just copied
** onto the stack exactly as it is found in the database file.
**
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498


3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526




















































3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
*/
case OP_RowKey:
case OP_RowData: {
  int i = pOp->p1;
  Cursor *pC;
  u32 n;

  /* Note that RowKey and RowData are really exactly the same instruction */
  pTos++;
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC->isTable || pOp->opcode==OP_RowKey );
  assert( pC->isIndex || pOp->opcode==OP_RowData );
  assert( pC!=0 );
  if( pC->nullRow ){
    pTos->flags = MEM_Null;
  }else if( pC->pCursor!=0 ){
    BtCursor *pCrsr = pC->pCursor;
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    if( pC->nullRow ){
      pTos->flags = MEM_Null;
      break;
    }else if( pC->isIndex ){
      i64 n64;
      assert( !pC->isTable );
      sqlite3BtreeKeySize(pCrsr, &n64);
      n = n64;
    }else{
      sqlite3BtreeDataSize(pCrsr, &n);
    }
    pTos->n = n;
    if( n<=NBFS ){
      pTos->flags = MEM_Blob | MEM_Short;
      pTos->z = pTos->zShort;
    }else{
      char *z = sqliteMallocRaw( n );
      if( z==0 ) goto no_mem;
      pTos->flags = MEM_Blob | MEM_Dyn;
      pTos->xDel = 0;
      pTos->z = z;
    }
    if( pC->isIndex ){
      sqlite3BtreeKey(pCrsr, 0, n, pTos->z);
    }else{
      sqlite3BtreeData(pCrsr, 0, n, pTos->z);
    }
#ifndef SQLITE_OMIT_TRIGGER
  }else if( pC->pseudoTable ){
    pTos->n = pC->nData;
    pTos->z = pC->pData;
    pTos->flags = MEM_Blob|MEM_Ephem;
#endif
  }else{
    pTos->flags = MEM_Null;
  }
  pTos->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
  break;
}

/* Opcode: Rowid P1 * *
**
** Push onto the stack an integer which is the key of the table entry that
** P1 is currently point to.


*/
case OP_Rowid: {
  int i = pOp->p1;
  Cursor *pC;
  i64 v;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc ) goto abort_due_to_error;
  pTos++;
  if( pC->rowidIsValid ){
    v = pC->lastRowid;
  }else if( pC->pseudoTable ){
    v = keyToInt(pC->iKey);
  }else if( pC->nullRow || pC->pCursor==0 ){
    pTos->flags = MEM_Null;
    break;
  }else{
    assert( pC->pCursor!=0 );
    sqlite3BtreeKeySize(pC->pCursor, &v);
    v = keyToInt(v);
  }
  pTos->i = v;
  pTos->flags = MEM_Int;
  break;
}





















































/* Opcode: NullRow P1 * *
**
** Move the cursor P1 to a null row.  Any OP_Column operations
** that occur while the cursor is on the null row will always push 
** a NULL onto the stack.
*/
case OP_NullRow: {        /* no-push */
  int i = pOp->p1;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  pC->nullRow = 1;
  pC->rowidIsValid = 0;
  break;
}

/* Opcode: Last P1 P2 *
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the last entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Last: {        /* no-push */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( (pCrsr = pC->pCursor)!=0 ){
    int res;
    rc = sqlite3BtreeLast(pCrsr, &res);
    pC->nullRow = res;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
    if( res && pOp->p2>0 ){
      pc = pOp->p2 - 1;
    }
  }else{
    pC->nullRow = 0;
  }
  break;
}


/* Opcode: Sort P1 P2 *
**
** This opcode does exactly the same thing as OP_Rewind except that
** it increments an undocumented global variable used for testing.
**
** Sorting is accomplished by writing records into a sorting index,
** then rewinding that index and playing it back from beginning to
** end.  We use the OP_Sort opcode instead of OP_Rewind to do the
** rewinding so that the global variable will be incremented and
** regression tests can determine whether or not the optimizer is
** correctly optimizing out sorts.
*/
case OP_Sort: {        /* no-push */
  sqlite3_sort_count++;
  sqlite3_search_count--;
  /* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 *
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Rewind: {        /* no-push */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  int res;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( (pCrsr = pC->pCursor)!=0 ){
    rc = sqlite3BtreeFirst(pCrsr, &res);
    pC->atFirst = res==0;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;
  }else{
    res = 1;
  }
  pC->nullRow = res;
  if( res && pOp->p2>0 ){
    pc = pOp->p2 - 1;
  }







<



<
<










|

|
















|













<



|

|
|
>
>

|










|
|














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







|







|





|





|












|









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|





|












|







3183
3184
3185
3186
3187
3188
3189

3190
3191
3192


3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235

3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374


















3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
*/
case OP_RowKey:
case OP_RowData: {
  int i = pOp->p1;
  Cursor *pC;
  u32 n;


  pTos++;
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];


  assert( pC!=0 );
  if( pC->nullRow ){
    pTos->flags = MEM_Null;
  }else if( pC->pCursor!=0 ){
    BtCursor *pCrsr = pC->pCursor;
    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    if( pC->nullRow ){
      pTos->flags = MEM_Null;
      break;
    }else if( pC->keyAsData || pOp->opcode==OP_RowKey ){
      i64 n64;
      assert( !pC->intKey );
      sqlite3BtreeKeySize(pCrsr, &n64);
      n = n64;
    }else{
      sqlite3BtreeDataSize(pCrsr, &n);
    }
    pTos->n = n;
    if( n<=NBFS ){
      pTos->flags = MEM_Blob | MEM_Short;
      pTos->z = pTos->zShort;
    }else{
      char *z = sqliteMallocRaw( n );
      if( z==0 ) goto no_mem;
      pTos->flags = MEM_Blob | MEM_Dyn;
      pTos->xDel = 0;
      pTos->z = z;
    }
    if( pC->keyAsData || pOp->opcode==OP_RowKey ){
      sqlite3BtreeKey(pCrsr, 0, n, pTos->z);
    }else{
      sqlite3BtreeData(pCrsr, 0, n, pTos->z);
    }
#ifndef SQLITE_OMIT_TRIGGER
  }else if( pC->pseudoTable ){
    pTos->n = pC->nData;
    pTos->z = pC->pData;
    pTos->flags = MEM_Blob|MEM_Ephem;
#endif
  }else{
    pTos->flags = MEM_Null;
  }

  break;
}

/* Opcode: Recno P1 * *
**
** Push onto the stack an integer which is the first 4 bytes of the
** the key to the current entry in a sequential scan of the database
** file P1.  The sequential scan should have been started using the 
** Next opcode.
*/
case OP_Recno: {
  int i = pOp->p1;
  Cursor *pC;
  i64 v;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  rc = sqlite3VdbeCursorMoveto(pC);
  if( rc ) goto abort_due_to_error;
  pTos++;
  if( pC->recnoIsValid ){
    v = pC->lastRecno;
  }else if( pC->pseudoTable ){
    v = keyToInt(pC->iKey);
  }else if( pC->nullRow || pC->pCursor==0 ){
    pTos->flags = MEM_Null;
    break;
  }else{
    assert( pC->pCursor!=0 );
    sqlite3BtreeKeySize(pC->pCursor, &v);
    v = keyToInt(v);
  }
  pTos->i = v;
  pTos->flags = MEM_Int;
  break;
}

#ifndef SQLITE_OMIT_COMPOUND_SELECT
/* Opcode: FullKey P1 * *
**
** Extract the complete key from the record that cursor P1 is currently
** pointing to and push the key onto the stack as a string.
**
** Compare this opcode to Recno.  The Recno opcode extracts the first
** 4 bytes of the key and pushes those bytes onto the stack as an
** integer.  This instruction pushes the entire key as a string.
**
** This opcode may not be used on a pseudo-table.
*/
case OP_FullKey: {
  int i = pOp->p1;
  BtCursor *pCrsr;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( p->apCsr[i]->keyAsData );
  assert( !p->apCsr[i]->pseudoTable );
  pTos++;
  pTos->flags = MEM_Null;
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    i64 amt;
    char *z;

    rc = sqlite3VdbeCursorMoveto(pC);
    if( rc ) goto abort_due_to_error;
    assert( pC->intKey==0 );
    sqlite3BtreeKeySize(pCrsr, &amt);
    if( amt<=0 ){
      rc = SQLITE_CORRUPT;
      goto abort_due_to_error;
    }
    if( amt>NBFS ){
      z = sqliteMallocRaw( amt );
      if( z==0 ) goto no_mem;
      pTos->flags = MEM_Blob | MEM_Dyn;
      pTos->xDel = 0;
    }else{
      z = pTos->zShort;
      pTos->flags = MEM_Blob | MEM_Short;
    }
    sqlite3BtreeKey(pCrsr, 0, amt, z);
    pTos->z = z;
    pTos->n = amt;
  }
  break;
}
#endif

/* Opcode: NullRow P1 * *
**
** Move the cursor P1 to a null row.  Any OP_Column operations
** that occur while the cursor is on the null row will always push 
** a NULL onto the stack.
*/
case OP_NullRow: {
  int i = pOp->p1;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  pC->nullRow = 1;
  pC->recnoIsValid = 0;
  break;
}

/* Opcode: Last P1 P2 *
**
** The next use of the Recno or Column or Next instruction for P1 
** will refer to the last entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Last: {
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( (pCrsr = pC->pCursor)!=0 ){
    int res;
    rc = sqlite3BtreeLast(pCrsr, &res);
    pC->nullRow = res;
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
    if( res && pOp->p2>0 ){
      pc = pOp->p2 - 1;
    }
  }else{
    pC->nullRow = 0;
  }
  break;
}



















/* Opcode: Rewind P1 P2 *
**
** The next use of the Recno or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Rewind: {
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  int res;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
  if( (pCrsr = pC->pCursor)!=0 ){
    rc = sqlite3BtreeFirst(pCrsr, &res);
    pC->atFirst = res==0;
    pC->deferredMoveto = 0;
    pC->cacheValid = 0;
  }else{
    res = 1;
  }
  pC->nullRow = res;
  if( res && pOp->p2>0 ){
    pc = pOp->p2 - 1;
  }
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681


3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694


























3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
/* Opcode: Prev P1 P2 *
**
** Back up cursor P1 so that it points to the previous key/data pair in its
** table or index.  If there is no previous key/value pairs then fall through
** to the following instruction.  But if the cursor backup was successful,
** jump immediately to P2.
*/
case OP_Prev:          /* no-push */
case OP_Next: {        /* no-push */
  Cursor *pC;
  BtCursor *pCrsr;

  CHECK_FOR_INTERRUPT;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  if( (pCrsr = pC->pCursor)!=0 ){
    int res;
    if( pC->nullRow ){
      res = 1;
    }else{
      assert( pC->deferredMoveto==0 );
      rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
                                  sqlite3BtreePrevious(pCrsr, &res);
      pC->nullRow = res;
      pC->cacheStatus = CACHE_STALE;
    }
    if( res==0 ){
      pc = pOp->p2 - 1;
      sqlite3_search_count++;
    }
  }else{
    pC->nullRow = 1;
  }
  pC->rowidIsValid = 0;
  break;
}

/* Opcode: IdxInsert P1 * *
**
** The top of the stack holds a SQL index key made using either the
** MakeIdxRec or MakeRecord instructions.  This opcode writes that key
** into the index P1.  Data for the entry is nil.
**
** This instruction only works for indices.  The equivalent instruction
** for tables is OP_Insert.


*/
case OP_IdxInsert: {        /* no-push */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( pTos->flags & MEM_Blob );
  assert( pOp->p2==0 );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int nKey = pTos->n;
    const char *zKey = pTos->z;


























    assert( pC->isTable==0 );
    rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
    assert( pC->deferredMoveto==0 );
    pC->cacheStatus = CACHE_STALE;
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: IdxDelete P1 * *
**
** The top of the stack is an index key built using the either the
** MakeIdxRec or MakeRecord opcodes.
** This opcode removes that entry from the index.
*/
case OP_IdxDelete: {        /* no-push */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  assert( pTos>=p->aStack );
  assert( pTos->flags & MEM_Blob );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int rx, res;
    rx = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
    if( rx==SQLITE_OK && res==0 ){
      rc = sqlite3BtreeDelete(pCrsr);
    }
    assert( pC->deferredMoveto==0 );
    pC->cacheStatus = CACHE_STALE;
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: IdxRowid P1 * *
**
** Push onto the stack an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1.  This integer should be
** the rowid of the table entry to which this index entry points.
**
** See also: Rowid, MakeIdxRec.
*/
case OP_IdxRowid: {
  int i = pOp->p1;
  BtCursor *pCrsr;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  pTos++;
  pTos->flags = MEM_Null;
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    i64 rowid;

    assert( pC->deferredMoveto==0 );
    assert( pC->isTable==0 );
    if( pC->nullRow ){
      pTos->flags = MEM_Null;
    }else{
      rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }







|
|
















|








|



|

|
|
|

|
|
>
>

|







<



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


|








|
<


|














|






|

|
|
|

|

|












|







3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472

3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514

3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
/* Opcode: Prev P1 P2 *
**
** Back up cursor P1 so that it points to the previous key/data pair in its
** table or index.  If there is no previous key/value pairs then fall through
** to the following instruction.  But if the cursor backup was successful,
** jump immediately to P2.
*/
case OP_Prev:
case OP_Next: {
  Cursor *pC;
  BtCursor *pCrsr;

  CHECK_FOR_INTERRUPT;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  if( (pCrsr = pC->pCursor)!=0 ){
    int res;
    if( pC->nullRow ){
      res = 1;
    }else{
      assert( pC->deferredMoveto==0 );
      rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
                                  sqlite3BtreePrevious(pCrsr, &res);
      pC->nullRow = res;
      pC->cacheValid = 0;
    }
    if( res==0 ){
      pc = pOp->p2 - 1;
      sqlite3_search_count++;
    }
  }else{
    pC->nullRow = 1;
  }
  pC->recnoIsValid = 0;
  break;
}

/* Opcode: IdxPut P1 P2 P3
**
** The top of the stack holds a SQL index key made using the
** MakeIdxKey instruction.  This opcode writes that key into the
** index P1.  Data for the entry is nil.
**
** If P2==1, then the key must be unique.  If the key is not unique,
** the program aborts with a SQLITE_CONSTRAINT error and the database
** is rolled back.  If P3 is not null, then it becomes part of the
** error message returned with the SQLITE_CONSTRAINT.
*/
case OP_IdxPut: {
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( pTos->flags & MEM_Blob );

  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int nKey = pTos->n;
    const char *zKey = pTos->z;
    if( pOp->p2 ){
      int res;
      int len;
   
      /* 'len' is the length of the key minus the rowid at the end */
      len = nKey - sqlite3VdbeIdxRowidLen(nKey, zKey);

      rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
      while( res!=0 && !sqlite3BtreeEof(pCrsr) ){
        int c;
        if( sqlite3VdbeIdxKeyCompare(pC, len, zKey, &c)==SQLITE_OK && c==0 ){
          rc = SQLITE_CONSTRAINT;
          if( pOp->p3 && pOp->p3[0] ){
            sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
          }
          goto abort_due_to_error;
        }
        if( res<0 ){
          sqlite3BtreeNext(pCrsr, &res);
          res = +1;
        }else{
          break;
        }
      }
    }
    assert( pC->intKey==0 );
    rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
    assert( pC->deferredMoveto==0 );
    pC->cacheValid = 0;
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: IdxDelete P1 * *
**
** The top of the stack is an index key built using the MakeIdxKey opcode.

** This opcode removes that entry from the index.
*/
case OP_IdxDelete: {
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  assert( pTos>=p->aStack );
  assert( pTos->flags & MEM_Blob );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int rx, res;
    rx = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
    if( rx==SQLITE_OK && res==0 ){
      rc = sqlite3BtreeDelete(pCrsr);
    }
    assert( pC->deferredMoveto==0 );
    pC->cacheValid = 0;
  }
  Release(pTos);
  pTos--;
  break;
}

/* Opcode: IdxRecno P1 * *
**
** Push onto the stack an integer which is the varint located at the
** end of the index key pointed to by cursor P1.  This integer should be
** the record number of the table entry to which this index entry points.
**
** See also: Recno, MakeIdxKey.
*/
case OP_IdxRecno: {
  int i = pOp->p1;
  BtCursor *pCrsr;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  pTos++;
  pTos->flags = MEM_Null;
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    i64 rowid;

    assert( pC->deferredMoveto==0 );
    assert( pC->intKey==0 );
    if( pC->nullRow ){
      pTos->flags = MEM_Null;
    }else{
      rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816

3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
** In either case, the stack is popped once.
**
** If P3 is the "+" string (or any other non-NULL string) then the
** index taken from the top of the stack is temporarily increased by
** an epsilon prior to the comparison.  This makes the opcode work
** like IdxLE.
*/
case OP_IdxLT:          /* no-push */
case OP_IdxGT:          /* no-push */
case OP_IdxGE: {        /* no-push */
  int i= pOp->p1;

  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( pTos>=p->aStack );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
    int res, rc;
 
    assert( pTos->flags & MEM_Blob );  /* Created using OP_Make*Key */
    Stringify(pTos, encoding);
    assert( pC->deferredMoveto==0 );
    *pC->pIncrKey = pOp->p3!=0;
    assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT );
    rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, (u8*)pTos->z, &res);
    *pC->pIncrKey = 0;
    if( rc!=SQLITE_OK ){
      break;
    }
    if( pOp->opcode==OP_IdxLT ){
      res = -res;
    }else if( pOp->opcode==OP_IdxGE ){







|
|
|

>





|



|



|







3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
** In either case, the stack is popped once.
**
** If P3 is the "+" string (or any other non-NULL string) then the
** index taken from the top of the stack is temporarily increased by
** an epsilon prior to the comparison.  This makes the opcode work
** like IdxLE.
*/
case OP_IdxLT:
case OP_IdxGT:
case OP_IdxGE: {
  int i= pOp->p1;
  BtCursor *pCrsr;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( pTos>=p->aStack );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    int res, rc;
 
    assert( pTos->flags & MEM_Blob );  /* Created using OP_Make*Key */
    Stringify(pTos, db->enc);
    assert( pC->deferredMoveto==0 );
    *pC->pIncrKey = pOp->p3!=0;
    assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT );
    rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, pTos->z, &res);
    *pC->pIncrKey = 0;
    if( rc!=SQLITE_OK ){
      break;
    }
    if( pOp->opcode==OP_IdxLT ){
      res = -res;
    }else if( pOp->opcode==OP_IdxGE ){
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
  pTos--;
  break;
}

/* Opcode: IdxIsNull P1 P2 *
**
** The top of the stack contains an index entry such as might be generated
** by the MakeIdxRec opcode.  This routine looks at the first P1 fields of
** that key.  If any of the first P1 fields are NULL, then a jump is made
** to address P2.  Otherwise we fall straight through.
**
** The index entry is always popped from the stack.
*/
case OP_IdxIsNull: {        /* no-push */
  int i = pOp->p1;
  int k, n;
  const char *z;
  u32 serial_type;

  assert( pTos>=p->aStack );
  assert( pTos->flags & MEM_Blob );
  z = pTos->z;
  n = pTos->n;
  k = sqlite3GetVarint32((u8*)z, &serial_type);
  for(; k<n && i>0; i--){
    k += sqlite3GetVarint32((u8*)&z[k], &serial_type);
    if( serial_type==0 ){   /* Serial type 0 is a NULL */
      pc = pOp->p2-1;
      break;
    }
  }
  Release(pTos);
  pTos--;







|





|









|

|







3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
  pTos--;
  break;
}

/* Opcode: IdxIsNull P1 P2 *
**
** The top of the stack contains an index entry such as might be generated
** by the MakeIdxKey opcode.  This routine looks at the first P1 fields of
** that key.  If any of the first P1 fields are NULL, then a jump is made
** to address P2.  Otherwise we fall straight through.
**
** The index entry is always popped from the stack.
*/
case OP_IdxIsNull: {
  int i = pOp->p1;
  int k, n;
  const char *z;
  u32 serial_type;

  assert( pTos>=p->aStack );
  assert( pTos->flags & MEM_Blob );
  z = pTos->z;
  n = pTos->n;
  k = sqlite3GetVarint32(z, &serial_type);
  for(; k<n && i>0; i--){
    k += sqlite3GetVarint32(&z[k], &serial_type);
    if( serial_type==0 ){   /* Serial type 0 is a NULL */
      pc = pOp->p2-1;
      break;
    }
  }
  Release(pTos);
  pTos--;
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
**
** The table being clear is in the main database file if P2==0.  If
** P2==1 then the table to be clear is in the auxiliary database file
** that is used to store tables create using CREATE TEMPORARY TABLE.
**
** See also: Destroy
*/
case OP_Clear: {        /* no-push */

  /* For consistency with the way other features of SQLite operate
  ** with a truncate, we will also skip the update callback.
  */
#if 0
  Btree *pBt = db->aDb[pOp->p2].pBt;
  if( db->xUpdateCallback && pOp->p3 ){
    const char *zDb = db->aDb[pOp->p2].zName;
    const char *zTbl = pOp->p3;
    BtCursor *pCur = 0;
    int fin = 0;

    rc = sqlite3BtreeCursor(pBt, pOp->p1, 0, 0, 0, &pCur);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
    for(
      rc=sqlite3BtreeFirst(pCur, &fin); 
      rc==SQLITE_OK && !fin; 
      rc=sqlite3BtreeNext(pCur, &fin)
    ){
      i64 iKey;
      rc = sqlite3BtreeKeySize(pCur, &iKey);
      if( rc ){
        break;
      }
      iKey = keyToInt(iKey);
      db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
    }
    sqlite3BtreeCloseCursor(pCur);
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }
  }
#endif
  rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
  break;
}

/* Opcode: CreateTable P1 * *
**
** Allocate a new table in the main database file if P2==0 or in the







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







3732
3733
3734
3735
3736
3737
3738
3739



































3740
3741
3742
3743
3744
3745
3746
**
** The table being clear is in the main database file if P2==0.  If
** P2==1 then the table to be clear is in the auxiliary database file
** that is used to store tables create using CREATE TEMPORARY TABLE.
**
** See also: Destroy
*/
case OP_Clear: {



































  rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
  break;
}

/* Opcode: CreateTable P1 * *
**
** Allocate a new table in the main database file if P2==0 or in the
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
** that match the WHERE clause P3.
**
** This opcode invokes the parser to create a new virtual machine,
** then runs the new virtual machine.  It is thus a reentrant opcode.
*/
case OP_ParseSchema: {        /* no-push */
  char *zSql;
  int iDb = pOp->p1;
  const char *zMaster;
  InitData initData;

  assert( iDb>=0 && iDb<db->nDb );
  if( !DbHasProperty(db, iDb, DB_SchemaLoaded) ) break;
  zMaster = SCHEMA_TABLE(iDb);
  initData.db = db;
  initData.pzErrMsg = &p->zErrMsg;
  zSql = sqlite3MPrintf(
     "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
     pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
  if( zSql==0 ) goto no_mem;
  sqlite3SafetyOff(db);
  assert( db->init.busy==0 );
  db->init.busy = 1;
  assert(0==pTsd->mallocFailed);
  rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
  sqliteFree(zSql);
  db->init.busy = 0;
  sqlite3SafetyOn(db);
  if( rc==SQLITE_NOMEM ){
    pTsd->mallocFailed = 1;
    goto no_mem;
  }
  break;  
}

#ifndef SQLITE_OMIT_ANALYZE
/* Opcode: LoadAnalysis P1 * *
**
** Read the sqlite_stat1 table for database P1 and load the content
** of that table into the internal index hash table.  This will cause
** the analysis to be used when preparing all subsequent queries.
*/
case OP_LoadAnalysis: {        /* no-push */
  int iDb = pOp->p1;
  assert( iDb>=0 && iDb<db->nDb );
  sqlite3AnalysisLoad(db, iDb);
  break;  
}
#endif /* SQLITE_OMIT_ANALYZE */

/* Opcode: DropTable P1 * P3
**
** Remove the internal (in-memory) data structures that describe
** the table named P3 in database P1.  This is called after a table
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropTable: {        /* no-push */
  sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p3);
  break;
}

/* Opcode: DropIndex P1 * P3
**
** Remove the internal (in-memory) data structures that describe
** the index named P3 in database P1.  This is called after an index
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropIndex: {        /* no-push */
  sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p3);
  break;
}

/* Opcode: DropTrigger P1 * P3
**
** Remove the internal (in-memory) data structures that describe
** the trigger named P3 in database P1.  This is called after a trigger
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropTrigger: {        /* no-push */
  sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p3);
  break;
}


#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/* Opcode: IntegrityCk * P2 *







|







|









<

<


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


<








|











|











|







3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814

3815

3816
3817






3818











3819
3820

3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
** that match the WHERE clause P3.
**
** This opcode invokes the parser to create a new virtual machine,
** then runs the new virtual machine.  It is thus a reentrant opcode.
*/
case OP_ParseSchema: {
  char *zSql;
  int iDb = pOp->p1;
  const char *zMaster;
  InitData initData;

  assert( iDb>=0 && iDb<db->nDb );
  if( !DbHasProperty(db, iDb, DB_SchemaLoaded) ) break;
  zMaster = iDb==1 ? TEMP_MASTER_NAME : MASTER_NAME;
  initData.db = db;
  initData.pzErrMsg = &p->zErrMsg;
  zSql = sqlite3MPrintf(
     "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
     pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
  if( zSql==0 ) goto no_mem;
  sqlite3SafetyOff(db);
  assert( db->init.busy==0 );
  db->init.busy = 1;

  rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);

  db->init.busy = 0;
  sqlite3SafetyOn(db);






  sqliteFree(zSql);











  break;  
}


/* Opcode: DropTable P1 * P3
**
** Remove the internal (in-memory) data structures that describe
** the table named P3 in database P1.  This is called after a table
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropTable: {
  sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p3);
  break;
}

/* Opcode: DropIndex P1 * P3
**
** Remove the internal (in-memory) data structures that describe
** the index named P3 in database P1.  This is called after an index
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropIndex: {
  sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p3);
  break;
}

/* Opcode: DropTrigger P1 * P3
**
** Remove the internal (in-memory) data structures that describe
** the trigger named P3 in database P1.  This is called after a trigger
** is dropped in order to keep the internal representation of the
** schema consistent with what is on disk.
*/
case OP_DropTrigger: {
  sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p3);
  break;
}


#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/* Opcode: IntegrityCk * P2 *
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166

4167










4168
4169
4170
4171
4172
4173
4174
4175
4176




















4177
4178
4179
4180
4181
4182

4183
4184
4185

4186


4187
4188
4189


















4190
4191
4192

























4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235

































































































4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
  }else{
    pTos->z = z;
    pTos->n = strlen(z);
    pTos->flags = MEM_Str | MEM_Dyn | MEM_Term;
    pTos->xDel = 0;
  }
  pTos->enc = SQLITE_UTF8;
  sqlite3VdbeChangeEncoding(pTos, encoding);
  sqliteFree(aRoot);
  break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

/* Opcode: FifoWrite * * *
**
** Write the integer on the top of the stack
** into the Fifo.
*/
case OP_FifoWrite: {        /* no-push */

  assert( pTos>=p->aStack );










  sqlite3VdbeMemIntegerify(pTos);
  sqlite3VdbeFifoPush(&p->sFifo, pTos->i);
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  break;
}

/* Opcode: FifoRead * P2 *
**




















** Attempt to read a single integer from the Fifo
** and push it onto the stack.  If the Fifo is empty
** push nothing but instead jump to P2.
*/
case OP_FifoRead: {
  i64 v;

  CHECK_FOR_INTERRUPT;
  if( sqlite3VdbeFifoPop(&p->sFifo, &v)==SQLITE_DONE ){
    pc = pOp->p2 - 1;

  }else{


    pTos++;
    pTos->i = v;
    pTos->flags = MEM_Int;


















  }
  break;
}


























#ifndef SQLITE_OMIT_TRIGGER
/* Opcode: ContextPush * * * 
**
** Save the current Vdbe context such that it can be restored by a ContextPop
** opcode. The context stores the last insert row id, the last statement change
** count, and the current statement change count.
*/
case OP_ContextPush: {        /* no-push */
  int i = p->contextStackTop++;
  Context *pContext;

  assert( i>=0 );
  /* FIX ME: This should be allocated as part of the vdbe at compile-time */
  if( i>=p->contextStackDepth ){
    p->contextStackDepth = i+1;
    sqliteReallocOrFree((void**)&p->contextStack, sizeof(Context)*(i+1));
    if( p->contextStack==0 ) goto no_mem;
  }
  pContext = &p->contextStack[i];
  pContext->lastRowid = db->lastRowid;
  pContext->nChange = p->nChange;
  pContext->sFifo = p->sFifo;
  sqlite3VdbeFifoInit(&p->sFifo);
  break;
}

/* Opcode: ContextPop * * * 
**
** Restore the Vdbe context to the state it was in when contextPush was last
** executed. The context stores the last insert row id, the last statement
** change count, and the current statement change count.
*/
case OP_ContextPop: {        /* no-push */
  Context *pContext = &p->contextStack[--p->contextStackTop];
  assert( p->contextStackTop>=0 );
  db->lastRowid = pContext->lastRowid;
  p->nChange = pContext->nChange;
  sqlite3VdbeFifoClear(&p->sFifo);
  p->sFifo = pContext->sFifo;
  break;
}
#endif /* #ifndef SQLITE_OMIT_TRIGGER */


































































































/* Opcode: MemStore P1 P2 *
**
** Write the top of the stack into memory location P1.
** P1 should be a small integer since space is allocated
** for all memory locations between 0 and P1 inclusive.
**
** After the data is stored in the memory location, the
** stack is popped once if P2 is 1.  If P2 is zero, then
** the original data remains on the stack.
*/
case OP_MemStore: {        /* no-push */
  assert( pTos>=p->aStack );
  assert( pOp->p1>=0 && pOp->p1<p->nMem );
  rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], pTos);
  pTos--;

  /* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will
  ** restore the top of the stack to its original value.







|





|


|

|
>

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





|

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


|
<
>

<
|
>
|
>
>

|

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



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








|







|





|
|









|




|
|



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











|







3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964

3965
3966

3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
  }else{
    pTos->z = z;
    pTos->n = strlen(z);
    pTos->flags = MEM_Str | MEM_Dyn | MEM_Term;
    pTos->xDel = 0;
  }
  pTos->enc = SQLITE_UTF8;
  sqlite3VdbeChangeEncoding(pTos, db->enc);
  sqliteFree(aRoot);
  break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

/* Opcode: ListWrite * * *
**
** Write the integer on the top of the stack
** into the temporary storage list.
*/
case OP_ListWrite: {
  Keylist *pKeylist;
  assert( pTos>=p->aStack );
  pKeylist = p->pList;
  if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){
    pKeylist = sqliteMallocRaw( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) );
    if( pKeylist==0 ) goto no_mem;
    pKeylist->nKey = 1000;
    pKeylist->nRead = 0;
    pKeylist->nUsed = 0;
    pKeylist->pNext = p->pList;
    p->pList = pKeylist;
  }
  Integerify(pTos);
  pKeylist->aKey[pKeylist->nUsed++] = pTos->i;
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  break;
}

/* Opcode: ListRewind * * *
**
** Rewind the temporary buffer back to the beginning.
*/
case OP_ListRewind: {
  /* What this opcode codes, really, is reverse the order of the
  ** linked list of Keylist structures so that they are read out
  ** in the same order that they were read in. */
  Keylist *pRev, *pTop;
  pRev = 0;
  while( p->pList ){
    pTop = p->pList;
    p->pList = pTop->pNext;
    pTop->pNext = pRev;
    pRev = pTop;
  }
  p->pList = pRev;
  break;
}

/* Opcode: ListRead * P2 *
**
** Attempt to read an integer from the temporary storage buffer
** and push it onto the stack.  If the storage buffer is empty, 
** push nothing but instead jump to P2.
*/
case OP_ListRead: {

  Keylist *pKeylist;
  CHECK_FOR_INTERRUPT;

  pKeylist = p->pList;
  if( pKeylist!=0 ){
    assert( pKeylist->nRead>=0 );
    assert( pKeylist->nRead<pKeylist->nUsed );
    assert( pKeylist->nRead<pKeylist->nKey );
    pTos++;
    pTos->i = pKeylist->aKey[pKeylist->nRead++];
    pTos->flags = MEM_Int;
    if( pKeylist->nRead>=pKeylist->nUsed ){
      p->pList = pKeylist->pNext;
      sqliteFree(pKeylist);
    }
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: ListReset * * *
**
** Reset the temporary storage buffer so that it holds nothing.
*/
case OP_ListReset: {
  if( p->pList ){
    sqlite3VdbeKeylistFree(p->pList);
    p->pList = 0;
  }
  break;
}

#ifndef SQLITE_OMIT_SUBQUERY
/* Opcode: AggContextPush * * * 
**
** Save the state of the current aggregator. It is restored an 
** AggContextPop opcode.
** 
*/
case OP_AggContextPush: {
  p->pAgg++;
  assert( p->pAgg<&p->apAgg[p->nAgg] );
  break;
}

/* Opcode: AggContextPop * * *
**
** Restore the aggregator to the state it was in when AggContextPush
** was last called. Any data in the current aggregator is deleted.
*/
case OP_AggContextPop: {
  p->pAgg--;
  assert( p->pAgg>=p->apAgg );
  break;
}
#endif

#ifndef SQLITE_OMIT_TRIGGER
/* Opcode: ContextPush * * * 
**
** Save the current Vdbe context such that it can be restored by a ContextPop
** opcode. The context stores the last insert row id, the last statement change
** count, and the current statement change count.
*/
case OP_ContextPush: {
  int i = p->contextStackTop++;
  Context *pContext;

  assert( i>=0 );
  /* FIX ME: This should be allocated as part of the vdbe at compile-time */
  if( i>=p->contextStackDepth ){
    p->contextStackDepth = i+1;
    p->contextStack = sqliteRealloc(p->contextStack, sizeof(Context)*(i+1));
    if( p->contextStack==0 ) goto no_mem;
  }
  pContext = &p->contextStack[i];
  pContext->lastRowid = db->lastRowid;
  pContext->nChange = p->nChange;
  pContext->pList = p->pList;
  p->pList = 0;
  break;
}

/* Opcode: ContextPop * * * 
**
** Restore the Vdbe context to the state it was in when contextPush was last
** executed. The context stores the last insert row id, the last statement
** change count, and the current statement change count.
*/
case OP_ContextPop: {
  Context *pContext = &p->contextStack[--p->contextStackTop];
  assert( p->contextStackTop>=0 );
  db->lastRowid = pContext->lastRowid;
  p->nChange = pContext->nChange;
  sqlite3VdbeKeylistFree(p->pList);
  p->pList = pContext->pList;
  break;
}
#endif /* #ifndef SQLITE_OMIT_TRIGGER */

/* Opcode: SortPut * * *
**
** The TOS is the key and the NOS is the data.  Pop both from the stack
** and put them on the sorter.  The key and data should have been
** made using the MakeRecord opcode.
*/
case OP_SortPut: {
  Mem *pNos = &pTos[-1];
  Sorter *pSorter;
  assert( pNos>=p->aStack );
  if( Dynamicify(pTos, db->enc) ) goto no_mem;
  pSorter = sqliteMallocRaw( sizeof(Sorter) );
  if( pSorter==0 ) goto no_mem;
  pSorter->pNext = p->pSort;
  p->pSort = pSorter;
  assert( pTos->flags & MEM_Dyn );
  pSorter->nKey = pTos->n;
  pSorter->zKey = pTos->z;
  pSorter->data.flags = MEM_Null;
  rc = sqlite3VdbeMemMove(&pSorter->data, pNos);
  pTos -= 2;
  break;
}

/* Opcode: Sort * * P3
**
** Sort all elements on the sorter.  The algorithm is a
** mergesort.  The P3 argument is a pointer to a KeyInfo structure
** that describes the keys to be sorted.
*/
case OP_Sort: {
  int i;
  KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3;
  Sorter *pElem;
  Sorter *apSorter[NSORT];
  sqlite3_sort_count++;
  pKeyInfo->enc = p->db->enc;
  for(i=0; i<NSORT; i++){
    apSorter[i] = 0;
  }
  while( p->pSort ){
    pElem = p->pSort;
    p->pSort = pElem->pNext;
    pElem->pNext = 0;
    for(i=0; i<NSORT-1; i++){
      if( apSorter[i]==0 ){
        apSorter[i] = pElem;
        break;
      }else{
        pElem = Merge(apSorter[i], pElem, pKeyInfo);
        apSorter[i] = 0;
      }
    }
    if( i>=NSORT-1 ){
      apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem, pKeyInfo);
    }
  }
  pElem = 0;
  for(i=0; i<NSORT; i++){
    pElem = Merge(apSorter[i], pElem, pKeyInfo);
  }
  p->pSort = pElem;
  break;
}

/* Opcode: SortNext * P2 *
**
** Push the data for the topmost element in the sorter onto the
** stack, then remove the element from the sorter.  If the sorter
** is empty, push nothing on the stack and instead jump immediately 
** to instruction P2.
*/
case OP_SortNext: {
  Sorter *pSorter = p->pSort;
  CHECK_FOR_INTERRUPT;
  if( pSorter!=0 ){
    p->pSort = pSorter->pNext;
    pTos++;
    pTos->flags = MEM_Null;
    rc = sqlite3VdbeMemMove(pTos, &pSorter->data);
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter);
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: SortReset * * *
**
** Remove any elements that remain on the sorter.
*/
case OP_SortReset: {
  sqlite3VdbeSorterReset(p);
  break;
}

/* Opcode: MemStore P1 P2 *
**
** Write the top of the stack into memory location P1.
** P1 should be a small integer since space is allocated
** for all memory locations between 0 and P1 inclusive.
**
** After the data is stored in the memory location, the
** stack is popped once if P2 is 1.  If P2 is zero, then
** the original data remains on the stack.
*/
case OP_MemStore: {
  assert( pTos>=p->aStack );
  assert( pOp->p1>=0 && pOp->p1<p->nMem );
  rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], pTos);
  pTos--;

  /* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will
  ** restore the top of the stack to its original value.
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303


4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314



4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339


4340

4341
4342

4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369

4370
4371
4372


4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414



4415
4416
4417
4418
4419
4420
4421
4422
4423
4424

4425
4426

4427
4428

4429
4430
4431
4432


4433
4434

4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445


4446
4447
4448
4449
4450
4451
4452
4453
4454

4455
4456


4457
4458
4459

































4460
4461





4462










4463











4464
4465
4466
4467
4468
4469

















4470



4471
4472
4473


































































4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541



4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578



4579
4580
4581
4582
4583
4584
4585
**
** Set the value of memory cell P1 to the maximum of its current value
** and the value on the top of the stack.  The stack is unchanged.
**
** This instruction throws an error if the memory cell is not initially
** an integer.
*/
case OP_MemMax: {        /* no-push */
  int i = pOp->p1;
  Mem *pMem;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  sqlite3VdbeMemIntegerify(pMem);
  sqlite3VdbeMemIntegerify(pTos);
  if( pMem->i<pTos->i){
    pMem->i = pTos->i;
  }
  break;
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */

/* Opcode: MemIncr P1 P2 *
**
** Increment the integer valued memory cell P2 by the value in P1.


**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_MemIncr: {        /* no-push */
  int i = pOp->p2;
  Mem *pMem;
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  pMem->i += pOp->p1;



  break;
}

/* Opcode: IfMemPos P1 P2 *
**
** If the value of memory cell P1 is 1 or greater, jump to P2.
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemPos: {        /* no-push */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->i>0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfMemNeg P1 P2 *
**
** If the value of memory cell P1 is less than zero, jump to P2. 


**

** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.

*/
case OP_IfMemNeg: {        /* no-push */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->i<0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfMemZero P1 P2 *
**
** If the value of memory cell P1 is exactly 0, jump to P2. 
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemZero: {        /* no-push */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->i==0 ){

     pc = pOp->p2 - 1;
  }
  break;


}

/* Opcode: MemNull P1 * *
**
** Store a NULL in memory cell P1
*/
case OP_MemNull: {
  assert( pOp->p1>=0 && pOp->p1<p->nMem );
  sqlite3VdbeMemSetNull(&p->aMem[pOp->p1]);
  break;
}

/* Opcode: MemInt P1 P2 *
**
** Store the integer value P1 in memory cell P2.
*/
case OP_MemInt: {
  assert( pOp->p2>=0 && pOp->p2<p->nMem );
  sqlite3VdbeMemSetInt64(&p->aMem[pOp->p2], pOp->p1);
  break;
}

/* Opcode: MemMove P1 P2 *
**
** Move the content of memory cell P2 over to memory cell P1.
** Any prior content of P1 is erased.  Memory cell P2 is left
** containing a NULL.
*/
case OP_MemMove: {
  assert( pOp->p1>=0 && pOp->p1<p->nMem );
  assert( pOp->p2>=0 && pOp->p2<p->nMem );
  rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], &p->aMem[pOp->p2]);
  break;
}

/* Opcode: AggStep P1 P2 P3
**
** Execute the step function for an aggregate.  The
** function has P2 arguments.  P3 is a pointer to the FuncDef
** structure that specifies the function.  Use memory location
** P1 as the accumulator.
**



** The P2 arguments are popped from the stack.
*/
case OP_AggStep: {        /* no-push */
  int n = pOp->p2;
  int i;
  Mem *pMem, *pRec;
  sqlite3_context ctx;
  sqlite3_value **apVal;

  assert( n>=0 );

  pRec = &pTos[1-n];
  assert( pRec>=p->aStack );

  apVal = p->apArg;
  assert( apVal || n==0 );

  for(i=0; i<n; i++, pRec++){
    apVal[i] = pRec;
    storeTypeInfo(pRec, encoding);
  }


  ctx.pFunc = (FuncDef*)pOp->p3;
  assert( pOp->p1>=0 && pOp->p1<p->nMem );

  ctx.pMem = pMem = &p->aMem[pOp->p1];
  pMem->n++;
  ctx.isError = 0;
  ctx.pColl = 0;
  if( ctx.pFunc->needCollSeq ){
    assert( pOp>p->aOp );
    assert( pOp[-1].p3type==P3_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = (CollSeq *)pOp[-1].p3;
  }
  (ctx.pFunc->xStep)(&ctx, n, apVal);


  popStack(&pTos, n);
  if( ctx.isError ){
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: AggFinal P1 P2 P3
**

** Execute the finalizer function for an aggregate.  P1 is
** the memory location that is the accumulator for the aggregate.


**
** P2 is the number of arguments that the step function takes and
** P3 is a pointer to the FuncDef for this function.  The P2

































** argument is not used by this opcode.  It is only there to disambiguate
** functions that can take varying numbers of arguments.  The





** P3 argument is only needed for the degenerate case where










** the step function was not previously called.











*/
case OP_AggFinal: {        /* no-push */
  Mem *pMem;
  assert( pOp->p1>=0 && pOp->p1<p->nMem );
  pMem = &p->aMem[pOp->p1];
  assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );

















  sqlite3VdbeMemFinalize(pMem, (FuncDef*)pOp->p3);



  break;
}




































































/* Opcode: Vacuum * * *
**
** Vacuum the entire database.  This opcode will cause other virtual
** machines to be created and run.  It may not be called from within
** a transaction.
*/
case OP_Vacuum: {        /* no-push */
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; 
  rc = sqlite3RunVacuum(&p->zErrMsg, db);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  break;
}

/* Opcode: Expire P1 * *
**
** Cause precompiled statements to become expired. An expired statement
** fails with an error code of SQLITE_SCHEMA if it is ever executed 
** (via sqlite3_step()).
** 
** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
** then only the currently executing statement is affected. 
*/
case OP_Expire: {        /* no-push */
  if( !pOp->p1 ){
    sqlite3ExpirePreparedStatements(db);
  }else{
    p->expired = 1;
  }
  break;
}

#ifndef SQLITE_OMIT_SHARED_CACHE
/* Opcode: TableLock P1 P2 P3
**
** Obtain a lock on a particular table. This instruction is only used when
** the shared-cache feature is enabled. 
**
** If P1 is not negative, then it is the index of the index of the database
** in sqlite3.aDb[] and a read-lock is required. If P1 is negative, a 
** write-lock is required. In this case the index of the database is the 
** absolute value of P1 minus one (iDb = abs(P1) - 1;) and a write-lock is
** required. 
**
** P2 contains the root-page of the table to lock.
**
** P3 contains a pointer to the name of the table being locked. This is only
** used to generate an error message if the lock cannot be obtained.
*/
case OP_TableLock: {        /* no-push */
  int p1 = pOp->p1; 
  u8 isWriteLock = (p1<0);
  if( isWriteLock ){
    p1 = (-1*p1)-1;
  }
  rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
  if( rc==SQLITE_LOCKED ){
    const char *z = (const char *)pOp->p3;
    sqlite3SetString(&p->zErrMsg, "database table is locked: ", z, (char*)0);
  }
  break;
}
#endif /* SHARED_OMIT_SHARED_CACHE */

/* An other opcode is illegal...
*/
default: {
  assert( 0 );



  break;
}

/*****************************************************************************
** The cases of the switch statement above this line should all be indented
** by 6 spaces.  But the left-most 6 spaces have been removed to improve the
** readability.  From this point on down, the normal indentation rules are
** restored.
*****************************************************************************/
    }

    /* Make sure the stack limit was not exceeded */
    assert( pTos<=pStackLimit );

#ifdef VDBE_PROFILE
    {
      long long elapse = hwtime() - start;
      pOp->cycles += elapse;
      pOp->cnt++;
#if 0
        fprintf(stdout, "%10lld ", elapse);
        sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
#endif
    }
#endif

    /* The following code adds nothing to the actual functionality
    ** of the program.  It is only here for testing and debugging.
    ** On the other hand, it does burn CPU cycles every time through
    ** the evaluator loop.  So we can leave it out when NDEBUG is defined.
    */
#ifndef NDEBUG
    /* Sanity checking on the top element of the stack */
    if( pTos>=p->aStack ){
      sqlite3VdbeMemSanity(pTos, encoding);
    }
    assert( pc>=-1 && pc<p->nOp );



#ifdef SQLITE_DEBUG
    /* Code for tracing the vdbe stack. */
    if( p->trace && pTos>=p->aStack ){
      int i;
      fprintf(p->trace, "Stack:");
      for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){
        if( pTos[i].flags & MEM_Null ){







|





|
|









|
>
>

|
|

|
|




|
>
>
>





|
<
<
|

|











|

|
>
>

>
|
<
>

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

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



|

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

|
|
|
|



|



|
<

>
>
>
|

|







>
|

>


>


|

>
>

|
>
|
|









>
>
|






|

>
|
|
>
>

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

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



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







|















|








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



<
>
>
>











<
<
<




















|

|
>
>
>







4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250


4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272

4273
4274
4275
4276





4277



4278








4279

4280

4281

4282
4283
4284

4285
4286
4287
4288





4289

4290
4291
4292
4293
4294
4295






4296


4297


4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310

4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368

4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403

4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559






















4560









4561
4562
4563

4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577



4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
**
** Set the value of memory cell P1 to the maximum of its current value
** and the value on the top of the stack.  The stack is unchanged.
**
** This instruction throws an error if the memory cell is not initially
** an integer.
*/
case OP_MemMax: {
  int i = pOp->p1;
  Mem *pMem;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  Integerify(pMem);
  Integerify(pTos);
  if( pMem->i<pTos->i){
    pMem->i = pTos->i;
  }
  break;
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */

/* Opcode: MemIncr P1 P2 *
**
** Increment the integer valued memory cell P1 by 1.  If P2 is not zero
** and the result after the increment is exactly 1, then jump
** to P2.
**
** This instruction throws an error if the memory cell is not initially
** an integer.
*/
case OP_MemIncr: {
  int i = pOp->p1;
  Mem *pMem;
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  pMem->i++;
  if( pOp->p2>0 && pMem->i==1 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IfMemPos P1 P2 *
**
** If the value of memory cell P1 is 1 or greater, jump to P2. This


** opcode assumes that memory cell P1 holds an integer value.
*/
case OP_IfMemPos: {
  int i = pOp->p1;
  Mem *pMem;
  assert( i>=0 && i<p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->i>0 ){
     pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: AggReset P1 P2 P3
**
** Reset the current aggregator context so that it no longer contains any 
** data. Future aggregator elements will contain P2 values each and be sorted
** using the KeyInfo structure pointed to by P3.
**
** If P1 is non-zero, then only a single aggregator row is available (i.e.
** there is no GROUP BY expression). In this case it is illegal to invoke

** OP_AggFocus.
*/
case OP_AggReset: {
  assert( !pOp->p3 || pOp->p3type==P3_KEYINFO );





  if( pOp->p1 ){



    rc = sqlite3VdbeAggReset(0, p->pAgg, (KeyInfo *)pOp->p3);








    p->pAgg->nMem = pOp->p2;    /* Agg.nMem is used by AggInsert() */

    rc = AggInsert(p->pAgg, 0, 0);

  }else{

    rc = sqlite3VdbeAggReset(db, p->pAgg, (KeyInfo *)pOp->p3);
    p->pAgg->nMem = pOp->p2;
  }

  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  p->pAgg->apFunc = sqliteMalloc( p->pAgg->nMem*sizeof(p->pAgg->apFunc[0]) );





  if( p->pAgg->apFunc==0 ) goto no_mem;

  break;
}

/* Opcode: AggInit * P2 P3
**
** Initialize the function parameters for an aggregate function.






** The aggregate will operate out of aggregate column P2.


** P3 is a pointer to the FuncDef structure for the function.


*/
case OP_AggInit: {
  int i = pOp->p2;
  assert( i>=0 && i<p->pAgg->nMem );
  p->pAgg->apFunc[i] = (FuncDef*)pOp->p3;
  break;
}

/* Opcode: AggFunc * P2 P3
**
** Execute the step function for an aggregate.  The
** function has P2 arguments.  P3 is a pointer to the FuncDef
** structure that specifies the function.

**
** The top of the stack must be an integer which is the index of
** the aggregate column that corresponds to this aggregate function.
** Ideally, this index would be another parameter, but there are
** no free parameters left.  The integer is popped from the stack.
*/
case OP_AggFunc: {
  int n = pOp->p2;
  int i;
  Mem *pMem, *pRec;
  sqlite3_context ctx;
  sqlite3_value **apVal;

  assert( n>=0 );
  assert( pTos->flags==MEM_Int );
  pRec = &pTos[-n];
  assert( pRec>=p->aStack );

  apVal = p->apArg;
  assert( apVal || n==0 );

  for(i=0; i<n; i++, pRec++){
    apVal[i] = pRec;
    storeTypeInfo(pRec, db->enc);
  }
  i = pTos->i;
  assert( i>=0 && i<p->pAgg->nMem );
  ctx.pFunc = (FuncDef*)pOp->p3;
  pMem = &p->pAgg->pCurrent->aMem[i];
  ctx.s.z = pMem->zShort;  /* Space used for small aggregate contexts */
  ctx.pAgg = pMem->z;
  ctx.cnt = ++pMem->i;
  ctx.isError = 0;
  ctx.pColl = 0;
  if( ctx.pFunc->needCollSeq ){
    assert( pOp>p->aOp );
    assert( pOp[-1].p3type==P3_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    ctx.pColl = (CollSeq *)pOp[-1].p3;
  }
  (ctx.pFunc->xStep)(&ctx, n, apVal);
  pMem->z = ctx.pAgg;
  pMem->flags = MEM_AggCtx;
  popStack(&pTos, n+1);
  if( ctx.isError ){
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: AggFocus * P2 *
**
** Pop the top of the stack and use that as an aggregator key.  If
** an aggregator with that same key already exists, then make the
** aggregator the current aggregator and jump to P2.  If no aggregator
** with the given key exists, create one and make it current but
** do not jump.
**

** The order of aggregator opcodes is important.  The order is:
** AggReset AggFocus AggNext.  In other words, you must execute
** AggReset first, then zero or more AggFocus operations, then
** zero or more AggNext operations.  You must not execute an AggFocus
** in between an AggNext and an AggReset.
*/
case OP_AggFocus: {
  char *zKey;
  int nKey;
  int res;
  assert( pTos>=p->aStack );
  Stringify(pTos, db->enc);
  zKey = pTos->z;
  nKey = pTos->n;
  assert( p->pAgg->pBtree );
  assert( p->pAgg->pCsr );
  rc = sqlite3BtreeMoveto(p->pAgg->pCsr, zKey, nKey, &res);
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  if( res==0 ){
    rc = sqlite3BtreeData(p->pAgg->pCsr, 0, sizeof(AggElem*),
        (char *)&p->pAgg->pCurrent);
    pc = pOp->p2 - 1;
  }else{
    rc = AggInsert(p->pAgg, zKey, nKey);
  }
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  Release(pTos);
  pTos--;
  break; 
}


/* Opcode: AggSet * P2 *
**
** Move the top of the stack into the P2-th field of the current
** aggregate.  String values are duplicated into new memory.
*/
case OP_AggSet: {
  AggElem *pFocus;
  int i = pOp->p2;
  pFocus = p->pAgg->pCurrent;
  assert( pTos>=p->aStack );
  if( pFocus==0 ) goto no_mem;
  assert( i>=0 && i<p->pAgg->nMem );
  rc = sqlite3VdbeMemMove(&pFocus->aMem[i], pTos);
  pTos--;
  break;
}

/* Opcode: AggGet P1 P2 *
**
** Push a new entry onto the stack which is a copy of the P2-th field
** of the current aggregate.  Strings are not duplicated so
** string values will be ephemeral.
**
** If P1 is zero, then the value is pulled out of the current aggregate
** in the current aggregate context. If P1 is greater than zero, then
** the value is taken from the P1th outer aggregate context. (i.e. if
** P1==1 then read from the aggregate context that will be restored
** by the next OP_AggContextPop opcode).
*/
case OP_AggGet: {
  AggElem *pFocus;
  int i = pOp->p2;
  Agg *pAgg = &p->pAgg[-pOp->p1];
  assert( pAgg>=p->apAgg );
  pFocus = pAgg->pCurrent;
  if( pFocus==0 ){
    int res;
    if( sqlite3_malloc_failed ) goto no_mem;
    rc = sqlite3BtreeFirst(pAgg->pCsr, &res);
    if( rc!=SQLITE_OK ){
      return rc;
    }
    if( res!=0 ){
      rc = AggInsert(pAgg, "", 1);
      pFocus = pAgg->pCurrent;
    }else{
      rc = sqlite3BtreeData(pAgg->pCsr, 0, 4, (char *)&pFocus);
    }
  }
  assert( i>=0 && i<pAgg->nMem );
  pTos++;
  sqlite3VdbeMemShallowCopy(pTos, &pFocus->aMem[i], MEM_Ephem);
  if( pTos->flags&MEM_Str ){
    sqlite3VdbeChangeEncoding(pTos, db->enc);
  }
  break;
}

/* Opcode: AggNext * P2 *
**
** Make the next aggregate value the current aggregate.  The prior
** aggregate is deleted.  If all aggregate values have been consumed,
** jump to P2.
**
** The order of aggregator opcodes is important.  The order is:
** AggReset AggFocus AggNext.  In other words, you must execute
** AggReset first, then zero or more AggFocus operations, then
** zero or more AggNext operations.  You must not execute an AggFocus
** in between an AggNext and an AggReset.
*/
case OP_AggNext: {
  int res;
  assert( rc==SQLITE_OK );
  CHECK_FOR_INTERRUPT;
  if( p->pAgg->searching==0 ){
    p->pAgg->searching = 1;
    if( p->pAgg->pCsr ){
      rc = sqlite3BtreeFirst(p->pAgg->pCsr, &res);
    }else{
      res = 0;
    }
  }else{
    if( p->pAgg->pCsr ){
      rc = sqlite3BtreeNext(p->pAgg->pCsr, &res);
    }else{
      res = 1;
    }
  }
  if( rc!=SQLITE_OK ) goto abort_due_to_error;
  if( res!=0 ){
    pc = pOp->p2 - 1;
  }else{
    int i;
    sqlite3_context ctx;
    Mem *aMem;

    if( p->pAgg->pCsr ){
      rc = sqlite3BtreeData(p->pAgg->pCsr, 0, sizeof(AggElem*),
          (char *)&p->pAgg->pCurrent);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
    }
    aMem = p->pAgg->pCurrent->aMem;
    for(i=0; i<p->pAgg->nMem; i++){
      FuncDef *pFunc = p->pAgg->apFunc[i];
      Mem *pMem = &aMem[i];
      if( pFunc==0 || pFunc->xFinalize==0 ) continue;
      ctx.s.flags = MEM_Null;
      ctx.s.z = pMem->zShort;
      ctx.pAgg = (void*)pMem->z;
      ctx.cnt = pMem->i;
      ctx.pFunc = pFunc;
      pFunc->xFinalize(&ctx);
      pMem->z = ctx.pAgg;
      if( pMem->z && pMem->z!=pMem->zShort ){
        sqliteFree( pMem->z );
      }
      *pMem = ctx.s;
      if( pMem->flags & MEM_Short ){
        pMem->z = pMem->zShort;
      }
    }
  }
  break;
}

/* Opcode: Vacuum * * *
**
** Vacuum the entire database.  This opcode will cause other virtual
** machines to be created and run.  It may not be called from within
** a transaction.
*/
case OP_Vacuum: {
  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; 
  rc = sqlite3RunVacuum(&p->zErrMsg, db);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
  break;
}

/* Opcode: Expire P1 * *
**
** Cause precompiled statements to become expired. An expired statement
** fails with an error code of SQLITE_SCHEMA if it is ever executed 
** (via sqlite3_step()).
** 
** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
** then only the currently executing statement is affected. 
*/
case OP_Expire: {
  if( !pOp->p1 ){
    sqlite3ExpirePreparedStatements(db);
  }else{
    p->expired = 1;
  }
  break;
}

































/* An other opcode is illegal...
*/
default: {

  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode);
  sqlite3SetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
  rc = SQLITE_INTERNAL;
  break;
}

/*****************************************************************************
** The cases of the switch statement above this line should all be indented
** by 6 spaces.  But the left-most 6 spaces have been removed to improve the
** readability.  From this point on down, the normal indentation rules are
** restored.
*****************************************************************************/
    }




#ifdef VDBE_PROFILE
    {
      long long elapse = hwtime() - start;
      pOp->cycles += elapse;
      pOp->cnt++;
#if 0
        fprintf(stdout, "%10lld ", elapse);
        sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
#endif
    }
#endif

    /* The following code adds nothing to the actual functionality
    ** of the program.  It is only here for testing and debugging.
    ** On the other hand, it does burn CPU cycles every time through
    ** the evaluator loop.  So we can leave it out when NDEBUG is defined.
    */
#ifndef NDEBUG
    /* Sanity checking on the top element of the stack */
    if( pTos>=p->aStack ){
      sqlite3VdbeMemSanity(pTos, db->enc);
    }
    if( pc<-1 || pc>=p->nOp ){
      sqlite3SetString(&p->zErrMsg, "jump destination out of range", (char*)0);
      rc = SQLITE_INTERNAL;
    }
#ifdef SQLITE_DEBUG
    /* Code for tracing the vdbe stack. */
    if( p->trace && pTos>=p->aStack ){
      int i;
      fprintf(p->trace, "Stack:");
      for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){
        if( pTos[i].flags & MEM_Null ){
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
    p->rc = rc;
    rc = SQLITE_ERROR;
  }else{
    rc = SQLITE_DONE;
  }
  sqlite3VdbeHalt(p);
  p->pTos = pTos;
  pTsd->nRef--;
  return rc;

  /* Jump to here if a malloc() fails.  It's hard to get a malloc()
  ** to fail on a modern VM computer, so this code is untested.
  */
no_mem:
  sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);







<







4636
4637
4638
4639
4640
4641
4642

4643
4644
4645
4646
4647
4648
4649
    p->rc = rc;
    rc = SQLITE_ERROR;
  }else{
    rc = SQLITE_DONE;
  }
  sqlite3VdbeHalt(p);
  p->pTos = pTos;

  return rc;

  /* Jump to here if a malloc() fails.  It's hard to get a malloc()
  ** to fail on a modern VM computer, so this code is untested.
  */
no_mem:
  sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
  /* Fall thru into abort_due_to_error */

  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  if( p->zErrMsg==0 ){
    if( pTsd->mallocFailed ) rc = SQLITE_NOMEM;
    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  }
  goto vdbe_halt;

  /* Jump to here if the sqlite3_interrupt() API sets the interrupt
  ** flag.
  */







|







4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
  /* Fall thru into abort_due_to_error */

  /* Jump to here for any other kind of fatal error.  The "rc" variable
  ** should hold the error number.
  */
abort_due_to_error:
  if( p->zErrMsg==0 ){
    if( sqlite3_malloc_failed ) rc = SQLITE_NOMEM;
    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
  }
  goto vdbe_halt;

  /* Jump to here if the sqlite3_interrupt() API sets the interrupt
  ** flag.
  */
Changes to SQLite.Interop/src/vdbe.h.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.15 2006/01/16 15:51:47 rmsimpson Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.1 2005/03/01 16:04:38 rmsimpson Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
** as an instance of the following structure:
*/
struct VdbeOp {
  u8 opcode;          /* What operation to perform */
  int p1;             /* First operand */
  int p2;             /* Second parameter (often the jump destination) */
  char *p3;           /* Third parameter */
  int p3type;         /* One of the P3_xxx constants defined below */
#ifdef VDBE_PROFILE
  int cnt;            /* Number of times this instruction was executed */
  long long cycles;   /* Total time spend executing this instruction */
#endif
};
typedef struct VdbeOp VdbeOp;








|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
** as an instance of the following structure:
*/
struct VdbeOp {
  u8 opcode;          /* What operation to perform */
  int p1;             /* First operand */
  int p2;             /* Second parameter (often the jump destination) */
  char *p3;           /* Third parameter */
  int p3type;         /* P3_STATIC, P3_DYNAMIC or P3_POINTER */
#ifdef VDBE_PROFILE
  int cnt;            /* Number of times this instruction was executed */
  long long cycles;   /* Total time spend executing this instruction */
#endif
};
typedef struct VdbeOp VdbeOp;

60
61
62
63
64
65
66

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

/*
** Allowed values of VdbeOp.p3type
*/
#define P3_NOTUSED    0   /* The P3 parameter is not used */
#define P3_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
#define P3_STATIC   (-2)  /* Pointer to a static string */

#define P3_COLLSEQ  (-4)  /* P3 is a pointer to a CollSeq structure */
#define P3_FUNCDEF  (-5)  /* P3 is a pointer to a FuncDef structure */
#define P3_KEYINFO  (-6)  /* P3 is a pointer to a KeyInfo structure */
#define P3_VDBEFUNC (-7)  /* P3 is a pointer to a VdbeFunc structure */
#define P3_MEM      (-8)  /* P3 is a pointer to a Mem*    structure */

/* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
** is made.  That copy is freed when the Vdbe is finalized.  But if the
** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used.  It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc().  But no copy is made and the calling
** function should *not* try to free the KeyInfo.
*/
#define P3_KEYINFO_HANDOFF (-9)

/*
** The following macro converts a relative address in the p2 field
** of a VdbeOp structure into a negative number so that 
** sqlite3VdbeAddOpList() knows that the address is relative.  Calling
** the macro again restores the address.
*/







>




<








|







60
61
62
63
64
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

/*
** Allowed values of VdbeOp.p3type
*/
#define P3_NOTUSED    0   /* The P3 parameter is not used */
#define P3_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
#define P3_STATIC   (-2)  /* Pointer to a static string */
#define P3_POINTER  (-3)  /* P3 is a pointer to some structure or object */
#define P3_COLLSEQ  (-4)  /* P3 is a pointer to a CollSeq structure */
#define P3_FUNCDEF  (-5)  /* P3 is a pointer to a FuncDef structure */
#define P3_KEYINFO  (-6)  /* P3 is a pointer to a KeyInfo structure */
#define P3_VDBEFUNC (-7)  /* P3 is a pointer to a VdbeFunc structure */


/* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
** is made.  That copy is freed when the Vdbe is finalized.  But if the
** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used.  It still
** gets freed when the Vdbe is finalized so it still should be obtained
** from a single sqliteMalloc().  But no copy is made and the calling
** function should *not* try to free the KeyInfo.
*/
#define P3_KEYINFO_HANDOFF (-7)

/*
** The following macro converts a relative address in the p2 field
** of a VdbeOp structure into a negative number so that 
** sqlite3VdbeAddOpList() knows that the address is relative.  Calling
** the macro again restores the address.
*/
100
101
102
103
104
105
106
107
108


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
Vdbe *sqlite3VdbeCreate(sqlite3*);
void sqlite3VdbeCreateCallback(Vdbe*, int*);
int sqlite3VdbeAddOp(Vdbe*,int,int,int);
int sqlite3VdbeOp3(Vdbe*,int,int,int,const char *zP3,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);


VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);
void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int);
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
void sqlite3VdbeTrace(Vdbe*,FILE*);
int sqlite3VdbeReset(Vdbe*);
int sqliteVdbeSetVariables(Vdbe*,int,const char**);
void sqlite3VdbeSetNumCols(Vdbe*,int);
int sqlite3VdbeSetColName(Vdbe*, int, const char *, int);
void sqlite3VdbeCountChanges(Vdbe*);
sqlite3 *sqlite3VdbeDb(Vdbe*);

#ifndef NDEBUG
  void sqlite3VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X)  sqlite3VdbeComment X
#else
# define VdbeComment(X)
#endif

#endif







<

>
>



|









<









100
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
Vdbe *sqlite3VdbeCreate(sqlite3*);
void sqlite3VdbeCreateCallback(Vdbe*, int*);
int sqlite3VdbeAddOp(Vdbe*,int,int,int);
int sqlite3VdbeOp3(Vdbe*,int,int,int,const char *zP3,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);

void sqlite3VdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
void sqlite3VdbeDequoteP3(Vdbe*, int addr);
int sqlite3VdbeFindOp(Vdbe*, int, int, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);
void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int);
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
void sqlite3VdbeTrace(Vdbe*,FILE*);
int sqlite3VdbeReset(Vdbe*);
int sqliteVdbeSetVariables(Vdbe*,int,const char**);
void sqlite3VdbeSetNumCols(Vdbe*,int);
int sqlite3VdbeSetColName(Vdbe*, int, const char *, int);
void sqlite3VdbeCountChanges(Vdbe*);


#ifndef NDEBUG
  void sqlite3VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X)  sqlite3VdbeComment X
#else
# define VdbeComment(X)
#endif

#endif
Changes to SQLite.Interop/src/vdbeInt.h.
56
57
58
59
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130


131
132
133
134
135

















136
137
138
139
140
141
142
** If the Cursor.isTriggerRow flag is set it means that this cursor is
** really a single row that represents the NEW or OLD pseudo-table of
** a row trigger.  The data for the row is stored in Cursor.pData and
** the rowid is in Cursor.iKey.
*/
struct Cursor {
  BtCursor *pCursor;    /* The cursor structure of the backend */
  int iDb;              /* Index of cursor database in db->aDb[] (or -1) */
  i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
  i64 nextRowid;        /* Next rowid returned by OP_NewRowid */
  Bool zeroed;          /* True if zeroed out and ready for reuse */
  Bool rowidIsValid;    /* True if lastRowid is valid */

  Bool atFirst;         /* True if pointing to first entry */
  Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
  Bool nullRow;         /* True if pointing to a row with no data */
  Bool nextRowidValid;  /* True if the nextRowid field is valid */
  Bool pseudoTable;     /* This is a NEW or OLD pseudo-tables of a trigger */
  Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
  Bool isTable;         /* True if a table requiring integer keys */
  Bool isIndex;         /* True if an index containing keys only - no data */
  u8 bogusIncrKey;      /* Something for pIncrKey to point to if pKeyInfo==0 */
  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
  Btree *pBt;           /* Separate file holding temporary table */
  int nData;            /* Number of bytes in pData */
  char *pData;          /* Data for a NEW or OLD pseudo-table */
  i64 iKey;             /* Key for the NEW or OLD pseudo-table row */
  u8 *pIncrKey;         /* Pointer to pKeyInfo->incrKey */
  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
  int nField;           /* Number of fields in the header */
  i64 seqCount;         /* Sequence counter */

  /* Cached information about the header for the data record that the
  ** cursor is currently pointing to.  Only valid if cacheValid is true.
  ** aRow might point to (ephemeral) data for the current row, or it might
  ** be NULL.
  */
  int cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
  int payloadSize;      /* Total number of bytes in the record */
  u32 *aType;           /* Type values for all entries in the record */
  u32 *aOffset;         /* Cached offsets to the start of each columns data */
  u8 *aRow;             /* Data for the current row, if all on one page */
};
typedef struct Cursor Cursor;

/*
** Number of bytes of string storage space available to each stack
** layer without having to malloc.  NBFS is short for Number of Bytes
** For Strings.
*/
#define NBFS 32

/*
** A value for Cursor.cacheValid that means the cache is always invalid.
*/
#define CACHE_STALE 0

/*
** Internally, the vdbe manipulates nearly all SQL values as Mem
** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.  A value (and therefore Mem structure)
** has the following properties:
**
** Each value has a manifest type. The manifest type of the value stored
** in a Mem struct is returned by the MemType(Mem*) macro. The type is
** one of SQLITE_NULL, SQLITE_INTEGER, SQLITE_REAL, SQLITE_TEXT or
** SQLITE_BLOB.
*/
struct Mem {
  i64 i;              /* Integer value. Or FuncDef* when flags==MEM_Agg */
  double r;           /* Real value */
  char *z;            /* String or BLOB value */
  int n;              /* Number of characters in string value, including '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of MEM_Null, MEM_Str, etc. */
  u8  enc;            /* TEXT_Utf8, TEXT_Utf16le, or TEXT_Utf16be */


  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
  char zShort[NBFS];  /* Space for short strings */
};
typedef struct Mem Mem;


















/* One or more of the following flags are set to indicate the validOK
** representations of the value stored in the Mem struct.
**
** If the MEM_Null flag is set, then the value is an SQL NULL value.
** No other flags may be set in this case.
**
** If the MEM_Str flag is set then Mem.z points at a string representation.







<
|


|
>






|
|









<



|
|
<
|














<
<
<
<
<












|
<
<




>
>





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







56
57
58
59
60
61
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88
89

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104





105
106
107
108
109
110
111
112
113
114
115
116
117


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
** If the Cursor.isTriggerRow flag is set it means that this cursor is
** really a single row that represents the NEW or OLD pseudo-table of
** a row trigger.  The data for the row is stored in Cursor.pData and
** the rowid is in Cursor.iKey.
*/
struct Cursor {
  BtCursor *pCursor;    /* The cursor structure of the backend */

  i64 lastRecno;        /* Last recno from a Next or NextIdx operation */
  i64 nextRowid;        /* Next rowid returned by OP_NewRowid */
  Bool zeroed;          /* True if zeroed out and ready for reuse */
  Bool recnoIsValid;    /* True if lastRecno is valid */
  Bool keyAsData;       /* The OP_Column command works on key instead of data */
  Bool atFirst;         /* True if pointing to first entry */
  Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
  Bool nullRow;         /* True if pointing to a row with no data */
  Bool nextRowidValid;  /* True if the nextRowid field is valid */
  Bool pseudoTable;     /* This is a NEW or OLD pseudo-tables of a trigger */
  Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
  Bool intKey;          /* True if the table requires integer keys */
  Bool zeroData;        /* True if table contains keys only - no data */
  u8 bogusIncrKey;      /* Something for pIncrKey to point to if pKeyInfo==0 */
  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
  Btree *pBt;           /* Separate file holding temporary table */
  int nData;            /* Number of bytes in pData */
  char *pData;          /* Data for a NEW or OLD pseudo-table */
  i64 iKey;             /* Key for the NEW or OLD pseudo-table row */
  u8 *pIncrKey;         /* Pointer to pKeyInfo->incrKey */
  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
  int nField;           /* Number of fields in the header */


  /* Cached information about the header for the data record that the
  ** cursor is currently pointing to.  Only valid if cacheValid is true.
  ** zRow might point to (ephemeral) data for the current row, or it might
  ** be NULL. */

  Bool cacheValid;      /* True if the cache is valid */
  int payloadSize;      /* Total number of bytes in the record */
  u32 *aType;           /* Type values for all entries in the record */
  u32 *aOffset;         /* Cached offsets to the start of each columns data */
  u8 *aRow;             /* Data for the current row, if all on one page */
};
typedef struct Cursor Cursor;

/*
** Number of bytes of string storage space available to each stack
** layer without having to malloc.  NBFS is short for Number of Bytes
** For Strings.
*/
#define NBFS 32






/*
** Internally, the vdbe manipulates nearly all SQL values as Mem
** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.  A value (and therefore Mem structure)
** has the following properties:
**
** Each value has a manifest type. The manifest type of the value stored
** in a Mem struct is returned by the MemType(Mem*) macro. The type is
** one of SQLITE_NULL, SQLITE_INTEGER, SQLITE_REAL, SQLITE_TEXT or
** SQLITE_BLOB.
*/
struct Mem {
  i64 i;              /* Integer value */


  int n;              /* Number of characters in string value, including '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of MEM_Null, MEM_Str, etc. */
  u8  enc;            /* TEXT_Utf8, TEXT_Utf16le, or TEXT_Utf16be */
  double r;           /* Real value */
  char *z;            /* String or BLOB value */
  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
  char zShort[NBFS];  /* Space for short strings */
};
typedef struct Mem Mem;

/*
** A sorter builds a list of elements to be sorted.  Each element of
** the list is an instance of the following structure.
*/
typedef struct Sorter Sorter;
struct Sorter {
  int nKey;           /* Number of bytes in the key */
  char *zKey;         /* The key by which we will sort */
  Mem data;
  Sorter *pNext;      /* Next in the list */
};

/* 
** Number of buckets used for merge-sort.  
*/
#define NSORT 30

/* One or more of the following flags are set to indicate the validOK
** representations of the value stored in the Mem struct.
**
** If the MEM_Null flag is set, then the value is an SQL NULL value.
** No other flags may be set in this case.
**
** If the MEM_Str flag is set then Mem.z points at a string representation.
160
161
162
163
164
165
166





167
168
169
170
171
172
173
174
** string is \000 or \u0000 terminated
*/
#define MEM_Term      0x0020   /* String rep is nul terminated */
#define MEM_Dyn       0x0040   /* Need to call sqliteFree() on Mem.z */
#define MEM_Static    0x0080   /* Mem.z points to a static string */
#define MEM_Ephem     0x0100   /* Mem.z points to an ephemeral string */
#define MEM_Short     0x0200   /* Mem.z points to Mem.zShort */





#define MEM_Agg       0x0400   /* Mem.z points to an agg function context */


/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
** additional information about auxiliary information bound to arguments
** of the function.  This is used to implement the sqlite3_get_auxdata()
** and sqlite3_set_auxdata() APIs.  The "auxdata" is some auxiliary data
** that can be associated with a constant argument to a function.  This







>
>
>
>
>
|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
** string is \000 or \u0000 terminated
*/
#define MEM_Term      0x0020   /* String rep is nul terminated */
#define MEM_Dyn       0x0040   /* Need to call sqliteFree() on Mem.z */
#define MEM_Static    0x0080   /* Mem.z points to a static string */
#define MEM_Ephem     0x0100   /* Mem.z points to an ephemeral string */
#define MEM_Short     0x0200   /* Mem.z points to Mem.zShort */

/* The following MEM_ value appears only in AggElem.aMem.s.flag fields.
** It indicates that the corresponding AggElem.aMem.z points to a
** aggregate function context that needs to be finalized.
*/
#define MEM_AggCtx    0x0400  /* Mem.z points to an agg function context */


/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
** additional information about auxiliary information bound to arguments
** of the function.  This is used to implement the sqlite3_get_auxdata()
** and sqlite3_set_auxdata() APIs.  The "auxdata" is some auxiliary data
** that can be associated with a constant argument to a function.  This
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
























209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h.  So all routines,
** even the public interface to SQLite, can use a pointer to this structure.
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbeInt.h because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
  FuncDef *pFunc;       /* Pointer to function information.  MUST BE FIRST */
  VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
  Mem s;                /* The return value is stored here */
  Mem *pMem;            /* Memory cell used to store aggregate context */
  u8 isError;           /* Set to true for an error */

  CollSeq *pColl;       /* Collating sequence */
























};

/*
** A Set structure is used for quick testing to see if a value
** is part of a small set.  Sets are used to implement code like
** this:
**            x.y IN ('hi','hoo','hum')
*/
typedef struct Set Set;
struct Set {
  Hash hash;             /* A set is just a hash table */
  HashElem *prev;        /* Previously accessed hash elemen */
};

/*
** A FifoPage structure holds a single page of valves.  Pages are arranged
** in a list.

*/
typedef struct FifoPage FifoPage;
struct FifoPage {
  int nSlot;         /* Number of entries aSlot[] */
  int iWrite;        /* Push the next value into this entry in aSlot[] */
  int iRead;         /* Read the next value from this entry in aSlot[] */
  FifoPage *pNext;   /* Next page in the fifo */
  i64 aSlot[1];      /* One or more slots for rowid values */
};

/*
** The Fifo structure is typedef-ed in vdbeInt.h.  But the implementation
** of that structure is private to this file.
**
** The Fifo structure describes the entire fifo.  
*/
typedef struct Fifo Fifo;
struct Fifo {
  int nEntry;         /* Total number of entries */
  FifoPage *pFirst;   /* First page on the list */
  FifoPage *pLast;    /* Last page on the list */
};

/*
** A Context stores the last insert rowid, the last statement change count,
** and the current statement change count (i.e. changes since last statement).
** The current keylist is also stored in the context.
** Elements of Context structure type make up the ContextStack, which is
** updated by the ContextPush and ContextPop opcodes (used by triggers).
** The context is pushed before executing a trigger a popped when the
** trigger finishes.
*/
typedef struct Context Context;
struct Context {
  i64 lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
  int nChange;      /* Statement changes (Vdbe.nChanges)     */
  Fifo sFifo;       /* Records that will participate in a DELETE or UPDATE */
};

/*
** An instance of the virtual machine.  This structure contains the complete
** state of the virtual machine.
**
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()







|



|

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















|
|
>

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













|

|







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274













275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h.  So all routines,
** even the public interface to SQLite, can use a pointer to this structure.
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbe.c because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
  FuncDef *pFunc;   /* Pointer to function information.  MUST BE FIRST */
  VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
  Mem s;            /* The return value is stored here */
  void *pAgg;       /* Aggregate context */
  u8 isError;       /* Set to true for an error */
  int cnt;          /* Number of times that the step function has been called */
  CollSeq *pColl;
};

/*
** An Agg structure describes an Aggregator.  Each Agg consists of
** zero or more Aggregator elements (AggElem).  Each AggElem contains
** a key and one or more values.  The values are used in processing
** aggregate functions in a SELECT.  The key is used to implement
** the GROUP BY clause of a select.
*/
typedef struct Agg Agg;
typedef struct AggElem AggElem;
struct Agg {
  int nMem;            /* Number of values stored in each AggElem */
  AggElem *pCurrent;   /* The AggElem currently in focus */
  FuncDef **apFunc;    /* Information about aggregate functions */
  Btree *pBtree;       /* The tmp. btree used to group elements, if required. */
  BtCursor *pCsr;      /* Read/write cursor to the table in pBtree */
  int nTab;            /* Root page of the table in pBtree */
  u8 searching;        /* True between the first AggNext and AggReset */
};
struct AggElem {
  char *zKey;          /* The key to this AggElem */
  int nKey;            /* Number of bytes in the key, including '\0' at end */
  Mem aMem[1];         /* The values for this AggElem */
};

/*
** A Set structure is used for quick testing to see if a value
** is part of a small set.  Sets are used to implement code like
** this:
**            x.y IN ('hi','hoo','hum')
*/
typedef struct Set Set;
struct Set {
  Hash hash;             /* A set is just a hash table */
  HashElem *prev;        /* Previously accessed hash elemen */
};

/*
** A Keylist is a bunch of keys into a table.  The keylist can
** grow without bound.  The keylist stores the ROWIDs of database
** records that need to be deleted or updated.
*/
typedef struct Keylist Keylist;
struct Keylist {
  int nKey;         /* Number of slots in aKey[] */
  int nUsed;        /* Next unwritten slot in aKey[] */
  int nRead;        /* Next unread slot in aKey[] */
  Keylist *pNext;   /* Next block of keys */
  i64 aKey[1];      /* One or more keys.  Extra space allocated as needed */













};

/*
** A Context stores the last insert rowid, the last statement change count,
** and the current statement change count (i.e. changes since last statement).
** The current keylist is also stored in the context.
** Elements of Context structure type make up the ContextStack, which is
** updated by the ContextPush and ContextPop opcodes (used by triggers).
** The context is pushed before executing a trigger a popped when the
** trigger finishes.
*/
typedef struct Context Context;
struct Context {
  int lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
  int nChange;      /* Statement changes (Vdbe.nChanges)     */
  Keylist *pList;   /* Records that will participate in a DELETE or UPDATE */
};

/*
** An instance of the virtual machine.  This structure contains the complete
** state of the virtual machine.
**
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()
281
282
283
284
285
286
287

288
289
290
291
292
293
294



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333



334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
  int *aLabel;        /* Space to hold the labels */
  Mem *aStack;        /* The operand stack, except string values */
  Mem *pTos;          /* Top entry in the operand stack */
  Mem **apArg;        /* Arguments to currently executing user function */
  Mem *aColName;      /* Column names to return */
  int nCursor;        /* Number of slots in apCsr[] */
  Cursor **apCsr;     /* One element of this array for each open cursor */

  int nVar;           /* Number of entries in aVar[] */
  Mem *aVar;          /* Values for the OP_Variable opcode. */
  char **azVar;       /* Name of variables */
  int okVar;          /* True if azVar[] has been initialized */
  int magic;              /* Magic number for sanity checking */
  int nMem;               /* Number of memory locations currently allocated */
  Mem *aMem;              /* The memory locations */



  int nCallback;          /* Number of callbacks invoked so far */
  int cacheCtr;           /* Cursor row cache generation counter */
  Fifo sFifo;             /* A list of ROWIDs */
  int contextStackTop;    /* Index of top element in the context stack */
  int contextStackDepth;  /* The size of the "context" stack */
  Context *contextStack;  /* Stack used by opcodes ContextPush & ContextPop*/
  int pc;                 /* The program counter */
  int rc;                 /* Value to return */
  unsigned uniqueCnt;     /* Used by OP_MakeRecord when P2!=0 */
  int errorAction;        /* Recovery action to do in case of an error */
  int inTempTrans;        /* True if temp database is transactioned */
  int returnStack[100];   /* Return address stack for OP_Gosub & OP_Return */
  int returnDepth;        /* Next unused element in returnStack[] */
  int nResColumn;         /* Number of columns in one row of the result set */
  char **azResColumn;     /* Values for one row of result */ 
  int popStack;           /* Pop the stack this much on entry to VdbeExec() */
  char *zErrMsg;          /* Error message written here */
  u8 resOnStack;          /* True if there are result values on the stack */
  u8 explain;             /* True if EXPLAIN present on SQL command */
  u8 changeCntOn;         /* True to update the change-counter */
  u8 aborted;             /* True if ROLLBACK in another VM causes an abort */
  u8 expired;             /* True if the VM needs to be recompiled */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  int nChange;            /* Number of db changes made since last reset */
  i64 startTime;          /* Time when query started - used for profiling */
};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */

/*
** Function prototypes
*/
void sqlite3VdbeFreeCursor(Cursor*);



void sqliteVdbePopStack(Vdbe*,int);
int sqlite3VdbeCursorMoveto(Cursor*);
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
#ifdef SQLITE_DEBUG
void sqlite3VdbePrintSql(Vdbe*);
#endif
int sqlite3VdbeSerialTypeLen(u32);
u32 sqlite3VdbeSerialType(Mem*, int);
int sqlite3VdbeSerialPut(unsigned char*, Mem*, int);
int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);

int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*);
int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);







>







>
>
>

<
|



















<

<














>
>
>









|
|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347

348

349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
  int *aLabel;        /* Space to hold the labels */
  Mem *aStack;        /* The operand stack, except string values */
  Mem *pTos;          /* Top entry in the operand stack */
  Mem **apArg;        /* Arguments to currently executing user function */
  Mem *aColName;      /* Column names to return */
  int nCursor;        /* Number of slots in apCsr[] */
  Cursor **apCsr;     /* One element of this array for each open cursor */
  Sorter *pSort;      /* A linked list of objects to be sorted */
  int nVar;           /* Number of entries in aVar[] */
  Mem *aVar;          /* Values for the OP_Variable opcode. */
  char **azVar;       /* Name of variables */
  int okVar;          /* True if azVar[] has been initialized */
  int magic;              /* Magic number for sanity checking */
  int nMem;               /* Number of memory locations currently allocated */
  Mem *aMem;              /* The memory locations */
  int nAgg;               /* Number of elements in apAgg */
  Agg *apAgg;             /* Array of aggregate contexts */
  Agg *pAgg;              /* Current aggregate context */
  int nCallback;          /* Number of callbacks invoked so far */

  Keylist *pList;         /* A list of ROWIDs */
  int contextStackTop;    /* Index of top element in the context stack */
  int contextStackDepth;  /* The size of the "context" stack */
  Context *contextStack;  /* Stack used by opcodes ContextPush & ContextPop*/
  int pc;                 /* The program counter */
  int rc;                 /* Value to return */
  unsigned uniqueCnt;     /* Used by OP_MakeRecord when P2!=0 */
  int errorAction;        /* Recovery action to do in case of an error */
  int inTempTrans;        /* True if temp database is transactioned */
  int returnStack[100];   /* Return address stack for OP_Gosub & OP_Return */
  int returnDepth;        /* Next unused element in returnStack[] */
  int nResColumn;         /* Number of columns in one row of the result set */
  char **azResColumn;     /* Values for one row of result */ 
  int popStack;           /* Pop the stack this much on entry to VdbeExec() */
  char *zErrMsg;          /* Error message written here */
  u8 resOnStack;          /* True if there are result values on the stack */
  u8 explain;             /* True if EXPLAIN present on SQL command */
  u8 changeCntOn;         /* True to update the change-counter */
  u8 aborted;             /* True if ROLLBACK in another VM causes an abort */
  u8 expired;             /* True if the VM needs to be recompiled */

  int nChange;            /* Number of db changes made since last reset */

};

/*
** The following are allowed values for Vdbe.magic
*/
#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */

/*
** Function prototypes
*/
void sqlite3VdbeFreeCursor(Cursor*);
void sqlite3VdbeSorterReset(Vdbe*);
int sqlite3VdbeAggReset(sqlite3*, Agg *, KeyInfo *);
void sqlite3VdbeKeylistFree(Keylist*);
void sqliteVdbePopStack(Vdbe*,int);
int sqlite3VdbeCursorMoveto(Cursor*);
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
#ifdef SQLITE_DEBUG
void sqlite3VdbePrintSql(Vdbe*);
#endif
int sqlite3VdbeSerialTypeLen(u32);
u32 sqlite3VdbeSerialType(Mem*);
int sqlite3VdbeSerialPut(unsigned char*, Mem*);
int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);

int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*);
int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
void sqlite3VdbeMemSetNull(Mem*);
int sqlite3VdbeMemMakeWriteable(Mem*);
int sqlite3VdbeMemDynamicify(Mem*);
int sqlite3VdbeMemStringify(Mem*, int);
i64 sqlite3VdbeIntValue(Mem*);
int sqlite3VdbeMemIntegerify(Mem*);
double sqlite3VdbeRealValue(Mem*);
void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
void sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef NDEBUG
void sqlite3VdbeMemSanity(Mem*, u8);
int sqlite3VdbeOpcodeNoPush(u8);
#endif
int sqlite3VdbeMemTranslate(Mem*, u8);
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf);
int sqlite3VdbeMemHandleBom(Mem *pMem);
void sqlite3VdbeFifoInit(Fifo*);
int sqlite3VdbeFifoPush(Fifo*, i64);
int sqlite3VdbeFifoPop(Fifo*, i64*);
void sqlite3VdbeFifoClear(Fifo*);







<

<


<


<




<
<
<
<
397
398
399
400
401
402
403

404

405
406

407
408

409
410
411
412




void sqlite3VdbeMemSetNull(Mem*);
int sqlite3VdbeMemMakeWriteable(Mem*);
int sqlite3VdbeMemDynamicify(Mem*);
int sqlite3VdbeMemStringify(Mem*, int);
i64 sqlite3VdbeIntValue(Mem*);
int sqlite3VdbeMemIntegerify(Mem*);
double sqlite3VdbeRealValue(Mem*);

int sqlite3VdbeMemRealify(Mem*);

int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);

#ifndef NDEBUG
void sqlite3VdbeMemSanity(Mem*, u8);

#endif
int sqlite3VdbeMemTranslate(Mem*, u8);
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf);
int sqlite3VdbeMemHandleBom(Mem *pMem);




Changes to SQLite.Interop/src/vdbeapi.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


27
28
29
30
31
32
33
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
#include "os.h"

/*
** Return TRUE (non-zero) of the statement supplied as an argument needs
** to be recompiled.  A statement needs to be recompiled whenever the
** execution environment changes in a way that would alter the program
** that sqlite3_prepare() generates.  For example, if new functions or
** collating sequences are registered or if an authorizer function is
** added or changed.


*/
int sqlite3_expired(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  return p==0 || p->expired;
}

/**************************** sqlite3_value_  *******************************







<








>
>







11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"


/*
** Return TRUE (non-zero) of the statement supplied as an argument needs
** to be recompiled.  A statement needs to be recompiled whenever the
** execution environment changes in a way that would alter the program
** that sqlite3_prepare() generates.  For example, if new functions or
** collating sequences are registered or if an authorizer function is
** added or changed.
**
***** EXPERIMENTAL ******
*/
int sqlite3_expired(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  return p==0 || p->expired;
}

/**************************** sqlite3_value_  *******************************
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
int sqlite3_value_int(sqlite3_value *pVal){
  return sqlite3VdbeIntValue((Mem*)pVal);
}
sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
  return sqlite3VdbeIntValue((Mem*)pVal);
}
const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
  return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_value_text16(sqlite3_value* pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
}
const void *sqlite3_value_text16be(sqlite3_value *pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16BE);







|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
int sqlite3_value_int(sqlite3_value *pVal){
  return sqlite3VdbeIntValue((Mem*)pVal);
}
sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
  return sqlite3VdbeIntValue((Mem*)pVal);
}
const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
  return (const char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_value_text16(sqlite3_value* pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
}
const void *sqlite3_value_text16be(sqlite3_value *pVal){
  return sqlite3ValueText(pVal, SQLITE_UTF16BE);
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
*/
void sqlite3_result_blob(
  sqlite3_context *pCtx, 
  const void *z, 
  int n, 
  void (*xDel)(void *)
){
  assert( n>=0 );
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);
}
void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
  sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
}
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
  pCtx->isError = 1;







|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
*/
void sqlite3_result_blob(
  sqlite3_context *pCtx, 
  const void *z, 
  int n, 
  void (*xDel)(void *)
){
  assert( n>0 );
  sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);
}
void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
  sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
}
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
  pCtx->isError = 1;
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
** statement is completely executed or an error occurs.
*/
int sqlite3_step(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  sqlite3 *db;
  int rc;

  /* Assert that malloc() has not failed */
  assert( !sqlite3ThreadDataReadOnly()->mallocFailed );

  if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }
  if( p->aborted ){
    return SQLITE_ABORT;
  }
  if( p->pc<=0 && p->expired ){
    if( p->rc==SQLITE_OK ){
      p->rc = SQLITE_SCHEMA;
    }
    return SQLITE_ERROR;
  }
  db = p->db;
  if( sqlite3SafetyOn(db) ){
    p->rc = SQLITE_MISUSE;
    return SQLITE_MISUSE;
  }
  if( p->pc<0 ){
#ifndef SQLITE_OMIT_TRACE
    /* Invoke the trace callback if there is one
    */
    if( db->xTrace && !db->init.busy ){
      assert( p->nOp>0 );
      assert( p->aOp[p->nOp-1].opcode==OP_Noop );
      assert( p->aOp[p->nOp-1].p3!=0 );
      assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC );
      sqlite3SafetyOff(db);
      db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3);
      if( sqlite3SafetyOn(db) ){
        p->rc = SQLITE_MISUSE;
        return SQLITE_MISUSE;
      }
    }
    if( db->xProfile && !db->init.busy ){
      double rNow;
      sqlite3OsCurrentTime(&rNow);
      p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0;
    }
#endif

    /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned
    ** on in debugging mode.
    */
#ifdef SQLITE_DEBUG
    if( (db->flags & SQLITE_SqlTrace)!=0 ){
      sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p3);







<
<
<


















<


|











<
<
<
<
<
<







153
154
155
156
157
158
159



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191






192
193
194
195
196
197
198
** statement is completely executed or an error occurs.
*/
int sqlite3_step(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  sqlite3 *db;
  int rc;




  if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }
  if( p->aborted ){
    return SQLITE_ABORT;
  }
  if( p->pc<=0 && p->expired ){
    if( p->rc==SQLITE_OK ){
      p->rc = SQLITE_SCHEMA;
    }
    return SQLITE_ERROR;
  }
  db = p->db;
  if( sqlite3SafetyOn(db) ){
    p->rc = SQLITE_MISUSE;
    return SQLITE_MISUSE;
  }
  if( p->pc<0 ){

    /* Invoke the trace callback if there is one
    */
    if( (db = p->db)->xTrace && !db->init.busy ){
      assert( p->nOp>0 );
      assert( p->aOp[p->nOp-1].opcode==OP_Noop );
      assert( p->aOp[p->nOp-1].p3!=0 );
      assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC );
      sqlite3SafetyOff(db);
      db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3);
      if( sqlite3SafetyOn(db) ){
        p->rc = SQLITE_MISUSE;
        return SQLITE_MISUSE;
      }
    }







    /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned
    ** on in debugging mode.
    */
#ifdef SQLITE_DEBUG
    if( (db->flags & SQLITE_SqlTrace)!=0 ){
      sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p3);
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261




262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    rc = sqlite3VdbeExec(p);
  }

  if( sqlite3SafetyOff(db) ){
    rc = SQLITE_MISUSE;
  }

#ifndef SQLITE_OMIT_TRACE
  /* Invoke the profile callback if there is one
  */
  if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy ){
    double rNow;
    u64 elapseTime;

    sqlite3OsCurrentTime(&rNow);
    elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime;
    assert( p->nOp>0 );
    assert( p->aOp[p->nOp-1].opcode==OP_Noop );
    assert( p->aOp[p->nOp-1].p3!=0 );
    assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC );
    db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p3, elapseTime);
  }
#endif

  sqlite3Error(p->db, rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
  sqlite3MallocClearFailed();
  return rc;
}

/*
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.
*/
void *sqlite3_user_data(sqlite3_context *p){
  assert( p && p->pFunc );
  return p->pFunc->pUserData;
}

/*
** Allocate or return the aggregate context for a user function.  A new
** context is allocated on the first call.  Subsequent calls return the
** same context that was returned on prior calls.




*/
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
  Mem *pMem = p->pMem;
  assert( p && p->pFunc && p->pFunc->xStep );
  if( (pMem->flags & MEM_Agg)==0 ){
    if( nByte==0 ){
      assert( pMem->flags==MEM_Null );
      pMem->z = 0;
    }else{
      pMem->flags = MEM_Agg;
      pMem->xDel = sqlite3FreeX;
      *(FuncDef**)&pMem->i = p->pFunc;
      if( nByte<=NBFS ){
        pMem->z = pMem->zShort;
        memset(pMem->z, 0, nByte);
      }else{
        pMem->z = sqliteMalloc( nByte );
      }
    }
  }
  return (void*)pMem->z;
}

/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){







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
















>
>
>
>


<

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







211
212
213
214
215
216
217

















218

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240

241

242






243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
    rc = sqlite3VdbeExec(p);
  }

  if( sqlite3SafetyOff(db) ){
    rc = SQLITE_MISUSE;
  }


















  sqlite3Error(p->db, rc, p->zErrMsg);

  return rc;
}

/*
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.
*/
void *sqlite3_user_data(sqlite3_context *p){
  assert( p && p->pFunc );
  return p->pFunc->pUserData;
}

/*
** Allocate or return the aggregate context for a user function.  A new
** context is allocated on the first call.  Subsequent calls return the
** same context that was returned on prior calls.
**
** This routine is defined here in vdbe.c because it depends on knowing
** the internals of the sqlite3_context structure which is only defined in
** this source file.
*/
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){

  assert( p && p->pFunc && p->pFunc->xStep );

  if( p->pAgg==0 ){






    if( nByte<=NBFS ){
      p->pAgg = (void*)p->s.z;
      memset(p->pAgg, 0, nByte);
    }else{
      p->pAgg = sqliteMalloc( nByte );
    }
  }

  return p->pAgg;
}

/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  struct AuxData *pAuxData;
  VdbeFunc *pVdbeFunc;
  if( iArg<0 ) return;

  pVdbeFunc = pCtx->pVdbeFunc;
  if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
    int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
    pVdbeFunc = sqliteRealloc(pVdbeFunc, nMalloc);
    if( !pVdbeFunc ) return;
    pCtx->pVdbeFunc = pVdbeFunc;
    memset(&pVdbeFunc->apAux[pVdbeFunc->nAux], 0, 
             sizeof(struct AuxData)*(iArg+1-pVdbeFunc->nAux));
    pVdbeFunc->nAux = iArg+1;
    pVdbeFunc->pFunc = pCtx->pFunc;
  }

  pAuxData = &pVdbeFunc->apAux[iArg];







|

<







276
277
278
279
280
281
282
283
284

285
286
287
288
289
290
291
  struct AuxData *pAuxData;
  VdbeFunc *pVdbeFunc;
  if( iArg<0 ) return;

  pVdbeFunc = pCtx->pVdbeFunc;
  if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
    int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
    pCtx->pVdbeFunc = pVdbeFunc = sqliteRealloc(pVdbeFunc, nMalloc);
    if( !pVdbeFunc ) return;

    memset(&pVdbeFunc->apAux[pVdbeFunc->nAux], 0, 
             sizeof(struct AuxData)*(iArg+1-pVdbeFunc->nAux));
    pVdbeFunc->nAux = iArg+1;
    pVdbeFunc->pFunc = pCtx->pFunc;
  }

  pAuxData = &pVdbeFunc->apAux[iArg];
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
**
** This routine is defined here in vdbe.c because it depends on knowing
** the internals of the sqlite3_context structure which is only defined in
** this source file.
*/
int sqlite3_aggregate_count(sqlite3_context *p){
  assert( p && p->pFunc && p->pFunc->xStep );
  return p->pMem->n;
}

/*
** Return the number of columns in the result set for the statement pStmt.
*/
int sqlite3_column_count(sqlite3_stmt *pStmt){
  Vdbe *pVm = (Vdbe *)pStmt;







|







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
**
** This routine is defined here in vdbe.c because it depends on knowing
** the internals of the sqlite3_context structure which is only defined in
** this source file.
*/
int sqlite3_aggregate_count(sqlite3_context *p){
  assert( p && p->pFunc && p->pFunc->xStep );
  return p->cnt;
}

/*
** Return the number of columns in the result set for the statement pStmt.
*/
int sqlite3_column_count(sqlite3_stmt *pStmt){
  Vdbe *pVm = (Vdbe *)pStmt;
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500


501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554

555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
    if( nullMem.flags==0 ){ nullMem.flags = MEM_Null; }
    sqlite3Error(pVm->db, SQLITE_RANGE, 0);
    return &nullMem;
  }
  return &pVm->pTos[(1-vals)+i];
}

/*
** This function is called after invoking an sqlite3_value_XXX function on a 
** column value (i.e. a value returned by evaluating an SQL expression in the
** select list of a SELECT statement) that may cause a malloc() failure. If 
** malloc() has failed, the threads mallocFailed flag is cleared and the result
** code of statement pStmt set to SQLITE_NOMEM.
**
** Specificly, this is called from within:
**
**     sqlite3_column_int()
**     sqlite3_column_int64()
**     sqlite3_column_text()
**     sqlite3_column_text16()
**     sqlite3_column_real()
**     sqlite3_column_bytes()
**     sqlite3_column_bytes16()
**
** But not for sqlite3_column_blob(), which never calls malloc().
*/
static void columnMallocFailure(sqlite3_stmt *pStmt)
{
  /* If malloc() failed during an encoding conversion within an
  ** sqlite3_column_XXX API, then set the return code of the statement to
  ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
  ** and _finalize() will return NOMEM.
  */
  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    ((Vdbe *)pStmt)->rc = SQLITE_NOMEM;
    sqlite3MallocClearFailed();
  }
}

/**************************** sqlite3_column_  *******************************
** The following routines are used to access elements of the current row
** in the result set.
*/
const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
  const void *val;
  sqlite3MallocDisallow();
  val = sqlite3_value_blob( columnMem(pStmt,i) );
  sqlite3MallocAllow();
  return val;
}
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
  int val = sqlite3_value_bytes( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
  int val = sqlite3_value_bytes16( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
  double val = sqlite3_value_double( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
  int val = sqlite3_value_int( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
  sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
  const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
#if 0
sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
  return columnMem(pStmt, i);
}
#endif
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
  const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
#endif /* SQLITE_OMIT_UTF16 */
int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_type( columnMem(pStmt,i) );
}

/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string.  If N is out of range, return 0.
**
** There are up to 5 names for each column.  useType determines which
** name is returned.  Here are the names:
**
**    0      The column name as it should be displayed for output
**    1      The datatype name for the column
**    2      The name of the database that the column derives from
**    3      The name of the table that the column derives from
**    4      The name of the table column that the result column derives from
**
** If the result is not a simple column reference (if it is an expression
** or a constant) then useTypes 2, 3, and 4 return NULL.
*/
static const void *columnName(
  sqlite3_stmt *pStmt,
  int N,
  const void *(*xFunc)(Mem*),
  int useType
){
  const void *ret;
  Vdbe *p = (Vdbe *)pStmt;
  int n = sqlite3_column_count(pStmt);

  if( p==0 || N>=n || N<0 ){
    return 0;
  }
  N += useType*n;


  ret = xFunc(&p->aColName[N]);

  /* A malloc may have failed inside of the xFunc() call. If this is the case,
  ** clear the mallocFailed flag and return NULL.
  */
  sqlite3MallocClearFailed();
  return ret;
}

/*
** Return the name of the Nth column of the result set returned by SQL
** statement pStmt.
*/
const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 0);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 0);
}
#endif

/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt.
*/
const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 1);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 1);
}
#endif /* SQLITE_OMIT_UTF16 */

#if !defined(SQLITE_OMIT_ORIGIN_NAMES) && 0
/*
** Return the name of the database from which a result column derives.
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unabiguous reference to a database column.
*/
const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 2);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 2);
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Return the name of the table from which a result column derives.
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unabiguous reference to a database column.

*/
const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 3);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 3);
}
#endif /* SQLITE_OMIT_UTF16 */

/*
** Return the name of the table column from which a result column derives.
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unabiguous reference to a database column.
*/
const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 4);
}
#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 4);
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_OMIT_ORIGIN_NAMES */




/******************************* sqlite3_bind_  ***************************
** 
** Routines used to attach values to wildcards in a compiled SQL statement.
*/
/*
** Unbind the value bound to variable i in virtual machine p. This is the 
** the same as binding a NULL value to the column. If the "i" parameter is
** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
**
** The error code stored in database p->db is overwritten with the return
** value in any case.
*/
static int vdbeUnbind(Vdbe *p, int i){
  Mem *pVar;
  if( p==0 || p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
    if( p ) sqlite3Error(p->db, SQLITE_MISUSE, 0);
    return SQLITE_MISUSE;
  }
  if( i<1 || i>p->nVar ){
    sqlite3Error(p->db, SQLITE_RANGE, 0);
    return SQLITE_RANGE;
  }
  i--;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<
<
|
<
<


|
<
<


|
<
<


|
<
<


|
<
<


|
<
<


|
<
<

<
<
<
<
<


|
<
<









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







<






|
>
>
|
|
<
<
<
<
<
|








<
<
<
<
<



|




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

<
<
<
<
<

|
<
<
>

<
<
<
<
|
|

<


|
|
<

<
<
<
<
|
|


<
<
<
<
















|







342
343
344
345
346
347
348
































349
350
351
352
353


354


355
356
357


358
359
360


361
362
363


364
365
366


367
368
369


370
371
372


373





374
375
376


377
378
379
380
381
382
383
384
385

386
387









388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405





406
407
408
409
410
411
412
413
414





415
416
417
418
419
420
421
422



423











424





425
426


427
428




429
430
431

432
433
434
435

436




437
438
439
440




441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
    if( nullMem.flags==0 ){ nullMem.flags = MEM_Null; }
    sqlite3Error(pVm->db, SQLITE_RANGE, 0);
    return &nullMem;
  }
  return &pVm->pTos[(1-vals)+i];
}

































/**************************** sqlite3_column_  *******************************
** The following routines are used to access elements of the current row
** in the result set.
*/
const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){


  return sqlite3_value_blob( columnMem(pStmt,i) );


}
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_bytes( columnMem(pStmt,i) );


}
int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_bytes16( columnMem(pStmt,i) );


}
double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_double( columnMem(pStmt,i) );


}
int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_int( columnMem(pStmt,i) );


}
sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_int64( columnMem(pStmt,i) );


}
const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_text( columnMem(pStmt,i) );


}





#ifndef SQLITE_OMIT_UTF16
const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_text16( columnMem(pStmt,i) );


}
#endif /* SQLITE_OMIT_UTF16 */
int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
  return sqlite3_value_type( columnMem(pStmt,i) );
}

/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string.  If N is out of range, return 0.

** If useType is 1, then use the second set of N elements (the datatype
** names) instead of the first set.









*/
static const void *columnName(
  sqlite3_stmt *pStmt,
  int N,
  const void *(*xFunc)(Mem*),
  int useType
){

  Vdbe *p = (Vdbe *)pStmt;
  int n = sqlite3_column_count(pStmt);

  if( p==0 || N>=n || N<0 ){
    return 0;
  }
  if( useType ){
    N += n;
  }
  return xFunc(&p->aColName[N]);
}







/*
** Return the name of the Nth column of the result set returned by SQL
** statement pStmt.
*/
const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 0);
}






/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-8.
*/
const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, 1);
}















#ifndef SQLITE_OMIT_UTF16





/*
** Return the name of the 'i'th column of the result set of SQL statement


** pStmt, encoded as UTF-16.
*/




const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 0);
}


/*
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt, encoded as UTF-16.

*/




const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
  return columnName(pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, 1);
}
#endif /* SQLITE_OMIT_UTF16 */





/******************************* sqlite3_bind_  ***************************
** 
** Routines used to attach values to wildcards in a compiled SQL statement.
*/
/*
** Unbind the value bound to variable i in virtual machine p. This is the 
** the same as binding a NULL value to the column. If the "i" parameter is
** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
**
** The error code stored in database p->db is overwritten with the return
** value in any case.
*/
static int vdbeUnbind(Vdbe *p, int i){
  Mem *pVar;
  if( p==0 || p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
    sqlite3Error(p->db, SQLITE_MISUSE, 0);
    return SQLITE_MISUSE;
  }
  if( i<1 || i>p->nVar ){
    sqlite3Error(p->db, SQLITE_RANGE, 0);
    return SQLITE_RANGE;
  }
  i--;
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
  }
  pVar = &p->aVar[i-1];
  rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
  if( rc ){
    return rc;
  }
  if( rc==SQLITE_OK && encoding!=0 ){
    rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
  }
  return rc;
}


/*
** Bind a blob value to an SQL statement variable.







|







490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
  }
  pVar = &p->aVar[i-1];
  rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
  if( rc ){
    return rc;
  }
  if( rc==SQLITE_OK && encoding!=0 ){
    rc = sqlite3VdbeChangeEncoding(pVar, p->db->enc);
  }
  return rc;
}


/*
** Bind a blob value to an SQL statement variable.
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
      if( z && strcmp(z,zName)==0 ){
        return i+1;
      }
    }
  }
  return 0;
}

/*
** Transfer all bindings from the first statement over to the second.
** If the two statements contain a different number of bindings, then
** an SQLITE_ERROR is returned.
*/
int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
  Vdbe *pFrom = (Vdbe*)pFromStmt;
  Vdbe *pTo = (Vdbe*)pToStmt;
  int i, rc = SQLITE_OK;
  if( (pFrom->magic!=VDBE_MAGIC_RUN && pFrom->magic!=VDBE_MAGIC_HALT)
    || (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT) ){
    return SQLITE_MISUSE;
  }
  if( pFrom->nVar!=pTo->nVar ){
    return SQLITE_ERROR;
  }
  for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){
    rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
  }
  return rc;
}

/*
** Return the sqlite3* database handle to which the prepared statement given
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
  return pStmt ? ((Vdbe*)pStmt)->db : 0;
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
618
619
620
621
622
623
624
































      if( z && strcmp(z,zName)==0 ){
        return i+1;
      }
    }
  }
  return 0;
}
































Changes to SQLite.Interop/src/vdbeaux.c.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35


/*
** When debugging the code generator in a symbolic debugger, one can
** set the sqlite3_vdbe_addop_trace to 1 and all opcodes will be printed
** as they are added to the instruction stream.
*/
#ifdef SQLITE_DEBUG
int sqlite3_vdbe_addop_trace = 0;
#endif


/*
** Create a new virtual database engine.
*/







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35


/*
** When debugging the code generator in a symbolic debugger, one can
** set the sqlite3_vdbe_addop_trace to 1 and all opcodes will be printed
** as they are added to the instruction stream.
*/
#ifndef NDEBUG
int sqlite3_vdbe_addop_trace = 0;
#endif


/*
** Create a new virtual database engine.
*/
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
*/
void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
  p->trace = trace;
}

/*
** Resize the Vdbe.aOp array so that it contains at least N
** elements. If the Vdbe is in VDBE_MAGIC_RUN state, then
** the Vdbe.aOp array will be sized to contain exactly N 
** elements.
*/
static void resizeOpArray(Vdbe *p, int N){
  int runMode = p->magic==VDBE_MAGIC_RUN;
  if( runMode || p->nOpAlloc<N ){
    VdbeOp *pNew;
    int nNew = N + 100*(!runMode);
    int oldSize = p->nOpAlloc;
    pNew = sqliteRealloc(p->aOp, nNew*sizeof(Op));
    if( pNew ){
      p->nOpAlloc = nNew;
      p->aOp = pNew;
      if( nNew>oldSize ){
        memset(&p->aOp[oldSize], 0, (nNew-oldSize)*sizeof(Op));
      }
    }
  }
}

/*
** Add a new instruction to the list of instructions current in the
** VDBE.  Return the address of the new instruction.







<
<



<
|
<
<

<
<
|
|
|
|
<







53
54
55
56
57
58
59


60
61
62

63


64


65
66
67
68

69
70
71
72
73
74
75
*/
void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
  p->trace = trace;
}

/*
** Resize the Vdbe.aOp array so that it contains at least N


** elements.
*/
static void resizeOpArray(Vdbe *p, int N){

  if( p->nOpAlloc<N ){


    int oldSize = p->nOpAlloc;


    p->nOpAlloc = N+100;
    p->aOp = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
    if( p->aOp ){
      memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));

    }
  }
}

/*
** Add a new instruction to the list of instructions current in the
** VDBE.  Return the address of the new instruction.
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  int i;
  VdbeOp *pOp;

  i = p->nOp;
  p->nOp++;
  assert( p->magic==VDBE_MAGIC_INIT );
  resizeOpArray(p, i+1);
  if( p->aOp==0 || p->nOpAlloc<=i ){
    return 0;
  }
  pOp = &p->aOp[i];
  pOp->opcode = op;
  pOp->p1 = p1;
  pOp->p2 = p2;
  pOp->p3 = 0;
  pOp->p3type = P3_NOTUSED;
  p->expired = 0;
#ifdef SQLITE_DEBUG
  if( sqlite3_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
#endif
  return i;
}

/*







|








<







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
  int i;
  VdbeOp *pOp;

  i = p->nOp;
  p->nOp++;
  assert( p->magic==VDBE_MAGIC_INIT );
  resizeOpArray(p, i+1);
  if( p->aOp==0 ){
    return 0;
  }
  pOp = &p->aOp[i];
  pOp->opcode = op;
  pOp->p1 = p1;
  pOp->p2 = p2;
  pOp->p3 = 0;
  pOp->p3type = P3_NOTUSED;

#ifdef SQLITE_DEBUG
  if( sqlite3_vdbe_addop_trace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
#endif
  return i;
}

/*
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
*/
int sqlite3VdbeMakeLabel(Vdbe *p){
  int i;
  i = p->nLabel++;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( i>=p->nLabelAlloc ){
    p->nLabelAlloc = p->nLabelAlloc*2 + 10;
    sqliteReallocOrFree((void**)&p->aLabel,
                          p->nLabelAlloc*sizeof(p->aLabel[0]));
  }
  if( p->aLabel ){
    p->aLabel[i] = -1;
  }
  return -1-i;
}








<
|







134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
*/
int sqlite3VdbeMakeLabel(Vdbe *p){
  int i;
  i = p->nLabel++;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( i>=p->nLabelAlloc ){
    p->nLabelAlloc = p->nLabelAlloc*2 + 10;

    p->aLabel = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
  }
  if( p->aLabel ){
    p->aLabel[i] = -1;
  }
  return -1-i;
}

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( j>=0 && j<p->nLabel );
  if( p->aLabel ){
    p->aLabel[j] = p->nOp;
  }
}

/*
** Return non-zero if opcode 'op' is guarenteed not to push more values
** onto the VDBE stack than it pops off.
*/
static int opcodeNoPush(u8 op){
  /* The 10 NOPUSH_MASK_n constants are defined in the automatically
  ** generated header file opcodes.h. Each is a 16-bit bitmask, one
  ** bit corresponding to each opcode implemented by the virtual
  ** machine in vdbe.c. The bit is true if the word "no-push" appears
  ** in a comment on the same line as the "case OP_XXX:" in 
  ** sqlite3VdbeExec() in vdbe.c.
  **
  ** If the bit is true, then the corresponding opcode is guarenteed not
  ** to grow the stack when it is executed. Otherwise, it may grow the
  ** stack by at most one entry.
  **
  ** NOPUSH_MASK_0 corresponds to opcodes 0 to 15. NOPUSH_MASK_1 contains
  ** one bit for opcodes 16 to 31, and so on.
  **
  ** 16-bit bitmasks (rather than 32-bit) are specified in opcodes.h 
  ** because the file is generated by an awk program. Awk manipulates
  ** all numbers as floating-point and we don't want to risk a rounding
  ** error if someone builds with an awk that uses (for example) 32-bit 
  ** IEEE floats.
  */ 
  static const u32 masks[5] = {
    NOPUSH_MASK_0 + (NOPUSH_MASK_1<<16),
    NOPUSH_MASK_2 + (NOPUSH_MASK_3<<16),
    NOPUSH_MASK_4 + (NOPUSH_MASK_5<<16),
    NOPUSH_MASK_6 + (NOPUSH_MASK_7<<16),
    NOPUSH_MASK_8 + (NOPUSH_MASK_9<<16)
  };
  assert( op<32*5 );
  return (masks[op>>5] & (1<<(op&0x1F)));
}

#ifndef NDEBUG
int sqlite3VdbeOpcodeNoPush(u8 op){
  return opcodeNoPush(op);
}
#endif

/*
** Loop through the program looking for P2 values that are negative.
** Each such value is a label.  Resolve the label by setting the P2
** value to its correct non-zero value.
**
** This routine is called once after all opcodes have been inserted.
**
** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument 
** to an OP_Function or OP_AggStep opcode. This is used by 
** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
**
** The integer *pMaxStack is set to the maximum number of vdbe stack
** entries that static analysis reveals this program might need.
**
** This routine also does the following optimization:  It scans for
** Halt instructions where P1==SQLITE_CONSTRAINT or P2==OE_Abort or for
** IdxInsert instructions where P2!=0.  If no such instruction is
** found, then every Statement instruction is changed to a Noop.  In
** this way, we avoid creating the statement journal file unnecessarily.
*/
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs, int *pMaxStack){
  int i;
  int nMaxArgs = 0;
  int nMaxStack = p->nOp;
  Op *pOp;
  int *aLabel = p->aLabel;
  int doesStatementRollback = 0;
  int hasStatementBegin = 0;

  for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
    u8 opcode = pOp->opcode;

    if( opcode==OP_Function || opcode==OP_AggStep ){
      if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
    }else if( opcode==OP_Halt ){
      if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
        doesStatementRollback = 1;
      }
    }else if( opcode==OP_IdxInsert ){
      if( pOp->p2 ){
        doesStatementRollback = 1;
      }
    }else if( opcode==OP_Statement ){
      hasStatementBegin = 1;
    }

    if( opcodeNoPush(opcode) ){
      nMaxStack--;
    }

    if( pOp->p2>=0 ) continue;
    assert( -1-pOp->p2<p->nLabel );
    pOp->p2 = aLabel[-1-pOp->p2];
  }
  sqliteFree(p->aLabel);
  p->aLabel = 0;

  *pMaxFuncArgs = nMaxArgs;
  *pMaxStack = nMaxStack;

  /* If we never rollback a statement transaction, then statement
  ** transactions are not needed.  So change every OP_Statement
  ** opcode into an OP_Noop.  This avoid a call to sqlite3OsOpenExclusive()
  ** which can be expensive on some platforms.
  */
  if( hasStatementBegin && !doesStatementRollback ){
    for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
      if( pOp->opcode==OP_Statement ){
        pOp->opcode = OP_Noop;
      }
    }
  }
}

/*
** Return the address of the next instruction to be inserted.
*/
int sqlite3VdbeCurrentAddr(Vdbe *p){
  assert( p->magic==VDBE_MAGIC_INIT );
  return p->nOp;
}

/*
** Add a whole list of operations to the operation stack.  Return the
** address of the first operation added.
*/
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
  int addr;
  assert( p->magic==VDBE_MAGIC_INIT );
  resizeOpArray(p, p->nOp + nOp);
  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    return 0;
  }
  addr = p->nOp;
  if( nOp>0 ){
    int i;
    VdbeOpList const *pIn = aOp;
    for(i=0; i<nOp; i++, pIn++){








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<
<
<
<
<
<
<
<
<
<
<
<
<

|

<
<


<
<
>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















|







156
157
158
159
160
161
162
163










































164
165
166
167
168













169
170
171


172
173


174
175




















176
177
178
179
180
181
















182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( j>=0 && j<p->nLabel );
  if( p->aLabel ){
    p->aLabel[j] = p->nOp;
  }
}

/*










































** Loop through the program looking for P2 values that are negative.
** Each such value is a label.  Resolve the label by setting the P2
** value to its correct non-zero value.
**
** This routine is called once after all opcodes have been inserted.













*/
static void resolveP2Values(Vdbe *p){
  int i;


  Op *pOp;
  int *aLabel = p->aLabel;


  if( aLabel==0 ) return;
  for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){




















    if( pOp->p2>=0 ) continue;
    assert( -1-pOp->p2<p->nLabel );
    pOp->p2 = aLabel[-1-pOp->p2];
  }
  sqliteFree(p->aLabel);
  p->aLabel = 0;
















}

/*
** Return the address of the next instruction to be inserted.
*/
int sqlite3VdbeCurrentAddr(Vdbe *p){
  assert( p->magic==VDBE_MAGIC_INIT );
  return p->nOp;
}

/*
** Add a whole list of operations to the operation stack.  Return the
** address of the first operation added.
*/
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
  int addr;
  assert( p->magic==VDBE_MAGIC_INIT );
  resizeOpArray(p, p->nOp + nOp);
  if( p->aOp==0 ){
    return 0;
  }
  addr = p->nOp;
  if( nOp>0 ){
    int i;
    VdbeOpList const *pIn = aOp;
    for(i=0; i<nOp; i++, pIn++){
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428

429
430

431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
  assert( val>=0 );
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p2 = val;
  }
}

/*
** Change teh P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  sqlite3VdbeChangeP2(p, addr, p->nOp);
}

/*
** Delete a P3 value if necessary.
*/
static void freeP3(int p3type, void *p3){
  if( p3 ){
    switch( p3type ){
      case P3_DYNAMIC:
      case P3_KEYINFO:
      case P3_KEYINFO_HANDOFF: {
        sqliteFree(p3);
        break;
      }
      case P3_VDBEFUNC: {
        VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
        sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
        sqliteFree(pVdbeFunc);
        break;
      }
      case P3_MEM: {
        sqlite3ValueFree((sqlite3_value*)p3);
        break;
      }
    }
  }
}


/*
** Change the value of the P3 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
** few minor changes to the program.
**
** If n>=0 then the P3 operand is dynamic, meaning that a copy of
** the string is made into memory obtained from sqliteMalloc().
** A value of n==0 means copy bytes of zP3 up to and including the
** first null byte.  If n>0 then copy n+1 bytes of zP3.
**
** If n==P3_KEYINFO it means that zP3 is a pointer to a KeyInfo structure.
** A copy is made of the KeyInfo structure into memory obtained from
** sqliteMalloc, to be freed when the Vdbe is finalized.

** n==P3_KEYINFO_HANDOFF indicates that zP3 points to a KeyInfo structure
** stored in memory that the caller has obtained from sqliteMalloc. The 
** caller should not free the allocation, it will be freed when the Vdbe is
** finalized.
** 
** Other values of n (P3_STATIC, P3_COLLSEQ etc.) indicate that zP3 points
** to a string or structure that is guaranteed to exist for the lifetime of
** the Vdbe. In these cases we can just copy the pointer.
**
** If addr<0 then change P3 on the most recently inserted instruction.
*/
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
  Op *pOp;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p==0 || p->aOp==0 || sqlite3ThreadDataReadOnly()->mallocFailed ){
    if (n != P3_KEYINFO) {
      freeP3(n, (void*)*(char**)&zP3);
    }
    return;
  }
  if( addr<0 || addr>=p->nOp ){
    addr = p->nOp - 1;
    if( addr<0 ) return;
  }
  pOp = &p->aOp[addr];

  freeP3(pOp->p3type, pOp->p3);
  pOp->p3 = 0;

  if( zP3==0 ){
    pOp->p3 = 0;
    pOp->p3type = P3_NOTUSED;
  }else if( n==P3_KEYINFO ){
    KeyInfo *pKeyInfo;
    int nField, nByte;

    nField = ((KeyInfo*)zP3)->nField;
    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
    pKeyInfo = sqliteMallocRaw( nByte );
    pOp->p3 = (char*)pKeyInfo;
    if( pKeyInfo ){
      char *aSortOrder;
      memcpy(pKeyInfo, zP3, nByte);
      aSortOrder = pKeyInfo->aSortOrder;
      if( aSortOrder ){
        pKeyInfo->aSortOrder = (char*)&pKeyInfo->aColl[nField];
        memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
      }
      pOp->p3type = P3_KEYINFO;
    }else{
      pOp->p3type = P3_NOTUSED;
    }
  }else if( n==P3_KEYINFO_HANDOFF ){
    pOp->p3 = (char*)zP3;
    pOp->p3type = P3_KEYINFO;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












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






|
<
<
<
<
<





>
|
|
>






<

|



<

<
<
<
<
<







243
244
245
246
247
248
249



































250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267






268
269
270
271
272
273
274





275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

290
291
292
293
294

295





296
297
298
299
300
301
302
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
  assert( val>=0 );
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p2 = val;
  }
}




































/*
** Change the value of the P3 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
** few minor changes to the program.
**
** If n>=0 then the P3 operand is dynamic, meaning that a copy of
** the string is made into memory obtained from sqliteMalloc().
** A value of n==0 means copy bytes of zP3 up to and including the
** first null byte.  If n>0 then copy n+1 bytes of zP3.
**
** If n==P3_STATIC  it means that zP3 is a pointer to a constant static
** string and we can just copy the pointer.  n==P3_POINTER means zP3 is
** a pointer to some object other than a string.  n==P3_COLLSEQ and
** n==P3_KEYINFO mean that zP3 is a pointer to a CollSeq or KeyInfo
** structure.  A copy is made of KeyInfo structures into memory obtained
** from sqliteMalloc.






**
** If addr<0 then change P3 on the most recently inserted instruction.
*/
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
  Op *pOp;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p==0 || p->aOp==0 ) return;





  if( addr<0 || addr>=p->nOp ){
    addr = p->nOp - 1;
    if( addr<0 ) return;
  }
  pOp = &p->aOp[addr];
  if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){
    sqliteFree(pOp->p3);
    pOp->p3 = 0;
  }
  if( zP3==0 ){
    pOp->p3 = 0;
    pOp->p3type = P3_NOTUSED;
  }else if( n==P3_KEYINFO ){
    KeyInfo *pKeyInfo;
    int nField, nByte;

    nField = ((KeyInfo*)zP3)->nField;
    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]);
    pKeyInfo = sqliteMallocRaw( nByte );
    pOp->p3 = (char*)pKeyInfo;
    if( pKeyInfo ){

      memcpy(pKeyInfo, zP3, nByte);





      pOp->p3type = P3_KEYINFO;
    }else{
      pOp->p3type = P3_NOTUSED;
    }
  }else if( n==P3_KEYINFO_HANDOFF ){
    pOp->p3 = (char*)zP3;
    pOp->p3type = P3_KEYINFO;
468
469
470
471
472
473
474
475
476
477
478
479
480
481









































482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501





502
503
504
505
506
507
508
/*
** Replace the P3 field of the most recently coded instruction with
** comment text.
*/
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
  va_list ap;
  assert( p->nOp>0 );
  assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 
          || sqlite3ThreadDataReadOnly()->mallocFailed );
  va_start(ap, zFormat);
  sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC);
  va_end(ap);
}
#endif










































/*
** Return the opcode for a given address.
*/
VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( addr>=0 && addr<p->nOp );
  return &p->aOp[addr];
}

#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Compute a string that describes the P3 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
static char *displayP3(Op *pOp, char *zTemp, int nTemp){
  char *zP3;
  assert( nTemp>=20 );
  switch( pOp->p3type ){





    case P3_KEYINFO: {
      int i, j;
      KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3;
      sprintf(zTemp, "keyinfo(%d", pKeyInfo->nField);
      i = strlen(zTemp);
      for(j=0; j<pKeyInfo->nField; j++){
        CollSeq *pColl = pKeyInfo->aColl[j];







|
<





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




















>
>
>
>
>







314
315
316
317
318
319
320
321

322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
/*
** Replace the P3 field of the most recently coded instruction with
** comment text.
*/
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
  va_list ap;
  assert( p->nOp>0 );
  assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 );

  va_start(ap, zFormat);
  sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC);
  va_end(ap);
}
#endif

/*
** If the P3 operand to the specified instruction appears
** to be a quoted string token, then this procedure removes 
** the quotes.
**
** The quoting operator can be either a grave ascent (ASCII 0x27)
** or a double quote character (ASCII 0x22).  Two quotes in a row
** resolve to be a single actual quote character within the string.
*/
void sqlite3VdbeDequoteP3(Vdbe *p, int addr){
  Op *pOp;
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p->aOp==0 ) return;
  if( addr<0 || addr>=p->nOp ){
    addr = p->nOp - 1;
    if( addr<0 ) return;
  }
  pOp = &p->aOp[addr];
  if( pOp->p3==0 || pOp->p3[0]==0 ) return;
  if( pOp->p3type==P3_STATIC ){
    pOp->p3 = sqliteStrDup(pOp->p3);
    pOp->p3type = P3_DYNAMIC;
  }
  assert( pOp->p3type==P3_DYNAMIC );
  sqlite3Dequote(pOp->p3);
}

/*
** Search the current program starting at instruction addr for the given
** opcode and P2 value.  Return the address plus 1 if found and 0 if not
** found.
*/
int sqlite3VdbeFindOp(Vdbe *p, int addr, int op, int p2){
  int i;
  assert( p->magic==VDBE_MAGIC_INIT );
  for(i=addr; i<p->nOp; i++){
    if( p->aOp[i].opcode==op && p->aOp[i].p2==p2 ) return i+1;
  }
  return 0;
}

/*
** Return the opcode for a given address.
*/
VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( addr>=0 && addr<p->nOp );
  return &p->aOp[addr];
}

#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
     || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Compute a string that describes the P3 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
static char *displayP3(Op *pOp, char *zTemp, int nTemp){
  char *zP3;
  assert( nTemp>=20 );
  switch( pOp->p3type ){
    case P3_POINTER: {
      sprintf(zTemp, "ptr(%#x)", (int)pOp->p3);
      zP3 = zTemp;
      break;
    }
    case P3_KEYINFO: {
      int i, j;
      KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3;
      sprintf(zTemp, "keyinfo(%d", pKeyInfo->nField);
      i = strlen(zTemp);
      for(j=0; j<pKeyInfo->nField; j++){
        CollSeq *pColl = pKeyInfo->aColl[j];
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
  ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
  */
  if( p->pTos==&p->aStack[4] ){
    releaseMemArray(p->aStack, 5);
  }
  p->resOnStack = 0;

  do{
    i = p->pc++;
  }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
  if( i>=p->nOp ){
    p->rc = SQLITE_OK;
    rc = SQLITE_DONE;
  }else if( db->flags & SQLITE_Interrupt ){
    db->flags &= ~SQLITE_Interrupt;
    p->rc = SQLITE_INTERRUPT;
    rc = SQLITE_ERROR;







|
|
<







501
502
503
504
505
506
507
508
509

510
511
512
513
514
515
516
  ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
  */
  if( p->pTos==&p->aStack[4] ){
    releaseMemArray(p->aStack, 5);
  }
  p->resOnStack = 0;


  i = p->pc++;

  if( i>=p->nOp ){
    p->rc = SQLITE_OK;
    rc = SQLITE_DONE;
  }else if( db->flags & SQLITE_Interrupt ){
    db->flags &= ~SQLITE_Interrupt;
    p->rc = SQLITE_INTERRUPT;
    rc = SQLITE_ERROR;
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
    pMem++;

    pMem->flags = MEM_Short|MEM_Str|MEM_Term;   /* P3 */
    pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort));
    pMem->type = SQLITE_TEXT;
    pMem->enc = SQLITE_UTF8;

    p->nResColumn = 5 - 2*(p->explain-1);
    p->pTos = pMem;
    p->rc = SQLITE_OK;
    p->resOnStack = 1;
    rc = SQLITE_ROW;
  }
  return rc;
}







|







541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
    pMem++;

    pMem->flags = MEM_Short|MEM_Str|MEM_Term;   /* P3 */
    pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort));
    pMem->type = SQLITE_TEXT;
    pMem->enc = SQLITE_UTF8;

    p->nResColumn = 5;
    p->pTos = pMem;
    p->rc = SQLITE_OK;
    p->resOnStack = 1;
    rc = SQLITE_ROW;
  }
  return rc;
}
692
693
694
695
696
697
698

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

741
742
743
744
745
746
747
748
749
750




751
752
753
754
755
756

757
758
759
760
761
762
763
** VDBE_MAGIC_RUN.
*/
void sqlite3VdbeMakeReady(
  Vdbe *p,                       /* The VDBE */
  int nVar,                      /* Number of '?' see in the SQL statement */
  int nMem,                      /* Number of memory cells to allocate */
  int nCursor,                   /* Number of cursors to allocate */

  int isExplain                  /* True if the EXPLAIN keywords is present */
){
  int n;

  assert( p!=0 );
  assert( p->magic==VDBE_MAGIC_INIT );

  /* There should be at least one opcode.
  */
  assert( p->nOp>0 );

  /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. This
   * is because the call to resizeOpArray() below may shrink the
   * p->aOp[] array to save memory if called when in VDBE_MAGIC_RUN 
   * state.
   */
  p->magic = VDBE_MAGIC_RUN;

  /* No instruction ever pushes more than a single element onto the
  ** stack.  And the stack never grows on successive executions of the
  ** same loop.  So the total number of instructions is an upper bound
  ** on the maximum stack depth required.  (Added later:)  The
  ** resolveP2Values() call computes a tighter upper bound on the
  ** stack size.
  **
  ** Allocation all the stack space we will ever need.
  */
  if( p->aStack==0 ){
    int nArg;       /* Maximum number of args passed to a user function. */
    int nStack;     /* Maximum number of stack entries required */
    resolveP2Values(p, &nArg, &nStack);
    resizeOpArray(p, p->nOp);
    assert( nVar>=0 );
    assert( nStack<p->nOp );
    nStack = isExplain ? 10 : nStack;
    p->aStack = sqliteMalloc(
        nStack*sizeof(p->aStack[0])    /* aStack */
      + nArg*sizeof(Mem*)              /* apArg */
      + nVar*sizeof(Mem)               /* aVar */
      + nVar*sizeof(char*)             /* azVar */
      + nMem*sizeof(Mem)               /* aMem */
      + nCursor*sizeof(Cursor*)        /* apCsr */

    );
    if( !sqlite3ThreadDataReadOnly()->mallocFailed ){
      p->aMem = &p->aStack[nStack];
      p->nMem = nMem;
      p->aVar = &p->aMem[nMem];
      p->nVar = nVar;
      p->okVar = 0;
      p->apArg = (Mem**)&p->aVar[nVar];
      p->azVar = (char**)&p->apArg[nArg];
      p->apCsr = (Cursor**)&p->azVar[nVar];




      p->nCursor = nCursor;
      for(n=0; n<nVar; n++){
        p->aVar[n].flags = MEM_Null;
      }
    }
  }

  for(n=0; n<p->nMem; n++){
    p->aMem[n].flags = MEM_Null;
  }

#ifdef SQLITE_DEBUG
  if( (p->db->flags & SQLITE_VdbeListing)!=0
    || sqlite3OsFileExists("vdbe_explain")







>











<
<
<
<
<
<
<



|
<
<




<
<
|
<

<
|

|
|




>

|
|





|

>
>
>
>






>







582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600







601
602
603
604


605
606
607
608


609

610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
** VDBE_MAGIC_RUN.
*/
void sqlite3VdbeMakeReady(
  Vdbe *p,                       /* The VDBE */
  int nVar,                      /* Number of '?' see in the SQL statement */
  int nMem,                      /* Number of memory cells to allocate */
  int nCursor,                   /* Number of cursors to allocate */
  int nAgg,                      /* Number of aggregate contexts required */
  int isExplain                  /* True if the EXPLAIN keywords is present */
){
  int n;

  assert( p!=0 );
  assert( p->magic==VDBE_MAGIC_INIT );

  /* There should be at least one opcode.
  */
  assert( p->nOp>0 );








  /* No instruction ever pushes more than a single element onto the
  ** stack.  And the stack never grows on successive executions of the
  ** same loop.  So the total number of instructions is an upper bound
  ** on the maximum stack depth required.


  **
  ** Allocation all the stack space we will ever need.
  */
  if( p->aStack==0 ){


    resolveP2Values(p);

    assert( nVar>=0 );

    n = isExplain ? 10 : p->nOp;
    p->aStack = sqliteMalloc(
        n*sizeof(p->aStack[0])         /* aStack */
      + n*sizeof(Mem*)                 /* apArg */
      + nVar*sizeof(Mem)               /* aVar */
      + nVar*sizeof(char*)             /* azVar */
      + nMem*sizeof(Mem)               /* aMem */
      + nCursor*sizeof(Cursor*)        /* apCsr */
      + nAgg*sizeof(Agg)               /* Aggregate contexts */
    );
    if( !sqlite3_malloc_failed ){
      p->aMem = &p->aStack[n];
      p->nMem = nMem;
      p->aVar = &p->aMem[nMem];
      p->nVar = nVar;
      p->okVar = 0;
      p->apArg = (Mem**)&p->aVar[nVar];
      p->azVar = (char**)&p->apArg[n];
      p->apCsr = (Cursor**)&p->azVar[nVar];
      if( nAgg>0 ){
        p->nAgg = nAgg;
        p->apAgg = (Agg*)&p->apCsr[nCursor];
      }
      p->nCursor = nCursor;
      for(n=0; n<nVar; n++){
        p->aVar[n].flags = MEM_Null;
      }
    }
  }
  p->pAgg = p->apAgg;
  for(n=0; n<p->nMem; n++){
    p->aMem[n].flags = MEM_Null;
  }

#ifdef SQLITE_DEBUG
  if( (p->db->flags & SQLITE_VdbeListing)!=0
    || sqlite3OsFileExists("vdbe_explain")
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
































































































































































799
800
801
802
803
804
805
  p->uniqueCnt = 0;
  p->returnDepth = 0;
  p->errorAction = OE_Abort;
  p->popStack =  0;
  p->explain |= isExplain;
  p->magic = VDBE_MAGIC_RUN;
  p->nChange = 0;
  p->cacheCtr = 1;
  p->minWriteFileFormat = 255;
#ifdef VDBE_PROFILE
  {
    int i;
    for(i=0; i<p->nOp; i++){
      p->aOp[i].cnt = 0;
      p->aOp[i].cycles = 0;
    }
  }
#endif
}

































































































































































/*
** Close a cursor and release all the resources that cursor happens
** to hold.
*/
void sqlite3VdbeFreeCursor(Cursor *pCx){
  if( pCx==0 ){
    return;







<
<











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







663
664
665
666
667
668
669


670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
  p->uniqueCnt = 0;
  p->returnDepth = 0;
  p->errorAction = OE_Abort;
  p->popStack =  0;
  p->explain |= isExplain;
  p->magic = VDBE_MAGIC_RUN;
  p->nChange = 0;


#ifdef VDBE_PROFILE
  {
    int i;
    for(i=0; i<p->nOp; i++){
      p->aOp[i].cnt = 0;
      p->aOp[i].cycles = 0;
    }
  }
#endif
}


/*
** Remove any elements that remain on the sorter for the VDBE given.
*/
void sqlite3VdbeSorterReset(Vdbe *p){
  while( p->pSort ){
    Sorter *pSorter = p->pSort;
    p->pSort = pSorter->pNext;
    sqliteFree(pSorter->zKey);
    sqlite3VdbeMemRelease(&pSorter->data);
    sqliteFree(pSorter);
  }
}

/*
** Free all resources allociated with AggElem pElem, an element of
** aggregate pAgg.
*/
static void freeAggElem(AggElem *pElem, Agg *pAgg){
  int i;
  for(i=0; i<pAgg->nMem; i++){
    Mem *pMem = &pElem->aMem[i];
    if( pAgg->apFunc && pAgg->apFunc[i] && (pMem->flags & MEM_AggCtx)!=0 ){
      sqlite3_context ctx;
      ctx.pFunc = pAgg->apFunc[i];
      ctx.s.flags = MEM_Null;
      ctx.pAgg = pMem->z;
      ctx.cnt = pMem->i;
      ctx.isError = 0;
      (*ctx.pFunc->xFinalize)(&ctx);
      pMem->z = ctx.pAgg;
      if( pMem->z!=0 && pMem->z!=pMem->zShort ){
        sqliteFree(pMem->z);
      }
      sqlite3VdbeMemRelease(&ctx.s);
    }else{
      sqlite3VdbeMemRelease(pMem);
    }
  }
  sqliteFree(pElem);
}

/*
** Reset an Agg structure.  Delete all its contents.
**
** For installable aggregate functions, if the step function has been
** called, make sure the finalizer function has also been called.  The
** finalizer might need to free memory that was allocated as part of its
** private context.  If the finalizer has not been called yet, call it
** now.
**
** If db is NULL, then this is being called from sqliteVdbeReset(). In
** this case clean up all references to the temp-table used for
** aggregates (if it was ever opened).
**
** If db is not NULL, then this is being called from with an OP_AggReset
** opcode. Open the temp-table, if it has not already been opened and
** delete the contents of the table used for aggregate information, ready
** for the next round of aggregate processing.
*/
int sqlite3VdbeAggReset(sqlite3 *db, Agg *pAgg, KeyInfo *pKeyInfo){
  int rc = 0;
  BtCursor *pCsr;

  if( !pAgg ) return SQLITE_OK;
  pCsr = pAgg->pCsr;
  assert( (pCsr && pAgg->nTab>0) || (!pCsr && pAgg->nTab==0)
         || sqlite3_malloc_failed );

  /* If pCsr is not NULL, then the table used for aggregate information
  ** is open. Loop through it and free the AggElem* structure pointed at
  ** by each entry. If the finalizer has not been called for an AggElem,
  ** do that too. Finally, clear the btree table itself.
  */
  if( pCsr ){
    int res;
    assert( pAgg->pBtree );
    assert( pAgg->nTab>0 );

    rc=sqlite3BtreeFirst(pCsr, &res);
    while( res==0 && rc==SQLITE_OK ){
      AggElem *pElem;
      rc = sqlite3BtreeData(pCsr, 0, sizeof(AggElem*), (char *)&pElem);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      assert( pAgg->apFunc!=0 );
      freeAggElem(pElem, pAgg);
      rc=sqlite3BtreeNext(pCsr, &res);
    }
    if( rc!=SQLITE_OK ){
      return rc;
    }

    sqlite3BtreeCloseCursor(pCsr);
    sqlite3BtreeClearTable(pAgg->pBtree, pAgg->nTab);
  }else{ 
    /* The cursor may not be open because the aggregator was never used,
    ** or it could be that it was used but there was no GROUP BY clause.
    */
    if( pAgg->pCurrent ){
      freeAggElem(pAgg->pCurrent, pAgg);
    }
  }

  /* If db is not NULL and we have not yet and we have not yet opened
  ** the temporary btree then do so and create the table to store aggregate
  ** information.
  **
  ** If db is NULL, then close the temporary btree if it is open.
  */
  if( db ){
    if( !pAgg->pBtree ){
      assert( pAgg->nTab==0 );
#ifndef SQLITE_OMIT_MEMORYDB
      rc = sqlite3BtreeFactory(db, ":memory:", 0, TEMP_PAGES, &pAgg->pBtree);
#else
      rc = sqlite3BtreeFactory(db, 0, 0, TEMP_PAGES, &pAgg->pBtree);
#endif
      if( rc!=SQLITE_OK ) return rc;
      sqlite3BtreeBeginTrans(pAgg->pBtree, 1);
      rc = sqlite3BtreeCreateTable(pAgg->pBtree, &pAgg->nTab, 0);
      if( rc!=SQLITE_OK ) return rc;
    }
    assert( pAgg->nTab!=0 );

    rc = sqlite3BtreeCursor(pAgg->pBtree, pAgg->nTab, 1,
        sqlite3VdbeRecordCompare, pKeyInfo, &pAgg->pCsr);
    if( rc!=SQLITE_OK ) return rc;
  }else{
    if( pAgg->pBtree ){
      sqlite3BtreeClose(pAgg->pBtree);
      pAgg->pBtree = 0;
      pAgg->nTab = 0;
    }
    pAgg->pCsr = 0;
  }

  if( pAgg->apFunc ){ 
    sqliteFree(pAgg->apFunc);
    pAgg->apFunc = 0;
  }
  pAgg->pCurrent = 0;
  pAgg->nMem = 0;
  pAgg->searching = 0;
  return SQLITE_OK;
}


/*
** Delete a keylist
*/
void sqlite3VdbeKeylistFree(Keylist *p){
  while( p ){
    Keylist *pNext = p->pNext;
    sqliteFree(p);
    p = pNext;
  }
}

/*
** Close a cursor and release all the resources that cursor happens
** to hold.
*/
void sqlite3VdbeFreeCursor(Cursor *pCx){
  if( pCx==0 ){
    return;
838
839
840
841
842
843
844

845


846
847
848
849
850
851




852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
  int i;
  if( p->aStack ){
    releaseMemArray(p->aStack, 1 + (p->pTos - p->aStack));
    p->pTos = &p->aStack[-1];
  }
  closeAllCursors(p);
  releaseMemArray(p->aMem, p->nMem);

  sqlite3VdbeFifoClear(&p->sFifo);


  if( p->contextStack ){
    for(i=0; i<p->contextStackTop; i++){
      sqlite3VdbeFifoClear(&p->contextStack[i].sFifo);
    }
    sqliteFree(p->contextStack);
  }




  p->contextStack = 0;
  p->contextStackDepth = 0;
  p->contextStackTop = 0;
  sqliteFree(p->zErrMsg);
  p->zErrMsg = 0;
}

/*
** Set the number of result columns that will be returned by this SQL
** statement. This is now set at compile time, rather than during
** execution of the vdbe program so that sqlite3_column_count() can
** be called on an SQL statement before sqlite3_step().
*/
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
  Mem *pColName;
  int n;
  releaseMemArray(p->aColName, p->nResColumn*2);
  sqliteFree(p->aColName);
  n = nResColumn*2;
  p->nResColumn = nResColumn;
  p->aColName = pColName = (Mem*)sqliteMalloc( sizeof(Mem)*n );
  if( p->aColName==0 ) return;
  while( n-- > 0 ){
    (pColName++)->flags = MEM_Null;
  }
}








>
|
>
>


|



>
>
>
>
















|
<
|
|







880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917

918
919
920
921
922
923
924
925
926
  int i;
  if( p->aStack ){
    releaseMemArray(p->aStack, 1 + (p->pTos - p->aStack));
    p->pTos = &p->aStack[-1];
  }
  closeAllCursors(p);
  releaseMemArray(p->aMem, p->nMem);
  if( p->pList ){
    sqlite3VdbeKeylistFree(p->pList);
    p->pList = 0;
  }
  if( p->contextStack ){
    for(i=0; i<p->contextStackTop; i++){
      sqlite3VdbeKeylistFree(p->contextStack[i].pList);
    }
    sqliteFree(p->contextStack);
  }
  sqlite3VdbeSorterReset(p);
  for(i=0; i<p->nAgg; i++){
    sqlite3VdbeAggReset(0, &p->apAgg[i], 0);
  }
  p->contextStack = 0;
  p->contextStackDepth = 0;
  p->contextStackTop = 0;
  sqliteFree(p->zErrMsg);
  p->zErrMsg = 0;
}

/*
** Set the number of result columns that will be returned by this SQL
** statement. This is now set at compile time, rather than during
** execution of the vdbe program so that sqlite3_column_count() can
** be called on an SQL statement before sqlite3_step().
*/
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
  Mem *pColName;
  int n;
  assert( 0==p->nResColumn );

  p->nResColumn = nResColumn;
  n = nResColumn*2;
  p->aColName = pColName = (Mem*)sqliteMalloc( sizeof(Mem)*n );
  if( p->aColName==0 ) return;
  while( n-- > 0 ){
    (pColName++)->flags = MEM_Null;
  }
}

887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
** the string is freed using sqliteFree() when the vdbe is finished with
** it. Otherwise, N bytes of zName are copied.
*/
int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
  int rc;
  Mem *pColName;
  assert( idx<(2*p->nResColumn) );
  if( sqlite3ThreadDataReadOnly()->mallocFailed ) return SQLITE_NOMEM;
  assert( p->aColName!=0 );
  pColName = &(p->aColName[idx]);
  if( N==P3_DYNAMIC || N==P3_STATIC ){
    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
  }else{
    rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
  }







|







935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
** the string is freed using sqliteFree() when the vdbe is finished with
** it. Otherwise, N bytes of zName are copied.
*/
int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
  int rc;
  Mem *pColName;
  assert( idx<(2*p->nResColumn) );
  if( sqlite3_malloc_failed ) return SQLITE_NOMEM;
  assert( p->aColName!=0 );
  pColName = &(p->aColName[idx]);
  if( N==P3_DYNAMIC || N==P3_STATIC ){
    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
  }else{
    rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
  }
924
925
926
927
928
929
930

931
932
933
934
935
936
937
      needXcommit = 1;
      if( i!=1 ) nTrans++;
    }
  }

  /* If there are any write-transactions at all, invoke the commit hook */
  if( needXcommit && db->xCommitCallback ){

    sqlite3SafetyOff(db);
    rc = db->xCommitCallback(db->pCommitArg);
    sqlite3SafetyOn(db);
    if( rc ){
      return SQLITE_CONSTRAINT;
    }
  }







>







972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
      needXcommit = 1;
      if( i!=1 ) nTrans++;
    }
  }

  /* If there are any write-transactions at all, invoke the commit hook */
  if( needXcommit && db->xCommitCallback ){
    int rc;
    sqlite3SafetyOff(db);
    rc = db->xCommitCallback(db->pCommitArg);
    sqlite3SafetyOn(db);
    if( rc ){
      return SQLITE_CONSTRAINT;
    }
  }
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989

990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
    }
  }

  /* The complex case - There is a multi-file write-transaction active.
  ** This requires a master journal file to ensure the transaction is
  ** committed atomicly.
  */
#ifndef SQLITE_OMIT_DISKIO
  else{
    int needSync = 0;
    char *zMaster = 0;   /* File-name for the master journal */
    char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
    OsFile *master = 0;

    /* Select a master journal file name */
    do {
      u32 random;
      sqliteFree(zMaster);
      sqlite3Randomness(sizeof(random), &random);
      zMaster = sqlite3MPrintf("%s-mj%08X", zMainFile, random&0x7fffffff);
      if( !zMaster ){
        return SQLITE_NOMEM;
      }
    }while( sqlite3OsFileExists(zMaster) );

    /* Open the master journal. */

    rc = sqlite3OsOpenExclusive(zMaster, &master, 0);
    if( rc!=SQLITE_OK ){
      sqliteFree(zMaster);
      return rc;
    }
 
    /* Write the name of each database file in the transaction into the new
    ** master journal file. If an error occurs at this point close
    ** and delete the master journal file. All the individual journal files
    ** still have 'null' as the master journal pointer, so they will roll
    ** back independently if a failure occurs.
    */
    for(i=0; i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( i==1 ) continue;   /* Ignore the TEMP database */
      if( pBt && sqlite3BtreeIsInTrans(pBt) ){
        char const *zFile = sqlite3BtreeGetJournalname(pBt);
        if( zFile[0]==0 ) continue;  /* Ignore :memory: databases */
        if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
          needSync = 1;
        }
        rc = sqlite3OsWrite(master, zFile, strlen(zFile)+1);
        if( rc!=SQLITE_OK ){
          sqlite3OsClose(&master);
          sqlite3OsDelete(zMaster);
          sqliteFree(zMaster);
          return rc;
        }
      }
    }


    /* Sync the master journal file. Before doing this, open the directory
    ** the master journal file is store in so that it gets synced too.
    */
    zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
    rc = sqlite3OsOpenDirectory(master, zMainFile);
    if( rc!=SQLITE_OK ||
          (needSync && (rc=sqlite3OsSync(master,0))!=SQLITE_OK) ){
      sqlite3OsClose(&master);
      sqlite3OsDelete(zMaster);
      sqliteFree(zMaster);
      return rc;
    }

    /* Sync all the db files involved in the transaction. The same call







<

<


|













>


















<
<
<
|














|
|
<







1013
1014
1015
1016
1017
1018
1019

1020

1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055



1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072

1073
1074
1075
1076
1077
1078
1079
    }
  }

  /* The complex case - There is a multi-file write-transaction active.
  ** This requires a master journal file to ensure the transaction is
  ** committed atomicly.
  */

  else{

    char *zMaster = 0;   /* File-name for the master journal */
    char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
    OsFile master;

    /* Select a master journal file name */
    do {
      u32 random;
      sqliteFree(zMaster);
      sqlite3Randomness(sizeof(random), &random);
      zMaster = sqlite3MPrintf("%s-mj%08X", zMainFile, random&0x7fffffff);
      if( !zMaster ){
        return SQLITE_NOMEM;
      }
    }while( sqlite3OsFileExists(zMaster) );

    /* Open the master journal. */
    memset(&master, 0, sizeof(master));
    rc = sqlite3OsOpenExclusive(zMaster, &master, 0);
    if( rc!=SQLITE_OK ){
      sqliteFree(zMaster);
      return rc;
    }
 
    /* Write the name of each database file in the transaction into the new
    ** master journal file. If an error occurs at this point close
    ** and delete the master journal file. All the individual journal files
    ** still have 'null' as the master journal pointer, so they will roll
    ** back independently if a failure occurs.
    */
    for(i=0; i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( i==1 ) continue;   /* Ignore the TEMP database */
      if( pBt && sqlite3BtreeIsInTrans(pBt) ){
        char const *zFile = sqlite3BtreeGetJournalname(pBt);
        if( zFile[0]==0 ) continue;  /* Ignore :memory: databases */



        rc = sqlite3OsWrite(&master, zFile, strlen(zFile)+1);
        if( rc!=SQLITE_OK ){
          sqlite3OsClose(&master);
          sqlite3OsDelete(zMaster);
          sqliteFree(zMaster);
          return rc;
        }
      }
    }


    /* Sync the master journal file. Before doing this, open the directory
    ** the master journal file is store in so that it gets synced too.
    */
    zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
    rc = sqlite3OsOpenDirectory(zMainFile, &master);
    if( rc!=SQLITE_OK || (rc = sqlite3OsSync(&master))!=SQLITE_OK ){

      sqlite3OsClose(&master);
      sqlite3OsDelete(zMaster);
      sqliteFree(zMaster);
      return rc;
    }

    /* Sync all the db files involved in the transaction. The same call
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
    for(i=0; i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( pBt ){
        sqlite3BtreeCommit(pBt);
      }
    }
  }
#endif

  return rc;
}

/*
** Find every active VM other than pVdbe and change its status to
** aborted.  This happens when one VM causes a rollback due to an







<







1129
1130
1131
1132
1133
1134
1135

1136
1137
1138
1139
1140
1141
1142
    for(i=0; i<db->nDb; i++){ 
      Btree *pBt = db->aDb[i].pBt;
      if( pBt ){
        sqlite3BtreeCommit(pBt);
      }
    }
  }


  return rc;
}

/*
** Find every active VM other than pVdbe and change its status to
** aborted.  This happens when one VM causes a rollback due to an
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234

1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
** means the close did not happen and needs to be repeated.
*/
int sqlite3VdbeHalt(Vdbe *p){
  sqlite3 *db = p->db;
  int i;
  int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */

  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    p->rc = SQLITE_NOMEM;
  }

  if( p->magic!=VDBE_MAGIC_RUN ){
    /* Already halted.  Nothing to do. */
    assert( p->magic==VDBE_MAGIC_HALT );
    return SQLITE_OK;
  }
  closeAllCursors(p);
  checkActiveVdbeCnt(db);
  if( p->pc<0 ){
    /* No commit or rollback needed if the program never started */
  }else if( db->autoCommit && db->activeVdbeCnt==1 ){

    if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && p->rc!=SQLITE_NOMEM)){
      /* The auto-commit flag is true, there are no other active queries
      ** using this handle and the vdbe program was successful or hit an
      ** 'OR FAIL' constraint. This means a commit is required.
      */
      int rc = vdbeCommit(db);
      if( rc==SQLITE_BUSY ){
        return SQLITE_BUSY;
      }else if( rc!=SQLITE_OK ){
        p->rc = rc;
        sqlite3RollbackAll(db);
      }else{
        sqlite3CommitInternalChanges(db);
      }
    }else{
      sqlite3RollbackAll(db);
    }
  }else{

    if( p->rc==SQLITE_NOMEM ){
      /* This loop does static analysis of the query to see which of the
      ** following three categories it falls into:
      **
      **     Read-only
      **     Query with statement journal          -> rollback statement
      **     Query without statement journal       -> rollback transaction
      **
      ** We could do something more elegant than this static analysis (i.e.
      ** store the type of query as part of the compliation phase), but 
      ** handling malloc() failure is a fairly obscure edge case so this is
      ** probably easier.
      **
      ** Todo: This means we always override the p->errorAction value for a
      ** malloc() failure. Is there any other choice here though?
      */
      int isReadOnly = 1;
      int isStatement = 0;
      assert(p->aOp || p->nOp==0);
      for(i=0; i<p->nOp; i++){ 
        switch( p->aOp[i].opcode ){
          case OP_Transaction:
            isReadOnly = 0;
            break;
          case OP_Statement:
            isStatement = 1;
            break;
        }
      }
      if( (isReadOnly||isStatement) && p->errorAction!=OE_Rollback ){
        p->errorAction = OE_Abort;
      }else{ 
        p->errorAction = OE_Rollback;
      }
    }

    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
      xFunc = sqlite3BtreeCommitStmt;
    }else if( p->errorAction==OE_Abort ){
      xFunc = sqlite3BtreeRollbackStmt;
    }else{
      abortOtherActiveVdbes(p);
      sqlite3RollbackAll(db);
      db->autoCommit = 1;

    }
  }

  /* If xFunc is not NULL, then it is one of 
  ** sqlite3BtreeRollbackStmt or sqlite3BtreeCommitStmt. Call it once on
  ** each backend. If an error occurs and the return code is still
  ** SQLITE_OK, set the return code to the new error value.
  */
  assert(!xFunc ||
    xFunc==sqlite3BtreeCommitStmt ||
    xFunc==sqlite3BtreeRollbackStmt
  );
  for(i=0; xFunc && i<db->nDb; i++){ 
    int rc;
    Btree *pBt = db->aDb[i].pBt;
    if( pBt ){
      rc = xFunc(pBt);
      if( p->rc==SQLITE_OK ) p->rc = rc;
    }
  }

  /* If this was an INSERT, UPDATE or DELETE, set the change counter. */
  if( p->changeCntOn && p->pc>=0 ){
    if( !xFunc || xFunc==sqlite3BtreeCommitStmt ){
      sqlite3VdbeSetChanges(db, p->nChange);
    }else{
      sqlite3VdbeSetChanges(db, 0);
    }
    p->nChange = 0;
  }

  /* Rollback or commit any schema changes that occurred. */
  if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){
    sqlite3ResetInternalSchema(db, 0);
    db->flags = (db->flags | SQLITE_InternChanges);

  }

  /* We have successfully halted and closed the VM.  Record this fact. */
  if( p->pc>=0 ){
    db->activeVdbeCnt--;
  }
  p->magic = VDBE_MAGIC_HALT;







<
<
<
<










<
|









|
<
<


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





<
|

>



|




<
<
<
<




















|
|
|
>







1193
1194
1195
1196
1197
1198
1199




1200
1201
1202
1203
1204
1205
1206
1207
1208
1209

1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220


1221
1222



1223



























1224



1225




1226
1227
1228
1229
1230

1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241




1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
** means the close did not happen and needs to be repeated.
*/
int sqlite3VdbeHalt(Vdbe *p){
  sqlite3 *db = p->db;
  int i;
  int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */





  if( p->magic!=VDBE_MAGIC_RUN ){
    /* Already halted.  Nothing to do. */
    assert( p->magic==VDBE_MAGIC_HALT );
    return SQLITE_OK;
  }
  closeAllCursors(p);
  checkActiveVdbeCnt(db);
  if( p->pc<0 ){
    /* No commit or rollback needed if the program never started */
  }else if( db->autoCommit && db->activeVdbeCnt==1 ){

    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
      /* The auto-commit flag is true, there are no other active queries
      ** using this handle and the vdbe program was successful or hit an
      ** 'OR FAIL' constraint. This means a commit is required.
      */
      int rc = vdbeCommit(db);
      if( rc==SQLITE_BUSY ){
        return SQLITE_BUSY;
      }else if( rc!=SQLITE_OK ){
        p->rc = rc;
        xFunc = sqlite3BtreeRollback;


      }
    }else{



      xFunc = sqlite3BtreeRollback;



























    }



  }else{




    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
      xFunc = sqlite3BtreeCommitStmt;
    }else if( p->errorAction==OE_Abort ){
      xFunc = sqlite3BtreeRollbackStmt;
    }else{

      xFunc = sqlite3BtreeRollback;
      db->autoCommit = 1;
      abortOtherActiveVdbes(p);
    }
  }

  /* If xFunc is not NULL, then it is one of sqlite3BtreeRollback,
  ** sqlite3BtreeRollbackStmt or sqlite3BtreeCommitStmt. Call it once on
  ** each backend. If an error occurs and the return code is still
  ** SQLITE_OK, set the return code to the new error value.
  */




  for(i=0; xFunc && i<db->nDb; i++){ 
    int rc;
    Btree *pBt = db->aDb[i].pBt;
    if( pBt ){
      rc = xFunc(pBt);
      if( p->rc==SQLITE_OK ) p->rc = rc;
    }
  }

  /* If this was an INSERT, UPDATE or DELETE, set the change counter. */
  if( p->changeCntOn && p->pc>=0 ){
    if( !xFunc || xFunc==sqlite3BtreeCommitStmt ){
      sqlite3VdbeSetChanges(db, p->nChange);
    }else{
      sqlite3VdbeSetChanges(db, 0);
    }
    p->nChange = 0;
  }

  /* Rollback or commit any schema changes that occurred. */
  if( p->rc!=SQLITE_OK ){
    sqlite3RollbackInternalChanges(db);
  }else if( db->flags & SQLITE_InternChanges ){
    sqlite3CommitInternalChanges(db);
  }

  /* We have successfully halted and closed the VM.  Record this fact. */
  if( p->pc>=0 ){
    db->activeVdbeCnt--;
  }
  p->magic = VDBE_MAGIC_HALT;
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341

  /* Reclaim all memory used by the VDBE
  */
  Cleanup(p);

  /* Save profiling information from this VDBE run.
  */
  assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || !p->aStack );
#ifdef VDBE_PROFILE
  {
    FILE *out = fopen("vdbe_profile.out", "a");
    if( out ){
      int i;
      fprintf(out, "---- ");
      for(i=0; i<p->nOp; i++){







|







1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337

  /* Reclaim all memory used by the VDBE
  */
  Cleanup(p);

  /* Save profiling information from this VDBE run.
  */
  assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || sqlite3_malloc_failed==1 );
#ifdef VDBE_PROFILE
  {
    FILE *out = fopen("vdbe_profile.out", "a");
    if( out ){
      int i;
      fprintf(out, "---- ");
      for(i=0; i<p->nOp; i++){
1412
1413
1414
1415
1416
1417
1418



1419




1420
1421
1422
1423
1424
1425
1426
  }
  if( p->pNext ){
    p->pNext->pPrev = p->pPrev;
  }
  if( p->aOp ){
    for(i=0; i<p->nOp; i++){
      Op *pOp = &p->aOp[i];



      freeP3(pOp->p3type, pOp->p3);




    }
    sqliteFree(p->aOp);
  }
  releaseMemArray(p->aVar, p->nVar);
  sqliteFree(p->aLabel);
  sqliteFree(p->aStack);
  releaseMemArray(p->aColName, p->nResColumn*2);







>
>
>
|
>
>
>
>







1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
  }
  if( p->pNext ){
    p->pNext->pPrev = p->pPrev;
  }
  if( p->aOp ){
    for(i=0; i<p->nOp; i++){
      Op *pOp = &p->aOp[i];
      if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){
        sqliteFree(pOp->p3);
      }
      if( pOp->p3type==P3_VDBEFUNC ){
        VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
        sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
        sqliteFree(pVdbeFunc);
      }
    }
    sqliteFree(p->aOp);
  }
  releaseMemArray(p->aVar, p->nVar);
  sqliteFree(p->aLabel);
  sqliteFree(p->aStack);
  releaseMemArray(p->aColName, p->nResColumn*2);
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
** MoveTo now.  Return an error code.  If no MoveTo is pending, this
** routine does nothing and returns SQLITE_OK.
*/
int sqlite3VdbeCursorMoveto(Cursor *p){
  if( p->deferredMoveto ){
    int res, rc;
    extern int sqlite3_search_count;
    assert( p->isTable );
    if( p->isTable ){
      rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
    }else{
      rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,
                              sizeof(i64),&res);
    }
    if( rc ) return rc;
    *p->pIncrKey = 0;
    p->lastRowid = keyToInt(p->movetoTarget);
    p->rowidIsValid = res==0;
    if( res<0 ){
      rc = sqlite3BtreeNext(p->pCursor, &res);
      if( rc ) return rc;
    }
    sqlite3_search_count++;
    p->deferredMoveto = 0;
    p->cacheStatus = CACHE_STALE;
  }
  return SQLITE_OK;
}

/*
** The following functions:
**







|
|







|
|






|







1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
** MoveTo now.  Return an error code.  If no MoveTo is pending, this
** routine does nothing and returns SQLITE_OK.
*/
int sqlite3VdbeCursorMoveto(Cursor *p){
  if( p->deferredMoveto ){
    int res, rc;
    extern int sqlite3_search_count;
    assert( p->intKey );
    if( p->intKey ){
      rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
    }else{
      rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,
                              sizeof(i64),&res);
    }
    if( rc ) return rc;
    *p->pIncrKey = 0;
    p->lastRecno = keyToInt(p->movetoTarget);
    p->recnoIsValid = res==0;
    if( res<0 ){
      rc = sqlite3BtreeNext(p->pCursor, &res);
      if( rc ) return rc;
    }
    sqlite3_search_count++;
    p->deferredMoveto = 0;
    p->cacheValid = 0;
  }
  return SQLITE_OK;
}

/*
** The following functions:
**
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
**      1                     1            signed integer
**      2                     2            signed integer
**      3                     3            signed integer
**      4                     4            signed integer
**      5                     6            signed integer
**      6                     8            signed integer
**      7                     8            IEEE float
**      8                     0            Integer constant 0
**      9                     0            Integer constant 1
**     10,11                               reserved for expansion
**    N>=12 and even       (N-12)/2        BLOB
**    N>=13 and odd        (N-13)/2        text
**
** The 8 and 9 types were added in 3.3.0, file format 4.  Prior versions
** of SQLite will not understand those serial types.
*/

/*
** Return the serial-type for the value stored in pMem.
*/
u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
  int flags = pMem->flags;

  if( flags&MEM_Null ){
    return 0;
  }
  if( flags&MEM_Int ){
    /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
#   define MAX_6BYTE ((((i64)0x00001000)<<32)-1)
    i64 i = pMem->i;
    u64 u;
    if( file_format>=4 && (i&1)==i ){
      return 8+i;
    }
    u = i<0 ? -i : i;
    if( u<=127 ) return 1;
    if( u<=32767 ) return 2;
    if( u<=8388607 ) return 3;
    if( u<=2147483647 ) return 4;
    if( u<=MAX_6BYTE ) return 5;
    return 6;
  }







<
<
|



<
<





|







|

<
<
<
<
|







1491
1492
1493
1494
1495
1496
1497


1498
1499
1500
1501


1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516




1517
1518
1519
1520
1521
1522
1523
1524
**      1                     1            signed integer
**      2                     2            signed integer
**      3                     3            signed integer
**      4                     4            signed integer
**      5                     6            signed integer
**      6                     8            signed integer
**      7                     8            IEEE float


**     8-11                                reserved for expansion
**    N>=12 and even       (N-12)/2        BLOB
**    N>=13 and odd        (N-13)/2        text
**


*/

/*
** Return the serial-type for the value stored in pMem.
*/
u32 sqlite3VdbeSerialType(Mem *pMem){
  int flags = pMem->flags;

  if( flags&MEM_Null ){
    return 0;
  }
  if( flags&MEM_Int ){
    /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
#   define MAX_6BYTE ((((i64)0x00010000)<<32)-1)
    i64 i = pMem->i;




    u64 u = i<0 ? -i : i;
    if( u<=127 ) return 1;
    if( u<=32767 ) return 2;
    if( u<=8388607 ) return 3;
    if( u<=2147483647 ) return 4;
    if( u<=MAX_6BYTE ) return 5;
    return 6;
  }
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564





1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601


1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613


1614



1615
1616

1617
1618
1619

1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647

1648

1649
1650
1651

1652
1653
1654

1655
1656
1657

1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
}

/*
** Write the serialized data blob for the value stored in pMem into 
** buf. It is assumed that the caller has allocated sufficient space.
** Return the number of bytes written.
*/ 
int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem, int file_format){
  u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
  int len;






  /* Integer and Real */
  if( serial_type<=7 && serial_type>0 ){
    u64 v;
    int i;
    if( serial_type==7 ){
      v = *(u64*)&pMem->r;
    }else{
      v = *(u64*)&pMem->i;
    }
    len = i = sqlite3VdbeSerialTypeLen(serial_type);
    while( i-- ){
      buf[i] = (v&0xFF);
      v >>= 8;
    }
    return len;
  }

  /* String or blob */
  if( serial_type>=12 ){
    len = sqlite3VdbeSerialTypeLen(serial_type);
    memcpy(buf, pMem->z, len);
    return len;
  }

  /* NULL or constants 0 or 1 */
  return 0;
}

/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem.  Return the number of bytes read.
*/ 
int sqlite3VdbeSerialGet(
  const unsigned char *buf,     /* Buffer to deserialize from */
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
){


  switch( serial_type ){
    case 10:   /* Reserved for future use */
    case 11:   /* Reserved for future use */
    case 0: {  /* NULL */
      pMem->flags = MEM_Null;
      break;
    }
    case 1: { /* 1-byte signed integer */
      pMem->i = (signed char)buf[0];
      pMem->flags = MEM_Int;
      return 1;
    }


    case 2: { /* 2-byte signed integer */



      pMem->i = (((signed char)buf[0])<<8) | buf[1];
      pMem->flags = MEM_Int;

      return 2;
    }
    case 3: { /* 3-byte signed integer */

      pMem->i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
      pMem->flags = MEM_Int;
      return 3;
    }
    case 4: { /* 4-byte signed integer */
      pMem->i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
      pMem->flags = MEM_Int;
      return 4;
    }
    case 5: { /* 6-byte signed integer */
      u64 x = (((signed char)buf[0])<<8) | buf[1];
      u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
      x = (x<<32) | y;
      pMem->i = *(i64*)&x;
      pMem->flags = MEM_Int;
      return 6;
    }
    case 6:   /* 8-byte signed integer */
    case 7: { /* IEEE floating point */
      u64 x;
      u32 y;
#ifndef NDEBUG
      /* Verify that integers and floating point values use the same
      ** byte order.  The byte order differs on some (broken) architectures.
      */
      static const u64 t1 = ((u64)0x3ff00000)<<32;
      assert( 1.0==*(double*)&t1 );
#endif



      x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
      y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
      x = (x<<32) | y;

      if( serial_type==6 ){
        pMem->i = *(i64*)&x;
        pMem->flags = MEM_Int;

      }else{
        pMem->r = *(double*)&x;
        pMem->flags = MEM_Real;

      }
      return 8;
    }
    case 8:    /* Integer 0 */
    case 9: {  /* Integer 1 */
      pMem->i = serial_type-8;
      pMem->flags = MEM_Int;
      return 0;
    }
    default: {
      int len = (serial_type-12)/2;
      pMem->z = (char *)buf;
      pMem->n = len;
      pMem->xDel = 0;
      if( serial_type&0x01 ){
        pMem->flags = MEM_Str | MEM_Ephem;
      }else{
        pMem->flags = MEM_Blob | MEM_Ephem;
      }
      return len;
    }
  }
  return 0;
}

/*
** The header of a record consists of a sequence variable-length integers.
** These integers are almost always small and are encoded as a single byte.
** The following macro takes advantage this fact to provide a fast decode
** of the integers in a record header.  It is faster for the common case
** where the integer is a single byte.  It is a little slower when the
** integer is two or more bytes.  But overall it is faster.
**
** The following expressions are equivalent:
**
**     x = sqlite3GetVarint32( A, &B );
**
**     x = GetVarint( A, B );
**
*/
#define GetVarint(A,B)  ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B))

/*
** This function compares the two table rows or index records specified by 
** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero
** or positive integer if {nKey1, pKey1} is less than, equal to or 
** greater than {nKey2, pKey2}.  Both Key1 and Key2 must be byte strings
** composed by the OP_MakeRecord opcode of the VDBE.







|
|


>
>
>
>
>

|














|

|
|
|
|
<
<
<
<











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

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

<
|
>

<

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

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586




1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600


1601
1602





1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615

1616
1617


1618


1619






1620

1621
1622


1623
1624
1625





1626
1627
1628
1629
1630


1631
1632

1633
1634
1635

1636
1637
1638

1639
1640
1641
1642





1643
1644
1645
1646
1647
1648
1649
1650

1651

1652
1653

















1654
1655
1656
1657
1658
1659
1660
}

/*
** Write the serialized data blob for the value stored in pMem into 
** buf. It is assumed that the caller has allocated sufficient space.
** Return the number of bytes written.
*/ 
int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem){
  u32 serial_type = sqlite3VdbeSerialType(pMem);
  int len;

  /* NULL */
  if( serial_type==0 ){
    return 0;
  }
 
  /* Integer and Real */
  if( serial_type<=7 ){
    u64 v;
    int i;
    if( serial_type==7 ){
      v = *(u64*)&pMem->r;
    }else{
      v = *(u64*)&pMem->i;
    }
    len = i = sqlite3VdbeSerialTypeLen(serial_type);
    while( i-- ){
      buf[i] = (v&0xFF);
      v >>= 8;
    }
    return len;
  }
  
  /* String or blob */
  assert( serial_type>=12 );
  len = sqlite3VdbeSerialTypeLen(serial_type);
  memcpy(buf, pMem->z, len);
  return len;




}

/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem.  Return the number of bytes read.
*/ 
int sqlite3VdbeSerialGet(
  const unsigned char *buf,     /* Buffer to deserialize from */
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */
){
  int len;

  if( serial_type==0 ){


    /* NULL */
    pMem->flags = MEM_Null;





    return 0;
  }
  len = sqlite3VdbeSerialTypeLen(serial_type);
  if( serial_type<=7 ){
    /* Integer and Real */
    if( serial_type<=4 ){
      /* 32-bit integer type.  This is handled by a special case for
      ** performance reasons. */
      int v = buf[0];
      int n;
      if( v&0x80 ){
        v |= -256;
      }

      for(n=1; n<len; n++){
        v = (v<<8) | buf[n];


      }


      pMem->flags = MEM_Int;






      pMem->i = v;

      return n;
    }else{


      u64 v = 0;
      int n;






      if( buf[0]&0x80 ){
        v = -1;
      }
      for(n=0; n<len; n++){
        v = (v<<8) | buf[n];


      }
      if( serial_type==7 ){

        pMem->flags = MEM_Real;
        pMem->r = *(double*)&v;
      }else{

        pMem->flags = MEM_Int;
        pMem->i = *(i64*)&v;
      }

    }
  }else{
    /* String or blob */
    assert( serial_type>=12 );





    pMem->z = (char *)buf;
    pMem->n = len;
    pMem->xDel = 0;
    if( serial_type&0x01 ){
      pMem->flags = MEM_Str | MEM_Ephem;
    }else{
      pMem->flags = MEM_Blob | MEM_Ephem;
    }

  }

  return len;
}


















/*
** This function compares the two table rows or index records specified by 
** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero
** or positive integer if {nKey1, pKey1} is less than, equal to or 
** greater than {nKey2, pKey2}.  Both Key1 and Key2 must be byte strings
** composed by the OP_MakeRecord opcode of the VDBE.
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770

1771
1772
1773
1774
1775
1776
1777
1778
1779
  const unsigned char *aKey2 = (const unsigned char *)pKey2;

  Mem mem1;
  Mem mem2;
  mem1.enc = pKeyInfo->enc;
  mem2.enc = pKeyInfo->enc;
  
  idx1 = GetVarint(aKey1, szHdr1);
  d1 = szHdr1;
  idx2 = GetVarint(aKey2, szHdr2);
  d2 = szHdr2;
  nField = pKeyInfo->nField;
  while( idx1<szHdr1 && idx2<szHdr2 ){
    u32 serial_type1;
    u32 serial_type2;

    /* Read the serial types for the next element in each key. */
    idx1 += GetVarint( aKey1+idx1, serial_type1 );
    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
    idx2 += GetVarint( aKey2+idx2, serial_type2 );
    if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;

    /* Assert that there is enough space left in each key for the blob of
    ** data to go with the serial type just read. This assert may fail if
    ** the file is corrupted.  Then read the value from each key into mem1
    ** and mem2 respectively.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
    d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);

    rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
    if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
    if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);
    if( rc!=0 ){
      break;
    }
    i++;
  }

  /* One of the keys ran out of fields, but all the fields up to that point
  ** were equal. If the incrKey flag is true, then the second key is
  ** treated as larger.
  */
  if( rc==0 ){
    if( pKeyInfo->incrKey ){
      rc = -1;
    }else if( d1<nKey1 ){
      rc = 1;
    }else if( d2<nKey2 ){
      rc = -1;
    }

  }else if( pKeyInfo->aSortOrder && i<pKeyInfo->nField
               && pKeyInfo->aSortOrder[i] ){
    rc = -rc;
  }

  return rc;
}

/*







|

|







|

|











|
|


















>
|
|







1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
  const unsigned char *aKey2 = (const unsigned char *)pKey2;

  Mem mem1;
  Mem mem2;
  mem1.enc = pKeyInfo->enc;
  mem2.enc = pKeyInfo->enc;
  
  idx1 = sqlite3GetVarint32(pKey1, &szHdr1);
  d1 = szHdr1;
  idx2 = sqlite3GetVarint32(pKey2, &szHdr2);
  d2 = szHdr2;
  nField = pKeyInfo->nField;
  while( idx1<szHdr1 && idx2<szHdr2 ){
    u32 serial_type1;
    u32 serial_type2;

    /* Read the serial types for the next element in each key. */
    idx1 += sqlite3GetVarint32(&aKey1[idx1], &serial_type1);
    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
    idx2 += sqlite3GetVarint32(&aKey2[idx2], &serial_type2);
    if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;

    /* Assert that there is enough space left in each key for the blob of
    ** data to go with the serial type just read. This assert may fail if
    ** the file is corrupted.  Then read the value from each key into mem1
    ** and mem2 respectively.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
    d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);

    rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
    sqlite3VdbeMemRelease(&mem1);
    sqlite3VdbeMemRelease(&mem2);
    if( rc!=0 ){
      break;
    }
    i++;
  }

  /* One of the keys ran out of fields, but all the fields up to that point
  ** were equal. If the incrKey flag is true, then the second key is
  ** treated as larger.
  */
  if( rc==0 ){
    if( pKeyInfo->incrKey ){
      rc = -1;
    }else if( d1<nKey1 ){
      rc = 1;
    }else if( d2<nKey2 ){
      rc = -1;
    }
  }

  if( pKeyInfo->aSortOrder && i<pKeyInfo->nField && pKeyInfo->aSortOrder[i] ){
    rc = -rc;
  }

  return rc;
}

/*
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
  u32 szHdr;        /* Size of the header */
  u32 typeRowid;    /* Serial type of the rowid */
  u32 lenRowid;     /* Size of the rowid */
  Mem m, v;

  sqlite3BtreeKeySize(pCur, &nCellKey);
  if( nCellKey<=0 ){
    return SQLITE_CORRUPT_BKPT;
  }
  rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  sqlite3GetVarint32((u8*)m.z, &szHdr);
  sqlite3GetVarint32((u8*)&m.z[szHdr-1], &typeRowid);
  lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
  sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
  *rowid = v.i;
  sqlite3VdbeMemRelease(&m);
  return SQLITE_OK;
}

/*
** Compare the key of the index entry that cursor pC is point to against







|





|
|

|







1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
  u32 szHdr;        /* Size of the header */
  u32 typeRowid;    /* Serial type of the rowid */
  u32 lenRowid;     /* Size of the rowid */
  Mem m, v;

  sqlite3BtreeKeySize(pCur, &nCellKey);
  if( nCellKey<=0 ){
    return SQLITE_CORRUPT;
  }
  rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  sqlite3GetVarint32(m.z, &szHdr);
  sqlite3GetVarint32(&m.z[szHdr-1], &typeRowid);
  lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
  sqlite3VdbeSerialGet(&m.z[m.n-lenRowid], typeRowid, &v);
  *rowid = v.i;
  sqlite3VdbeMemRelease(&m);
  return SQLITE_OK;
}

/*
** Compare the key of the index entry that cursor pC is point to against
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
    *res = 0;
    return SQLITE_OK;
  }
  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  lenRowid = sqlite3VdbeIdxRowidLen(m.n, (u8*)m.z);
  *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey);
  sqlite3VdbeMemRelease(&m);
  return SQLITE_OK;
}

/*
** This routine sets the value to be returned by subsequent calls to







|







1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
    *res = 0;
    return SQLITE_OK;
  }
  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  lenRowid = sqlite3VdbeIdxRowidLen(m.n, m.z);
  *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey);
  sqlite3VdbeMemRelease(&m);
  return SQLITE_OK;
}

/*
** This routine sets the value to be returned by subsequent calls to
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
*/
void sqlite3ExpirePreparedStatements(sqlite3 *db){
  Vdbe *p;
  for(p = db->pVdbe; p; p=p->pNext){
    p->expired = 1;
  }
}

/*
** Return the database associated with the Vdbe.
*/
sqlite3 *sqlite3VdbeDb(Vdbe *v){
  return v->db;
}







<
<
<
<
<
<
<
1843
1844
1845
1846
1847
1848
1849







*/
void sqlite3ExpirePreparedStatements(sqlite3 *db){
  Vdbe *p;
  for(p = db->pVdbe; p; p=p->pNext){
    p->expired = 1;
  }
}







Deleted SQLite.Interop/src/vdbefifo.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
** 2005 June 16
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file implements a FIFO queue of rowids used for processing
** UPDATE and DELETE statements.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

/*
** Allocate a new FifoPage and return a pointer to it.  Return NULL if
** we run out of memory.  Leave space on the page for nEntry entries.
*/
static FifoPage *allocatePage(int nEntry){
  FifoPage *pPage;
  if( nEntry>32767 ){
    nEntry = 32767;
  }
  pPage = sqliteMallocRaw( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
  if( pPage ){
    pPage->nSlot = nEntry;
    pPage->iWrite = 0;
    pPage->iRead = 0;
    pPage->pNext = 0;
  }
  return pPage;
}

/*
** Initialize a Fifo structure.
*/
void sqlite3VdbeFifoInit(Fifo *pFifo){
  memset(pFifo, 0, sizeof(*pFifo));
}

/*
** Push a single 64-bit integer value into the Fifo.  Return SQLITE_OK
** normally.   SQLITE_NOMEM is returned if we are unable to allocate
** memory.
*/
int sqlite3VdbeFifoPush(Fifo *pFifo, i64 val){
  FifoPage *pPage;
  pPage = pFifo->pLast;
  if( pPage==0 ){
    pPage = pFifo->pLast = pFifo->pFirst = allocatePage(20);
    if( pPage==0 ){
      return SQLITE_NOMEM;
    }
  }else if( pPage->iWrite>=pPage->nSlot ){
    pPage->pNext = allocatePage(pFifo->nEntry);
    if( pPage->pNext==0 ){
      return SQLITE_NOMEM;
    }
    pPage = pFifo->pLast = pPage->pNext;
  }
  pPage->aSlot[pPage->iWrite++] = val;
  pFifo->nEntry++;
  return SQLITE_OK;
}

/*
** Extract a single 64-bit integer value from the Fifo.  The integer
** extracted is the one least recently inserted.  If the Fifo is empty
** return SQLITE_DONE.
*/
int sqlite3VdbeFifoPop(Fifo *pFifo, i64 *pVal){
  FifoPage *pPage;
  if( pFifo->nEntry==0 ){
    return SQLITE_DONE;
  }
  assert( pFifo->nEntry>0 );
  pPage = pFifo->pFirst;
  assert( pPage!=0 );
  assert( pPage->iWrite>pPage->iRead );
  assert( pPage->iWrite<=pPage->nSlot );
  assert( pPage->iRead<pPage->nSlot );
  assert( pPage->iRead>=0 );
  *pVal = pPage->aSlot[pPage->iRead++];
  pFifo->nEntry--;
  if( pPage->iRead>=pPage->iWrite ){
    pFifo->pFirst = pPage->pNext;
    sqliteFree(pPage);
    if( pFifo->nEntry==0 ){
      assert( pFifo->pLast==pPage );
      pFifo->pLast = 0;
    }else{
      assert( pFifo->pFirst!=0 );
    }
  }else{
    assert( pFifo->nEntry>0 );
  }
  return SQLITE_OK;
}

/*
** Delete all information from a Fifo object.   Free all memory held
** by the Fifo.
*/
void sqlite3VdbeFifoClear(Fifo *pFifo){
  FifoPage *pPage, *pNextPage;
  for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
    pNextPage = pPage->pNext;
    sqliteFree(pPage);
  }
  sqlite3VdbeFifoInit(pFifo);
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































Changes to SQLite.Interop/src/vdbemem.c.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  int rc;
  if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
    return SQLITE_OK;
  }
#ifdef SQLITE_OMIT_UTF16
  return SQLITE_ERROR;
#else

  /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned,
  ** then the encoding of the value may not have changed.
  */
  rc = sqlite3VdbeMemTranslate(pMem, desiredEnc);
  assert(rc==SQLITE_OK    || rc==SQLITE_NOMEM);
  assert(rc==SQLITE_OK    || pMem->enc!=desiredEnc);
  assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);

  if( rc==SQLITE_NOMEM ){
/*
    sqlite3VdbeMemRelease(pMem);
    pMem->flags = MEM_Null;
    pMem->z = 0;
*/
  }
  return rc;
#endif
}

/*
** Make the given Mem object MEM_Dyn.







<
<
<
<

<
<
<
<

<



<







37
38
39
40
41
42
43




44




45

46
47
48

49
50
51
52
53
54
55
  int rc;
  if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
    return SQLITE_OK;
  }
#ifdef SQLITE_OMIT_UTF16
  return SQLITE_ERROR;
#else




  rc = sqlite3VdbeMemTranslate(pMem, desiredEnc);




  if( rc==SQLITE_NOMEM ){

    sqlite3VdbeMemRelease(pMem);
    pMem->flags = MEM_Null;
    pMem->z = 0;

  }
  return rc;
#endif
}

/*
** Make the given Mem object MEM_Dyn.
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
    return SQLITE_NOMEM;
  }
  pMem->flags |= MEM_Dyn|MEM_Term;
  pMem->xDel = 0;
  memcpy(z, pMem->z, n );
  z[n] = 0;
  z[n+1] = 0;
  pMem->z = (char*)z;
  pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short);
  return SQLITE_OK;
}

/*
** Make the given Mem object either MEM_Short or MEM_Dyn so that bytes
** of the Mem.z[] array can be modified.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite3VdbeMemMakeWriteable(Mem *pMem){
  int n;
  u8 *z;
  if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){
    return SQLITE_OK;
  }
  assert( (pMem->flags & MEM_Dyn)==0 );
  assert( pMem->flags & (MEM_Str|MEM_Blob) );
  if( (n = pMem->n)+2<sizeof(pMem->zShort) ){
    z = (u8*)pMem->zShort;
    pMem->flags |= MEM_Short|MEM_Term;
  }else{
    z = sqliteMallocRaw( n+2 );
    if( z==0 ){
      return SQLITE_NOMEM;
    }
    pMem->flags |= MEM_Dyn|MEM_Term;
    pMem->xDel = 0;
  }
  memcpy(z, pMem->z, n );
  z[n] = 0;
  z[n+1] = 0;
  pMem->z = (char*)z;
  pMem->flags &= ~(MEM_Ephem|MEM_Static);
  return SQLITE_OK;
}

/*
** Make sure the given Mem is \u0000 terminated.
*/







|



















|












|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    return SQLITE_NOMEM;
  }
  pMem->flags |= MEM_Dyn|MEM_Term;
  pMem->xDel = 0;
  memcpy(z, pMem->z, n );
  z[n] = 0;
  z[n+1] = 0;
  pMem->z = z;
  pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short);
  return SQLITE_OK;
}

/*
** Make the given Mem object either MEM_Short or MEM_Dyn so that bytes
** of the Mem.z[] array can be modified.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite3VdbeMemMakeWriteable(Mem *pMem){
  int n;
  u8 *z;
  if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){
    return SQLITE_OK;
  }
  assert( (pMem->flags & MEM_Dyn)==0 );
  assert( pMem->flags & (MEM_Str|MEM_Blob) );
  if( (n = pMem->n)+2<sizeof(pMem->zShort) ){
    z = pMem->zShort;
    pMem->flags |= MEM_Short|MEM_Term;
  }else{
    z = sqliteMallocRaw( n+2 );
    if( z==0 ){
      return SQLITE_NOMEM;
    }
    pMem->flags |= MEM_Dyn|MEM_Term;
    pMem->xDel = 0;
  }
  memcpy(z, pMem->z, n );
  z[n] = 0;
  z[n+1] = 0;
  pMem->z = z;
  pMem->flags &= ~(MEM_Ephem|MEM_Static);
  return SQLITE_OK;
}

/*
** Make sure the given Mem is \u0000 terminated.
*/
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
** sqlite3_value_text()), or for ensuring that values to be used as btree
** keys are strings. In the former case a NULL pointer is returned the
** user and the later is an internal programming error.
*/
int sqlite3VdbeMemStringify(Mem *pMem, int enc){
  int rc = SQLITE_OK;
  int fg = pMem->flags;
  char *z = pMem->zShort;

  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );

  /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
  ** string representation of the value. Then, if the required encoding
  ** is UTF-16le or UTF-16be do a translation.
  ** 
  ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
  */
  if( fg & MEM_Int ){
    sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
  }else{
    assert( fg & MEM_Real );
    sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r);
  }
  pMem->n = strlen(z);
  pMem->z = z;
  pMem->enc = SQLITE_UTF8;
  pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
  sqlite3VdbeChangeEncoding(pMem, enc);
  return rc;
}

/*
** Memory cell pMem contains the context of an aggregate function.
** This routine calls the finalize method for that function.  The
** result of the aggregate is stored back into pMem.
*/
void sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
  if( pFunc && pFunc->xFinalize ){
    sqlite3_context ctx;
    assert( (pMem->flags & MEM_Null)!=0 || pFunc==*(FuncDef**)&pMem->i );
    ctx.s.flags = MEM_Null;
    ctx.s.z = pMem->zShort;
    ctx.pMem = pMem;
    ctx.pFunc = pFunc;
    pFunc->xFinalize(&ctx);
    if( pMem->z && pMem->z!=pMem->zShort ){
      sqliteFree( pMem->z );
    }
    *pMem = ctx.s;
    if( pMem->flags & MEM_Short ){
      pMem->z = pMem->zShort;
    }
  }
}

/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.type==SQLITE_TEXT).
*/
void sqlite3VdbeMemRelease(Mem *p){
  if( p->flags & (MEM_Dyn|MEM_Agg) ){
    if( p->xDel ){
      if( p->flags & MEM_Agg ){
        sqlite3VdbeMemFinalize(p, *(FuncDef**)&p->i);
        assert( (p->flags & MEM_Agg)==0 );
        sqlite3VdbeMemRelease(p);
      }else{
        p->xDel((void *)p->z);
      }
    }else{
      sqliteFree(p->z);
    }
    p->z = 0;
    p->xDel = 0;
  }
}







|










|
|

|
|









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|

<
<
<
<
<
|
<







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
























190
191
192
193
194
195
196
197





198

199
200
201
202
203
204
205
** sqlite3_value_text()), or for ensuring that values to be used as btree
** keys are strings. In the former case a NULL pointer is returned the
** user and the later is an internal programming error.
*/
int sqlite3VdbeMemStringify(Mem *pMem, int enc){
  int rc = SQLITE_OK;
  int fg = pMem->flags;
  u8 *z = pMem->zShort;

  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );

  /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
  ** string representation of the value. Then, if the required encoding
  ** is UTF-16le or UTF-16be do a translation.
  ** 
  ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
  */
  if( fg & MEM_Real ){
    sqlite3_snprintf(NBFS, z, "%.15g", pMem->r);
  }else{
    assert( fg & MEM_Int );
    sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
  }
  pMem->n = strlen(z);
  pMem->z = z;
  pMem->enc = SQLITE_UTF8;
  pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
  sqlite3VdbeChangeEncoding(pMem, enc);
  return rc;
}

























/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.type==SQLITE_TEXT).
*/
void sqlite3VdbeMemRelease(Mem *p){
  if( p->flags & MEM_Dyn ){
    if( p->xDel ){





      p->xDel((void *)p->z);

    }else{
      sqliteFree(p->z);
    }
    p->z = 0;
    p->xDel = 0;
  }
}
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275










276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
    return pMem->i;
  }else if( flags & MEM_Real ){
    return (i64)pMem->r;
  }else if( flags & (MEM_Str|MEM_Blob) ){
    i64 value;
    if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
       || sqlite3VdbeMemNulTerminate(pMem) ){
      return 0;
    }
    assert( pMem->z );
    sqlite3atoi64(pMem->z, &value);
    return value;
  }else{
    return 0;
  }
}











/*
** Return the best representation of pMem that we can get into a
** double.  If pMem is already a double or an integer, return its
** value.  If it is a string or blob, try to convert it to a double.
** If it is a NULL, return 0.0.
*/
double sqlite3VdbeRealValue(Mem *pMem){
  if( pMem->flags & MEM_Real ){
    return pMem->r;
  }else if( pMem->flags & MEM_Int ){
    return (double)pMem->i;
  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
    double val = 0.0;
    if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
       || sqlite3VdbeMemNulTerminate(pMem) ){
      return 0.0;
    }
    assert( pMem->z );
    sqlite3AtoF(pMem->z, &val);
    return val;
  }else{
    return 0.0;
  }
}

/*
** The MEM structure is already a MEM_Real.  Try to also make it a
** MEM_Int if we can.
*/
void sqlite3VdbeIntegerAffinity(Mem *pMem){
  assert( pMem->flags & MEM_Real );
  pMem->i = pMem->r;
  if( ((double)pMem->i)==pMem->r ){
    pMem->flags |= MEM_Int;
  }
}

/*
** Convert pMem to type integer.  Invalidate any prior representations.
*/
int sqlite3VdbeMemIntegerify(Mem *pMem){
  pMem->i = sqlite3VdbeIntValue(pMem);
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Int;
  return SQLITE_OK;
}

/*
** Convert pMem so that it is of type MEM_Real.
** Invalidate any prior representations.
*/
int sqlite3VdbeMemRealify(Mem *pMem){
  pMem->r = sqlite3VdbeRealValue(pMem);
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Real;
  return SQLITE_OK;
}

/*
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Invalidate any prior representations.
*/
int sqlite3VdbeMemNumerify(Mem *pMem){
  sqlite3VdbeMemRealify(pMem);
  sqlite3VdbeIntegerAffinity(pMem);
  return SQLITE_OK;
}

/*
** Delete any previous value and set the value stored in *pMem to NULL.
*/
void sqlite3VdbeMemSetNull(Mem *pMem){
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Null;
  pMem->type = SQLITE_NULL;
  pMem->n = 0;
}

/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type INTEGER.
*/
void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){







|








>
>
>
>
>
>
>
>
>
>













<


|


|
<






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








<
<
<
<
<
<
<
<
<
<







<







220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

259
260
261
262
263
264

265
266
267
268
269
270






















271
272
273
274
275
276
277
278
279
280










281
282
283
284
285
286
287

288
289
290
291
292
293
294
    return pMem->i;
  }else if( flags & MEM_Real ){
    return (i64)pMem->r;
  }else if( flags & (MEM_Str|MEM_Blob) ){
    i64 value;
    if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
       || sqlite3VdbeMemNulTerminate(pMem) ){
      return SQLITE_NOMEM;
    }
    assert( pMem->z );
    sqlite3atoi64(pMem->z, &value);
    return value;
  }else{
    return 0;
  }
}

/*
** Convert pMem to type integer.  Invalidate any prior representations.
*/
int sqlite3VdbeMemIntegerify(Mem *pMem){
  pMem->i = sqlite3VdbeIntValue(pMem);
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Int;
  return SQLITE_OK;
}

/*
** Return the best representation of pMem that we can get into a
** double.  If pMem is already a double or an integer, return its
** value.  If it is a string or blob, try to convert it to a double.
** If it is a NULL, return 0.0.
*/
double sqlite3VdbeRealValue(Mem *pMem){
  if( pMem->flags & MEM_Real ){
    return pMem->r;
  }else if( pMem->flags & MEM_Int ){
    return (double)pMem->i;
  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){

    if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
       || sqlite3VdbeMemNulTerminate(pMem) ){
      return SQLITE_NOMEM;
    }
    assert( pMem->z );
    return sqlite3AtoF(pMem->z, 0);

  }else{
    return 0.0;
  }
}

/*






















** Convert pMem so that it is of type MEM_Real.  Invalidate any
** prior representations.
*/
int sqlite3VdbeMemRealify(Mem *pMem){
  pMem->r = sqlite3VdbeRealValue(pMem);
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Real;
  return SQLITE_OK;
}











/*
** Delete any previous value and set the value stored in *pMem to NULL.
*/
void sqlite3VdbeMemSetNull(Mem *pMem){
  sqlite3VdbeMemRelease(pMem);
  pMem->flags = MEM_Null;
  pMem->type = SQLITE_NULL;

}

/*
** Delete any previous value and set the value stored in *pMem to val,
** manifest type INTEGER.
*/
void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
  pMem->n = n;

  assert( enc==0 || enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE 
      || enc==SQLITE_UTF16BE );
  switch( enc ){
    case 0:
      pMem->flags |= MEM_Blob;
      pMem->enc = SQLITE_UTF8;
      break;

    case SQLITE_UTF8:
      pMem->flags |= MEM_Str;
      if( n<0 ){
        pMem->n = strlen(z);
        pMem->flags |= MEM_Term;







<







402
403
404
405
406
407
408

409
410
411
412
413
414
415
  pMem->n = n;

  assert( enc==0 || enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE 
      || enc==SQLITE_UTF16BE );
  switch( enc ){
    case 0:
      pMem->flags |= MEM_Blob;

      break;

    case SQLITE_UTF8:
      pMem->flags |= MEM_Str;
      if( n<0 ){
        pMem->n = strlen(z);
        pMem->flags |= MEM_Term;
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
      return -1;
    }

    assert( pMem1->enc==pMem2->enc );
    assert( pMem1->enc==SQLITE_UTF8 || 
            pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );

    /* The collation sequence must be defined at this point, even if
    ** the user deletes the collation sequence after the vdbe program is
    ** compiled (this was not always the case).
    */
    assert( !pColl || pColl->xCmp );

    if( pColl ){
      if( pMem1->enc==pColl->enc ){
        return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
      }else{







|
|
|







509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
      return -1;
    }

    assert( pMem1->enc==pMem2->enc );
    assert( pMem1->enc==SQLITE_UTF8 || 
            pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );

    /* This assert may fail if the collation sequence is deleted after this
    ** vdbe program is compiled. The documentation defines this as an
    ** undefined condition. A crash is usual result.
    */
    assert( !pColl || pColl->xCmp );

    if( pColl ){
      if( pMem1->enc==pColl->enc ){
        return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
      }else{
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
      rc = sqlite3BtreeKey(pCur, offset, amt, zData);
    }else{
      rc = sqlite3BtreeData(pCur, offset, amt, zData);
    }
    zData[amt] = 0;
    zData[amt+1] = 0;
    if( rc!=SQLITE_OK ){
      if( amt>NBFS-2 ){
        assert( zData!=pMem->zShort );
        assert( pMem->flags & MEM_Dyn );
        sqliteFree(zData);
      } else {
        assert( zData==pMem->zShort );
        assert( pMem->flags & MEM_Short );
      }
      return rc;
    }
  }

  return SQLITE_OK;
}







|
<
<

<
<
<







604
605
606
607
608
609
610
611


612



613
614
615
616
617
618
619
      rc = sqlite3BtreeKey(pCur, offset, amt, zData);
    }else{
      rc = sqlite3BtreeData(pCur, offset, amt, zData);
    }
    zData[amt] = 0;
    zData[amt+1] = 0;
    if( rc!=SQLITE_OK ){
      if( amt>NBFS ){


        sqliteFree(zData);



      }
      return rc;
    }
  }

  return SQLITE_OK;
}
728
729
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
    /* Cannot define a string subtype for non-string objects */
    assert( (pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
    assert( pMem->xDel==0 );
  }
  /* MEM_Null excludes all other types */
  assert( (pMem->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0
          || (pMem->flags&MEM_Null)==0 );
  /* If the MEM is both real and integer, the values are equal */
  assert( (pMem->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) 
          || pMem->r==pMem->i );

}
#endif

/* This function is only available internally, it is not part of the
** external API. It works in a similar way to sqlite3_value_text(),
** except the data returned is in the encoding specified by the second
** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
** SQLITE_UTF8.
*/
const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
  if( !pVal ) return 0;
  assert( enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE || enc==SQLITE_UTF8);

  if( pVal->flags&MEM_Null ){
    return 0;
  }
  assert( (MEM_Blob>>3) == MEM_Str );
  pVal->flags |= (pVal->flags & MEM_Blob)>>3;
  if( pVal->flags&MEM_Str ){
    sqlite3VdbeChangeEncoding(pVal, enc);
  }else if( !(pVal->flags&MEM_Blob) ){
    sqlite3VdbeMemStringify(pVal, enc);
  }
  assert(pVal->enc==enc || sqlite3ThreadDataReadOnly()->mallocFailed);
  return (const void *)(pVal->enc==enc ? (pVal->z) : 0);
}

/*
** Create a new sqlite3_value object.
*/
sqlite3_value* sqlite3ValueNew(void){
  Mem *p = sqliteMalloc(sizeof(*p));
  if( p ){
    p->flags = MEM_Null;
    p->type = SQLITE_NULL;
  }
  return p;
}

/*
** Create a new sqlite3_value object, containing the value of pExpr.
**
** This only works for very simple expressions that consist of one constant
** token (i.e. "5", "5.1", "NULL", "'a string'"). If the expression can
** be converted directly into a value, then the value is allocated and
** a pointer written to *ppVal. The caller is responsible for deallocating
** the value by passing it to sqlite3ValueFree() later on. If the expression
** cannot be converted to a value, then *ppVal is set to NULL.
*/
int sqlite3ValueFromExpr(
  Expr *pExpr, 
  u8 enc, 
  u8 affinity,
  sqlite3_value **ppVal
){
  int op;
  char *zVal = 0;
  sqlite3_value *pVal = 0;

  if( !pExpr ){
    *ppVal = 0;
    return SQLITE_OK;
  }
  op = pExpr->op;

  if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
    zVal = sqliteStrNDup((char*)pExpr->token.z, pExpr->token.n);
    pVal = sqlite3ValueNew();
    if( !zVal || !pVal ) goto no_mem;
    sqlite3Dequote(zVal);
    sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, sqlite3FreeX);
    if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
      sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc);
    }else{
      sqlite3ValueApplyAffinity(pVal, affinity, enc);
    }
  }else if( op==TK_UMINUS ) {
    if( SQLITE_OK==sqlite3ValueFromExpr(pExpr->pLeft, enc, affinity, &pVal) ){
      pVal->i = -1 * pVal->i;
      pVal->r = -1.0 * pVal->r;
    }
  }
#ifndef SQLITE_OMIT_BLOB_LITERAL
  else if( op==TK_BLOB ){
    int nVal;
    pVal = sqlite3ValueNew();
    zVal = sqliteStrNDup((char*)pExpr->token.z+1, pExpr->token.n-1);
    if( !zVal || !pVal ) goto no_mem;
    sqlite3Dequote(zVal);
    nVal = strlen(zVal)/2;
    sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(zVal), nVal, 0, sqlite3FreeX);
    sqliteFree(zVal);
  }
#endif

  *ppVal = pVal;
  return SQLITE_OK;

no_mem:
  sqliteFree(zVal);
  sqlite3ValueFree(pVal);
  *ppVal = 0;
  return SQLITE_NOMEM;
}

/*
** Change the string value of an sqlite3_value object
*/
void sqlite3ValueSetStr(
  sqlite3_value *v, 
  int n, 
  const void *z, 







<
|
|
>
















<
<





<
|





|








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







657
658
659
660
661
662
663

664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682


683
684
685
686
687

688
689
690
691
692
693
694
695
696
697
698
699
700
701
702


































































703
704
705
706
707
708
709
    /* Cannot define a string subtype for non-string objects */
    assert( (pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
    assert( pMem->xDel==0 );
  }
  /* MEM_Null excludes all other types */
  assert( (pMem->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0
          || (pMem->flags&MEM_Null)==0 );

  if( (pMem->flags & (MEM_Int|MEM_Real))==(MEM_Int|MEM_Real) ){
    assert( pMem->r==pMem->i );
  }
}
#endif

/* This function is only available internally, it is not part of the
** external API. It works in a similar way to sqlite3_value_text(),
** except the data returned is in the encoding specified by the second
** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
** SQLITE_UTF8.
*/
const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
  if( !pVal ) return 0;
  assert( enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE || enc==SQLITE_UTF8);

  if( pVal->flags&MEM_Null ){
    return 0;
  }


  if( pVal->flags&MEM_Str ){
    sqlite3VdbeChangeEncoding(pVal, enc);
  }else if( !(pVal->flags&MEM_Blob) ){
    sqlite3VdbeMemStringify(pVal, enc);
  }

  return (const void *)(pVal->z);
}

/*
** Create a new sqlite3_value object.
*/
sqlite3_value* sqlite3ValueNew(){
  Mem *p = sqliteMalloc(sizeof(*p));
  if( p ){
    p->flags = MEM_Null;
    p->type = SQLITE_NULL;
  }
  return p;
}



































































/*
** Change the string value of an sqlite3_value object
*/
void sqlite3ValueSetStr(
  sqlite3_value *v, 
  int n, 
  const void *z, 
Changes to SQLite.Interop/src/where.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63



64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104


105
106
107
108
109
110
111
112
113
114
115


116

117
118
119
120





121
122
123
124
125
126
127
128
129
130
131
132
133
134
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.17 2006/01/16 15:51:47 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)

/*
** Determine the number of elements in an array.
*/
#define ARRAYSIZE(X)  (sizeof(X)/sizeof(X[0]))

/*
** Trace output macros
*/
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
int sqlite3_where_trace = 0;
# define TRACE(X)  if(sqlite3_where_trace) sqlite3DebugPrintf X
#else
# define TRACE(X)
#endif

/*
** A large value which is the maximum cost of using an index.
** By default this is a large floating point value.  When compiling
** SQLite for a processor that lacks floating point support, simply
** redefine this constant to a large integer.
*/
#ifndef SQLITE_BIG_DBL
# define SQLITE_BIG_DBL (1.0e+99)
#endif

/* Forward reference
*/
typedef struct WhereClause WhereClause;

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
**
** All WhereTerms are collected into a single WhereClause structure.  
** The following identity holds:



**
**        WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm
**
** When a term is of the form:
**
**              X <op> <expr>
**
** where X is a column name and <op> is one of certain operators,
** then WhereTerm.leftCursor and WhereTerm.leftColumn record the
** cursor number and column number for X.  WhereTerm.operator records
** the <op> using a bitmask encoding defined by WO_xxx below.  The
** use of a bitmask encoding for the operator allows us to search
** quickly for terms that match any of several different operators.

**
** prereqRight and prereqAll record sets of cursor numbers,
** but they do so indirectly.  A single ExprMaskSet structure translates
** cursor number into bits and the translated bit is stored in the prereq
** fields.  The translation is used in order to maximize the number of
** bits that will fit in a Bitmask.  The VDBE cursor numbers might be
** spread out over the non-negative integers.  For example, the cursor
** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45.  The ExprMaskSet
** translates these sparse cursor numbers into consecutive integers
** beginning with 0 in order to make the best possible use of the available
** bits in the Bitmask.  So, in the example above, the cursor numbers
** would be mapped into integers 0 through 7.
*/
typedef struct WhereTerm WhereTerm;
struct WhereTerm {
  Expr *pExpr;            /* Pointer to the subexpression */
  i16 iParent;            /* Disable pWC->a[iParent] when this term disabled */
  i16 leftCursor;         /* Cursor number of X in "X <op> <expr>" */
  i16 leftColumn;         /* Column number of X in "X <op> <expr>" */
  u16 operator;           /* A WO_xx value describing <op> */
  u8 flags;               /* Bit flags.  See below */
  u8 nChild;              /* Number of children that must disable us */
  WhereClause *pWC;       /* The clause this term is part of */
  Bitmask prereqRight;    /* Bitmask of tables used by pRight */
  Bitmask prereqAll;      /* Bitmask of tables referenced by p */
};

/*


** Allowed values of WhereTerm.flags
*/
#define TERM_DYNAMIC    0x01   /* Need to call sqlite3ExprDelete(pExpr) */
#define TERM_VIRTUAL    0x02   /* Added by the optimizer.  Do not code */
#define TERM_CODED      0x04   /* This term is already coded */
#define TERM_COPIED     0x08   /* Has a child */
#define TERM_OR_OK      0x10   /* Used during OR-clause processing */

/*
** An instance of the following structure holds all information about a
** WHERE clause.  Mostly this is a container for one or more WhereTerms.


*/

struct WhereClause {
  Parse *pParse;           /* The parser context */
  int nTerm;               /* Number of terms */
  int nSlot;               /* Number of entries in a[] */





  WhereTerm *a;            /* Each a[] describes a term of the WHERE cluase */
  WhereTerm aStatic[10];   /* Initial static space for a[] */
};

/*
** An instance of the following structure keeps track of a mapping
** between VDBE cursor numbers and bits of the bitmasks in WhereTerm.
**
** The VDBE cursor numbers are small integers contained in 
** SrcList_item.iCursor and Expr.iTable fields.  For any given WHERE 
** clause, the cursor numbers might not begin with 0 and they might
** contain gaps in the numbering sequence.  But we want to make maximum
** use of the bits in our bitmasks.  This structure provides a mapping
** from the sparse cursor numbers into consecutive integers beginning







|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




<
|
>
>
>
|
<

<
<
<
<
<
<
|
<
<
<
>

|










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

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




|







12
13
14
15
16
17
18
19
20
21
22
23


































24
25
26
27

28
29
30
31
32

33






34



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53








54
55
56
57
58
59





60
61


62
63
64
65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** generating the code that loops through a table looking for applicable
** rows.  Indices are selected and used to speed the search when doing
** so is applicable.  Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.1 2005/03/01 16:04:39 rmsimpson Exp $
*/
#include "sqliteInt.h"

/*


































** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
**

** The idxLeft and idxRight fields are the VDBE cursor numbers for the
** table that contains the column that appears on the left-hand and
** right-hand side of ExprInfo.p.  If either side of ExprInfo.p is
** something other than a simple column reference, then idxLeft or
** idxRight are -1.  

**






** It is the VDBE cursor number is the value stored in Expr.iTable



** when Expr.op==TK_COLUMN and the value stored in SrcList.a[].iCursor.
**
** prereqLeft, prereqRight, and prereqAll record sets of cursor numbers,
** but they do so indirectly.  A single ExprMaskSet structure translates
** cursor number into bits and the translated bit is stored in the prereq
** fields.  The translation is used in order to maximize the number of
** bits that will fit in a Bitmask.  The VDBE cursor numbers might be
** spread out over the non-negative integers.  For example, the cursor
** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45.  The ExprMaskSet
** translates these sparse cursor numbers into consecutive integers
** beginning with 0 in order to make the best possible use of the available
** bits in the Bitmask.  So, in the example above, the cursor numbers
** would be mapped into integers 0 through 7.
**
** prereqLeft tells us every VDBE cursor that is referenced on the
** left-hand side of ExprInfo.p.  prereqRight does the same for the
** right-hand side of the expression.  The following identity always
** holds:
**








**       prereqAll = prereqLeft | prereqRight
**
** The ExprInfo.indexable field is true if the ExprInfo.p expression
** is of a form that might control an index.  Indexable expressions
** look like this:
**





**              <column> <op> <expr>
**


** Where <column> is a simple column name and <op> is on of the operators
** that allowedOp() recognizes.  
*/
typedef struct ExprInfo ExprInfo;
struct ExprInfo {
  Expr *p;                /* Pointer to the subexpression */
  u8 indexable;           /* True if this subexprssion is usable by an index */
  short int idxLeft;      /* p->pLeft is a column in this table number. -1 if
                          ** p->pLeft is not the column of any table */
  short int idxRight;     /* p->pRight is a column in this table number. -1 if
                          ** p->pRight is not the column of any table */
  Bitmask prereqLeft;     /* Bitmask of tables referenced by p->pLeft */
  Bitmask prereqRight;    /* Bitmask of tables referenced by p->pRight */
  Bitmask prereqAll;      /* Bitmask of tables referenced by p */

};

/*
** An instance of the following structure keeps track of a mapping
** between VDBE cursor numbers and bits of the bitmasks in ExprInfo.
**
** The VDBE cursor numbers are small integers contained in 
** SrcList_item.iCursor and Expr.iTable fields.  For any given WHERE 
** clause, the cursor numbers might not begin with 0 and they might
** contain gaps in the numbering sequence.  But we want to make maximum
** use of the bits in our bitmasks.  This structure provides a mapping
** from the sparse cursor numbers into consecutive integers beginning
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

259
260

261




262
263

264
265
266
267

268
269
270
271
272
273
274
*/
typedef struct ExprMaskSet ExprMaskSet;
struct ExprMaskSet {
  int n;                        /* Number of assigned cursor values */
  int ix[sizeof(Bitmask)*8];    /* Cursor assigned to each bit */
};


/*
** Bitmasks for the operators that indices are able to exploit.  An
** OR-ed combination of these values can be used when searching for
** terms in the where clause.
*/
#define WO_IN     1
#define WO_EQ     2
#define WO_LT     (WO_EQ<<(TK_LT-TK_EQ))
#define WO_LE     (WO_EQ<<(TK_LE-TK_EQ))
#define WO_GT     (WO_EQ<<(TK_GT-TK_EQ))
#define WO_GE     (WO_EQ<<(TK_GE-TK_EQ))

/*
** Value for flags returned by bestIndex()
*/
#define WHERE_ROWID_EQ       0x0001   /* rowid=EXPR or rowid IN (...) */
#define WHERE_ROWID_RANGE    0x0002   /* rowid<EXPR and/or rowid>EXPR */
#define WHERE_COLUMN_EQ      0x0010   /* x=EXPR or x IN (...) */
#define WHERE_COLUMN_RANGE   0x0020   /* x<EXPR and/or x>EXPR */
#define WHERE_COLUMN_IN      0x0040   /* x IN (...) */
#define WHERE_TOP_LIMIT      0x0100   /* x<EXPR or x<=EXPR constraint */
#define WHERE_BTM_LIMIT      0x0200   /* x>EXPR or x>=EXPR constraint */
#define WHERE_IDX_ONLY       0x0800   /* Use index only - omit table */
#define WHERE_ORDERBY        0x1000   /* Output will appear in correct order */
#define WHERE_REVERSE        0x2000   /* Scan in reverse order */
#define WHERE_UNIQUE         0x4000   /* Selects no more than one row */

/*
** Initialize a preallocated WhereClause structure.
*/
static void whereClauseInit(WhereClause *pWC, Parse *pParse){
  pWC->pParse = pParse;
  pWC->nTerm = 0;
  pWC->nSlot = ARRAYSIZE(pWC->aStatic);
  pWC->a = pWC->aStatic;
}

/*
** Deallocate a WhereClause structure.  The WhereClause structure
** itself is not freed.  This routine is the inverse of whereClauseInit().
*/
static void whereClauseClear(WhereClause *pWC){
  int i;
  WhereTerm *a;
  for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
    if( a->flags & TERM_DYNAMIC ){
      sqlite3ExprDelete(a->pExpr);
    }
  }
  if( pWC->a!=pWC->aStatic ){
    sqliteFree(pWC->a);
  }
}

/*
** Add a new entries to the WhereClause structure.  Increase the allocated
** space as necessary.
**
** WARNING:  This routine might reallocate the space used to store
** WhereTerms.  All pointers to WhereTerms should be invalided after
** calling this routine.  Such pointers may be reinitialized by referencing
** the pWC->a[] array.
*/
static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){
  WhereTerm *pTerm;
  int idx;
  if( pWC->nTerm>=pWC->nSlot ){
    WhereTerm *pOld = pWC->a;
    pWC->a = sqliteMalloc( sizeof(pWC->a[0])*pWC->nSlot*2 );
    if( pWC->a==0 ) return 0;
    memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
    if( pOld!=pWC->aStatic ){
      sqliteFree(pOld);
    }
    pWC->nSlot *= 2;
  }
  pTerm = &pWC->a[idx = pWC->nTerm];
  pWC->nTerm++;
  pTerm->pExpr = p;
  pTerm->flags = flags;
  pTerm->pWC = pWC;
  pTerm->iParent = -1;
  return idx;
}

/*
** This routine identifies subexpressions in the WHERE clause where
** each subexpression is separated by the AND operator or some other
** operator specified in the op parameter.  The WhereClause structure
** is filled with pointers to subexpressions.  For example:
**
**    WHERE  a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22)
**           \________/     \_______________/     \________________/
**            slot[0]            slot[1]               slot[2]
**
** The original WHERE clause in pExpr is unaltered.  All this routine
** does is make slot[] entries point to substructure within pExpr.
**
** In the previous sentence and in the diagram, "slot[]" refers to
** the WhereClause.a[] array.  This array grows as needed to contain
** all terms of the WHERE clause.

*/
static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){

  if( pExpr==0 ) return;




  if( pExpr->op!=op ){
    whereClauseInsert(pWC, pExpr, 0);

  }else{
    whereSplit(pWC, pExpr->pLeft, op);
    whereSplit(pWC, pExpr->pRight, op);
  }

}

/*
** Initialize an expression mask set
*/
#define initMaskSet(P)  memset(P, 0, sizeof(*P))








<

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

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

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
|






|

|
|
|
>

|
>
|
>
>
>
>
|
|
>

|
|

>







103
104
105
106
107
108
109

110










111


112











113








114

115
















































116
117

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
*/
typedef struct ExprMaskSet ExprMaskSet;
struct ExprMaskSet {
  int n;                        /* Number of assigned cursor values */
  int ix[sizeof(Bitmask)*8];    /* Cursor assigned to each bit */
};


/*










** Determine the number of elements in an array.


*/











#define ARRAYSIZE(X)  (sizeof(X)/sizeof(X[0]))










/*
















































** This routine identifies subexpressions in the WHERE clause where
** each subexpression is separate by the AND operator.  aSlot is 

** filled with pointers to the subexpressions.  For example:
**
**    WHERE  a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22)
**           \________/     \_______________/     \________________/
**            slot[0]            slot[1]               slot[2]
**
** The original WHERE clause in pExpr is unaltered.  All this routine
** does is make aSlot[] entries point to substructure within pExpr.
**
** aSlot[] is an array of subexpressions structures.  There are nSlot
** spaces left in this array.  This routine finds as many AND-separated
** subexpressions as it can and puts pointers to those subexpressions
** into aSlot[] entries.  The return value is the number of slots filled.
*/
static int exprSplit(int nSlot, ExprInfo *aSlot, Expr *pExpr){
  int cnt = 0;
  if( pExpr==0 || nSlot<1 ) return 0;
  if( nSlot==1 || pExpr->op!=TK_AND ){
    aSlot[0].p = pExpr;
    return 1;
  }
  if( pExpr->pLeft->op!=TK_AND ){
    aSlot[0].p = pExpr->pLeft;
    cnt = 1 + exprSplit(nSlot-1, &aSlot[1], pExpr->pRight);
  }else{
    cnt = exprSplit(nSlot, aSlot, pExpr->pLeft);
    cnt += exprSplit(nSlot-cnt, &aSlot[cnt], pExpr->pRight);
  }
  return cnt;
}

/*
** Initialize an expression mask set
*/
#define initMaskSet(P)  memset(P, 0, sizeof(*P))

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301






302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327


328





329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589


590
591
592
593
594
595
596
597

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654

655
656
657
658

659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695

696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773




774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848

849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151

1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223

1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
    }
  }
  return 0;
}

/*
** Create a new mask for cursor iCursor.
**
** There is one cursor per table in the FROM clause.  The number of
** tables in the FROM clause is limited by a test early in the
** sqlite3WhereBegin() routine.  So we know that the pMaskSet->ix[]
** array will never overflow.
*/
static void createMask(ExprMaskSet *pMaskSet, int iCursor){
  assert( pMaskSet->n < ARRAYSIZE(pMaskSet->ix) );
  pMaskSet->ix[pMaskSet->n++] = iCursor;
}







/*
** This routine walks (recursively) an expression tree and generates
** a bitmask indicating which tables are used in that expression
** tree.
**
** In order for this routine to work, the calling function must have
** previously invoked sqlite3ExprResolveNames() on the expression.  See
** the header comment on that routine for additional information.
** The sqlite3ExprResolveNames() routines looks for column names and
** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
** the VDBE cursor number of the table.  This routine just has to
** translate the cursor numbers into bitmask values and OR all
** the bitmasks together.
*/
static Bitmask exprListTableUsage(ExprMaskSet*, ExprList*);
static Bitmask exprSelectTableUsage(ExprMaskSet*, Select*);
static Bitmask exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
  Bitmask mask = 0;
  if( p==0 ) return 0;
  if( p->op==TK_COLUMN ){
    mask = getMask(pMaskSet, p->iTable);
    return mask;
  }
  mask = exprTableUsage(pMaskSet, p->pRight);
  mask |= exprTableUsage(pMaskSet, p->pLeft);
  mask |= exprListTableUsage(pMaskSet, p->pList);


  mask |= exprSelectTableUsage(pMaskSet, p->pSelect);





  return mask;
}
static Bitmask exprListTableUsage(ExprMaskSet *pMaskSet, ExprList *pList){
  int i;
  Bitmask mask = 0;
  if( pList ){
    for(i=0; i<pList->nExpr; i++){
      mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr);
    }
  }
  return mask;
}
static Bitmask exprSelectTableUsage(ExprMaskSet *pMaskSet, Select *pS){
  Bitmask mask;
  if( pS==0 ){
    mask = 0;
  }else{
    mask = exprListTableUsage(pMaskSet, pS->pEList);
    mask |= exprListTableUsage(pMaskSet, pS->pGroupBy);
    mask |= exprListTableUsage(pMaskSet, pS->pOrderBy);
    mask |= exprTableUsage(pMaskSet, pS->pWhere);
    mask |= exprTableUsage(pMaskSet, pS->pHaving);
  }
  return mask;
}

/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term.  The allowed operators are
** "=", "<", ">", "<=", ">=", and "IN".
*/
static int allowedOp(int op){
  assert( TK_GT>TK_EQ && TK_GT<TK_GE );
  assert( TK_LT>TK_EQ && TK_LT<TK_GE );
  assert( TK_LE>TK_EQ && TK_LE<TK_GE );
  assert( TK_GE==TK_EQ+4 );
  return op==TK_IN || (op>=TK_EQ && op<=TK_GE);
}

/*
** Swap two objects of type T.
*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}

/*
** Commute a comparision operator.  Expressions of the form "X op Y"
** are converted into "Y op X".
*/
static void exprCommute(Expr *pExpr){
  assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
  SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
  SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
  if( pExpr->op>=TK_GT ){
    assert( TK_LT==TK_GT+2 );
    assert( TK_GE==TK_LE+2 );
    assert( TK_GT>TK_EQ );
    assert( TK_GT<TK_LE );
    assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
    pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
  }
}

/*
** Translate from TK_xx operator to WO_xx bitmask.
*/
static int operatorMask(int op){
  int c;
  assert( allowedOp(op) );
  if( op==TK_IN ){
    c = WO_IN;
  }else{
    c = WO_EQ<<(op-TK_EQ);
  }
  assert( op!=TK_IN || c==WO_IN );
  assert( op!=TK_EQ || c==WO_EQ );
  assert( op!=TK_LT || c==WO_LT );
  assert( op!=TK_LE || c==WO_LE );
  assert( op!=TK_GT || c==WO_GT );
  assert( op!=TK_GE || c==WO_GE );
  return c;
}

/*
** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
** where X is a reference to the iColumn of table iCur and <op> is one of
** the WO_xx operator codes specified by the op parameter.
** Return a pointer to the term.  Return 0 if not found.
*/
static WhereTerm *findTerm(
  WhereClause *pWC,     /* The WHERE clause to be searched */
  int iCur,             /* Cursor number of LHS */
  int iColumn,          /* Column number of LHS */
  Bitmask notReady,     /* RHS must not overlap with this mask */
  u16 op,               /* Mask of WO_xx values describing operator */
  Index *pIdx           /* Must be compatible with this index, if not NULL */
){
  WhereTerm *pTerm;
  int k;
  for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
    if( pTerm->leftCursor==iCur
       && (pTerm->prereqRight & notReady)==0
       && pTerm->leftColumn==iColumn
       && (pTerm->operator & op)!=0
    ){
      if( iCur>=0 && pIdx ){
        Expr *pX = pTerm->pExpr;
        CollSeq *pColl;
        char idxaff;
        int k;
        Parse *pParse = pWC->pParse;

        idxaff = pIdx->pTable->aCol[iColumn].affinity;
        if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;
        pColl = sqlite3ExprCollSeq(pParse, pX->pLeft);
        if( !pColl ){
          if( pX->pRight ){
            pColl = sqlite3ExprCollSeq(pParse, pX->pRight);
          }
          if( !pColl ){
            pColl = pParse->db->pDfltColl;
          }
        }
        for(k=0; k<pIdx->nColumn && pIdx->aiColumn[k]!=iColumn; k++){}
        assert( k<pIdx->nColumn );
        if( sqlite3StrICmp(pColl->zName, pIdx->azColl[k]) ) continue;
      }
      return pTerm;
    }
  }
  return 0;
}

/* Forward reference */
static void exprAnalyze(SrcList*, ExprMaskSet*, WhereClause*, int);

/*
** Call exprAnalyze on all terms in a WHERE clause.  
**
**
*/
static void exprAnalyzeAll(
  SrcList *pTabList,       /* the FROM clause */
  ExprMaskSet *pMaskSet,   /* table masks */
  WhereClause *pWC         /* the WHERE clause to be analyzed */
){
  int i;
  for(i=pWC->nTerm-1; i>=0; i--){
    exprAnalyze(pTabList, pMaskSet, pWC, i);
  }
}

#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION
/*
** Check to see if the given expression is a LIKE or GLOB operator that
** can be optimized using inequality constraints.  Return TRUE if it is
** so and false if not.
**
** In order for the operator to be optimizible, the RHS must be a string
** literal that does not begin with a wildcard.  
*/
static int isLikeOrGlob(
  sqlite3 *db,      /* The database */
  Expr *pExpr,      /* Test this expression */
  int *pnPattern,   /* Number of non-wildcard prefix characters */
  int *pisComplete  /* True if the only wildcard is % in the last character */
){
  const char *z;
  Expr *pRight, *pLeft;
  ExprList *pList;
  int c, cnt;
  int noCase;
  char wc[3];
  CollSeq *pColl;

  if( !sqlite3IsLikeFunction(db, pExpr, &noCase, wc) ){
    return 0;
  }
  pList = pExpr->pList;
  pRight = pList->a[0].pExpr;
  if( pRight->op!=TK_STRING ){
    return 0;
  }
  pLeft = pList->a[1].pExpr;
  if( pLeft->op!=TK_COLUMN ){
    return 0;
  }
  pColl = pLeft->pColl;
  if( pColl==0 ){
    pColl = db->pDfltColl;
  }
  if( (pColl->type!=SQLITE_COLL_BINARY || noCase) &&
      (pColl->type!=SQLITE_COLL_NOCASE || !noCase) ){
    return 0;
  }
  sqlite3DequoteExpr(pRight);
  z = (char *)pRight->token.z;
  for(cnt=0; (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2]; cnt++){}
  if( cnt==0 || 255==(u8)z[cnt] ){
    return 0;
  }
  *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0;
  *pnPattern = cnt;
  return 1;
}
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */

/*
** If the pBase expression originated in the ON or USING clause of
** a join, then transfer the appropriate markings over to derived.
*/
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
  pDerived->flags |= pBase->flags & EP_FromJoin;
  pDerived->iRightJoinTable = pBase->iRightJoinTable;
}


/*
** The input to this routine is an WhereTerm structure with only the
** "pExpr" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the WhereTerm
** structure.
**
** If the expression is of the form "<expr> <op> X" it gets commuted
** to the standard form of "X <op> <expr>".  If the expression is of
** the form "X <op> Y" where both X and Y are columns, then the original
** expression is unchanged and a new virtual expression of the form
** "Y <op> X" is added to the WHERE clause and analyzed separately.
*/
static void exprAnalyze(
  SrcList *pSrc,            /* the FROM clause */
  ExprMaskSet *pMaskSet,    /* table masks */
  WhereClause *pWC,         /* the WHERE clause */
  int idxTerm               /* Index of the term to be analyzed */
){
  WhereTerm *pTerm = &pWC->a[idxTerm];
  Expr *pExpr = pTerm->pExpr;
  Bitmask prereqLeft;
  Bitmask prereqAll;
  int nPattern;
  int isComplete;

  if( sqlite3ThreadDataReadOnly()->mallocFailed ) return;
  prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
  if( pExpr->op==TK_IN ){
    assert( pExpr->pRight==0 );
    pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList)
                          | exprSelectTableUsage(pMaskSet, pExpr->pSelect);
  }else{
    pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
  }
  prereqAll = exprTableUsage(pMaskSet, pExpr);
  if( ExprHasProperty(pExpr, EP_FromJoin) ){
    prereqAll |= getMask(pMaskSet, pExpr->iRightJoinTable);
  }
  pTerm->prereqAll = prereqAll;
  pTerm->leftCursor = -1;
  pTerm->iParent = -1;
  pTerm->operator = 0;
  if( allowedOp(pExpr->op) && (pTerm->prereqRight & prereqLeft)==0 ){
    Expr *pLeft = pExpr->pLeft;
    Expr *pRight = pExpr->pRight;


    if( pLeft->op==TK_COLUMN ){
      pTerm->leftCursor = pLeft->iTable;
      pTerm->leftColumn = pLeft->iColumn;
      pTerm->operator = operatorMask(pExpr->op);
    }
    if( pRight && pRight->op==TK_COLUMN ){
      WhereTerm *pNew;
      Expr *pDup;

      if( pTerm->leftCursor>=0 ){
        int idxNew;
        pDup = sqlite3ExprDup(pExpr);
        idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
        if( idxNew==0 ) return;
        pNew = &pWC->a[idxNew];
        pNew->iParent = idxTerm;
        pTerm = &pWC->a[idxTerm];
        pTerm->nChild = 1;
        pTerm->flags |= TERM_COPIED;
      }else{
        pDup = pExpr;
        pNew = pTerm;
      }
      exprCommute(pDup);
      pLeft = pDup->pLeft;
      pNew->leftCursor = pLeft->iTable;
      pNew->leftColumn = pLeft->iColumn;
      pNew->prereqRight = prereqLeft;
      pNew->prereqAll = prereqAll;
      pNew->operator = operatorMask(pDup->op);
    }
  }

#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION
  /* If a term is the BETWEEN operator, create two new virtual terms
  ** that define the range that the BETWEEN implements.
  */
  else if( pExpr->op==TK_BETWEEN ){
    ExprList *pList = pExpr->pList;
    int i;
    static const u8 ops[] = {TK_GE, TK_LE};
    assert( pList!=0 );
    assert( pList->nExpr==2 );
    for(i=0; i<2; i++){
      Expr *pNewExpr;
      int idxNew;
      pNewExpr = sqlite3Expr(ops[i], sqlite3ExprDup(pExpr->pLeft),
                             sqlite3ExprDup(pList->a[i].pExpr), 0);
      idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
      exprAnalyze(pSrc, pMaskSet, pWC, idxNew);
      pTerm = &pWC->a[idxTerm];
      pWC->a[idxNew].iParent = idxTerm;
    }
    pTerm->nChild = 2;
  }
#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */

#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
  /* Attempt to convert OR-connected terms into an IN operator so that
  ** they can make use of indices.  Example:
  **
  **      x = expr1  OR  expr2 = x  OR  x = expr3
  **
  ** is converted into
  **
  **      x IN (expr1,expr2,expr3)

  **
  ** This optimization must be omitted if OMIT_SUBQUERY is defined because
  ** the compiler for the the IN operator is part of sub-queries.
  */

  else if( pExpr->op==TK_OR ){
    int ok;
    int i, j;
    int iColumn, iCursor;
    WhereClause sOr;
    WhereTerm *pOrTerm;

    assert( (pTerm->flags & TERM_DYNAMIC)==0 );
    whereClauseInit(&sOr, pWC->pParse);
    whereSplit(&sOr, pExpr, TK_OR);
    exprAnalyzeAll(pSrc, pMaskSet, &sOr);
    assert( sOr.nTerm>0 );
    j = 0;
    do{
      iColumn = sOr.a[j].leftColumn;
      iCursor = sOr.a[j].leftCursor;
      ok = iCursor>=0;
      for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){
        if( pOrTerm->operator!=WO_EQ ){
          goto or_not_possible;
        }
        if( pOrTerm->leftCursor==iCursor && pOrTerm->leftColumn==iColumn ){
          pOrTerm->flags |= TERM_OR_OK;
        }else if( (pOrTerm->flags & TERM_COPIED)!=0 ||
                    ((pOrTerm->flags & TERM_VIRTUAL)!=0 &&
                     (sOr.a[pOrTerm->iParent].flags & TERM_OR_OK)!=0) ){
          pOrTerm->flags &= ~TERM_OR_OK;
        }else{
          ok = 0;
        }
      }
    }while( !ok && (sOr.a[j++].flags & TERM_COPIED)!=0 && j<sOr.nTerm );
    if( ok ){
      ExprList *pList = 0;
      Expr *pNew, *pDup;
      for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){
        if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue;

        pDup = sqlite3ExprDup(pOrTerm->pExpr->pRight);
        pList = sqlite3ExprListAppend(pList, pDup, 0);
      }
      pDup = sqlite3Expr(TK_COLUMN, 0, 0, 0);
      if( pDup ){
        pDup->iTable = iCursor;
        pDup->iColumn = iColumn;
      }
      pNew = sqlite3Expr(TK_IN, pDup, 0, 0);
      if( pNew ){
        int idxNew;
        transferJoinMarkings(pNew, pExpr);
        pNew->pList = pList;
        idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
        exprAnalyze(pSrc, pMaskSet, pWC, idxNew);
        pTerm = &pWC->a[idxTerm];
        pWC->a[idxNew].iParent = idxTerm;
        pTerm->nChild = 1;
      }else{
        sqlite3ExprListDelete(pList);
      }
    }
or_not_possible:
    whereClauseClear(&sOr);
  }
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */

#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION
  /* Add constraints to reduce the search space on a LIKE or GLOB
  ** operator.
  */
  if( isLikeOrGlob(pWC->pParse->db, pExpr, &nPattern, &isComplete) ){
    Expr *pLeft, *pRight;
    Expr *pStr1, *pStr2;
    Expr *pNewExpr1, *pNewExpr2;
    int idxNew1, idxNew2;

    pLeft = pExpr->pList->a[1].pExpr;
    pRight = pExpr->pList->a[0].pExpr;
    pStr1 = sqlite3Expr(TK_STRING, 0, 0, 0);
    if( pStr1 ){
      sqlite3TokenCopy(&pStr1->token, &pRight->token);
      pStr1->token.n = nPattern;
    }
    pStr2 = sqlite3ExprDup(pStr1);
    if( pStr2 ){
      assert( pStr2->token.dyn );
      ++*(u8*)&pStr2->token.z[nPattern-1];
    }
    pNewExpr1 = sqlite3Expr(TK_GE, sqlite3ExprDup(pLeft), pStr1, 0);
    idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
    exprAnalyze(pSrc, pMaskSet, pWC, idxNew1);
    pNewExpr2 = sqlite3Expr(TK_LT, sqlite3ExprDup(pLeft), pStr2, 0);
    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
    exprAnalyze(pSrc, pMaskSet, pWC, idxNew2);
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){
      pWC->a[idxNew1].iParent = idxTerm;
      pWC->a[idxNew2].iParent = idxTerm;
      pTerm->nChild = 2;
    }
  }
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
}


/*
** This routine decides if pIdx can be used to satisfy the ORDER BY
** clause.  If it can, it returns 1.  If pIdx cannot satisfy the
** ORDER BY clause, this routine returns 0.
**
** pOrderBy is an ORDER BY clause from a SELECT statement.  pTab is the
** left-most table in the FROM clause of that same SELECT statement and
** the table has a cursor number of "base".  pIdx is an index on pTab.
**
** nEqCol is the number of columns of pIdx that are used as equality
** constraints.  Any of these columns may be missing from the ORDER BY
** clause and the match can still be a success.




**
** All terms of the ORDER BY that match against the index must be either
** ASC or DESC.  (Terms of the ORDER BY clause past the end of a UNIQUE
** index do not need to satisfy this constraint.)  The *pbRev value is
** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if
** the ORDER BY clause is all ASC.
*/
static int isSortingIndex(
  Parse *pParse,          /* Parsing context */
  Index *pIdx,            /* The index we are testing */
  Table *pTab,            /* The table to be sorted */
  int base,               /* Cursor number for pTab */
  ExprList *pOrderBy,     /* The ORDER BY clause */
  int nEqCol,             /* Number of index columns with == constraints */
  int *pbRev              /* Set to 1 if ORDER BY is DESC */
){
  int i, j;                       /* Loop counters */
  int sortOrder = 0;              /* XOR of index and ORDER BY sort direction */
  int nTerm;                      /* Number of ORDER BY terms */
  struct ExprList_item *pTerm;    /* A term of the ORDER BY clause */
  sqlite3 *db = pParse->db;

  assert( pOrderBy!=0 );
  nTerm = pOrderBy->nExpr;
  assert( nTerm>0 );

  /* Match terms of the ORDER BY clause against columns of
  ** the index.
  */
  for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<pIdx->nColumn; i++){
    Expr *pExpr;       /* The expression of the ORDER BY pTerm */
    CollSeq *pColl;    /* The collating sequence of pExpr */
    int termSortOrder; /* Sort order for this term */

    pExpr = pTerm->pExpr;
    if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
      /* Can not use an index sort on anything that is not a column in the
      ** left-most table of the FROM clause */
      return 0;
    }
    pColl = sqlite3ExprCollSeq(pParse, pExpr);
    if( !pColl ) pColl = db->pDfltColl;
    if( pExpr->iColumn!=pIdx->aiColumn[i] || 
        sqlite3StrICmp(pColl->zName, pIdx->azColl[i]) ){
      /* Term j of the ORDER BY clause does not match column i of the index */
      if( i<nEqCol ){
        /* If an index column that is constrained by == fails to match an
        ** ORDER BY term, that is OK.  Just ignore that column of the index
        */
        continue;
      }else{
        /* If an index column fails to match and is not constrained by ==
        ** then the index cannot satisfy the ORDER BY constraint.
        */
        return 0;
      }
    }
    assert( pIdx->aSortOrder!=0 );
    assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
    assert( pIdx->aSortOrder[i]==0 || pIdx->aSortOrder[i]==1 );
    termSortOrder = pIdx->aSortOrder[i] ^ pTerm->sortOrder;
    if( i>nEqCol ){
      if( termSortOrder!=sortOrder ){
        /* Indices can only be used if all ORDER BY terms past the
        ** equality constraints are all either DESC or ASC. */
        return 0;
      }
    }else{
      sortOrder = termSortOrder;
    }
    j++;
    pTerm++;
  }

  /* The index can be used for sorting if all terms of the ORDER BY clause

  ** are covered.
  */
  if( j>=nTerm ){
    *pbRev = sortOrder!=0;
    return 1;
  }
  return 0;
}

/*
** Check table to see if the ORDER BY clause in pOrderBy can be satisfied
** by sorting in order of ROWID.  Return true if so and set *pbRev to be
** true for reverse ROWID and false for forward ROWID order.
*/
static int sortableByRowid(
  int base,               /* Cursor number for table to be sorted */
  ExprList *pOrderBy,     /* The ORDER BY clause */
  int *pbRev              /* Set to 1 if ORDER BY is DESC */
){
  Expr *p;

  assert( pOrderBy!=0 );
  assert( pOrderBy->nExpr>0 );
  p = pOrderBy->a[0].pExpr;
  if( pOrderBy->nExpr==1 && p->op==TK_COLUMN && p->iTable==base
          && p->iColumn==-1 ){
    *pbRev = pOrderBy->a[0].sortOrder;
    return 1;
  }
  return 0;
}

/*
** Prepare a crude estimate of the logarithm of the input value.
** The results need not be exact.  This is only used for estimating
** the total cost of performing operatings with O(logN) or O(NlogN)
** complexity.  Because N is just a guess, it is no great tragedy if
** logN is a little off.
*/
static double estLog(double N){
  double logN = 1;
  double x = 10;
  while( N>x ){
    logN += 1;
    x *= 10;
  }
  return logN;
}

/*
** Find the best index for accessing a particular table.  Return a pointer
** to the index, flags that describe how the index should be used, the
** number of equality constraints, and the "cost" for this index.
**
** The lowest cost index wins.  The cost is an estimate of the amount of
** CPU and disk I/O need to process the request using the selected index.
** Factors that influence cost include:
**
**    *  The estimated number of rows that will be retrieved.  (The
**       fewer the better.)
**
**    *  Whether or not sorting must occur.
**
**    *  Whether or not there must be separate lookups in the
**       index and in the main table.
**
*/
static double bestIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  struct SrcList_item *pSrc,  /* The FROM clause term to search */
  Bitmask notReady,           /* Mask of cursors that are not available */
  ExprList *pOrderBy,         /* The order by clause */
  Index **ppIndex,            /* Make *ppIndex point to the best index */
  int *pFlags,                /* Put flags describing this choice in *pFlags */
  int *pnEq                   /* Put the number of == or IN constraints here */
){
  WhereTerm *pTerm;
  Index *bestIdx = 0;         /* Index that gives the lowest cost */
  double lowestCost;          /* The cost of using bestIdx */
  int bestFlags = 0;          /* Flags associated with bestIdx */
  int bestNEq = 0;            /* Best value for nEq */
  int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
  Index *pProbe;              /* An index we are evaluating */
  int rev;                    /* True to scan in reverse order */
  int flags;                  /* Flags associated with pProbe */
  int nEq;                    /* Number of == or IN constraints */
  double cost;                /* Cost of using pProbe */

  TRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady));
  lowestCost = SQLITE_BIG_DBL;

  /* Check for a rowid=EXPR or rowid IN (...) constraints
  */
  pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0);
  if( pTerm ){
    Expr *pExpr;
    *ppIndex = 0;
    bestFlags = WHERE_ROWID_EQ;
    if( pTerm->operator & WO_EQ ){
      /* Rowid== is always the best pick.  Look no further.  Because only
      ** a single row is generated, output is always in sorted order */
      *pFlags = WHERE_ROWID_EQ | WHERE_UNIQUE;
      *pnEq = 1;
      TRACE(("... best is rowid\n"));
      return 0.0;
    }else if( (pExpr = pTerm->pExpr)->pList!=0 ){
      /* Rowid IN (LIST): cost is NlogN where N is the number of list
      ** elements.  */
      lowestCost = pExpr->pList->nExpr;
      lowestCost *= estLog(lowestCost);
    }else{
      /* Rowid IN (SELECT): cost is NlogN where N is the number of rows
      ** in the result of the inner select.  We have no way to estimate
      ** that value so make a wild guess. */
      lowestCost = 200;
    }
    TRACE(("... rowid IN cost: %.9g\n", lowestCost));
  }

  /* Estimate the cost of a table scan.  If we do not know how many
  ** entries are in the table, use 1 million as a guess.
  */
  pProbe = pSrc->pTab->pIndex;
  cost = pProbe ? pProbe->aiRowEst[0] : 1000000;
  TRACE(("... table scan base cost: %.9g\n", cost));
  flags = WHERE_ROWID_RANGE;

  /* Check for constraints on a range of rowids in a table scan.
  */
  pTerm = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE|WO_GT|WO_GE, 0);
  if( pTerm ){
    if( findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0) ){
      flags |= WHERE_TOP_LIMIT;
      cost /= 3;  /* Guess that rowid<EXPR eliminates two-thirds or rows */
    }
    if( findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0) ){
      flags |= WHERE_BTM_LIMIT;
      cost /= 3;  /* Guess that rowid>EXPR eliminates two-thirds of rows */
    }
    TRACE(("... rowid range reduces cost to %.9g\n", cost));
  }else{
    flags = 0;
  }

  /* If the table scan does not satisfy the ORDER BY clause, increase
  ** the cost by NlogN to cover the expense of sorting. */
  if( pOrderBy ){
    if( sortableByRowid(iCur, pOrderBy, &rev) ){
      flags |= WHERE_ORDERBY|WHERE_ROWID_RANGE;
      if( rev ){
        flags |= WHERE_REVERSE;
      }
    }else{
      cost += cost*estLog(cost);
      TRACE(("... sorting increases cost to %.9g\n", cost));
    }
  }
  if( cost<lowestCost ){
    lowestCost = cost;
    bestFlags = flags;
  }

  /* Look at each index.
  */
  for(; pProbe; pProbe=pProbe->pNext){
    int i;                       /* Loop counter */
    double inMultiplier = 1;

    TRACE(("... index %s:\n", pProbe->zName));

    /* Count the number of columns in the index that are satisfied
    ** by x=EXPR constraints or x IN (...) constraints.
    */
    flags = 0;
    for(i=0; i<pProbe->nColumn; i++){
      int j = pProbe->aiColumn[i];
      pTerm = findTerm(pWC, iCur, j, notReady, WO_EQ|WO_IN, pProbe);
      if( pTerm==0 ) break;
      flags |= WHERE_COLUMN_EQ;
      if( pTerm->operator & WO_IN ){
        Expr *pExpr = pTerm->pExpr;
        flags |= WHERE_COLUMN_IN;
        if( pExpr->pSelect!=0 ){
          inMultiplier *= 100;
        }else if( pExpr->pList!=0 ){
          inMultiplier *= pExpr->pList->nExpr + 1;
        }
      }
    }
    cost = pProbe->aiRowEst[i] * inMultiplier * estLog(inMultiplier);
    nEq = i;
    if( pProbe->onError!=OE_None && (flags & WHERE_COLUMN_IN)==0
         && nEq==pProbe->nColumn ){
      flags |= WHERE_UNIQUE;
    }
    TRACE(("...... nEq=%d inMult=%.9g cost=%.9g\n", nEq, inMultiplier, cost));

    /* Look for range constraints
    */
    if( nEq<pProbe->nColumn ){
      int j = pProbe->aiColumn[nEq];
      pTerm = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pProbe);
      if( pTerm ){
        flags |= WHERE_COLUMN_RANGE;
        if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pProbe) ){
          flags |= WHERE_TOP_LIMIT;
          cost /= 3;
        }
        if( findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pProbe) ){
          flags |= WHERE_BTM_LIMIT;
          cost /= 3;
        }
        TRACE(("...... range reduces cost to %.9g\n", cost));
      }
    }

    /* Add the additional cost of sorting if that is a factor.
    */
    if( pOrderBy ){
      if( (flags & WHERE_COLUMN_IN)==0 &&
           isSortingIndex(pParse,pProbe,pSrc->pTab,iCur,pOrderBy,nEq,&rev) ){
        if( flags==0 ){
          flags = WHERE_COLUMN_RANGE;
        }
        flags |= WHERE_ORDERBY;
        if( rev ){
          flags |= WHERE_REVERSE;
        }
      }else{
        cost += cost*estLog(cost);
        TRACE(("...... orderby increases cost to %.9g\n", cost));
      }
    }

    /* Check to see if we can get away with using just the index without
    ** ever reading the table.  If that is the case, then halve the
    ** cost of this index.
    */
    if( flags && pSrc->colUsed < (((Bitmask)1)<<(BMS-1)) ){
      Bitmask m = pSrc->colUsed;
      int j;
      for(j=0; j<pProbe->nColumn; j++){
        int x = pProbe->aiColumn[j];
        if( x<BMS-1 ){
          m &= ~(((Bitmask)1)<<x);
        }
      }
      if( m==0 ){
        flags |= WHERE_IDX_ONLY;
        cost /= 2;
        TRACE(("...... idx-only reduces cost to %.9g\n", cost));
      }
    }

    /* If this index has achieved the lowest cost so far, then use it.
    */
    if( cost < lowestCost ){
      bestIdx = pProbe;
      lowestCost = cost;
      assert( flags!=0 );
      bestFlags = flags;
      bestNEq = nEq;
    }
  }

  /* Report the best result
  */
  *ppIndex = bestIdx;
  TRACE(("best index is %s, cost=%.9g, flags=%x, nEq=%d\n",
        bestIdx ? bestIdx->zName : "(none)", lowestCost, bestFlags, bestNEq));
  *pFlags = bestFlags;
  *pnEq = bestNEq;
  return lowestCost;
}


/*
** Disable a term in the WHERE clause.  Except, do not disable the term
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
** or USING clause of that join.
**
** Consider the term t2.z='ok' in the following queries:
**
**   (1)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
**   (2)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
**   (3)  SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
**
** The t2.z='ok' is disabled in the in (2) because it originates
** in the ON clause.  The term is disabled in (3) because it is not part
** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
**
** Disabling a term causes that term to not be tested in the inner loop
** of the join.  Disabling is an optimization.  When terms are satisfied
** by indices, we disable them to prevent redundant tests in the inner
** loop.  We would get the correct results if nothing were ever disabled,
** but joins might run a little slower.  The trick is to disable as much
** as we can without disabling too much.  If we disabled in (1), we'd get
** the wrong answer.  See ticket #813.
*/
static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
  if( pTerm
      && (pTerm->flags & TERM_CODED)==0

      && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
  ){
    pTerm->flags |= TERM_CODED;
    if( pTerm->iParent>=0 ){
      WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent];
      if( (--pOther->nChild)==0 ){
        disableTerm(pLevel, pOther);
      }
    }
  }
}

/*
** Generate code that builds a probe for an index.  Details:
**
**    *  Check the top nColumn entries on the stack.  If any
**       of those entries are NULL, jump immediately to brk,
**       which is the loop exit, since no index entry will match
**       if any part of the key is NULL. Pop (nColumn+nExtra) 
**       elements from the stack.
**
**    *  Construct a probe entry from the top nColumn entries in
**       the stack with affinities appropriate for index pIdx. 
**       Only nColumn elements are popped from the stack in this case
**       (by OP_MakeRecord).
**
*/
static void buildIndexProbe(
  Vdbe *v, 
  int nColumn, 
  int nExtra, 
  int brk, 
  Index *pIdx
){
  sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
  sqlite3VdbeAddOp(v, OP_Pop, nColumn+nExtra, 0);
  sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
  sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
  sqlite3IndexAffinityStr(v, pIdx);
}


/*
** Generate code for a single equality term of the WHERE clause.  An equality
** term can be either X=expr or X IN (...).   pTerm is the term to be 
** coded.
**
** The current value for the constraint is left on the top of the stack.
**
** For a constraint of the form X=expr, the expression is evaluated and its
** result is left on the stack.  For constraints of the form X IN (...)
** this routine sets up a loop that will iterate over all values of X.
*/
static void codeEqualityTerm(
  Parse *pParse,      /* The parsing context */
  WhereTerm *pTerm,   /* The term of the WHERE clause to be coded */
  int brk,            /* Jump here to abandon the loop */
  WhereLevel *pLevel  /* When level of the FROM clause we are working on */
){
  Expr *pX = pTerm->pExpr;
  if( pX->op!=TK_IN ){
    assert( pX->op==TK_EQ );
    sqlite3ExprCode(pParse, pX->pRight);
#ifndef SQLITE_OMIT_SUBQUERY
  }else{
    int iTab;
    int *aIn;
    Vdbe *v = pParse->pVdbe;

    sqlite3CodeSubselect(pParse, pX);
    iTab = pX->iTable;
    sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk);

    VdbeComment((v, "# %.*s", pX->span.n, pX->span.z));
    pLevel->nIn++;
    sqliteReallocOrFree((void**)&pLevel->aInLoop,
                                 sizeof(pLevel->aInLoop[0])*3*pLevel->nIn);
    aIn = pLevel->aInLoop;
    if( aIn ){
      aIn += pLevel->nIn*3 - 3;
      aIn[0] = OP_Next;
      aIn[1] = iTab;
      aIn[2] = sqlite3VdbeAddOp(v, OP_Column, iTab, 0);
    }else{
      pLevel->nIn = 0;
    }
#endif
  }
  disableTerm(pLevel, pTerm);
}

/*
** Generate code that will evaluate all == and IN constraints for an
** index.  The values for all constraints are left on the stack.
**
** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c).
** Suppose the WHERE clause is this:  a==5 AND b IN (1,2,3) AND c>5 AND c<10
** The index has as many as three equality constraints, but in this
** example, the third "c" value is an inequality.  So only two 
** constraints are coded.  This routine will generate code to evaluate
** a==5 and b IN (1,2,3).  The current values for a and b will be left
** on the stack - a is the deepest and b the shallowest.
**
** In the example above nEq==2.  But this subroutine works for any value
** of nEq including 0.  If nEq==0, this routine is nearly a no-op.
** The only thing it does is allocate the pLevel->iMem memory cell.
**
** This routine always allocates at least one memory cell and puts
** the address of that memory cell in pLevel->iMem.  The code that
** calls this routine will use pLevel->iMem to store the termination
** key value of the loop.  If one or more IN operators appear, then
** this routine allocates an additional nEq memory cells for internal
** use.
*/
static void codeAllEqualityTerms(
  Parse *pParse,        /* Parsing context */
  WhereLevel *pLevel,   /* Which nested loop of the FROM we are coding */
  WhereClause *pWC,     /* The WHERE clause */
  Bitmask notReady,     /* Which parts of FROM have not yet been coded */
  int brk               /* Jump here to end the loop */
){
  int nEq = pLevel->nEq;        /* The number of == or IN constraints to code */
  int termsInMem = 0;           /* If true, store value in mem[] cells */
  Vdbe *v = pParse->pVdbe;      /* The virtual machine under construction */
  Index *pIdx = pLevel->pIdx;   /* The index being used for this loop */
  int iCur = pLevel->iTabCur;   /* The cursor of the table */
  WhereTerm *pTerm;             /* A single constraint term */
  int j;                        /* Loop counter */

  /* Figure out how many memory cells we will need then allocate them.
  ** We always need at least one used to store the loop terminator
  ** value.  If there are IN operators we'll need one for each == or
  ** IN constraint.
  */
  pLevel->iMem = pParse->nMem++;
  if( pLevel->flags & WHERE_COLUMN_IN ){
    pParse->nMem += pLevel->nEq;
    termsInMem = 1;
  }

  /* Evaluate the equality constraints
  */
  for(j=0; j<pIdx->nColumn; j++){
    int k = pIdx->aiColumn[j];
    pTerm = findTerm(pWC, iCur, k, notReady, WO_EQ|WO_IN, pIdx);
    if( pTerm==0 ) break;
    assert( (pTerm->flags & TERM_CODED)==0 );
    codeEqualityTerm(pParse, pTerm, brk, pLevel);
    if( termsInMem ){
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem+j+1, 1);
    }
  }
  assert( j==nEq );

  /* Make sure all the constraint values are on the top of the stack
  */
  if( termsInMem ){
    for(j=0; j<nEq; j++){
      sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem+j+1, 0);
    }
  }
}

#if defined(SQLITE_TEST)
/*
** The following variable holds a text description of query plan generated
** by the most recent call to sqlite3WhereBegin().  Each call to WhereBegin
** overwrites the previous.  This information is used for testing and
** analysis only.
*/
char sqlite3_query_plan[BMS*2*40];  /* Text of the join */
static int nQPlan = 0;              /* Next free slow in _query_plan[] */

#endif /* SQLITE_TEST */



/*
** Generate the beginning of the loop used for WHERE clause processing.
** The return value is a pointer to an opaque structure that contains
** information needed to terminate the loop.  Later, the calling routine
** should invoke sqlite3WhereEnd() with the return value of this function







<
<
<
<
<


|
|
|
|
>
>
>
>
>
>










|
<
<

|
<










>
>
|
>
>
>
>
>












<
<
<
<
<
<
<
<
<
<
<
<
<







<
<
<
|









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

<
|
<
<
<

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

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

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

<
<
<
<
<
<

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

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













>
>
>
>
















|
|
|
|












<









|
<













<
<
<
<

|





|






>
|

|
|




















|
<






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















|
<
|
|
|
|

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









|
<


|
<
<
<

|
<
<
<
<
<
<

|





<

|
|
<
<
<
<
<
<
<



|



|






<





>

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


|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<

<
<
|
<
<







163
164
165
166
167
168
169





170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192


193
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224













225
226
227
228
229
230
231



232
233
234
235
236
237
238
239
240
241
















242

















243

244
245



























246




















247


248




249

250



251




252






















253

254
255



256
257



258




















259










260
261
262
263






264
265






266






267





268

269



270
271
272

273
274
275
276
277
278
279
280

281



282
283
284











285









286























287









288
289
290
291
292
293
294

295
296
297

298
299

300

301






302









303
304







305
306

307




308












309
310











































311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

360
361
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382




383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428




















































































































































































































































429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446

447
448
449
450
451
452


453
454



455




456
457
458
459
460
461
462
463
464
465

466
467
468



469
470






471
472
473
474
475
476
477

478
479
480







481
482
483
484
485
486
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501








502
503
504

505
506
507
508






































509



































510
511



512


513


514
515
516
517
518
519
520
    }
  }
  return 0;
}

/*
** Create a new mask for cursor iCursor.





*/
static void createMask(ExprMaskSet *pMaskSet, int iCursor){
  if( pMaskSet->n<ARRAYSIZE(pMaskSet->ix) ){
    pMaskSet->ix[pMaskSet->n++] = iCursor;
  }
}

/*
** Destroy an expression mask set
*/
#define freeMaskSet(P)   /* NO-OP */

/*
** This routine walks (recursively) an expression tree and generates
** a bitmask indicating which tables are used in that expression
** tree.
**
** In order for this routine to work, the calling function must have
** previously invoked sqlite3ExprResolveNames() on the expression.  See
** the header comment on that routine for additional information.
** The sqlite3ExprResolveNames() routines looks for column names and
** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
** the VDBE cursor number of the table.


*/
static Bitmask exprListTableUsage(ExprMaskSet *, ExprList *);

static Bitmask exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
  Bitmask mask = 0;
  if( p==0 ) return 0;
  if( p->op==TK_COLUMN ){
    mask = getMask(pMaskSet, p->iTable);
    return mask;
  }
  mask = exprTableUsage(pMaskSet, p->pRight);
  mask |= exprTableUsage(pMaskSet, p->pLeft);
  mask |= exprListTableUsage(pMaskSet, p->pList);
  if( p->pSelect ){
    Select *pS = p->pSelect;
    mask |= exprListTableUsage(pMaskSet, pS->pEList);
    mask |= exprListTableUsage(pMaskSet, pS->pGroupBy);
    mask |= exprListTableUsage(pMaskSet, pS->pOrderBy);
    mask |= exprTableUsage(pMaskSet, pS->pWhere);
    mask |= exprTableUsage(pMaskSet, pS->pHaving);
  }
  return mask;
}
static Bitmask exprListTableUsage(ExprMaskSet *pMaskSet, ExprList *pList){
  int i;
  Bitmask mask = 0;
  if( pList ){
    for(i=0; i<pList->nExpr; i++){
      mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr);
    }
  }
  return mask;
}














/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term.  The allowed operators are
** "=", "<", ">", "<=", ">=", and "IN".
*/
static int allowedOp(int op){



  assert( TK_GT==TK_LE-1 && TK_LE==TK_LT-1 && TK_LT==TK_GE-1 && TK_EQ==TK_GT-1);
  return op==TK_IN || (op>=TK_EQ && op<=TK_GE);
}

/*
** Swap two objects of type T.
*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}

/*
















** Return the index in the SrcList that uses cursor iCur.  If iCur is

















** used by the first entry in SrcList return 0.  If iCur is used by

** the second entry return 1.  And so forth.
**



























** SrcList is the set of tables in the FROM clause in the order that




















** they will be processed.  The value returned here gives us an index


** of which tables will be processed first.




*/

static int tableOrder(SrcList *pList, int iCur){



  int i;




  struct SrcList_item *pItem;






















  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){

    if( pItem->iCursor==iCur ) return i;
  }



  return -1;
}
























/*










** The input to this routine is an ExprInfo structure with only the
** "p" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the ExprInfo
** structure.






*/
static void exprAnalyze(SrcList *pSrc, ExprMaskSet *pMaskSet, ExprInfo *pInfo){






  Expr *pExpr = pInfo->p;






  pInfo->prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);





  pInfo->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);

  pInfo->prereqAll = exprTableUsage(pMaskSet, pExpr);



  pInfo->indexable = 0;
  pInfo->idxLeft = -1;
  pInfo->idxRight = -1;

  if( allowedOp(pExpr->op) && (pInfo->prereqRight & pInfo->prereqLeft)==0 ){
    if( pExpr->pRight && pExpr->pRight->op==TK_COLUMN ){
      pInfo->idxRight = pExpr->pRight->iTable;
      pInfo->indexable = 1;
    }
    if( pExpr->pLeft->op==TK_COLUMN ){
      pInfo->idxLeft = pExpr->pLeft->iTable;
      pInfo->indexable = 1;

    }



  }
  if( pInfo->indexable ){
    assert( pInfo->idxLeft!=pInfo->idxRight );





















    /* We want the expression to be of the form "X = expr", not "expr = X".























    ** So flip it over if necessary.  If the expression is "X = Y", then









    ** we want Y to come from an earlier table than X.
    **
    ** The collating sequence rule is to always choose the left expression.
    ** So if we do a flip, we also have to move the collating sequence.
    */
    if( tableOrder(pSrc,pInfo->idxLeft)<tableOrder(pSrc,pInfo->idxRight) ){
      assert( pExpr->op!=TK_IN );

      SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
      SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
      if( pExpr->op>=TK_GT ){

        assert( TK_LT==TK_GT+2 );
        assert( TK_GE==TK_LE+2 );

        assert( TK_GT>TK_EQ );

        assert( TK_GT<TK_LE );






        assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );









        pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
      }







      SWAP(unsigned, pInfo->prereqLeft, pInfo->prereqRight);
      SWAP(short int, pInfo->idxLeft, pInfo->idxRight);

    }




  }      













}












































/*
** This routine decides if pIdx can be used to satisfy the ORDER BY
** clause.  If it can, it returns 1.  If pIdx cannot satisfy the
** ORDER BY clause, this routine returns 0.
**
** pOrderBy is an ORDER BY clause from a SELECT statement.  pTab is the
** left-most table in the FROM clause of that same SELECT statement and
** the table has a cursor number of "base".  pIdx is an index on pTab.
**
** nEqCol is the number of columns of pIdx that are used as equality
** constraints.  Any of these columns may be missing from the ORDER BY
** clause and the match can still be a success.
**
** If the index is UNIQUE, then the ORDER BY clause is allowed to have
** additional terms past the end of the index and the match will still
** be a success.
**
** All terms of the ORDER BY that match against the index must be either
** ASC or DESC.  (Terms of the ORDER BY clause past the end of a UNIQUE
** index do not need to satisfy this constraint.)  The *pbRev value is
** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if
** the ORDER BY clause is all ASC.
*/
static int isSortingIndex(
  Parse *pParse,          /* Parsing context */
  Index *pIdx,            /* The index we are testing */
  Table *pTab,            /* The table to be sorted */
  int base,               /* Cursor number for pTab */
  ExprList *pOrderBy,     /* The ORDER BY clause */
  int nEqCol,             /* Number of index columns with == constraints */
  int *pbRev              /* Set to 1 if ORDER BY is DESC */
){
  int i, j;                    /* Loop counters */
  int sortOrder;               /* Which direction we are sorting */
  int nTerm;                   /* Number of ORDER BY terms */
  struct ExprList_item *pTerm; /* A term of the ORDER BY clause */
  sqlite3 *db = pParse->db;

  assert( pOrderBy!=0 );
  nTerm = pOrderBy->nExpr;
  assert( nTerm>0 );

  /* Match terms of the ORDER BY clause against columns of
  ** the index.
  */
  for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<pIdx->nColumn; i++){
    Expr *pExpr;       /* The expression of the ORDER BY pTerm */
    CollSeq *pColl;    /* The collating sequence of pExpr */


    pExpr = pTerm->pExpr;
    if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
      /* Can not use an index sort on anything that is not a column in the
      ** left-most table of the FROM clause */
      return 0;
    }
    pColl = sqlite3ExprCollSeq(pParse, pExpr);
    if( !pColl ) pColl = db->pDfltColl;
    if( pExpr->iColumn!=pIdx->aiColumn[i] || pColl!=pIdx->keyInfo.aColl[i] ){

      /* Term j of the ORDER BY clause does not match column i of the index */
      if( i<nEqCol ){
        /* If an index column that is constrained by == fails to match an
        ** ORDER BY term, that is OK.  Just ignore that column of the index
        */
        continue;
      }else{
        /* If an index column fails to match and is not constrained by ==
        ** then the index cannot satisfy the ORDER BY constraint.
        */
        return 0;
      }
    }




    if( i>nEqCol ){
      if( pTerm->sortOrder!=sortOrder ){
        /* Indices can only be used if all ORDER BY terms past the
        ** equality constraints are all either DESC or ASC. */
        return 0;
      }
    }else{
      sortOrder = pTerm->sortOrder;
    }
    j++;
    pTerm++;
  }

  /* The index can be used for sorting if all terms of the ORDER BY clause
  ** or covered or if we ran out of index columns and the it is a UNIQUE
  ** index.
  */
  if( j>=nTerm || (i>=pIdx->nColumn && pIdx->onError!=OE_None) ){
    *pbRev = sortOrder==SQLITE_SO_DESC;
    return 1;
  }
  return 0;
}

/*
** Check table to see if the ORDER BY clause in pOrderBy can be satisfied
** by sorting in order of ROWID.  Return true if so and set *pbRev to be
** true for reverse ROWID and false for forward ROWID order.
*/
static int sortableByRowid(
  int base,               /* Cursor number for table to be sorted */
  ExprList *pOrderBy,     /* The ORDER BY clause */
  int *pbRev              /* Set to 1 if ORDER BY is DESC */
){
  Expr *p;

  assert( pOrderBy!=0 );
  assert( pOrderBy->nExpr>0 );
  p = pOrderBy->a[0].pExpr;
  if( p->op==TK_COLUMN && p->iTable==base && p->iColumn==-1 ){

    *pbRev = pOrderBy->a[0].sortOrder;
    return 1;
  }
  return 0;
}






















































































































































































































































/*
** Disable a term in the WHERE clause.  Except, do not disable the term
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
** or USING clause of that join.
**
** Consider the term t2.z='ok' in the following queries:
**
**   (1)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
**   (2)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
**   (3)  SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
**
** The t2.z='ok' is disabled in the in (2) because it originates
** in the ON clause.  The term is disabled in (3) because it is not part
** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
**
** Disabling a term causes that term to not be tested in the inner loop
** of the join.  Disabling is an optimization.  We would get the correct

** results if nothing were ever disabled, but joins might run a little
** slower.  The trick is to disable as much as we can without disabling
** too much.  If we disabled in (1), we'd get the wrong answer.
** See ticket #813.
*/
static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){


  Expr *pExpr = *ppExpr;
  if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){



    *ppExpr = 0;




  }
}

/*
** Generate code that builds a probe for an index.  Details:
**
**    *  Check the top nColumn entries on the stack.  If any
**       of those entries are NULL, jump immediately to brk,
**       which is the loop exit, since no index entry will match
**       if any part of the key is NULL.

**
**    *  Construct a probe entry from the top nColumn entries in
**       the stack with affinities appropriate for index pIdx.



*/
static void buildIndexProbe(Vdbe *v, int nColumn, int brk, Index *pIdx){






  sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
  sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
  sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
  sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
  sqlite3IndexAffinityStr(v, pIdx);
}


/*
** Generate code for an equality term of the WHERE clause.  An equality
** term can be either X=expr  or X IN (...).   pTerm is the X.  







*/
static void codeEqualityTerm(
  Parse *pParse,      /* The parsing context */
  ExprInfo *pTerm,    /* The term of the WHERE clause to be coded */
  int brk,            /* Jump here to abandon the loop */
  WhereLevel *pLevel  /* When level of the FROM clause we are working on */
){
  Expr *pX = pTerm->p;
  if( pX->op!=TK_IN ){
    assert( pX->op==TK_EQ );
    sqlite3ExprCode(pParse, pX->pRight);
#ifndef SQLITE_OMIT_SUBQUERY
  }else{
    int iTab;

    Vdbe *v = pParse->pVdbe;

    sqlite3CodeSubselect(pParse, pX);
    iTab = pX->iTable;
    sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk);
    sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1);
    VdbeComment((v, "# %.*s", pX->span.n, pX->span.z));








    pLevel->inP2 = sqlite3VdbeAddOp(v, OP_Column, iTab, 0);
    pLevel->inOp = OP_Next;
    pLevel->inP1 = iTab;

#endif
  }
  disableTerm(pLevel, &pTerm->p);
}










































































/*
** The number of bits in a Bitmask



*/


#define BMS  (sizeof(Bitmask)*8-1)




/*
** Generate the beginning of the loop used for WHERE clause processing.
** The return value is a pointer to an opaque structure that contains
** information needed to terminate the loop.  Later, the calling routine
** should invoke sqlite3WhereEnd() with the return value of this function
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
**        foreach row2 in t2 do      |-- by sqlite3WhereBegin()
**          foreach row3 in t3 do   /
**            ...
**          end                     \    Code generated
**        end                        |-- by sqlite3WhereEnd()
**      end                         /
**
** Note that the loops might not be nested in the order in which they
** appear in the FROM clause if a different order is better able to make
** use of indices.  Note also that when the IN operator appears in
** the WHERE clause, it might result in additional nested loops for
** scanning through all values on the right-hand side of the IN.
**
** There are Btree cursors associated with each table.  t1 uses cursor
** number pTabList->a[0].iCursor.  t2 uses the cursor pTabList->a[1].iCursor.
** And so forth.  This routine generates code to open those VDBE cursors
** and sqlite3WhereEnd() generates the code to close them.
**
** The code that sqlite3WhereBegin() generates leaves the cursors named
** in pTabList pointing at their appropriate entries.  The [...] code
** can use OP_Column and OP_Rowid opcodes on these cursors to extract
** data from the various tables of the loop.
**
** If the WHERE clause is empty, the foreach loops must each scan their
** entire tables.  Thus a three-way join is an O(N^3) operation.  But if
** the tables have indices and there are terms in the WHERE clause that
** refer to those indices, a complete table scan can be avoided and the
** code will run much faster.  Most of the work of this routine is checking







<
<
<
<
<
<







|







535
536
537
538
539
540
541






542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
**        foreach row2 in t2 do      |-- by sqlite3WhereBegin()
**          foreach row3 in t3 do   /
**            ...
**          end                     \    Code generated
**        end                        |-- by sqlite3WhereEnd()
**      end                         /
**






** There are Btree cursors associated with each table.  t1 uses cursor
** number pTabList->a[0].iCursor.  t2 uses the cursor pTabList->a[1].iCursor.
** And so forth.  This routine generates code to open those VDBE cursors
** and sqlite3WhereEnd() generates the code to close them.
**
** The code that sqlite3WhereBegin() generates leaves the cursors named
** in pTabList pointing at their appropriate entries.  The [...] code
** can use OP_Column and OP_Recno opcodes on these cursors to extract
** data from the various tables of the loop.
**
** If the WHERE clause is empty, the foreach loops must each scan their
** entire tables.  Thus a three-way join is an O(N^3) operation.  But if
** the tables have indices and there are terms in the WHERE clause that
** refer to those indices, a complete table scan can be avoided and the
** code will run much faster.  Most of the work of this routine is checking
1413
1414
1415
1416
1417
1418
1419
1420

1421
1422
1423
1424
1425
1426

1427
1428



1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439

1440
1441
1442
1443
1444


1445
1446



1447

1448

1449
1450
1451
1452
1453
1454

1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476

1477
1478
1479
1480
1481
1482


1483
1484
1485


1486

1487
1488
1489
1490
1491
1492
1493

1494
1495
1496
1497
1498
1499
1500
1501




1502
1503
1504
1505
1506
1507
1508
1509
1510


























1511










1512









































1513
1514
1515
1516
1517
1518
1519
1520


1521
1522
1523


1524





1525
1526


1527





1528




1529
1530
1531
1532











1533
1534
1535
1536





1537







1538







1539


1540















1541





1542






1543


1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556









1557




1558
1559
1560
1561















1562

1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617

1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628


1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646

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

1660
1661
1662
1663
1664
1665
1666
1667
1668

1669
1670
1671
1672
1673

1674

1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884

1885
1886

1887
1888
1889











1890

1891
1892



1893
1894

1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922















































































1923
1924
















1925


















1926






















































































































1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950

1951
1952
1953
1954
1955
1956
1957

1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038

2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059

2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077

2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
** If the where clause loops cannot be arranged to provide the correct
** output order, then the *ppOrderBy is unchanged.
*/
WhereInfo *sqlite3WhereBegin(
  Parse *pParse,        /* The parser context */
  SrcList *pTabList,    /* A list of all tables to be scanned */
  Expr *pWhere,         /* The WHERE clause */
  ExprList **ppOrderBy  /* An ORDER BY clause, or NULL */

){
  int i;                     /* Loop counter */
  WhereInfo *pWInfo;         /* Will become the return value of this function */
  Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
  int brk, cont = 0;         /* Addresses used during code generation */
  Bitmask notReady;          /* Cursors that are not yet positioned */

  WhereTerm *pTerm;          /* A single term in the WHERE clause */
  ExprMaskSet maskSet;       /* The expression mask set */



  WhereClause wc;            /* The WHERE clause is divided into these terms */
  struct SrcList_item *pTabItem;  /* A single entry from pTabList */
  WhereLevel *pLevel;             /* A single level in the pWInfo list */
  int iFrom;                      /* First unused FROM clause element */
  int andFlags;              /* AND-ed combination of all wc.a[].flags */

  /* The number of tables in the FROM clause is limited by the number of
  ** bits in a Bitmask 
  */
  if( pTabList->nSrc>BMS ){
    sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS);

    return 0;
  }

  /* Split the WHERE clause into separate subexpressions where each
  ** subexpression is separated by an AND operator.


  */
  initMaskSet(&maskSet);



  whereClauseInit(&wc, pParse);

  whereSplit(&wc, pWhere, TK_AND);

    
  /* Allocate and initialize the WhereInfo structure that will become the
  ** return value.
  */
  pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
  if( sqlite3ThreadDataReadOnly()->mallocFailed ){

    goto whereBeginNoMem;
  }
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->iBreak = sqlite3VdbeMakeLabel(v);

  /* Special case: a WHERE clause that is constant.  Evaluate the
  ** expression and either jump over all of the code or fall thru.
  */
  if( pWhere && (pTabList->nSrc==0 || sqlite3ExprIsConstant(pWhere)) ){
    sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);
    pWhere = 0;
  }

  /* Analyze all of the subexpressions.  Note that exprAnalyze() might
  ** add new virtual terms onto the end of the WHERE clause.  We do not
  ** want to analyze these virtual terms, so start analyzing at the end
  ** and work forward so that the added virtual terms are never processed.
  */
  for(i=0; i<pTabList->nSrc; i++){
    createMask(&maskSet, pTabList->a[i].iCursor);
  }

  exprAnalyzeAll(pTabList, &maskSet, &wc);
  if( sqlite3ThreadDataReadOnly()->mallocFailed ){
    goto whereBeginNoMem;
  }

  /* Chose the best index to use for each table in the FROM clause.


  **
  ** This loop fills in the following fields:
  **


  **   pWInfo->a[].pIdx      The index to use for this level of the loop.

  **   pWInfo->a[].flags     WHERE_xxx flags associated with pIdx
  **   pWInfo->a[].nEq       The number of == and IN constraints
  **   pWInfo->a[].iFrom     When term of the FROM clause is being coded
  **   pWInfo->a[].iTabCur   The VDBE cursor for the database table
  **   pWInfo->a[].iIdxCur   The VDBE cursor for the index
  **
  ** This loop also figures out the nesting order of tables in the FROM

  ** clause.
  */
  notReady = ~(Bitmask)0;
  pTabItem = pTabList->a;
  pLevel = pWInfo->a;
  andFlags = ~0;
  TRACE(("*** Optimizer Start ***\n"));
  for(i=iFrom=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){




    Index *pIdx;                /* Index for FROM table at pTabItem */
    int flags;                  /* Flags asssociated with pIdx */
    int nEq;                    /* Number of == or IN constraints */
    double cost;                /* The cost for pIdx */
    int j;                      /* For looping over FROM tables */
    Index *pBest = 0;           /* The best index seen so far */
    int bestFlags = 0;          /* Flags associated with pBest */
    int bestNEq = 0;            /* nEq associated with pBest */
    double lowestCost;          /* Cost of the pBest */


























    int bestJ;                  /* The value of j */










    Bitmask m;                  /* Bitmask value for j or bestJ */










































    lowestCost = SQLITE_BIG_DBL;
    for(j=iFrom, pTabItem=&pTabList->a[j]; j<pTabList->nSrc; j++, pTabItem++){
      m = getMask(&maskSet, pTabItem->iCursor);
      if( (m & notReady)==0 ){
        if( j==iFrom ) iFrom++;
        continue;
      }


      cost = bestIndex(pParse, &wc, pTabItem, notReady,
                       (i==0 && ppOrderBy) ? *ppOrderBy : 0,
                       &pIdx, &flags, &nEq);


      if( cost<lowestCost ){





        lowestCost = cost;
        pBest = pIdx;


        bestFlags = flags;





        bestNEq = nEq;




        bestJ = j;
      }
      if( (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0
         || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0)











      ){
        break;
      }
    }





    TRACE(("*** Optimizer choose table %d for loop %d\n", bestJ,







           pLevel-pWInfo->a));







    if( (bestFlags & WHERE_ORDERBY)!=0 ){


      *ppOrderBy = 0;















    }





    andFlags &= bestFlags;






    pLevel->flags = bestFlags;


    pLevel->pIdx = pBest;
    pLevel->nEq = bestNEq;
    pLevel->aInLoop = 0;
    pLevel->nIn = 0;
    if( pBest ){
      pLevel->iIdxCur = pParse->nTab++;
    }else{
      pLevel->iIdxCur = -1;
    }
    notReady &= ~getMask(&maskSet, pTabList->a[bestJ].iCursor);
    pLevel->iFrom = bestJ;
  }
  TRACE(("*** Optimizer Finished ***\n"));














  /* If the total query only selects a single row, then the ORDER BY
  ** clause is irrelevant.
  */
  if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){















    *ppOrderBy = 0;

  }

  /* Open all tables in the pTabList and any indices selected for
  ** searching those tables.
  */
  sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
  pLevel = pWInfo->a;
  for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
    Table *pTab;     /* Table to open */
    Index *pIx;      /* Index used to access pTab (if any) */
    int iDb;         /* Index of database containing table/index */
    int iIdxCur = pLevel->iIdxCur;

#ifndef SQLITE_OMIT_EXPLAIN
    if( pParse->explain==2 ){
      char *zMsg;
      struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
      zMsg = sqlite3MPrintf("TABLE %s", pItem->zName);
      if( pItem->zAlias ){
        zMsg = sqlite3MPrintf("%z AS %s", zMsg, pItem->zAlias);
      }
      if( (pIx = pLevel->pIdx)!=0 ){
        zMsg = sqlite3MPrintf("%z WITH INDEX %s", zMsg, pIx->zName);
      }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
        zMsg = sqlite3MPrintf("%z USING PRIMARY KEY", zMsg);
      }
      sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC);
    }
#endif /* SQLITE_OMIT_EXPLAIN */
    pTabItem = &pTabList->a[pLevel->iFrom];
    pTab = pTabItem->pTab;
    iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
    if( pTab->isTransient || pTab->pSelect ) continue;
    if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
      sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, OP_OpenRead);
      if( pTab->nCol<(sizeof(Bitmask)*8) ){
        Bitmask b = pTabItem->colUsed;
        int n = 0;
        for(; b; b=b>>1, n++);
        sqlite3VdbeChangeP2(v, sqlite3VdbeCurrentAddr(v)-1, n);
        assert( n<=pTab->nCol );
      }
    }else{
      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
    }
    pLevel->iTabCur = pTabItem->iCursor;
    if( (pIx = pLevel->pIdx)!=0 ){
      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
      assert( pIx->pSchema==pTab->pSchema );
      sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
      VdbeComment((v, "# %s", pIx->zName));
      sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum,
                     (char*)pKey, P3_KEYINFO_HANDOFF);
    }
    if( (pLevel->flags & WHERE_IDX_ONLY)!=0 ){

      sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
    }
    sqlite3CodeVerifySchema(pParse, iDb);
  }
  pWInfo->iTop = sqlite3VdbeCurrentAddr(v);

  /* Generate the code to do the search.  Each iteration of the for
  ** loop below generates code for a single nested loop of the VM
  ** program.
  */
  notReady = ~(Bitmask)0;


  for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
    int j;
    int iCur = pTabItem->iCursor;  /* The VDBE cursor for the table */
    Index *pIdx;       /* The index we will be using */
    int iIdxCur;       /* The VDBE cursor for the index */
    int omitTable;     /* True if we use the index only */
    int bRev;          /* True if we need to scan in reverse order */

    pTabItem = &pTabList->a[pLevel->iFrom];
    iCur = pTabItem->iCursor;
    pIdx = pLevel->pIdx;
    iIdxCur = pLevel->iIdxCur;
    bRev = (pLevel->flags & WHERE_REVERSE)!=0;
    omitTable = (pLevel->flags & WHERE_IDX_ONLY)!=0;

    /* Create labels for the "break" and "continue" instructions
    ** for the current loop.  Jump to brk to break out of a loop.
    ** Jump to cont to go immediately to the next iteration of the

    ** loop.
    */
    brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
    cont = pLevel->cont = sqlite3VdbeMakeLabel(v);

    /* If this is the right table of a LEFT OUTER JOIN, allocate and
    ** initialize a memory cell that records if this table matches any
    ** row of the left table of the join.
    */
    if( pLevel->iFrom>0 && (pTabItem[-1].jointype & JT_LEFT)!=0 ){
      if( !pParse->nMem ) pParse->nMem++;
      pLevel->iLeftJoin = pParse->nMem++;
      sqlite3VdbeAddOp(v, OP_MemInt, 0, pLevel->iLeftJoin);

      VdbeComment((v, "# init LEFT JOIN no-match flag"));
    }

    if( pLevel->flags & WHERE_ROWID_EQ ){
      /* Case 1:  We can directly reference a single row using an
      **          equality comparison against the ROWID field.  Or
      **          we reference multiple rows using a "rowid IN (...)"
      **          construct.
      */

      pTerm = findTerm(&wc, iCur, -1, notReady, WO_EQ|WO_IN, 0);
      assert( pTerm!=0 );
      assert( pTerm->pExpr!=0 );
      assert( pTerm->leftCursor==iCur );
      assert( omitTable==0 );

      codeEqualityTerm(pParse, pTerm, brk, pLevel);

      sqlite3VdbeAddOp(v, OP_MustBeInt, 1, brk);
      sqlite3VdbeAddOp(v, OP_NotExists, iCur, brk);
      VdbeComment((v, "pk"));
      pLevel->op = OP_Noop;
    }else if( pLevel->flags & WHERE_ROWID_RANGE ){
      /* Case 2:  We have an inequality comparison against the ROWID field.
      */
      int testOp = OP_Noop;
      int start;
      WhereTerm *pStart, *pEnd;

      assert( omitTable==0 );
      pStart = findTerm(&wc, iCur, -1, notReady, WO_GT|WO_GE, 0);
      pEnd = findTerm(&wc, iCur, -1, notReady, WO_LT|WO_LE, 0);
      if( bRev ){
        pTerm = pStart;
        pStart = pEnd;
        pEnd = pTerm;
      }
      if( pStart ){
        Expr *pX;
        pX = pStart->pExpr;
        assert( pX!=0 );
        assert( pStart->leftCursor==iCur );
        sqlite3ExprCode(pParse, pX->pRight);
        sqlite3VdbeAddOp(v, OP_ForceInt, pX->op==TK_LE || pX->op==TK_GT, brk);
        sqlite3VdbeAddOp(v, bRev ? OP_MoveLt : OP_MoveGe, iCur, brk);
        VdbeComment((v, "pk"));
        disableTerm(pLevel, pStart);
      }else{
        sqlite3VdbeAddOp(v, bRev ? OP_Last : OP_Rewind, iCur, brk);
      }
      if( pEnd ){
        Expr *pX;
        pX = pEnd->pExpr;
        assert( pX!=0 );
        assert( pEnd->leftCursor==iCur );
        sqlite3ExprCode(pParse, pX->pRight);
        pLevel->iMem = pParse->nMem++;
        sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
        if( pX->op==TK_LT || pX->op==TK_GT ){
          testOp = bRev ? OP_Le : OP_Ge;
        }else{
          testOp = bRev ? OP_Lt : OP_Gt;
        }
        disableTerm(pLevel, pEnd);
      }
      start = sqlite3VdbeCurrentAddr(v);
      pLevel->op = bRev ? OP_Prev : OP_Next;
      pLevel->p1 = iCur;
      pLevel->p2 = start;
      if( testOp!=OP_Noop ){
        sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
        sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, testOp, SQLITE_AFF_NUMERIC, brk);
      }
    }else if( pLevel->flags & WHERE_COLUMN_RANGE ){
      /* Case 3: The WHERE clause term that refers to the right-most
      **         column of the index is an inequality.  For example, if
      **         the index is on (x,y,z) and the WHERE clause is of the
      **         form "x=5 AND y<10" then this case is used.  Only the
      **         right-most column can be an inequality - the rest must
      **         use the "==" and "IN" operators.
      **
      **         This case is also used when there are no WHERE clause
      **         constraints but an index is selected anyway, in order
      **         to force the output order to conform to an ORDER BY.
      */
      int start;
      int nEq = pLevel->nEq;
      int topEq=0;        /* True if top limit uses ==. False is strictly < */
      int btmEq=0;        /* True if btm limit uses ==. False if strictly > */
      int topOp, btmOp;   /* Operators for the top and bottom search bounds */
      int testOp;
      int nNotNull;       /* Number of rows of index that must be non-NULL */
      int topLimit = (pLevel->flags & WHERE_TOP_LIMIT)!=0;
      int btmLimit = (pLevel->flags & WHERE_BTM_LIMIT)!=0;

      /* Generate code to evaluate all constraint terms using == or IN
      ** and level the values of those terms on the stack.
      */
      codeAllEqualityTerms(pParse, pLevel, &wc, notReady, brk);

      /* Duplicate the equality term values because they will all be
      ** used twice: once to make the termination key and once to make the
      ** start key.
      */
      for(j=0; j<nEq; j++){
        sqlite3VdbeAddOp(v, OP_Dup, nEq-1, 0);
      }

      /* Figure out what comparison operators to use for top and bottom 
      ** search bounds. For an ascending index, the bottom bound is a > or >=
      ** operator and the top bound is a < or <= operator.  For a descending
      ** index the operators are reversed.
      */
      nNotNull = nEq + topLimit;
      if( pIdx->aSortOrder[nEq]==SQLITE_SO_ASC ){
        topOp = WO_LT|WO_LE;
        btmOp = WO_GT|WO_GE;
      }else{
        topOp = WO_GT|WO_GE;
        btmOp = WO_LT|WO_LE;
        SWAP(int, topLimit, btmLimit);
      }

      /* Generate the termination key.  This is the key value that
      ** will end the search.  There is no termination key if there
      ** are no equality terms and no "X<..." term.
      **
      ** 2002-Dec-04: On a reverse-order scan, the so-called "termination"
      ** key computed here really ends up being the start key.
      */
      if( topLimit ){
        Expr *pX;
        int k = pIdx->aiColumn[j];
        pTerm = findTerm(&wc, iCur, k, notReady, topOp, pIdx);
        assert( pTerm!=0 );
        pX = pTerm->pExpr;
        assert( (pTerm->flags & TERM_CODED)==0 );
        sqlite3ExprCode(pParse, pX->pRight);
        topEq = pTerm->operator & (WO_LE|WO_GE);
        disableTerm(pLevel, pTerm);
        testOp = OP_IdxGE;
      }else{
        testOp = nEq>0 ? OP_IdxGE : OP_Noop;
        topEq = 1;
      }
      if( testOp!=OP_Noop ){
        int nCol = nEq + topLimit;
        pLevel->iMem = pParse->nMem++;
        buildIndexProbe(v, nCol, nEq, brk, pIdx);
        if( bRev ){
          int op = topEq ? OP_MoveLe : OP_MoveLt;
          sqlite3VdbeAddOp(v, op, iIdxCur, brk);
        }else{
          sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
        }
      }else if( bRev ){
        sqlite3VdbeAddOp(v, OP_Last, iIdxCur, brk);
      }

      /* Generate the start key.  This is the key that defines the lower
      ** bound on the search.  There is no start key if there are no
      ** equality terms and if there is no "X>..." term.  In
      ** that case, generate a "Rewind" instruction in place of the
      ** start key search.
      **
      ** 2002-Dec-04: In the case of a reverse-order search, the so-called
      ** "start" key really ends up being used as the termination key.
      */
      if( btmLimit ){
        Expr *pX;
        int k = pIdx->aiColumn[j];
        pTerm = findTerm(&wc, iCur, k, notReady, btmOp, pIdx);
        assert( pTerm!=0 );
        pX = pTerm->pExpr;
        assert( (pTerm->flags & TERM_CODED)==0 );
        sqlite3ExprCode(pParse, pX->pRight);
        btmEq = pTerm->operator & (WO_LE|WO_GE);
        disableTerm(pLevel, pTerm);
      }else{
        btmEq = 1;
      }
      if( nEq>0 || btmLimit ){
        int nCol = nEq + btmLimit;
        buildIndexProbe(v, nCol, 0, brk, pIdx);
        if( bRev ){
          pLevel->iMem = pParse->nMem++;
          sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
          testOp = OP_IdxLT;
        }else{
          int op = btmEq ? OP_MoveGe : OP_MoveGt;
          sqlite3VdbeAddOp(v, op, iIdxCur, brk);
        }
      }else if( bRev ){
        testOp = OP_Noop;
      }else{
        sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, brk);
      }

      /* Generate the the top of the loop.  If there is a termination
      ** key we have to test for that key and abort at the top of the
      ** loop.
      */
      start = sqlite3VdbeCurrentAddr(v);
      if( testOp!=OP_Noop ){
        sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, testOp, iIdxCur, brk);
        if( (topEq && !bRev) || (!btmEq && bRev) ){
          sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
        }
      }
      sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
      sqlite3VdbeAddOp(v, OP_IdxIsNull, nNotNull, cont);
      if( !omitTable ){
        sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
        sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      }

      /* Record the instruction used to terminate the loop.
      */
      pLevel->op = bRev ? OP_Prev : OP_Next;
      pLevel->p1 = iIdxCur;
      pLevel->p2 = start;
    }else if( pLevel->flags & WHERE_COLUMN_EQ ){
      /* Case 4:  There is an index and all terms of the WHERE clause that
      **          refer to the index using the "==" or "IN" operators.
      */
      int start;

      int nEq = pLevel->nEq;


      /* Generate code to evaluate all constraint terms using == or IN
      ** and leave the values of those terms on the stack.
      */











      codeAllEqualityTerms(pParse, pLevel, &wc, notReady, brk);


      /* Generate a single key that will be used to both start and terminate



      ** the search
      */

      buildIndexProbe(v, nEq, 0, brk, pIdx);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);

      /* Generate code (1) to move to the first matching element of the table.
      ** Then generate code (2) that jumps to "brk" after the cursor is past
      ** the last matching element of the table.  The code (1) is executed
      ** once to initialize the search, the code (2) is executed before each
      ** iteration of the scan to see if the scan has finished. */
      if( bRev ){
        /* Scan in reverse order */
        sqlite3VdbeAddOp(v, OP_MoveLe, iIdxCur, brk);
        start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, OP_IdxLT, iIdxCur, brk);
        pLevel->op = OP_Prev;
      }else{
        /* Scan in the forward order */
        sqlite3VdbeAddOp(v, OP_MoveGe, iIdxCur, brk);
        start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, brk, "+", P3_STATIC);
        pLevel->op = OP_Next;
      }
      sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
      sqlite3VdbeAddOp(v, OP_IdxIsNull, nEq, cont);
      if( !omitTable ){
        sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
        sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      }
      pLevel->p1 = iIdxCur;















































































      pLevel->p2 = start;
    }else{
















      /* Case 5:  There is no usable index.  We must do a complete


















      **          scan of the entire table.






















































































































      */
      assert( omitTable==0 );
      assert( bRev==0 );
      pLevel->op = OP_Next;
      pLevel->p1 = iCur;
      pLevel->p2 = 1 + sqlite3VdbeAddOp(v, OP_Rewind, iCur, brk);
    }
    notReady &= ~getMask(&maskSet, iCur);

    /* Insert code to test every subexpression that can be completely
    ** computed using the current set of tables.
    */
    for(pTerm=wc.a, j=wc.nTerm; j>0; j--, pTerm++){
      Expr *pE;
      if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
      if( (pTerm->prereqAll & notReady)!=0 ) continue;
      pE = pTerm->pExpr;
      assert( pE!=0 );
      if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
        continue;
      }
      sqlite3ExprIfFalse(pParse, pE, cont, 1);
      pTerm->flags |= TERM_CODED;
    }


    /* For a LEFT OUTER JOIN, generate code that will record the fact that
    ** at least one row of the right table has matched the left table.  
    */
    if( pLevel->iLeftJoin ){
      pLevel->top = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp(v, OP_MemInt, 1, pLevel->iLeftJoin);

      VdbeComment((v, "# record LEFT JOIN hit"));
      for(pTerm=wc.a, j=0; j<wc.nTerm; j++, pTerm++){
        if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
        if( (pTerm->prereqAll & notReady)!=0 ) continue;
        assert( pTerm->pExpr );
        sqlite3ExprIfFalse(pParse, pTerm->pExpr, cont, 1);
        pTerm->flags |= TERM_CODED;
      }
    }
  }

#ifdef SQLITE_TEST  /* For testing and debugging use only */
  /* Record in the query plan information about the current table
  ** and the index used to access it (if any).  If the table itself
  ** is not used, its name is just '{}'.  If no index is used
  ** the index is listed as "{}".  If the primary key is used the
  ** index name is '*'.
  */
  for(i=0; i<pTabList->nSrc; i++){
    char *z;
    int n;
    pLevel = &pWInfo->a[i];
    pTabItem = &pTabList->a[pLevel->iFrom];
    z = pTabItem->zAlias;
    if( z==0 ) z = pTabItem->pTab->zName;
    n = strlen(z);
    if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){
      if( pLevel->flags & WHERE_IDX_ONLY ){
        strcpy(&sqlite3_query_plan[nQPlan], "{}");
        nQPlan += 2;
      }else{
        strcpy(&sqlite3_query_plan[nQPlan], z);
        nQPlan += n;
      }
      sqlite3_query_plan[nQPlan++] = ' ';
    }
    if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
      strcpy(&sqlite3_query_plan[nQPlan], "* ");
      nQPlan += 2;
    }else if( pLevel->pIdx==0 ){
      strcpy(&sqlite3_query_plan[nQPlan], "{} ");
      nQPlan += 3;
    }else{
      n = strlen(pLevel->pIdx->zName);
      if( n+nQPlan < sizeof(sqlite3_query_plan)-2 ){
        strcpy(&sqlite3_query_plan[nQPlan], pLevel->pIdx->zName);
        nQPlan += n;
        sqlite3_query_plan[nQPlan++] = ' ';
      }
    }
  }
  while( nQPlan>0 && sqlite3_query_plan[nQPlan-1]==' ' ){
    sqlite3_query_plan[--nQPlan] = 0;
  }
  sqlite3_query_plan[nQPlan] = 0;
  nQPlan = 0;
#endif /* SQLITE_TEST // Testing and debugging use only */

  /* Record the continuation address in the WhereInfo structure.  Then
  ** clean up and return.
  */
  pWInfo->iContinue = cont;
  whereClauseClear(&wc);
  return pWInfo;

  /* Jump here if malloc fails */
whereBeginNoMem:
  whereClauseClear(&wc);
  sqliteFree(pWInfo);
  return 0;
}

/*
** Generate the end of the WHERE loop.  See comments on 
** sqlite3WhereBegin() for additional information.
*/
void sqlite3WhereEnd(WhereInfo *pWInfo){
  Vdbe *v = pWInfo->pParse->pVdbe;
  int i;
  WhereLevel *pLevel;
  SrcList *pTabList = pWInfo->pTabList;


  /* Generate loop termination code.
  */
  for(i=pTabList->nSrc-1; i>=0; i--){
    pLevel = &pWInfo->a[i];
    sqlite3VdbeResolveLabel(v, pLevel->cont);
    if( pLevel->op!=OP_Noop ){
      sqlite3VdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
    }
    sqlite3VdbeResolveLabel(v, pLevel->brk);
    if( pLevel->nIn ){
      int *a;
      int j;
      for(j=pLevel->nIn, a=&pLevel->aInLoop[j*3-3]; j>0; j--, a-=3){
        sqlite3VdbeAddOp(v, a[0], a[1], a[2]);
      }
      sqliteFree(pLevel->aInLoop);
    }
    if( pLevel->iLeftJoin ){
      int addr;
      addr = sqlite3VdbeAddOp(v, OP_IfMemPos, pLevel->iLeftJoin, 0);

      sqlite3VdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
      if( pLevel->iIdxCur>=0 ){
        sqlite3VdbeAddOp(v, OP_NullRow, pLevel->iIdxCur, 0);
      }
      sqlite3VdbeAddOp(v, OP_Goto, 0, pLevel->top);
      sqlite3VdbeJumpHere(v, addr);
    }
  }

  /* The "break" point is here, just past the end of the outer loop.
  ** Set it.
  */
  sqlite3VdbeResolveLabel(v, pWInfo->iBreak);

  /* Close all of the cursors that were opened by sqlite3WhereBegin.
  */
  for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
    struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];

    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
    if( pTab->isTransient || pTab->pSelect ) continue;
    if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
      sqlite3VdbeAddOp(v, OP_Close, pTabItem->iCursor, 0);
    }
    if( pLevel->pIdx!=0 ){
      sqlite3VdbeAddOp(v, OP_Close, pLevel->iIdxCur, 0);
    }

    /* Make cursor substitutions for cases where we want to use
    ** just the index and never reference the table.
    ** 
    ** Calls to the code generator in between sqlite3WhereBegin and
    ** sqlite3WhereEnd will have created code that references the table
    ** directly.  This loop scans all that code looking for opcodes
    ** that reference the table and converts them into opcodes that
    ** reference the index.
    */
    if( pLevel->flags & WHERE_IDX_ONLY ){
      int i, j, last;
      VdbeOp *pOp;
      Index *pIdx = pLevel->pIdx;

      assert( pIdx!=0 );
      pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
      last = sqlite3VdbeCurrentAddr(v);
      for(i=pWInfo->iTop; i<last; i++, pOp++){
        if( pOp->p1!=pLevel->iTabCur ) continue;
        if( pOp->opcode==OP_Column ){
          pOp->p1 = pLevel->iIdxCur;
          for(j=0; j<pIdx->nColumn; j++){
            if( pOp->p2==pIdx->aiColumn[j] ){
              pOp->p2 = j;
              break;
            }
          }
        }else if( pOp->opcode==OP_Rowid ){
          pOp->p1 = pLevel->iIdxCur;
          pOp->opcode = OP_IdxRowid;
        }else if( pOp->opcode==OP_NullRow ){
          pOp->opcode = OP_Noop;
        }
      }
    }
  }

  /* Final cleanup
  */
  sqliteFree(pWInfo);
  return;
}







|
>





|
>
|
|
>
>
>
|


<
<

|


|
|
>




|
>
>


>
>
>
|
>
|
>





|
>
|













|
<
<
<




>
|
<
<


|
>
>
|
<

>
>
|
>
|
<
<
|
<

|
>
|

|


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

<
<
<
|
<
|

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

<
<

<
<

|
>
>
>
>
>
>
>
>
>

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







|
|
|
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<

|
|
<
<
<
<
<
<
<
<
<



<
<
|
<

|

|
>


|



|
<
<

|
>
>
|
|




<

<
<


|
<

<
<
<
>
|

|
<





|


|
>



|





>
|
|
|
<

>

>




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



>
|

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







|













|

|



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


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

<
<
|
|
|

|




|
<
|
|
<
<
|


|
|

>






|
>

|
|
|
<
|
|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
|
<
<
<
<
|











>










|
<
<
<
|
<
<



|
>





<








|

|
|
>



|















|

















|

|












595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618


619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663



664
665
666
667
668
669


670
671
672
673
674
675

676
677
678
679
680
681


682

683
684
685
686
687
688
689
690


691
692
693
694
695
696




697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780



781

782
783
784
785
786
787

788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890


891


892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938

939
940

















941

942
943
944









945
946
947


948

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


961
962
963
964
965
966
967
968
969
970

971


972
973
974

975



976
977
978
979

980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002

1003
1004
1005
1006
1007
1008
1009
1010






































































































































1011



































































1012
1013
1014
1015
1016
1017
1018
1019
1020
1021

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

1036
1037
1038
1039

1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304


1305
1306
1307
1308
1309
1310
1311
1312
1313
1314

1315
1316


1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335

1336
1337
1338
1339
1340



















































1341


1342




1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366



1367


1368
1369
1370
1371
1372
1373
1374
1375
1376
1377

1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
** If the where clause loops cannot be arranged to provide the correct
** output order, then the *ppOrderBy is unchanged.
*/
WhereInfo *sqlite3WhereBegin(
  Parse *pParse,        /* The parser context */
  SrcList *pTabList,    /* A list of all tables to be scanned */
  Expr *pWhere,         /* The WHERE clause */
  ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
  Fetch *pFetch         /* Initial location of cursors.  NULL otherwise */
){
  int i;                     /* Loop counter */
  WhereInfo *pWInfo;         /* Will become the return value of this function */
  Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
  int brk, cont = 0;         /* Addresses used during code generation */
  int nExpr;           /* Number of subexpressions in the WHERE clause */
  Bitmask loopMask;    /* One bit set for each outer loop */
  ExprInfo *pTerm;     /* A single term in the WHERE clause; ptr to aExpr[] */
  ExprMaskSet maskSet; /* The expression mask set */
  int iDirectEq[BMS];  /* Term of the form ROWID==X for the N-th table */
  int iDirectLt[BMS];  /* Term of the form ROWID<X or ROWID<=X */
  int iDirectGt[BMS];  /* Term of the form ROWID>X or ROWID>=X */
  ExprInfo aExpr[101]; /* The WHERE clause is divided into these terms */
  struct SrcList_item *pTabItem;  /* A single entry from pTabList */
  WhereLevel *pLevel;             /* A single level in the pWInfo list */



  /* The number of terms in the FROM clause is limited by the number of
  ** bits in a Bitmask 
  */
  if( pTabList->nSrc>sizeof(Bitmask)*8 ){
    sqlite3ErrorMsg(pParse, "at most %d tables in a join",
       sizeof(Bitmask)*8);
    return 0;
  }

  /* Split the WHERE clause into separate subexpressions where each
  ** subexpression is separated by an AND operator.  If the aExpr[]
  ** array fills up, the last entry might point to an expression which
  ** contains additional unfactored AND operators.
  */
  initMaskSet(&maskSet);
  memset(aExpr, 0, sizeof(aExpr));
  nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere);
  if( nExpr==ARRAYSIZE(aExpr) ){
    sqlite3ErrorMsg(pParse, "WHERE clause too complex - no more "
       "than %d terms allowed", (int)ARRAYSIZE(aExpr)-1);
    return 0;
  }
    
  /* Allocate and initialize the WhereInfo structure that will become the
  ** return value.
  */
  pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
  if( sqlite3_malloc_failed ){
    /* sqliteFree(pWInfo); // Leak memory when malloc fails */
    return 0;
  }
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->iBreak = sqlite3VdbeMakeLabel(v);

  /* Special case: a WHERE clause that is constant.  Evaluate the
  ** expression and either jump over all of the code or fall thru.
  */
  if( pWhere && (pTabList->nSrc==0 || sqlite3ExprIsConstant(pWhere)) ){
    sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);
    pWhere = 0;
  }

  /* Analyze all of the subexpressions.



  */
  for(i=0; i<pTabList->nSrc; i++){
    createMask(&maskSet, pTabList->a[i].iCursor);
  }
  for(pTerm=aExpr, i=0; i<nExpr; i++, pTerm++){
    exprAnalyze(pTabList, &maskSet, pTerm);


  }

  /* Figure out what index to use (if any) for each nested loop.
  ** Make pWInfo->a[i].pIdx point to the index to use for the i-th nested
  ** loop where i==0 is the outer loop and i==pTabList->nSrc-1 is the inner
  ** loop. 

  **
  ** If terms exist that use the ROWID of any table, then set the
  ** iDirectEq[], iDirectLt[], or iDirectGt[] elements for that table
  ** to the index of the term containing the ROWID.  We always prefer
  ** to use a ROWID which can directly access a table rather than an
  ** index which requires reading an index first to get the rowid then


  ** doing a second read of the actual database table.

  **
  ** Actually, if there are more than 32 tables in the join, only the
  ** first 32 tables are candidates for indices.  This is (again) due
  ** to the limit of 32 bits in an integer bitmask.
  */
  loopMask = 0;
  pTabItem = pTabList->a;
  pLevel = pWInfo->a;


  for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++,pTabItem++,pLevel++){
    int j;
    int iCur = pTabItem->iCursor;            /* The cursor for this table */
    Bitmask mask = getMask(&maskSet, iCur);  /* Cursor mask for this table */
    Table *pTab = pTabItem->pTab;
    Index *pIdx;




    Index *pBestIdx = 0;
    int bestScore = 0;
    int bestRev = 0;

    /* Check to see if there is an expression that uses only the
    ** ROWID field of this table.  For terms of the form ROWID==expr
    ** set iDirectEq[i] to the index of the term.  For terms of the
    ** form ROWID<expr or ROWID<=expr set iDirectLt[i] to the term index.
    ** For terms like ROWID>expr or ROWID>=expr set iDirectGt[i].
    **
    ** (Added:) Treat ROWID IN expr like ROWID=expr.
    */
    pLevel->iIdxCur = -1;
    iDirectEq[i] = -1;
    iDirectLt[i] = -1;
    iDirectGt[i] = -1;
    for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
      Expr *pX = pTerm->p;
      if( pTerm->idxLeft==iCur && pX->pLeft->iColumn<0
            && (pTerm->prereqRight & loopMask)==pTerm->prereqRight ){
        switch( pX->op ){
          case TK_IN:
          case TK_EQ: iDirectEq[i] = j; break;
          case TK_LE:
          case TK_LT: iDirectLt[i] = j; break;
          case TK_GE:
          case TK_GT: iDirectGt[i] = j;  break;
        }
      }
    }

    /* If we found a term that tests ROWID with == or IN, that term
    ** will be used to locate the rows in the database table.  There
    ** is not need to continue into the code below that looks for
    ** an index.  We will always use the ROWID over an index.
    */
    if( iDirectEq[i]>=0 ){
      loopMask |= mask;
      pLevel->pIdx = 0;
      continue;
    }

    /* Do a search for usable indices.  Leave pBestIdx pointing to
    ** the "best" index.  pBestIdx is left set to NULL if no indices
    ** are usable.
    **
    ** The best index is the one with the highest score.  The score
    ** for the index is determined as follows.  For each of the
    ** left-most terms that is fixed by an equality operator, add
    ** 32 to the score.  The right-most term of the index may be
    ** constrained by an inequality.  Add 4 if for an "x<..." constraint
    ** and add 8 for an "x>..." constraint.  If both constraints
    ** are present, add 12.
    **
    ** If the left-most term of the index uses an IN operator
    ** (ex:  "x IN (...)")  then add 16 to the score.
    **
    ** If an index can be used for sorting, add 2 to the score.
    ** If an index contains all the terms of a table that are ever
    ** used by any expression in the SQL statement, then add 1 to
    ** the score.
    **
    ** This scoring system is designed so that the score can later be
    ** used to determine how the index is used.  If the score&0x1c is 0
    ** then all constraints are equalities.  If score&0x4 is not 0 then
    ** there is an inequality used as a termination key.  (ex: "x<...")
    ** If score&0x8 is not 0 then there is an inequality used as the
    ** start key.  (ex: "x>...").  A score or 0x10 is the special case
    ** of an IN operator constraint.  (ex:  "x IN ...").
    **
    ** The IN operator (as in "<expr> IN (...)") is treated the same as
    ** an equality comparison except that it can only be used on the
    ** left-most column of an index and other terms of the WHERE clause
    ** cannot be used in conjunction with the IN operator to help satisfy
    ** other columns of the index.
    */
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      Bitmask eqMask = 0;  /* Index columns covered by an x=... term */
      Bitmask ltMask = 0;  /* Index columns covered by an x<... term */
      Bitmask gtMask = 0;  /* Index columns covered by an x>... term */
      Bitmask inMask = 0;  /* Index columns covered by an x IN .. term */
      Bitmask m;
      int nEq, score, bRev = 0;




      if( pIdx->nColumn>sizeof(eqMask)*8 ){

        continue;  /* Ignore indices with too many columns to analyze */
      }
      for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
        Expr *pX = pTerm->p;
        CollSeq *pColl = sqlite3ExprCollSeq(pParse, pX->pLeft);
        if( !pColl && pX->pRight ){

          pColl = sqlite3ExprCollSeq(pParse, pX->pRight);
        }
        if( !pColl ){
          pColl = pParse->db->pDfltColl;
        }
        if( pTerm->idxLeft==iCur 
             && (pTerm->prereqRight & loopMask)==pTerm->prereqRight ){
          int iColumn = pX->pLeft->iColumn;
          int k;
          char idxaff = pIdx->pTable->aCol[iColumn].affinity; 
          for(k=0; k<pIdx->nColumn; k++){
            /* If the collating sequences or affinities don't match, 
            ** ignore this index.  */
            if( pColl!=pIdx->keyInfo.aColl[k] ) continue;
            if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;
            if( pIdx->aiColumn[k]==iColumn ){
              switch( pX->op ){
                case TK_IN: {
                  if( k==0 ) inMask |= 1;
                  break;
                }
                case TK_EQ: {
                  eqMask |= ((Bitmask)1)<<k;
                  break;
                }
                case TK_LE:

                case TK_LT: {
                  ltMask |= ((Bitmask)1)<<k;
                  break;
                }
                case TK_GE:
                case TK_GT: {
                  gtMask |= ((Bitmask)1)<<k;
                  break;
                }
                default: {
                  /* CANT_HAPPEN */
                  assert( 0 );
                  break;
                }
              }
              break;
            }
          }
        }
      }

      /* The following loop ends with nEq set to the number of columns
      ** on the left of the index with == constraints.
      */
      for(nEq=0; nEq<pIdx->nColumn; nEq++){
        m = (((Bitmask)1)<<(nEq+1))-1;
        if( (m & eqMask)!=m ) break;
      }

      /* Begin assemblying the score
      */
      score = nEq*32;   /* Base score is 32 times number of == constraints */
      m = ((Bitmask)1)<<nEq;
      if( m & ltMask ) score+=4;    /* Increase score for a < constraint */
      if( m & gtMask ) score+=8;    /* Increase score for a > constraint */
      if( score==0 && inMask ) score = 16; /* Default score for IN constraint */

      /* Give bonus points if this index can be used for sorting
      */
      if( i==0 && score!=16 && ppOrderBy && *ppOrderBy ){
        int base = pTabList->a[0].iCursor;
        if( isSortingIndex(pParse, pIdx, pTab, base, *ppOrderBy, nEq, &bRev) ){
          score += 2;
        }
      }

      /* Check to see if we can get away with using just the index without
      ** ever reading the table.  If that is the case, then add one bonus
      ** point to the score.
      */
      if( score && pTabItem->colUsed < (((Bitmask)1)<<(BMS-1)) ){
        for(m=0, j=0; j<pIdx->nColumn; j++){
          int x = pIdx->aiColumn[j];
          if( x<BMS-1 ){
            m |= ((Bitmask)1)<<x;
          }
        }
        if( (pTabItem->colUsed & m)==pTabItem->colUsed ){
          score++;
        }
      }

      /* If the score for this index is the best we have seen so far, then
      ** save it
      */
      if( score>bestScore ){
        pBestIdx = pIdx;
        bestScore = score;
        bestRev = bRev;
      }
    }
    pLevel->pIdx = pBestIdx;
    pLevel->score = bestScore;
    pLevel->bRev = bestRev;
    loopMask |= mask;
    if( pBestIdx ){
      pLevel->iIdxCur = pParse->nTab++;


    }


  }

  /* Check to see if the ORDER BY clause is or can be satisfied by the
  ** use of an index on the first table.
  */
  if( ppOrderBy && *ppOrderBy && pTabList->nSrc>0 ){
    Index *pIdx;             /* Index derived from the WHERE clause */
    Table *pTab;             /* Left-most table in the FROM clause */
    int bRev = 0;            /* True to reverse the output order */
    int iCur;                /* Btree-cursor that will be used by pTab */
    WhereLevel *pLevel0 = &pWInfo->a[0];

    pTab = pTabList->a[0].pTab;
    pIdx = pLevel0->pIdx;
    iCur = pTabList->a[0].iCursor;
    if( pIdx==0 && sortableByRowid(iCur, *ppOrderBy, &bRev) ){
      /* The ORDER BY clause specifies ROWID order, which is what we
      ** were going to be doing anyway...
      */
      *ppOrderBy = 0;
      pLevel0->bRev = bRev;
    }else if( pLevel0->score==16 ){
      /* If there is already an IN index on the left-most table,
      ** it will not give the correct sort order.
      ** So, pretend that no suitable index is found.
      */
    }else if( iDirectEq[0]>=0 || iDirectLt[0]>=0 || iDirectGt[0]>=0 ){
      /* If the left-most column is accessed using its ROWID, then do
      ** not try to sort by index.  But do delete the ORDER BY clause
      ** if it is redundant.
      */
    }else if( (pLevel0->score&2)!=0 ){
      /* The index that was selected for searching will cause rows to
      ** appear in sorted order.
      */
      *ppOrderBy = 0;
    }
  }

  /* Open all tables in the pTabList and any indices selected for
  ** searching those tables.
  */
  sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
  pLevel = pWInfo->a;
  for(i=0, pTabItem=pTabList->a; i<pTabList->nSrc; i++, pTabItem++, pLevel++){
    Table *pTab;
    Index *pIx;

    int iIdxCur = pLevel->iIdxCur;


















    pTab = pTabItem->pTab;

    if( pTab->isTransient || pTab->pSelect ) continue;
    if( (pLevel->score & 1)==0 ){
      sqlite3OpenTableForReading(v, pTabItem->iCursor, pTab);









    }
    pLevel->iTabCur = pTabItem->iCursor;
    if( (pIx = pLevel->pIdx)!=0 ){


      sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0);

      sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum,
                     (char*)&pIx->keyInfo, P3_KEYINFO);
    }
    if( (pLevel->score & 1)!=0 ){
      sqlite3VdbeAddOp(v, OP_KeyAsData, iIdxCur, 1);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
    }
    sqlite3CodeVerifySchema(pParse, pTab->iDb);
  }
  pWInfo->iTop = sqlite3VdbeCurrentAddr(v);

  /* Generate the code to do the search


  */
  loopMask = 0;
  pLevel = pWInfo->a;
  pTabItem = pTabList->a;
  for(i=0; i<pTabList->nSrc; i++, pTabItem++, pLevel++){
    int j, k;
    int iCur = pTabItem->iCursor;  /* The VDBE cursor for the table */
    Index *pIdx;       /* The index we will be using */
    int iIdxCur;       /* The VDBE cursor for the index */
    int omitTable;     /* True if we use the index only */




    pIdx = pLevel->pIdx;
    iIdxCur = pLevel->iIdxCur;
    pLevel->inOp = OP_Noop;





    /* Check to see if it is appropriate to omit the use of the table
    ** here and use its index instead.
    */
    omitTable = (pLevel->score&1)!=0;


    /* If this is the right table of a LEFT OUTER JOIN, allocate and
    ** initialize a memory cell that records if this table matches any
    ** row of the left table of the join.
    */
    if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){
      if( !pParse->nMem ) pParse->nMem++;
      pLevel->iLeftJoin = pParse->nMem++;
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
      VdbeComment((v, "# init LEFT JOIN no-match flag"));
    }

    if( i<ARRAYSIZE(iDirectEq) && (k = iDirectEq[i])>=0 ){
      /* Case 1:  We can directly reference a single row using an
      **          equality comparison against the ROWID field.  Or
      **          we reference multiple rows using a "rowid IN (...)"
      **          construct.
      */
      assert( k<nExpr );
      pTerm = &aExpr[k];
      assert( pTerm->p!=0 );
      assert( pTerm->idxLeft==iCur );

      assert( omitTable==0 );
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
      codeEqualityTerm(pParse, pTerm, brk, pLevel);
      cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp(v, OP_MustBeInt, 1, brk);
      sqlite3VdbeAddOp(v, OP_NotExists, iCur, brk);
      VdbeComment((v, "pk"));
      pLevel->op = OP_Noop;






































































































































    }else if( pIdx!=0 && pLevel->score>3 && (pLevel->score&0x0c)==0 ){



































































      /* Case 2:  There is an index and all terms of the WHERE clause that
      **          refer to the index using the "==" or "IN" operators.
      */
      int start;
      int nColumn = (pLevel->score+16)/32;
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);

      /* For each column of the index, find the term of the WHERE clause that
      ** constraints that column.  If the WHERE clause term is X=expr, then
      ** evaluation expr and leave the result on the stack */

      for(j=0; j<nColumn; j++){
        for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
          Expr *pX = pTerm->p;
          if( pX==0 ) continue;
          if( pTerm->idxLeft==iCur
             && (pTerm->prereqRight & loopMask)==pTerm->prereqRight 
             && pX->pLeft->iColumn==pIdx->aiColumn[j]
             && (pX->op==TK_EQ || pX->op==TK_IN)
          ){
            char idxaff = pIdx->pTable->aCol[pX->pLeft->iColumn].affinity;
            if( sqlite3IndexAffinityOk(pX, idxaff) ){
              codeEqualityTerm(pParse, pTerm, brk, pLevel);
              break;
            }

          }
        }
      }
      pLevel->iMem = pParse->nMem++;

      cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
      buildIndexProbe(v, nColumn, brk, pIdx);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);

      /* Generate code (1) to move to the first matching element of the table.
      ** Then generate code (2) that jumps to "brk" after the cursor is past
      ** the last matching element of the table.  The code (1) is executed
      ** once to initialize the search, the code (2) is executed before each
      ** iteration of the scan to see if the scan has finished. */
      if( pLevel->bRev ){
        /* Scan in reverse order */
        sqlite3VdbeAddOp(v, OP_MoveLe, iIdxCur, brk);
        start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, OP_IdxLT, iIdxCur, brk);
        pLevel->op = OP_Prev;
      }else{
        /* Scan in the forward order */
        sqlite3VdbeAddOp(v, OP_MoveGe, iIdxCur, brk);
        start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, brk, "+", P3_STATIC);
        pLevel->op = OP_Next;
      }
      sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
      sqlite3VdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
      if( !omitTable ){
        sqlite3VdbeAddOp(v, OP_IdxRecno, iIdxCur, 0);
        sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      }
      pLevel->p1 = iIdxCur;
      pLevel->p2 = start;
    }else if( i<ARRAYSIZE(iDirectLt) && (iDirectLt[i]>=0 || iDirectGt[i]>=0) ){
      /* Case 3:  We have an inequality comparison against the ROWID field.
      */
      int testOp = OP_Noop;
      int start;
      int bRev = pLevel->bRev;

      assert( omitTable==0 );
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
      cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
      if( bRev ){
        int t = iDirectGt[i];
        iDirectGt[i] = iDirectLt[i];
        iDirectLt[i] = t;
      }
      if( iDirectGt[i]>=0 ){
        Expr *pX;
        k = iDirectGt[i];
        assert( k<nExpr );
        pTerm = &aExpr[k];
        pX = pTerm->p;
        assert( pX!=0 );
        assert( pTerm->idxLeft==iCur );
        sqlite3ExprCode(pParse, pX->pRight);
        sqlite3VdbeAddOp(v, OP_ForceInt, pX->op==TK_LE || pX->op==TK_GT, brk);
        sqlite3VdbeAddOp(v, bRev ? OP_MoveLt : OP_MoveGe, iCur, brk);
        VdbeComment((v, "pk"));
        disableTerm(pLevel, &pTerm->p);
      }else{
        sqlite3VdbeAddOp(v, bRev ? OP_Last : OP_Rewind, iCur, brk);
      }
      if( iDirectLt[i]>=0 ){
        Expr *pX;
        k = iDirectLt[i];
        assert( k<nExpr );
        pTerm = &aExpr[k];
        pX = pTerm->p;
        assert( pX!=0 );
        assert( pTerm->idxLeft==iCur );
        sqlite3ExprCode(pParse, pX->pRight);
        pLevel->iMem = pParse->nMem++;
        sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
        if( pX->op==TK_LT || pX->op==TK_GT ){
          testOp = bRev ? OP_Le : OP_Ge;
        }else{
          testOp = bRev ? OP_Lt : OP_Gt;
        }
        disableTerm(pLevel, &pTerm->p);
      }
      start = sqlite3VdbeCurrentAddr(v);
      pLevel->op = bRev ? OP_Prev : OP_Next;
      pLevel->p1 = iCur;
      pLevel->p2 = start;
      if( testOp!=OP_Noop ){
        sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
        sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, testOp, 0, brk);
      }
    }else if( pIdx==0 ){
      /* Case 4:  There is no usable index.  We must do a complete
      **          scan of the entire database table.
      */
      int start;
      int opRewind;

      assert( omitTable==0 );
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);
      cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
      if( pLevel->bRev ){
        opRewind = OP_Last;
        pLevel->op = OP_Prev;
      }else{
        opRewind = OP_Rewind;
        pLevel->op = OP_Next;
      }
      sqlite3VdbeAddOp(v, opRewind, iCur, brk);
      start = sqlite3VdbeCurrentAddr(v);
      pLevel->p1 = iCur;
      pLevel->p2 = start;
    }else{
      /* Case 5: The WHERE clause term that refers to the right-most
      **         column of the index is an inequality.  For example, if
      **         the index is on (x,y,z) and the WHERE clause is of the
      **         form "x=5 AND y<10" then this case is used.  Only the
      **         right-most column can be an inequality - the rest must
      **         use the "==" operator.
      **
      **         This case is also used when there are no WHERE clause
      **         constraints but an index is selected anyway, in order
      **         to force the output order to conform to an ORDER BY.
      */
      int score = pLevel->score;
      int nEqColumn = score/32;
      int start;
      int leFlag=0, geFlag=0;
      int testOp;

      /* Evaluate the equality constraints
      */
      for(j=0; j<nEqColumn; j++){
        int iIdxCol = pIdx->aiColumn[j];
        for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
          Expr *pX = pTerm->p;
          if( pX==0 ) continue;
          if( pTerm->idxLeft==iCur
             && pX->op==TK_EQ
             && (pTerm->prereqRight & loopMask)==pTerm->prereqRight 
             && pX->pLeft->iColumn==iIdxCol
          ){
            sqlite3ExprCode(pParse, pX->pRight);
            disableTerm(pLevel, &pTerm->p);
            break;
          }
        }
      }

      /* Duplicate the equality term values because they will all be
      ** used twice: once to make the termination key and once to make the
      ** start key.
      */
      for(j=0; j<nEqColumn; j++){
        sqlite3VdbeAddOp(v, OP_Dup, nEqColumn-1, 0);
      }

      /* Labels for the beginning and end of the loop
      */
      cont = pLevel->cont = sqlite3VdbeMakeLabel(v);
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);

      /* Generate the termination key.  This is the key value that
      ** will end the search.  There is no termination key if there
      ** are no equality terms and no "X<..." term.
      **
      ** 2002-Dec-04: On a reverse-order scan, the so-called "termination"
      ** key computed here really ends up being the start key.
      */
      if( (score & 4)!=0 ){
        for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
          Expr *pX = pTerm->p;
          if( pX==0 ) continue;
          if( pTerm->idxLeft==iCur
             && (pX->op==TK_LT || pX->op==TK_LE)
             && (pTerm->prereqRight & loopMask)==pTerm->prereqRight 
             && pX->pLeft->iColumn==pIdx->aiColumn[j]
          ){
            sqlite3ExprCode(pParse, pX->pRight);
            leFlag = pX->op==TK_LE;
            disableTerm(pLevel, &pTerm->p);
            break;
          }
        }
        testOp = OP_IdxGE;
      }else{
        testOp = nEqColumn>0 ? OP_IdxGE : OP_Noop;
        leFlag = 1;
      }
      if( testOp!=OP_Noop ){
        int nCol = nEqColumn + ((score & 4)!=0);
        pLevel->iMem = pParse->nMem++;
        buildIndexProbe(v, nCol, brk, pIdx);
        if( pLevel->bRev ){
          int op = leFlag ? OP_MoveLe : OP_MoveLt;
          sqlite3VdbeAddOp(v, op, iIdxCur, brk);
        }else{
          sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
        }
      }else if( pLevel->bRev ){
        sqlite3VdbeAddOp(v, OP_Last, iIdxCur, brk);
      }

      /* Generate the start key.  This is the key that defines the lower
      ** bound on the search.  There is no start key if there are no
      ** equality terms and if there is no "X>..." term.  In
      ** that case, generate a "Rewind" instruction in place of the
      ** start key search.
      **
      ** 2002-Dec-04: In the case of a reverse-order search, the so-called
      ** "start" key really ends up being used as the termination key.
      */
      if( (score & 8)!=0 ){
        for(pTerm=aExpr, k=0; k<nExpr; k++, pTerm++){
          Expr *pX = pTerm->p;
          if( pX==0 ) continue;
          if( pTerm->idxLeft==iCur
             && (pX->op==TK_GT || pX->op==TK_GE)
             && (pTerm->prereqRight & loopMask)==pTerm->prereqRight 
             && pX->pLeft->iColumn==pIdx->aiColumn[j]
          ){
            sqlite3ExprCode(pParse, pX->pRight);
            geFlag = pX->op==TK_GE;
            disableTerm(pLevel, &pTerm->p);
            break;
          }
        }
      }else{
        geFlag = 1;
      }
      if( nEqColumn>0 || (score&8)!=0 ){
        int nCol = nEqColumn + ((score&8)!=0);
        buildIndexProbe(v, nCol, brk, pIdx);
        if( pLevel->bRev ){
          pLevel->iMem = pParse->nMem++;
          sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
          testOp = OP_IdxLT;
        }else{
          int op = geFlag ? OP_MoveGe : OP_MoveGt;
          sqlite3VdbeAddOp(v, op, iIdxCur, brk);
        }
      }else if( pLevel->bRev ){
        testOp = OP_Noop;
      }else{
        sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, brk);
      }

      /* Generate the the top of the loop.  If there is a termination
      ** key we have to test for that key and abort at the top of the
      ** loop.
      */
      start = sqlite3VdbeCurrentAddr(v);
      if( testOp!=OP_Noop ){
        sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, testOp, iIdxCur, brk);
        if( (leFlag && !pLevel->bRev) || (!geFlag && pLevel->bRev) ){
          sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
        }
      }
      sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
      sqlite3VdbeAddOp(v, OP_IdxIsNull, nEqColumn + ((score&4)!=0), cont);
      if( !omitTable ){
        sqlite3VdbeAddOp(v, OP_IdxRecno, iIdxCur, 0);
        sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
      }

      /* Record the instruction used to terminate the loop.
      */


      pLevel->op = pLevel->bRev ? OP_Prev : OP_Next;
      pLevel->p1 = iIdxCur;
      pLevel->p2 = start;
    }
    loopMask |= getMask(&maskSet, iCur);

    /* Insert code to test every subexpression that can be completely
    ** computed using the current set of tables.
    */
    for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){

      if( pTerm->p==0 ) continue;
      if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue;


      if( pLevel->iLeftJoin && !ExprHasProperty(pTerm->p,EP_FromJoin) ){
        continue;
      }
      sqlite3ExprIfFalse(pParse, pTerm->p, cont, 1);
      pTerm->p = 0;
    }
    brk = cont;

    /* For a LEFT OUTER JOIN, generate code that will record the fact that
    ** at least one row of the right table has matched the left table.  
    */
    if( pLevel->iLeftJoin ){
      pLevel->top = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp(v, OP_Integer, 1, 0);
      sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
      VdbeComment((v, "# record LEFT JOIN hit"));
      for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){
        if( pTerm->p==0 ) continue;
        if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue;

        sqlite3ExprIfFalse(pParse, pTerm->p, cont, 1);
        pTerm->p = 0;
      }
    }
  }



















































  pWInfo->iContinue = cont;


  freeMaskSet(&maskSet);




  return pWInfo;
}

/*
** Generate the end of the WHERE loop.  See comments on 
** sqlite3WhereBegin() for additional information.
*/
void sqlite3WhereEnd(WhereInfo *pWInfo){
  Vdbe *v = pWInfo->pParse->pVdbe;
  int i;
  WhereLevel *pLevel;
  SrcList *pTabList = pWInfo->pTabList;
  struct SrcList_item *pTabItem;

  /* Generate loop termination code.
  */
  for(i=pTabList->nSrc-1; i>=0; i--){
    pLevel = &pWInfo->a[i];
    sqlite3VdbeResolveLabel(v, pLevel->cont);
    if( pLevel->op!=OP_Noop ){
      sqlite3VdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
    }
    sqlite3VdbeResolveLabel(v, pLevel->brk);
    if( pLevel->inOp!=OP_Noop ){



      sqlite3VdbeAddOp(v, pLevel->inOp, pLevel->inP1, pLevel->inP2);


    }
    if( pLevel->iLeftJoin ){
      int addr;
      addr = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0);
      sqlite3VdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iIdxCur>=0));
      sqlite3VdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
      if( pLevel->iIdxCur>=0 ){
        sqlite3VdbeAddOp(v, OP_NullRow, pLevel->iIdxCur, 0);
      }
      sqlite3VdbeAddOp(v, OP_Goto, 0, pLevel->top);

    }
  }

  /* The "break" point is here, just past the end of the outer loop.
  ** Set it.
  */
  sqlite3VdbeResolveLabel(v, pWInfo->iBreak);

  /* Close all of the cursors that were opend by sqlite3WhereBegin.
  */
  pLevel = pWInfo->a;
  pTabItem = pTabList->a;
  for(i=0; i<pTabList->nSrc; i++, pTabItem++, pLevel++){
    Table *pTab = pTabItem->pTab;
    assert( pTab!=0 );
    if( pTab->isTransient || pTab->pSelect ) continue;
    if( (pLevel->score & 1)==0 ){
      sqlite3VdbeAddOp(v, OP_Close, pTabItem->iCursor, 0);
    }
    if( pLevel->pIdx!=0 ){
      sqlite3VdbeAddOp(v, OP_Close, pLevel->iIdxCur, 0);
    }

    /* Make cursor substitutions for cases where we want to use
    ** just the index and never reference the table.
    ** 
    ** Calls to the code generator in between sqlite3WhereBegin and
    ** sqlite3WhereEnd will have created code that references the table
    ** directly.  This loop scans all that code looking for opcodes
    ** that reference the table and converts them into opcodes that
    ** reference the index.
    */
    if( pLevel->score & 1 ){
      int i, j, last;
      VdbeOp *pOp;
      Index *pIdx = pLevel->pIdx;

      assert( pIdx!=0 );
      pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
      last = sqlite3VdbeCurrentAddr(v);
      for(i=pWInfo->iTop; i<last; i++, pOp++){
        if( pOp->p1!=pLevel->iTabCur ) continue;
        if( pOp->opcode==OP_Column ){
          pOp->p1 = pLevel->iIdxCur;
          for(j=0; j<pIdx->nColumn; j++){
            if( pOp->p2==pIdx->aiColumn[j] ){
              pOp->p2 = j;
              break;
            }
          }
        }else if( pOp->opcode==OP_Recno ){
          pOp->p1 = pLevel->iIdxCur;
          pOp->opcode = OP_IdxRecno;
        }else if( pOp->opcode==OP_NullRow ){
          pOp->opcode = OP_Noop;
        }
      }
    }
  }

  /* Final cleanup
  */
  sqliteFree(pWInfo);
  return;
}
Changes to SQLite.NET.sln.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite - Compact", "System.Data.SQLite\System.Data.SQLite - Compact.csproj", "{AC139951-261A-4463-B6FA-AEBC25283A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}"
	ProjectSection(ProjectDependencies) = postProject
		{10B51CE8-A838-44DE-BD82-B658F0296F80} = {10B51CE8-A838-44DE-BD82-B658F0296F80}
		{AC139952-261A-4463-B6FA-AEBC25283A66} = {AC139952-261A-4463-B6FA-AEBC25283A66}
		{AC139951-261A-4463-B6FA-AEBC25283A66} = {AC139951-261A-4463-B6FA-AEBC25283A66}
	EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{39A3B743-1EBD-4CC0-8E37-ACE3DD38B1C0}"
	ProjectSection(SolutionItems) = preProject
		readme.htm = readme.htm
	EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop", "SQLite.Interop\SQLite.Interop.vcproj", "{10B51CE8-A838-44DE-BD82-B658F0296F80}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139951-261A-4463-B6FA-AEBC25283A66} = {AC139951-261A-4463-B6FA-AEBC25283A66}
		{AC139952-261A-4463-B6FA-AEBC25283A66} = {AC139952-261A-4463-B6FA-AEBC25283A66}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testce", "testce\testce.csproj", "{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}"
	ProjectSection(ProjectDependencies) = postProject
		{AC139951-261A-4463-B6FA-AEBC25283A66} = {AC139951-261A-4463-B6FA-AEBC25283A66}
		{10B51CE8-A838-44DE-BD82-B658F0296F80} = {10B51CE8-A838-44DE-BD82-B658F0296F80}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite.Designer", "SQLite.Designer\SQLite.Designer.csproj", "{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite - Full", "System.Data.SQLite\System.Data.SQLite - Full.csproj", "{AC139952-261A-4463-B6FA-AEBC25283A66}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Compact Framework = Debug|Compact Framework
		Debug|Itanium = Debug|Itanium
		Debug|Mixed Platforms = Debug|Mixed Platforms
		Debug|Win32 = Debug|Win32
		Debug|x64 = Debug|x64
		Release|Compact Framework = Release|Compact Framework
		Release|Itanium = Release|Itanium
		Release|Mixed Platforms = Release|Mixed Platforms
		Release|Win32 = Release|Win32
		Release|x64 = Release|x64
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Compact Framework.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Compact Framework.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Compact Framework.Deploy.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Itanium.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Compact Framework.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Compact Framework.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Itanium.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Compact Framework.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Itanium.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Itanium.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|x64.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Compact Framework.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Itanium.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Itanium.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|x64.Build.0 = Release|Any CPU
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Compact Framework.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Compact Framework.Build.0 = Debug|Pocket PC 2003 (ARMV4)
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Compact Framework.Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Itanium.ActiveCfg = Debug|Itanium
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Itanium.Build.0 = Debug|Itanium
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Itanium.Deploy.0 = Debug|Itanium
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Mixed Platforms.ActiveCfg = Debug|x64
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Mixed Platforms.Build.0 = Debug|x64
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Win32.ActiveCfg = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Win32.Build.0 = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Win32.Deploy.0 = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|x64.ActiveCfg = Debug|x64
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|x64.Build.0 = Debug|x64
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|x64.Deploy.0 = Debug|x64
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Compact Framework.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Compact Framework.Build.0 = Release|Pocket PC 2003 (ARMV4)
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Compact Framework.Deploy.0 = Release|Pocket PC 2003 (ARMV4)
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Itanium.ActiveCfg = Release|Itanium
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Itanium.Build.0 = Release|Itanium
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Mixed Platforms.ActiveCfg = Release|x64
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Mixed Platforms.Build.0 = Release|x64
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Win32.ActiveCfg = Release|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Win32.Build.0 = Release|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|x64.ActiveCfg = Release|x64
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|x64.Build.0 = Release|x64
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Compact Framework.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Compact Framework.Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Compact Framework.Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Itanium.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|x64.ActiveCfg = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Debug|x64.Deploy.0 = Debug|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Compact Framework.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Compact Framework.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Compact Framework.Deploy.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Itanium.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|Win32.ActiveCfg = Release|Any CPU
		{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}.Release|x64.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Compact Framework.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Compact Framework.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Itanium.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Itanium.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|Win32.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|x64.ActiveCfg = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Debug|x64.Build.0 = Debug|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Compact Framework.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Compact Framework.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Itanium.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Itanium.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Win32.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|Win32.Build.0 = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|x64.ActiveCfg = Release|Any CPU
		{9B4A5CF6-5BE5-4926-ACC7-B729A8C05198}.Release|x64.Build.0 = Release|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Compact Framework.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Itanium.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Itanium.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Debug|x64.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Compact Framework.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Itanium.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Debug|Any CPU
		{AC139952-261A-4463-B6FA-AEBC25283A66}.Release|x64.ActiveCfg = Debug|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal



|


<
<
<
<
<


|




<
<
<
<
<
<
<
<
<
<
<
<
<
<



<
|


<
<
|


<


<
|
<
|


<

<
<
|
|


<

<
<
|
|



<
<
<
<
|
|



<
<
<
<
<
<
<
|
<
|
|


<
<
<
<
<
<
<
<
|
|
|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





1
2
3
4
5
6





7
8
9
10
11
12
13














14
15
16

17
18
19


20
21
22

23
24

25

26
27
28

29


30
31
32
33

34


35
36
37
38
39




40
41
42
43
44







45

46
47
48
49








50
51
52
53
54
























































55
56
57
58
59

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Data.SQLite", "System.Data.SQLite\System.Data.SQLite.csproj", "{AC139951-261A-4463-B6FA-AEBC25283A66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}"





EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{39A3B743-1EBD-4CC0-8E37-ACE3DD38B1C0}"
	ProjectSection(SolutionItems) = postProject
		readme.htm = readme.htm
	EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SQLite.Interop", "SQLite.Interop\SQLite.Interop.vcproj", "{10B51CE8-A838-44DE-BD82-B658F0296F80}"














EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution

		Debug|Any CPU = Debug|Any CPU
		Debug|Mixed Platforms = Debug|Mixed Platforms
		Debug|Win32 = Debug|Win32


		Release|Any CPU = Release|Any CPU
		Release|Mixed Platforms = Release|Mixed Platforms
		Release|Win32 = Release|Win32

	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution

		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU

		{AC139951-261A-4463-B6FA-AEBC25283A66}.Debug|Win32.ActiveCfg = Debug|Any CPU


		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Any CPU.Build.0 = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Mixed Platforms.Build.0 = Release|Any CPU

		{AC139951-261A-4463-B6FA-AEBC25283A66}.Release|Win32.ActiveCfg = Release|Any CPU


		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Debug|Win32.ActiveCfg = Debug|Any CPU




		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Any CPU.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Mixed Platforms.Build.0 = Release|Any CPU
		{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}.Release|Win32.ActiveCfg = Release|Any CPU







		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Any CPU.ActiveCfg = Debug|Win32

		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Mixed Platforms.Build.0 = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Win32.ActiveCfg = Debug|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Debug|Win32.Build.0 = Debug|Win32








		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Any CPU.ActiveCfg = Release|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Mixed Platforms.ActiveCfg = Release|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Mixed Platforms.Build.0 = Release|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Win32.ActiveCfg = Release|Win32
		{10B51CE8-A838-44DE-BD82-B658F0296F80}.Release|Win32.Build.0 = Release|Win32
























































	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
Deleted SQLite.NET.suo.

cannot compute difference between binary files

Changes to System.Data.SQLite/AssemblyInfo.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

#if !PLATFORM_COMPACTFRAMEWORK
using System.Runtime.ConstrainedExecution;
#endif

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("System.Data.SQLite")]
[assembly: AssemblyDescription("ADO.NET 2.0 Data Provider for SQLite")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("http://sourceforge.net/projects/sqlite-dotnet2")]
[assembly: AssemblyProduct("System.Data.SQLite")]
[assembly: AssemblyCopyright("Public Domain")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

//  Setting ComVisible to false makes the types in this assembly not visible 
//  to COM componenets.  If you need to access a type in this assembly from 
//  COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

[assembly: CLSCompliant(true)]

#if !PLATFORM_COMPACTFRAMEWORK
[assembly: ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#endif

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.24.5")]
#if !PLATFORM_COMPACTFRAMEWORK
[assembly: AssemblyFileVersion("1.0.24.5")]
#endif
<




<
<
<
<






|










<
<
<
<
<
<









|
<
<
<

1
2
3
4




5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21






22
23
24
25
26
27
28
29
30
31




using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;





// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("System.Data.SQLite")]
[assembly: AssemblyDescription("ADO.NET 2.0 Data Provider for SQLite")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("System.Data.SQLite")]
[assembly: AssemblyCopyright("Public Domain")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

//  Setting ComVisible to false makes the types in this assembly not visible 
//  to COM componenets.  If you need to access a type in this assembly from 
//  COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]







// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.6.*")]



Deleted System.Data.SQLite/DataTypes.xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<?xml version="1.0" standalone="yes"?>
<DocumentElement>
  <DataTypes>
    <TypeName>System.Int16</TypeName>
    <ProviderDbType>10</ProviderDbType>
    <ColumnSize>5</ColumnSize>
    <DataType>System.Int16</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
  </DataTypes>
  <DataTypes>
    <TypeName>System.Int32</TypeName>
    <ProviderDbType>8</ProviderDbType>
    <ColumnSize>10</ColumnSize>
    <DataType>System.Int32</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
  </DataTypes>
  <DataTypes>
    <TypeName>System.Single</TypeName>
    <ProviderDbType>15</ProviderDbType>
    <ColumnSize>7</ColumnSize>
    <DataType>System.Single</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
  </DataTypes>
  <DataTypes>
    <TypeName>System.Double</TypeName>
    <ProviderDbType>8</ProviderDbType>
    <ColumnSize>6</ColumnSize>
    <DataType>System.Double</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
  </DataTypes>
  <DataTypes>
    <TypeName>System.Decimal</TypeName>
    <ProviderDbType>7</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Decimal</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
  </DataTypes>
  <DataTypes>
    <TypeName>System.Boolean</TypeName>
    <ProviderDbType>3</ProviderDbType>
    <ColumnSize>1</ColumnSize>
    <DataType>System.Boolean</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
  </DataTypes>
  <DataTypes>
    <TypeName>System.Byte</TypeName>
    <ProviderDbType>2</ProviderDbType>
    <ColumnSize>3</ColumnSize>
    <DataType>System.Byte</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>true</IsUnsigned>
  </DataTypes>
  <DataTypes>
    <TypeName>System.Int64</TypeName>
    <ProviderDbType>12</ProviderDbType>
    <ColumnSize>19</ColumnSize>
    <DataType>System.Int64</DataType>
    <IsAutoIncrementable>true</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>true</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <IsUnsigned>false</IsUnsigned>
  </DataTypes>
  <DataTypes>
    <TypeName>System.Byte[]</TypeName>
    <ProviderDbType>1</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <DataType>System.Byte[]</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>true</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>false</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <LiteralPrefix>X'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
  </DataTypes>
  <DataTypes>
    <TypeName>System.String</TypeName>
    <ProviderDbType>16</ProviderDbType>
    <ColumnSize>2147483647</ColumnSize>
    <CreateParameters>max length</CreateParameters>
    <DataType>System.String</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>false</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
  </DataTypes>
  <DataTypes>
    <TypeName>System.DateTime</TypeName>
    <ProviderDbType>6</ProviderDbType>
    <ColumnSize>23</ColumnSize>
    <DataType>System.DateTime</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>true</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
  </DataTypes>
  <DataTypes>
    <TypeName>System.Guid</TypeName>
    <ProviderDbType>4</ProviderDbType>
    <ColumnSize>16</ColumnSize>
    <DataType>System.Guid</DataType>
    <IsAutoIncrementable>false</IsAutoIncrementable>
    <IsCaseSensitive>false</IsCaseSensitive>
    <IsFixedLength>true</IsFixedLength>
    <IsFixedPrecisionScale>false</IsFixedPrecisionScale>
    <IsLong>false</IsLong>
    <IsNullable>true</IsNullable>
    <IsSearchable>true</IsSearchable>
    <IsSearchableWithLike>false</IsSearchableWithLike>
    <LiteralPrefix>'</LiteralPrefix>
    <LiteralSuffix>'</LiteralSuffix>
  </DataTypes>
</DocumentElement>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































Deleted System.Data.SQLite/MetaDataCollections.xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?xml version="1.0" encoding="utf-8" ?>
<DocumentElement>
  <MetaDataCollections>
    <CollectionName>MetaDataCollections</CollectionName>
    <NumberOfRestrictions>0</NumberOfRestrictions>
    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>DataSourceInformation</CollectionName>
    <NumberOfRestrictions>0</NumberOfRestrictions>
    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>DataTypes</CollectionName>
    <NumberOfRestrictions>0</NumberOfRestrictions>
    <NumberOfIdentifierParts>0</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Catalogs</CollectionName>
    <NumberOfRestrictions>1</NumberOfRestrictions>
    <NumberOfIdentifierParts>1</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Columns</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Indexes</CollectionName>
    <NumberOfRestrictions>5</NumberOfRestrictions>
    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>IndexColumns</CollectionName>
    <NumberOfRestrictions>5</NumberOfRestrictions>
    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Tables</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>Views</CollectionName>
    <NumberOfRestrictions>3</NumberOfRestrictions>
    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>ViewColumns</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIdentifierParts>4</NumberOfIdentifierParts>
  </MetaDataCollections>
  <MetaDataCollections>
    <CollectionName>ForeignKeys</CollectionName>
    <NumberOfRestrictions>4</NumberOfRestrictions>
    <NumberOfIdentifierParts>3</NumberOfIdentifierParts>
  </MetaDataCollections>
</DocumentElement>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































Changes to System.Data.SQLite/SQLite3.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Runtime.InteropServices;
  using System.Collections.Generic;
  using System.Globalization;

  /// <summary>
  /// This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET
  /// </summary>
  internal class SQLite3 : SQLiteBase
  {
    /// <summary>
    /// The opaque pointer returned to us by the sqlite provider
    /// </summary>
    protected int              _sql;

    /// <summary>
    /// The user-defined functions registered on this connection
    /// </summary>
    protected SQLiteFunction[] _functionsArray;

    internal SQLite3(SQLiteDateFormats fmt)
      : base(fmt)
    {


    }

    protected override void Dispose(bool bDisposing)
    {
      Close();
    }

    internal override void Close()
    {
      if (_sql != 0)
      {
        int n = UnsafeNativeMethods.sqlite3_close_interop(_sql);
        if (n > 0) throw new SQLiteException(n, SQLiteLastError());
        SQLiteFunction.UnbindFunctions(this, _functionsArray);
      }
      _sql = 0;
    }

    internal override void Cancel()
    {
      UnsafeNativeMethods.sqlite3_interrupt_interop(_sql);
    }

    internal override string Version
    {
      get
      {
        int len;
        return ToString(UnsafeNativeMethods.sqlite3_libversion_interop(out len), len);
      }












<










>





|


>
>


















<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51





52
53
54
55
56
57
58
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Runtime.InteropServices;
  using System.Collections.Generic;


  /// <summary>
  /// This class implements SQLiteBase completely, and is the guts of the code that interop's SQLite with .NET
  /// </summary>
  internal class SQLite3 : SQLiteBase
  {
    /// <summary>
    /// The opaque pointer returned to us by the sqlite provider
    /// </summary>
    protected int              _sql;

    /// <summary>
    /// The user-defined functions registered on this connection
    /// </summary>
    protected SQLiteFunction[] _functionsArray;

    internal SQLite3(DateTimeFormat fmt)
      : base(fmt)
    {
      _sql = 0;
      _functionsArray = null;
    }

    protected override void Dispose(bool bDisposing)
    {
      Close();
    }

    internal override void Close()
    {
      if (_sql != 0)
      {
        int n = UnsafeNativeMethods.sqlite3_close_interop(_sql);
        if (n > 0) throw new SQLiteException(n, SQLiteLastError());
        SQLiteFunction.UnbindFunctions(this, _functionsArray);
      }
      _sql = 0;
    }






    internal override string Version
    {
      get
      {
        int len;
        return ToString(UnsafeNativeMethods.sqlite3_libversion_interop(out len), len);
      }
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
      }
      if (n > 0) throw new SQLiteException(n, str);
    }

    internal override bool Step(SQLiteStatement stmt)
    {
      int n;
      long dwtick = 0;
      Random rnd = null;

      while (true)
      {
        n = UnsafeNativeMethods.sqlite3_step_interop(stmt._sqlite_stmt);

        if (n == 100) return true;
        if (n == 101) return false;

        if (n > 0)
        {
          int r;

          // An error occurred, attempt to reset the statement.  If the reset worked because the
          // schema has changed, re-try the step again.  If it errored our because the database
          // is locked, then keep retrying until the command timeout occurs.
          r = Reset(stmt);

          if (r == 0)
            throw new SQLiteException(n, SQLiteLastError());

          else if (r == 6 && stmt._command != null) // SQLITE_LOCKED
          {
            // Keep trying
            if (dwtick == 0) // First time we've encountered the lock
            {
              dwtick = DateTime.Now.Ticks + (stmt._command._commandTimeout * 10000000);
              rnd = new Random();
            }
            // If we've exceeded the command's timeout, give up and throw an error
            if (DateTime.Now.Ticks - dwtick > 0)
            {
              throw new SQLiteException(r, SQLiteLastError());
            }
            else
            {
              // Otherwise sleep for a random amount of time up to 250ms
              UnsafeNativeMethods.sqlite3_sleep_interop((uint)rnd.Next(1, 250));
            }
          }

        }
      }
    }

    internal override void FinalizeStatement(SQLiteStatement stmt)
    {
      if (stmt._sqlite_stmt > 0)
      {
        int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt._sqlite_stmt);
        if (n > 0) throw new SQLiteException(n, SQLiteLastError());
      }
      stmt._sqlite_stmt = 0;
    }

    internal override int Reset(SQLiteStatement stmt)
    {
      int n;

      n = UnsafeNativeMethods.sqlite3_reset_interop(stmt._sqlite_stmt);

      // If the schema changed, try and re-prepare it
      if (n == 17) // SQLITE_SCHEMA
      {
        // Recreate a dummy statement

        string str;
        using (SQLiteStatement tmp = Prepare(stmt._sqlStatement, null, out str))
        {
          // Finalize the existing statement
          FinalizeStatement(stmt);

          // Reassign a new statement pointer to the old statement and clear the temporary one
          stmt._sqlite_stmt = tmp._sqlite_stmt;
          tmp._sqlite_stmt = 0;

          // Reapply parameters
          stmt.BindParameters();
        }
        return -1; // Reset was OK, with schema change
      }
      else if (n == 6) // SQLITE_LOCKED
        return n;

      if (n > 0)
        throw new SQLiteException(n, SQLiteLastError());

      return 0; // We reset OK, no schema changes
    }

    internal override string SQLiteLastError()
    {
      int len;
      return ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(_sql, out len), len);
    }

    internal override SQLiteStatement Prepare(string strSql, SQLiteStatement previous, out string strRemain)
    {
      int stmt;
      IntPtr ptr;
      int len;

      byte[] b = ToUTF8(strSql);

      int n = UnsafeNativeMethods.sqlite3_prepare_interop(_sql, b, b.Length - 1, out stmt, out ptr, out len);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      strRemain = ToString(ptr, len);

      SQLiteStatement cmd = null;
      if (stmt > 0) cmd = new SQLiteStatement(this, stmt, strSql.Substring(0, strSql.Length - strRemain.Length), previous);

      return cmd;
    }

    internal override void Bind_Double(SQLiteStatement stmt, int index, double value)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_double_interop(stmt._sqlite_stmt, index, ref value);







<
<










<
<

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

<
<
<
<
|









|

<
<
|





>

|


|








|

<
<




|








|












<
|







95
96
97
98
99
100
101


102
103
104
105
106
107
108
109
110
111


112
113




114
115









116

117
118




119
120
121




122
123
124
125
126
127
128
129
130
131
132
133


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155


156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
      }
      if (n > 0) throw new SQLiteException(n, str);
    }

    internal override bool Step(SQLiteStatement stmt)
    {
      int n;



      while (true)
      {
        n = UnsafeNativeMethods.sqlite3_step_interop(stmt._sqlite_stmt);

        if (n == 100) return true;
        if (n == 101) return false;

        if (n > 0)
        {


          // An error occurred, attempt to reset the statement.  If the reset worked because the
          // schema has changed, re-try the step again.  Otherwise throw the original error.




          string str = SQLiteLastError();
          









          if (Reset(stmt) == false)

            throw new SQLiteException(n, str);
        }




      }
    }





    internal override void Finalize(SQLiteStatement stmt)
    {
      if (stmt._sqlite_stmt > 0)
      {
        int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt._sqlite_stmt);
        if (n > 0) throw new SQLiteException(n, SQLiteLastError());
      }
      stmt._sqlite_stmt = 0;
    }

    internal override bool Reset(SQLiteStatement stmt)
    {


      int n = UnsafeNativeMethods.sqlite3_reset_interop(stmt._sqlite_stmt);

      // If the schema changed, try and re-prepare it
      if (n == 17) // SQLITE_SCHEMA
      {
        // Recreate a dummy statement
        int nc = 0;
        string str;
        using (SQLiteStatement tmp = Prepare(stmt._sqlStatement, ref nc, out str))
        {
          // Finalize the existing statement
          Finalize(stmt);

          // Reassign a new statement pointer to the old statement and clear the temporary one
          stmt._sqlite_stmt = tmp._sqlite_stmt;
          tmp._sqlite_stmt = 0;

          // Reapply parameters
          stmt.BindParameters();
        }
        return true; // Reset was OK, with schema change
      }



      if (n > 0)
        throw new SQLiteException(n, SQLiteLastError());

      return false; // We reset OK, no schema changes
    }

    internal override string SQLiteLastError()
    {
      int len;
      return ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(_sql, out len), len);
    }

    internal override SQLiteStatement Prepare(string strSql, ref int nParamStart, out string strRemain)
    {
      int stmt;
      IntPtr ptr;
      int len;

      byte[] b = ToUTF8(strSql);

      int n = UnsafeNativeMethods.sqlite3_prepare_interop(_sql, b, b.Length - 1, out stmt, out ptr, out len);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      strRemain = ToString(ptr, len);


      SQLiteStatement cmd = new SQLiteStatement(this, stmt, strSql.Substring(0, strSql.Length - strRemain.Length), ref nParamStart);

      return cmd;
    }

    internal override void Bind_Double(SQLiteStatement stmt, int index, double value)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_double_interop(stmt._sqlite_stmt, index, ref value);
286
287
288
289
290
291
292


293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
    {
      int len;
      return ToString(UnsafeNativeMethods.sqlite3_column_name_interop(stmt._sqlite_stmt, index, out len), len);
    }

    internal override string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity)
    {


      int len;
      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype_interop(stmt._sqlite_stmt, index, out len);
      nAffinity = UnsafeNativeMethods.sqlite3_column_type_interop(stmt._sqlite_stmt, index);
      if (p != IntPtr.Zero) return ToString(p, len);
      else
      {

        switch (nAffinity)
        {
          case TypeAffinity.Int64:
            return "BIGINT";
          case TypeAffinity.Double:
            return "DOUBLE";
          case TypeAffinity.Blob:
            return "BLOB";
          default:
            return "TEXT";
        }
      }
    }

    internal override int ColumnIndex(SQLiteStatement stmt, string columnName)
    {
      int x = ColumnCount(stmt);

      for (int n = 0; n < x; n++)
      {
        if (String.Compare(columnName, ColumnName(stmt, n), true, CultureInfo.InvariantCulture) == 0)
          return n;
      }
      return -1;
    }

    internal override double GetDouble(SQLiteStatement stmt, int index)
    {
      double value;







>
>


<



>
















<
<
|

|
<







253
254
255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283


284
285
286

287
288
289
290
291
292
293
    {
      int len;
      return ToString(UnsafeNativeMethods.sqlite3_column_name_interop(stmt._sqlite_stmt, index, out len), len);
    }

    internal override string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity)
    {
      nAffinity = TypeAffinity.None;

      int len;
      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype_interop(stmt._sqlite_stmt, index, out len);

      if (p != IntPtr.Zero) return ToString(p, len);
      else
      {
        nAffinity = UnsafeNativeMethods.sqlite3_column_type_interop(stmt._sqlite_stmt, index);
        switch (nAffinity)
        {
          case TypeAffinity.Int64:
            return "BIGINT";
          case TypeAffinity.Double:
            return "DOUBLE";
          case TypeAffinity.Blob:
            return "BLOB";
          default:
            return "TEXT";
        }
      }
    }

    internal override int ColumnIndex(SQLiteStatement stmt, string columnName)
    {


      for (int n = 0; n < ColumnCount(stmt); n++)
      {
        if (String.Compare(columnName, ColumnName(stmt, n), true) == 0) return n;

      }
      return -1;
    }

    internal override double GetDouble(SQLiteStatement stmt, int index)
    {
      double value;
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
      return UnsafeNativeMethods.sqlite3_aggregate_context_interop(context, 1);
    }

    internal override void SetRealColNames(bool bOn)
    {
      UnsafeNativeMethods.sqlite3_realcolnames(_sql, Convert.ToInt32(bOn));
    }

    internal override void SetPassword(byte[] passwordBytes)
    {
      int n = UnsafeNativeMethods.sqlite3_key_interop(_sql, passwordBytes, passwordBytes.Length);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override void ChangePassword(byte[] newPasswordBytes)
    {
      int n = UnsafeNativeMethods.sqlite3_rekey_interop(_sql, newPasswordBytes, (newPasswordBytes == null) ? 0 : newPasswordBytes.Length);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }
  }
}







|
<
<
<
<
|
<
<
<
<
<
<
<
<
486
487
488
489
490
491
492
493




494








      return UnsafeNativeMethods.sqlite3_aggregate_context_interop(context, 1);
    }

    internal override void SetRealColNames(bool bOn)
    {
      UnsafeNativeMethods.sqlite3_realcolnames(_sql, Convert.ToInt32(bOn));
    }
  }




}








Changes to System.Data.SQLite/SQLite3_UTF16.cs.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34





35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116

117
118
119
120
121
122
123
  using System.Runtime.InteropServices;

  /// <summary>
  /// Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode)
  /// </summary>
  internal class SQLite3_UTF16 : SQLite3
  {
    internal SQLite3_UTF16(SQLiteDateFormats fmt)
      : base(fmt)
    {
    }

    /// <summary>
    /// Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8
    /// </summary>
    /// <param name="b">A pointer to a UTF-16 string</param>
    /// <param name="nbytelen">The length (IN BYTES) of the string</param>
    /// <returns>A .NET string</returns>
    public override string ToString(IntPtr b, int nbytelen)
    {
      if (nbytelen == 0) return "";
      return Marshal.PtrToStringUni(b, nbytelen / 2);
    }






    internal override string Version
    {
      get
      {
        int len;
        return base.ToString(UnsafeNativeMethods.sqlite3_libversion_interop(out len), len);
      }
    }

    internal override void Open(string strFilename)
    {
      if (_sql != 0) return;
      int n = UnsafeNativeMethods.sqlite3_open16_interop(strFilename, out _sql);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      _functionsArray = SQLiteFunction.BindFunctions(this);
    }

    internal override string SQLiteLastError()
    {
      int len;
      return ToString(UnsafeNativeMethods.sqlite3_errmsg16_interop(_sql, out len), len);
    }

    internal override SQLiteStatement Prepare(string strSql, SQLiteStatement previous, out string strRemain)
    {
      int stmt;
      IntPtr ptr;
      int len;

      int n = UnsafeNativeMethods.sqlite3_prepare16_interop(_sql, strSql, strSql.Length, out stmt, out ptr, out len);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      strRemain = ToString(ptr, len);

      SQLiteStatement cmd = new SQLiteStatement(this, stmt, strSql.Substring(0, strSql.Length - strRemain.Length), previous);

      return cmd;
    }

    internal override void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt)
    {
      Bind_Text(stmt, index, ToString(dt));
    }

    internal override string Bind_ParamName(SQLiteStatement stmt, int index)
    {
      int len;
      return base.ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name_interop(stmt._sqlite_stmt, index, out len), len);
    }

    internal override void Bind_Text(SQLiteStatement stmt, int index, string value)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_text16_interop(stmt._sqlite_stmt, index, value, value.Length * 2, -1);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override string ColumnName(SQLiteStatement stmt, int index)
    {
      int len;
      return ToString(UnsafeNativeMethods.sqlite3_column_name16_interop(stmt._sqlite_stmt, index, out len), len);
    }

    internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
    {
      return ToDateTime(GetText(stmt, index));
    }
    internal override string GetText(SQLiteStatement stmt, int index)
    {
      int len;
      return ToString(UnsafeNativeMethods.sqlite3_column_text16_interop(stmt._sqlite_stmt, index, out len), len);
    }

    internal override string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity)
    {

      int len;
      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype16_interop(stmt._sqlite_stmt, index, out len);
      nAffinity = UnsafeNativeMethods.sqlite3_column_type_interop(stmt._sqlite_stmt, index);

      if (p != IntPtr.Zero) return ToString(p, len);
      else
      {

        switch (nAffinity)
        {
          case TypeAffinity.Int64:
            return "BIGINT";
          case TypeAffinity.Double:
            return "DOUBLE";
          case TypeAffinity.Blob:







|
















>
>
>
>
>
|

|
<
<
|
<













<
|


|



<

|


|

|









<
<
<
<
<
<








<
|








<
|




>
|
|
<
<
|


>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42


43

44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79






80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104


105
106
107
108
109
110
111
112
113
114
115
  using System.Runtime.InteropServices;

  /// <summary>
  /// Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode)
  /// </summary>
  internal class SQLite3_UTF16 : SQLite3
  {
    internal SQLite3_UTF16(DateTimeFormat fmt)
      : base(fmt)
    {
    }

    /// <summary>
    /// Overrides SQLiteConvert.ToString() to marshal UTF-16 strings instead of UTF-8
    /// </summary>
    /// <param name="b">A pointer to a UTF-16 string</param>
    /// <param name="nbytelen">The length (IN BYTES) of the string</param>
    /// <returns>A .NET string</returns>
    public override string ToString(IntPtr b, int nbytelen)
    {
      if (nbytelen == 0) return "";
      return Marshal.PtrToStringUni(b, nbytelen / 2);
    }

    /// <summary>
    /// Another custom string marshaling function
    /// </summary>
    /// <param name="b">A pointer to a zero-terminated UTF-16 string</param>
    /// <returns>A .NET string</returns>
    internal string ToString(IntPtr b)
    {
      if (b == IntPtr.Zero) return "";


      return Marshal.PtrToStringUni(b);

    }

    internal override void Open(string strFilename)
    {
      if (_sql != 0) return;
      int n = UnsafeNativeMethods.sqlite3_open16_interop(strFilename, out _sql);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      _functionsArray = SQLiteFunction.BindFunctions(this);
    }

    internal override string SQLiteLastError()
    {

      return ToString(UnsafeNativeMethods.sqlite3_errmsg16_interop(_sql));
    }

    internal override SQLiteStatement Prepare(string strSql, ref int nParamStart, out string strRemain)
    {
      int stmt;
      IntPtr ptr;


      int n = UnsafeNativeMethods.sqlite3_prepare16_interop(_sql, strSql, strSql.Length, out stmt, out ptr);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      strRemain = ToString(ptr);

      SQLiteStatement cmd = new SQLiteStatement(this, stmt, strSql.Substring(0, strSql.Length - strRemain.Length), ref nParamStart);

      return cmd;
    }

    internal override void Bind_DateTime(SQLiteStatement stmt, int index, DateTime dt)
    {
      Bind_Text(stmt, index, ToString(dt));
    }







    internal override void Bind_Text(SQLiteStatement stmt, int index, string value)
    {
      int n = UnsafeNativeMethods.sqlite3_bind_text16_interop(stmt._sqlite_stmt, index, value, value.Length * 2, -1);
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());
    }

    internal override string ColumnName(SQLiteStatement stmt, int index)
    {

      return ToString(UnsafeNativeMethods.sqlite3_column_name16_interop(stmt._sqlite_stmt, index));
    }

    internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
    {
      return ToDateTime(GetText(stmt, index));
    }
    internal override string GetText(SQLiteStatement stmt, int index)
    {

      return ToString(UnsafeNativeMethods.sqlite3_column_text16_interop(stmt._sqlite_stmt, index));
    }

    internal override string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity)
    {
      nAffinity = TypeAffinity.None;

      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype16_interop(stmt._sqlite_stmt, index);


      if (p != IntPtr.Zero) return ToString(p);
      else
      {
        nAffinity = UnsafeNativeMethods.sqlite3_column_type_interop(stmt._sqlite_stmt, index);
        switch (nAffinity)
        {
          case TypeAffinity.Int64:
            return "BIGINT";
          case TypeAffinity.Double:
            return "DOUBLE";
          case TypeAffinity.Blob:
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      return nCookie;
    }

    internal override string GetParamValueText(int ptr)
    {
      int len;
      return ToString(UnsafeNativeMethods.sqlite3_value_text16_interop(ptr, out len), len);
    }

    internal override void ReturnError(int context, string value)
    {
      UnsafeNativeMethods.sqlite3_result_error16_interop(context, value, value.Length);
    }

    internal override void ReturnText(int context, string value)
    {
      UnsafeNativeMethods.sqlite3_result_text16_interop(context, value, value.Length, -1);
    }
  }
}







<
|













138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
      if (n > 0) throw new SQLiteException(n, SQLiteLastError());

      return nCookie;
    }

    internal override string GetParamValueText(int ptr)
    {

      return ToString(UnsafeNativeMethods.sqlite3_value_text16_interop(ptr));
    }

    internal override void ReturnError(int context, string value)
    {
      UnsafeNativeMethods.sqlite3_result_error16_interop(context, value, value.Length);
    }

    internal override void ReturnText(int context, string value)
    {
      UnsafeNativeMethods.sqlite3_result_text16_interop(context, value, value.Length, -1);
    }
  }
}
Changes to System.Data.SQLite/SQLiteBase.cs.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

  /// <summary>
  /// This internal class provides the foundation of SQLite support.  It defines all the abstract members needed to implement
  /// a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite.
  /// </summary>
  internal abstract class SQLiteBase : SQLiteConvert, IDisposable
  {
    internal SQLiteBase(SQLiteDateFormats fmt)
      : base(fmt) {}

    /// <summary>
    /// Returns a string representing the active version of SQLite
    /// </summary>
    internal abstract string Version { get; }
    /// <summary>







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

  /// <summary>
  /// This internal class provides the foundation of SQLite support.  It defines all the abstract members needed to implement
  /// a SQLite data provider, and inherits from SQLiteConvert which allows for simple translations of string to and from SQLite.
  /// </summary>
  internal abstract class SQLiteBase : SQLiteConvert, IDisposable
  {
    internal SQLiteBase(DateTimeFormat fmt)
      : base(fmt) {}

    /// <summary>
    /// Returns a string representing the active version of SQLite
    /// </summary>
    internal abstract string Version { get; }
    /// <summary>
63
64
65
66
67
68
69
70




71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    /// <returns></returns>
    internal abstract string SQLiteLastError();

    /// <summary>
    /// Prepares a SQL statement for execution.
    /// </summary>
    /// <param name="strSql">The SQL command text to prepare</param>
    /// <param name="previous">The previous statement in a multi-statement command, or null if no previous statement exists</param>




    /// <param name="strRemain">The remainder of the statement that was not processed.  Each call to prepare parses the
    /// SQL up to to either the end of the text or to the first semi-colon delimiter.  The remaining text is returned
    /// here for a subsequent call to Prepare() until all the text has been processed.</param>
    /// <returns>Returns an initialized SQLiteStatement.</returns>
    internal abstract SQLiteStatement Prepare(string strSql, SQLiteStatement previous, out string strRemain);
    /// <summary>
    /// Steps through a prepared statement.
    /// </summary>
    /// <param name="stmt">The SQLiteStatement to step through</param>
    /// <returns>True if a row was returned, False if not.</returns>
    internal abstract bool Step(SQLiteStatement stmt);
    /// <summary>
    /// Finalizes a prepared statement.
    /// </summary>
    /// <param name="stmt">The statement to finalize</param>
    internal abstract void FinalizeStatement(SQLiteStatement stmt);
    /// <summary>
    /// Resets a prepared statement so it can be executed again.  If the error returned is SQLITE_SCHEMA, 
    /// transparently attempt to rebuild the SQL statement and throw an error if that was not possible.
    /// </summary>
    /// <param name="stmt">The statement to reset</param>
    /// <returns>Returns -1 if the schema changed while resetting, 0 if the reset was sucessful or 6 (SQLITE_LOCKED) if the reset failed due to a lock</returns>
    internal abstract int Reset(SQLiteStatement stmt);

    internal abstract void Cancel();

    /// <summary>
    /// An interop-specific function, this call sets an internal flag in the sqlite.interop.dll which causes all column names
    /// of subsequently-prepared statements to return in Database.Table.Column format, ignoring all aliases that may have been applied
    /// to tables or columns in a resultset.
    /// </summary>
    /// <remarks>







|
>
>
>
>




|










|





<
<
|
|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95


96
97
98
99
100
101
102
103
104
    /// <returns></returns>
    internal abstract string SQLiteLastError();

    /// <summary>
    /// Prepares a SQL statement for execution.
    /// </summary>
    /// <param name="strSql">The SQL command text to prepare</param>
    /// <param name="nParamStart">When preparing multiple statements that are tied together into a single command,
    /// this value should be initialized to 0 for the first statement prepared.  On return from this function, the
    /// variable will automatically be incremented by 1 for each unnamed parameter that occurred in the statement.
    /// When implementing this function, one need only pass the nParamStart variable by reference to the SQLiteStatement()
    /// constructor.  SQLiteStatement will take care of it.</param>
    /// <param name="strRemain">The remainder of the statement that was not processed.  Each call to prepare parses the
    /// SQL up to to either the end of the text or to the first semi-colon delimiter.  The remaining text is returned
    /// here for a subsequent call to Prepare() until all the text has been processed.</param>
    /// <returns>Returns an initialized SQLiteStatement.</returns>
    internal abstract SQLiteStatement Prepare(string strSql, ref int nParamStart, out string strRemain);
    /// <summary>
    /// Steps through a prepared statement.
    /// </summary>
    /// <param name="stmt">The SQLiteStatement to step through</param>
    /// <returns>True if a row was returned, False if not.</returns>
    internal abstract bool Step(SQLiteStatement stmt);
    /// <summary>
    /// Finalizes a prepared statement.
    /// </summary>
    /// <param name="stmt">The statement to finalize</param>
    internal abstract void Finalize(SQLiteStatement stmt);
    /// <summary>
    /// Resets a prepared statement so it can be executed again.  If the error returned is SQLITE_SCHEMA, 
    /// transparently attempt to rebuild the SQL statement and throw an error if that was not possible.
    /// </summary>
    /// <param name="stmt">The statement to reset</param>


    /// <returns>Returns true if the schema changed while resetting, or false otherwise.</returns>
    internal abstract bool Reset(SQLiteStatement stmt);

    /// <summary>
    /// An interop-specific function, this call sets an internal flag in the sqlite.interop.dll which causes all column names
    /// of subsequently-prepared statements to return in Database.Table.Column format, ignoring all aliases that may have been applied
    /// to tables or columns in a resultset.
    /// </summary>
    /// <remarks>
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
    internal abstract Int32    GetInt32(SQLiteStatement stmt, int index);
    internal abstract Int64    GetInt64(SQLiteStatement stmt, int index);
    internal abstract string   GetText(SQLiteStatement stmt, int index);
    internal abstract long     GetBytes(SQLiteStatement stmt, int index, int nDataoffset, byte[] bDest, int nStart, int nLength);
    internal abstract long     GetChars(SQLiteStatement stmt, int index, int nDataoffset, char[] bDest, int nStart, int nLength);
    internal abstract DateTime GetDateTime(SQLiteStatement stmt, int index);
    internal abstract bool     IsNull(SQLiteStatement stmt, int index);
    
    /// <summary>
    /// Helper function to retrieve a column of data from an active statement.
    /// </summary>
    /// <param name="stmt">The statement being step()'d through</param>
    /// <param name="index">The column index to retrieve</param>
    /// <param name="typ">The type of data contained in the column.  If Uninitialized, this function will retrieve the datatype information.</param>
    /// <returns>Returns the data in the column</returns>
    internal virtual  object   GetValue(SQLiteStatement stmt, int index, ref SQLiteType typ)
    {
      if (typ.Affinity == 0) typ = SQLiteConvert.ColumnToType(stmt, index);
      if (IsNull(stmt, index)) return DBNull.Value;
      
      Type t = SQLiteConvert.SQLiteTypeToType(typ);

      switch (TypeToAffinity(t))
      {
        case TypeAffinity.Blob:
          int n = (int)GetBytes(stmt, index, 0, null, 0, 0);
          byte[] b = new byte[n];
          GetBytes(stmt, index, 0, b, 0, n);
          return b;
        case TypeAffinity.DateTime:
          return GetDateTime(stmt, index);
        case TypeAffinity.Double:
          return Convert.ChangeType(GetDouble(stmt, index), t, null);
        case TypeAffinity.Int64:
          return Convert.ChangeType(GetInt64(stmt, index), t, null);
        default:
          return GetText(stmt, index);
      }
    }

    internal abstract int  CreateCollation(string strCollation, SQLiteCollation func);
    internal abstract int  CreateFunction(string strFunction, int nArgs, SQLiteCallback func, SQLiteCallback funcstep, SQLiteCallback funcfinal);
    internal abstract void FreeFunction(int nCookie);

    internal abstract int AggregateCount(int context);
    internal abstract int AggregateContext(int context);







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







128
129
130
131
132
133
134
































135
136
137
138
139
140
141
    internal abstract Int32    GetInt32(SQLiteStatement stmt, int index);
    internal abstract Int64    GetInt64(SQLiteStatement stmt, int index);
    internal abstract string   GetText(SQLiteStatement stmt, int index);
    internal abstract long     GetBytes(SQLiteStatement stmt, int index, int nDataoffset, byte[] bDest, int nStart, int nLength);
    internal abstract long     GetChars(SQLiteStatement stmt, int index, int nDataoffset, char[] bDest, int nStart, int nLength);
    internal abstract DateTime GetDateTime(SQLiteStatement stmt, int index);
    internal abstract bool     IsNull(SQLiteStatement stmt, int index);

































    internal abstract int  CreateCollation(string strCollation, SQLiteCollation func);
    internal abstract int  CreateFunction(string strFunction, int nArgs, SQLiteCallback func, SQLiteCallback funcstep, SQLiteCallback funcfinal);
    internal abstract void FreeFunction(int nCookie);

    internal abstract int AggregateCount(int context);
    internal abstract int AggregateContext(int context);
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
    internal abstract void ReturnDouble(int context, double value);
    internal abstract void ReturnError(int context, string value);
    internal abstract void ReturnInt32(int context, Int32 value);
    internal abstract void ReturnInt64(int context, Int64 value);
    internal abstract void ReturnNull(int context);
    internal abstract void ReturnText(int context, string value);

    internal abstract void SetPassword(byte[] passwordBytes);
    internal abstract void ChangePassword(byte[] newPasswordBytes);

    protected virtual void Dispose(bool bDisposing)
    {
    }

    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }
  }
}







<
<
<



<







151
152
153
154
155
156
157



158
159
160

161
162
163
164
165
166
167
    internal abstract void ReturnDouble(int context, double value);
    internal abstract void ReturnError(int context, string value);
    internal abstract void ReturnInt32(int context, Int32 value);
    internal abstract void ReturnInt64(int context, Int64 value);
    internal abstract void ReturnNull(int context);
    internal abstract void ReturnText(int context, string value);




    protected virtual void Dispose(bool bDisposing)
    {
    }

    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }
  }
}
Changes to System.Data.SQLite/SQLiteCommand.cs.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162

163


164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232



233
234
235
236


237
238
239
240
241
242
243
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;

  /// <summary>
  /// SQLite implementation of DbCommand.
  /// </summary>
  public sealed class SQLiteCommand : DbCommand, ICloneable
  {
    /// <summary>
    /// The command text this command is based on
    /// </summary>
    private string _commandText;
    /// <summary>
    /// The connection the command is associated with
    /// </summary>
    private SQLiteConnection _cnn;
    /// <summary>
    /// Indicates whether or not a DataReader is active on the command.
    /// </summary>
    private bool _isReaderOpen;
    /// <summary>
    /// The timeout for the command, kludged because SQLite doesn't support per-command timeout values
    /// </summary>
    internal int _commandTimeout;
    /// <summary>
    /// Designer support
    /// </summary>
    private bool _designTimeVisible;
    /// <summary>
    /// Used by DbDataAdapter to determine updating behavior
    /// </summary>
    private UpdateRowSource _updateRowSource;
    /// <summary>
    /// The collection of parameters for the command
    /// </summary>
    private SQLiteParameterCollection _parameterCollection;
    /// <summary>
    /// The SQL command text, broken into individual SQL statements as they are executed
    /// </summary>
    internal List<SQLiteStatement> _statementList;
    /// <summary>
    /// Unprocessed SQL text that has not been executed
    /// </summary>
    internal string _remainingText;

    ///<overloads>
    /// Constructs a new SQLiteCommand
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteCommand()
    {
      Initialize(null, null);
    }

    /// <summary>
    /// Initializes the command with the given command text
    /// </summary>
    /// <param name="commandText">The SQL command text</param>
    public SQLiteCommand(string commandText)
    {
      Initialize(commandText, null);
    }

    /// <summary>
    /// Initializes the command with the given SQL command text and attach the command to the specified
    /// connection.
    /// </summary>
    /// <param name="commandText">The SQL command text</param>
    /// <param name="cnn">The connection to associate with the command</param>
    public SQLiteCommand(string commandText, SQLiteConnection cnn)
    {
      Initialize(commandText, cnn);
    }

    /// <summary>
    /// Initializes the command and associates it with the specified connection.
    /// </summary>
    /// <param name="cnn">The connection to associate with the command</param>
    public SQLiteCommand(SQLiteConnection cnn)
    {
      Initialize(null, cnn);
    }

    /// <summary>
    /// Initializes a command with the given SQL, connection and transaction
    /// </summary>
    /// <param name="commandText">The SQL command text</param>
    /// <param name="cnn">The connection to associate with the command</param>
    /// <param name="trans">The transaction the command should be associated with</param>
    public SQLiteCommand(string commandText, SQLiteConnection cnn, SQLiteTransaction trans)
    {
      Initialize(commandText, cnn);
      Transaction = trans;
    }

    /// <summary>
    /// Initializes the command class
    /// </summary>
    /// <param name="strSql">The SQL command text</param>
    /// <param name="cnn">A connection to associate with the command</param>
    private void Initialize(string strSql, SQLiteConnection cnn)
    {
      _statementList = null;
      _isReaderOpen = false;
      _commandTimeout = 30;
      _parameterCollection = new SQLiteParameterCollection(this);
      _designTimeVisible = true;
      _updateRowSource = UpdateRowSource.FirstReturnedRecord;

      if (strSql != null)
        CommandText = strSql;

      if (cnn != null)
        DbConnection = cnn;
    }

    /// <summary>
    /// Disposes of the command and clears all member variables
    /// </summary>
    /// <param name="disposing">Whether or not the class is being explicitly or implicitly disposed</param>
    protected override void Dispose(bool disposing)
    {
      base.Dispose(disposing);
      Connection = null;
      _parameterCollection.Clear();
      _commandText = null;
    }

    /// <summary>
    /// Clears and destroys all statements currently prepared
    /// </summary>
    internal void ClearCommands()
    {
      if (_statementList == null) return;

      int x = _statementList.Count;
      for (int n = 0; n < x; n++)
        _statementList[n].Dispose();

      _statementList = null;

      _parameterCollection.Unbind();
    }

    /// <summary>

    /// Builds an array of prepared statements for each complete SQL statement in the command text
    /// </summary>
    internal SQLiteStatement BuildNextCommand()
    {

      SQLiteStatement stmt;



      try
      {
        if (_statementList == null)
          _remainingText = _commandText;

        stmt = _cnn._sql.Prepare(_remainingText, (_statementList == null) ? null : _statementList[_statementList.Count - 1], out _remainingText);
        if (stmt != null)
        {
          stmt._command = this;
          if (_statementList == null)
            _statementList = new List<SQLiteStatement>();

          _statementList.Add(stmt);
          _parameterCollection.MapParameters(stmt);
          stmt.BindParameters();
        }        
        return stmt;
      }
      catch (Exception)
      {
        ClearCommands();
        throw;
      }
    }

    internal SQLiteStatement GetStatement(int index)
    {
      // Haven't built any statements yet
      if (_statementList == null) return BuildNextCommand();

      // If we're at the last built statement and want the next unbuilt statement, then build it
      if (index == _statementList.Count)
      {
        if (String.IsNullOrEmpty(_remainingText) == false) return BuildNextCommand();
        else return null; // No more commands
      }

      SQLiteStatement stmt = _statementList[index];
      stmt.BindParameters();

      return stmt;
    }

    /// <summary>
    /// Not implemented
    /// </summary>
    public override void Cancel()
    {

    }

    /// <summary>
    /// The SQL command text associated with the command
    /// </summary>
    public override string CommandText
    {
      get
      {
        return _commandText;
      }
      set
      {
        if (_commandText == value) return;

        if (_isReaderOpen)
        {
          throw new InvalidOperationException("Cannot set CommandText while a DataReader is active");
        }




        ClearCommands();
        _commandText = value;

        if (_cnn == null) return;


      }
    }

    /// <summary>
    /// The amount of time to wait for the connection to become available before erroring out
    /// </summary>
    public override int CommandTimeout







|

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

|
<
<
|
<
<
<
<















|
|

|






|

|

|





|





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|













|

|



|

<


<
<
<




<
|







|
>
|
|
|
|
>
|
>
>



<
<
|
<
<

<
<
<
|
|
<
<
|
<

|


|

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







>















|




>
>
>




>
>







11
12
13
14
15
16
17
18
19



20



21



22



23



24



25



26
27


28




29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

















70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

95
96



97
98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121


122


123



124
125


126

127
128
129
130
131
132

133






134









135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;

  /// <summary>
  /// SQLite implementation of DbCommand.
  /// </summary>
  public sealed class SQLiteCommand : DbCommand
  {



    private string                    _commandText;



    private SQLiteConnection          _cnn;



    private SQLiteDataReader          _dataReader;



    private int                       _commandTimeout;



    private bool                      _designTimeVisible;



    private UpdateRowSource           _updateRowSource;



    private SQLiteParameterCollection _parameterCollection;



    internal SQLiteStatement[]        _statementList;





    ///<overloads>
    /// Constructs a new SQLiteCommand
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteCommand()
    {
      Initialize(null, null);
    }

    /// <summary>
    /// Initializes the command with the given command text
    /// </summary>
    /// <param name="strSql">The SQL command text</param>
    public SQLiteCommand(string strSql)
    {
      Initialize(strSql, null);
    }

    /// <summary>
    /// Initializes the command with the given SQL command text and attach the command to the specified
    /// connection.
    /// </summary>
    /// <param name="strSql">The SQL command text</param>
    /// <param name="cnn">The connection to associate with the command</param>
    public SQLiteCommand(string strSql, SQLiteConnection cnn)
    {
      Initialize(strSql, cnn);
    }

    /// <summary>
    /// Initializes the command and associates it with the specified connection.
    /// </summary>
    /// <param name="cnn"></param>
    public SQLiteCommand(SQLiteConnection cnn)
    {
      Initialize(null, cnn);
    }


















    private void Initialize(string strSql, SQLiteConnection cnn)
    {
      _statementList = null;
      _dataReader = null;
      _commandTimeout = 30;
      _parameterCollection = new SQLiteParameterCollection(this);
      _designTimeVisible = true;
      _updateRowSource = UpdateRowSource.FirstReturnedRecord;

      if (strSql != null)
        CommandText = strSql;

      if (cnn != null)
        DbConnection = cnn;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="disposing"></param>
    protected override void Dispose(bool disposing)
    {
      base.Dispose(disposing);
      ClearCommands();
      _parameterCollection.Clear();

    }




    internal void ClearCommands()
    {
      if (_statementList == null) return;


      for (int n = 0; n < _statementList.Length; n++)
        _statementList[n].Dispose();

      _statementList = null;

      _parameterCollection.Unbind();
    }

    internal void BuildCommands()
    {
      ClearCommands();

      if (_cnn.State != ConnectionState.Open) return;

      string strRemain = _commandText;
      SQLiteStatement itm;
      int nStart = 0;
      List<SQLiteStatement> lst = new List<SQLiteStatement>();

      try
      {


        while (strRemain.Length > 0)


        {



          itm = _cnn._sql.Prepare(strRemain, ref nStart, out strRemain);
          if (itm != null) lst.Add(itm);


        }

      }
      catch (Exception e)
      {
        ClearCommands();
        throw (e);
      }

      _statementList = new SQLiteStatement[lst.Count];






      lst.CopyTo(_statementList, 0);









    }

    /// <summary>
    /// Not implemented
    /// </summary>
    public override void Cancel()
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// The SQL command text associated with the command
    /// </summary>
    public override string CommandText
    {
      get
      {
        return _commandText;
      }
      set
      {
        if (_commandText == value) return;

        if (_dataReader != null)
        {
          throw new InvalidOperationException("Cannot set CommandText while a DataReader is active");
        }

//        if (value == null)
//          throw new ArgumentNullException();

        ClearCommands();
        _commandText = value;

        if (_cnn == null) return;

        BuildCommands();
      }
    }

    /// <summary>
    /// The amount of time to wait for the connection to become available before erroring out
    /// </summary>
    public override int CommandTimeout
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295


296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354


355

356
357
358
359
360

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

414
415
416
417
418
419
420
421


422
423
424
425
426
427
428
429

430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480


481

482


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

510
511
512




513
514
515
516
517
518
519
      {
        return CommandType.Text;
      }
      set
      {
        if (value != CommandType.Text)
        {
          throw new NotSupportedException();
        }
      }
    }

    /// <summary>
    /// Forwards to the local CreateParameter() function
    /// </summary>
    /// <returns></returns>
    protected override DbParameter CreateDbParameter()
    {
      return CreateParameter();
    }

    /// <summary>
    /// Create a new parameter
    /// </summary>
    /// <returns></returns>
    public new SQLiteParameter CreateParameter()
    {
      return new SQLiteParameter();
    }

    /// <summary>
    /// The connection associated with this command
    /// </summary>
    public new SQLiteConnection Connection
    {


      get { return _cnn; }

      set
      {
        if (_isReaderOpen)
          throw new InvalidOperationException("Cannot set Connection while a DataReader is active");

        if (_cnn != null)
        {
          ClearCommands();
          _cnn._commandList.Remove(this);
        }

        _cnn = value;

        if (_cnn != null)
          _cnn._commandList.Add(this);
      }
    }

    /// <summary>
    /// Forwards to the local Connection property
    /// </summary>
    protected override DbConnection DbConnection
    {
      get
      {
        return Connection;
      }
      set
      {
        Connection = (SQLiteConnection)value;
      }
    }

    /// <summary>
    /// Returns the SQLiteParameterCollection for the given command
    /// </summary>
    public new SQLiteParameterCollection Parameters
    {
      get { return _parameterCollection; }
    }

    /// <summary>
    /// Forwards to the local Parameters property
    /// </summary>
    protected override DbParameterCollection DbParameterCollection
    {
      get
      {
        return Parameters;
      }
    }

    /// <summary>
    /// The transaction associated with this command.  SQLite only supports one transaction per connection, so this property forwards to the
    /// command's underlying connection.
    /// </summary>
    public new SQLiteTransaction Transaction
    {


      get { return _cnn._activeTransaction; }

      set
      {
        if (_cnn != null)
        {
          if (value != _cnn._activeTransaction && value != null)

            throw new ArgumentOutOfRangeException("SQLiteTransaction", "Transaction is for a different connection than the one associated with this Command");
        }
        else if (value != null)
          throw new ArgumentOutOfRangeException("SQLiteTransaction", "Not associated with a connection");
      }
    }

    /// <summary>
    /// Forwards to the local Transaction property
    /// </summary>
    protected override DbTransaction DbTransaction
    {
      get
      {
        return Transaction;
      }
      set
      {
        Transaction = (SQLiteTransaction)value;
      }
    }

    /// <summary>
    /// This function ensures there are no active readers, that we have a valid connection,
    /// that the connection is open, that all statements are prepared and all parameters are assigned
    /// in preparation for allocating a data reader.
    /// </summary>
    private void InitializeForReader()
    {
      if (_isReaderOpen)
        throw new InvalidOperationException("DataReader already active on this command");

      if (_cnn == null)
        throw new InvalidOperationException("No connection associated with this command");

      if (_cnn.State != ConnectionState.Open)
        throw new InvalidOperationException("Database is not open");

      // Map all parameters for statements already built
      _parameterCollection.MapParameters(null);

      // Set the default command timeout
      _cnn._sql.SetTimeout(_commandTimeout * 1000);
    }

    /// <summary>
    /// Creates a new SQLiteDataReader to execute/iterate the array of SQLite prepared statements
    /// </summary>
    /// <param name="behavior">The behavior the data reader should adopt</param>
    /// <returns>Returns a SQLiteDataReader object</returns>
    protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
    {
      return ExecuteReader(behavior);

    }

    /// <summary>
    /// Overrides the default behavior to return a SQLiteDataReader specialization class
    /// </summary>
    /// <param name="behavior">The flags to be associated with the reader</param>
    /// <returns>A SQLiteDataReader</returns>
    public new SQLiteDataReader ExecuteReader(CommandBehavior behavior)


    {
      InitializeForReader();

      SQLiteDataReader rd = new SQLiteDataReader(this, behavior);
      _isReaderOpen = true;

      return rd;
    }


    /// <summary>
    /// Overrides the default behavior of DbDataReader to return a specialized SQLiteDataReader class
    /// </summary>
    /// <returns>A SQLiteDataReader</returns>
    public new SQLiteDataReader ExecuteReader()
    {
      return ExecuteReader(CommandBehavior.Default);
    }

    /// <summary>
    /// Called by the SQLiteDataReader when the data reader is closed.
    /// </summary>
    internal void ClearDataReader()
    {
      _isReaderOpen = false;
    }

    /// <summary>
    /// Execute the command and return the number of rows inserted/updated affected by it.
    /// </summary>
    /// <returns></returns>
    public override int ExecuteNonQuery()
    {
      InitializeForReader();

      int nAffected = 0;
      int x = 0;
      SQLiteStatement stmt;

      for(;;)
      {
        stmt = GetStatement(x);
        x++;
        if (stmt == null) break;

        _cnn._sql.Step(stmt);
        nAffected += _cnn._sql.Changes;
        _cnn._sql.Reset(stmt);
      }

      return nAffected;
    }

    /// <summary>
    /// Execute the command and return the first column of the first row of the resultset
    /// (if present), or null if no resultset was returned.
    /// </summary>
    /// <returns>The first column of the first row of the first resultset from the query</returns>
    public override object ExecuteScalar()
    {


      InitializeForReader();




      int x = 0;
      object ret = null;
      SQLiteType typ = new SQLiteType();
      SQLiteStatement stmt;

      // We step through every statement in the command, but only grab the first row of the first resultset.
      // We keep going even after obtaining it.
      for (;;)
      {
        stmt = GetStatement(x);
        x++;
        if (stmt == null) break;

        if (_cnn._sql.Step(stmt) == true && ret == null)
        {
          ret = _cnn._sql.GetValue(stmt, 0, ref typ);
        }
        _cnn._sql.Reset(stmt);
      }

      if (ret == null) ret = DBNull.Value;

      return ret;
    }

    /// <summary>
    /// Does nothing.  Commands are prepared as they are executed the first time, and kept in prepared state afterwards.

    /// </summary>
    public override void Prepare()
    {




    }

    /// <summary>
    /// Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable.
    /// </summary>
    public override UpdateRowSource UpdatedRowSource
    {







|




<
<
<
<
<
<
<
<
<




|







|

>
>
|
>


|








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






<
<
<
<
<
<
<
<




|







|

>
>
|
>


|
|
|
>
|

<
<




|

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

|



|




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

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

<
<
<
<
|
|
|


<
<
<


|








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

|
<
|
<

|
<

|


>
>
|
>
|
>
>
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
>



>
>
>
>







196
197
198
199
200
201
202
203
204
205
206
207









208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237


238
239

240
241











242
243
244
245
246
247








248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273


274
275
276
277
278
279











280
281




282
283
284
285
286
287
288
289
290
291
292


293


294
295






296

297
298
299






300
301
302

303

304
305

306
307
308




309
310
311
312
313



314
315
316
317
318
319
320
321
322
323
324

325



326





327

328

329
330

331

332
333

334
335
336
337
338
339
340
341
342
343
344




345




















346

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
      {
        return CommandType.Text;
      }
      set
      {
        if (value != CommandType.Text)
        {
          throw new NotImplementedException();
        }
      }
    }










    /// <summary>
    /// Create a new parameter
    /// </summary>
    /// <returns></returns>
    protected override DbParameter CreateDbParameter()
    {
      return new SQLiteParameter();
    }

    /// <summary>
    /// The connection associated with this command
    /// </summary>
    protected override DbConnection DbConnection
    {
      get
      {
        return _cnn;
      }
      set
      {
        if (_dataReader != null)
          throw new InvalidOperationException("Cannot set Connection while a DataReader is active");

        if (_cnn != null)
        {
          ClearCommands();
          _cnn._commandList.Remove(this);
        }

        _cnn = (SQLiteConnection)value;


        _cnn._commandList.Add(this);


        if (_commandText != null)
          BuildCommands();











      }
    }

    /// <summary>
    /// Returns the SQLiteParameterCollection for the given command
    /// </summary>








    protected override DbParameterCollection DbParameterCollection
    {
      get
      {
        return _parameterCollection;
      }
    }

    /// <summary>
    /// The transaction associated with this command.  SQLite only supports one transaction per connection, so this property forwards to the
    /// command's underlying connection.
    /// </summary>
    protected override DbTransaction DbTransaction
    {
      get
      {
        return _cnn._activeTransaction;
      }
      set
      {
        if (_cnn == null) return;

        if (value != _cnn._activeTransaction && value != null)
        {
          throw new ArgumentOutOfRangeException();
        }


      }
    }

    /// <summary>
    /// 
    /// </summary>











    /// <param name="behavior"></param>
    /// <returns></returns>




    protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
    {
      if (_dataReader != null)
        throw new InvalidOperationException("DataReader already active on this command");

      if (_cnn == null)
        throw new InvalidOperationException("No connection associated with this Command");

      if (_cnn.State != ConnectionState.Open)
        throw new InvalidOperationException("Database is not open");



      int n;



      if (_statementList.Length == 0)






      {

        BuildCommands();
      }







      // Make sure all parameters are mapped properly to associated statement(s)
      _parameterCollection.MapParameters();


      // Bind all parameters to their statements

      for (n = 0; n < _statementList.Length; n++)
        _statementList[n].BindParameters();


      _cnn._sql.SetTimeout(_commandTimeout * 1000);





      _dataReader = new SQLiteDataReader(this, behavior);

      return _dataReader;
    }




    internal void ClearDataReader()
    {
      _dataReader = null;
    }

    /// <summary>
    /// Execute the command and return the number of rows inserted/updated affected by it.
    /// </summary>
    /// <returns></returns>
    public override int ExecuteNonQuery()
    {

      using (DbDataReader rd = ExecuteDbDataReader(CommandBehavior.Default))



      {





        rd.Close();

        return rd.RecordsAffected;

      }
    }



    /// <summary>
    /// Execute the command and return the first column of the first row of the resultset (if present), or null if no resultset was returned.

    /// </summary>
    /// <returns></returns>
    public override object ExecuteScalar()
    {
      using (DbDataReader rd = ExecuteDbDataReader(CommandBehavior.Default))
      {
        if (rd.Read())
          return rd[0];
      }
      return null;
    }

























    /// <summary>

    /// Prepares the command for execution.
    /// </summary>
    public override void Prepare()
    {
      if (_statementList.Length == 0)
      {
        BuildCommands();
      }
    }

    /// <summary>
    /// Sets the method the SQLiteCommandBuilder uses to determine how to update inserted or updated rows in a DataTable.
    /// </summary>
    public override UpdateRowSource UpdatedRowSource
    {
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
        return _designTimeVisible;
      }
      set
      {
        _designTimeVisible = value;
      }
    }

    /// <summary>
    /// Clones a command, including all its parameters
    /// </summary>
    /// <returns>A new SQLiteCommand with the same commandtext, connection and parameters</returns>
    public object Clone()
    {
      SQLiteCommand newcommand = new SQLiteCommand(CommandText, Connection as SQLiteConnection);
      foreach (SQLiteParameter param in _parameterCollection)
      {
        newcommand.Parameters.Add(param.Clone());
      }
      return newcommand;
    }
  }
}







|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
379
380
381
382
383
384
385
386










387




        return _designTimeVisible;
      }
      set
      {
        _designTimeVisible = value;
      }
    }
  }










}




Added System.Data.SQLite/SQLiteCommandBase.cs.






















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;

namespace System.Data.SQLite
{
  internal sealed class SQLiteCommandBase : IDisposable
  {
    internal SQLiteBase _sqlbase;
    internal string     _strCommand;
    internal int        _sqlite_stmt;

    internal SQLiteCommandBase(SQLiteBase sqlbase, int stmt, string strCommand)
    {
      _sqlbase     = sqlbase;
      _sqlite_stmt = stmt;
      _strCommand  = strCommand;
    }

    #region IDisposable Members

    public void Dispose()
    {
      _sqlbase.Finalize(this);
    }

    #endregion
  }
}
Changes to System.Data.SQLite/SQLiteCommandBuilder.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Globalization;
  using System.ComponentModel;

  /// <summary>
  /// SQLite implementation of DbCommandBuilder.
  /// </summary>
  public sealed class SQLiteCommandBuilder : DbCommandBuilder
  {
    private EventHandler<RowUpdatingEventArgs> _handler;

    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteCommandBuilder()
    {
    }













<
<






<
<







1
2
3
4
5
6
7
8
9
10
11
12


13
14
15
16
17
18


19
20
21
22
23
24
25
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;



  /// <summary>
  /// SQLite implementation of DbCommandBuilder.
  /// </summary>
  public sealed class SQLiteCommandBuilder : DbCommandBuilder
  {


    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteCommandBuilder()
    {
    }

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85











86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    /// </summary>
    /// <param name="parameter">The parameter to use in applying custom behaviors to a row</param>
    /// <param name="row">The row to apply the parameter to</param>
    /// <param name="statementType">The type of statement</param>
    /// <param name="whereClause">Whether the application of the parameter is part of a WHERE clause</param>
    protected override void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause)
    {
      SQLiteParameter param = (SQLiteParameter)parameter;
      param.DbType = (DbType)row[SchemaTableColumn.ProviderType];
    }

    /// <overloads>
    /// Not implemented.  Throws a NotImplementedException() if called.
    /// </overloads>
    /// <summary>
    /// Not implemented.
    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <returns>Error</returns>
    protected override string GetParameterName(string parameterName)
    {
      return String.Format(CultureInfo.InvariantCulture, "${0}", parameterName);
    }

    /// <summary>
    /// Not implemented.
    /// </summary>
    /// <param name="parameterOrdinal">The i of the parameter</param>
    /// <returns>Error</returns>
    protected override string GetParameterName(int parameterOrdinal)
    {
      return String.Format(CultureInfo.InvariantCulture, "$param{0}", parameterOrdinal);
    }

    /// <summary>
    /// Returns a placeholder character for the specified parameter i.
    /// </summary>
    /// <param name="parameterOrdinal">The index of the parameter to provide a placeholder for</param>
    /// <returns>Returns a "?" character, used for all placeholders.</returns>
    protected override string GetParameterPlaceholder(int parameterOrdinal)
    {
      return GetParameterName(parameterOrdinal);
    }


    /// <summary>











    /// Sets the handler for receiving row updating events.  Used by the DbCommandBuilder to autogenerate SQL

    /// statements that may not have previously been generated.
    /// </summary>
    /// <param name="adapter">A data adapter to receive events on.</param>
    protected override void SetRowUpdatingHandler(DbDataAdapter adapter)
    {
      SQLiteDataAdapter adp = (SQLiteDataAdapter)adapter;

      _handler = new EventHandler<RowUpdatingEventArgs>(RowUpdatingEventHandler);
      adp.RowUpdating += _handler;
    }

    private void RowUpdatingEventHandler(object sender, RowUpdatingEventArgs e)
    {
      base.RowUpdatingHandler(e);
    }

    /// <summary>
    /// Gets/sets the DataAdapter for this CommandBuilder
    /// </summary>
    public new SQLiteDataAdapter DataAdapter
    {
      get { return (SQLiteDataAdapter)base.DataAdapter; }
      set { base.DataAdapter = value; }
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to delete rows from the database
    /// </summary>
    /// <returns></returns>
    public new SQLiteCommand GetDeleteCommand()
    {
      return (SQLiteCommand)base.GetDeleteCommand();
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to delete rows from the database
    /// </summary>
    /// <param name="useColumnsForParameterNames"></param>
    /// <returns></returns>
    public new SQLiteCommand GetDeleteCommand(bool useColumnsForParameterNames)
    {
      return (SQLiteCommand)base.GetDeleteCommand(useColumnsForParameterNames);
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to update rows in the database
    /// </summary>
    /// <returns></returns>
    public new SQLiteCommand GetUpdateCommand()
    {
      return (SQLiteCommand)base.GetUpdateCommand();
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to update rows in the database
    /// </summary>
    /// <param name="useColumnsForParameterNames"></param>
    /// <returns></returns>
    public new SQLiteCommand GetUpdateCommand(bool useColumnsForParameterNames)
    {
      return (SQLiteCommand)base.GetUpdateCommand(useColumnsForParameterNames);
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to insert rows into the database
    /// </summary>
    /// <returns></returns>
    public new SQLiteCommand GetInsertCommand()
    {
      return (SQLiteCommand)base.GetInsertCommand();
    }

    /// <summary>
    /// Returns the automatically-generated SQLite command to insert rows into the database
    /// </summary>
    /// <param name="useColumnsForParameterNames"></param>
    /// <returns></returns>
    public new SQLiteCommand GetInsertCommand(bool useColumnsForParameterNames)
    {
      return (SQLiteCommand)base.GetInsertCommand(useColumnsForParameterNames);
    }

    /// <summary>
    /// Overridden to hide its property from the designer
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false)]
#endif
    public override CatalogLocation CatalogLocation
    {
      get
      {
        return base.CatalogLocation;
      }
      set
      {
        base.CatalogLocation = value;
      }
    }

    /// <summary>
    /// Overridden to hide its property from the designer
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false)]
#endif
    public override string CatalogSeparator
    {
      get
      {
        return base.CatalogSeparator;
      }
      set
      {
        base.CatalogSeparator = value;
      }
    }

    /// <summary>
    /// Overridden to hide its property from the designer
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false)]
#endif
    public override string QuotePrefix
    {
      get
      {
        return base.QuotePrefix;
      }
      set
      {
        base.QuotePrefix = value;
      }
    }

    /// <summary>
    /// Overridden to hide its property from the designer
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false)]
#endif
    public override string QuoteSuffix
    {
      get
      {
        return base.QuoteSuffix;
      }
      set
      {
        base.QuoteSuffix = value;
      }
    }

    /// <summary>
    /// Overridden to hide its property from the designer
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false)]
#endif
    public override string SchemaSeparator
    {
      get
      {
        return base.SchemaSeparator;
      }
      set
      {
        base.SchemaSeparator = value;
      }
    }
  }
}







<
<












|





|



|



|





|


>

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




<
|
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
37
38
39
40
41
42
43


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

99


100
101


































































































































































    /// </summary>
    /// <param name="parameter">The parameter to use in applying custom behaviors to a row</param>
    /// <param name="row">The row to apply the parameter to</param>
    /// <param name="statementType">The type of statement</param>
    /// <param name="whereClause">Whether the application of the parameter is part of a WHERE clause</param>
    protected override void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause)
    {


    }

    /// <overloads>
    /// Not implemented.  Throws a NotImplementedException() if called.
    /// </overloads>
    /// <summary>
    /// Not implemented.
    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <returns>Error</returns>
    protected override string GetParameterName(string parameterName)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// Not implemented.
    /// </summary>
    /// <param name="parameterOrdinal">The ordinal of the parameter</param>
    /// <returns>Error</returns>
    protected override string GetParameterName(int parameterOrdinal)
    {
      return null;
    }

    /// <summary>
    /// Returns a placeholder character for the specified parameter ordinal.
    /// </summary>
    /// <param name="parameterOrdinal">The index of the parameter to provide a placeholder for</param>
    /// <returns>Returns a "?" character, used for all placeholders.</returns>
    protected override string GetParameterPlaceholder(int parameterOrdinal)
    {
      return "?";
    }

#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// Obsolete
    /// </summary>
    [Obsolete]
    protected override DbProviderFactory ProviderFactory
    {
      get 
      {
        return new SQLiteFactory();
      }
    }
#endif

    /// <summary>
    /// Not implemented.
    /// </summary>
    /// <param name="adapter">A data adapter to receive events on.</param>
    protected override void SetRowUpdatingHandler(DbDataAdapter adapter)
    {

    }


  }
}


































































































































































Changes to System.Data.SQLite/SQLiteConnection.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;
  using System.Globalization;

  /// <summary>
  /// The I/O file cache flushing behavior for the connection
  /// </summary>
  public enum SynchronizationModes
  {
    /// <summary>
    /// Normal file flushing at critical sections of the code
    /// </summary>
    Normal = 0,
    /// <summary>
    /// Full file flushing after every write operation













<




|







1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;


  /// <summary>
  /// The I/O file cache flushing behavior for the connection
  /// </summary>
  public enum SyncMode
  {
    /// <summary>
    /// Normal file flushing at critical sections of the code
    /// </summary>
    Normal = 0,
    /// <summary>
    /// Full file flushing after every write operation
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128

129
130
131
132
133
134
135
  /// </item>
  /// <item>
  /// <description>Page Size</description>
  /// <description>{size in bytes}</description>
  /// <description>N</description>
  /// <description>1024</description>
  /// </item>
  /// <item>
  /// <description>Password</description>
  /// <description>{password}</description>
  /// <description>N</description>
  /// <description></description>
  /// </item>
  /// </list>
  /// </remarks>
  public sealed class SQLiteConnection : DbConnection, ICloneable
  {
    /// <summary>
    /// State of the current connection
    /// </summary>
    private ConnectionState     _connectionState;
    /// <summary>
    /// The connection string
    /// </summary>
    private string              _connectionString;
    /// <summary>
    /// One transaction allowed per connection please!
    /// </summary>
    internal SQLiteTransaction  _activeTransaction;
    /// <summary>
    /// The base SQLite object to interop with
    /// </summary>
    internal SQLiteBase          _sql;
    /// <summary>
    /// Commands associated with this connection
    /// </summary>
    internal List<SQLiteCommand> _commandList;
    /// <summary>
    /// The database filename minus path and extension
    /// </summary>
    private string _dataSource;


    /// <event/>
    /// <summary>
    /// This event is raised whenever the database is opened or closed.
    /// </summary>
    public override event StateChangeEventHandler StateChange;


    ///<overloads>
    /// Constructs a new SQLiteConnection object
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>







<
<
<
<
<
<















|








<
<
<
<

>





>







81
82
83
84
85
86
87






88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111




112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  /// </item>
  /// <item>
  /// <description>Page Size</description>
  /// <description>{size in bytes}</description>
  /// <description>N</description>
  /// <description>1024</description>
  /// </item>






  /// </list>
  /// </remarks>
  public sealed class SQLiteConnection : DbConnection, ICloneable
  {
    /// <summary>
    /// State of the current connection
    /// </summary>
    private ConnectionState     _connectionState;
    /// <summary>
    /// The connection string
    /// </summary>
    private string              _connectionString;
    /// <summary>
    /// One transaction allowed per connection please!
    /// </summary>
    internal DbTransaction       _activeTransaction;
    /// <summary>
    /// The base SQLite object to interop with
    /// </summary>
    internal SQLiteBase          _sql;
    /// <summary>
    /// Commands associated with this connection
    /// </summary>
    internal List<SQLiteCommand> _commandList;





#if !PLATFORM_COMPACTFRAMEWORK
    /// <event/>
    /// <summary>
    /// This event is raised whenever the database is opened or closed.
    /// </summary>
    public override event StateChangeEventHandler StateChange;
#endif

    ///<overloads>
    /// Constructs a new SQLiteConnection object
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

        // Reattach all attached databases from the existing connection
        using (DataTable tbl = cnn.GetSchema("Catalogs"))
        {
          foreach (DataRow row in tbl.Rows)
          {
            str = row[0].ToString();
            if (String.Compare(str, "main", true, CultureInfo.InvariantCulture) != 0
              && String.Compare(str, "temp", true, CultureInfo.InvariantCulture) != 0)
            {
              _sql.Execute(String.Format(CultureInfo.InvariantCulture, "ATTACH DATABASE '{0}' AS [{1}]", row[1], row[0]));
            }
          }
        }
      }
    }

#if PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// Obsolete
    /// </summary>
    public override int ConnectionTimeout
    {
      get
      {
        return 30;
      }
    }







|
<

|







<
<
<







156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
172



173
174
175
176
177
178
179

        // Reattach all attached databases from the existing connection
        using (DataTable tbl = cnn.GetSchema("Catalogs"))
        {
          foreach (DataRow row in tbl.Rows)
          {
            str = row[0].ToString();
            if (String.Compare(str, "MAIN", true) != 0 && String.Compare(str, "TEMP", true) != 0)

            {
              _sql.Execute(String.Format("ATTACH DATABASE '{0}' AS [{1}]", row[1], row[0]));
            }
          }
        }
      }
    }

#if PLATFORM_COMPACTFRAMEWORK



    public override int ConnectionTimeout
    {
      get
      {
        return 30;
      }
    }
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319

320
321
322
323
324

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
      if (connectionString != null)
        ConnectionString = connectionString;
    }

    /// <summary>
    /// Disposes of the SQLiteConnection, closing it if it is active.
    /// </summary>
    /// <param name="disposing">True if the connection is being explicitly closed.</param>
    protected override void Dispose(bool disposing)
    {
      base.Dispose(disposing);
      Close();
    }

    /// <summary>
    /// Creates a database file.  This just creates a zero-byte file which SQLite
    /// will turn into a database when the file is opened properly.
    /// </summary>
    /// <param name="databaseFileName">The file to create</param>
    static public void CreateFile(string databaseFileName)
    {
      IO.FileStream fs = IO.File.Create(databaseFileName);
      fs.Close();
    }

    /// <summary>
    /// On NTFS volumes, this function turns on the compression attribute for the given file.
    /// It must not be open or referenced at the time of the function call.
    /// </summary>
    /// <param name="databaseFileName">The file to compress</param>
    static public void CompressFile(string databaseFileName)
    {
      UnsafeNativeMethods.sqlite3_compressfile(databaseFileName);
    }

    /// <summary>
    /// On NTFS volumes, this function removes the compression attribute for the given file.
    /// It must not be open or referenced at the time of the function call.
    /// </summary>
    /// <param name="databaseFileName">The file to decompress</param>
    static public void DecompressFile(string databaseFileName)
    {
      UnsafeNativeMethods.sqlite3_decompressfile(databaseFileName);
    }

    /// <summary>
    /// On NTFS volumes, this function turns on the EFS (Encrypted File System) attribute
    /// for the given file, which causes the file to be encrypted.
    /// For a full description of EFS, see the MSDN documentation.
    /// </summary>
    /// <remarks>
    /// Requires Win2K and above, plus a valid EFS certificate (which is beyond the scope
    /// of this function description).
    /// </remarks>
    /// <param name="databaseFileName">The file to encrypt</param>
    [Obsolete("Define a password in the ConnectionString, call SetPassword() on a new open database, or call ChangePassword({password}) on an existing open database to encrypt the database file.")]
    static public void EncryptFile(string databaseFileName)
    {
      int n = UnsafeNativeMethods.sqlite3_encryptfile(databaseFileName);
      if (n == 0) throw new System.ComponentModel.Win32Exception();
    }

    /// <summary>
    /// On NTFS volumes, this function removes the encryption attribute from the file,
    /// causing the file to be decrypted.  See the MSDN documentation for full details on
    /// EFS (Encrypted File System).
    /// </summary>
    /// <remarks>
    /// Requires Win2K and above, plus a valid EFS certificate (which is beyond the scope
    /// of this function description).
    /// </remarks>
    /// <param name="databaseFileName">The file to decrypt</param>
    [Obsolete("Call ChangePassword(null) on an open connection to decrypt an encrypted database file.")]
    static public void DecryptFile(string databaseFileName)
    {
      int n = UnsafeNativeMethods.sqlite3_decryptfile(databaseFileName);
      if (n == 0) throw new System.ComponentModel.Win32Exception();
    }

    /// <summary>
    /// Returns true if the file is encrypted, or false otherwise.
    /// </summary>
    /// <remarks>
    /// Requires Win2K and above, plus a valid EFS certificate (which is beyond the scope
    /// of this function description).
    /// </remarks>
    /// <param name="databaseFileName">The file to check</param>
    /// <returns>true if the file is encrypted</returns>
    [Obsolete("EFS file encryption will be removed from future versions of this library")]
    static public bool IsEncrypted(string databaseFileName)
    {
      int status;
      int n = UnsafeNativeMethods.sqlite3_encryptedstatus(databaseFileName, out status);
      if (n == 0) throw new System.ComponentModel.Win32Exception();

      return (status == 1);
    }

    /// <summary>
    /// Raises the state change event when the state of the connection changes
    /// </summary>
    /// <param name="newState">The new state.  If it is different from the previous state, an event is raised.</param>
    internal void OnStateChange(ConnectionState newState)
    {
      ConnectionState oldState = _connectionState;
      _connectionState = newState;


      if (StateChange != null && oldState != newState)
      {
        StateChangeEventArgs e = new StateChangeEventArgs(oldState, newState);
        StateChange(this, e);
      }

    }

    /// <summary>
    /// Creates a new SQLiteTransaction if one isn't already active on the connection.
    /// </summary>
    /// <param name="isolationLevel">SQLite doesn't support varying isolation levels, so this parameter is ignored.</param>
    /// <param name="deferredLock">When TRUE, SQLite defers obtaining a write lock until a write operation is requested.
    /// When FALSE, a writelock is obtained immediately.  The default is TRUE, but in a multi-threaded multi-writer 
    /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock.</param>
    /// <returns>Returns a SQLiteTransaction object.</returns>
    public SQLiteTransaction BeginTransaction(IsolationLevel isolationLevel, bool deferredLock)
    {
      return BeginTransaction(true);
    }

    /// <summary>
    /// Creates a new SQLiteTransaction if one isn't already active on the connection.
    /// </summary>
    /// <param name="deferredLock">When TRUE, SQLite defers obtaining a write lock until a write operation is requested.
    /// When FALSE, a writelock is obtained immediately.  The default is TRUE, but in a multi-threaded multi-writer 
    /// environment, one may instead choose to lock the database immediately to avoid any possible writer deadlock.</param>
    /// <returns>Returns a SQLiteTransaction object.</returns>
    public SQLiteTransaction BeginTransaction(bool deferredLock)
    {
      if (_connectionState != ConnectionState.Open)
        throw new InvalidOperationException();

      if (_activeTransaction != null)
        throw new ArgumentException("Transaction already pending");

      _activeTransaction = new SQLiteTransaction(this, deferredLock);
      return _activeTransaction;
    }

    /// <summary>
    /// Creates a new SQLiteTransaction if one isn't already active on the connection.
    /// </summary>
    /// <param name="isolationLevel">SQLite doesn't support varying isolation levels, so this parameter is ignored.</param>
    /// <returns>Returns a SQLiteTransaction object.</returns>
    public new SQLiteTransaction BeginTransaction(IsolationLevel isolationLevel)
    {
      return BeginTransaction(true);
    }

    /// <summary>
    /// Creates a new SQLiteTransaction if one isn't already active on the connection.
    /// </summary>
    /// <returns>Returns a SQLiteTransaction object.</returns>
    public new SQLiteTransaction BeginTransaction()
    {
      return BeginTransaction(true);
    }

    /// <summary>
    /// Forwards to the local BeginTransaction() function
    /// </summary>
    /// <param name="isolationLevel"></param>
    /// <returns></returns>
    protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)
    {
      return BeginTransaction(isolationLevel, true);
    }

    /// <summary>
    /// Not implemented
    /// </summary>
    /// <param name="databaseName"></param>
    public override void ChangeDatabase(string databaseName)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// When the database connection is closed, all commands linked to this connection are automatically reset.
    /// </summary>
    public override void Close()
    {
      if (_sql != null)
      {
        int x = _commandList.Count;
        for (int n = 0; n < x; n++)
        {
          _commandList[n].ClearCommands();
        }
        _sql.Close();
      }

      _sql = null;







|
|

|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





>





>






<
<
<

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







|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















<
|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
























































































214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231



232
233












234
235
236
237
238
239
240
241
242
243
244





























245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268
      if (connectionString != null)
        ConnectionString = connectionString;
    }

    /// <summary>
    /// Disposes of the SQLiteConnection, closing it if it is active.
    /// </summary>
    /// <param name="bDisposing">True if the connection is being explicitly closed.</param>
    protected override void Dispose(bool bDisposing)
    {
      base.Dispose(bDisposing);
      Close();
    }

























































































    internal void OnStateChange(ConnectionState newState)
    {
      ConnectionState oldState = _connectionState;
      _connectionState = newState;

#if !PLATFORM_COMPACTFRAMEWORK
      if (StateChange != null && oldState != newState)
      {
        StateChangeEventArgs e = new StateChangeEventArgs(oldState, newState);
        StateChange(this, e);
      }
#endif
    }

    /// <summary>
    /// Creates a new SQLiteTransaction if one isn't already active on the connection.
    /// </summary>
    /// <param name="isolationLevel">SQLite doesn't support varying isolation levels, so this parameter is ignored.</param>



    /// <returns>Returns a SQLiteTransaction object.</returns>
    protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel)












    {
      if (_connectionState != ConnectionState.Open)
        throw new InvalidOperationException();

      if (_activeTransaction != null)
        throw new ArgumentException("Transaction already pending");

      _activeTransaction = new SQLiteTransaction(this);
      return _activeTransaction;
    }






























    /// <summary>
    /// Not implemented
    /// </summary>
    /// <param name="databaseName"></param>
    public override void ChangeDatabase(string databaseName)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// When the database connection is closed, all commands linked to this connection are automatically reset.
    /// </summary>
    public override void Close()
    {
      if (_sql != null)
      {

        for (int n = 0; n < _commandList.Count; n++)
        {
          _commandList[n].ClearCommands();
        }
        _sql.Close();
      }

      _sql = null;
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
    /// <description>N</description>
    /// <description>Normal</description>
    /// </item>
    /// <item>
    /// <description>Page Size</description>
    /// <description>{size in bytes}</description>
    /// <description>N</description>
    /// <description>1024</description>
    /// </item>
    /// <item>
    /// <description>Password</description>
    /// <description>{password}</description>
    /// <description>N</description>
    /// <description></description>
    /// </item>
    /// </list>
    /// </remarks>
    public override string ConnectionString
    {
      get
      {







<
<
<
<
<
|
<







317
318
319
320
321
322
323





324

325
326
327
328
329
330
331
    /// <description>N</description>
    /// <description>Normal</description>
    /// </item>
    /// <item>
    /// <description>Page Size</description>
    /// <description>{size in bytes}</description>
    /// <description>N</description>





    /// <description>4096</description>

    /// </item>
    /// </list>
    /// </remarks>
    public override string ConnectionString
    {
      get
      {
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543

544
545
546
547
548
549
550
551
552
553
554
555
556
557


558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
      }
    }

    /// <summary>
    /// Create a new SQLiteCommand and associate it with this connection.
    /// </summary>
    /// <returns>Returns an instantiated SQLiteCommand object already assigned to this connection.</returns>
    public new SQLiteCommand CreateCommand()
    {
      return new SQLiteCommand(this);
    }

    /// <summary>
    /// Forwards to the local CreateCommand() function
    /// </summary>
    /// <returns></returns>
    protected override DbCommand CreateDbCommand()
    {
      return CreateCommand();
    }

    /// <summary>
    /// Returns the filename without extension or path
    /// </summary>
    public override string DataSource
    {
      get 
      {
        return _dataSource;
      }
    }

    /// <summary>
    /// Returns an empty string
    /// </summary>
    public override string Database
    {
      get
      {
        return "main";
      }
    }

    /// <summary>
    /// Parses the connection string into component parts
    /// </summary>
    /// <returns>An array of key-value pairs representing each parameter of the connection string</returns>
    internal KeyValuePair<string, string>[] ParseConnectionString()
    {
      string s = _connectionString;
      int n;

      List<KeyValuePair<string, string>> ls = new List<KeyValuePair<string, string>>();

      // First split into semi-colon delimited values.  The Split() function of SQLiteBase accounts for and properly
      // skips semi-colons in quoted strings
      string[] arParts = SQLiteConvert.Split(s, ';');
      string[] arPiece;

      int x = arParts.Length;
      // For each semi-colon piece, split into key and value pairs by the presence of the = sign
      for (n = 0; n < x; n++)
      {
        arPiece = SQLiteConvert.Split(arParts[n], '=');
        if (arPiece.Length == 2)
        {


          ls.Add(new KeyValuePair<string, string>(arPiece[0], arPiece[1]));
        }
        else throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format for parameter \"{0}\"", (arPiece.Length > 0) ? arPiece[0] : "null"));
      }
      KeyValuePair<string, string>[] ar = new KeyValuePair<string, string>[ls.Count];
      ls.CopyTo(ar, 0);

      // Return the array of key-value pairs
      return ar;
    }

    /// <summary>
    /// Looks for a key in the array of key/values of the parameter string.  If not found, return the specified default value
    /// </summary>
    /// <param name="opts">The Key/Value pair array to look in</param>
    /// <param name="key">The key to find</param>
    /// <param name="defValue">The default value to return if the key is not found</param>
    /// <returns>The value corresponding to the specified key, or the default value if not found.</returns>
    static internal string FindKey(KeyValuePair<string, string>[] opts, string key, string defValue)
    {
      int x = opts.Length;
      for (int n = 0; n < x; n++)
      {
        if (String.Compare(opts[n].Key, key, true, CultureInfo.InvariantCulture) == 0)
        {
          return opts[n].Value;
        }
      }
      return defValue;
    }

    /// <summary>
    /// Opens the connection using the parameters found in the <see cref="ConnectionString">ConnectionString</see>
    /// </summary>
    public override void Open()
    {
      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException();

      Close();

      KeyValuePair<string, string>[] opts = ParseConnectionString();

      if (Convert.ToInt32(FindKey(opts, "Version", "3"), CultureInfo.InvariantCulture) != 3)
        throw new NotSupportedException("Only SQLite Version 3 is supported at this time");

      string strFile = FindKey(opts, "Data Source", "");

      if (String.IsNullOrEmpty(strFile))
        throw new ArgumentException("Data Source cannot be empty.  Use :MEMORY: to open an in-memory database");

      try
      {

        bool bUTF16 = (Convert.ToBoolean(FindKey(opts, "UseUTF16Encoding", "False"), CultureInfo.InvariantCulture) == true);
        SQLiteDateFormats dateFormat = String.Compare(FindKey(opts, "DateTimeFormat", "ISO8601"), "ticks", true, CultureInfo.InvariantCulture) == 0 ? SQLiteDateFormats.Ticks : SQLiteDateFormats.ISO8601;

        if (bUTF16) // SQLite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16()
          _sql = new SQLite3_UTF16(dateFormat);
        else
          _sql = new SQLite3(dateFormat);
        
        _sql.Open(strFile);

        string password = FindKey(opts, "Password", null);

        if (String.IsNullOrEmpty(password) == false)
          _sql.SetPassword(String.IsNullOrEmpty(password) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(password));

        _dataSource = System.IO.Path.GetFileNameWithoutExtension(strFile);

        _sql.Execute(String.Format(CultureInfo.InvariantCulture, "PRAGMA Synchronous={0}", FindKey(opts, "Synchronous", "Normal")));
        _sql.Execute(String.Format(CultureInfo.InvariantCulture, "PRAGMA Cache_Size={0}", FindKey(opts, "Cache Size", "2000")));
        if (String.Compare(":MEMORY:", strFile, true, CultureInfo.InvariantCulture) == 0)
          _sql.Execute(String.Format(CultureInfo.InvariantCulture, "PRAGMA Page_Size={0}", FindKey(opts, "Page Size", "1024")));
      }
      catch (SQLiteException)
      {
        OnStateChange(ConnectionState.Broken);
        throw;
      }
      OnStateChange(ConnectionState.Open);
    }

    /// <summary>
    /// Returns the version of the underlying SQLite database engine
    /// </summary>







|





<
<
<
<
<
<
<
|
<
<



<
<
|
<



|



<
<
|
<










>







<

|




>
>
|

<















|

<
|

|



















|
|
<
<
<
<
<



>
|
<

|
|

|
|


|
|
|
<
|
<

|
|
|
|

|


|







343
344
345
346
347
348
349
350
351
352
353
354
355







356


357
358
359


360

361
362
363
364
365
366
367


368

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

387
388
389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413

414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437





438
439
440
441
442

443
444
445
446
447
448
449
450
451
452
453

454

455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
      }
    }

    /// <summary>
    /// Create a new SQLiteCommand and associate it with this connection.
    /// </summary>
    /// <returns>Returns an instantiated SQLiteCommand object already assigned to this connection.</returns>
    protected override DbCommand CreateDbCommand()
    {
      return new SQLiteCommand(this);
    }

    /// <summary>







    /// Not implemented.  Returns null.


    /// </summary>
    public override string DataSource
    {


      get { return null; }

    }

    /// <summary>
    /// Not implemented.  Returns null.
    /// </summary>
    public override string Database
    {


      get { return null; }

    }

    /// <summary>
    /// Parses the connection string into component parts
    /// </summary>
    /// <returns>An array of key-value pairs representing each parameter of the connection string</returns>
    internal KeyValuePair<string, string>[] ParseConnectionString()
    {
      string s = _connectionString;
      int n;
      KeyValuePair<string, string> kv;
      List<KeyValuePair<string, string>> ls = new List<KeyValuePair<string, string>>();

      // First split into semi-colon delimited values.  The Split() function of SQLiteBase accounts for and properly
      // skips semi-colons in quoted strings
      string[] arParts = SQLiteConvert.Split(s, ';');
      string[] arPiece;


      // For each semi-colon piece, split into key and value pairs by the presence of the = sign
      for (n = 0; n < arParts.Length; n++)
      {
        arPiece = SQLiteConvert.Split(arParts[n], '=');
        if (arPiece.Length == 2)
        {
          kv.Key = arPiece[0];
          kv.Value = arPiece[1];
          ls.Add(kv);
        }

      }
      KeyValuePair<string, string>[] ar = new KeyValuePair<string, string>[ls.Count];
      ls.CopyTo(ar, 0);

      // Return the array of key-value pairs
      return ar;
    }

    /// <summary>
    /// Looks for a key in the array of key/values of the parameter string.  If not found, return the specified default value
    /// </summary>
    /// <param name="opts">The Key/Value pair array to look in</param>
    /// <param name="key">The key to find</param>
    /// <param name="defValue">The default value to return if the key is not found</param>
    /// <returns>The value corresponding to the specified key, or the default value if not found.</returns>
    internal string FindKey(KeyValuePair<string, string>[] opts, string key, string defValue)
    {

      for (int n = 0; n < opts.Length; n++)
      {
        if (String.Compare(opts[n].Key, key, true) == 0)
        {
          return opts[n].Value;
        }
      }
      return defValue;
    }

    /// <summary>
    /// Opens the connection using the parameters found in the <see cref="ConnectionString">ConnectionString</see>
    /// </summary>
    public override void Open()
    {
      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException();

      Close();

      KeyValuePair<string, string>[] opts = ParseConnectionString();

      if (Convert.ToInt32(FindKey(opts, "Version", "3")) != 3)
        throw new NotImplementedException("Only SQLite Version 3 is supported at this time");






      try
      {
        string strFile = FindKey(opts, "Data Source", "");
        bool bUTF16 = (Convert.ToBoolean(FindKey(opts, "UseUTF16Encoding", "False")) == true);


        if (bUTF16)
          _sql = new SQLite3_UTF16(String.Compare(FindKey(opts, "DateTimeFormat", "ISO8601"), "TICKS") == 0 ? DateTimeFormat.Ticks : DateTimeFormat.ISO8601);
        else
          _sql = new SQLite3(String.Compare(FindKey(opts, "DateTimeFormat", "ISO8601"), "TICKS") == 0 ? DateTimeFormat.Ticks : DateTimeFormat.ISO8601);

        _sql.Open(strFile);

        if (bUTF16 == true)
          _sql.Execute("PRAGMA encoding = 'UTF-16'");
        else

          _sql.Execute("PRAGMA encoding = 'UTF-8'");


        _sql.Execute(String.Format("PRAGMA Synchronous={0}", FindKey(opts, "Synchronous", "Normal")));
        _sql.Execute(String.Format("PRAGMA Cache_Size={0}", FindKey(opts, "Cache Size", "2000")));
        if (String.Compare(strFile, ":MEMORY:", true) != 0)
          _sql.Execute(String.Format("PRAGMA Page_Size={0}", FindKey(opts, "Page Size", "1024")));
      }
      catch (SQLiteException e)
      {
        OnStateChange(ConnectionState.Broken);
        throw (e);
      }
      OnStateChange(ConnectionState.Open);
    }

    /// <summary>
    /// Returns the version of the underlying SQLite database engine
    /// </summary>
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
    }

    /// <summary>
    /// Returns the state of the connection.
    /// </summary>
    public override ConnectionState State
    {
      get
      {
        return _connectionState;
      }
    }

    /// <summary>
    /// Change the password (or assign a password) to an open database.
    /// </summary>
    /// <remarks>
    /// No readers or writers may be active for this process.  The database must already be open
    /// and if it already was password protected, the existing password must already have been supplied.
    /// </remarks>
    /// <param name="newPassword">The new password to assign to the database</param>
    public void ChangePassword(string newPassword)
    {
      ChangePassword(String.IsNullOrEmpty(newPassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(newPassword));
    }

    /// <summary>
    /// Change the password (or assign a password) to an open database.
    /// </summary>
    /// <remarks>
    /// No readers or writers may be active for this process.  The database must already be open
    /// and if it already was password protected, the existing password must already have been supplied.
    /// </remarks>
    /// <param name="newPassword">The new password to assign to the database</param>
    public void ChangePassword(byte[] newPassword)
    {
      if (_connectionState != ConnectionState.Open)
        throw new InvalidOperationException();

      _sql.ChangePassword(newPassword);
    }

    /// <summary>
    /// Sets the password for a password-protected database.  A password-protected database is
    /// unusable for any operation until the password has been set.
    /// </summary>
    /// <param name="databasePassword">The password for the database</param>
    public void SetPassword(string databasePassword)
    {
      SetPassword(String.IsNullOrEmpty(databasePassword) ? null : System.Text.UTF8Encoding.UTF8.GetBytes(databasePassword));
    }

    /// <summary>
    /// Sets the password for a password-protected database.  A password-protected database is
    /// unusable for any operation until the password has been set.
    /// </summary>
    /// <param name="databasePassword">The password for the database</param>
    public void SetPassword(byte[] databasePassword)
    {
      if (_connectionState != ConnectionState.Open)
        throw new InvalidOperationException();

      _sql.SetPassword(databasePassword);
    }

    ///<overloads>
    /// The following commands are used to extract schema information out of the database.  Valid schema types are:
    /// <list type="bullet">
    /// <item>
    /// <description>MetaDataCollections</description>







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







481
482
483
484
485
486
487


488





















































489
490
491
492
493
494
495
    }

    /// <summary>
    /// Returns the state of the connection.
    /// </summary>
    public override ConnectionState State
    {


      get { return _connectionState; }





















































    }

    ///<overloads>
    /// The following commands are used to extract schema information out of the database.  Valid schema types are:
    /// <list type="bullet">
    /// <item>
    /// <description>MetaDataCollections</description>
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815

816
817
818
819
820
821
822
823



824



825



826















827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
        throw new InvalidOperationException();

      string[] parms = new string[5];

      restrictionValues.CopyTo(parms, 0);

      if (restrictionValues == null) restrictionValues = new string[0];
      switch (collectionName.ToUpper(CultureInfo.InvariantCulture))
      {
        case "METADATACOLLECTIONS":
          return Schema_MetaDataCollections();
        case "DATASOURCEINFORMATION":
          return Schema_DataSourceInformation();
        //case "RESERVEDWORDS":
        //  return Schema_ReservedWords();
        case "DATATYPES":
          return Schema_DataTypes();
        case "COLUMNS":
          return Schema_Columns(parms[0], parms[2], parms[3]);
        case "INDEXES":
          return Schema_Indexes(parms[0], parms[2], parms[4]);
        case "INDEXCOLUMNS":
          return Schema_IndexColumns(parms[0], parms[2], parms[3], parms[4]);
        case "TABLES":
          return Schema_Tables(parms[0], parms[2], parms[3]);
        case "VIEWS":
          return Schema_Views(parms[0], parms[2]);
        case "VIEWCOLUMNS":
          return Schema_ViewColumns(parms[0], parms[2], parms[3]);
        case "FOREIGNKEYS":
          return Schema_ForeignKeys(parms[0], parms[2], parms[3]);
        case "CATALOGS":
          return Schema_Catalogs(parms[0]);
      }
      throw new NotSupportedException();
    }

    /// <summary>
    /// Builds a MetaDataCollections schema datatable
    /// </summary>
    /// <returns>DataTable</returns>
    private static DataTable Schema_MetaDataCollections()
    {
      DataTable tbl = new DataTable("MetaDataCollections");


      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("CollectionName", typeof(string));
      tbl.Columns.Add("NumberOfRestrictions", typeof(int));
      tbl.Columns.Add("NumberOfIdentifierParts", typeof(int));

      tbl.BeginLoadData();




      IO.StringReader reader = new IO.StringReader(SR.MetaDataCollections);



      tbl.ReadXml(reader);



      reader.Close();
















      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Builds a DataSourceInformation datatable
    /// </summary>
    /// <returns>DataTable</returns>
    private DataTable Schema_DataSourceInformation()
    {
      DataTable tbl = new DataTable("DataSourceInformation");
      DataRow row;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("CompositeIdentifierSeparatorPattern", typeof(string));
      tbl.Columns.Add("DataSourceProductName", typeof(string));
      tbl.Columns.Add("DataSourceProductVersion", typeof(string));
      tbl.Columns.Add("DataSourceProductVersionNormalized", typeof(string));
      tbl.Columns.Add("GroupByBehavior", typeof(int));
      tbl.Columns.Add("IdentifierPattern", typeof(string));
      tbl.Columns.Add("IdentifierCase", typeof(int));







|





<
<
<
<




<
<




<
<
<
<



|


<
<
<
<
|


>

<






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







<
<
<
<





<







545
546
547
548
549
550
551
552
553
554
555
556
557




558
559
560
561


562
563
564
565




566
567
568
569
570
571




572
573
574
575
576

577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616




617
618
619
620
621

622
623
624
625
626
627
628
        throw new InvalidOperationException();

      string[] parms = new string[5];

      restrictionValues.CopyTo(parms, 0);

      if (restrictionValues == null) restrictionValues = new string[0];
      switch (collectionName.ToUpper())
      {
        case "METADATACOLLECTIONS":
          return Schema_MetaDataCollections();
        case "DATASOURCEINFORMATION":
          return Schema_DataSourceInformation();




        case "COLUMNS":
          return Schema_Columns(parms[0], parms[2], parms[3]);
        case "INDEXES":
          return Schema_Indexes(parms[0], parms[2], parms[4]);


        case "TABLES":
          return Schema_Tables(parms[0], parms[2], parms[3]);
        case "VIEWS":
          return Schema_Views(parms[0], parms[2]);




        case "CATALOGS":
          return Schema_Catalogs(parms[0]);
      }
      return null;
    }





    private DataTable Schema_MetaDataCollections()
    {
      DataTable tbl = new DataTable("MetaDataCollections");
      DataRow row;


      tbl.Columns.Add("CollectionName", typeof(string));
      tbl.Columns.Add("NumberOfRestrictions", typeof(int));
      tbl.Columns.Add("NumberOfIdentifierParts", typeof(int));

      tbl.BeginLoadData();

      row = tbl.NewRow();
      row.ItemArray = new object[] { "MetaDataCollections", 0, 0 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "DataSourceInformation", 0, 0 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "Catalogs", 1, 1 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "Columns", 4, 4 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "Indexes", 5, 4 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "Tables", 4, 3 };
      tbl.Rows.Add(row);

      row = tbl.NewRow();
      row.ItemArray = new object[] { "Views", 3, 3 };
      tbl.Rows.Add(row);

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }





    private DataTable Schema_DataSourceInformation()
    {
      DataTable tbl = new DataTable("DataSourceInformation");
      DataRow row;


      tbl.Columns.Add("CompositeIdentifierSeparatorPattern", typeof(string));
      tbl.Columns.Add("DataSourceProductName", typeof(string));
      tbl.Columns.Add("DataSourceProductVersion", typeof(string));
      tbl.Columns.Add("DataSourceProductVersionNormalized", typeof(string));
      tbl.Columns.Add("GroupByBehavior", typeof(int));
      tbl.Columns.Add("IdentifierPattern", typeof(string));
      tbl.Columns.Add("IdentifierCase", typeof(int));
861
862
863
864
865
866
867
868
869
870
871
872


873
874
875
876
877

878
879
880
881
882
883

884


885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070

1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114





1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582

      tbl.BeginLoadData();

      // TODO: Fixup the regular expressions to support only the SQLite stuff, they were originally cloned
      // from JET's DataSourceInformation return result.
      row = tbl.NewRow();
      row.ItemArray = new object[] {
        null,
        "SQLite",
        _sql.Version,
        _sql.Version,
        3,


        null,
        2,
        false,
        "{0}",
        null,

        0,
        null,
        @"(([^\[]|\]\])*)",
        2,
        ";",
        @"'(([^']|'')*)'",

        null


      };
      tbl.Rows.Add(row);

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Build a Columns schema
    /// </summary>
    /// <param name="strCatalog">The catalog (attached database) to query, can be null</param>
    /// <param name="strTable">The table to retrieve schema information for, must not be null</param>
    /// <param name="strColumn">The column to retrieve schema information for, can be null</param>
    /// <returns>DataTable</returns>
    private DataTable Schema_Columns(string strCatalog, string strTable, string strColumn)
    {
      DataTable tbl = new DataTable("Columns");
      DataRow row;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));
      tbl.Columns.Add("COLUMN_PROPID", typeof(long));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));
      tbl.Columns.Add("COLUMN_HASDEFAULT", typeof(bool));
      tbl.Columns.Add("COLUMN_DEFAULT", typeof(string));
      tbl.Columns.Add("COLUMN_FLAGS", typeof(long));
      tbl.Columns.Add("IS_NULLABLE", typeof(bool));
      tbl.Columns.Add("DATA_TYPE", typeof(string));
      tbl.Columns.Add("TYPE_GUID", typeof(Guid));
      tbl.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(int));
      tbl.Columns.Add("CHARACTER_OCTET_LENGTH", typeof(int));
      tbl.Columns.Add("NUMERIC_PRECISION", typeof(int));
      tbl.Columns.Add("NUMERIC_SCALE", typeof(int));
      tbl.Columns.Add("DATETIME_PRECISION", typeof(long));
      tbl.Columns.Add("CHARACTER_SET_CATALOG", typeof(string));
      tbl.Columns.Add("CHARACTER_SET_SCHEMA", typeof(string));
      tbl.Columns.Add("CHARACTER_SET_NAME", typeof(string));
      tbl.Columns.Add("COLLATION_CATALOG", typeof(string));
      tbl.Columns.Add("COLLATION_SCHEMA", typeof(string));
      tbl.Columns.Add("COLLATION_NAME", typeof(string));
      tbl.Columns.Add("DOMAIN_CATALOG", typeof(string));
      tbl.Columns.Add("DOMAIN_NAME", typeof(string));
      tbl.Columns.Add("DESCRIPTION", typeof(string));

      tbl.BeginLoadData();

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table' OR [type] LIKE 'view'", strCatalog), this))
      {
        using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
        {
          while (rdTables.Read())
          {
            if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), true, CultureInfo.InvariantCulture) == 0)
            {
              using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this))
              {
                using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly))
                {
                  using (DataTable tblSchema = rd.GetSchemaTable())
                  {
                    foreach (DataRow schemaRow in tblSchema.Rows)
                    {
                      if (String.Compare(schemaRow[SchemaTableColumn.ColumnName].ToString(), strColumn, true, CultureInfo.InvariantCulture) == 0
                        || strColumn == null)
                      {
                        row = tbl.NewRow();

                        row["TABLE_NAME"] = rdTables.GetString(2);
                        row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.ColumnName];
                        row["TABLE_CATALOG"] = strCatalog;
                        row["ORDINAL_POSITION"] = schemaRow[SchemaTableColumn.ColumnOrdinal];
                        row["COLUMN_HASDEFAULT"] = (schemaRow[SchemaTableOptionalColumn.DefaultValue] != DBNull.Value);
                        row["COLUMN_DEFAULT"] = schemaRow[SchemaTableOptionalColumn.DefaultValue];
                        row["IS_NULLABLE"] = schemaRow[SchemaTableColumn.AllowDBNull];
                        row["DATA_TYPE"] = SQLiteConvert.DbTypeToType((DbType)schemaRow[SchemaTableColumn.ProviderType]).ToString();
                        row["CHARACTER_MAXIMUM_LENGTH"] = schemaRow[SchemaTableColumn.ColumnSize];
                        row["TABLE_SCHEMA"] = schemaRow[SchemaTableColumn.BaseSchemaName];

                        tbl.Rows.Add(row);
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Returns index information for the given database and catalog
    /// </summary>
    /// <param name="strCatalog">The catalog (attached database) to query, can be null</param>
    /// <param name="strIndex">The name of the index to retrieve information for, can be null</param>
    /// <param name="strTable">The table to retrieve index information for, can be null</param>
    /// <returns>DataTable</returns>
    private DataTable Schema_Indexes(string strCatalog, string strTable, string strIndex)
    {
      DataTable tbl = new DataTable("Indexes");
      DataRow row;
      DataTable tblSchema;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("INDEX_CATALOG", typeof(string));
      tbl.Columns.Add("INDEX_SCHEMA", typeof(string));
      tbl.Columns.Add("INDEX_NAME", typeof(string));
      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));
      tbl.Columns.Add("UNIQUE", typeof(bool));
      tbl.Columns.Add("CLUSTERED", typeof(bool));
      tbl.Columns.Add("TYPE", typeof(int));
      tbl.Columns.Add("FILL_FACTOR", typeof(int));
      tbl.Columns.Add("INITIAL_SIZE", typeof(int));
      tbl.Columns.Add("NULLS", typeof(int));
      tbl.Columns.Add("SORT_BOOKMARKS", typeof(bool));
      tbl.Columns.Add("AUTO_UPDATE", typeof(bool));
      tbl.Columns.Add("NULL_COLLATION", typeof(int));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));
      tbl.Columns.Add("COLUMN_PROPID", typeof(long));
      tbl.Columns.Add("COLLATION", typeof(short));
      tbl.Columns.Add("CARDINALITY", typeof(Decimal));
      tbl.Columns.Add("PAGES", typeof(int));
      tbl.Columns.Add("FILTER_CONDITION", typeof(string));
      tbl.Columns.Add("INTEGRATED", typeof(bool));

      tbl.BeginLoadData();

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this))
      {
        using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
        {
          while (rdTables.Read())
          {
            if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0)
            {
              using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}]", rdTables.GetString(2)), this))
              {
                using (SQLiteDataReader rdTable = cmdTable.ExecuteReader(CommandBehavior.SchemaOnly))
                {
                  tblSchema = rdTable.GetSchemaTable();
                  foreach (DataRow schemaRow in tblSchema.Rows)
                  {
                    if (Convert.ToBoolean(schemaRow[SchemaTableColumn.IsKey], CultureInfo.CurrentCulture) == true)
                    {
                      row = tbl.NewRow();
                      row["TABLE_CATALOG"] = strCatalog;
                      row["TABLE_NAME"] = rdTables.GetString(2);
                      row["INDEX_CATALOG"] = strCatalog;
                      row["INDEX_NAME"] = String.Format(CultureInfo.InvariantCulture, "PK_{0}_{1}", rdTables.GetString(2), schemaRow[SchemaTableColumn.BaseColumnName]);
                      row["PRIMARY_KEY"] = true;
                      row["UNIQUE"] = true;
                      if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, row["INDEX_NAME"].ToString(), true, CultureInfo.InvariantCulture) == 0)
                      {
                        tbl.Rows.Add(row);
                      }
                    }
                  }
                }
              }
              using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_list([{1}])", strCatalog, rdTables.GetString(2)), this))
              {
                using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
                {
                  while (rd.Read())
                  {
                    if (String.Compare(rd.GetString(1), strIndex, true, CultureInfo.InvariantCulture) == 0

                    || strIndex == null)
                    {
                      row = tbl.NewRow();

                      row["TABLE_CATALOG"] = strCatalog;
                      row["TABLE_NAME"] = rdTables.GetString(2);
                      row["INDEX_CATALOG"] = strCatalog;
                      row["INDEX_NAME"] = rd.GetString(1);
                      row["UNIQUE"] = rd.GetBoolean(2);

                      tbl.Rows.Add(row);
                    }
                  }
                }
              }
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Retrieves table schema information for the database and catalog
    /// </summary>
    /// <param name="strCatalog">The catalog (attached database) to retrieve tables on</param>
    /// <param name="strTable">The table to retrieve, can be null</param>
    /// <param name="strType">The table type, can be null</param>
    /// <returns>DataTable</returns>
    private DataTable Schema_Tables(string strCatalog, string strTable, string strType)
    {
      DataTable tbl = new DataTable("Tables");
      DataRow row;
      string strItem;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("TABLE_TYPE", typeof(string));






      tbl.BeginLoadData();

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] NOT LIKE 'index'", strCatalog), this))
      {
        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            strItem = rd.GetString(0);
            if (String.Compare(rd.GetString(2), 0, "SQLITE_", 0, 7, true, CultureInfo.InvariantCulture) == 0)
              strItem = "SYSTEM_TABLE";

            if (String.Compare(strType, strItem, true, CultureInfo.InvariantCulture) == 0
              || strType == null)
            {
              if (String.Compare(rd.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0
                || strTable == null)
              {
                row = tbl.NewRow();

                row["TABLE_CATALOG"] = strCatalog;
                row["TABLE_NAME"] = rd.GetString(2);
                row["TABLE_TYPE"] = strItem;

                tbl.Rows.Add(row);
              }
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Retrieves view schema information for the database
    /// </summary>
    /// <param name="strCatalog">The catalog (attached database) to retrieve views on</param>
    /// <param name="strView">The view name, can be null</param>
    /// <returns>DataTable</returns>
    private DataTable Schema_Views(string strCatalog, string strView)
    {
      DataTable tbl = new DataTable("Views");
      DataRow row;
      string strItem;
      int nPos;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("VIEW_DEFINITION", typeof(string));
      tbl.Columns.Add("CHECK_OPTION", typeof(bool));
      tbl.Columns.Add("IS_UPDATABLE", typeof(bool));
      tbl.Columns.Add("DESCRIPTION", typeof(string));
      tbl.Columns.Add("DATE_CREATED", typeof(DateTime));
      tbl.Columns.Add("DATE_MODIFIED", typeof(DateTime));

      tbl.BeginLoadData();

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'view'", strCatalog), this))
      {
        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            if (String.Compare(rd.GetString(1), strView, true, CultureInfo.InvariantCulture) == 0
              || String.IsNullOrEmpty(strView))
            {
              strItem = rd.GetString(4);
              nPos = Globalization.CultureInfo.InvariantCulture.CompareInfo.IndexOf(strItem, " AS ", CompareOptions.IgnoreCase);
              if (nPos > -1)
              {
                strItem = strItem.Substring(nPos + 4).Trim();
                row = tbl.NewRow();

                row["TABLE_CATALOG"] = strCatalog;
                row["TABLE_NAME"] = rd.GetString(2);
                row["IS_UPDATABLE"] = false;
                row["VIEW_DEFINITION"] = strItem;

                tbl.Rows.Add(row);
              }
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Retrieves catalog (attached databases) schema information for the database
    /// </summary>
    /// <param name="strCatalog">The catalog to retrieve, can be null</param>
    /// <returns>DataTable</returns>
    private DataTable Schema_Catalogs(string strCatalog)
    {
      DataTable tbl = new DataTable("Catalogs");
      DataRow row;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("CATALOG_NAME", typeof(string));
      tbl.Columns.Add("DESCRIPTION", typeof(string));

      tbl.BeginLoadData();

      using (SQLiteCommand cmd = new SQLiteCommand("PRAGMA database_list", this))
      {
        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            if (String.Compare(rd.GetString(1), strCatalog, true, CultureInfo.InvariantCulture) == 0
              || strCatalog == null)
            {
              row = tbl.NewRow();

              row["CATALOG_NAME"] = rd.GetString(1);
              row["DESCRIPTION"] = rd.GetString(2);

              tbl.Rows.Add(row);
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    private DataTable Schema_DataTypes()
    {
      DataTable tbl = new DataTable("DataTypes");

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("TypeName", typeof(String));
      tbl.Columns.Add("ProviderDbType", typeof(int));
      tbl.Columns.Add("ColumnSize", typeof(long));
      tbl.Columns.Add("CreateFormat", typeof(String));
      tbl.Columns.Add("CreateParameters", typeof(String));
      tbl.Columns.Add("DataType", typeof(String));
      tbl.Columns.Add("IsAutoIncrementable", typeof(bool));
      tbl.Columns.Add("IsBestMatch", typeof(bool));
      tbl.Columns.Add("IsCaseSensitive", typeof(bool));
      tbl.Columns.Add("IsFixedLength", typeof(bool));
      tbl.Columns.Add("IsFixedPrecisionScale", typeof(bool));
      tbl.Columns.Add("IsLong", typeof(bool));
      tbl.Columns.Add("IsNullable", typeof(bool));
      tbl.Columns.Add("IsSearchable", typeof(bool));
      tbl.Columns.Add("IsSearchableWithLike", typeof(bool));
      tbl.Columns.Add("IsLiteralSupported", typeof(bool));
      tbl.Columns.Add("LiteralPrefix", typeof(String));
      tbl.Columns.Add("LiteralSuffix", typeof(String));
      tbl.Columns.Add("IsUnsigned", typeof(bool));
      tbl.Columns.Add("MaximumScale", typeof(short));
      tbl.Columns.Add("MinimumScale", typeof(short));
      tbl.Columns.Add("IsConcurrencyType", typeof(bool));

      tbl.BeginLoadData();

      IO.StringReader reader = new IO.StringReader(SR.DataTypes);
      tbl.ReadXml(reader);
      reader.Close();

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Returns the base column information for indexes in a database
    /// </summary>
    /// <param name="strCatalog">The catalog to retrieve indexes for (can be null)</param>
    /// <param name="strTable">The table to restrict index information by (can be null)</param>
    /// <param name="strIndex">The index to restrict index information by (can be null)</param>
    /// <param name="strColumn">The source column to restrict index information by (can be null)</param>
    /// <returns>A DataTable containing the results</returns>
    private DataTable Schema_IndexColumns(string strCatalog, string strTable, string strIndex, string strColumn)
    {
      DataTable tbl = new DataTable("IndexColumns");
      DataRow row;
      DataTable tblSchema;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("CONSTRAINT_CATALOG", typeof(string));
      tbl.Columns.Add("CONSTRAINT_SCHEMA", typeof(string));
      tbl.Columns.Add("CONSTRAINT_NAME", typeof(string));
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(int));
      tbl.Columns.Add("INDEX_NAME", typeof(string));

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      tbl.BeginLoadData();

      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this))
      {
        using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
        {
          while (rdTables.Read())
          {
            if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, true, CultureInfo.InvariantCulture) == 0)
            {
              using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}]", rdTables.GetString(2)), this))
              {
                using (SQLiteDataReader rdTable = cmdTable.ExecuteReader(CommandBehavior.SchemaOnly))
                {
                  tblSchema = rdTable.GetSchemaTable();
                  foreach (DataRow schemaRow in tblSchema.Rows)
                  {
                    if (Convert.ToBoolean(schemaRow[SchemaTableColumn.IsKey], CultureInfo.InvariantCulture) == true)
                    {
                      row = tbl.NewRow();
                      row["CONSTRAINT_CATALOG"] = strCatalog;
                      row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "PK_{0}_{1}", rdTables.GetString(2), schemaRow[SchemaTableColumn.BaseColumnName]);
                      row["TABLE_CATALOG"] = strCatalog;
                      row["TABLE_NAME"] = rdTables.GetString(2);
                      row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.BaseColumnName];
                      row["INDEX_NAME"] = row["CONSTRAINT_NAME"];
                      row["ORDINAL_POSITION"] = schemaRow[SchemaTableColumn.ColumnOrdinal];
                      if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, row["INDEX_NAME"].ToString(), true, CultureInfo.InvariantCulture) == 0)
                      {
                        tbl.Rows.Add(row);
                      }
                    }
                  }
                }
              }
              using (SQLiteCommand cmdIndexes = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'index' AND [tbl_name] LIKE '{1}'", strCatalog, rdTables.GetString(2)), this))
              {
                using (SQLiteDataReader rdIndexes = cmdIndexes.ExecuteReader())
                {
                  while (rdIndexes.Read())
                  {
                    if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, rdIndexes.GetString(1), true, CultureInfo.InvariantCulture) == 0)
                    {
                      using (SQLiteCommand cmdIndex = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rdIndexes.GetString(1)), this))
                      {
                        using (SQLiteDataReader rdIndex = cmdIndex.ExecuteReader())
                        {
                          while (rdIndex.Read())
                          {
                            row = tbl.NewRow();
                            row["CONSTRAINT_CATALOG"] = strCatalog;
                            row["CONSTRAINT_NAME"] = rdIndexes.GetString(1);
                            row["TABLE_CATALOG"] = strCatalog;
                            row["TABLE_NAME"] = rdIndexes.GetString(2);
                            row["COLUMN_NAME"] = rdIndex.GetString(2);
                            row["INDEX_NAME"] = rdIndexes.GetString(1);
                            row["ORDINAL_POSITION"] = rdIndex.GetInt32(1);

                            tbl.Rows.Add(row);
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }


      tbl.EndLoadData();
      tbl.AcceptChanges();

      return tbl;
    }

    /// <summary>
    /// Returns detailed column information for a specified view
    /// </summary>
    /// <param name="strCatalog">The catalog to retrieve columns for (can be null)</param>
    /// <param name="strView">The view to restrict column information by (can be null)</param>
    /// <param name="strColumn">The source column to restrict column information by (can be null)</param>
    /// <returns>A DataTable containing the results</returns>
    private DataTable Schema_ViewColumns(string strCatalog, string strView, string strColumn)
    {
      DataTable tbl = new DataTable("ViewColumns");
      DataRow row;
      string strSql;
      int n;
      DataRow schemaRow;
      DataRow viewRow;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("VIEW_CATALOG", typeof(string));
      tbl.Columns.Add("VIEW_SCHEMA", typeof(string));
      tbl.Columns.Add("VIEW_NAME", typeof(string));
      tbl.Columns.Add("VIEW_COLUMN_NAME", typeof(String));
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      tbl.BeginLoadData();

      using (SQLiteCommand cmdViews = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'view'", strCatalog), this))
      {
        using (SQLiteDataReader rdViews = cmdViews.ExecuteReader())
        {
          while (rdViews.Read())
          {
            if (String.IsNullOrEmpty(strView) || String.Compare(strView, rdViews.GetString(2), true, CultureInfo.InvariantCulture) == 0)
            {
              using (SQLiteCommand cmdViewSelect = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdViews.GetString(2)), this))
              {
                strSql = rdViews.GetString(4);
                n = CultureInfo.InvariantCulture.CompareInfo.IndexOf(strSql, " AS ", CompareOptions.IgnoreCase);
                if (n < 0)
                  continue;

                strSql = strSql.Substring(n + 4);

                using (SQLiteCommand cmd = new SQLiteCommand(strSql, this))
                {
                  using (SQLiteDataReader rdViewSelect = cmdViewSelect.ExecuteReader(CommandBehavior.SchemaOnly))
                  {
                    using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly))
                    {
                      using (DataTable tblSchemaView = rdViewSelect.GetSchemaTable())
                      {
                        using (DataTable tblSchema = rd.GetSchemaTable())
                        {
                          for (n = 0; n < tblSchema.Rows.Count; n++)
                          {
                            viewRow = tblSchemaView.Rows[n];
                            schemaRow = tblSchema.Rows[n];

                            if (String.Compare(viewRow[SchemaTableColumn.ColumnName].ToString(), strColumn, true, CultureInfo.InvariantCulture) == 0
                              || strColumn == null)
                            {
                              row = tbl.NewRow();

                              row["VIEW_CATALOG"] = strCatalog;
                              row["VIEW_NAME"] = rdViews.GetString(2);
                              row["TABLE_CATALOG"] = strCatalog;
                              row["TABLE_SCHEMA"] = schemaRow[SchemaTableColumn.BaseSchemaName];
                              row["TABLE_NAME"] = schemaRow[SchemaTableColumn.BaseTableName];
                              row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.ColumnName];
                              row["VIEW_COLUMN_NAME"] = viewRow[SchemaTableColumn.ColumnName];

                              tbl.Rows.Add(row);
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }

      tbl.EndLoadData();
      tbl.AcceptChanges();

      return tbl;
    }

    /// <summary>
    /// Retrieves foreign key information from the specified set of filters
    /// </summary>
    /// <param name="strCatalog">An optional catalog to restrict results on</param>
    /// <param name="strTable">An optional table to restrict results on</param>
    /// <param name="strKeyName">An optional foreign key name to restrict results on</param>
    /// <returns>A DataTable with the results of the query</returns>
    private DataTable Schema_ForeignKeys(string strCatalog, string strTable, string strKeyName)
    {
      DataTable tbl = new DataTable("ForeignKeys");
      DataRow row;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add("CONSTRAINT_CATALOG", typeof(string));
      tbl.Columns.Add("CONSTRAINT_SCHEMA", typeof(string));
      tbl.Columns.Add("CONSTRAINT_NAME", typeof(string));
      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("CONSTRAINT_TYPE", typeof(string));
      tbl.Columns.Add("IS_DEFERRABLE", typeof(bool));
      tbl.Columns.Add("INITIALLY_DEFERRED", typeof(bool));
      tbl.Columns.Add("FKEY_FROM_COLUMN", typeof(string));
      tbl.Columns.Add("FKEY_FROM_ORDINAL_POSITION", typeof(int));
      tbl.Columns.Add("FKEY_TO_CATALOG", typeof(string));
      tbl.Columns.Add("FKEY_TO_SCHEMA", typeof(string));
      tbl.Columns.Add("FKEY_TO_TABLE", typeof(string));
      tbl.Columns.Add("FKEY_TO_COLUMN", typeof(string));

      if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";

      tbl.BeginLoadData();

      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'table'", strCatalog), this))
      {
        using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
        {
          while (rdTables.Read())
          {
            if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), true, CultureInfo.InvariantCulture) == 0)
            {
              using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}]", rdTables.GetString(2)), this))
              {
                using (SQLiteDataReader rdTable = cmdTable.ExecuteReader(CommandBehavior.SchemaOnly))
                {
                  using (SQLiteCommand cmdKey = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].foreign_key_list([{1}])", strCatalog, rdTables.GetString(2)), this))
                  {
                    using (SQLiteDataReader rdKey = cmdKey.ExecuteReader())
                    {
                      while (rdKey.Read())
                      {
                        row = tbl.NewRow();
                        row["CONSTRAINT_CATALOG"] = strCatalog;
                        row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}_{2}", rdTables.GetString(2), rdKey.GetString(3), rdKey.GetString(4));
                        row["TABLE_CATALOG"] = strCatalog;
                        row["TABLE_NAME"] = rdTables.GetString(2);
                        row["CONSTRAINT_TYPE"] = "FOREIGN KEY";
                        row["IS_DEFERRABLE"] = false;
                        row["INITIALLY_DEFERRED"] = false;
                        row["FKEY_FROM_COLUMN"] = rdKey.GetString(3);
                        row["FKEY_FROM_ORDINAL_POSITION"] = rdTable.GetOrdinal(row["FKEY_FROM_COLUMN"].ToString());
                        row["FKEY_TO_CATALOG"] = strCatalog;
                        row["FKEY_TO_TABLE"] = rdKey.GetString(2);
                        row["FKEY_TO_COLUMN"] = rdKey.GetString(4);

                        if (String.IsNullOrEmpty(strKeyName) || String.Compare(strKeyName, row["CONSTRAINT_NAME"].ToString(), true, CultureInfo.InvariantCulture) == 0)
                          tbl.Rows.Add(row);
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }

      tbl.EndLoadData();
      tbl.AcceptChanges();

      return tbl;
    }
  }
}







|




>
>
|
<
<
|
<
>

|
|
<
<
<
>
|
>
>









<
<
<
<
<
<
<





<






|




|

|
|

|













|

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

|
|
|
|
|
|
|
|
|
<

|
<
<
<
<












<
<
<
<
<
<
<
|



<

<
















|











|

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

|
<
<
<












<
<
<
<
<
<
<






<




>
>
>
>
>



|

|





|
|
|

<
|

|
<


<

















<
<
<
<
<
<







<





|






|

|





|
<


|


|

<


|















<
<
<
<
<





<











|
<


<

<
<









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




639
640
641
642
643
644
645
646
647
648
649
650
651
652
653


654

655
656
657
658



659
660
661
662
663
664
665
666
667
668
669
670
671







672
673
674
675
676

677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708








709
710
711
712
713
714
715
716
717

718
719
720
721
722
723
724
725
726
727
728
729

730
731




732
733
734
735
736
737
738
739
740
741
742
743







744
745
746
747

748

749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
































779
780
781
782
783
784
785
786
787
788
789

790
791

792

793
794



795
796
797
798
799
800
801
802
803
804
805
806







807
808
809
810
811
812

813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836

837
838
839

840
841

842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858






859
860
861
862
863
864
865

866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886

887
888
889
890
891
892
893

894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911





912
913
914
915
916

917
918
919
920
921
922
923
924
925
926
927
928

929
930

931


932
933
934
935
936
937
938
939
940



































































































































































































































































































































941
942
943
944

      tbl.BeginLoadData();

      // TODO: Fixup the regular expressions to support only the SQLite stuff, they were originally cloned
      // from JET's DataSourceInformation return result.
      row = tbl.NewRow();
      row.ItemArray = new object[] {
        DBNull.Value,
        "SQLite",
        _sql.Version,
        _sql.Version,
        3,
        @"[^ ][^\.!`\[\]]*",
        1,
        DBNull.Value,


        "?",

        "?",
        0,
        DBNull.Value,
        @"`(([^`]|``)*)`",



        1,
        DBNull.Value,
        DBNull.Value,
        DBNull.Value
      };
      tbl.Rows.Add(row);

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }








    private DataTable Schema_Columns(string strCatalog, string strTable, string strColumn)
    {
      DataTable tbl = new DataTable("Columns");
      DataRow row;


      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));
      tbl.Columns.Add("COLUMN_PROPID", typeof(long));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(long));
      tbl.Columns.Add("COLUMN_HASDEFAULT", typeof(bool));
      tbl.Columns.Add("COLUMN_DEFAULT", typeof(string));
      tbl.Columns.Add("COLUMN_FLAGS", typeof(long));
      tbl.Columns.Add("IS_NULLABLE", typeof(bool));
      tbl.Columns.Add("DATA_TYPE", typeof(int));
      tbl.Columns.Add("TYPE_GUID", typeof(Guid));
      tbl.Columns.Add("CHARACTER_MAXIMUM_LENGTH", typeof(long));
      tbl.Columns.Add("CHARACTER_OCTET_LENGTH", typeof(long));
      tbl.Columns.Add("NUMERIC_PRECISION", typeof(int));
      tbl.Columns.Add("NUMERIC_SCALE", typeof(short));
      tbl.Columns.Add("DATETIME_PRECISION", typeof(long));
      tbl.Columns.Add("CHARACTER_SET_CATALOG", typeof(string));
      tbl.Columns.Add("CHARACTER_SET_SCHEMA", typeof(string));
      tbl.Columns.Add("CHARACTER_SET_NAME", typeof(string));
      tbl.Columns.Add("COLLATION_CATALOG", typeof(string));
      tbl.Columns.Add("COLLATION_SCHEMA", typeof(string));
      tbl.Columns.Add("COLLATION_NAME", typeof(string));
      tbl.Columns.Add("DOMAIN_CATALOG", typeof(string));
      tbl.Columns.Add("DOMAIN_NAME", typeof(string));
      tbl.Columns.Add("DESCRIPTION", typeof(string));

      tbl.BeginLoadData();

      if (strCatalog == null || strCatalog == "") strCatalog = "main";









      using (SQLiteCommand cmd = new SQLiteCommand(String.Format("SELECT * FROM [{0}].[{1}]", strCatalog, strTable), this))
      {
        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          using (DataTable tblSchema = rd.GetSchemaTable())
          {
            foreach (DataRow schemaRow in tblSchema.Rows)
            {
              if (String.Compare(schemaRow[SchemaTableColumn.ColumnName].ToString(), strColumn, true) == 0 || strColumn == null)

              {
                row = tbl.NewRow();

                row["TABLE_NAME"] = strTable;
                row["COLUMN_NAME"] = schemaRow[SchemaTableColumn.ColumnName];
                row["TABLE_CATALOG"] = schemaRow[SchemaTableOptionalColumn.BaseCatalogName];
                row["ORDINAL_POSITION"] = schemaRow[SchemaTableColumn.ColumnOrdinal];
                row["COLUMN_HASDEFAULT"] = (schemaRow[SchemaTableOptionalColumn.DefaultValue] != DBNull.Value);
                row["COLUMN_DEFAULT"] = schemaRow[SchemaTableOptionalColumn.DefaultValue];
                row["IS_NULLABLE"] = schemaRow[SchemaTableColumn.AllowDBNull];
                row["DATA_TYPE"] = schemaRow[SchemaTableColumn.ProviderType];
                row["CHARACTER_MAXIMUM_LENGTH"] = schemaRow[SchemaTableColumn.ColumnSize];


                tbl.Rows.Add(row);




              }
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }








    private DataTable Schema_Indexes(string strCatalog, string strIndex, string strTable)
    {
      DataTable tbl = new DataTable("Indexes");
      DataRow row;



      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("INDEX_CATALOG", typeof(string));
      tbl.Columns.Add("INDEX_SCHEMA", typeof(string));
      tbl.Columns.Add("INDEX_NAME", typeof(string));
      tbl.Columns.Add("PRIMARY_KEY", typeof(bool));
      tbl.Columns.Add("UNIQUE", typeof(bool));
      tbl.Columns.Add("CLUSTERED", typeof(bool));
      tbl.Columns.Add("TYPE", typeof(int));
      tbl.Columns.Add("FILL_FACTOR", typeof(int));
      tbl.Columns.Add("INITIAL_SIZE", typeof(int));
      tbl.Columns.Add("NULLS", typeof(int));
      tbl.Columns.Add("SORT_BOOKMARKS", typeof(bool));
      tbl.Columns.Add("AUTO_UPDATE", typeof(bool));
      tbl.Columns.Add("NULL_COLLATION", typeof(int));
      tbl.Columns.Add("ORDINAL_POSITION", typeof(long));
      tbl.Columns.Add("COLUMN_NAME", typeof(string));
      tbl.Columns.Add("COLUMN_GUID", typeof(Guid));
      tbl.Columns.Add("COLUMN_PROPID", typeof(long));
      tbl.Columns.Add("COLLATION", typeof(short));
      tbl.Columns.Add("CARDINALITY", typeof(Decimal));
      tbl.Columns.Add("PAGES", typeof(int));
      tbl.Columns.Add("FILTER_CONDITION", typeof(string));
      tbl.Columns.Add("INTEGRATED", typeof(bool));

      tbl.BeginLoadData();

      if (strCatalog == null || strCatalog == "") strCatalog = "main";

































      using (SQLiteCommand cmd = new SQLiteCommand(String.Format("SELECT * FROM [{0}].[sqlite_master] WHERE [type] = 'index'", strCatalog), this))
      {
        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            if (String.Compare(rd.GetString(1), strIndex, true) == 0 || strIndex == null)
            {
              if (String.Compare(rd.GetString(2), strTable, true) == 0 || strTable == null)
              {
                row = tbl.NewRow();

                row["TABLE_CATALOG"] = strCatalog;
                row["TABLE_NAME"] = rd.GetString(2);

                row["INDEX_NAME"] = rd.GetString(1);


                tbl.Rows.Add(row);



              }
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }








    private DataTable Schema_Tables(string strCatalog, string strTable, string strType)
    {
      DataTable tbl = new DataTable("Tables");
      DataRow row;
      string strItem;


      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("TABLE_TYPE", typeof(string));
      tbl.Columns.Add("TABLE_GUID", typeof(Guid));
      tbl.Columns.Add("DESCRIPTION", typeof(string));
      tbl.Columns.Add("TABLE_PROPID", typeof(long));
      tbl.Columns.Add("DATE_CREATED", typeof(DateTime));
      tbl.Columns.Add("DATE_MODIFIED", typeof(DateTime));

      tbl.BeginLoadData();

      if (strCatalog == null || strCatalog == "") strCatalog = "main";

      using (SQLiteCommand cmd = new SQLiteCommand(String.Format("SELECT * FROM [{0}].[sqlite_master] WHERE [type] NOT LIKE 'index'", strCatalog), this))
      {
        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            strItem = rd.GetString(0).ToUpper();
            if (rd.GetString(2).ToUpper().IndexOf("SQLITE_") == 0)
              strItem = "SYSTEM TABLE";


            if (String.Compare(strItem, strType, true) == 0 || strType == null)
            {
              if (String.Compare(rd.GetString(2), strTable, true) == 0 || strTable == null)

              {
                row = tbl.NewRow();

                row["TABLE_CATALOG"] = strCatalog;
                row["TABLE_NAME"] = rd.GetString(2);
                row["TABLE_TYPE"] = strItem;

                tbl.Rows.Add(row);
              }
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }







    private DataTable Schema_Views(string strCatalog, string strView)
    {
      DataTable tbl = new DataTable("Views");
      DataRow row;
      string strItem;
      int nPos;


      tbl.Columns.Add("TABLE_CATALOG", typeof(string));
      tbl.Columns.Add("TABLE_SCHEMA", typeof(string));
      tbl.Columns.Add("TABLE_NAME", typeof(string));
      tbl.Columns.Add("VIEW_DEFINITION", typeof(string));
      tbl.Columns.Add("CHECK_OPTION", typeof(bool));
      tbl.Columns.Add("IS_UPDATEABLE", typeof(bool));
      tbl.Columns.Add("DESCRIPTION", typeof(string));
      tbl.Columns.Add("DATE_CREATED", typeof(DateTime));
      tbl.Columns.Add("DATE_MODIFIED", typeof(DateTime));

      tbl.BeginLoadData();

      if (strCatalog == null || strCatalog == "") strCatalog = "main";

      using (SQLiteCommand cmd = new SQLiteCommand(String.Format("SELECT * FROM [{0}].[sqlite_master] WHERE [type] LIKE 'view'", strCatalog), this))
      {
        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            if (String.Compare(rd.GetString(1), strView, true) == 0 || strView == null)

            {
              strItem = rd.GetString(4);
              nPos = Globalization.CultureInfo.InvariantCulture.CompareInfo.IndexOf(strItem, " AS ");
              if (nPos > -1)
              {
                strItem = strItem.Substring(nPos + 4);
                row = tbl.NewRow();

                row["TABLE_CATALOG"] = strCatalog;
                row["TABLE_NAME"] = rd.GetString(2);
                row["IS_UPDATEABLE"] = false;
                row["VIEW_DEFINITION"] = strItem;

                tbl.Rows.Add(row);
              }
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }






    private DataTable Schema_Catalogs(string strCatalog)
    {
      DataTable tbl = new DataTable("Catalogs");
      DataRow row;


      tbl.Columns.Add("CATALOG_NAME", typeof(string));
      tbl.Columns.Add("DESCRIPTION", typeof(string));

      tbl.BeginLoadData();

      using (SQLiteCommand cmd = new SQLiteCommand("PRAGMA database_list", this))
      {
        using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            if (strCatalog == null || String.Compare(rd.GetString(1), strCatalog, true) == 0)

            {
              row = tbl.NewRow();

              row["CATALOG_NAME"] = rd.GetString(1);


              tbl.Rows.Add(row);
            }
          }
        }
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();




































































































































































































































































































































      return tbl;
    }
  }
}
Changes to System.Data.SQLite/SQLiteConnectionStringBuilder.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57



58




59


60


61


62





63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97









98
99
100




101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data.Common;
  using System.ComponentModel;
  using System.Collections;
  using System.Globalization;
  using System.Reflection;

#if !PLATFORM_COMPACTFRAMEWORK
  using System.ComponentModel.Design;

  /// <summary>
  /// SQLite implementation of DbConnectionStringBuilder.
  /// </summary>
  [DefaultProperty("DataSource")]
  [DefaultMember("Item")]
  public sealed class SQLiteConnectionStringBuilder : DbConnectionStringBuilder
  {
    /// <summary>
    /// Properties of this class
    /// </summary>
    private Hashtable _properties;

    /// <overloads>
    /// Constructs a new instance of the class
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteConnectionStringBuilder()
    {
      Initialize(null);
    }

    /// <summary>
    /// Constructs a new instance of the class using the specified connection string.
    /// </summary>
    /// <param name="connectionString">The connection string to parse</param>
    public SQLiteConnectionStringBuilder(string connectionString)
    {
      Initialize(connectionString);
    }

    /// <summary>
    /// Private initializer, which assigns the connection string and resets the builder
    /// </summary>
    /// <param name="cnnString">The connection string to assign</param>
    private void Initialize(string cnnString)
    {



      _properties = new Hashtable();




      base.GetProperties(_properties);





      if (String.IsNullOrEmpty(cnnString) == false)


        ConnectionString = cnnString;





    }

    /// <summary>
    /// Gets/Sets the default version of the SQLite engine to instantiate.  Currently the only valid value is 3, indicating version 3 of the sqlite library.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(3)]
    public int Version
    {
      get
      {
        if (ContainsKey("Version") == false) return 3;

        return Convert.ToInt32(this["Version"], CultureInfo.CurrentCulture);
      }
      set
      {
        if (value != 3)
          throw new NotSupportedException();

        this["Version"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the synchronous mode of the connection string.  Default is "Normal".
    /// </summary>
    [DisplayName("Synchronous")]
    [Browsable(true)]
    [DefaultValue(SynchronizationModes.Normal)]
    public SynchronizationModes SyncMode
    {
      get
      {
        return (SynchronizationModes)TypeDescriptor.GetConverter(typeof(SynchronizationModes)).ConvertFrom(this["Synchronous"]);









      }
      set
      {




        this["Synchronous"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the encoding for the connection string.  The default is "False" which indicates UTF-8 encoding.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(false)]
    public bool UseUTF16Encoding
    {
      get
      {
        return Convert.ToBoolean(this["UseUTF16Encoding"], CultureInfo.CurrentCulture);
      }
      set
      {
        this["UseUTF16Encoding"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the filename to open on the connection string.
    /// </summary>
    [DisplayName("Data Source")]
    [Browsable(true)]
    public string DataSource
    {
      get
      {
        if (ContainsKey("Data Source") == false) return "";

        return this["Data Source"].ToString();
      }
      set
      {
        this["Data Source"] = value;
      }
    }

    /// <summary>
    /// Gets/sets the database encryption password
    /// </summary>
    [Browsable(true)]
    public string Password
    {
      get
      {
        if (ContainsKey("Password") == false) return "";

        return this["Password"].ToString();
      }
      set
      {
        this["Password"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the page size for the connection.
    /// </summary>
    [DisplayName("Page Size")]
    [Browsable(true)]
    [DefaultValue(1024)]
    public int PageSize
    {
      get
      {
        if (ContainsKey("Page Size") == false) return 1024;
        return Convert.ToInt32(this["Page Size"], CultureInfo.InvariantCulture);
      }
      set
      {
        this["Page Size"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the cache size for the connection.
    /// </summary>
    [DisplayName("Cache Size")]
    [Browsable(true)]
    [DefaultValue(2000)]
    public int CacheSize
    {
      get
      {
        if (ContainsKey("Cache Size") == false) return 2000;
        return Convert.ToInt32(this["Cache Size"], CultureInfo.InvariantCulture);
      }
      set
      {
        this["Cache Size"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the datetime format for the connection.
    /// </summary>
    [Browsable(true)]
    [DefaultValue(SQLiteDateFormats.ISO8601)]
    public SQLiteDateFormats DateTimeFormat
    {
      get
      {
        if (ContainsKey("DateTimeFormat") == false) return SQLiteDateFormats.ISO8601;


        return (SQLiteDateFormats)TypeDescriptor.GetConverter(typeof(SQLiteDateFormats)).ConvertFrom(this["DateTimeFormat"]);
      }
      set
      {
        this["DateTimeFormat"] = value;
      }
    }

    /// <summary>
    /// Helper function for retrieving values from the connectionstring
    /// </summary>
    /// <param name="keyword">The keyword to retrieve settings for</param>
    /// <param name="value">The resulting parameter value</param>
    /// <returns>Returns true if the value was found and returned</returns>
    public override bool TryGetValue(string keyword, out object value)
    {
      bool b = base.TryGetValue(keyword, out value);

      if (!_properties.ContainsKey(keyword)) return b;

      PropertyDescriptor pd = _properties[keyword] as PropertyDescriptor;

      if (pd == null) return b;

      if (b)
      {
        value = TypeDescriptor.GetConverter(pd.PropertyType).ConvertFrom(value);
      }
      else
      {
        DefaultValueAttribute att = pd.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;
        if (att != null)
        {
          value = att.Value;
          b = true;
        }
      }
      return b;
    }
  }
#endif
}











<
<
<
<


<
<



<
<


<
<
<
<
<














|
|

|


<
<
<
<


>
>
>
|
>
>
>
>
|
>
>

>
>
|
>
>
|
>
>
>
>
>





<
<




<
<
|




|








<
<
<
|



|
>
>
>
>
>
>
>
>
>



>
>
>
>
|






<
<




|



|






<
<




<
<








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



<
<
<




<
|










<
<
<




<
|










<
<
|



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


<




1
2
3
4
5
6
7
8
9
10
11




12
13


14
15
16


17
18





19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38




39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68


69
70
71
72


73
74
75
76
77
78
79
80
81
82
83
84
85
86



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129


130
131
132
133


134
135
136
137
138
139
140
141


















142
143
144



145
146
147
148

149
150
151
152
153
154
155
156
157
158
159



160
161
162
163

164
165
166
167
168
169
170
171
172
173
174


175
176
177
178
179
180
181
182

183

184
185
186
187







188
189
190

191

192
193
194









195
196
197
198

199
200
201
202
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data.Common;





#if !PLATFORM_COMPACTFRAMEWORK


  /// <summary>
  /// SQLite implementation of DbConnectionStringBuilder.
  /// </summary>


  public sealed class SQLiteConnectionStringBuilder : DbConnectionStringBuilder
  {





    /// <overloads>
    /// Constructs a new instance of the class
    /// </overloads>
    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteConnectionStringBuilder()
    {
      Initialize(null);
    }

    /// <summary>
    /// Constructs a new instance of the class using the specified connection string.
    /// </summary>
    /// <param name="cnnString">The connection string to parse</param>
    public SQLiteConnectionStringBuilder(string cnnString)
    {
      Initialize(cnnString);
    }





    private void Initialize(string cnnString)
    {
      ConnectionString = cnnString;
      Reset();
    }

    internal void Reset()
    {
      if (this.ContainsKey("Version") == false)
        Version = 3;

      if (ContainsKey("UseUTF16Encoding") == false)
        UseUTF16Encoding = false;

      if (ContainsKey("Cache Size") == false)
        CacheSize = 2000;

      if (ContainsKey("Synchronous") == false)
        SyncMode = SyncMode.Normal;

      if (ContainsKey("DateTimeFormat") == false)
        DateTimeFormat = DateTimeFormat.ISO8601;

      if (ContainsKey("Page Size") == false)
        PageSize = 4096;
    }

    /// <summary>
    /// Gets/Sets the default version of the SQLite engine to instantiate.  Currently the only valid value is 3, indicating version 3 of the sqlite library.
    /// </summary>


    public int Version
    {
      get
      {


        return Convert.ToInt32(this["Version"]);
      }
      set
      {
        if (value != 3)
          throw new NotImplementedException();

        this["Version"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the synchronous mode of the connection string.  Default is "Normal".
    /// </summary>



    public SyncMode SyncMode
    {
      get
      {
        string s = this["Synchronous"].ToString().ToUpper();
        switch (s)
        {
          case "FULL":
            return SyncMode.Full;
          case "OFF":
            return SyncMode.Off;
          default:
            return SyncMode.Normal;
        }
      }
      set
      {
        string s = "Normal";
        if (value == SyncMode.Full) s = "Full";
        else if (value == SyncMode.Off) s = "Off";

        this["Synchronous"] = s;
      }
    }

    /// <summary>
    /// Gets/Sets the encoding for the connection string.  The default is "False" which indicates UTF-8 encoding.
    /// </summary>


    public bool UseUTF16Encoding
    {
      get
      {
        return (this["UseUTF16Encoding"].ToString().ToUpper() == "TRUE");
      }
      set
      {
        this["UseUTF16Encoding"] = ((value == true) ? "True" : "False");
      }
    }

    /// <summary>
    /// Gets/Sets the filename to open on the connection string.
    /// </summary>


    public string DataSource
    {
      get
      {


        return this["Data Source"].ToString();
      }
      set
      {
        this["Data Source"] = value;
      }
    }



















    /// <summary>
    /// Gets/Sets the page size for the connection.
    /// </summary>



    public int PageSize
    {
      get
      {

        return Convert.ToInt32(this["Page Size"]);
      }
      set
      {
        this["Page Size"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the cache size for the connection.
    /// </summary>



    public int CacheSize
    {
      get
      {

        return Convert.ToInt32(this["Cache Size"]);
      }
      set
      {
        this["Cache Size"] = value;
      }
    }

    /// <summary>
    /// Gets/Sets the datetime format for the connection.
    /// </summary>


    public DateTimeFormat DateTimeFormat
    {
      get
      {
        switch(this["DateTimeFormat"].ToString().ToUpper())
        {
          case "TICKS":
            return DateTimeFormat.Ticks;

          default:

            return DateTimeFormat.ISO8601;
        }
      }
      set







      {
        switch (value)
        {

          case DateTimeFormat.Ticks:

            this["DateTimeFormat"] = "Ticks";
            break;
          case DateTimeFormat.ISO8601:









            this["DateTimeFormat"] = "ISO8601";
            break;
        }
      }

    }
  }
#endif
}
Changes to System.Data.SQLite/SQLiteConvert.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Runtime.InteropServices;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Globalization;
  using System.Text;

#if !PLATFORM_COMPACTFRAMEWORK 
  using System.ComponentModel.Design;
#endif

  /// <summary>
  /// SQLite has very limited types, and is inherently text-based.  The first 5 types below represent the sum of all types SQLite
  /// understands.  The DateTime extension to the spec is for internal use only.
  /// </summary>
  public enum TypeAffinity
  {
    /// <summary>
    /// Not used
    /// </summary>
    Uninitialized = 0,
    /// <summary>
    /// All integers in SQLite default to Int64
    /// </summary>
    Int64 = 1,
    /// <summary>
    /// All floating point numbers in SQLite default to double
    /// </summary>
    Double = 2,












<
<
<
<
<
<
<








<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12







13
14
15
16
17
18
19
20




21
22
23
24
25
26
27
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Runtime.InteropServices;
  using System.Collections.Generic;








  /// <summary>
  /// SQLite has very limited types, and is inherently text-based.  The first 5 types below represent the sum of all types SQLite
  /// understands.  The DateTime extension to the spec is for internal use only.
  /// </summary>
  public enum TypeAffinity
  {
    /// <summary>




    /// All integers in SQLite default to Int64
    /// </summary>
    Int64 = 1,
    /// <summary>
    /// All floating point numbers in SQLite default to double
    /// </summary>
    Double = 2,
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

145
146
147












148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228



229



















230






231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
    /// <summary>
    /// Null types can be returned from functions
    /// </summary>
    Null = 5,
    /// <summary>
    /// Used internally by this provider
    /// </summary>
    DateTime = 10,
    /// <summary>
    /// Used internally
    /// </summary>
    None = 11,
  }

  /// <summary>
  /// This implementation of SQLite for ADO.NET can process date/time fields in databases in only one of two formats.  Ticks and ISO8601.
  /// Ticks is inherently more accurate, but less compatible with 3rd party tools that query the database, and renders the DateTime field
  /// unreadable without post-processing.
  /// ISO8601 is more compatible, readable, fully-processable, but less accurate as it doesn't provide time down to fractions of a second.
  /// </summary>
  public enum SQLiteDateFormats
  {
    /// <summary>
    /// Using ticks is more accurate but less compatible with other viewers and utilities that access your database.
    /// </summary>
    Ticks = 0,
    /// <summary>
    /// The default format for this provider.  More compatible with SQLite's intended usage of datetimes, but overall less accurate than Ticks as it doesn't
    /// natively support times down to fractions of a second.
    /// </summary>
    ISO8601 = 1,
  }

  /// <summary>
  /// Struct used internally to determine the datatype of a column in a resultset
  /// </summary>
  internal struct SQLiteType
  {
    /// <summary>
    /// The DbType of the column, or DbType.Object if it cannot be determined
    /// </summary>
    internal DbType Type;
    /// <summary>
    /// The affinity of a column, used for expressions or when Type is DbType.Object
    /// </summary>
    internal TypeAffinity Affinity;
  }

  internal struct SQLiteTypeNames
  {
    internal SQLiteTypeNames(string newtypeName, DbType newdataType)
    {
      typeName = newtypeName;
      dataType = newdataType;
    }

    internal string typeName;
    internal DbType dataType;
  }

  /// <summary>
  /// This base class provides datatype conversion services for the SQLite provider.
  /// </summary>
  public abstract class SQLiteConvert
  {
    /// <summary>
    /// An array of ISO8601 datetime formats we support conversion from
    /// </summary>
    private static string[] _datetimeFormats = new string[] {
      "yyyy-MM-dd HH:mm:ss.fffffff",
      "yyyy-MM-dd HH:mm:ss",
      "yyyy-MM-dd HH:mm",                               
      "yyyyMMddHHmmss",
      "yyyyMMddHHmm",
      "yyyyMMddTHHmmssfffffff",
      "yyyy-MM-dd",
      "yy-MM-dd",
      "yyyyMMdd",
      "HH:mm:ss",
      "HH:mm",
      "THHmmss",
      "THHmm",
      "yyyy-MM-dd HH:mm:ss.fff",
      "yyyy-MM-ddTHH:mm",
      "yyyy-MM-ddTHH:mm:ss",
      "yyyy-MM-ddTHH:mm:ss.fff",
      "yyyy-MM-ddTHH:mm:ss.ffffff",
      "HH:mm:ss.fff"
    };

    /// <summary>
    /// An UTF-8 Encoding instance, so we can convert strings to and from UTF-8
    /// </summary>
    private Encoding _utf8 = new UTF8Encoding();
    /// <summary>
    /// The default DateTime format for this instance
    /// </summary>
    private SQLiteDateFormats _datetimeFormat;

    /// <summary>
    /// Initializes the conversion class
    /// </summary>












    /// <param name="fmt">The default date/time format to use for this instance</param>
    internal SQLiteConvert(SQLiteDateFormats fmt)
    {
      _datetimeFormat = fmt;

    }

    #region UTF-8 Conversion Functions
    /// <summary>
    /// Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character.
    /// </summary>
    /// <param name="sourceText">The string to convert to UTF-8</param>
    /// <returns>A byte array containing the converted string plus an extra 0 terminating byte at the end of the array.</returns>
    public byte[] ToUTF8(string sourceText)
    {
      Byte[] byteArray;
      int nlen = _utf8.GetByteCount(sourceText) + 1;

      byteArray = new byte[nlen];
      nlen = _utf8.GetBytes(sourceText, 0, sourceText.Length, byteArray, 0);
      byteArray[nlen] = 0;

      return byteArray;
    }

    /// <summary>
    /// Convert a DateTime to a UTF-8 encoded, zero-terminated byte array.
    /// </summary>
    /// <remarks>
    /// This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the
    /// string result.
    /// </remarks>
    /// <param name="dateTimeValue">The DateTime to convert.</param>
    /// <returns>The UTF-8 encoded string, including a 0 terminating byte at the end of the array.</returns>
    public byte[] ToUTF8(DateTime dateTimeValue)
    {
      return ToUTF8(ToString(dateTimeValue));
    }

    /// <summary>
    /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string
    /// </summary>
    /// <param name="nativestring">The pointer to the memory where the UTF-8 string is encoded</param>
    /// <param name="nativestringlen">The number of bytes to decode</param>
    /// <returns>A string containing the translated character(s)</returns>
    public virtual string ToString(IntPtr nativestring, int nativestringlen)
    {
      if (nativestringlen == 0) return "";

      byte[] byteArray = new byte[nativestringlen];


      Marshal.Copy(nativestring, byteArray, 0, nativestringlen);

      return _utf8.GetString(byteArray, 0, nativestringlen);
    }

    #endregion

    #region DateTime Conversion Functions
    /// <summary>
    /// Converts a string into a DateTime, using the current DateTimeFormat specified for the connection when it was opened.
    /// </summary>
    /// <remarks>
    /// Acceptable ISO8601 DateTime formats are:
    ///   yyyy-MM-dd HH:mm:ss
    ///   yyyyMMddHHmmss
    ///   yyyyMMddTHHmmssfffffff
    ///   yyyy-MM-dd
    ///   yy-MM-dd
    ///   yyyyMMdd
    ///   HH:mm:ss
    ///   THHmmss
    /// </remarks>
    /// <param name="dateText">The string containing either a Tick value or an ISO8601-format string</param>
    /// <returns>A DateTime value</returns>
    public DateTime ToDateTime(string dateText)
    {
      switch (_datetimeFormat)
      {
        case SQLiteDateFormats.Ticks:
          return new DateTime(Convert.ToInt64(dateText, CultureInfo.InvariantCulture));
        default:



          return DateTime.ParseExact(dateText, _datetimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None);



















      }






    }

    /// <summary>
    /// Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened.
    /// </summary>
    /// <param name="dateValue">The DateTime value to convert</param>
    /// <returns>Either a string consisting of the tick count for DateTimeFormat.Ticks, or a date/time in ISO8601 format.</returns>
    public string ToString(DateTime dateValue)
    {
      switch (_datetimeFormat)
      {
        case SQLiteDateFormats.Ticks:
          return dateValue.Ticks.ToString(CultureInfo.InvariantCulture);
        default:
          return dateValue.ToString(_datetimeFormats[0], CultureInfo.InvariantCulture);
      }
    }

    /// <summary>
    /// Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime.
    /// </summary>
    /// <remarks>







|

|

|








|












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








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


|

|



|
>

|

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


>






|

|

|
|

|
|
|

|









|

|

|





|
|

|

|

|

>
|

|



















|

|



|
|

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





|

|



|
|

|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68



























69
70
71
72
73
74
75
76
77




















78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
    /// <summary>
    /// Null types can be returned from functions
    /// </summary>
    Null = 5,
    /// <summary>
    /// Used internally by this provider
    /// </summary>
    DateTime = 128,
    /// <summary>
    /// Used internally by this provider
    /// </summary>
    None=256,
  }

  /// <summary>
  /// This implementation of SQLite for ADO.NET can process date/time fields in databases in only one of two formats.  Ticks and ISO8601.
  /// Ticks is inherently more accurate, but less compatible with 3rd party tools that query the database, and renders the DateTime field
  /// unreadable without post-processing.
  /// ISO8601 is more compatible, readable, fully-processable, but less accurate as it doesn't provide time down to fractions of a second.
  /// </summary>
  public enum DateTimeFormat
  {
    /// <summary>
    /// Using ticks is more accurate but less compatible with other viewers and utilities that access your database.
    /// </summary>
    Ticks = 0,
    /// <summary>
    /// The default format for this provider.  More compatible with SQLite's intended usage of datetimes, but overall less accurate than Ticks as it doesn't
    /// natively support times down to fractions of a second.
    /// </summary>
    ISO8601 = 1,
  }




























  /// <summary>
  /// This base class provides datatype conversion services for the SQLite provider.
  /// </summary>
  public abstract class SQLiteConvert
  {
    /// <summary>
    /// An array of ISO8601 datetime formats we support conversion from
    /// </summary>
    private static string[] _datetimeFormats;





















    /// <summary>
    /// An UTF-8 Encoding instance, so we can convert strings to and from UTF8
    /// </summary>
    private Text.UTF8Encoding _utf8;
    /// <summary>
    /// The default DateTime format for this instance
    /// </summary>
    private DateTimeFormat _datetimeFormat;

    /// <summary>
    /// Static constructor, initializes the supported ISO8601 date time formats
    /// </summary>
    static SQLiteConvert()
    {
      _datetimeFormats = new string[] {"yyyy-MM-dd HH:mm:ss",
																	  "yyyyMMddHHmmss",
																	  "yyyyMMddTHHmmssfffffff",
																	  "yyyy-MM-dd",
																	  "yy-MM-dd",
																	  "yyyyMMdd",
																	  "HH:mm:ss",
																	  "THHmmss"
															 };
    }

    internal SQLiteConvert(DateTimeFormat fmt)
    {
      _datetimeFormat = fmt;
      _utf8 = new System.Text.UTF8Encoding();
    }

    #region UTF-8 Conversion Functions
    /// <summary>
    /// Converts a string to a UTF-8 encoded byte array sized to include a null-terminating character.
    /// </summary>
    /// <param name="strSrc">The string to convert to UTF-8</param>
    /// <returns>A byte array containing the converted string plus an extra 0 terminating byte at the end of the array.</returns>
    public byte[] ToUTF8(string strSrc)
    {
      Byte[] b;
      int nlen = _utf8.GetByteCount(strSrc) + 1;

      b = new byte[nlen];
      nlen = _utf8.GetBytes(strSrc, 0, strSrc.Length, b, 0);
      b[nlen] = 0;

      return b;
    }

    /// <summary>
    /// Convert a DateTime to a UTF-8 encoded, zero-terminated byte array.
    /// </summary>
    /// <remarks>
    /// This function is a convenience function, which first calls ToString() on the DateTime, and then calls ToUTF8() with the
    /// string result.
    /// </remarks>
    /// <param name="dtSrc">The DateTime to convert.</param>
    /// <returns>The UTF-8 encoded string, including a 0 terminating byte at the end of the array.</returns>
    public byte[] ToUTF8(DateTime dtSrc)
    {
      return ToUTF8(ToString(dtSrc));
    }

    /// <summary>
    /// Converts a UTF-8 encoded IntPtr of the specified length into a .NET string
    /// </summary>
    /// <param name="b">The pointer to the memory where the UTF-8 string is encoded</param>
    /// <param name="nlen">The number of bytes to decode</param>
    /// <returns>A string containing the translated character(s)</returns>
    public virtual string ToString(IntPtr b, int nlen)
    {
      if (nlen == 0) return "";

      byte[] byt;

      byt = new byte[nlen];
      Marshal.Copy(b, byt, 0, nlen);

      return _utf8.GetString(byt, 0, nlen);
    }

    #endregion

    #region DateTime Conversion Functions
    /// <summary>
    /// Converts a string into a DateTime, using the current DateTimeFormat specified for the connection when it was opened.
    /// </summary>
    /// <remarks>
    /// Acceptable ISO8601 DateTime formats are:
    ///   yyyy-MM-dd HH:mm:ss
    ///   yyyyMMddHHmmss
    ///   yyyyMMddTHHmmssfffffff
    ///   yyyy-MM-dd
    ///   yy-MM-dd
    ///   yyyyMMdd
    ///   HH:mm:ss
    ///   THHmmss
    /// </remarks>
    /// <param name="strSrc">The string containing either a Tick value or an ISO8601-format string</param>
    /// <returns>A DateTime value</returns>
    public DateTime ToDateTime(string strSrc)
    {
      switch (_datetimeFormat)
      {
        case DateTimeFormat.Ticks:
          return new DateTime(Convert.ToInt64(strSrc));
        default:
          return DateTime.ParseExact(strSrc, _datetimeFormats, System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None);
      }
    }

    /// <summary>
    /// Attempt to convert the specified string to a datetime value.
    /// </summary>
    /// <param name="strSrc">The string to parse into a datetime</param>
    /// <param name="result">If successful, a valid datetime structure</param>
    /// <returns>Returns true if the string was a valid ISO8601 datetime, false otherwise.</returns>
    public bool TryToDateTime(string strSrc, out DateTime result)
    {
      switch (_datetimeFormat)
      {
        case DateTimeFormat.ISO8601:
          return DateTime.TryParseExact(strSrc, _datetimeFormats, System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None, out result);
        case DateTimeFormat.Ticks:
          {
            long n;
            if (long.TryParse(strSrc, out n) == true)
            {
              result = new DateTime(n);
              return true;
            }
          }
          break;
      }

      result = DateTime.Now;
      return false;
    }

    /// <summary>
    /// Converts a DateTime to a string value, using the current DateTimeFormat specified for the connection when it was opened.
    /// </summary>
    /// <param name="dtSrc">The DateTime value to convert</param>
    /// <returns>Either a string consisting of the tick count for DateTimeFormat.Ticks, or a date/time in ISO8601 format.</returns>
    public string ToString(DateTime dtSrc)
    {
      switch (_datetimeFormat)
      {
        case DateTimeFormat.Ticks:
          return dtSrc.Ticks.ToString();
        default:
          return dtSrc.ToString(_datetimeFormats[0]);
      }
    }

    /// <summary>
    /// Internal function to convert a UTF-8 encoded IntPtr of the specified length to a DateTime.
    /// </summary>
    /// <remarks>
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404



405






406

407



408

409


410
411
412
413
414
415
416
417
418
419
420
421
422

423

424
425

426
427
428
429
430

431


432


433
434
435
436
437
438
439
440
441
442
443

444
445
446
447
448

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486

487
488

489
490
491
492
493
494
495
496
497
498
499
500
501

502

503































504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
    /// [0] One<br/>
    /// [1] Two<br/>
    /// [2] Three, Four<br/>
    /// [3] Five<br/>
    /// <br/>
    /// Note that the leading and trailing spaces were removed from each item during the split.
    /// </remarks>
    /// <param name="source">Source string to split apart</param>
    /// <param name="separator">Separator character</param>
    /// <returns>A string array of the split up elements</returns>
    public static string[] Split(string source, char separator)
    {
      char[] toks = new char[2] { '\"', separator };
      char[] quot = new char[1] { '\"' };
      int n = 0;
      List<string> ls = new List<string>();
      string s;

      while (source.Length > 0)
      {
        n = source.IndexOfAny(toks, n);
        if (n == -1) break;
        if (source[n] == toks[0])
        {
          source = source.Remove(n, 1);
          n = source.IndexOfAny(quot, n);
          if (n == -1)
          {
            source = "\"" + source;
            break;
          }
          source = source.Remove(n, 1);
        }
        else
        {
          s = source.Substring(0, n).Trim();
          source = source.Substring(n + 1).Trim();
          if (s.Length > 0) ls.Add(s);
          n = 0;
        }
      }
      if (source.Length > 0) ls.Add(source);

      string[] ar = new string[ls.Count];
      ls.CopyTo(ar, 0);

      return ar;
    }

    #region Type Conversions
    /// <summary>
    /// Determines the data type of a column in a statement
    /// </summary>
    /// <param name="stmt">The statement to retrieve information for</param>
    /// <param name="i">The column to retrieve type information on</param>
    /// <returns>Returns a SQLiteType struct</returns>
    internal static SQLiteType ColumnToType(SQLiteStatement stmt, int i)
    {
      SQLiteType typ;

      typ.Type = TypeNameToDbType(stmt._sql.ColumnType(stmt, i, out typ.Affinity));

      return typ;
    }

    /// <summary>
    /// Converts a SQLiteType to a .NET Type object
    /// </summary>
    /// <param name="t">The SQLiteType to convert</param>
    /// <returns>Returns a .NET Type object</returns>
    internal static Type SQLiteTypeToType(SQLiteType t)
    {
      if (t.Type != DbType.Object)
        return SQLiteConvert.DbTypeToType(t.Type);

      return _typeaffinities[(int)t.Affinity];
    }

    static Type[] _typeaffinities = {
      null,
      typeof(Int64),
      typeof(Double),
      typeof(string),
      typeof(byte[]),
      typeof(DBNull),
      null,
      null,
      null,
      null,
      typeof(DateTime),
      null,
    };

    /// <summary>
    /// For a given intrinsic type, return a DbType
    /// </summary>
    /// <param name="typ">The native type to convert</param>
    /// <returns>The corresponding (closest match) DbType</returns>
    internal static DbType TypeToDbType(Type typ)
    {
      TypeCode tc = Type.GetTypeCode(typ);
      if (tc == TypeCode.Object)
      {
        if (typ == typeof(byte[])) return DbType.Binary;
        if (typ == typeof(Guid)) return DbType.Guid;
        return DbType.String;
      }
      return _typetodbtype[(int)tc];
    }

    private static DbType[] _typetodbtype = {
      DbType.Object,
      DbType.Binary,
      DbType.Object,
      DbType.Boolean,
      DbType.SByte,
      DbType.SByte,
      DbType.Byte,
      DbType.Int16, // 7
      DbType.UInt16,
      DbType.Int32,
      DbType.UInt32,
      DbType.Int64, // 11
      DbType.UInt64,
      DbType.Single,
      DbType.Double,



      DbType.Decimal,






      DbType.DateTime,

      DbType.Object,



      DbType.String,

    };



    /// <summary>
    /// Convert a DbType to a Type
    /// </summary>
    /// <param name="typ">The DbType to convert from</param>
    /// <returns>The closest-match .NET type</returns>
    internal static Type DbTypeToType(DbType typ)
    {
      return _dbtypeToType[(int)typ];
    }

    private static Type[] _dbtypeToType = {
      typeof(string),   // 0

      typeof(byte[]),   // 1

      typeof(byte),     // 2
      typeof(bool),     // 3

      typeof(decimal),  // 4
      typeof(DateTime), // 5
      typeof(DateTime), // 6
      typeof(decimal),  // 7
      typeof(double),   // 8

      typeof(Guid),     // 9


      typeof(Int16),


      typeof(Int32),
      typeof(Int64),
      typeof(object),
      typeof(sbyte),
      typeof(float),
      typeof(string),
      typeof(DateTime),
      typeof(UInt16),
      typeof(UInt32),
      typeof(UInt64),
      typeof(double),

      typeof(string),
      typeof(string),
      typeof(string),
      typeof(string),   // 25 (Xml)
    };


    /// <summary>
    /// For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types.
    /// </summary>
    /// <param name="typ">The type to evaluate</param>
    /// <returns>The SQLite type affinity for that type.</returns>
    internal static TypeAffinity TypeToAffinity(Type typ)
    {
      TypeCode tc = Type.GetTypeCode(typ);
      if (tc == TypeCode.Object)
      {
        if (typ == typeof(byte[]))
          return TypeAffinity.Blob;
        else
          return TypeAffinity.Text;
      }
      return _typecodeAffinities[(int)tc];
    }

    private static TypeAffinity[] _typecodeAffinities = {
      TypeAffinity.Null,
      TypeAffinity.Blob,
      TypeAffinity.Null,
      TypeAffinity.Int64,
      TypeAffinity.Int64,
      TypeAffinity.Int64,
      TypeAffinity.Int64,
      TypeAffinity.Int64, // 7
      TypeAffinity.Int64,
      TypeAffinity.Int64,

      TypeAffinity.Int64,
      TypeAffinity.Int64, // 11
      TypeAffinity.Int64,
      TypeAffinity.Double,
      TypeAffinity.Double,
      TypeAffinity.Double,
      TypeAffinity.DateTime,
      TypeAffinity.Null,

      TypeAffinity.Text,
    };


    /// <summary>
    /// For a given type name, return a closest-match .NET type
    /// </summary>
    /// <param name="Name">The name of the type to match</param>
    /// <returns>The .NET DBType the text evaluates to.</returns>
    internal static DbType TypeNameToDbType(string Name)
    {
      if (String.IsNullOrEmpty(Name)) return DbType.Object;

      int x = _typeNames.Length;
      for (int n = 0; n < x; n++)
      {

        if (String.Compare(Name, 0, _typeNames[n].typeName, 0, _typeNames[n].typeName.Length, true, CultureInfo.InvariantCulture) == 0)

          return _typeNames[n].dataType; 































      }
      return DbType.Object;
    }
    #endregion

    private static SQLiteTypeNames[] _typeNames = {
      new SQLiteTypeNames("COUNTER", DbType.Int64),
      new SQLiteTypeNames("AUTOINCREMENT", DbType.Int64),
      new SQLiteTypeNames("IDENTITY", DbType.Int64),
      new SQLiteTypeNames("LONGTEXT", DbType.String),
      new SQLiteTypeNames("LONGCHAR", DbType.String),
      new SQLiteTypeNames("LONG", DbType.Int64),
      new SQLiteTypeNames("TINYINT", DbType.Byte),
      new SQLiteTypeNames("INTEGER", DbType.Int64),
      new SQLiteTypeNames("INT", DbType.Int32),
      new SQLiteTypeNames("VARCHAR", DbType.String),
      new SQLiteTypeNames("NVARCHAR", DbType.String),
      new SQLiteTypeNames("CHAR", DbType.String),
      new SQLiteTypeNames("TEXT", DbType.String),
      new SQLiteTypeNames("DOUBLE", DbType.Double),
      new SQLiteTypeNames("FLOAT", DbType.Double),
      new SQLiteTypeNames("REAL", DbType.Single),          
      new SQLiteTypeNames("BIT", DbType.Boolean),
      new SQLiteTypeNames("YESNO", DbType.Boolean),
      new SQLiteTypeNames("LOGICAL", DbType.Boolean),
      new SQLiteTypeNames("BOOL", DbType.Boolean),
      new SQLiteTypeNames("NUMERIC", DbType.Decimal),
      new SQLiteTypeNames("DECIMAL", DbType.Decimal),
      new SQLiteTypeNames("MONEY", DbType.Decimal),
      new SQLiteTypeNames("CURRENCY", DbType.Decimal),
      new SQLiteTypeNames("TIME", DbType.DateTime),
      new SQLiteTypeNames("DATE", DbType.DateTime),
      new SQLiteTypeNames("BLOB", DbType.Binary),
      new SQLiteTypeNames("BINARY", DbType.Binary),
      new SQLiteTypeNames("VARBINARY", DbType.Binary),
      new SQLiteTypeNames("IMAGE", DbType.Binary),
      new SQLiteTypeNames("GENERAL", DbType.Binary),
      new SQLiteTypeNames("OLEOBJECT", DbType.Binary),
      new SQLiteTypeNames("GUID", DbType.Guid),
      new SQLiteTypeNames("UNIQUEIDENTIFIER", DbType.Guid),
      new SQLiteTypeNames("MEMO", DbType.String),
      new SQLiteTypeNames("NOTE", DbType.String),
      new SQLiteTypeNames("SMALLINT", DbType.Int16),
      new SQLiteTypeNames("BIGINT", DbType.Int64),
    };
  }
}







|
|

|

|





|

|

|

|
|


|


|



|
|




|








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|
<

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








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








|
<

|
|
|

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








|

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



|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313











































314
315
316
317
318
319
320
321

322
323

324



325





326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366

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

394
395
396
397
398
399




400
401
402
403
404
405
406
407
408
409

410
411
412
413
414



415

416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436

437
438
439
440
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489








































490

    /// [0] One<br/>
    /// [1] Two<br/>
    /// [2] Three, Four<br/>
    /// [3] Five<br/>
    /// <br/>
    /// Note that the leading and trailing spaces were removed from each item during the split.
    /// </remarks>
    /// <param name="src">Source string to split apart</param>
    /// <param name="sep">Separator character</param>
    /// <returns>A string array of the split up elements</returns>
    public static string[] Split(string src, char sep)
    {
      char[] toks = new char[2] { '\"', sep };
      char[] quot = new char[1] { '\"' };
      int n = 0;
      List<string> ls = new List<string>();
      string s;

      while (src.Length > 0)
      {
        n = src.IndexOfAny(toks, n);
        if (n == -1) break;
        if (src[n] == toks[0])
        {
          src = src.Remove(n, 1);
          n = src.IndexOfAny(quot, n);
          if (n == -1)
          {
            src = "\"" + src;
            break;
          }
          src = src.Remove(n, 1);
        }
        else
        {
          s = src.Substring(0, n).Trim();
          src = src.Substring(n + 1).Trim();
          if (s.Length > 0) ls.Add(s);
          n = 0;
        }
      }
      if (src.Length > 0) ls.Add(src);

      string[] ar = new string[ls.Count];
      ls.CopyTo(ar, 0);

      return ar;
    }

    #region Type Conversions











































    /// <summary>
    /// For a given intrinsic type, return a DbType
    /// </summary>
    /// <param name="typ">The native type to convert</param>
    /// <returns>The corresponding (closest match) DbType</returns>
    internal static DbType TypeToDbType(Type typ)
    {
      switch (Type.GetTypeCode(typ))

      {
        case TypeCode.Int16:

          return DbType.Int16;



        case TypeCode.Int32:





          return DbType.Int32;
        case TypeCode.Int64:
          return DbType.Int64;
        case TypeCode.UInt16:
          return DbType.UInt16;
        case TypeCode.UInt32:
          return DbType.UInt32;
        case TypeCode.UInt64:
          return DbType.UInt64;
        case TypeCode.Double:
          return DbType.Double;
        case TypeCode.Single:
          return DbType.Single;
        case TypeCode.Decimal:
          return DbType.Decimal;
        case TypeCode.Boolean:
          return DbType.Boolean;
        case TypeCode.SByte:
        case TypeCode.Char:
          return DbType.SByte;
        case TypeCode.DateTime:
          return DbType.DateTime;
        case TypeCode.String:
          return DbType.String;
        case TypeCode.Object:
          if (typ == typeof(byte[])) return DbType.Binary;
          if (typ == typeof(Guid)) return DbType.Guid;
          return DbType.String;
      }

      return DbType.String;
    }

    /// <summary>
    /// Convert a DbType to a Type
    /// </summary>
    /// <param name="typ">The DbType to convert from</param>
    /// <returns>The closest-match .NET type</returns>
    internal static Type DbTypeToType(DbType typ)
    {
      switch (typ)

      {
        case DbType.Binary:
          return typeof(byte[]);
        case DbType.Boolean:
          return typeof(bool);
        case DbType.Byte:
          return typeof(byte);
        case DbType.Currency:
        case DbType.Decimal:
          return typeof(decimal);
        case DbType.DateTime:
          return typeof(DateTime);
        case DbType.Double:
          return typeof(double);
        case DbType.Guid:
          return typeof(Guid);
        case DbType.Int16:
        case DbType.UInt16:
          return typeof(Int16);
        case DbType.Int32:
        case DbType.UInt32:
          return typeof(Int32);
        case DbType.Int64:
        case DbType.UInt64:
          return typeof(Int64);
        case DbType.String:
          return typeof(string);

        case DbType.SByte:
          return typeof(char);
        case DbType.Single:
          return typeof(float);
      }
      return typeof(string);




    }

    /// <summary>
    /// For a given type, return the closest-match SQLite TypeAffinity, which only understands a very limited subset of types.
    /// </summary>
    /// <param name="typ">The type to evaluate</param>
    /// <returns>The SQLite type affinity for that type.</returns>
    internal static TypeAffinity TypeToAffinity(Type typ)
    {
      switch (Type.GetTypeCode(typ))

      {
        case TypeCode.DBNull:
          return TypeAffinity.Null;
        case TypeCode.String:
          return TypeAffinity.Text;



        case TypeCode.DateTime:

          return TypeAffinity.DateTime;
        case TypeCode.Int16:
        case TypeCode.Int32:
        case TypeCode.Int64:
        case TypeCode.UInt16:
        case TypeCode.UInt32:
        case TypeCode.UInt64:
        case TypeCode.Char:
        case TypeCode.SByte:
        case TypeCode.Byte:
        case TypeCode.Boolean:
          return TypeAffinity.Int64;
        case TypeCode.Double:
        case TypeCode.Single:
        case TypeCode.Decimal:
          return TypeAffinity.Double;
        case TypeCode.Object:
          if (typ == typeof(byte[])) return TypeAffinity.Blob;
          else return TypeAffinity.Text;
      }
      return TypeAffinity.Text;

    }

    /// <summary>
    /// For a given type name, return a closest-match .NET type
    /// </summary>
    /// <param name="Name">The name of the type to match</param>
    /// <returns>The .NET DBType the text evaluates to.</returns>
    internal static DbType TypeNameToDbType(string Name)
    {
      if (Name == null) return DbType.Object;

      Name = Name.ToUpper();


      if (Name.IndexOf("LONGTEXT") > -1) return DbType.String;
      if (Name.IndexOf("LONGCHAR") > -1) return DbType.String;
      if (Name.IndexOf("SMALLINT") > -1) return DbType.Int16;
      if (Name.IndexOf("BIGINT") > -1) return DbType.Int64;
      if (Name.IndexOf("COUNTER") > -1) return DbType.Int64;
      if (Name.IndexOf("AUTOINCREMENT") > -1) return DbType.Int64;
      if (Name.IndexOf("IDENTITY") > -1) return DbType.Int64;
      if (Name.IndexOf("LONG") > -1) return DbType.Int64;
      if (Name.IndexOf("TINYINT") > -1) return DbType.Byte;
      if (Name.IndexOf("INTEGER") > -1) return DbType.Int64;
      if (Name.IndexOf("INT") > -1) return DbType.Int32;
      if (Name.IndexOf("TEXT") > -1) return DbType.String;
      if (Name.IndexOf("DOUBLE") > -1) return DbType.Double;
      if (Name.IndexOf("FLOAT") > -1) return DbType.Double;
      if (Name.IndexOf("REAL") > -1) return DbType.Single;
      if (Name.IndexOf("BIT") > -1) return DbType.Boolean;
      if (Name.IndexOf("YESNO") > -1) return DbType.Boolean;
      if (Name.IndexOf("LOGICAL") > -1) return DbType.Boolean;
      if (Name.IndexOf("BOOL") > -1) return DbType.Boolean;
      if (Name.IndexOf("NUMERIC") > -1) return DbType.Decimal;
      if (Name.IndexOf("DECIMAL") > -1) return DbType.Decimal;
      if (Name.IndexOf("MONEY") > -1) return DbType.Decimal;
      if (Name.IndexOf("CURRENCY") > -1) return DbType.Decimal;
      if (Name.IndexOf("TIME") > -1) return DbType.DateTime;
      if (Name.IndexOf("DATE") > -1) return DbType.DateTime;
      if (Name.IndexOf("BLOB") > -1) return DbType.Binary;
      if (Name.IndexOf("BINARY") > -1) return DbType.Binary;
      if (Name.IndexOf("IMAGE") > -1) return DbType.Binary;
      if (Name.IndexOf("GENERAL") > -1) return DbType.Binary;
      if (Name.IndexOf("OLEOBJECT") > -1) return DbType.Binary;
      if (Name.IndexOf("GUID") > -1) return DbType.Guid;
      if (Name.IndexOf("UNIQUEIDENTIFIER") > -1) return DbType.Guid;
      if (Name.IndexOf("MEMO") > -1) return DbType.String;
      if (Name.IndexOf("NOTE") > -1) return DbType.String;
      if (Name.IndexOf("CHAR") > -1) return DbType.String;

      return DbType.Object;
    }
    #endregion
  }








































}

Changes to System.Data.SQLite/SQLiteDataAdapter.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.ComponentModel;

  /// <summary>
  /// SQLite implementation of DbDataAdapter.
  /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
  [DefaultEvent("RowUpdated")]
#endif
  public sealed class SQLiteDataAdapter : DbDataAdapter
  {
    private static object _updatingEventPH = new object();
    private static object _updatedEventPH = new object();

    /// <overloads>
    /// This class is just a shell around the DbDataAdapter.  Nothing from DbDataAdapter is overridden here, just a few constructors are defined.
    /// </overloads>
    /// <summary>
    /// Default constructor.
    /// </summary>
    public SQLiteDataAdapter()












<




<
<
<


<
<
<







1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16



17
18



19
20
21
22
23
24
25
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;


  /// <summary>
  /// SQLite implementation of DbDataAdapter.
  /// </summary>



  public sealed class SQLiteDataAdapter : DbDataAdapter
  {



    /// <overloads>
    /// This class is just a shell around the DbDataAdapter.  Nothing from DbDataAdapter is overridden here, just a few constructors are defined.
    /// </overloads>
    /// <summary>
    /// Default constructor.
    /// </summary>
    public SQLiteDataAdapter()
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
    {
      SelectCommand = cmd;
    }

    /// <summary>
    /// Constructs a data adapter with the supplied select command text and associated with the specified connection.
    /// </summary>
    /// <param name="commandText">The select command text to associate with the data adapter.</param>
    /// <param name="cnn">The connection to associate with the select command.</param>
    public SQLiteDataAdapter(string commandText, SQLiteConnection cnn)
    {
      SelectCommand = new SQLiteCommand(commandText, cnn);
    }

    /// <summary>
    /// Constructs a data adapter with the specified select command text, and using the specified database connection string.
    /// </summary>
    /// <param name="commandText">The select command text to use to construct a select command.</param>
    /// <param name="connectionString">A connection string suitable for passing to a new SQLiteConnection, which is associated with the select command.</param>
    public SQLiteDataAdapter(string commandText, string connectionString)
    {
      SQLiteConnection cnn = new SQLiteConnection(connectionString);
      SelectCommand = new SQLiteCommand(commandText, cnn);
    }

    /// <summary>
    /// Row updating event handler
    /// </summary>
    public event EventHandler<RowUpdatingEventArgs> RowUpdating
    {
      add { base.Events.AddHandler(_updatingEventPH, value); }
      remove { base.Events.RemoveHandler(_updatingEventPH, value); }
    }

    /// <summary>
    /// Row updated event handler
    /// </summary>
    public event EventHandler<RowUpdatedEventArgs> RowUpdated
    {
      add { base.Events.AddHandler(_updatedEventPH, value); }
      remove { base.Events.RemoveHandler(_updatedEventPH, value); }
    }

    /// <summary>
    /// Raised by the underlying DbDataAdapter when a row is being updated
    /// </summary>
    /// <param name="value">The event's specifics</param>
    protected override void OnRowUpdating(RowUpdatingEventArgs value)
    {
      EventHandler<RowUpdatingEventArgs> handler = base.Events[_updatingEventPH] as EventHandler<RowUpdatingEventArgs>;

      if (handler != null)
        handler(this, value);
    }

    /// <summary>
    /// Raised by DbDataAdapter after a row is updated
    /// </summary>
    /// <param name="value">The event's specifics</param>
    protected override void OnRowUpdated(RowUpdatedEventArgs value)
    {
      EventHandler<RowUpdatedEventArgs> handler = base.Events[_updatedEventPH] as EventHandler<RowUpdatedEventArgs>;

      if (handler != null)
        handler(this, value);
    }

    /// <summary>
    /// Gets/sets the select command for this DataAdapter
    /// </summary>
    public new SQLiteCommand SelectCommand
    {
      get { return (SQLiteCommand)base.SelectCommand; }
      set { base.SelectCommand = value; }
    }

    /// <summary>
    /// Gets/sets the insert command for this DataAdapter
    /// </summary>
    public new SQLiteCommand InsertCommand
    {
      get { return (SQLiteCommand)base.InsertCommand; }
      set { base.InsertCommand = value; }
    }

    /// <summary>
    /// Gets/sets the update command for this DataAdapter
    /// </summary>
    public new SQLiteCommand UpdateCommand
    {
      get { return (SQLiteCommand)base.UpdateCommand; }
      set { base.UpdateCommand = value; }
    }

    /// <summary>
    /// Gets/sets the delete command for this DataAdapter
    /// </summary>
    public new SQLiteCommand DeleteCommand
    {
      get { return (SQLiteCommand)base.DeleteCommand; }
      set { base.DeleteCommand = value; }
    }
  }
}







|

|

|





|
|
|

|
|

|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58







59







































































    {
      SelectCommand = cmd;
    }

    /// <summary>
    /// Constructs a data adapter with the supplied select command text and associated with the specified connection.
    /// </summary>
    /// <param name="CommandText">The select command text to associate with the data adapter.</param>
    /// <param name="cnn">The connection to associate with the select command.</param>
    public SQLiteDataAdapter(string CommandText, SQLiteConnection cnn)
    {
      SelectCommand = new SQLiteCommand(CommandText, cnn);
    }

    /// <summary>
    /// Constructs a data adapter with the specified select command text, and using the specified database connection string.
    /// </summary>
    /// <param name="CommandText">The select command text to use to construct a select command.</param>
    /// <param name="ConnectionString">A connection string suitable for passing to a new SQLiteConnection, which is associated with the select command.</param>
    public SQLiteDataAdapter(string CommandText, string ConnectionString)
    {
      SQLiteConnection cnn = new SQLiteConnection(ConnectionString);
      SelectCommand = new SQLiteCommand(CommandText, cnn);
    }
  }







}







































































Changes to System.Data.SQLite/SQLiteDataReader.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15




16
17
18
19
20
21
22
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;
  using System.Globalization;
  using System.Reflection;





  /// <summary>
  /// SQLite implementation of DbDataReader.
  /// </summary>
  public sealed class SQLiteDataReader : DbDataReader
  {
    /// <summary>













|
|
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;

  internal struct SQLiteType
  {
    internal DbType         Type;
    internal TypeAffinity Affinity;
  }

  /// <summary>
  /// SQLite implementation of DbDataReader.
  /// </summary>
  public sealed class SQLiteDataReader : DbDataReader
  {
    /// <summary>
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    private SQLiteType[]    _fieldTypeArray;

    /// <summary>
    /// The behavior of the datareader
    /// </summary>
    private CommandBehavior _commandBehavior;

    /// <summary>
    /// Internal constructor, initializes the datareader and sets up to begin executing statements
    /// </summary>
    /// <param name="cmd">The SQLiteCommand this data reader is for</param>
    /// <param name="behave">The expected behavior of the data reader</param>
    internal SQLiteDataReader(SQLiteCommand cmd, CommandBehavior behave)
    {
      _command = cmd;
      _commandBehavior = behave;
      Initialize();

      if (_command != null)
        NextResult();
    }

    /// <summary>
    /// Initializes and resets the datareader's member variables
    /// </summary>
    internal void Initialize()
    {
      _activeStatementIndex = -1;
      _activeStatement = null;
      _rowsAffected = -1;
      _fieldCount = -1;


    }

    /// <summary>
    /// Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified.
    /// </summary>
    public override void Close()
    {
      if (_command != null)
      {
        while (NextResult())
        {
        }
        _command.ClearDataReader();
      }

      // If the datareader's behavior includes closing the connection, then do so here.
      if ((_commandBehavior & CommandBehavior.CloseConnection) != 0)
        _command.Connection.Close();

      _command = null;
      _activeStatement = null;
      _fieldTypeArray = null;
    }

    /// <summary>
    /// Disposes the datareader.  Calls Close() to ensure everything is cleaned up.
    /// </summary>
    protected override void Dispose(bool disposing)
    {
      Close();
      base.Dispose(disposing);
    }

    /// <summary>
    /// Throw an error if the datareader is closed
    /// </summary>
    private void CheckClosed()
    {
      if (_command == null)
        throw new InvalidOperationException("DataReader has been closed");
    }

    /// <summary>
    /// Throw an error if a row is not loaded
    /// </summary>
    private void CheckValidRow()
    {
      if (_readingState != 0)
        throw new InvalidOperationException("No current row");
    }

    /// <summary>
    /// Enumerator support
    /// </summary>
    /// <returns>Returns a DbEnumerator object.</returns>
    public override Collections.IEnumerator GetEnumerator()
    {
      return new DbEnumerator(this);
    }

    /// <summary>
    /// Not implemented.  Returns 0
    /// </summary>
    public override int Depth
    {
      get
      {
        CheckClosed();
        return 0;
      }
    }

    /// <summary>
    /// Returns the number of columns in the current resultset
    /// </summary>
    public override int FieldCount
    {
      get
      {
        CheckClosed();
        return _fieldCount;







<
<
<
<
<





|
<
<
|
<
<
<
<






>
>









|
<
<








<
<





|


|











<
<
<
<
<
<
<
<
<










|











|







57
58
59
60
61
62
63





64
65
66
67
68
69


70




71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88


89
90
91
92
93
94
95
96


97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116









117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
    private SQLiteType[]    _fieldTypeArray;

    /// <summary>
    /// The behavior of the datareader
    /// </summary>
    private CommandBehavior _commandBehavior;






    internal SQLiteDataReader(SQLiteCommand cmd, CommandBehavior behave)
    {
      _command = cmd;
      _commandBehavior = behave;
      Initialize();
    }







    internal void Initialize()
    {
      _activeStatementIndex = -1;
      _activeStatement = null;
      _rowsAffected = -1;
      _fieldCount = -1;

      NextResult();
    }

    /// <summary>
    /// Closes the datareader, potentially closing the connection as well if CommandBehavior.CloseConnection was specified.
    /// </summary>
    public override void Close()
    {
      if (_command != null)
      {
        while (NextResult()) ;


        _command.ClearDataReader();
      }

      // If the datareader's behavior includes closing the connection, then do so here.
      if ((_commandBehavior & CommandBehavior.CloseConnection) != 0)
        _command.Connection.Close();

      _command = null;


    }

    /// <summary>
    /// Disposes the datareader.  Calls Close() to ensure everything is cleaned up.
    /// </summary>
    public override void Dispose()
    {
      Close();
      GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Throw an error if the datareader is closed
    /// </summary>
    private void CheckClosed()
    {
      if (_command == null)
        throw new InvalidOperationException("DataReader has been closed");
    }










    /// <summary>
    /// Enumerator support
    /// </summary>
    /// <returns>Returns a DbEnumerator object.</returns>
    public override Collections.IEnumerator GetEnumerator()
    {
      return new DbEnumerator(this);
    }

    /// <summary>
    /// 
    /// </summary>
    public override int Depth
    {
      get
      {
        CheckClosed();
        return 0;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override int FieldCount
    {
      get
      {
        CheckClosed();
        return _fieldCount;
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187


188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

255
256
257























258





259









260


261
262
263
264
265

266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283

284
285
286
287
288
289

290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312


313
314
315
316
317
318
319

320
321
322








323
324

325
326
327
328
329
330
331

332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
    /// This function attempts to verify that the type of data being requested of a column matches the datatype of the column.  In
    /// the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob)
    /// to a set of known types that closely match that affinity.  It's not an exact science, but its the best we can do.
    /// </summary>
    /// <returns>
    /// This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity.
    /// </returns>
    /// <param name="i">The index of the column to type-check</param>
    /// <param name="typ">The type we want to get out of the column</param>
    private void VerifyType(int i, DbType typ)
    {
      CheckValidRow();
      SQLiteType t = GetSQLiteType(i);

      if (t.Type == typ) return;



        // Coercable type, usually a literal of some kind
      switch (_fieldTypeArray[i].Affinity)
      {
        case TypeAffinity.Int64:
          if (typ == DbType.Int16) return;
          if (typ == DbType.Int32) return;
          if (typ == DbType.Int64) return;
          if (typ == DbType.Boolean) return;
          if (typ == DbType.Byte) return;
          break;
        case TypeAffinity.Double:
          if (typ == DbType.Single) return;
          if (typ == DbType.Double) return;
          if (typ == DbType.Decimal) return;
          break;
        case TypeAffinity.Text:
          if (typ == DbType.SByte) return;
          if (typ == DbType.String) return;
          if (typ == DbType.SByte) return;
          if (typ == DbType.Guid) return;
          if (typ == DbType.DateTime) return;
          break;
        case TypeAffinity.Blob:
          if (typ == DbType.String) return;
          if (typ == DbType.Binary) return;
          break;

      }

      throw new InvalidCastException();
    }

    /// <summary>
    /// Retrieves the column as a boolean value
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>bool</returns>
    public override bool GetBoolean(int i)
    {

      VerifyType(i, DbType.Boolean);
      return Convert.ToBoolean(GetValue(i), CultureInfo.CurrentCulture);
    }

    /// <summary>
    /// Retrieves the column as a single byte value
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>byte</returns>
    public override byte GetByte(int i)
    {

      VerifyType(i, DbType.Byte);
      return Convert.ToByte(_activeStatement._sql.GetInt32(_activeStatement, i));
    }

    /// <summary>
    /// Retrieves a column as an array of bytes (blob)
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <param name="fieldOffset">The zero-based index of where to begin reading the data</param>
    /// <param name="buffer">The buffer to write the bytes into</param>
    /// <param name="bufferoffset">The zero-based index of where to begin writing into the array</param>
    /// <param name="length">The number of bytes to retrieve</param>
    /// <returns>The actual number of bytes written into the array</returns>
    /// <remarks>
    /// To determine the number of bytes in the column, pass a null value for the buffer.  The total length will be returned.
    /// </remarks>
    public override long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
    {

      VerifyType(i, DbType.Binary);
      return _activeStatement._sql.GetBytes(_activeStatement, i, (int)fieldOffset, buffer, bufferoffset, length);
    }





























    /// <summary>









    /// Returns the column as a single character


    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>char</returns>
    public override char GetChar(int i)
    {

      VerifyType(i, DbType.SByte);
      return Convert.ToChar(_activeStatement._sql.GetInt32(_activeStatement, i));
    }

    /// <summary>
    /// Retrieves a column as an array of chars (blob)
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <param name="fieldoffset">The zero-based index of where to begin reading the data</param>
    /// <param name="buffer">The buffer to write the characters into</param>
    /// <param name="bufferoffset">The zero-based index of where to begin writing into the array</param>
    /// <param name="length">The number of bytes to retrieve</param>
    /// <returns>The actual number of characters written into the array</returns>
    /// <remarks>
    /// To determine the number of characters in the column, pass a null value for the buffer.  The total length will be returned.
    /// </remarks>
    public override long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
    {

      VerifyType(i, DbType.String);
      return _activeStatement._sql.GetChars(_activeStatement, i, (int)fieldoffset, buffer, bufferoffset, length);
    }

    /// <summary>
    /// Retrieves the name of the back-end datatype of the column

    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>string</returns>
    public override string GetDataTypeName(int i)
    {
      CheckClosed();
      SQLiteType typ = GetSQLiteType(i);

      if (typ.Type == DbType.Object) return SQLiteConvert.SQLiteTypeToType(typ).Name;

      return _activeStatement._sql.ColumnType(_activeStatement, i, out typ.Affinity);
    }

    /// <summary>
    /// Retrieve the column as a date/time value
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>DateTime</returns>
    public override DateTime GetDateTime(int i)
    {

      VerifyType(i, DbType.DateTime);
      return _activeStatement._sql.GetDateTime(_activeStatement, i);
    }



    /// <summary>
    /// Retrieve the column as a decimal value
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>decimal</returns>
    public override decimal GetDecimal(int i)

    {
      VerifyType(i, DbType.Decimal);
      return Convert.ToDecimal(_activeStatement._sql.GetDouble(_activeStatement, i));








    }


    /// <summary>
    /// Returns the column as a double
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>double</returns>
    public override double GetDouble(int i)
    {

      VerifyType(i, DbType.Double);
      return _activeStatement._sql.GetDouble(_activeStatement, i);
    }

    /// <summary>
    /// Returns the .NET type of a given column
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>Type</returns>
    public override Type GetFieldType(int i)
    {
      return SQLiteConvert.SQLiteTypeToType(GetSQLiteType(i));
    }

    /// <summary>
    /// Returns a column as a float value
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>float</returns>
    public override float GetFloat(int i)
    {
      VerifyType(i, DbType.Single);
      return Convert.ToSingle(_activeStatement._sql.GetDouble(_activeStatement, i));
    }

    /// <summary>
    /// Returns the column as a Guid
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>Guid</returns>
    public override Guid GetGuid(int i)
    {
      VerifyType(i, DbType.Guid);
      return new Guid(_activeStatement._sql.GetText(_activeStatement, i));
    }

    /// <summary>
    /// Returns the column as a short
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>Int16</returns>
    public override Int16 GetInt16(int i)
    {

      VerifyType(i, DbType.Int16);
      return Convert.ToInt16(_activeStatement._sql.GetInt32(_activeStatement, i));
    }

    /// <summary>
    /// Retrieves the column as an int
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>Int32</returns>
    public override Int32 GetInt32(int i)
    {

      VerifyType(i, DbType.Int32);
      return _activeStatement._sql.GetInt32(_activeStatement, i);
    }

    /// <summary>
    /// Retrieves the column as a long
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>Int64</returns>
    public override Int64 GetInt64(int i)
    {

      VerifyType(i, DbType.Int64);
      return _activeStatement._sql.GetInt64(_activeStatement, i);
    }

    /// <summary>
    /// Retrieves the name of the column
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>string</returns>
    public override string GetName(int i)
    {
      CheckClosed();
      return _activeStatement._sql.ColumnName(_activeStatement, i);
    }

    /// <summary>
    /// Retrieves the i of a column, given its name
    /// </summary>
    /// <param name="name">The name of the column to retrieve</param>
    /// <returns>The int i of the column</returns>
    public override int GetOrdinal(string name)
    {
      CheckClosed();
      return _activeStatement._sql.ColumnIndex(_activeStatement, name);
    }

    /// <summary>







|

|

<
|



>
>

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






<

|
|
|

>
|
|



|

|
|
|

>
|
|



|

|
|
|
|
|
<
|
<
<
|

>
|
|

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

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

|
|
|

>
|
|



|

|
<
<
<
<
<
|
<
<
|

>
|
|



<
>

|
|
|


<
|
<
<
|



|

|
|
|

>
|
<
|
>
>

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

|

|
|
|

>
|
|



|

|
|
|

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

|

|
|
|

>
|
|



|

|
|
|

>
|
|



|

|
|
|

>
|
|



|

|
|
|


|



|

|
|







154
155
156
157
158
159
160
161
162
163
164

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

204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

234


235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296





297


298
299
300
301
302
303
304
305

306
307
308
309
310
311
312

313


314
315
316
317
318
319
320
321
322
323
324
325

326
327
328
329






330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363


364







365
366

367






368




369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
    /// This function attempts to verify that the type of data being requested of a column matches the datatype of the column.  In
    /// the case of columns that are not backed into a table definition, we attempt to match up the affinity of a column (int, double, string or blob)
    /// to a set of known types that closely match that affinity.  It's not an exact science, but its the best we can do.
    /// </summary>
    /// <returns>
    /// This function throws an InvalidTypeCast() exception if the requested type doesn't match the column's definition or affinity.
    /// </returns>
    /// <param name="ordinal">The index of the column to type-check</param>
    /// <param name="typ">The type we want to get out of the column</param>
    private void VerifyType(int ordinal, DbType typ)
    {

      SQLiteType t = GetSQLiteType(ordinal);

      if (t.Type == typ) return;

      if (t.Type != DbType.Object)
      {
        // Coercable type, usually a literal of some kind
        switch (_fieldTypeArray[ordinal].Affinity)
        {
          case TypeAffinity.Int64:
            if (typ == DbType.Int16) return;
            if (typ == DbType.Int32) return;
            if (typ == DbType.Int64) return;
            if (typ == DbType.Boolean) return;
            if (typ == DbType.Byte) return;
            break;
          case TypeAffinity.Double:
            if (typ == DbType.Single) return;
            if (typ == DbType.Double) return;
            if (typ == DbType.Decimal) return;
            break;
          case TypeAffinity.Text:
            if (typ == DbType.SByte) return;
            if (typ == DbType.String) return;
            if (typ == DbType.SByte) return;
            if (typ == DbType.Guid) return;
            if (typ == DbType.DateTime) return;
            break;
          case TypeAffinity.Blob:
            if (typ == DbType.String) return;
            if (typ == DbType.Binary) return;
            break;
        }
      }

      throw new InvalidCastException();
    }

    /// <summary>

    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override bool GetBoolean(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.Boolean);
      return Convert.ToBoolean(GetValue(ordinal));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override byte GetByte(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.Byte);
      return Convert.ToByte(_activeStatement._sql.GetInt32(_activeStatement, ordinal));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <param name="dataOffset"></param>
    /// <param name="buffer"></param>
    /// <param name="bufferOffset"></param>
    /// <param name="length"></param>

    /// <returns></returns>


    public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.Binary);
      return _activeStatement._sql.GetBytes(_activeStatement, ordinal, (int)dataOffset, buffer, bufferOffset, length);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override char GetChar(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.SByte);
      return Convert.ToChar(_activeStatement._sql.GetInt32(_activeStatement, ordinal));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <param name="dataOffset"></param>
    /// <param name="buffer"></param>
    /// <param name="bufferOffset"></param>
    /// <param name="length"></param>
    /// <returns></returns>
    public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.String);
      return _activeStatement._sql.GetChars(_activeStatement, ordinal, (int)dataOffset, buffer, bufferOffset, length);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override string GetDataTypeName(int ordinal)
    {
      CheckClosed();
      return _activeStatement._sql.ColumnName(_activeStatement, ordinal);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override DateTime GetDateTime(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.DateTime);
      return _activeStatement._sql.GetDateTime(_activeStatement, ordinal);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>





    /// <returns></returns>


    public override decimal GetDecimal(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.Decimal);
      return Convert.ToDecimal(_activeStatement._sql.GetDouble(_activeStatement, ordinal));
    }

    /// <summary>

    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override double GetDouble(int ordinal)
    {
      CheckClosed();

      VerifyType(ordinal, DbType.Double);


      return _activeStatement._sql.GetDouble(_activeStatement, ordinal);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override Type GetFieldType(int ordinal)
    {
      CheckClosed();
      SQLiteType t = GetSQLiteType(ordinal);


      if (t.Type != DbType.Object)
        return SQLiteConvert.DbTypeToType(t.Type);







      switch (t.Affinity)
      {
        case TypeAffinity.Null:
          return typeof(DBNull);
        case TypeAffinity.Int64:
          return typeof(Int64);
        case TypeAffinity.Double:
          return typeof(Double);
        case TypeAffinity.Blob:
          return typeof(byte[]);
        default:
          return typeof(string);
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override float GetFloat(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.Single);
      return Convert.ToSingle(_activeStatement._sql.GetDouble(_activeStatement, ordinal));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override Guid GetGuid(int ordinal)
    {


      CheckClosed();







      VerifyType(ordinal, DbType.Guid);
      return new Guid(_activeStatement._sql.GetText(_activeStatement, ordinal));

    }











    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override Int16 GetInt16(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.Int16);
      return Convert.ToInt16(_activeStatement._sql.GetInt32(_activeStatement, ordinal));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override Int32 GetInt32(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.Int32);
      return _activeStatement._sql.GetInt32(_activeStatement, ordinal);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override Int64 GetInt64(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.Int64);
      return _activeStatement._sql.GetInt64(_activeStatement, ordinal);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override string GetName(int ordinal)
    {
      CheckClosed();
      return _activeStatement._sql.ColumnName(_activeStatement, ordinal);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public override int GetOrdinal(string name)
    {
      CheckClosed();
      return _activeStatement._sql.ColumnIndex(_activeStatement, name);
    }

    /// <summary>
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498

499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550

551
552
553
554
555
556

557
558
559
560
561
562
563
564
565
566
567
568




569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587

588
589
590
591
592
593

594
595
596
597
598


599

600



601

602
603



604
605

606
607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665


666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705

706
707
708

709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
    /// original connection's existing statements or state.  Any attached databases are re-attached to the new connection.
    /// </remarks>
    /// <returns>Returns a DataTable containing the schema information for the active SELECT statement being processed.</returns>
    public override DataTable GetSchemaTable()
    {
      CheckClosed();

      DataTable tbl = new DataTable("SchemaTable");
      string[] arName;
      string strTable;
      string strCatalog;
      DataRow row;

      tbl.Locale = CultureInfo.InvariantCulture;
      tbl.Columns.Add(SchemaTableColumn.ColumnName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.ColumnOrdinal, typeof(int));
      tbl.Columns.Add(SchemaTableColumn.ColumnSize, typeof(int));
      tbl.Columns.Add(SchemaTableColumn.NumericPrecision, typeof(short));
      tbl.Columns.Add(SchemaTableColumn.NumericScale, typeof(short));
      tbl.Columns.Add(SchemaTableColumn.IsUnique, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.IsKey, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.BaseServerName, typeof(string));
      tbl.Columns.Add(SchemaTableOptionalColumn.BaseCatalogName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.BaseColumnName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.BaseSchemaName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.BaseTableName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.DataType, typeof(Type));
      tbl.Columns.Add(SchemaTableColumn.AllowDBNull, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.ProviderType, typeof(int));
      tbl.Columns.Add(SchemaTableColumn.IsAliased, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.IsExpression, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsAutoIncrement, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsRowVersion, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsHidden, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.IsLong, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsReadOnly, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.ProviderSpecificDataType, typeof(Type));
      tbl.Columns.Add(SchemaTableOptionalColumn.DefaultValue, typeof(object));

      tbl.BeginLoadData();

      SQLiteConnection cnn = (SQLiteConnection)_command.Connection;

      try
      {
        cnn._sql.SetRealColNames(true);

        // Create a new command based on the original.  The only difference being that this new command returns
        // fully-qualified Database.Table.Column column names because of the above pragma
        using (SQLiteCommand cmd = (SQLiteCommand)_command.Clone())
        {
          using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.SchemaOnly))
          {
            // No need to Read() from this reader, we just want the column names
            for (int n = 0; n < _fieldCount; n++)
            {
              strTable = "";
              strCatalog = "main";

              row = tbl.NewRow();

              // Default settings for the column
              row[SchemaTableColumn.ColumnName] = GetName(n);
              row[SchemaTableColumn.ColumnOrdinal] = n;
              row[SchemaTableColumn.ColumnSize] = 0;
              row[SchemaTableColumn.NumericPrecision] = 0;
              row[SchemaTableColumn.NumericScale] = 0;

              row[SchemaTableColumn.ProviderType] = GetSQLiteType(n).Type;
              row[SchemaTableColumn.IsLong] = false;
              row[SchemaTableColumn.AllowDBNull] = true;
              row[SchemaTableOptionalColumn.IsReadOnly] = false;
              row[SchemaTableOptionalColumn.IsRowVersion] = false;
              row[SchemaTableColumn.IsUnique] = false;
              row[SchemaTableColumn.IsKey] = false;
              row[SchemaTableOptionalColumn.IsAutoIncrement] = false;
              row[SchemaTableOptionalColumn.IsReadOnly] = false;
              row[SchemaTableColumn.BaseColumnName] = GetName(n);

              // Try and extract the database, table and column from the datareader
              arName = rd.GetName(n).Split('\x01');

              if (arName.Length > 1)
                strTable = arName[arName.Length - 2];

              if (arName.Length > 2)
                strCatalog = arName[arName.Length - 3];

              // If we have a table-bound column, extract the extra information from it
              if (arName.Length > 1)
              {
                using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{1}].TABLE_INFO([{0}])", strTable, strCatalog), cnn))
                {
                  if (arName.Length < 3) strCatalog = "main";

                  using (DbDataReader rdTable = cmdTable.ExecuteReader())
                  {
                    while (rdTable.Read())
                    {
                      if (String.Compare(arName[arName.Length - 1], rdTable.GetString(1), true, CultureInfo.InvariantCulture) == 0)
                      {
                        string strType = rdTable.GetString(2);
                        string[] arSize = strType.Split('(');
                        if (arSize.Length > 1)
                        {
                          strType = arSize[0];
                          arSize = arSize[1].Split(')');
                          if (arSize.Length > 1)
                            row[SchemaTableColumn.ColumnSize] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture);
                        }

                        bool bNotNull = rdTable.GetBoolean(3);
                        bool bPrimaryKey = rdTable.GetBoolean(5);

                        row[SchemaTableColumn.DataType] = GetFieldType(n);
                        row[SchemaTableColumn.BaseTableName] = strTable;
                        row[SchemaTableColumn.BaseColumnName] = rdTable.GetString(1);
                        if (String.IsNullOrEmpty(strCatalog) == false)
                        {
                          row[SchemaTableOptionalColumn.BaseCatalogName] = strCatalog;

                        }

                        row[SchemaTableColumn.AllowDBNull] = (!bNotNull && !bPrimaryKey);
                        row[SchemaTableColumn.IsUnique] = bPrimaryKey;
                        row[SchemaTableColumn.IsKey] = bPrimaryKey;
                        row[SchemaTableOptionalColumn.IsAutoIncrement] = bPrimaryKey;

                        if (rdTable.IsDBNull(4) == false)
                          row[SchemaTableOptionalColumn.DefaultValue] = rdTable[4];
                        break;
                      }
                    }
                  }
                }
              }
              tbl.Rows.Add(row);
            }
          }
        }




      }
      finally
      {
        cnn._sql.SetRealColNames(false);
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// Retrieves the column as a string
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>string</returns>
    public override string GetString(int i)
    {

      VerifyType(i, DbType.String);
      return _activeStatement._sql.GetText(_activeStatement, i);
    }

    /// <summary>
    /// Retrieves the column as an object corresponding to the underlying datatype of the column

    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>object</returns>
    public override object GetValue(int i)
    {


      SQLiteType typ = GetSQLiteType(i);





      return _activeStatement._sql.GetValue(_activeStatement, i, ref typ);

    }




    /// <summary>
    /// Retreives the values of multiple columns, up to the size of the supplied array

    /// </summary>
    /// <param name="values">The array to fill with values from the columns in the current resultset</param>
    /// <returns>The number of columns retrieved</returns>
    public override int GetValues(object[] values)
    {

      int nMax = _fieldCount;
      if (values.Length < nMax) nMax = values.Length;

      for (int n = 0; n < nMax; n++)
      {
        values.SetValue(GetValue(n), n);
      }

      return nMax;
    }

    /// <summary>
    /// Returns True if the resultset has rows that can be fetched
    /// </summary>
    public override bool HasRows
    {
      get
      {
        CheckClosed();
        return (_readingState != 1);
      }
    }

    /// <summary>
    /// Returns True if the data reader is closed
    /// </summary>
    public override bool IsClosed
    {
      get { return (_command == null); }
    }

    /// <summary>
    /// Returns True if the specified column is null
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>True or False</returns>
    public override bool IsDBNull(int i)
    {
      CheckClosed();
      return _activeStatement._sql.IsNull(_activeStatement, i);
    }

    /// <summary>
    /// Moves to the next resultset in multiple row-returning SQL command.
    /// </summary>
    /// <returns>True if the command was successful and a new resultset is available, False otherwise.</returns>
    public override bool NextResult()
    {
      CheckClosed();

      SQLiteStatement stmt = null;
      int fieldCount;

      while (true)
      {


        if (_activeStatement != null && stmt == null)
        {
          // Reset the previously-executed statement
          _activeStatement._sql.Reset(_activeStatement);
          
          // If we're only supposed to return a single rowset, step through all remaining statements once until
          // they are all done and return false to indicate no more resultsets exist.
          if ((_commandBehavior & CommandBehavior.SingleResult) != 0)
          {
            for (; ; )
            {
              stmt = _command.GetStatement(_activeStatementIndex + 1);
              if (stmt == null) break;
              _activeStatementIndex++;

              stmt._sql.Step(stmt);
              if (stmt._sql.ColumnCount(stmt) == 0)
              {
                if (_rowsAffected == -1) _rowsAffected = 0;
                _rowsAffected += stmt._sql.Changes;
              }
              stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!
            }
            return false;
          }
        }

        // Get the next statement to execute
        stmt = _command.GetStatement(_activeStatementIndex + 1);

        // If we've reached the end of the statements, return false, no more resultsets
        if (stmt == null)
          return false;

        // If we were on a current resultset, set the state to "done reading" for it
        if (_readingState < 1)
          _readingState = 1;

        _activeStatementIndex++;


        fieldCount = stmt._sql.ColumnCount(stmt);

        // If the statement is not a select statement or we're not retrieving schema only, then perform the initial step

        if ((_commandBehavior & CommandBehavior.SchemaOnly) == 0 || fieldCount == 0)
        {
          if (stmt._sql.Step(stmt))
          {
            _readingState = -1;
          }
          else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement
          {
            if (_rowsAffected == -1) _rowsAffected = 0;
            _rowsAffected += stmt._sql.Changes;
            stmt._sql.Reset(stmt);
            continue; // Skip this command and move to the next, it was not a row-returning resultset
          }
          else // No rows, fieldCount is non-zero so stop here
          {
            _readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false
          }
        }

        // Ahh, we found a row-returning resultset eligible to be returned!
        _activeStatement = stmt;
        _fieldCount = fieldCount;
        _fieldTypeArray = null;

        return true;
      }
    }

    /// <summary>
    /// Retrieves the SQLiteType for a given column, and caches it to avoid repetetive interop calls.
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>A SQLiteType structure</returns>
    private SQLiteType GetSQLiteType(int i)
    {
      CheckClosed();
      if (_fieldTypeArray == null) _fieldTypeArray = new SQLiteType[_fieldCount];

      if (_fieldTypeArray[i].Affinity == TypeAffinity.Uninitialized || _fieldTypeArray[i].Affinity == TypeAffinity.Null)
        _fieldTypeArray[i].Type = SQLiteConvert.TypeNameToDbType(_activeStatement._sql.ColumnType(_activeStatement, i, out _fieldTypeArray[i].Affinity));
      return _fieldTypeArray[i];
    }

    /// <summary>
    /// Reads the next row from the resultset
    /// </summary>
    /// <returns>True if a new row was successfully loaded and is ready for processing</returns>
    public override bool Read()
    {
      CheckClosed();

      if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true.
      {
        _readingState = 0;







|





<

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

|
|
|
|
|












|

|


|












>



|








|










|

|





|





<


|

<



<


|

|
>





|
>












>
>
>
>













|

|
|
|

>
|
|



<
>

|
|
|

>
>
|
>
|
>
>
>
|
>
|

>
>
>

<
>

|
|


>
|











|






|




|







|

|
|
|


|



|

|




|




>
>
|

|

|




|

<
<

|

<
<
<
<
<






<
<
<

|


<
<
<
<


>


<
>








<
<


















<
<
<
<
<
|

<


|
|
|



|

|







436
437
438
439
440
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455


456


457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535

536
537
538
539

540
541
542

543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618

619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693


694
695
696





697
698
699
700
701
702



703
704
705
706




707
708
709
710
711

712
713
714
715
716
717
718
719
720


721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738





739
740

741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
    /// original connection's existing statements or state.  Any attached databases are re-attached to the new connection.
    /// </remarks>
    /// <returns>Returns a DataTable containing the schema information for the active SELECT statement being processed.</returns>
    public override DataTable GetSchemaTable()
    {
      CheckClosed();

      DataTable tbl = new DataTable("Schema");
      string[] arName;
      string strTable;
      string strCatalog;
      DataRow row;


      tbl.Columns.Add(SchemaTableColumn.ColumnName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.ColumnOrdinal, typeof(Int32));
      tbl.Columns.Add(SchemaTableColumn.ColumnSize, typeof(Int32));
      tbl.Columns.Add(SchemaTableColumn.NumericPrecision, typeof(Int32));
      tbl.Columns.Add(SchemaTableColumn.NumericScale, typeof(Int32));
      tbl.Columns.Add(SchemaTableColumn.DataType, typeof(Type));
      tbl.Columns.Add(SchemaTableColumn.ProviderType, typeof(Int32));


      tbl.Columns.Add(SchemaTableColumn.IsLong, typeof(Boolean));


      tbl.Columns.Add(SchemaTableColumn.AllowDBNull, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsReadOnly, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsRowVersion, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.IsUnique, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.IsKey, typeof(Boolean));
      tbl.Columns.Add(SchemaTableOptionalColumn.IsAutoIncrement, typeof(Boolean));
      tbl.Columns.Add(SchemaTableColumn.BaseSchemaName, typeof(String));
      tbl.Columns.Add(SchemaTableOptionalColumn.BaseCatalogName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.BaseTableName, typeof(String));
      tbl.Columns.Add(SchemaTableColumn.BaseColumnName, typeof(String));
      tbl.Columns.Add(SchemaTableOptionalColumn.BaseColumnNamespace, typeof(string));
      tbl.Columns.Add(SchemaTableOptionalColumn.DefaultValue, typeof(object));

      tbl.BeginLoadData();

      SQLiteConnection cnn = (SQLiteConnection)_command.Connection;

      try
      {
        cnn._sql.SetRealColNames(true);

        // Create a new command based on the original.  The only difference being that this new command returns
        // fully-qualified Database.Table.Column column names because of the above pragma
        using (SQLiteCommand cmd = new SQLiteCommand(_activeStatement._sqlStatement, cnn))
        {
          using (DbDataReader rd = cmd.ExecuteReader())
          {
            // No need to Read() from this reader, we just want the column names
            for (int n = 0; n < FieldCount; n++)
            {
              strTable = "";
              strCatalog = "main";

              row = tbl.NewRow();

              // Default settings for the column
              row[SchemaTableColumn.ColumnName] = GetName(n);
              row[SchemaTableColumn.ColumnOrdinal] = n;
              row[SchemaTableColumn.ColumnSize] = 0;
              row[SchemaTableColumn.NumericPrecision] = 0;
              row[SchemaTableColumn.NumericScale] = 0;
              row[SchemaTableColumn.DataType] = GetFieldType(n);
              row[SchemaTableColumn.ProviderType] = GetSQLiteType(n).Type;
              row[SchemaTableColumn.IsLong] = false;
              row[SchemaTableColumn.AllowDBNull] = true;
              row[SchemaTableOptionalColumn.IsReadOnly] = true;
              row[SchemaTableOptionalColumn.IsRowVersion] = false;
              row[SchemaTableColumn.IsUnique] = false;
              row[SchemaTableColumn.IsKey] = false;
              row[SchemaTableOptionalColumn.IsAutoIncrement] = false;
              row[SchemaTableOptionalColumn.IsReadOnly] = false;
              row[SchemaTableColumn.BaseColumnName] = GetName(n);

              // Try and extract the database, table and column from the datareader
              arName = rd.GetName(n).Split('.');

              if (arName.Length > 1)
                strTable = arName[arName.Length - 2];

              if (arName.Length > 2)
                strCatalog = arName[arName.Length - 3];

              // If we have a table-bound column, extract the extra information from it
              if (arName.Length > 1)
              {
                using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format("PRAGMA [{1}].TABLE_INFO([{0}])", strTable, strCatalog), cnn))
                {
                  if (arName.Length < 3) strCatalog = "";

                  using (DbDataReader rdTable = cmdTable.ExecuteReader())
                  {
                    while (rdTable.Read())
                    {
                      if (String.Compare(arName[arName.Length - 1], rdTable.GetString(1), true) == 0)
                      {
                        string strType = rdTable.GetString(2);
                        string[] arSize = strType.Split('(');
                        if (arSize.Length > 1)
                        {

                          arSize = arSize[1].Split(')');
                          if (arSize.Length > 1)
                            row["ColumnSize"] = Convert.ToInt32(arSize[0]);
                        }

                        bool bNotNull = rdTable.GetBoolean(3);
                        bool bPrimaryKey = rdTable.GetBoolean(5);


                        row[SchemaTableColumn.BaseTableName] = strTable;
                        row[SchemaTableColumn.BaseColumnName] = rdTable.GetString(1);
                        if (strCatalog.Length > 0)
                        {
                          row[SchemaTableOptionalColumn.BaseColumnNamespace] = strCatalog;
                          row[SchemaTableColumn.BaseSchemaName] = strCatalog;
                        }

                        row[SchemaTableColumn.AllowDBNull] = (!bNotNull && !bPrimaryKey);
                        row[SchemaTableColumn.IsUnique] = bPrimaryKey;
                        row[SchemaTableColumn.IsKey] = bPrimaryKey;
                        row[SchemaTableOptionalColumn.IsAutoIncrement] = (bPrimaryKey && String.Compare(strType, "Integer", true) == 0);
                        row[SchemaTableOptionalColumn.IsReadOnly] = !(bool)row[SchemaTableOptionalColumn.IsAutoIncrement];
                        if (rdTable.IsDBNull(4) == false)
                          row[SchemaTableOptionalColumn.DefaultValue] = rdTable[4];
                        break;
                      }
                    }
                  }
                }
              }
              tbl.Rows.Add(row);
            }
          }
        }
      }
      catch (Exception e)
      {
        throw (e);
      }
      finally
      {
        cnn._sql.SetRealColNames(false);
      }

      tbl.AcceptChanges();
      tbl.EndLoadData();

      return tbl;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override string GetString(int ordinal)
    {
      CheckClosed();
      VerifyType(ordinal, DbType.String);
      return _activeStatement._sql.GetText(_activeStatement, ordinal);
    }

    /// <summary>

    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override object GetValue(int ordinal)
    {
      CheckClosed();
      if (IsDBNull(ordinal)) return DBNull.Value;

      if (GetFieldType(ordinal) == typeof(byte[]))
      {
        int n = (int)GetBytes(ordinal, 0, null, 0, 0);
        byte[] b = new byte[n];
        GetBytes(ordinal, 0, b, 0, n);

        return b;
      }

      return Convert.ChangeType(_activeStatement._sql.GetText(_activeStatement, ordinal), GetFieldType(ordinal), null);
    }

    /// <summary>

    /// 
    /// </summary>
    /// <param name="values"></param>
    /// <returns></returns>
    public override int GetValues(object[] values)
    {
      CheckClosed();
      int nMax = FieldCount;
      if (values.Length < nMax) nMax = values.Length;

      for (int n = 0; n < nMax; n++)
      {
        values.SetValue(GetValue(n), n);
      }

      return nMax;
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool HasRows
    {
      get
      {
        CheckClosed();
        return (_readingState != 2);
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool IsClosed
    {
      get { return (_command == null); }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override bool IsDBNull(int ordinal)
    {
      CheckClosed();
      return _activeStatement._sql.IsNull(_activeStatement, ordinal);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override bool NextResult()
    {
      CheckClosed();

      SQLiteStatement stmt;
      int fieldCount;

      while (true)
      {
        _readingState = 2; // HasRows() returns false, Read() returns false

        if (_activeStatement != null)
        {
          // Reset the previously-executed command
          _activeStatement._sql.Reset(_activeStatement);

          // If we're only supposed to return a single rowset, step through all remaining statements once until
          // they are all done and return false to indicate no more resultsets exist.
          if ((_commandBehavior & CommandBehavior.SingleResult) != 0)
          {
            while (_activeStatementIndex + 1 != _command._statementList.Length)
            {


              _activeStatementIndex++;
              stmt = _command._statementList[_activeStatementIndex];
              stmt._sql.Step(stmt);





              stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!
            }
            return false;
          }
        }




        // If we've reached the end of the statements, return false, no more resultsets
        if (_activeStatementIndex + 1 == _command._statementList.Length)
          return false;





        _activeStatementIndex++;

        stmt = _command._statementList[_activeStatementIndex];
        fieldCount = stmt._sql.ColumnCount(stmt);


        // If we're told to get schema information only, then don't perform an initial step() through the resultset
        if ((_commandBehavior & CommandBehavior.SchemaOnly) == 0 || fieldCount == 0)
        {
          if (stmt._sql.Step(stmt))
          {
            _readingState = -1;
          }
          else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement
          {


            stmt._sql.Reset(stmt);
            continue; // Skip this command and move to the next, it was not a row-returning resultset
          }
          else // No rows, fieldCount is non-zero so stop here
          {
            _readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false
          }
        }

        // Ahh, we found a row-returning resultset eligible to be returned!
        _activeStatement = stmt;
        _fieldCount = fieldCount;
        _fieldTypeArray = null;

        return true;
      }
    }






    private SQLiteType GetSQLiteType(int ordinal)
    {

      if (_fieldTypeArray == null) _fieldTypeArray = new SQLiteType[_fieldCount];

      if (_fieldTypeArray[ordinal].Affinity == 0)
        _fieldTypeArray[ordinal].Type = SQLiteConvert.TypeNameToDbType(_activeStatement._sql.ColumnType(_activeStatement, ordinal, out _fieldTypeArray[ordinal].Affinity));
      return _fieldTypeArray[ordinal];
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override bool Read()
    {
      CheckClosed();

      if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true.
      {
        _readingState = 0;
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
        _readingState = 1; // Finished reading rows
      }

      return false;
    }

    /// <summary>
    /// Retrieve the count of records affected by an update/insert command.  Only valid once the data reader is closed!
    /// </summary>
    public override int RecordsAffected
    {
      get { return _rowsAffected; }
    }

    /// <summary>
    /// Indexer to retrieve data from a column given its name
    /// </summary>
    /// <param name="name">The name of the column to retrieve data for</param>
    /// <returns>The value contained in the column</returns>
    public override object this[string name]
    {
      get { return GetValue(GetOrdinal(name)); }
    }

    /// <summary>
    /// Indexer to retrieve data from a column given its i
    /// </summary>
    /// <param name="i">The index of the column to retrieve</param>
    /// <returns>The value contained in the column</returns>
    public override object this[int i]
    {
      get { return GetValue(i); }
    }
  }
}







|







|

|
|






|

|
|
|

|



766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
        _readingState = 1; // Finished reading rows
      }

      return false;
    }

    /// <summary>
    /// 
    /// </summary>
    public override int RecordsAffected
    {
      get { return _rowsAffected; }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public override object this[string name]
    {
      get { return GetValue(GetOrdinal(name)); }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="ordinal"></param>
    /// <returns></returns>
    public override object this[int ordinal]
    {
      get { return GetValue(ordinal); }
    }
  }
}
Changes to System.Data.SQLite/SQLiteException.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151


152
153
154
155

156
157

158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177

178
179

180
181
182
183
184
185

186

187
188
189
190
191

192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219

220
221
222
223
224

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243

244

245

246

247

248

249

250
251



252
253
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Data.Common;

#if !PLATFORM_COMPACTFRAMEWORK
  using System.Runtime.Serialization;
#endif

  /// <summary>
  /// SQLite error codes
  /// </summary>
  public enum SQLiteErrorCode
  {
    /// <summary>
    /// Success
    /// </summary>
    Ok = 0,
    /// <summary>
    /// SQL error or missing database
    /// </summary>
    Error,
    /// <summary>
    /// Internal logic error in SQLite
    /// </summary>
    Internal,
    /// <summary>
    /// Access permission denied
    /// </summary>
    Perm,
    /// <summary>
    /// Callback routine requested an abort
    /// </summary>
    Abort,
    /// <summary>
    /// The database file is locked
    /// </summary>
    Busy,
    /// <summary>
    /// A table in the database is locked
    /// </summary>
    Locked,
    /// <summary>
    /// malloc() failed
    /// </summary>
    NoMem,
    /// <summary>
    /// Attempt to write a read-only database
    /// </summary>
    ReadOnly,
    /// <summary>
    /// Operation terminated by sqlite3_interrupt()
    /// </summary>
    Interrupt,
    /// <summary>
    /// Some kind of disk I/O error occurred
    /// </summary>
    IOErr,
    /// <summary>
    /// The database disk image is malformed
    /// </summary>
    Corrupt,
    /// <summary>
    /// Table or record not found
    /// </summary>
    NotFound,
    /// <summary>
    /// Insertion failed because database is full
    /// </summary>
    Full,
    /// <summary>
    /// Unable to open the database file
    /// </summary>
    CantOpen,
    /// <summary>
    /// Database lock protocol error
    /// </summary>
    Protocol,
    /// <summary>
    /// Database is empty
    /// </summary>
    Empty,
    /// <summary>
    /// The database schema changed
    /// </summary>
    Schema,
    /// <summary>
    /// Too much data for one row of a table
    /// </summary>
    TooBig,
    /// <summary>
    /// Abort due to constraint violation
    /// </summary>
    Constraint,
    /// <summary>
    /// Data type mismatch
    /// </summary>
    Mismatch,
    /// <summary>
    /// Library used incorrectly
    /// </summary>
    Misuse,
    /// <summary>
    /// Uses OS features not supported on host
    /// </summary>
    NOLFS,
    /// <summary>
    /// Authorization denied
    /// </summary>
    Auth,
    /// <summary>
    /// Auxiliary database format error
    /// </summary>
    Format,
    /// <summary>
    /// 2nd parameter to sqlite3_bind out of range
    /// </summary>
    Range,
    /// <summary>
    /// File opened that is not a database file
    /// </summary>
    NotADatabase,
    /// <summary>
    /// sqlite3_step() has another row ready
    /// </summary>
    Row = 100,
    /// <summary>
    /// sqlite3_step() has finished executing
    /// </summary>
    Done = 101,
  }

  /// <summary>
  /// SQLite exception class.
  /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
  [Serializable]
#endif
  public sealed class SQLiteException : Exception
  {
    private SQLiteErrorCode _errorCode;



#if !PLATFORM_COMPACTFRAMEWORK
    private SQLiteException(SerializationInfo info, StreamingContext context)
      : base(info, context)
    {

    }
#endif


    /// <summary>
    /// Public constructor for generating a SQLite error given the base error code
    /// </summary>
    /// <param name="errorCode">The SQLite error code to report</param>
    /// <param name="extendedInformation">Extra text to go along with the error message text</param>
    public SQLiteException(int errorCode, string extendedInformation)
      : base(GetStockErrorMessage(errorCode, extendedInformation))
    {

      _errorCode = (SQLiteErrorCode)errorCode;
    }

    /// <summary>
    /// Various public constructors that just pass along to the base Exception
    /// </summary>
    /// <param name="message">Passed verbatim to Exception</param>
    public SQLiteException(string message)
      : base(message)
    {
    }


    /// <summary>

    /// Various public constructors that just pass along to the base Exception
    /// </summary>
    public SQLiteException()
    {
    }


    /// <summary>

    /// Various public constructors that just pass along to the base Exception
    /// <param name="message">Passed to Exception</param>
    /// <param name="innerException">Passed to Exception</param>
    /// </summary>
    public SQLiteException(string message, Exception innerException)

      : base(message, innerException)
    {
    }

    /// <summary>
    /// Retrieves the underlying SQLite error code for this exception

    /// </summary>
    public SQLiteErrorCode ErrorCode
    {
      get { return _errorCode; }
    }

    /// <summary>
    /// Initializes the exception class with the SQLite error code.
    /// </summary>
    /// <param name="errorCode">The SQLite error code</param>
    /// <param name="errorMessage">A detailed error message</param>
    /// <returns>An error message string</returns>
    private static string GetStockErrorMessage(int errorCode, string errorMessage)
    {
      if (errorMessage == null) errorMessage = "";

      if (errorMessage.Length > 0)

        errorMessage = "\r\n" + errorMessage;

      if (errorCode < 0 || errorCode >= _errorMessages.Length)
        errorCode = 1;


      return _errorMessages[errorCode] + errorMessage;
    }

    private static string[] _errorMessages = {
      "SQLite OK",

      "SQLite error",
      "An internal logic error in SQLite",
      "Access permission denied",
      "Callback routine requested an abort",
      "The database file is locked",
      "A table in the database is locked",
      "malloc() failed",
      "Atempt to write a read-only database",
      "Operation terminated by sqlite3_interrupt()",
      "Some kind of disk I/O error occurred",
      "The database disk image is malformed",
      "Table or record not found",
      "Insertion failed because the database is full",
      "Unable to open the database file",
      "Database lock protocol error",
      "Database is empty",
      "The database schema changed",
      "Too much data for one row of a table",

      "Abort due to constraint violation",

      "Data type mismatch",

      "Library used incorrectly",

      "Uses OS features not supported on host",

      "Authorization denied",

      "Auxiliary database format error",

      "2nd parameter to sqlite3_bind() out of range",

      "File opened that is not a database file",
    };



  }
}












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




<
<
<


|
|
>
>
|
|
<

>

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


1
2
3
4
5
6
7
8
9
10
11
12
































































































































13
14
15
16



17
18
19
20
21
22
23
24

25
26
27
28
29
30






31
32
33
34
35







36

37
38
39
40
41

42


43
44
45
46
47
48

49

50
51


52
53

54
55


56

57








58
59
60
61
62
63
64
65
66
67
68

69
70
71
72















73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;
  using System.Text;

































































































































  /// <summary>
  /// SQLite exception class.
  /// </summary>



  public sealed class SQLiteException : Exception
  {
    internal SQLiteException(int nCode) : base(Initialize(nCode, null))
    {
      HResult = (int)((uint)0x800F0000 | (uint)nCode);
    }

    internal SQLiteException(int nCode, string strMessage) : base(Initialize(nCode, strMessage))

    {
      HResult = (int)((uint)0x800F0000 | (uint)nCode);
    }

    private static string Initialize(int nCode, string strMessage)
    {






      if (strMessage != null)
      {
        if (strMessage.Length > 0)
          strMessage = "\r\n\r\n" + strMessage;
      }









      switch (nCode)
      {
        case 1:
          return "SQLite error" + strMessage;
        case 2:

          return "An internal logic error in SQLite" + strMessage;


        case 3:
          return "Access permission denied" + strMessage;
        case 4:
          return "Callback routine requested an abort" + strMessage;
        case 5:
          return "The database file is locked" + strMessage;

        case 6:

          return "A table in the database is locked" + strMessage;
        case 7:


          return "A malloc() failed" + strMessage;
        case 8:

          return "Attempt to write a readonly database" + strMessage;
        case 9:


          return "Operation terminated by sqlite3_interrupt()" + strMessage;

        case 10:








          return "Some kind of disk I/O error occurred" + strMessage;
        case 11:
          return "The database disk image is malformed" + strMessage;
        case 12:
          return "Table or record not found" + strMessage;
        case 13:
          return "Insertion failed because database is full" + strMessage;
        case 14:
          return "Unable to open the database file" + strMessage;
        case 15:
          return "Database lock protocol error" + strMessage;

        case 16:
          return "Database is empty" + strMessage;
        case 17:
          return "The database schema changed" + strMessage;















        case 18:

          return "Too much data for one row of a table" + strMessage;
        case 19:
          return "Abort due to constraint violation" + strMessage;
        case 20:
          return "Data type mismatch" + strMessage;
        case 21:
          return "Library used incorrectly" + strMessage;
        case 22:
          return "Uses OS features not supported on host" + strMessage;
        case 23:
          return "Authorization denied" + strMessage;
        case 24:
          return "Auxiliary database format error" + strMessage;
        case 25:
          return "2nd parameter to sqlite3_bind() out of range" + strMessage;
        case 26:
          return "File opened that is not a database file" + strMessage;

      }
      return strMessage;
    }
  }
}
Changes to System.Data.SQLite/SQLiteFactory.cs.
16
17
18
19
20
21
22












23
24
25
26
27
28
29
  /// </summary>
  public sealed class SQLiteFactory : DbProviderFactory
  {
    /// <summary>
    /// Static instance member which returns an instanced SQLiteFactory class.
    /// </summary>
    public static readonly SQLiteFactory Instance = new SQLiteFactory();













    /// <summary>
    /// Returns a new SQLiteCommand object.
    /// </summary>
    /// <returns>A SQLiteCommand object.</returns>
    public override DbCommand CreateCommand()
    {







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







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  /// </summary>
  public sealed class SQLiteFactory : DbProviderFactory
  {
    /// <summary>
    /// Static instance member which returns an instanced SQLiteFactory class.
    /// </summary>
    public static readonly SQLiteFactory Instance = new SQLiteFactory();

    /// <summary>
    /// Returns the types of classes this factory supports
    /// </summary>
    [Obsolete]
    public override DbProviderSupportedClasses SupportedClasses
    {
      get
      {
        return (DbProviderSupportedClasses)0x3F;
      }
    }

    /// <summary>
    /// Returns a new SQLiteCommand object.
    /// </summary>
    /// <returns>A SQLiteCommand object.</returns>
    public override DbCommand CreateCommand()
    {
Changes to System.Data.SQLite/SQLiteFunction.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Runtime.InteropServices;
  using System.Globalization;

  /// <summary>
  /// The type of user-defined function to declare
  /// </summary>
  public enum FunctionType
  {
    /// <summary>













<







1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Runtime.InteropServices;


  /// <summary>
  /// The type of user-defined function to declare
  /// </summary>
  public enum FunctionType
  {
    /// <summary>
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114







115
116
117
118
119
120
121
  /// information in member variables of user-defined function classes.
  /// 
  /// For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step.  This data will
  /// be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes.
  /// </remarks>
  public abstract class SQLiteFunction : IDisposable
  {
    /// <summary>
    /// The base connection this function is attached to
    /// </summary>
    private SQLiteBase              _base;
    /// <summary>
    /// Used internally to keep track of memory allocated for aggregate functions
    /// </summary>
    private int                     _interopCookie;
    /// <summary>
    /// Internal array used to keep track of aggregate function context data
    /// </summary>

    private SortedList<int, object> _contextDataList;




    /// <summary>
    /// Holds a reference to the callback function for user functions
    /// </summary>
    private SQLiteCallback  _InvokeFunc;
    /// <summary>
    /// Holds a reference to the callbakc function for stepping in an aggregate function
    /// </summary>
    private SQLiteCallback  _StepFunc;
    /// <summary>
    /// Holds a reference to the callback function for finalizing an aggregate function
    /// </summary>
    private SQLiteCallback  _FinalFunc;
    /// <summary>
    /// Holds a reference to the callback function for collation sequences
    /// </summary>
    private SQLiteCollation _CompareFunc;

    /// <summary>
    /// This static list contains all the user-defined functions declared using the proper attributes.
    /// </summary>
    private static List<SQLiteFunctionAttribute> _registeredFunctions = new List<SQLiteFunctionAttribute>();

    /// <summary>
    /// Internal constructor, initializes the function's internal variables.
    /// </summary>
    protected SQLiteFunction()
    {

      _contextDataList = new SortedList<int, object>();







    }

    /// <summary>
    /// Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert
    /// strings and DateTime's into the current connection's encoding schema.
    /// </summary>
    public SQLiteConvert SQLiteConvert







|
<
<

<
<
<

<
<
<
>

>
>
>

<
<
<

<
<
<

<
<
<

<
<
<












>

>
>
>
>
>
>
>







66
67
68
69
70
71
72
73


74



75



76
77
78
79
80
81



82



83



84



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
  /// information in member variables of user-defined function classes.
  /// 
  /// For aggregate functions, always create and store your per-statement data in the contextData object on the 1st step.  This data will
  /// be automatically freed for you (and Dispose() called if the item supports IDisposable) when the statement completes.
  /// </remarks>
  public abstract class SQLiteFunction : IDisposable
  {



    private SQLiteBase              _base;



    private int                     _interopCookie;



#if !PLATFORM_COMPACTFRAMEWORK
    private SortedList<int, object> _contextDataList;
#else
    private SortedList _contextDataList;
#endif




    private SQLiteCallback  _InvokeFunc;



    private SQLiteCallback  _StepFunc;



    private SQLiteCallback  _FinalFunc;



    private SQLiteCollation _CompareFunc;

    /// <summary>
    /// This static list contains all the user-defined functions declared using the proper attributes.
    /// </summary>
    private static List<SQLiteFunctionAttribute> _registeredFunctions = new List<SQLiteFunctionAttribute>();

    /// <summary>
    /// Internal constructor, initializes the function's internal variables.
    /// </summary>
    protected SQLiteFunction()
    {
#if !PLATFORM_COMPACTFRAMEWORK
      _contextDataList = new SortedList<int, object>();
#else
      _contextDataList = new SortedList();
#endif
      _InvokeFunc = null;
      _StepFunc = null;
      _FinalFunc = null;
      _CompareFunc = null;
    }

    /// <summary>
    /// Returns a reference to the underlying connection's SQLiteConvert class, which can be used to convert
    /// strings and DateTime's into the current connection's encoding schema.
    /// </summary>
    public SQLiteConvert SQLiteConvert
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165




166
167
168
169
170
171
172
      return null;
    }

    /// <summary>
    /// Aggregate functions override this method to do their magic.
    /// </summary>
    /// <remarks>

    /// Typically you'll be updating whatever you've placed in the contextData field and returning as quickly as possible.
    /// </remarks>
    /// <param name="args">The arguments for the command to process</param>
    /// <param name="stepNumber">The 1-based step number.  This is incrememted each time the step method is called.</param>
    /// <param name="contextData">A placeholder for implementers to store contextual data pertaining to the current context.</param>
    public virtual void Step(object[] args, int stepNumber, ref object contextData)
    {
    }

    /// <summary>
    /// Aggregate functions override this method to finish their aggregate processing.
    /// </summary>
    /// <remarks>
    /// If you implemented your aggregate function properly,
    /// you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have
    /// all the information you need in there to figure out what to return.




    /// </remarks>
    /// <param name="contextData">Your own assigned contextData, provided for you so you can return your final results.</param>
    /// <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
    /// you may return an Exception-derived class if you wish to return an error to SQLite.  Do not actually throw the error,
    /// just return it!
    /// </returns>
    public virtual object Final(object contextData)







>
|


|

|







|


>
>
>
>







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
      return null;
    }

    /// <summary>
    /// Aggregate functions override this method to do their magic.
    /// </summary>
    /// <remarks>
    /// Don't call the ReturnXXX functions of the context object during this function call.  Save it for the Final() method.
    /// Typically you'll just be updating whatever you've placed in the contextData field and returning as quickly as possible.
    /// </remarks>
    /// <param name="args">The arguments for the command to process</param>
    /// <param name="nStep">The 1-based step number.  This is incrememted each time the step method is called.</param>
    /// <param name="contextData">A placeholder for implementers to store contextual data pertaining to the current context.</param>
    public virtual void Step(object[] args, int nStep, ref object contextData)
    {
    }

    /// <summary>
    /// Aggregate functions override this method to finish their aggregate processing.
    /// </summary>
    /// <remarks>
    /// This is where you will call one of the ReturnXXX methods of the context class.  If you implemented your aggregate properly,
    /// you've been recording and keeping track of your data in the contextData object provided, and now at this stage you should have
    /// all the information you need in there to figure out what to return.
    /// 
    /// Parameters passed to this function have only an affinity for a certain data type, there is no underlying schema available
    /// to force them into a certain type.  Therefore the only types you will ever see as parameters are
    /// DBNull.Value, Int64, Double, String or byte[] array.
    /// </remarks>
    /// <param name="contextData">Your own assigned contextData, provided for you so you can return your final results.</param>
    /// <returns>You may return most simple types as a return value, null or DBNull.Value to return null, DateTime, or
    /// you may return an Exception-derived class if you wish to return an error to SQLite.  Do not actually throw the error,
    /// just return it!
    /// </returns>
    public virtual object Final(object contextData)
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
      return parms;
    }

    /// <summary>
    /// Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context.
    /// </summary>
    /// <param name="context">The context the return value applies to</param>
    /// <param name="returnValue">The parameter to return to SQLite</param>
    void SetReturnValue(int context, object returnValue)
    {
      if (returnValue == null || returnValue == DBNull.Value)
      {
        _base.ReturnNull(context);
        return;
      }

      Type t = returnValue.GetType();
      if (t == typeof(DateTime))
      {
        _base.ReturnText(context, _base.ToString((DateTime)returnValue));
        return;
      }
      else
      {
        Exception r = returnValue as Exception;

        if (r != null)
        {
          _base.ReturnError(context, r.Message);
          return;
        }
      }

      switch (SQLiteConvert.TypeToAffinity(t))
      {
        case TypeAffinity.Null:
          _base.ReturnNull(context);
          return;
        case TypeAffinity.Int64:
          _base.ReturnInt64(context, Convert.ToInt64(returnValue, CultureInfo.CurrentCulture));
          return;
        case TypeAffinity.Double:
          _base.ReturnDouble(context, Convert.ToDouble(returnValue, CultureInfo.CurrentCulture));
          return;
        case TypeAffinity.Text:
          _base.ReturnText(context, returnValue.ToString());
          return;
        case TypeAffinity.Blob:
          _base.ReturnBlob(context, (byte[])returnValue);
          return;
      }
    }

    /// <summary>
    /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method.
    /// </summary>







|
|

|





|


|


<
<
|
|
<
<
|
|
<








|


|


|


|







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260


261
262


263
264

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
      return parms;
    }

    /// <summary>
    /// Takes the return value from Invoke() and Final() and figures out how to return it to SQLite's context.
    /// </summary>
    /// <param name="context">The context the return value applies to</param>
    /// <param name="obj">The parameter to return to SQLite</param>
    void SetReturnValue(int context, object obj)
    {
      if (obj == null || obj == DBNull.Value)
      {
        _base.ReturnNull(context);
        return;
      }

      Type t = obj.GetType();
      if (t == typeof(DateTime))
      {
        _base.ReturnText(context, _base.ToString((DateTime)obj));
        return;
      }


      else if (obj as Exception != null)
      {


        _base.ReturnError(context, ((Exception)obj).Message);
        return;

      }

      switch (SQLiteConvert.TypeToAffinity(t))
      {
        case TypeAffinity.Null:
          _base.ReturnNull(context);
          return;
        case TypeAffinity.Int64:
          _base.ReturnInt64(context, Convert.ToInt64(obj));
          return;
        case TypeAffinity.Double:
          _base.ReturnDouble(context, Convert.ToDouble(obj));
          return;
        case TypeAffinity.Text:
          _base.ReturnText(context, obj.ToString());
          return;
        case TypeAffinity.Blob:
          _base.ReturnBlob(context, (byte[])obj);
          return;
      }
    }

    /// <summary>
    /// Internal scalar callback function, which wraps the raw context pointer and calls the virtual Invoke() method.
    /// </summary>
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378





379
380

381



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
      IDisposable disp = obj as IDisposable;
      if (disp != null) disp.Dispose();
    }

    /// <summary>
    /// Placeholder for a user-defined disposal routine
    /// </summary>
    /// <param name="disposing">True if the object is being disposed explicitly</param>
    protected virtual void Dispose(bool disposing)
    {
    }

    /// <summary>
    /// Disposes of any active contextData variables that were not automatically cleaned up.  Sometimes this can happen if
    /// someone closes the connection while a DataReader is open.
    /// </summary>
    public void Dispose()
    {
      Dispose(true);






      IDisposable disp;


      foreach (KeyValuePair<int, object> kv in _contextDataList)



      {
        disp = kv.Value as IDisposable;
        if (disp != null)
          disp.Dispose();
      }
      _contextDataList.Clear();

      _InvokeFunc = null;
      _StepFunc = null;
      _FinalFunc = null;
      _CompareFunc = null;
      _base = null;
      _contextDataList = null;

      GC.SuppressFinalize(this);
    }

#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// Using reflection, enumerate all assemblies in the current appdomain looking for classes that
    /// have a SQLiteFunctionAttribute attribute, and registering them accordingly.
    /// </summary>
    static SQLiteFunction()
    {
      SQLiteFunctionAttribute at;
      System.Reflection.Assembly[] arAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
      int w = arAssemblies.Length;

      for (int n = 0; n < w; n++)
      {
        Type[] arTypes;
        try
        {
          arTypes = arAssemblies[n].GetTypes();
        }
        catch (Reflection.ReflectionTypeLoadException e)
        {
          arTypes = e.Types;
        }

        int v = arTypes.Length;
        for (int x = 0; x < v; x++)
        {
          if (arTypes[x] == null) continue;

          object[] arAtt = arTypes[x].GetCustomAttributes(typeof(SQLiteFunctionAttribute), false);
          int u = arAtt.Length;
          for (int y = 0; y < u; y++)
          {
            at = arAtt[y] as SQLiteFunctionAttribute;
            if (at != null)
            {
              at._instanceType = arTypes[x];
              _registeredFunctions.Add(at);
            }
          }
        }
      }
    }
#else
    /// <summary>
    /// Manual method of registering a function.  The type must still have the SQLiteFunctionAttributes in order to work
    /// properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported.
    /// </summary>
    /// <param name="typ">The type of the function to register</param>
    public static void RegisterFunction(Type typ)
    {
      object[] arAtt = typ.GetCustomAttributes(typeof(SQLiteFunctionAttribute), false);
      int u = arAtt.Length;
      SQLiteFunctionAttribute at;

      for (int y = 0; y < u; y++)
      {
        at = arAtt[y] as SQLiteFunctionAttribute;
        if (at != null)
        {
          at._instanceType = typ;
          _registeredFunctions.Add(at);
        }
      }
    }
#endif

    /// <summary>
    /// Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection.
    /// It is done this way so that all user-defined functions will access the database using the same encoding scheme
    /// as the connection (UTF-8 or UTF-16).
    /// </summary>
    /// <remarks>
    /// The wrapper functions that interop with SQLite will create a unique cooke value, which internally is a pointer to
    /// all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.
    /// </remarks>
    /// <param name="sqlbase">The base object on which the functions are to bind</param>
    /// <returns>Returns an array of functions which the connection object should retain until the connection is closed.</returns>
    internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase)
    {
      SQLiteFunction f;
      List<SQLiteFunction> lFunctions = new List<SQLiteFunction>();

      foreach (SQLiteFunctionAttribute pr in _registeredFunctions)
      {
        f = (SQLiteFunction)Activator.CreateInstance(pr._instanceType);
        f._base = sqlbase;
        f._InvokeFunc = (pr.FuncType == FunctionType.Scalar) ? new SQLiteCallback(f.ScalarCallback) : null;
        f._StepFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.StepCallback) : null;
        f._FinalFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.FinalCallback) : null;
        f._CompareFunc = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback) : null;

        if (pr.FuncType != FunctionType.Collation)







|
|











>
>
>
>
>


>

>
>
>







<
<
<
<
<
<
<



<












<
<
<
|
<
<
<
<
<
<



<
<
|






|






|







|








|




<



















|







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388







389
390
391

392
393
394
395
396
397
398
399
400
401
402
403



404






405
406
407


408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
      IDisposable disp = obj as IDisposable;
      if (disp != null) disp.Dispose();
    }

    /// <summary>
    /// Placeholder for a user-defined disposal routine
    /// </summary>
    /// <param name="bDisposing">True if the object is being disposed explicitly</param>
    protected virtual void Dispose(bool bDisposing)
    {
    }

    /// <summary>
    /// Disposes of any active contextData variables that were not automatically cleaned up.  Sometimes this can happen if
    /// someone closes the connection while a DataReader is open.
    /// </summary>
    public void Dispose()
    {
      Dispose(true);

      _InvokeFunc = null;
      _StepFunc = null;
      _FinalFunc = null;
      _CompareFunc = null;

      IDisposable disp;

#if !PLATFORM_COMPACTFRAMEWORK
      foreach (KeyValuePair<int, object> kv in _contextDataList)
#else
      foreach (DictionaryEntry kv in _contextDataList)
#endif
      {
        disp = kv.Value as IDisposable;
        if (disp != null)
          disp.Dispose();
      }
      _contextDataList.Clear();








      GC.SuppressFinalize(this);
    }


    /// <summary>
    /// Using reflection, enumerate all assemblies in the current appdomain looking for classes that
    /// have a SQLiteFunctionAttribute attribute, and registering them accordingly.
    /// </summary>
    static SQLiteFunction()
    {
      SQLiteFunctionAttribute at;
      System.Reflection.Assembly[] arAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
      int w = arAssemblies.Length;

      for (int n = 0; n < w; n++)
      {



        Type[] arTypes = arAssemblies[n].GetTypes();






        int v = arTypes.Length;
        for (int x = 0; x < v; x++)
        {


          object[] arAtt = arTypes[x].GetCustomAttributes(false);
          int u = arAtt.Length;
          for (int y = 0; y < u; y++)
          {
            at = arAtt[y] as SQLiteFunctionAttribute;
            if (at != null)
            {
              at.InstanceType = arTypes[x];
              _registeredFunctions.Add(at);
            }
          }
        }
      }
    }

    /// <summary>
    /// Manual method of registering a function.  The type must still have the SQLiteFunctionAttributes in order to work
    /// properly, but this is a workaround for the Compact Framework where enumerating assemblies is not currently supported.
    /// </summary>
    /// <param name="typ">The type of the function to register</param>
    public static void RegisterFunction(Type typ)
    {
      object[] arAtt = typ.GetCustomAttributes(false);
      int u = arAtt.Length;
      SQLiteFunctionAttribute at;

      for (int y = 0; y < u; y++)
      {
        at = arAtt[y] as SQLiteFunctionAttribute;
        if (at != null)
        {
          at.InstanceType = typ;
          _registeredFunctions.Add(at);
        }
      }
    }


    /// <summary>
    /// Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection.
    /// It is done this way so that all user-defined functions will access the database using the same encoding scheme
    /// as the connection (UTF-8 or UTF-16).
    /// </summary>
    /// <remarks>
    /// The wrapper functions that interop with SQLite will create a unique cooke value, which internally is a pointer to
    /// all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.
    /// </remarks>
    /// <param name="sqlbase">The base object on which the functions are to bind</param>
    /// <returns>Returns an array of functions which the connection object should retain until the connection is closed.</returns>
    internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase)
    {
      SQLiteFunction f;
      List<SQLiteFunction> lFunctions = new List<SQLiteFunction>();

      foreach (SQLiteFunctionAttribute pr in _registeredFunctions)
      {
        f = (SQLiteFunction)Activator.CreateInstance(pr.InstanceType);
        f._base = sqlbase;
        f._InvokeFunc = (pr.FuncType == FunctionType.Scalar) ? new SQLiteCallback(f.ScalarCallback) : null;
        f._StepFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.StepCallback) : null;
        f._FinalFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.FinalCallback) : null;
        f._CompareFunc = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback) : null;

        if (pr.FuncType != FunctionType.Collation)
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
    /// </remarks>
    /// <param name="sqlbase">The base SQLite connection object</param>
    /// <param name="ar">An array of user-defined functions for this object</param>
    internal static void UnbindFunctions(SQLiteBase sqlbase, SQLiteFunction[] ar)
    {
      if (ar == null) return;

      int x = ar.Length;
      for (int n = 0; n < x; n++)
      {
        sqlbase.FreeFunction(ar[n]._interopCookie);
        ar[n].Dispose();
      }
    }
  }
}







<
|







492
493
494
495
496
497
498

499
500
501
502
503
504
505
506
    /// </remarks>
    /// <param name="sqlbase">The base SQLite connection object</param>
    /// <param name="ar">An array of user-defined functions for this object</param>
    internal static void UnbindFunctions(SQLiteBase sqlbase, SQLiteFunction[] ar)
    {
      if (ar == null) return;


      for (int n = 0; n < ar.Length; n++)
      {
        sqlbase.FreeFunction(ar[n]._interopCookie);
        ar[n].Dispose();
      }
    }
  }
}
Changes to System.Data.SQLite/SQLiteFunctionAttribute.cs.
13
14
15
16
17
18
19



20



21



22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  /// <summary>
  /// A simple custom attribute to enable us to easily find user-defined functions in
  /// the loaded assemblies and initialize them in SQLite as connections are made.
  /// </summary>
  [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
  public sealed class SQLiteFunctionAttribute : Attribute
  {



    private string       _name;



    private int          _arguments;



    private FunctionType _functionType;

    internal Type        _instanceType;

    /// <summary>
    /// Default constructor, initializes the internal variables for the function.
    /// </summary>
    public SQLiteFunctionAttribute()
    {
      Name = "";
      Arguments = -1;
      FuncType = FunctionType.Scalar;
    }

    /// <summary>
    /// The function's name as it will be used in SQLite command text.
    /// </summary>
    public string Name
    {
      get { return _name; }
      set { _name = value; }
    }

    /// <summary>
    /// The number of arguments this function expects.  -1 if the number of arguments is variable.
    /// </summary>
    public int Arguments
    {
      get { return _arguments; }
      set { _arguments = value; }
    }

    /// <summary>
    /// The type of function this implementation will be.
    /// </summary>
    public FunctionType FuncType
    {
      get { return _functionType; }
      set { _functionType = value; }
    }
  }
}







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









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



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

43

























44
45
46
  /// <summary>
  /// A simple custom attribute to enable us to easily find user-defined functions in
  /// the loaded assemblies and initialize them in SQLite as connections are made.
  /// </summary>
  [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
  public sealed class SQLiteFunctionAttribute : Attribute
  {
    /// <summary>
    /// The function's name as it will be used in SQLite command text.
    /// </summary>
    public string       Name;
    /// <summary>
    /// The number of arguments this function expects.  -1 if the number of arguments is variable.
    /// </summary>
    public int          Arguments;
    /// <summary>
    /// The type of function this implementation will be.
    /// </summary>
    public FunctionType FuncType;

    internal Type       InstanceType;

    /// <summary>
    /// Default constructor, initializes the internal variables for the function.
    /// </summary>
    public SQLiteFunctionAttribute()
    {
      Name = "";
      Arguments = -1;
      FuncType = FunctionType.Scalar;

      InstanceType = null;

























    }
  }
}
Changes to System.Data.SQLite/SQLiteParameter.cs.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204

205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268








269


270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296














297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
  using System;
  using System.Data;
  using System.Data.Common;

  /// <summary>
  /// SQLite implementation of DbParameter.
  /// </summary>
  public sealed class SQLiteParameter : DbParameter, ICloneable
  {
    /// <summary>
    /// The data type of the parameter
    /// </summary>
    private int            _dbType;
    /// <summary>
    /// The version information for mapping the parameter
    /// </summary>
    private DataRowVersion _rowVersion;
    /// <summary>
    /// The value of the data in the parameter
    /// </summary>
    private Object         _objValue;
    /// <summary>
    /// The source column for the parameter
    /// </summary>
    private string         _sourceColumn;
    /// <summary>
    /// The column name
    /// </summary>
    private string         _columnName;
    /// <summary>
    /// The data size, unused by SQLite
    /// </summary>
    private int            _dataSize;

    /// <summary>
    /// Default constructor
    /// </summary>
    public SQLiteParameter()
    {
      Initialize(null, -1, 0, null, DataRowVersion.Current);
    }

    /// <summary>
    /// Constructs a named parameter given the specified parameter name
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    public SQLiteParameter(string parameterName)
    {
      Initialize(parameterName, -1, 0, null, DataRowVersion.Current);
    }

    /// <summary>
    /// Constructs a named parameter given the specified parameter name and initial value
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="value">The initial value of the parameter</param>
    public SQLiteParameter(string parameterName, object value)
    {
      Initialize(parameterName, -1, 0, null, DataRowVersion.Current);
      Value = value;
    }

    /// <summary>
    /// Constructs a named parameter of the specified type
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="dbType">The datatype of the parameter</param>
    public SQLiteParameter(string parameterName, DbType dbType)
    {
      Initialize(parameterName, (int)dbType, 0, null, DataRowVersion.Current);
    }

    /// <summary>
    /// Constructs a named parameter of the specified type and source column reference
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="dbType">The data type</param>
    /// <param name="sourceColumn">The source column</param>
    public SQLiteParameter(string parameterName, DbType dbType, string sourceColumn)
    {
      Initialize(parameterName, (int)dbType, 0, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// Constructs a named parameter of the specified type, source column and row version
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="dbType">The data type</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    public SQLiteParameter(string parameterName, DbType dbType, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(parameterName, (int)dbType, 0, sourceColumn, rowVersion);
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified data type
    /// </summary>
    /// <param name="dbType">The datatype of the parameter</param>
    public SQLiteParameter(DbType dbType)
    {
      Initialize(null, (int)dbType, 0, null, DataRowVersion.Current);
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified data type and sets the initial value
    /// </summary>
    /// <param name="dbType">The datatype of the parameter</param>
    /// <param name="value">The initial value of the parameter</param>
    public SQLiteParameter(DbType dbType, object value)
    {
      Initialize(null, (int)dbType, 0, null, DataRowVersion.Current);
      Value = value;
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified data type and source column
    /// </summary>
    /// <param name="dbType">The datatype of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    public SQLiteParameter(DbType dbType, string sourceColumn)
    {
      Initialize(null, (int)dbType, 0, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified data type, source column and row version
    /// </summary>
    /// <param name="dbType">The data type</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    public SQLiteParameter(DbType dbType, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(null, (int)dbType, 0, sourceColumn, rowVersion);
    }

    /// <summary>
    /// Constructs a named parameter of the specified type and size
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize)
    {
      Initialize(parameterName, (int)parameterType, parameterSize, null, DataRowVersion.Current);
    }

    /// <summary>
    /// Constructs a named parameter of the specified type, size and source column
    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn)
    {
      Initialize(parameterName, (int)parameterType, parameterSize, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// Constructs a named parameter of the specified type, size, source column and row version
    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(parameterName, (int)parameterType, parameterSize, sourceColumn, rowVersion);
    }

    /// <summary>
    /// Constructs a named parameter of the specified type, size, source column and row version
    /// </summary>
    /// <param name="parameterName">The name of the parameter</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="direction">Only input parameters are supported in SQLite</param>
    /// <param name="isNullable">Ignored</param>
    /// <param name="precision">Ignored</param>
    /// <param name="scale">Ignored</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    /// <param name="value">The initial value to assign the parameter</param>
    public SQLiteParameter(string parameterName, DbType parameterType, int parameterSize, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion rowVersion, object value)
    {
      Initialize(parameterName, (int)parameterType, parameterSize, sourceColumn, rowVersion);
      Direction = direction;
      IsNullable = isNullable;
      Value = value;
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified type and size

    /// </summary>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>

    public SQLiteParameter(DbType parameterType, int parameterSize)
    {
      Initialize(null, (int)parameterType, parameterSize, null, DataRowVersion.Current);
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified type, size, and source column
    /// </summary>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    public SQLiteParameter(DbType parameterType, int parameterSize, string sourceColumn)
    {
      Initialize(null, (int)parameterType, parameterSize, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// Constructs an unnamed parameter of the specified type, size, source column and row version

    /// </summary>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the parameter</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version information</param>
    public SQLiteParameter(DbType parameterType, int parameterSize, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(null, (int)parameterType, parameterSize, sourceColumn, rowVersion);
    }

    /// <summary>
    /// Initializes the parameter member variables
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="paramType">The data type</param>
    /// <param name="nSize">The size</param>
    /// <param name="sourceColumn">The source column</param>
    /// <param name="rowVersion">The row version</param>
    private void Initialize(string parameterName, int paramType, int nSize, string sourceColumn, DataRowVersion rowVersion)
    {
      _columnName = parameterName;
      _dbType = paramType;
      _sourceColumn = sourceColumn;
      _rowVersion = rowVersion;
      _objValue = null;
      _dataSize = nSize;
    }

    /// <summary>
    /// Returns True.
    /// </summary>
    public override bool IsNullable
    {
      get
      {
        return true;
      }
      set 
      {
      }
    }

    /// <summary>








    /// Returns the datatype of the parameter


    /// </summary>
    public override DbType DbType
    {
      get
      {
        if (_dbType == -1) return DbType.String; // Unassigned default value is String
        return (DbType)_dbType;
      }
      set
      {
        _dbType = (int)value;
      }
    }

    /// <summary>
    /// Supports only input parameters
    /// </summary>
    public override ParameterDirection Direction
    {
      get
      {
        return ParameterDirection.Input;
      }
      set
      {
        if (value != ParameterDirection.Input)
          throw new NotSupportedException();














      }
    }

    /// <summary>
    /// Returns the parameter name
    /// </summary>
    public override string ParameterName
    {
      get
      {
        return _columnName;
      }
      set
      {
        _columnName = value;
      }
    }

    /// <summary>
    /// Not implemented
    /// </summary>
    public override void ResetDbType()
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// Returns the size of the parameter
    /// </summary>
    public override int Size
    {
      get
      {
        return _dataSize;
      }
      set
      {
        _dataSize = value;
      }
    }

    /// <summary>
    /// Gets/sets the source column
    /// </summary>
    public override string SourceColumn
    {
      get
      {
        return _sourceColumn;
      }
      set
      {
        _sourceColumn = value;
      }
    }

    /// <summary>
    /// Returns false, ignores any set value
    /// </summary>
    public override bool SourceColumnNullMapping
    {
      get
      {
        return false;
      }
      set
      {
      }
    }

    /// <summary>
    /// Gets and sets the row version
    /// </summary>
    public override DataRowVersion SourceVersion
    {
      get
      {
        return _rowVersion;
      }
      set
      {
        _rowVersion = value;
      }
    }

    /// <summary>
    /// Gets and sets the parameter value.  If no datatype was specified, the datatype will assume the type from the value given.
    /// </summary>
    public override object Value
    {
      get
      {
        return _objValue;
      }
      set
      {
        _objValue = value;
        if (_dbType == -1 && _objValue != null && _objValue != DBNull.Value) // If the DbType has never been assigned, try to glean one from the value's datatype 
          _dbType = (int)SQLiteConvert.TypeToDbType(_objValue.GetType());
      }
    }

    /// <summary>
    /// Clones a parameter
    /// </summary>
    /// <returns>A new, unassociated SQLiteParameter</returns>
    public object Clone()
    {
      SQLiteParameter newparam = new SQLiteParameter(ParameterName, this.DbType, Size, Direction, IsNullable, 0, 0, SourceColumn, SourceVersion, Value);

      return newparam;
    }
  }
}







|

<
<
<

<
<
<

<
<
<

<
<
<

<
<
<

<
<
<



|







|

|






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

|
|






|

|
|
|






|

|
|
|
|






|

|






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

|
|






|

|
|
|






|

|
|
|
|

|



|

|
|
|
|
|

|



|

|
|
|
|
|
|

|



|

<
<
<
<
|
<
|
<
<
<
|

|
<
<
<



<
>

|
|
>
|

|

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

<
>

|
|
|
|
|

|



|

|
|
|
|
|
|


|







|













>
>
>
>
>
>
>
>
|
>
>















|










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




|














|







|














|














|













|














|













|
|
<
<
<
<
<
<
<
|
<
<
<
<
10
11
12
13
14
15
16
17
18



19



20



21



22



23



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44










45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86










87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144




145

146



147
148
149



150
151
152

153
154
155
156
157
158
159
160
161








162



163

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361







362




  using System;
  using System.Data;
  using System.Data.Common;

  /// <summary>
  /// SQLite implementation of DbParameter.
  /// </summary>
  public sealed class SQLiteParameter : DbParameter
  {



    private int            _dbType;



    private DataRowVersion _rowVersion;



    private Object         _objValue;



    private string         _sourceColumn;



    private string         _columnName;



    private int            _dataSize;

    /// <summary>
    /// 
    /// </summary>
    public SQLiteParameter()
    {
      Initialize(null, -1, 0, null, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    public SQLiteParameter(string parameterName)
    {
      Initialize(parameterName, -1, 0, null, DataRowVersion.Current);
    }

    /// <summary>

    /// 










    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    public SQLiteParameter(string parameterName, DbType dbType)
    {
      Initialize(parameterName, (int)dbType, 0, null, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="sourceColumn"></param>
    public SQLiteParameter(string parameterName, DbType dbType, string sourceColumn)
    {
      Initialize(parameterName, (int)dbType, 0, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="sourceColumn"></param>
    /// <param name="rowVersion"></param>
    public SQLiteParameter(string parameterName, DbType dbType, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(parameterName, (int)dbType, 0, sourceColumn, rowVersion);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="dbType"></param>
    public SQLiteParameter(DbType dbType)
    {
      Initialize(null, (int)dbType, 0, null, DataRowVersion.Current);
    }

    /// <summary>

    /// 










    /// </summary>
    /// <param name="dbType"></param>
    /// <param name="sourceColumn"></param>
    public SQLiteParameter(DbType dbType, string sourceColumn)
    {
      Initialize(null, (int)dbType, 0, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="dbType"></param>
    /// <param name="sourceColumn"></param>
    /// <param name="rowVersion"></param>
    public SQLiteParameter(DbType dbType, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(null, (int)dbType, 0, sourceColumn, rowVersion);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    public SQLiteParameter(string parameterName, DbType dbType, int nSize)
    {
      Initialize(parameterName, (int)dbType, nSize, null, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    public SQLiteParameter(string parameterName, DbType dbType, int nSize, string sourceColumn)
    {
      Initialize(parameterName, (int)dbType, nSize, sourceColumn, DataRowVersion.Current);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    /// <param name="rowVersion"></param>
    public SQLiteParameter(string parameterName, DbType dbType, int nSize, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(parameterName, (int)dbType, nSize, sourceColumn, rowVersion);
    }

    /// <summary>
    /// 
    /// </summary>




    /// <param name="dbType"></param>

    /// <param name="nSize"></param>



    public SQLiteParameter(DbType dbType, int nSize)
    {
      Initialize(null, (int)dbType, nSize, null, DataRowVersion.Current);



    }

    /// <summary>

    /// 
    /// </summary>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    public SQLiteParameter(DbType dbType, int nSize, string sourceColumn)
    {
      Initialize(null, (int)dbType, nSize, sourceColumn, DataRowVersion.Current);
    }












    /// <summary>

    /// 
    /// </summary>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    /// <param name="rowVersion"></param>
    public SQLiteParameter(DbType dbType, int nSize, string sourceColumn, DataRowVersion rowVersion)
    {
      Initialize(null, (int)dbType, nSize, sourceColumn, rowVersion);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    /// <param name="rowVersion"></param>
    private void Initialize(string parameterName, int dbType, int nSize, string sourceColumn, DataRowVersion rowVersion)
    {
      _columnName = parameterName;
      _dbType = dbType;
      _sourceColumn = sourceColumn;
      _rowVersion = rowVersion;
      _objValue = null;
      _dataSize = nSize;
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool IsNullable
    {
      get
      {
        return true;
      }
      set 
      {
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="destination"></param>
    [Obsolete]
    public override void CopyTo(DbParameter destination)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// 
    /// </summary>
    public override DbType DbType
    {
      get
      {
        if (_dbType == -1) return DbType.String; // Unassigned default value is String
        return (DbType)_dbType;
      }
      set
      {
        _dbType = (int)value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override ParameterDirection Direction
    {
      get
      {
        return ParameterDirection.Input;
      }
      set
      {
        if (value != ParameterDirection.Input)
          throw new NotImplementedException();
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override int Offset
    {
      get
      {
        throw new NotImplementedException();
      }
      set
      {
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override string ParameterName
    {
      get
      {
        return _columnName;
      }
      set
      {
        _columnName = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override void ResetDbType()
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// 
    /// </summary>
    public override int Size
    {
      get
      {
        return _dataSize;
      }
      set
      {
        _dataSize = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override string SourceColumn
    {
      get
      {
        return _sourceColumn;
      }
      set
      {
        _sourceColumn = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool SourceColumnNullMapping
    {
      get
      {
        return false;
      }
      set
      {
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override DataRowVersion SourceVersion
    {
      get
      {
        return _rowVersion;
      }
      set
      {
        _rowVersion = value;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    public override object Value
    {
      get
      {
        return _objValue;
      }
      set
      {
        _objValue = value;
        if (_dbType == -1 && _objValue != null && _objValue != DBNull.Value) // If the DbType has never been assigned, try to glean one from the value's datatype 
          _dbType = (int)SQLiteConvert.TypeToDbType(_objValue.GetType());
      }
    }    
  }







}




Changes to System.Data.SQLite/SQLiteParameterCollection.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208









209


210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

255
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;
  using System.Globalization;
  using System.ComponentModel;
  using System.Reflection;

  /// <summary>
  /// SQLite implementation of DbParameterCollection.
  /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
  [ListBindable(true)]
#endif
  [DefaultMember("Item")]
  public sealed class SQLiteParameterCollection : DbParameterCollection
  {
    /// <summary>
    /// The underlying command to which this collection belongs
    /// </summary>
    private SQLiteCommand         _command;
    /// <summary>
    /// The internal array of parameters in this collection
    /// </summary>
    private List<SQLiteParameter> _parameterList;
    /// <summary>
    /// Determines whether or not all parameters have been bound to their statement(s)
    /// </summary>
    private bool                  _unboundFlag;

    /// <summary>
    /// Initializes the collection
    /// </summary>
    /// <param name="cmd">The command to which the collection belongs</param>
    internal SQLiteParameterCollection(SQLiteCommand cmd)
    {
      _command = cmd;
      _parameterList = new List<SQLiteParameter>();
      _unboundFlag = true;
    }

    /// <summary>
    /// Returns true
    /// </summary>
    public override bool IsSynchronized
    {
      get { return true; }
    }

    /// <summary>
    /// Returns false
    /// </summary>
    public override bool IsFixedSize
    {
      get { return false; }
    }

    /// <summary>
    /// Returns false
    /// </summary>
    public override bool IsReadOnly
    {
      get { return false; }
    }

    /// <summary>
    /// Returns null
    /// </summary>
    public override object SyncRoot
    {
      get { return null; }
    }

    /// <summary>
    /// Retrieves an enumerator for the collection
    /// </summary>
    /// <returns>An enumerator for the underlying array</returns>
    public override System.Collections.IEnumerator GetEnumerator()
    {
      return _parameterList.GetEnumerator();
    }

    /// <summary>
    /// Adds a parameter to the collection
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the value</param>
    /// <param name="sourceColumn">The source column</param>
    /// <returns>A SQLiteParameter object</returns>
    public SQLiteParameter Add(string parameterName, DbType parameterType, int parameterSize, string sourceColumn)
    {
      SQLiteParameter param = new SQLiteParameter(parameterName, parameterType, parameterSize, sourceColumn);
      Add(param);

      return param;
    }

    /// <summary>
    /// Adds a parameter to the collection
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="parameterType">The data type</param>
    /// <param name="parameterSize">The size of the value</param>
    /// <returns>A SQLiteParameter object</returns>
    public SQLiteParameter Add(string parameterName, DbType parameterType, int parameterSize)
    {
      SQLiteParameter param = new SQLiteParameter(parameterName, parameterType, parameterSize);
      Add(param);

      return param;
    }

    /// <summary>
    /// Adds a parameter to the collection
    /// </summary>
    /// <param name="parameterName">The parameter name</param>
    /// <param name="parameterType">The data type</param>
    /// <returns>A SQLiteParameter object</returns>
    public SQLiteParameter Add(string parameterName, DbType parameterType)
    {
      SQLiteParameter param = new SQLiteParameter(parameterName, parameterType);
      Add(param);

      return param;
    }

    /// <summary>
    /// Adds a parameter to the collection
    /// </summary>
    /// <param name="parameter">The parameter to add</param>
    /// <returns>A zero-based index of where the parameter is located in the array</returns>
    public int Add(DbParameter parameter)
    {
      int n = -1;

      if (parameter.ParameterName != null)
      {
        n = IndexOf(parameter.ParameterName);
      }

      if (n == -1)
      {
        n = _parameterList.Count;
        _parameterList.Add((SQLiteParameter)parameter);
      }

      SetParameter(n, parameter);

      return n;
    }

    /// <summary>
    /// Adds a parameter to the collection
    /// </summary>
    /// <param name="value">The parameter to add</param>
    /// <returns>A zero-based index of where the parameter is located in the array</returns>
    public override int Add(object value)
    {
      return Add((SQLiteParameter)value);
    }

    /// <summary>
    /// Adds a named/unnamed parameter and its value to the parameter collection.
    /// </summary>
    /// <param name="parameterName">Name of the parameter, or null to indicate an unnamed parameter</param>
    /// <param name="value">The initial value of the parameter</param>
    /// <returns>Returns the SQLiteParameter object created during the call.</returns>
    public SQLiteParameter AddWithValue(string parameterName, object value)
    {
      SQLiteParameter param = new SQLiteParameter(parameterName, value);
      Add(param);

      return param;
    }

    /// <summary>
    /// Adds an array of parameters to the collection
    /// </summary>
    /// <param name="values">The array of parameters to add</param>
    public void AddRange(DbParameter[] values)
    {
      int x = values.Length;
      for (int n = 0; n < x; n++)
        Add(values[n]);
    }

    /// <summary>
    /// Adds an array of parameters to the collection
    /// </summary>
    /// <param name="values">The array of parameters to add</param>
    public override void AddRange(Array values)
    {
      int x = values.Length;
      for (int n = 0; n < x; n++)
        Add((SQLiteParameter)(values.GetValue(n)));
    }

    /// <summary>









    /// Clears the array and resets the collection


    /// </summary>
    public override void Clear()
    {
      _unboundFlag = true;
      _parameterList.Clear();
    }

    /// <summary>
    /// Determines if the named parameter exists in the collection
    /// </summary>
    /// <param name="parameterName">The name of the parameter to check</param>
    /// <returns>True if the parameter is in the collection</returns>
    public override bool Contains(string parameterName)
    {
      return (IndexOf(parameterName) != -1);
    }

    /// <summary>
    /// Determines if the parameter exists in the collection
    /// </summary>
    /// <param name="value">The SQLiteParameter to check</param>
    /// <returns>True if the parameter is in the collection</returns>
    public override bool Contains(object value)
    {
      return _parameterList.Contains((SQLiteParameter)value);
    }

    /// <summary>
    /// Not implemented
    /// </summary>
    /// <param name="array"></param>
    /// <param name="index"></param>
    public override void CopyTo(Array array, int index)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// Returns a count of parameters in the collection
    /// </summary>
    public override int Count
    {
      get { return _parameterList.Count; }
    }


    /// <summary>
    /// Retrieve a parameter by name from the collection
    /// </summary>
    /// <param name="parameterName">The name of the parameter to fetch</param>
    /// <returns>A DbParameter object</returns>
    protected override DbParameter GetParameter(string parameterName)
    {
      return GetParameter(IndexOf(parameterName));
    }


    /// <summary>
    /// Retrieves a parameter by its index in the collection
    /// </summary>
    /// <param name="index">The index of the parameter to retrieve</param>
    /// <returns>A DbParameter object</returns>
    protected override DbParameter GetParameter(int index)
    {
      return _parameterList[index];
    }

    /// <summary>
    /// Returns the index of a parameter given its name
    /// </summary>
    /// <param name="parameterName">The name of the parameter to find</param>
    /// <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>
    public override int IndexOf(string parameterName)
    {
      int x = _parameterList.Count;
      for (int n = 0; n < x; n++)
      {
        if (String.Compare(parameterName, _parameterList[n].ParameterName, true, CultureInfo.InvariantCulture) == 0)
          return n;
      }
      return -1;
    }

    /// <summary>
    /// Returns the index of a parameter
    /// </summary>
    /// <param name="value">The parameter to find</param>
    /// <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>
    public override int IndexOf(object value)
    {
      return _parameterList.IndexOf((SQLiteParameter)value);
    }

    /// <summary>
    /// Inserts a parameter into the array at the specified location
    /// </summary>
    /// <param name="index">The zero-based index to insert the parameter at</param>
    /// <param name="value">The parameter to insert</param>
    public override void Insert(int index, object value)
    {
      _unboundFlag = true;
      _parameterList.Insert(index, (SQLiteParameter)value);
    }

    /// <summary>
    /// Removes a parameter from the collection
    /// </summary>
    /// <param name="value">The parameter to remove</param>
    public override void Remove(object value)
    {
      _unboundFlag = true;
      _parameterList.Remove((SQLiteParameter)value);
    }

    /// <summary>
    /// Removes a parameter from the collection given its name
    /// </summary>
    /// <param name="parameterName">The name of the parameter to remove</param>
    public override void RemoveAt(string parameterName)
    {
      Remove(IndexOf(parameterName));
    }

    /// <summary>
    /// Removes a parameter from the collection given its index
    /// </summary>
    /// <param name="index">The zero-based parameter index to remove</param>
    public override void RemoveAt(int index)
    {
      _unboundFlag = true;
      _parameterList.RemoveAt(index);
    }


    /// <summary>
    /// Re-assign the named parameter to a new parameter object
    /// </summary>
    /// <param name="parameterName">The name of the parameter to replace</param>
    /// <param name="value">The new parameter</param>
    protected override void SetParameter(string parameterName, DbParameter value)
    {
      SetParameter(IndexOf(parameterName), value);
    }


    /// <summary>
    /// Re-assign a parameter at the specified index
    /// </summary>
    /// <param name="index">The zero-based index of the parameter to replace</param>
    /// <param name="value">The new parameter</param>
    protected override void SetParameter(int index, DbParameter value)
    {
      _unboundFlag = true;
      _parameterList[index] = (SQLiteParameter)value;
    }

    /// <summary>
    /// Un-binds all parameters from their statements
    /// </summary>
    internal void Unbind()
    {
      _unboundFlag = true;
    }

    /// <summary>
    /// This function attempts to map all parameters in the collection to all statements in a Command.
    /// Since named parameters may span multiple statements, this function makes sure all statements are bound
    /// to the same named parameter.  Unnamed parameters are bound in sequence.
    /// </summary>
    internal void MapParameters(SQLiteStatement activeStatement)
    {
      if (_unboundFlag == false || _parameterList.Count == 0 || _command._statementList == null) return;

      int nUnnamed = 0;
      string s;
      int n;
      int y = -1;
      SQLiteStatement stmt;

      foreach(SQLiteParameter p in _parameterList)
      {
        y ++;
        s = p.ParameterName;
        if (s == null)
        {
          s = String.Format(CultureInfo.InvariantCulture, ";{0}", nUnnamed);
          nUnnamed++;
        }

        int x;
        bool isMapped = false;

        if (activeStatement == null)
          x = _command._statementList.Count;
        else
          x = 1;

        stmt = activeStatement;
        for (n = 0; n < x; n++)
        {
          isMapped = false;
          if (stmt == null) stmt = _command._statementList[n];
          if (stmt._paramNames != null)
          {
            if (stmt.MapParameter(s, p) == true)
              isMapped = true;
          }
          stmt = null;
        }

        // If the parameter has a name, but the SQL statement uses unnamed references, this can happen -- attempt to map
        // the parameter by its index in the collection
        if (isMapped == false)
        {
          s = String.Format(CultureInfo.InvariantCulture, ";{0}", y);

          stmt = activeStatement;
          for (n = 0; n < x; n++)
          {
            if (stmt == null) stmt = _command._statementList[n];
            if (stmt._paramNames != null)
            {
              if (stmt.MapParameter(s, p) == true)
                isMapped = true;
            }
            stmt = null;
          }
        }
      }
      if (activeStatement == null) _unboundFlag = false;
    }
  }
}













<
<
<




<
<
<
<


<
<
<

<
<
<

<
<
<


<
<
<
<








|







|







|







|







|

|






|

|
|
|
|
|
|

|






|

|
|
|
|
|

|






|

|
|
|
|

|






|

|
|
|



|

|





|


|





|

|
|






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

|
|

<
|




|

|


<
|




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








|

|
|
|

|



|

|
|






|









|






>

|

|
|




>


|

|
|






|

|
|


<
|

|
<





|

|
|






|

|
|







|

|







|

|






|

|






>

|

|
|




>


|

|
|






<
<
<










|

|




<




<



|



<
<
<
<
<
<
<
<
<
|

<
|


|
<

<

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



1
2
3
4
5
6
7
8
9
10
11
12
13



14
15
16
17




18
19



20



21



22
23




24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153













154
155
156
157

158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

356
357
358
359

360
361
362
363
364
365
366









367
368

369
370
371
372

373

374
375



















376
377
378
379
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data;
  using System.Data.Common;
  using System.Collections.Generic;




  /// <summary>
  /// SQLite implementation of DbParameterCollection.
  /// </summary>




  public sealed class SQLiteParameterCollection : DbParameterCollection
  {



    private SQLiteCommand         _command;



    private List<SQLiteParameter> _parameterList;



    private bool                  _unboundFlag;





    internal SQLiteParameterCollection(SQLiteCommand cmd)
    {
      _command = cmd;
      _parameterList = new List<SQLiteParameter>();
      _unboundFlag = true;
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool IsSynchronized
    {
      get { return true; }
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool IsFixedSize
    {
      get { return false; }
    }

    /// <summary>
    /// 
    /// </summary>
    public override bool IsReadOnly
    {
      get { return false; }
    }

    /// <summary>
    /// 
    /// </summary>
    public override object SyncRoot
    {
      get { return null; }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override System.Collections.IEnumerator GetEnumerator()
    {
      return _parameterList.GetEnumerator();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="paramName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <param name="sourceColumn"></param>
    /// <returns></returns>
    public SQLiteParameter Add(string paramName, DbType dbType, int nSize, string sourceColumn)
    {
      SQLiteParameter param = new SQLiteParameter(paramName, dbType, nSize, sourceColumn);
      Add(param);

      return param;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="paramName"></param>
    /// <param name="dbType"></param>
    /// <param name="nSize"></param>
    /// <returns></returns>
    public SQLiteParameter Add(string paramName, DbType dbType, int nSize)
    {
      SQLiteParameter param = new SQLiteParameter(paramName, dbType, nSize);
      Add(param);

      return param;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="paramName"></param>
    /// <param name="dbType"></param>
    /// <returns></returns>
    public SQLiteParameter Add(string paramName, DbType dbType)
    {
      SQLiteParameter param = new SQLiteParameter(paramName, dbType);
      Add(param);

      return param;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    public int Add(SQLiteParameter p)
    {
      int n = -1;

      if (p.ParameterName != null)
      {
        n = IndexOf(p.ParameterName);
      }

      if (n == -1)
      {
        n = _parameterList.Count;
        _parameterList.Add(p);
      }

      SetParameter(n, p);

      return n;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public override int Add(object value)
    {
      return Add((SQLiteParameter)value);
    }

    /// <summary>

    /// 













    /// </summary>
    /// <param name="values"></param>
    public void AddRange(SQLiteParameter[] values)
    {

      for (int n = 0; n < values.Length; n++)
        Add(values[n]);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="values"></param>
    public override void AddRange(Array values)
    {

      for (int n = 0; n < values.Length; n++)
        Add((SQLiteParameter)(values.GetValue(n)));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <returns></returns>
    [Obsolete]
    protected override int CheckName(string parameterName)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// 
    /// </summary>
    public override void Clear()
    {
      _unboundFlag = true;
      _parameterList.Clear();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public override bool Contains(string value)
    {
      return (IndexOf(value) != -1);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public override bool Contains(object value)
    {
      return _parameterList.Contains((SQLiteParameter)value);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="array"></param>
    /// <param name="index"></param>
    public override void CopyTo(Array array, int index)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// 
    /// </summary>
    public override int Count
    {
      get { return _parameterList.Count; }
    }

#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <returns></returns>
    protected override DbParameter GetParameter(string parameterName)
    {
      return GetParameter(IndexOf(parameterName));
    }
#endif

    /// <summary>
    /// 
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    protected override DbParameter GetParameter(int index)
    {
      return _parameterList[index];
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <returns></returns>
    public override int IndexOf(string parameterName)
    {

      for (int n = 0; n < _parameterList.Count; n++)
      {
        if (String.Compare(parameterName, _parameterList[n].ParameterName, true) == 0) return n;

      }
      return -1;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public override int IndexOf(object value)
    {
      return _parameterList.IndexOf((SQLiteParameter)value);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="index"></param>
    /// <param name="value"></param>
    public override void Insert(int index, object value)
    {
      _unboundFlag = true;
      _parameterList.Insert(index, (SQLiteParameter)value);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="value"></param>
    public override void Remove(object value)
    {
      _unboundFlag = true;
      _parameterList.Remove((SQLiteParameter)value);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    public override void RemoveAt(string parameterName)
    {
      Remove(IndexOf(parameterName));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="index"></param>
    public override void RemoveAt(int index)
    {
      _unboundFlag = true;
      _parameterList.RemoveAt(index);
    }

#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// 
    /// </summary>
    /// <param name="parameterName"></param>
    /// <param name="value"></param>
    protected override void SetParameter(string parameterName, DbParameter value)
    {
      SetParameter(IndexOf(parameterName), value);
    }
#endif

    /// <summary>
    /// 
    /// </summary>
    /// <param name="index"></param>
    /// <param name="value"></param>
    protected override void SetParameter(int index, DbParameter value)
    {
      _unboundFlag = true;
      _parameterList[index] = (SQLiteParameter)value;
    }




    internal void Unbind()
    {
      _unboundFlag = true;
    }

    /// <summary>
    /// This function attempts to map all parameters in the collection to all statements in a Command.
    /// Since named parameters may span multiple statements, this function makes sure all statements are bound
    /// to the same named parameter.  Unnamed parameters are bound in sequence.
    /// </summary>
    internal void MapParameters()
    {
      if (_unboundFlag == false || _parameterList.Count == 0) return;

      int nUnnamed = 0;
      string s;
      int n;

      SQLiteStatement stmt;

      foreach(SQLiteParameter p in _parameterList)
      {

        s = p.ParameterName;
        if (s == null)
        {
          s = String.Format(";{0}", nUnnamed);
          nUnnamed++;
        }










        for (n = 0; n < _command._statementList.Length; n++)
        {

          stmt = _command._statementList[n];
          if (stmt._paramNames != null)
          {
            stmt.MapParameter(s, p);

          }

        }
      }



















      _unboundFlag = false;
    }
  }
}
Changes to System.Data.SQLite/SQLiteStatement.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56




57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;
  using System.Globalization;

  /// <summary>
  /// Represents a single SQL statement in SQLite.
  /// </summary>
  internal sealed class SQLiteStatement : IDisposable
  {
    /// <summary>
    /// The underlying SQLite object this statement is bound to
    /// </summary>
    internal SQLiteBase        _sql;
    /// <summary>
    /// The command text of this SQL statement
    /// </summary>
    internal string            _sqlStatement;
    /// <summary>
    /// The actual statement pointer
    /// </summary>
    internal int               _sqlite_stmt;
    /// <summary>
    /// An index from which unnamed parameters begin
    /// </summary>
    internal int               _unnamedParameters;
    /// <summary>
    /// Names of the parameters as SQLite understands them to be
    /// </summary>
    internal string[]          _paramNames;
    /// <summary>
    /// Parameters for this statement
    /// </summary>
    internal SQLiteParameter[] _paramValues;
    /// <summary>
    /// Command this statement belongs to (if any)
    /// </summary>
    internal SQLiteCommand     _command;

    /// <summary>
    /// Initializes the statement and attempts to get all information about parameters in the statement
    /// </summary>
    /// <param name="sqlbase">The base SQLite object</param>
    /// <param name="stmt">The statement</param>
    /// <param name="strCommand">The command text for this statement</param>
    /// <param name="previous">The previous command in a multi-statement command</param>
    internal SQLiteStatement(SQLiteBase sqlbase, int stmt, string strCommand, SQLiteStatement previous)
    {




      _sql     = sqlbase;
      _sqlite_stmt = stmt;
      _sqlStatement  = strCommand;

      // Determine parameters for this statement (if any) and prepare space for them.
      int nCmdStart = 0;
      int n = _sql.Bind_ParamCount(this);
      int x;
      string s;

      if (n > 0)
      {
        if (previous != null)
          nCmdStart = previous._unnamedParameters;

        _paramNames = new string[n];
        _paramValues = new SQLiteParameter[n];

        for (x = 0; x < n; x++)
        {
          s = _sql.Bind_ParamName(this, x + 1);
          if (String.IsNullOrEmpty(s))
          {
            s = String.Format(CultureInfo.InvariantCulture, ";{0}", nCmdStart);
            nCmdStart++;
            _unnamedParameters++;
          }
          _paramNames[x] = s;
          _paramValues[x] = null;
        }
      }
    }

    /// <summary>
    /// Called by SQLiteParameterCollection, this function determines if the specified parameter name belongs to
    /// this statement, and if so, keeps a reference to the parameter so it can be bound later.
    /// </summary>
    /// <param name="s">The parameter name to map</param>
    /// <param name="p">The parameter to assign it</param>
    internal bool MapParameter(string s, SQLiteParameter p)
    {
      if (_paramNames == null) return false;

      int x = _paramNames.Length;
      for (int n = 0; n < x; n++)
      {
        if (String.Compare(_paramNames[n], s, true, CultureInfo.InvariantCulture) == 0)
        {
          _paramValues[n] = p;
          return true;
        }
      }
      return false;
    }

    #region IDisposable Members
    /// <summary>
    /// Disposes and finalizes the statement
    /// </summary>
    public void Dispose()
    {
      _sql.FinalizeStatement(this);
      
      _paramNames = null;
      _paramValues = null;
      _sql = null;
      _sqlStatement = null;

      GC.SuppressFinalize(this);
    }
    #endregion
    
    /// <summary>
    ///  Bind all parameters, making sure the caller didn't miss any











<






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

<
<
<

<
<
<
<

<
<
<
<
<
<
<
|

>
>
>
>





<






<
<
<





|
|

|

<







<
<
<
<
<
<
|

|

<
|

|


|


<



<
<
<


|



<
<







1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17



18



19



20



21



22



23




24







25
26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41



42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58






59
60
61
62

63
64
65
66
67
68
69
70

71
72
73



74
75
76
77
78
79


80
81
82
83
84
85
86
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Collections.Generic;


  /// <summary>
  /// Represents a single SQL statement in SQLite.
  /// </summary>
  internal sealed class SQLiteStatement : IDisposable
  {



    internal SQLiteBase                          _sql;



    internal string                              _sqlStatement;



    internal int                                 _sqlite_stmt;



    internal int                                 _unnamedParameterStart;



    internal string[]          _paramNames;



    internal SQLiteParameter[] _paramValues;












    internal SQLiteStatement(SQLiteBase sqlbase, int stmt, string strCommand, ref int nCmdStart)
    {
      _paramNames = null;
      _paramValues = null;

      _unnamedParameterStart   = nCmdStart;
      _sql     = sqlbase;
      _sqlite_stmt = stmt;
      _sqlStatement  = strCommand;

      // Determine parameters for this statement (if any) and prepare space for them.

      int n = _sql.Bind_ParamCount(this);
      int x;
      string s;

      if (n > 0)
      {



        _paramNames = new string[n];
        _paramValues = new SQLiteParameter[n];

        for (x = 0; x < n; x++)
        {
          s = _sql.Bind_ParamName(this, x);
          if (s == null || s == "")
          {
            s = String.Format(";{0}", nCmdStart);
            nCmdStart++;

          }
          _paramNames[x] = s;
          _paramValues[x] = null;
        }
      }
    }







    internal void MapParameter(string s, SQLiteParameter p)
    {
      if (_paramNames == null) return;


      for (int n = 0; n < _paramNames.Length; n++)
      {
        if (String.Compare(_paramNames[n], s, true) == 0)
        {
          _paramValues[n] = p;
          break;
        }
      }

    }

    #region IDisposable Members



    public void Dispose()
    {
      _sql.Finalize(this);
      
      _paramNames = null;
      _paramValues = null;



      GC.SuppressFinalize(this);
    }
    #endregion
    
    /// <summary>
    ///  Bind all parameters, making sure the caller didn't miss any
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    /// <summary>
    /// Perform the bind operation for an individual parameter
    /// </summary>
    /// <param name="index">The index of the parameter to bind</param>
    /// <param name="param">The parameter we're binding</param>
    private void BindParameter(int index, SQLiteParameter param)
    {
      if (param == null)
        throw new SQLiteException((int)SQLiteErrorCode.Error, "Insufficient parameters supplied to the command");

      object obj = param.Value;

      if (Convert.IsDBNull(obj) || obj == null)
      {
        _sql.Bind_Null(this, index);
        return;
      }

      switch (param.DbType)
      {
        case DbType.Date:
        case DbType.Time:
        case DbType.DateTime:
          _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Int64:
        case DbType.UInt64:
          _sql.Bind_Int64(this, index, Convert.ToInt64(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Boolean:
        case DbType.Int16:
        case DbType.Int32:
        case DbType.UInt16:
        case DbType.UInt32:
        case DbType.SByte:
        case DbType.Byte:
          _sql.Bind_Int32(this, index, Convert.ToInt32(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Single:
        case DbType.Double:
        case DbType.Currency:
        case DbType.Decimal:
          _sql.Bind_Double(this, index, Convert.ToDouble(obj, CultureInfo.CurrentCulture));
          break;
        case DbType.Binary:
          _sql.Bind_Blob(this, index, (byte[])obj);
          break;
        default:
          _sql.Bind_Text(this, index, obj.ToString());
          break;
      }
    }
  }
}







<
<
<













|



|








|





|











99
100
101
102
103
104
105



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    /// <summary>
    /// Perform the bind operation for an individual parameter
    /// </summary>
    /// <param name="index">The index of the parameter to bind</param>
    /// <param name="param">The parameter we're binding</param>
    private void BindParameter(int index, SQLiteParameter param)
    {



      object obj = param.Value;

      if (Convert.IsDBNull(obj) || obj == null)
      {
        _sql.Bind_Null(this, index);
        return;
      }

      switch (param.DbType)
      {
        case DbType.Date:
        case DbType.Time:
        case DbType.DateTime:
            _sql.Bind_DateTime(this, index, Convert.ToDateTime(obj));
          break;
        case DbType.Int64:
        case DbType.UInt64:
          _sql.Bind_Int64(this, index, Convert.ToInt64(obj));
          break;
        case DbType.Boolean:
        case DbType.Int16:
        case DbType.Int32:
        case DbType.UInt16:
        case DbType.UInt32:
        case DbType.SByte:
        case DbType.Byte:
            _sql.Bind_Int32(this, index, Convert.ToInt32(obj));
          break;
        case DbType.Single:
        case DbType.Double:
        case DbType.Currency:
        case DbType.Decimal:
          _sql.Bind_Double(this, index, Convert.ToDouble(obj));
          break;
        case DbType.Binary:
          _sql.Bind_Blob(this, index, (byte[])obj);
          break;
        default:
          _sql.Bind_Text(this, index, obj.ToString());
          break;
      }
    }
  }
}
Changes to System.Data.SQLite/SQLiteTransaction.cs.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
  using System.Data.Common;

  /// <summary>
  /// SQLite implementation of DbTransaction.
  /// </summary>
  public sealed class SQLiteTransaction : DbTransaction
  {
    /// <summary>
    /// The connection to which this transaction is bound
    /// </summary>
    internal SQLiteConnection _cnn;

    /// <summary>
    /// Constructs the transaction object, binding it to the supplied connection
    /// </summary>
    /// <param name="cnn">The connection to open a transaction on</param>
    /// <param name="deferredLock">TRUE to defer the writelock, or FALSE to lock immediately</param>
    internal SQLiteTransaction(SQLiteConnection cnn, bool deferredLock)
    {
      try
      {
        if (!deferredLock)
          cnn._sql.Execute("BEGIN IMMEDIATE");
        else
          cnn._sql.Execute("BEGIN");

        _cnn = cnn;
      }
      catch (SQLiteException)
      {
        BaseDispose();
        throw;
      }
    }

    /// <summary>
    /// Commits the current transaction.
    /// </summary>
    public override void Commit()
    {
      if (_cnn == null)
        throw new ArgumentNullException();

      try
      {
        _cnn._sql.Execute("COMMIT");
      }
      catch (SQLiteException)
      {
        BaseDispose();
        throw;
      }
      BaseDispose();
    }

    /// <summary>
    /// Returns the underlying connection to which this transaction applies.
    /// </summary>
    public new SQLiteConnection Connection
    {
      get { return _cnn; }
    }

    /// <summary>
    /// Forwards to the local Connection property
    /// </summary>
    protected override DbConnection DbConnection
    {
      get { return Connection; }
    }

    /// <summary>
    /// Disposes the transaction.  If it is currently active, any changes are rolled back.
    /// </summary>
    protected override void Dispose(bool disposing)
    {
      if (_cnn != null) 
        Rollback();

      _cnn = null;

      base.Dispose(disposing);
    }

    /// <summary>
    /// Gets the isolation level of the transaction.  SQLite does not support isolation levels, so this always returns Unspecified.
    /// </summary>
    public override IsolationLevel IsolationLevel
    {







<
<
<
|

<
<
<
<
<
|



<
<
<
|
<


|


|















|


|







|




<
<
<
<
<
<
<
<



|



|
<
<
<







12
13
14
15
16
17
18



19
20





21
22
23
24



25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62








63
64
65
66
67
68
69
70



71
72
73
74
75
76
77
  using System.Data.Common;

  /// <summary>
  /// SQLite implementation of DbTransaction.
  /// </summary>
  public sealed class SQLiteTransaction : DbTransaction
  {



    private SQLiteConnection _cnn;






    internal SQLiteTransaction(SQLiteConnection cnn)
    {
      try
      {



        cnn._sql.Execute("BEGIN");

        _cnn = cnn;
      }
      catch (SQLiteException e)
      {
        BaseDispose();
        throw (e);
      }
    }

    /// <summary>
    /// Commits the current transaction.
    /// </summary>
    public override void Commit()
    {
      if (_cnn == null)
        throw new ArgumentNullException();

      try
      {
        _cnn._sql.Execute("COMMIT");
      }
      catch (SQLiteException e)
      {
        BaseDispose();
        throw (e);
      }
      BaseDispose();
    }

    /// <summary>
    /// Returns the underlying connection to which this transaction applies.
    /// </summary>
    protected override DbConnection DbConnection
    {
      get { return _cnn; }
    }









    /// <summary>
    /// Disposes the transaction.  If it is currently active, any changes are rolled back.
    /// </summary>
    public override void Dispose()
    {
      if (_cnn != null) 
        Rollback();
      GC.SuppressFinalize(this);



    }

    /// <summary>
    /// Gets the isolation level of the transaction.  SQLite does not support isolation levels, so this always returns Unspecified.
    /// </summary>
    public override IsolationLevel IsolationLevel
    {
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
      if (_cnn == null)
        throw new ArgumentNullException();

      try
      {
        _cnn._sql.Execute("ROLLBACK");
      }
      catch (SQLiteException)
      {
        BaseDispose();
        throw;
      }
      BaseDispose();
    }

    private void BaseDispose()
    {
      _cnn._activeTransaction = null;
      _cnn = null;
    }
  }
}







|


|











86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
      if (_cnn == null)
        throw new ArgumentNullException();

      try
      {
        _cnn._sql.Execute("ROLLBACK");
      }
      catch (SQLiteException e)
      {
        BaseDispose();
        throw (e);
      }
      BaseDispose();
    }

    private void BaseDispose()
    {
      _cnn._activeTransaction = null;
      _cnn = null;
    }
  }
}
Deleted System.Data.SQLite/SR.Designer.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace System.Data.SQLite {
    using System;
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    internal class SR {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        internal SR() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Data.SQLite.SR", typeof(SR).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        internal static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; standalone=&quot;yes&quot;?&gt;
        ///&lt;DocumentElement&gt;
        ///  &lt;DataTypes&gt;
        ///    &lt;TypeName&gt;System.Int16&lt;/TypeName&gt;
        ///    &lt;ProviderDbType&gt;10&lt;/ProviderDbType&gt;
        ///    &lt;ColumnSize&gt;5&lt;/ColumnSize&gt;
        ///    &lt;DataType&gt;System.Int16&lt;/DataType&gt;
        ///    &lt;IsAutoIncrementable&gt;false&lt;/IsAutoIncrementable&gt;
        ///    &lt;IsCaseSensitive&gt;false&lt;/IsCaseSensitive&gt;
        ///    &lt;IsFixedLength&gt;true&lt;/IsFixedLength&gt;
        ///    &lt;IsFixedPrecisionScale&gt;true&lt;/IsFixedPrecisionScale&gt;
        ///    &lt;IsLong&gt;false&lt;/IsLong&gt;
        ///    &lt;IsNullable&gt;true&lt;/IsNullable&gt;
        ///    &lt;IsSearchable&gt;true&lt;/Is [rest of string was truncated]&quot;;.
        /// </summary>
        internal static string DataTypes {
            get {
                return ResourceManager.GetString("DataTypes", resourceCulture);
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
        ///&lt;DocumentElement&gt;
        ///  &lt;MetaDataCollections&gt;
        ///    &lt;CollectionName&gt;MetaDataCollections&lt;/CollectionName&gt;
        ///    &lt;NumberOfRestrictions&gt;0&lt;/NumberOfRestrictions&gt;
        ///    &lt;NumberOfIdentifierParts&gt;0&lt;/NumberOfIdentifierParts&gt;
        ///  &lt;/MetaDataCollections&gt;
        ///  &lt;MetaDataCollections&gt;
        ///    &lt;CollectionName&gt;DataSourceInformation&lt;/CollectionName&gt;
        ///    &lt;NumberOfRestrictions&gt;0&lt;/NumberOfRestrictions&gt;
        ///    &lt;NumberOfIdentifierParts&gt;0&lt;/NumberOfIdentifierParts&gt;
        ///  &lt;/MetaDataCollections&gt;
        ///  &lt;MetaDataC [rest of string was truncated]&quot;;.
        /// </summary>
        internal static string MetaDataCollections {
            get {
                return ResourceManager.GetString("MetaDataCollections", resourceCulture);
            }
        }
    }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































Deleted System.Data.SQLite/SR.resx.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <data name="DataTypes" type="System.Resources.ResXFileRef, System.Windows.Forms">
    <value>datatypes.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
  </data>
  <data name="MetaDataCollections" type="System.Resources.ResXFileRef, System.Windows.Forms">
    <value>metadatacollections.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
  </data>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































Deleted System.Data.SQLite/System.Data.SQLite.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.50727</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{AC139952-261A-4463-B6FA-AEBC25283A66}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>System.Data.SQLite</RootNamespace>
    <AssemblyName>System.Data.SQLite</AssemblyName>
    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
    <SignAssembly>true</SignAssembly>
    <AssemblyOriginatorKeyFile>System.Data.SQLite.snk</AssemblyOriginatorKeyFile>
    <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>..\bin\</OutputPath>
    <DefineConstants>TRACE;DEBUG;USE_INTEROP_DLL</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <DocumentationFile>
    </DocumentationFile>
    <GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="SQLite3.cs" />
    <Compile Include="SQLite3_UTF16.cs" />
    <Compile Include="SQLiteBase.cs" />
    <Compile Include="SQLiteCommand.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteCommandBuilder.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteConnection.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteConnectionStringBuilder.cs" />
    <Compile Include="SQLiteConvert.cs" />
    <Compile Include="SQLiteDataAdapter.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteDataReader.cs" />
    <Compile Include="SQLiteException.cs" />
    <Compile Include="SQLiteFactory.cs" />
    <Compile Include="SQLiteFunction.cs" />
    <Compile Include="SQLiteFunctionAttribute.cs" />
    <Compile Include="SQLiteParameter.cs" />
    <Compile Include="SQLiteParameterCollection.cs" />
    <Compile Include="SQLiteStatement.cs" />
    <Compile Include="SQLiteTransaction.cs" />
    <Compile Include="SR.Designer.cs">
      <DependentUpon>SR.resx</DependentUpon>
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
    </Compile>
    <Compile Include="UnsafeNativeMethods.cs" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="SR.resx">
      <SubType>Designer</SubType>
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>SR.Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="System.Data.SQLite.snk" />
  </ItemGroup>
  <ItemGroup>
    <None Include="DataTypes.xml" />
  </ItemGroup>
  <ItemGroup>
    <None Include="MetaDataCollections.xml" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
  <PropertyGroup>
  </PropertyGroup>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































Deleted System.Data.SQLite/System.Data.SQLite.CF.snk.

cannot compute difference between binary files

Added System.Data.SQLite/System.Data.SQLite.csproj.




















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.41202</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{AC139951-261A-4463-B6FA-AEBC25283A66}</ProjectGuid>
    <OutputType>Library</OutputType>
    <RootNamespace>System.Data.SQLite</RootNamespace>
    <AssemblyName>System.Data.SQLite</AssemblyName>
    <WarningLevel>4</WarningLevel>
    <SignAssembly>true</SignAssembly>
    <AssemblyOriginatorKeyFile>System.Data.SQLite.snk</AssemblyOriginatorKeyFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>.\bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <PlatformTarget>x86</PlatformTarget>
    <DocumentationFile>bin\Debug\System.Data.SQLite.XML</DocumentationFile>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>.\bin\Release\</OutputPath>
    <DefineConstants>
    </DefineConstants>
    <PlatformTarget>x86</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
    <NoStdLib>false</NoStdLib>
    <DocumentationFile>bin\Release\System.Data.SQLite.XML</DocumentationFile>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.XML" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <None Include="System.Data.SQLite.snk" />
    <Compile Include="SQLite3.cs" />
    <Compile Include="SQLite3_UTF16.cs" />
    <Compile Include="SQLiteBase.cs" />
    <Compile Include="SQLiteCommand.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteCommandBuilder.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteConnectionStringBuilder.cs">
    </Compile>
    <Compile Include="SQLiteConvert.cs" />
    <Compile Include="SQLiteFactory.cs" />
    <Compile Include="SQLiteFunction.cs" />
    <Compile Include="SQLiteFunctionAttribute.cs" />
    <Compile Include="SQLiteStatement.cs" />
    <Compile Include="SQLiteConnection.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteDataAdapter.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="SQLiteDataReader.cs" />
    <Compile Include="SQLiteException.cs" />
    <Compile Include="SQLiteParameter.cs" />
    <Compile Include="SQLiteParameterCollection.cs" />
    <Compile Include="SQLiteTransaction.cs" />
    <Compile Include="UnsafeNativeMethods.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>
Added System.Data.SQLite/System.Data.SQLite.csproj.user.














>
>
>
>
>
>
>
1
2
3
4
5
6
7
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <LastOpenVersion>8.0.41202</LastOpenVersion>
    <ProjectView>ProjectFiles</ProjectView>
    <ProjectTrust>0</ProjectTrust>
  </PropertyGroup>
</Project>
Changes to System.Data.SQLite/System.Data.SQLite.snk.

cannot compute difference between binary files

Changes to System.Data.SQLite/UnsafeNativeMethods.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Security;
  using System.Runtime.InteropServices;

#if !PLATFORM_COMPACTFRAMEWORK
  [SuppressUnmanagedCodeSecurity]
#endif
  internal sealed class UnsafeNativeMethods
  {
#if !USE_INTEROP_DLL
    private const string SQLITE_DLL = "System.Data.SQLite.DLL";
#else
    private const string SQLITE_DLL = "SQLite.Interop.DLL";
#endif

    private UnsafeNativeMethods()
    {
    }

    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_sleep_interop(uint dwMilliseconds);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_libversion_interop(out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_free_interop(IntPtr p);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_open_interop(byte[] utf8Filename, out int db);

    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_interrupt_interop(int db);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_close_interop(int db);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_exec_interop(int db, byte[] strSql, int pvCallback, int pvParam, out IntPtr errMsg, out int len);

    [DllImport(SQLITE_DLL)]













<

<
|

<
<
<

<
<
<
<
<
<
<
<










<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13

14

15
16



17








18
19
20
21
22
23
24
25
26
27



28
29
30
31
32
33
34
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Security;
  using System.Runtime.InteropServices;


  [SuppressUnmanagedCodeSecurity]

  internal class UnsafeNativeMethods
  {



    private const string SQLITE_DLL = "SQLite.Interop.DLL";









    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_libversion_interop(out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_free_interop(IntPtr p);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_open_interop(byte[] utf8Filename, out int db);




    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_close_interop(int db);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_exec_interop(int db, byte[] strSql, int pvCallback, int pvParam, out IntPtr errMsg, out int len);

    [DllImport(SQLITE_DLL)]
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_aggregate_context_interop(int context, int nBytes);

    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_realcolnames(int db, int bset);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_text16_interop(int stmt, int index, out int len);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_open16_interop(string utf16Filename, out int db);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_errmsg16_interop(int db, out int len);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_prepare16_interop(int db, string strSql, int sqlLen, out int stmt, out IntPtr ptrRemain, out int len);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_bind_text16_interop(int stmt, int index, string value, int nlen, int nTransient);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_name16_interop(int stmt, int index, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_decltype16_interop(int stmt, int index, out int len);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_create_collation16_interop(int db, string strName, int nType, int nArgs, SQLiteCollation func, out int nCookie);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_create_function16_interop(int db, string strName, int nArgs, int nType, SQLiteCallback func, SQLiteCallback funcstep, SQLiteCallback funcfinal, out int nCookie);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_value_text16_interop(int p, out int len);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern void sqlite3_result_error16_interop(int context, string strName, int nLen);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern void sqlite3_result_text16_interop(int context, string strName, int nLen, int pvReserved);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]
    internal static extern int sqlite3_encryptfile(string fileName);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]
    internal static extern int sqlite3_decryptfile(string fileName);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]
    internal static extern int sqlite3_encryptedstatus(string fileName, out int fileStatus);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]
    internal static extern int sqlite3_compressfile(string fileName);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode, SetLastError = true)]
    internal static extern int sqlite3_decompressfile(string fileName);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_key_interop(int db, byte[] key, int keylen);

    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_rekey_interop(int db, byte[] key, int keylen);
  }
}







|





|


|





|


|








|






|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207


208



















    [DllImport(SQLITE_DLL)]
    internal static extern int sqlite3_aggregate_context_interop(int context, int nBytes);

    [DllImport(SQLITE_DLL)]
    internal static extern void sqlite3_realcolnames(int db, int bset);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_text16_interop(int stmt, int index);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_open16_interop(string utf16Filename, out int db);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_errmsg16_interop(int db);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_prepare16_interop(int db, string strSql, int sqlLen, out int stmt, out IntPtr ptrRemain);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_bind_text16_interop(int stmt, int index, string value, int nlen, int nTransient);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_name16_interop(int stmt, int index);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_column_decltype16_interop(int stmt, int index);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_create_collation16_interop(int db, string strName, int nType, int nArgs, SQLiteCollation func, out int nCookie);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern int sqlite3_create_function16_interop(int db, string strName, int nArgs, int nType, SQLiteCallback func, SQLiteCallback funcstep, SQLiteCallback funcfinal, out int nCookie);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_value_text16_interop(int p);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern void sqlite3_result_error16_interop(int context, string strName, int nLen);

    [DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
    internal static extern void sqlite3_result_text16_interop(int context, string strName, int nLen, int pvReserved);
  }


}



















Deleted bin/CompactFramework/System.Data.SQLite.DLL.

cannot compute difference between binary files

Deleted bin/CompactFramework/System.Data.SQLite.dll.

cannot compute difference between binary files

Deleted bin/CompactFramework/testce.exe.

cannot compute difference between binary files

Deleted bin/Designer/Install.cmd.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@ECHO OFF

SETLOCAL

SET MYDIR=%~dp0
SET REGROOT=SOFTWARE\Microsoft\VisualStudio\8.0
SET XMLPATH=%MYDIR%

:ParseCmdLine

IF "%1"=="" GOTO Main
IF "%1"=="/regroot" IF NOT "%~2"=="" SET REGROOT=%~2& SHIFT & GOTO NextCmdLine
IF "%1"=="/xmlpath" IF NOT "%~2"=="" SET XMLPATH=%~f2& SHIFT & GOTO NextCmdLine
IF "%1"=="/?" GOTO Help
GOTO Help

:NextCmdLine

SHIFT
GOTO ParseCmdLine

:Main

ECHO Installing DDEX Data Provider for SQLite
ECHO   VS Registry Root: %REGROOT%
ECHO   XML File Path:    %XMLPATH%
ECHO   SQLite.DLL Path:  %MYDIR%..\

IF NOT EXIST "%XMLPATH%\SQLiteDataViewSupport.xml" ECHO The data view support XML file was not found.& GOTO End
IF NOT EXIST "%XMLPATH%\SQLiteDataObjectSupport.xml" ECHO The data object support XML file was not found.& GOTO End
IF NOT EXIST "..\System.Data.SQLite.DLL" ECHO The ..\System.Data.SQLite.DLL could not be found.& GOTO End

CScript //D "%MYDIR%\Install.vbs" //NoLogo "%REGROOT%" "%XMLPATH%"

GOTO End

:Help

ECHO DDEX Data Provider for SQLite Installation
ECHO   Usage: install [/?] [/regroot ^<regroot^>] [/xmlpath ^<xmlpath^>]

:End

ECHO Done!

ENDLOCAL
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































Deleted bin/Designer/Install.vbs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
Main

Sub Main()

   Dim WshShell
   Set WshShell = WScript.CreateObject("WScript.Shell")

   Dim GacPath
   Dim oExec
   GacPath = WshShell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\sdkInstallRootv2.0")

   Dim fso
   Set fso = WScript.CreateObject("Scripting.FileSystemObject")

   Dim myDir
   myDir = fso.GetParentFolderName(WScript.ScriptFullName)
   
   Set oExec = WshShell.Exec(GacPath & "\bin\gacutil.exe -u System.Data.SQLite")
   Do While oExec.Status = 0
     WScript.Sleep(100)
   Loop
   
   oExec.StdOut.ReadAll()
   
   Set oExec = WshShell.Exec(GacPath & "\bin\gacutil.exe -if ..\System.Data.SQLite.DLL")
   Do While oExec.Status = 0
     WScript.Sleep(100)
   Loop
   oExec.StdOut.ReadAll()

   Dim gacEntry
   
   Set oExec = WshShell.Exec(GacPath & "\bin\gacutil.exe -nologo -l System.Data.SQLite")
   Do While oExec.Status = 0
     WScript.Sleep(100)
   Loop   
   oExec.StdOut.SkipLine
   gacEntry = oExec.StdOut.ReadLine()
   oExec.StdOut.ReadAll()
   
   Dim regRoot
   regRoot = WScript.Arguments(0)
   If Right(regRoot, 1) = "\" Then
      regRoot = Left(regRoot, Len(regRoot) - 1)
   End If

   Dim xmlPath
   xmlPath = fso.GetAbsolutePathName(WScript.Arguments(1))
   If Right(xmlPath, 1) = "\" Then
      xmlPath = Left(xmlPath, Len(xmlPath) - 1)
   End If

   Dim regFile
   Dim genRegFile
   Dim regFileContents
   Set regFile = fso.OpenTextFile(myDir & "\SQLiteDesigner.reg", 1)
   Set genRegFile = fso.CreateTextFile(myDir & "\SQLiteDesigner.gen.reg", true)
   regFileContents = regFile.ReadAll()
   regFileContents = Replace(regFileContents, "%REGROOT%", regRoot)
   regFileContents = Replace(regFileContents, "%XMLPATH%", Replace(xmlPath, "\", "\\"))
   genRegFile.Write(regFileContents)
   genRegFile.Close()
   regFile.Close()

   Set oExec = WshShell.Exec("regedit /s """ & myDir & "\SQLiteDesigner.gen.reg""")
   Do While oExec.Status = 0
      WScript.Sleep(100)
   Loop
   oExec.StdOut.ReadAll()

   fso.DeleteFile(myDir & "\SQLiteDesigner.gen.reg")

   Dim machineConfigFile
   Dim machineConfig
   
   machineConfigFile = fso.GetSpecialFolder(WindowsFolder).Path & "\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config"
   Set machineConfig = CreateObject("Microsoft.XMLDOM")
   machineConfig.load machineConfigFile
   
   Dim xmlNode
   Dim xmlParent
   
   Set xmlNode = machineConfig.selectSingleNode("configuration/system.data/DbProviderFactories/add[@invariant=""System.Data.SQLite""]")
   If xmlNode Is Nothing Then
     Set xmlParent = machineConfig.selectSingleNode("configuration/system.data/DbProviderFactories")
     Set xmlNode = machineConfig.createNode(1, "add", "")
     xmlNode.attributes.setNamedItem(machineConfig.createAttribute("name"))
     xmlNode.attributes.setNamedItem(machineConfig.createAttribute("invariant"))
     xmlNode.attributes.setNamedItem(machineConfig.createAttribute("description"))
     xmlNode.attributes.setNamedItem(machineConfig.createAttribute("type"))
     xmlParent.appendChild xmlNode
   End If
   
   xmlNode.attributes.getNamedItem("name").value = "SQLite Data Provider"
   xmlNode.attributes.getNamedItem("invariant").value = "System.Data.SQLite"
   xmlNode.attributes.getNamedItem("description").value = ".Net Framework Data Provider for SQLite"
   xmlNode.attributes.getNamedItem("type").value = "System.Data.SQLite.SQLiteFactory," & gacEntry

   machineConfig.save machineConfigFile
End Sub
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































Deleted bin/Designer/InstallVWDExpress.cmd.
1
2
3
@ECHO OFF

@INSTALL.CMD /regroot SOFTWARE\Microsoft\VWDExpress\8.0
<
<
<






Deleted bin/Designer/SQLite.Designer.dll.

cannot compute difference between binary files

Deleted bin/Designer/SQLiteDataObjectSupport.xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
<?xml version="1.0" encoding="utf-8"?> 

<!--
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/
-->

<VSDataObjectSupport xmlns="http://tempuri.org/VSDataObjectSupport.xsd">
	<Types>
		<RootType>
			<Properties>
        <Property name="Server" type="System.String" itemName="DataSource"/>
        <Property name="Database" type="System.String" itemName="Database"/>
      </Properties>
			<Actions>
				<Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetRootObjectEnumerator"/>
			</Actions>
		</RootType>

		<Type name="Table" defaultSort="Database,Schema,Name">
			<Concepts>
				<Concept name="Table" restrictions="{Catalog},null,{Name},TABLE"/>
			</Concepts>
			<Identifier>
				<Part name="Database" itemName="table_catalog">
					<Concepts>
						<Concept name="Identifier0"/>
					</Concepts>
				</Part>
				<Part name="Schema" itemName="table_schema">
					<Concepts>
						<Concept name="Identifier1"/>
					</Concepts>
				</Part>
				<Part name="Name" itemName="table_name">
					<Concepts>
						<Concept name="Identifier2"/>
					</Concepts>
				</Part>
			</Identifier>
			<Restrictions>
				<Restriction name="Database"/>
				<Restriction name="Schema"/>
				<Restriction name="Name"/>
				<Restriction name="Type"/>
			</Restrictions>
			<Properties>
				<Property name="Name" type="System.String" itemName="table_name"/>
				<Property name="Schema" type="System.String" itemName="table_schema"/>
				<Property name="Type" type="System.String" itemName="table_type"/>
			</Properties>
			<Actions>
				<Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
					<Parameter value="Tables"/>
				</Action>
				<Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
					<Parameter>
						<Parameter value="{2}"/>
						<Parameter value="{1}"/>
						<Parameter value="Table"/>
						<Parameter/>
						<Parameter>
							<!-- GUID_DSRefProperty_PreciseType -->
							<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
								<Parameter value="101" type="System.Int32"/> <!-- Table -->
							</Parameter>
						</Parameter>
					</Parameter>
				</Action>
			</Actions>
		</Type>

		<Type name="TableColumn" defaultSort="Database,Schema,Table,Ordinal">
			<Concepts>
				<Concept name="TableColumn" restrictions="{Catalog},null,{Table},{Name}"/>
			</Concepts>
			<Identifier>
				<Part name="Database" itemName="table_catalog">
					<Concepts>
						<Concept name="Identifier0"/>
					</Concepts>
				</Part>
				<Part name="Schema" itemName="table_schema">
					<Concepts>
						<Concept name="Identifier1"/>
					</Concepts>
				</Part>
				<Part name="Table" itemName="table_name">
					<Concepts>
						<Concept name="Identifier2"/>
					</Concepts>
				</Part>
				<Part name="Name" itemName="column_name">
					<Concepts>
						<Concept name="Identifier3"/>
					</Concepts>
				</Part>
			</Identifier>
			<Properties>
				<Property name="Name" type="System.String" itemName="column_name"/>
				<Property name="Ordinal" type="System.Int32" itemName="ordinal_position">
					<Concepts>
						<Concept name="Ordinal">
						</Concept>
					</Concepts>
				</Property>
				<Property name="SystemType" type="System.String" itemName="data_type">
					<Concepts>
						<Concept name="UserDataType"/>
						<Concept name="NativeDataType"/>
						<Concept name="ProviderDataType">
							<Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
						</Concept>
						<Concept name="ProviderDbType">
							<Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
						</Concept>
						<Concept name="FrameworkDataType">
							<Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
						</Concept>
					</Concepts>
				</Property>
				<Property name="Length" type="System.Int32" itemName='character_maximum_length'>
					<Concepts>
						<Concept name="Length"/>
					</Concepts>
				</Property>
				<Property name="Precision" type="System.Int32" itemName="numeric_precision">
					<Concepts>
						<Concept name="Precision">
						</Concept>
					</Concepts>
				</Property>
				<Property name="Scale" type="System.Int32" itemName="numeric_scale">
					<Concepts>
						<Concept name="Scale"/>
					</Concepts>
				</Property>
				<Property name="Nullable" type="System.Boolean" itemName="is_nullable">
					<Concepts>
						<Concept name="Nullable">
						</Concept>
					</Concepts>
				</Property>
				<Property name="Default" type="System.String" itemName="column_default">
					<Concepts>
						<Concept name="Default"/>
					</Concepts>
				</Property>
			</Properties>
			<Actions>
				<Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
					<Parameter value="Columns"/>
				</Action>
				<Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
					<Parameter>
						<Parameter value="{2}"/>
						<Parameter value="{1}"/>
						<Parameter value="Table"/>
						<Parameter/>
						<Parameter>
							<!-- GUID_DSRefProperty_PreciseType -->
							<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
								<Parameter value="101" type="System.Int32"/> <!-- Table -->
							</Parameter>
						</Parameter>
						<Parameter>
							<Parameter>
								<Parameter value="{3}"/>
								<Parameter/>
								<Parameter value="Field"/>
								<Parameter/>
								<Parameter>
									<!-- GUID_DSRefProperty_PreciseType -->
									<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
										<Parameter value="102" type="System.Int32"/> <!-- Table_Column -->
									</Parameter>
								</Parameter>
							</Parameter>
						</Parameter>
					</Parameter>
				</Action>
			</Actions>
		</Type>

		<Type name="View" defaultSort="Database, Schema, Name">
			<Concepts>
				<Concept name="View" restrictions="{Catalog}, null, {Name}"/>
			</Concepts>
			<Identifier>
				<Part name="Database" itemName="table_catalog">
					<Concepts>
						<Concept name="Identifier0"/>
					</Concepts>
				</Part>
				<Part name="Schema" itemName="table_schema">
					<Concepts>
						<Concept name="Identifier1"/>
					</Concepts>
				</Part>
				<Part name="Name" itemName="table_name">
					<Concepts>
						<Concept name="Identifier2"/>
					</Concepts>
				</Part>
			</Identifier>
			<Properties>
				<Property name="Name" type="System.String" itemName="table_name"/>
				<Property name="Schema" type="System.String" itemName="table_schema">
					<Concepts>
						<Concept name="Schema"/>
					</Concepts>
				</Property>
				<Property name="CheckOption" type="System.Boolean" itemName="check_option"/>
				<Property name="IsUpdatable" type="System.Boolean" itemName="is_updatable"/>
			</Properties>
			<Actions>
				<Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
					<Parameter value="Views"/>
				</Action>
				<Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
					<Parameter>
						<Parameter value="{2}"/>
						<Parameter value="{1}"/>
						<Parameter value="View"/>
						<Parameter/>
						<Parameter>
							<!-- GUID_DSRefProperty_PreciseType -->
							<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
								<Parameter value="301" type="System.Int32"/> <!-- View -->
							</Parameter>
						</Parameter>
					</Parameter>
				</Action>
			</Actions>
		</Type>

		<!--
			Defines a type that represents a view column.
		-->
		<Type name="ViewColumn" defaultSort="Database,Schema,View,Ordinal">
			<Concepts>
				<Concept name="ViewColumn" restrictions="{Catalog},null,{View},{Name}"/>
			</Concepts>
			<Identifier>
				<Part name="Database" itemName="table_catalog">
					<Concepts>
						<Concept name="Identifier0"/>
					</Concepts>
				</Part>
				<Part name="Schema" itemName="table_schema">
					<Concepts>
						<Concept name="Identifier1"/>
					</Concepts>
				</Part>
				<Part name="View" itemName="table_name">
					<Concepts>
						<Concept name="Identifier2"/>
					</Concepts>
				</Part>
				<Part name="Name" itemName="column_name">
					<Concepts>
						<Concept name="Identifier3"/>
					</Concepts>
				</Part>
			</Identifier>
			<Properties>
				<Property name="Name" type="System.String" itemName="column_name"/>
				<Property name="Ordinal" type="System.Int32" itemName="ordinal_position">
					<Concepts>
						<Concept name="Ordinal">
						</Concept>
					</Concepts>
				</Property>
				<Property name="SystemType" type="System.String" itemName="data_type">
					<Concepts>
						<Concept name="UserDataType"/>
						<Concept name="NativeDataType"/>
						<Concept name="ProviderDataType">
							<Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
						</Concept>
						<Concept name="ProviderDbType">
							<Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
						</Concept>
						<Concept name="FrameworkDataType">
							<Conversion mapper="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectConceptMapper"/>
						</Concept>
					</Concepts>
				</Property>
				<Property name="Length" type="System.Int32" itemName='character_maximum_length'>
					<Concepts>
						<Concept name="Length"/>
					</Concepts>
				</Property>
				<Property name="Precision" type="System.Int32" itemName="numeric_precision">
					<Concepts>
						<Concept name="Precision">
						</Concept>
					</Concepts>
				</Property>
				<Property name="Scale" type="System.Int32" itemName="numeric_scale">
					<Concepts>
						<Concept name="Scale"/>
					</Concepts>
				</Property>
				<Property name="Nullable" type="System.Boolean" itemName="is_nullable">
					<Concepts>
						<Concept name="Nullable">
						</Concept>
					</Concepts>
				</Property>
				<Property name="Default" type="System.String" itemName="column_default">
					<Concepts>
						<Concept name="Default"/>
					</Concepts>
				</Property>
			</Properties>
			<Actions>
				<Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
					<Parameter value="Columns"/>
				</Action>
				<Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
					<Parameter>
						<Parameter value="{2}"/>
						<Parameter value="{1}"/>
						<Parameter value="View"/>
						<Parameter/>
						<Parameter>
							<!-- GUID_DSRefProperty_PreciseType -->
							<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
								<Parameter value="301" type="System.Int32"/> <!-- View -->
							</Parameter>
						</Parameter>
						<Parameter>
							<Parameter>
								<Parameter value="{3}"/>
								<Parameter/>
								<Parameter value="Field"/>
								<Parameter/>
								<Parameter>
									<!-- GUID_DSRefProperty_PreciseType -->
									<Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
										<Parameter value="302" type="System.Int32"/> <!-- View_Column -->
									</Parameter>
								</Parameter>
							</Parameter>
						</Parameter>
					</Parameter>
				</Action>
			</Actions>
		</Type>
    <!--
			Defines a type that represents an index.
		-->
    <Type name="Index" defaultSort="Database,Schema,Table,Name">
      <Concepts>
        <Concept name="TableUniqueKey" restrictions="{Catalog},null,{Table},{Name}" filter="IsUnique = true"/>
      </Concepts>
      <Identifier>
        <Part name="Database" itemName="table_catalog">
          <Concepts>
            <Concept name="Identifier0"/>
          </Concepts>
        </Part>
        <Part name="Schema" itemName="table_schema">
          <Concepts>
            <Concept name="Identifier1"/>
          </Concepts>
        </Part>
        <Part name="Table" itemName="table_name">
          <Concepts>
            <Concept name="Identifier2"/>
          </Concepts>
        </Part>
        <Part name="Name" itemName="index_name">
          <Concepts>
            <Concept name="Identifier3"/>
          </Concepts>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Name" type="System.String" itemName="index_name"/>
        <Property name="IsUnique" type="System.Boolean" itemName="UNIQUE"/>
        <Property name="IsPrimary" type="System.Boolean" itemName="PRIMARY_KEY">
          <Concepts>
            <Concept name="IsPrimary"/>
          </Concepts>
        </Property>
      </Properties>
      <Actions>
        <Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
          <Parameter value="Indexes"/>
        </Action>
        <Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
          <Parameter>
            <Parameter value="{2}"/>
            <Parameter value="{1}"/>
            <Parameter value="Table"/>
            <Parameter/>
            <Parameter>
              <!-- GUID_DSRefProperty_Qualifier -->
              <Parameter value="4656BAEA-F397-11ce-BFE1-00AA0057B34E">
                <Parameter value="{0}"/>
              </Parameter>
              <!-- GUID_DSRefProperty_PreciseType -->
              <Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
                <Parameter value="101" type="System.Int32"/>
                <!-- Table -->
              </Parameter>
            </Parameter>
            <Parameter>
              <Parameter>
                <Parameter value="{3}"/>
                <Parameter/>
                <Parameter value="Index"/>
              </Parameter>
            </Parameter>
          </Parameter>
        </Action>
      </Actions>
    </Type>

    <Type name="IndexColumn" defaultSort="Database,Schema,Table,Index,Ordinal">
      <Concepts>
        <Concept name="TableUniqueKeyColumn" restrictions="{Catalog},null,{Table},{TableUniqueKey},{Name}"/>
      </Concepts>
      <Identifier>
        <Part name="Database" itemName="table_catalog">
          <Concepts>
            <Concept name="Identifier0"/>
          </Concepts>
        </Part>
        <Part name="Schema" itemName="table_schema">
          <Concepts>
            <Concept name="Identifier1"/>
          </Concepts>
        </Part>
        <Part name="Table" itemName="table_name">
          <Concepts>
            <Concept name="Identifier2"/>
          </Concepts>
        </Part>
        <Part name="Index" itemName="index_name">
          <Concepts>
            <Concept name="Identifier3"/>
          </Concepts>
        </Part>
        <Part name="Name" itemName="column_name">
          <Concepts>
            <Concept name="Identifier4"/>
          </Concepts>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Name" type="System.String" itemName="column_name"/>
        <Property name="Ordinal" type="System.Byte" itemName="ordinal_position">
          <Concepts>
            <Concept name="Ordinal">
              <Conversion>
                <ChangeType type="System.Int32"/>
              </Conversion>
            </Concept>
          </Concepts>
        </Property>
      </Properties>
      <Actions>
        <Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
          <Parameter value="IndexColumns"/>
        </Action>
        <Action name="BuildDSRef" guid="7C030900-E8DD-471b-8F18-D83DA7036144" handler="Microsoft.VisualStudio.Data.DSRefBuilder">
          <Parameter>
            <Parameter value="{2}"/>
            <Parameter value="{1}"/>
            <Parameter value="Table"/>
            <Parameter/>
            <Parameter>
              <!-- GUID_DSRefProperty_Qualifier -->
              <Parameter value="4656BAEA-F397-11ce-BFE1-00AA0057B34E">
                <Parameter value="{0}"/>
              </Parameter>
              <!-- GUID_DSRefProperty_PreciseType -->
              <Parameter value="39A5A7E7-513F-44a4-B79D-7652CD8962D9">
                <Parameter value="101" type="System.Int32"/>
                <!-- Table -->
              </Parameter>
            </Parameter>
            <Parameter>
              <Parameter>
                <Parameter value="{3}"/>
                <Parameter/>
                <Parameter value="Index"/>
                <Parameter/>
                <Parameter/>
                <Parameter>
                  <Parameter>
                    <Parameter value="{4}"/>
                    <Parameter/>
                    <Parameter value="Field"/>
                  </Parameter>
                </Parameter>
              </Parameter>
            </Parameter>
          </Parameter>
        </Action>
      </Actions>
    </Type>

    <Type name="ForeignKey" defaultSort="Database,Schema,Table,Name">
      <Concepts>
        <Concept name="TableForeignKey" restrictions="{Catalog},null,{Table},{Name}"/>
      </Concepts>
      <Identifier>
        <Part name="Database" itemName="table_catalog">
          <Concepts>
            <Concept name="Identifier0"/>
          </Concepts>
        </Part>
        <Part name="Schema" itemName="table_schema">
          <Concepts>
            <Concept name="Identifier1"/>
          </Concepts>
        </Part>
        <Part name="Table" itemName="table_name">
          <Concepts>
            <Concept name="Identifier2"/>
          </Concepts>
        </Part>
        <Part name="Name" itemName="constraint_name">
          <Concepts>
            <Concept name="Identifier3"/>
          </Concepts>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Name" type="System.String" itemName="constraint_name"/>
        <Property name="ReferencedTableDatabase" type="System.String" itemName="fkey_to_catalog">
          <Concepts>
            <Concept name="ReferencedTableId0"/>
          </Concepts>
        </Property>
        <Property name="ReferencedTableSchema" type="System.String" itemName="fkey_to_schema">
          <Concepts>
            <Concept name="ReferencedTableId1"/>
          </Concepts>
        </Property>
        <Property name="ReferencedTableName" type="System.String" itemName="fkey_to_table">
          <Concepts>
            <Concept name="ReferencedTableId2"/>
          </Concepts>
        </Property>
      </Properties>
      <Actions>
        <Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
          <Parameter value="ForeignKeys"/>
        </Action>
      </Actions>
    </Type>

    <Type name="ForeignKeyColumn" defaultSort="Database,Schema,Table,ForeignKey,Ordinal">
      <Concepts>
        <Concept name="TableForeignKeyColumn" restrictions="{Catalog},null,{Table},{TableForeignKey},{Name}"/>
      </Concepts>
      <Identifier>
        <Part name="Database" itemName="table_catalog">
          <Concepts>
            <Concept name="Identifier0"/>
          </Concepts>
        </Part>
        <Part name="Schema" itemName="table_schema">
          <Concepts>
            <Concept name="Identifier1"/>
          </Concepts>
        </Part>
        <Part name="Table" itemName="table_name">
          <Concepts>
            <Concept name="Identifier2"/>
          </Concepts>
        </Part>
        <Part name="ForeignKey" itemName="constraint_name">
          <Concepts>
            <Concept name="Identifier3"/>
          </Concepts>
        </Part>
        <Part name="Name" itemName="fkey_from_column">
          <Concepts>
            <Concept name="Identifier4"/>
          </Concepts>
        </Part>
      </Identifier>
      <Properties>
        <Property name="Name" type="System.String" itemName="fkey_from_column"/>
        <Property name="Ordinal" type="System.Int32" itemName="fkey_from_ordinal_position">
          <Concepts>
            <Concept name="Ordinal"/>
          </Concepts>
        </Property>
        <Property name="ReferencedColumnName" type="System.String" itemName="fkey_to_column">
          <Concepts>
            <Concept name="ReferencedTableColumn"/>
          </Concepts>
        </Property>
      </Properties>
      <Actions>
        <Action name="Enumerate" guid="61CC0372-384D-42e5-9707-6D7C8DC5287A" handler="Microsoft.VisualStudio.Data.AdoDotNet.AdoDotNetObjectEnumerator">
          <Parameter value="ForeignKeys"/>
        </Action>
      </Actions>
    </Type>
  </Types>
</VSDataObjectSupport>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted bin/Designer/SQLiteDataViewSupport.xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?xml version="1.0" encoding="utf-8"?>

<!--
/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/
-->

<VSDataViewSupport xmlns="http://tempuri.org/VSDataViewSupport.xsd">
	<DataViews>
		<!-- This sample defines a single data view -->
		<DataView name="SQLite">
      <DisplayName>SQLite</DisplayName>
			<!-- The connection node is static, i.e. has no underlying object -->
			<StaticConnectionNode>
				<!-- We can always specify data from the root object -->
				<InitialDisplayName>{Root.Server}</InitialDisplayName>
				<CommandBindings>
					<!--
						This command binding hooks up a command that launches the built-
						in Visual Studio query designer.
					-->
					<CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
				</CommandBindings>
				<Children>
					<StaticNode nid="Tables">
            <DisplayName>User Tables</DisplayName>
						<CommandBindings>
							<CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
						</CommandBindings>
						<Children>
							<!--
								To show a set of objects from the data source we issue a
								selection, specifying type, restrictions and filter.
							-->
							<Selection type="Table" restrictions="null,null,null,TABLE">
								<!--
									The selection node indicates how to represent each object
									in the selection.
								-->
								<SelectionNode nid="Table">
                  <DisplayName>{Table.Name}</DisplayName>
									<Icon name="Table"/>
									<Children>
										<Selection type="TableColumn" restrictions="{Table.Database},null,{Table.Name}">
											<SelectionNode>
												<Icon name="Column"/>
											</SelectionNode>
										</Selection>
									</Children>
								</SelectionNode>
							</Selection>
						</Children>
					</StaticNode>
					<StaticNode nid="Views">
            <DisplayName>User Views</DisplayName>
						<CommandBindings>
							<CommandBinding name="NewQuery" guid="501822E1-B5AF-11d0-B4DC-00A0C91506EF" cmdid="13608" handler="884DD964-5327-461f-9F06-6484DD540F8F"/>
						</CommandBindings>
						<Children>
							<Selection type="View">
								<SelectionNode nid="View">
                  <DisplayName>{View.Name}</DisplayName>
									<Icon name="View"/>
									<Children>
										<Selection type="ViewColumn" restrictions="{View.Database},null,{View.Name}">
											<SelectionNode>
												<Icon name="Column"/>
											</SelectionNode>
										</Selection>
									</Children>
								</SelectionNode>
							</Selection>
						</Children>
					</StaticNode>
				</Children>
			</StaticConnectionNode>
		</DataView>
	</DataViews>
</VSDataViewSupport>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































Deleted bin/Designer/SQLiteDesigner.reg.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\%REGROOT%\DataProviders\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C70}]
@=".NET Framework Data Provider for SQLite"
"Codebase"="%XMLPATH%\\SQLite.Designer.DLL"
"InvariantName"="System.Data.SQLite"
"Technology"="{77AB9A9D-78B9-4ba7-91AC-873F5338F1D2}"

[HKEY_LOCAL_MACHINE\%REGROOT%\DataProviders\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C70}\SupportedObjects]

[HKEY_LOCAL_MACHINE\%REGROOT%\DataProviders\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C70}\SupportedObjects\DataConnectionProperties]

[HKEY_LOCAL_MACHINE\%REGROOT%\DataProviders\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C70}\SupportedObjects\DataConnectionSupport]

[HKEY_LOCAL_MACHINE\%REGROOT%\DataProviders\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C70}\SupportedObjects\DataObjectEnumerator]

[HKEY_LOCAL_MACHINE\%REGROOT%\DataProviders\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C70}\SupportedObjects\DataObjectSupport]
@="SQLiteDataObjectSupport.xml"
"Path"="%XMLPATH%"

[HKEY_LOCAL_MACHINE\%REGROOT%\DataProviders\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C70}\SupportedObjects\DataViewSupport]
@="SQLiteDataViewSupport.xml"
"Path"="%XMLPATH%"

[HKEY_LOCAL_MACHINE\%REGROOT%\DataProviders\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C70}\SupportedObjects\DataSourceInformation]
@="SQLite.Designer.SQLiteDataSourceInformation"

[HKEY_LOCAL_MACHINE\%REGROOT%\DataProviders\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C70}\SupportedObjects\DataObjectIdentifierResolver]
@="SQLite.Designer.SQLiteDataObjectIdentifierResolver"

[HKEY_LOCAL_MACHINE\%REGROOT%\DataSources\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C71}]
@="SQLite Database File"

[HKEY_LOCAL_MACHINE\%REGROOT%\DataSources\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C71}\SupportingProviders]

[HKEY_LOCAL_MACHINE\%REGROOT%\DataSources\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C71}\SupportingProviders\{0EBAAB6E-CA80-4b4a-8DDF-CBE6BF058C70}]

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































Deleted bin/Designer/readme.txt.
1
2
3
4
5
6
7
8
Installation Instructions
-------------------------

For Visual Studio 2005 (full versions):
  Run the INSTALL.CMD batch file to install the designer into the registry

For Visual Web Developer Express Edition:
  Run the INSTALLVWDEXPRESS.CMD batch file to install the designer into the registry
<
<
<
<
<
<
<
<
















Deleted bin/System.Data.SQLite.dll.

cannot compute difference between binary files

Deleted bin/itanium/System.Data.SQLite.DLL.

cannot compute difference between binary files

Deleted bin/test.exe.

cannot compute difference between binary files

Changes to bin/test.exe.config.
1
2
3
4
5
6
7
8
<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite"/>
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
    </DbProviderFactories>
  </system.data>
</configuration>



<
|



1
2
3

4
5
6
7
<configuration>
  <system.data>
    <DbProviderFactories>

      <add name="SQLite Data Provider" invariant="System.Data.SQLite" support="3F" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
    </DbProviderFactories>
  </system.data>
</configuration>
Deleted bin/tools/mergebin.exe.

cannot compute difference between binary files

Deleted bin/x64/System.Data.SQLite.DLL.

cannot compute difference between binary files

Changes to readme.htm.
1
2
3
4
5
6
7
8
9
10
11
12



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

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


88

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

118
119
120
121
122
123

124
125
126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211

212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277



278







279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365





366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title></title>
  </head>
  <body>
    ADO.NET 2.0 SQLite Data Provider<br>
    Version 1.0.24.5 (beta) - Jan 20, 2006<br>
    Using SQLite 3.3.1 alpha<br>
    Written by Robert Simpson (<a href="mailto:robert@blackcastlesoft.com">robert@blackcastlesoft.com</a>)<br>
    Released to the public domain, use at your own risk!<br>
    <br>



    The latest version can be downloaded <a href="http://sourceforge.net/projects/sqlite-dotnet2">
      here</a>
    <br>
    <br>
    <b></b>
    <h2>
      <b>Features:</b><br>
    </h2>
    <UL>
      <LI>
      Written from scratch on VS2005 specifically for ADO.NET 2.0, implenting all the
      base classes and features recently introduced in the framework.<li>Supports the Full
        and Compact .NET Framework, as well as native C/C++ development.&nbsp; 100% binary
        compatible with the original sqlite3.dll.</li>
      <LI>
      On the Compact Framework, it is faster than the newly-introduced Sql Server 
      Mobile, often more than 10x faster at inserts/updates.&nbsp; SQLite databases 
      are also a fraction of the size of Sql Mobile databases.
      <li>Encrypted database support.&nbsp; Encrypted databases are fully encrypted and
        support both binary and cleartext password types.</li>
      <LI>
      Visual Studio 2005 Design-Time Support.&nbsp; You can add a SQLite 
      database to the Servers list, design queries with the Query Designer, 
      drag-and-drop tables onto a Typed DataSet, etc.
      <LI>
      Single file redistributable.&nbsp; The core sqlite3 codebase and the ADO.NET wrapper 
      are combined into one multi-module assembly.
      <LI>
      Binaries included for Itanium, x64, x86 and ARM processors.
      <LI>
      DbProviderFactory support.
      <LI>
        Full support for ATTACH'ed databases.&nbsp; Exposed as <I>Catalogs</I>
      in the schema.&nbsp; When cloning a connection, all attached databases are 
      automatically re-attached to the new connection.
      <LI>
        DbConnection.GetSchema(...) support includes the <I>MetaDataCollections</I>, <I>DataSourceInformation</I>,
        <I>Columns</I>, <I>Tables</I>, <I>Views, ViewColumns, </I><I>Catalogs, </I><I>Indexes, 
          IndexColumns </I>and <EM>ForeignKeys</EM>
      keywords.
      <LI>
      Enhanced DbDataReader.GetSchemaTable() functionality returns catalog, namespace 
      and detailed schema information even for complex queries.
      <LI>
      Named and unnamed parameters.
      <LI>
      Full UTF-8 and UTF-16 support, each with optimized pipelines into the native 
      database core.
      <LI>
      Multiple simultaneous DataReaders (one DataReader per Command however).
      <LI>
      Full support for user-defined scalar and aggregate functions, encapsulated into 

      an easy-to-use base class in which only a couple of overrides are necessary to 
      implement new SQL functions.
      <LI>
      Full support for user-defined collating sequences, every bit as simple to 
      implement as user-defined functions and uses the same base class.
      <LI>
        Full source for the entire engine and wrapper.&nbsp; No copyrights.&nbsp; 
        Public Domain.&nbsp; 100% free.&nbsp; If you want to know if you can use it in 
        your commercial project, please read the previous sentence again -- only slower 
        and sound out the words this time.
      </LI>
    </UL>
    <strong></strong>
    <h2>
      <strong>Design-Time Support (new as of 1.0.14)</strong></h2>
    <P>Until an installer is created, through a command-prompt or Windows Explorer, navigate to the <STRONG>SQLite.NET\bin\Designer</STRONG>
        folder and execute the <STRONG>INSTALL.CMD</STRONG>
      file.&nbsp; The script and
      batch file will register the System.Data.SQLite DLL in the Global Assembly Cache,
      and modify the machine.config file to add SQLite to the list of default data providers.</P>
    <H2><STRONG>DbFactory Support (Non-Compact Framework)</STRONG></H2>
    In order to use the SQLiteFactory and have the SQLite data provider enumerated 
    in the DbProviderFactories methods, you must add the following segment into your application's app.config file:<br>


    <br>

    <pre>&lt;configuration&gt;
  &lt;system.data&gt;
    &lt;DbProviderFactories&gt;
      &lt;remove invariant="System.Data.SQLite"/&gt;
      &lt;add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite"<BR > type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /&gt;
    &lt;/DbProviderFactories&gt;
  &lt;/system.data&gt;
&lt;/configuration&gt;
</pre>
    <p>See the help documentation for further details on implementing both version-specific (GAC enabled) and version independent DBProviderFactories support.
      </p>
    <h3>
      Compiling for the Compact Framework</h3>
    <p>
      Just change the target platform from Win32 to Compact Framework and 
      recompile.&nbsp; <STRONG>The Compact Framework has no support for enumerating 
        attributes in an assembly, therefore all user-defined collating sequences and 
        functions must be explicitly registered.</STRONG>&nbsp; See the <STRONG>testce</STRONG>
      sample application for an example of how to explicitly register user-defined 
      collating sequences and functions.</p>
    <h2>
      <b><A name="redist"></A>Distributing The SQLite Engine and ADO.NET Assembly</b></h2>
    <P>
      Only the <STRONG>System.Data.SQLite.DLL</STRONG> file needs to be distributed with your 
      application(s).&nbsp; This DLL contains both the managed wrapper and the native 
      SQLite3 codebase.</P>
    <H2><B>Development Notes Regarding the SQLite 3 Source Code</B></H2>
    <p>
      The SQLite3 source code is compiled almost directly from the SQLite.org release

      sources.&nbsp; All builds of sqlite after 3.2.8 have included support for Windows
      CE (without file locking), but the ADO.NET sources here contain CE locking modifications
      to the os_win.c.&nbsp; I hope eventually the locking code will be incorporated into
      the root sqlite codebase.&nbsp; Additionally, two minor modifications are made to
      the sources, those modifications are made automatically by the fixsource.vbs file
      when the VS2005 solution is compiled.</p>

    <p></p>
    <p>
      <b>Version History</b></p>
    <p><b>1.0.24.5 beta - January 20, 2006</b></p>
    <ul>

    <li>This beta is built from sqlite.org's 3.3.1 alpha and contains development-in-progress code.&nbsp; Therefore no guarantees
      can be made regarding its suitability for production use.</li>
    <li><strong>You no longer need to distribute 2 files on the CompactFramework.&nbsp;
      You can delete SQLite.Interop.DLL entirely.&nbsp; </strong>I wrote a custom tool
      called "mergebin" (available in the source zip file) which combines the two libraries
      and gets around a glaring defect in the VS2005 linker for ARM processors which doesn't
      allow you to link netmodules.</li>
      <li><strong>x64 and ia64 builds now use the same strong name as the x86 build.</strong>&nbsp;
        This means breaking backward compatibility, but it was necessary in order to allow
        you to drop any of those 3 builds onto a PC and have your .NET program run properly.&nbsp;
        Prior to this, you'd get an error if you built your program using the x86 build,
        and then installed the x64 version on a target machine and tried to run your program
        against it.</li>
      <li>The entire source project has been gone over top to bottom.&nbsp; A debug build
        no longer combines the binaries into a single module, which was preventing proper
        debugging.</li></ul>
    <p><b>1.0.24.4 beta - January 16, 2006</b></p>
    <ul>
    <li>This beta is built from sqlite.org's 3.3.1 alpha and contains development-in-progress code.&nbsp; Therefore no guarantees
      can be made regarding its suitability for production use.</li>
    <li>Fixed a bug in the UTF-16 handling code for preparing statements due to a behavioral
      change in SQLite 3.3.0.</li>
      <li>Added pager.c code necessary to cleanup after an encrypted file is closed.</li>
      <li>Fixed an encryption bug that caused a fault when an encrypted file was rolled

        back.</li>
      <li>Modified the testcase code to take advantage of optimizations regarding the use
        of a DbCommandBuilder.&nbsp; DataAdapter insert speed increased dramatically as
        a result.</li>
    </ul>
    <p><b>1.0.24.3 beta - January 10, 2006</b></p>
    <ul>
    <li>This beta is built from sqlite.org's 3.3.0 alpha and contains development-in-progress code.&nbsp; Therefore no guarantees
      can be made regarding its suitability for production use.</li><li>Added support for database encryption at the pager level.&nbsp; Databases
    are encrypted using a 128-bit RC4 stream algorithm.&nbsp; To open an existing encrypted
    database, you may now specify a "Password={password}" text in the ConnectionString,
    or you may call the SQLiteConnection.SetPassword() function to set the password
    on an open connection. &nbsp;To encrypt existing non-encrypted databases or to change
    the password on an encrypted database, you must use the SQLiteConnection.ChangePassword()
    function.&nbsp; If you use SetPassword() instead of specifying a password in the
    connection string, or call ChangePassword() you may use a binary byte array or a
    text string as the password.</li>
      <li>Rewrote the locking implementation for the Compact Framework.&nbsp; It is now
        more robust and incorporates into the SQLite codebase more efficiently than the
        previous CE adaptation.</li>
      <li>Moved some of the embedded schema XML data into a resource file to ease code readability.</li>
      <li>Automated the fixup of the original sqlite codebase's source prior to compiling,
        to ease merging with sqlite.org's source.</li>
      <li>Fixed a memory leak in SQLiteCommand due to it not removing an internal reference
        to itself in SQLiteConnection.&nbsp; </li>
    </ul>
    <p><b>1.0.24.2 - December 30, 2005</b></p>
    <ul>
    <li>Fixed the SQLiteDataReader.HasRows property to return the proper value.</li>
      <li>Implemented the inadvertently neglected RecordsAffected property on SQLiteDataReader.
      </li>
      <li>SQLiteFunction static constructor was changed to pre-filter classes with only the
        SQLiteFunctionAttribute.&nbsp; The code was throwing an exception when certain
        assemblies were referenced in a project. </li>
      <li>Fixed the SQLiteDataAdapter OnRowUpdated event, which was using the wrong variable
        to find the attached event handler and subsequently not raising the event.</li>
      <li>Small optimizations and fixes to SQLiteDataReader.NextResult().&nbsp;</li>
    </ul>
    <p><b>1.0.24.1 - December 19, 2005</b></p>
    <ul>
    <li>Update core SQLite engine to 3.2.8&nbsp;</li></ul>
    <p><b>1.0.24 - December 9, 2005</b></p>
    <ul>
    <li>Fixed the<em> Catalogs</em> schema bug that caused attached databases not to be re-attached to a cloned connection
    </li>
      <li>Enhanced transactions to allow for a deferred or immediate writelock. &nbsp;SQLiteConnection.BeginTransaction()
        now has an additional overload to support it&nbsp;</li><li>Commands are now prepared as they are executed instead of beforehand.&nbsp; This
      fixes a bug whereby a multi-statement command that alters the database and subsequently
      references the altered data would fail during Prepare().</li><li>Tightened up the SQLiteDataReader to prevent reading columns before calling
    the first Read() and to prevent reading columns after the last Read().</li>
      <li>A more descriptive error is thrown if there aren't enough parameters in the command
        to satisfy the parameters required by the statement(s).&nbsp;</li>
    </ul>
    <p><b>1.0.23 - November 21, 2005</b></p>
    <ul>
    <li>Named parameters may now begin with <strong>@</strong> to ease portability of

      the provider. SQLite's named parameters are ordinarily prefixed with a <strong>: </strong>
      or<strong> $</strong>.&nbsp; The designer will still use the <strong>$</strong>
      prefix however, since its more compatible with the default SQLite engine.</li><li>Added several alternate ISO8601 date/time formats to SQLiteConvert.cs to increase

    compatibility.</li>

      <li>Relaxed coersion restrictions to work better with SQLite's inherent typelessness.&nbsp;</li>
    </ul>
    <p><b>1.0.22 - November 11, 2005</b></p>
    <ul>
    <li>Fixed some globalization issues which resulted in incorrect case-insensitive comparisons</li>
      <li>Fixed a bug in the routine that finds all user-defined functions in a loaded assembly.&nbsp;
        It would throw an exception if any of the types in the assembly could not be loaded.&nbsp;
        The exception is now caught and handled appropriately.</li>
    </ul>
    <p><b>1.0.21 - November 4, 2005</b></p>
    <UL>
      <li>Fixed a designer bug when creating typed datasets with parameterized queries.</li>
      <li>The above fix then exposed another bug in the datareader's ability to query schema
        information on parameterized commands, which was also fixed.</li>
      <li>Compiled against the RTM version of VS2005.</li>
      <li>Rewrote the design-time install script to use the XML DOM objects when writing
        to the machine.config and to automatically register the DLL in the GAC.</li><li>Made changes to the app.config descriptions and help file to improve version-independent
        factory support.</li></UL>
    <p><b>1.0.20 - October 19, 2005</b></p>
    <UL>
      <li>
        Fixed a shortcut in SQLiteBase.GetValue which was insufficient for 
        international environments.&nbsp; The shortcut was removed and the "proper" 
        procedure put in.</li></UL>
    <p><b>1.0.19 - October 5, 2005</b></p>
    <UL>
      <li>
      Code merge with SQLite 3.2.7
      <LI>
      Fixed bugs in the CE port code (os_wince.c)&nbsp;which were brought to 
      light&nbsp;by&nbsp;recent changes in the SQLite engine.
      <LI>
        Recompiled and modified to be compatible with the September VS2005 Release 
        Candidate.<br>
        Beta 2 users should continue to use 1.0.18.1</LI></UL>
    <p><b>1.0.18.1 - September 19, 2005</b></p>
    <UL>
      <li>
        Code merge with SQLite 3.2.6</li></UL>
    <p><b>1.0.18 - September 1, 2005</b></p>
    <UL>
      <li>
        Added type-specific method calls when using the various SQLite classes that 
        would've normally returned a a generic Db base class, which aligns the code 
        better with the Microsoft-supplied data providers.</li></UL>
    <p><b>1.0.17 - August 26, 2005</b></p>
    <ul>
      <li>
      Code merge with SQLite 3.2.5
      <li>
      Added Itanium and x64 build settings to the project (needs testing)
      <li>
      Bugfixes and enhancements to several schema types
      <li>
      Additional design-time support to include index and foreign key 
      enumerations.&nbsp; Requires re-registering the designer using 
      INSTALL.CMD.&nbsp; The new designer code now allows the VS query designer and 
      typed datasets to automatically link up foreign keys, use indexes, and 
      automatically generate relationships from the schema.<li>
        Additional static methods on SQLiteConnection to create a database file, 
        encrypt a file using the Encrypted File System (EFS) on NTFS (requires NT 2K or 
        above) and NTFS file compression</li>
    </ul>
    <p><b>1.0.16 - August 24, 2005</b></p>
    <ul>



      <li>







      Code merge with SQLite 3.2.4 with the large delete bugfix in CVS (which will 
      become 3.2.5 soon)
      <li>
        Added new GetSchema() types: IndexColumns, ViewColumns, ForeignKeys</li>
    </ul>
    <p><b>1.0.15 - August 22, 2005</b><br>
    </p>
    <ul>
      <li>
      Code merge with SQLite 3.2.3
      <LI>
        Minor updates for better design-time experience. More design-time code to 
        follow in subsequent releases.</LI>
    </ul>
    <p><b>1.0.14 - August 16, 2005</b><br>
    </p>
    <ul>
      <li>
      Fixed a bug in the SQLiteDataAdapter due to insufficient implementation of the 
      class.&nbsp; The RowUpdating and RowUpdated events are now properly 
      implemented, but unfortunately inserting and updating data in a DataTable or 
      DataSet is now much slower.&nbsp; This is the proper design however, so the 
      changes are here to stay.
      <LI>
      Lots of schema changes to support Visual Studio's Data Designer architecture.<li>Added 
        Designer support for the provider.&nbsp; It's not 100%, but you can design 
        queries, add typed datasets and perform quite a number of tasks all within 
        Visual Studio now.</li></ul>
    <P><B>1.0.13 - August 8, 2005</B><BR>
    </P>
    <DIV>
      <UL>
        <LI>
        Fixed a named parameter bug in the base SQLite_UTF16 class, which of course 
        only showed up when a database connection was opened using the 
        UseUTF16Encoding=True parameter.
        <LI>
          Fixed a performance issue in SQLite_UTF16 involving string marshaling.</LI></UL>
    </DIV>
    <P><B>1.0.12 - August 5, 2005</B><BR>
    </P>
    <DIV>
      <UL>
        <LI>
          Full support for the Compact Framework.&nbsp; Each build (Debug/Release) now 
          has a&nbsp;platform, either Win32 or Compact Framework.&nbsp; The correct 
          projects are built accordingly.&nbsp; See the&nbsp;<A href="#redist">Distributing 
            SQLite</A>
        section for information on what files need to be distributed for each 
        platform.&nbsp;
        <LI>
        Modified SQLite3.Reset() and Step() functions to transparently handle timeouts 
        while waiting on the database to become available (typically when a writer is 
        waiting on a reader to finish, or a reader is waiting on a writer to finish).
        <LI>
        Lots of code cleanup&nbsp;as suggested&nbsp;by the Code Analyzer (FxCop).
        <LI>
        Lots of updates to the helpfile (as you can see).
        <LI>
          Statements&nbsp;were already prepared lazily&nbsp;in a SQLiteCommand, but now 
          its even more lazy.&nbsp; Statements are now only prepared if the statements 
          haven't been previously prepared and a Prepare() function is called (and the 
          command is associated with a connection) or just prior to the command being 
          executed.&nbsp;</LI></UL>
    </DIV>
    <P><B>1.0.11 - August 1, 2005</B><BR>
    </P>
    <UL>
      <LI>
        <STRONG>For everything except the Compact Framework, System.Data.SQLite.DLL is 
          now the <EM>only</EM> DLL required to use this provider!</STRONG>&nbsp; The 
      assembly is now a multi-module assembly, containing both the native SQLite3 
      codebase and the C# classes built on top of it.&nbsp; The Compact Framework 
      version (when completed) will not be able to support this feature, so backwards 
      compatibility with the Compact Framework has been preserved for the future.
      <LI>
        Fixed a bug in SQLiteCommand.ExecuteScalar() that caused it to stop executing 
        commands once it obtained the first column of the first row-returning 
        resultset.&nbsp; Any remaining statements after the row-returning statement was 
        ignored.
      </LI>
    </UL>
    <P><B>1.0.10 - June 10, 2005</B><BR>
    </P>
    <UL>
      <LI>
      Fixed a bug in the SQLite3.cs Prepare() function that created a statement even 





      when the SQLite engine returned a NULL pointer. Typically this occurs when 
      multiple statements are processed and there are trailing comments at the end of 
      the statement.
      <LI>
        Fixed a bug in SQLiteStatement.cs that retrieved parameter names for a 
        parameterized query.&nbsp; SQLite's parameters are 1-based, and the function 
        was starting at 0.&nbsp; This was fine when all parameters were unnamed, but 
        for named parameters it caused the parameters to be out of whack.
      </LI>
    </UL>
    <P><B>1.0.09a - May 25, 2005</B><BR>
    </P>
    <UL>
      <LI>
      Fixed a broken helpfile and corrected some obsolete help remarks in 
      SQLiteFunction.cs
      <LI>
        Added a version resource to the SQLite.Interop.DLL.&nbsp;</LI></UL>
    <P><B>1.0.09 - May 24, 2005</B><BR>
    </P>
    <UL>
      <LI>
      Code merge with the latest 3.21 version of SQLite.
      <LI>
        Removed obsolete methods and properties for Whidbey Beta 2</LI></UL>
    <P><B>1.0.08 Refresh - Mar 24, 2005<BR>
      </B>
    </P>
    <UL>
      <LI>
      Code merge with the latest 3.20 version of SQLite.
      <LI>
        Recompiled the help file to fix a build error in it.
      </LI>
    </UL>
    <P><B>1.0.08 - Mar 11, 2005<BR>
      </B>
    </P>
    <UL>
      <LI>
      Added additional #if statements to support the old beta 1 edition of VS2005.
      <LI>
        Code merged the SQLite 3.14 source.
      </LI>
    </UL>
    <P><B>1.0.07 - Mar 5, 2005</B><BR>
    </P>
    <UL>
      <LI>
      Made more optimizations to frequently-called functions, resulting in 
      significant performance gains in all tests.
      <LI>
        Recompiled the binaries using the latest VS2005 February CTP, resulting in yet 
        more significant speed gains.&nbsp; The 100k insert test used to take 3.5 

        seconds and the insertwithidentity took almost 8 seconds.&nbsp; With the above 
        two changes, those tests are now executing in 1.9 and 4.9 seconds respectively.</LI></UL>
    <P><B>1.0.06 - Mar 1, 2005<BR>
      </B>
    </P>
    <UL>
      <LI>
      Speed-ups to SQLiteDataReader.&nbsp; It was interop'ing unnecessarily every 
      time it tried to fetch a field due to a logic error.
      <LI>
      Changed/Added some code to SQLiteConvert's internal DbType, Type and 
      TypeAffinity functions.
      <LI>
      Fixed the SQLiteDataReader to obey the flags set in the optional 
      CommandBehavior flag from SQLiteCommand.ExecuteReader().
      <LI>
      Changed the default page size to 1024 to reflect the defaults of SQLite.&nbsp; 
      Ignores the "Page Size" connection string option for memory databases, as tests 
      revealed that changing it resulted in memory corruption errors.
      <LI>
        Performance enhancements to the SQLiteCommand and SQLiteStatement classes which 
        reduced the 100,000 row insert execution time as well as the various Function 
        execution times significantly.
      </LI>
    </UL>
    <P><B>1.0.05 - Feb 25, 2005</B>
    </P>
    <UL>
      <LI>
      Fixed the SQLite3 C# class step/reset functions to accomodate schema changes 
      that invalidate a prepared statement.&nbsp; Statements are recompiled 
      transparently.
      <LI>
      Moved all native DLL declarations to an UnsafeNativeMethods class.
      <LI>
      Split several classes into their own modules for readability.
      <LI>
      Renamed many internal variables, reviewed access to variables marked as 
      internal and altered their protection levels accordingly.
      <LI>
      Due to the presence of the altered sqlite3 codebase and so many added interop 
      functions, I decided to rename the sqlite3 C project and the DLL to 
      SQLite.Interop.DLL.&nbsp; This is the same core sqlite3 codebase but designed 
      specifically for this ADO.NET provider.&nbsp; This eliminates any possibility 
      of someone dropping another build of sqlite3.dll into the system and rendering 
      the provider inoperable.&nbsp; In the future if the folks at sqlite.org finally 
      introduce a method of retrieving column usage for an arbitrary prepared 
      statement, I'll retool this library to be a lightweight function call wrapper 
      around the core binary distribution.
      <LI>
      Added [SuppressUnmanagedCodeSecurity] attribute to the UnsafeNativeMethods 
      class which brings VS2005 November CTP execution speeds inline with the 
      December CTP.
      <LI>
        Added a <B>bin</B>
      directory to the project root where pre-compiled binaries can be found.
      <LI>
        Added a <B>doc</B>
      directory where preliminary documentation on the class library can be found.
      <LI>
        Documented a lot more of the classes internally.
      </LI>
    </UL>
    <P><B>1.0.04 - Feb 24, 2005</B>

    </P>
    <UL>
      <LI>
      Removed the SQLiteContext class and revamped the way UserFunctions work to 
      simplify the imlementation.
      <LI>
      Fixed a counting bug in the TestCases class, specifically in the function tests 
      where I wasn't resetting the counter and it was consequently reporting 
      intrinsic and raw select calls as being much much faster than they actually 
      were.&nbsp; The numbers are now much closer to what I expected for performance, 
      with .NET user-functions still being the slowest, but only by a small margin.
      <LI>
      Small performance tweaks to SQLiteDataReader.
      <LI>
      Added PageSize to the SQLiteConnectionStringBuilder and subsequently to the 
      SQLiteConnection
      <LI>
        Added a PRAGMA encoding=XXX execution statement to the SQLiteConnection after 
        opening a connection.
      </LI>
    </UL>
    <P><B>1.0.03 - Feb 23, 2005</B>
    </P>
    <UL>
      <LI>
      Fixed up SQLiteCommandBuilder to correct implementation errors, which resulted 
      in an enormous performance boost in the InsertMany test.&nbsp;&nbsp; 10,000 row 
      insert that executed in 1500ms now executes in 500ms.
      <LI>
      Fixed several errors in the SQLite3_UTF16 class.&nbsp; ToString() was working 
      incorrectly and the Open() method failed to register user defined functions and 
      collations.
      <LI>
      Fixed a bug in SQLiteCommand.ClearCommands() whereby only the first statement 
      was being properly cleaned up.
      <LI>
      Fixed a bug in SQLiteDataReader whereby calling NextResult() would not properly 
      reset the previously-executed command in the sequence.
      <LI>
        Added an InsertManyWithIdentityFetch test, which appends a select clause to 
        populate the ID of the last inserted row into the InsertCommand, demonstrating 
        ADO.NET's ability to auto-fetch identity columns on insert.
      </LI>
    </UL>
    <P><B>1.0.02 - Feb 21, 2005</B></P>
    <UL>
      <LI>
      Tweaks to the xxx_interop functions that return char *'s, so they also return 
      the length.&nbsp; Saves an interop call to get the UTF-8 string length during 
      conversion to a .NET string.
      <LI>
      Reworked the whole interop.c thing into interop.h and reduced the code required 
      to merge the main sqlite3 codebase.
      <LI>
        Added support for user-defined collations.
      </LI>
    </UL>
  </body>
</html>


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


<
|




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

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

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

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

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

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

1
2
3
4
5
6
7
8

9
10
11
12
13
14
15

16
17
18

19
20






















21

22
23
24

25
26

27

28
29

30

31


32

33
34
35
36

37
38
















39
40
41
42
43
44
45
46
47

48
49
50
51
52




53












54


55
56
57




58
59
60
61

62
63
64


65











66








67
68
69
70
71
72
73
74


















75

76
77

78





79







80



81
82






83

84

85
86
87
88






89
90










































91

92









93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115



116




























117
118





















119
120









121






122


123
124
125
126
127
128
129

130





131


132
133





134
135






















136







137


138
139
140










141


142








143






























144
145

146


147



148
149
150
151









































152
153

154
155
156

157
158

159
160

161
162
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<title></title>
	</head>
	<body>
    ADO.NET 2.0 SQLite Data Provider<br />
    Version 1.0.6 - Feb 28, 2005<br />

    Written by Robert Simpson (<a href="mailto:robert@blackcastlesoft.com">robert@blackcastlesoft.com</a>)<br />
    Released to the public domain, use at your own risk!<br />
    <br />
    This provider was written and verified using the Visual Studio 2005 November and
    December CTP's.<br />
    <br />
    The latest version can be downloaded <a href="http://www.blackcastlesoft.com/files/system.data.sqlite.zip">here</a>

    <br />
    <br />


    <b>Features:</b><br />
    <ul>






















      <li>DbProviderFactory support, just add the XML below at the machine.config and/or app.config level. </li>

      <li>Full support for ATTACH'ed databases.&nbsp; Exposed as <i>Catalogs</i> in the
        schema.&nbsp; When cloning a connection, all attached databases are automatically
        re-attached to the new connection.</li>

      <li>DbConnection.GetSchema(...) support includes the <i>MetaDataCollections</i>, <i>
        DataSourceInformation</i>, <i>Columns</i>, <i>Tables</i>, <i>Views</i>, <i>Catalogs</i>

        and <i>Indexes</i> keywords.</li>

      <li>Enhanced DbDataReader.GetSchemaTable() functionality returns catalog, namespace
        and detailed schema information even for complex queries.</li>

      <li>Named and unnamed parameters.</li>

      <li>Full UTF-8 and UTF-16 support.</li>


      <li>Multiple simultaneous DataReaders (one DataReader per Command however).</li>

      <li>Full support for user-defined scalar and aggregate functions, encapsulated into
        an
        easy-to-use base class in which only a couple of overrides are necessary to implement
        new SQL functions.</li>

      <li>Full support for user-defined collating sequences, every bit as simple to implement
        as user-defined functions and uses the same base class.</li></ul>
















    In order to use the SQLiteFactory and have the SQLite data provider enumerated in
    the DbProviderFactories methods, you must add the following segment into either
    your application's app.config or the system's machine.config located in the %SystemRoot%\Microsoft.Net\Framework\v2.xxxx\Config
    folder:<br />
    <br />
    <pre>
&lt;configuration&gt;
  &lt;system.data&gt;
    &lt;DbProviderFactories&gt;

      &lt;add name="SQLite Data Provider" invariant="System.Data.SQLite" support="3F" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /&gt;
    &lt;/DbProviderFactories&gt;
  &lt;/system.data&gt;
&lt;/configuration&gt;
</pre>




    <br />












    <b>Development Notes Regarding the SQLite 3 Source Code<br />


    </b>*** At this time, the necessary changes to the DLL to support Windows CE have
    not been completed.&nbsp; All function calls that return or pass a 64-bit value
    have been wrapped, but the necessary OS changes have not been finished.<br />




    <br />
      <p></p>
    <p>
      Steps for merging the sqlite3 core codebase:</p>

    <ol>
      <li>Download the latest sqlite3 source from <a href="http://www.sqlite.org/download.html">
        http://www.sqlite.org/download.html</a></li>


      <li>Extract the source code to the <b>SQLite.Interop\src</b> directory of this project</li>











      <li>Open the <b>src\select.c</b> file.</li>








      <li>Add <b>#include "../interop.h" </b>to the top of the file where the other include's
        are.</li>
      <li>Scroll down the <b>select.c</b> file to around line <b>748</b>.&nbsp; Change the name of the function <b>static void generateColumnNames </b>to
    <b>static void _generateColumnNames</b> (<i>note the underscore in front of the name</i>).</li>
      <li>Compile it.</li>
    </ol>
      <b>Version History<br />
        1.06 - Feb 28, 2005<br />


















      </b>

    <ul>
      <li>Speed-ups to SQLiteDataReader.&nbsp; It was interop'ing every time it tried to

        fetch a field due to a logic error.</li>





      <li>Changed/Added some code to SQLiteConvert's internal DbType, Type and TypeAffinity







        functions.</li>



      <li>Fixed the SQLiteDataReader to obey the flags set in the optional CommandBehavior
        flag from SQLiteCommand.ExecuteReader().</li>






		<li>Changed the default page size to 1024 to reflect the defaults of 

		SQLite.&nbsp; Ignores the &quot;Page Size&quot; connection string option for 

		memory databases, as tests revealed that changing it resulted in memory 
		corruption errors.</li>
      <li>Performance enhancements to the SQLiteCommand and SQLiteStatement classes which
        reduced the 100,000 row insert execution time as well as the various Function execution






        times significantly.</li>
    </ul>










































    <b>

      <br />









        1.05 - Feb 25, 2005</b>
    <ul>
      <li>Fixed the SQLite3 C# class step/reset functions to accomodate schema changes
        that invalidate a prepared statement.&nbsp; Statements are recompiled transparently.</li>
      <li>Moved all native DLL declarations to an UnsafeNativeMethods class.</li>
      <li>Split several classes into their own modules for readability.</li>
      <li>Renamed many internal variables, reviewed access to variables marked as internal
        and altered their protection levels accordingly.</li>
      <li>Due to the presence of the altered sqlite3 codebase and so many added interop
        functions, I decided to rename the sqlite3 C project and the DLL to SQLite.Interop.DLL.&nbsp;
        This is the same core sqlite3 codebase but designed specifically for this
        ADO.NET provider.&nbsp; This eliminates any possibility of someone dropping another
        build of sqlite3.dll into the system and rendering the provider inoperable.&nbsp;
        In the future if the folks at sqlite.org finally introduce a method of retrieving
        column usage for an arbitrary prepared statement, I'll retool this library to be
        a lightweight function call wrapper around the core binary distribution.</li>
      <li>Added [SuppressUnmanagedCodeSecurity] attribute to the UnsafeNativeMethods class
        which brings VS2005 November CTP execution speeds inline with the December CTP.</li>
		<li>Added a <b>bin</b> directory to the project root where pre-compiled 
		binaries can be found.</li>
		<li>Added a <b>doc</b> directory where preliminary documentation on the 
		class library can be found.</li>
		<li>Documented a lot more of the classes internally.</li>



    </ul>




























      <b>
        <br />





















        1.04 - Feb 24, 2005</b>
    <ul>









      <li>Removed the SQLiteContext class and revamped the way UserFunctions work to simplify






        the imlementation.</li>


      <li>Fixed a counting bug in the TestCases class, specifically in the function tests
        where I wasn't resetting the counter and it was consequently reporting intrinsic
        and raw select calls as being much much faster than they actually were.&nbsp; The
        numbers are now much closer to what I expected for performance, with .NET user-functions
        still being the slowest, but only by a small margin.</li>
      <li>Small performance tweaks to SQLiteDataReader.</li>
      <li>Added PageSize to the SQLiteConnectionStringBuilder and subsequently to the SQLiteConnection</li>

      <li>Added a PRAGMA encoding=XXX execution statement to the SQLiteConnection after





        opening a connection.</li>


    </ul>
      <b>





        1.03 - Feb 23, 2005</b>
    <ul>






















      <li>Fixed up SQLiteCommandBuilder to correct implementation errors, which resulted







        in an enormous performance boost in the InsertMany test.&nbsp;&nbsp; 10,000 row


        insert that executed in 1500ms now executes in 500ms.</li>
      <li>Fixed several errors in the SQLite3_UTF16 class.&nbsp; ToString() was working
        incorrectly and the Open() method failed to register user defined functions and










        collations.</li>


      <li>Fixed a bug in SQLiteCommand.ClearCommands() whereby only the first statement








        was being properly cleaned up.</li>






























      <li>Fixed a bug in SQLiteDataReader whereby calling NextResult() would not properly
        reset the previously-executed command in the sequence.</li>

      <li>Added an InsertManyWithIdentityFetch test, which appends a select clause to populate


        the ID of the last inserted row into the InsertCommand, demonstrating ADO.NET's



        ability to auto-fetch identity columns on insert.</li>
    </ul>
    <p>
      <b>









































        1.02 - Feb 21, 2005</b></p>
    <ul>

      <li>Tweaks to the xxx_interop functions that return char *'s, so they also return
        the length.&nbsp; Saves an interop call to get the UTF-8 string length during conversion
        to a .NET string.</li>

      <li>Reworked the whole interop.c thing into interop.h and reduced the code required
        to merge the main sqlite3 codebase.</li>

      <li>Added support for user-defined collations.</li>
    </ul>

	</body>
</html>
Changes to test/Program.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


17
18

19
20


21
22
23
24


25
26
27
28
29
using System;
using System.Data;
using System.Text;
using System.Data.Common;
using System.Data.SQLite;

namespace test
{
  class Program
  {
    static void Main(string[] args)
    {
      DbProviderFactory fact;
      DbConnection cnn;

      System.IO.File.Delete("test.db3");



      using (cnn = new SQLiteConnection())

      {
        fact = DbProviderFactories.GetFactory("System.Data.SQLite");


        cnn.ConnectionString = "Data Source=test.db3";
        cnn.Open();
        TestCases.Run(fact, cnn);
      }



      Console.ReadKey();
    }
  }
}












|
|

|
>
>

<
>
|
|
>
>




>
>





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Data;
using System.Text;
using System.Data.Common;
using System.Data.SQLite;

namespace test
{
  class Program
  {
    static void Main(string[] args)
    {
      DbProviderFactory fact; // = DbProviderFactories.GetFactory("System.Data.OleDb");
      DbConnection cnn; //  = fact.CreateConnection();

//      cnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Temp\\db.mdb;Persist Security Info=False";
//      cnn.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DirectLink;Data Source=MASTER";
//      cnn.Open();


//      TestCases.Run(fact, cnn);

      fact = DbProviderFactories.GetFactory("System.Data.SQLite");
      using (cnn = fact.CreateConnection())
      {
        cnn.ConnectionString = "Data Source=test.db3";
        cnn.Open();
        TestCases.Run(fact, cnn);
      }

      System.IO.File.Delete("test.db3");

      Console.ReadKey();
    }
  }
}
Changes to test/TestCases.cs.
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

      try { CoersionTest(cnn); Console.WriteLine("FAIL - CoersionTest"); }
      catch (Exception) { Console.WriteLine("SUCCESS - CoersionTest"); }

      try { ParameterizedInsert(cnn); Console.WriteLine("SUCCESS - ParameterizedInsert"); }
      catch (Exception) { Console.WriteLine("FAIL - ParameterizedInsert"); }

      try { BinaryInsert(cnn); Console.WriteLine("SUCCESS - BinaryInsert (using named parameter)"); }
      catch (Exception) { Console.WriteLine("FAIL - BinaryInsert"); }

      try { VerifyBinaryData(cnn); Console.WriteLine("SUCCESS - VerifyBinaryData"); }
      catch (Exception) { Console.WriteLine("FAIL - VerifyBinaryData"); }

      try { LockTest(cnn); Console.WriteLine("SUCCESS - LockTest"); }
      catch (Exception) { Console.WriteLine("FAIL - LockTest"); }

      try { ParameterizedInsertMissingParams(cnn); Console.WriteLine("FAIL - ParameterizedInsertMissingParams\r\n"); }
      catch (Exception) { Console.WriteLine("SUCCESS - ParameterizedInsertMissingParams\r\n"); }

//      try { TimeoutTest(cnn); Console.WriteLine("SUCCESS - TimeoutTest"); }
//      catch (Exception) { Console.WriteLine("FAIL - TimeoutTest"); }

      try { DataAdapter(fact, cnn, false); Console.WriteLine(""); }
      catch (Exception) { Console.WriteLine("FAIL - DataAdapter"); }

      try { DataAdapter(fact, cnn, true); Console.WriteLine(""); }
      catch (Exception) { Console.WriteLine("FAIL - DataAdapterWithIdentityFetch"); }

      try { FastInsertMany(cnn); Console.WriteLine(""); }
      catch (Exception) { Console.WriteLine("FAIL - FastInsertMany"); }

      try { IterationTest(cnn); Console.WriteLine(""); }
      catch (Exception) { Console.WriteLine("FAIL - Iteration Test"); }

      try { UserFunction(cnn); Console.WriteLine(""); }
      catch (Exception) { Console.WriteLine("FAIL - UserFunction"); }

      try { UserAggregate(cnn); Console.WriteLine(""); }
      catch (Exception) { Console.WriteLine("FAIL - UserAggregate"); }

      try { UserCollation(cnn); Console.WriteLine("SUCCESS - UserCollation"); }
      catch (Exception) { Console.WriteLine("FAIL - UserCollation"); }

      try { DropTable(cnn); Console.WriteLine("SUCCESS - DropTable"); }
      catch (Exception) { Console.WriteLine("FAIL - DropTable"); }

      Console.WriteLine("\r\nTests Finished.");
    }

    internal static void CreateTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "CREATE TABLE TestCase (ID integer primary key autoincrement, Field1 Integer, Field2 Float, Field3 VARCHAR(50), Field4 CHAR(10), Field5 DateTime, Field6 Image)";
        //cmd.CommandText = "CREATE TABLE TestCase (ID bigint primary key identity, Field1 Integer, Field2 Float, Field3 VARCHAR(50), Field4 CHAR(10), Field5 DateTime, Field6 Image)";
        cmd.ExecuteNonQuery();
      }
    }

    internal static void DropTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())







|





<
<
<
|
|

<
<
<
|
|

|
<
<
<
|

|


|


|
















<







78
79
80
81
82
83
84
85
86
87
88
89
90



91
92
93



94
95
96
97



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129

      try { CoersionTest(cnn); Console.WriteLine("FAIL - CoersionTest"); }
      catch (Exception) { Console.WriteLine("SUCCESS - CoersionTest"); }

      try { ParameterizedInsert(cnn); Console.WriteLine("SUCCESS - ParameterizedInsert"); }
      catch (Exception) { Console.WriteLine("FAIL - ParameterizedInsert"); }

      try { BinaryInsert(cnn); Console.WriteLine("SUCCESS - BinaryInsert"); }
      catch (Exception) { Console.WriteLine("FAIL - BinaryInsert"); }

      try { VerifyBinaryData(cnn); Console.WriteLine("SUCCESS - VerifyBinaryData"); }
      catch (Exception) { Console.WriteLine("FAIL - VerifyBinaryData"); }




      try { ParameterizedInsertMissingParams(cnn); Console.WriteLine("FAIL - ParameterizedInsertMissingParams"); }
      catch (Exception) { Console.WriteLine("SUCCESS - ParameterizedInsertMissingParams"); }




      try { InsertMany(fact, cnn, false); Console.WriteLine("SUCCESS - InsertMany"); }
      catch (Exception) { Console.WriteLine("FAIL - InsertMany"); }

      try { InsertMany(fact, cnn, true); Console.WriteLine("SUCCESS - InsertManyWithIdentityFetch"); }



      catch (Exception) { Console.WriteLine("FAIL - InsertManyWithIdentityFetch"); }

      try { IterationTest(cnn); Console.WriteLine("SUCCESS - Iteration Test"); }
      catch (Exception) { Console.WriteLine("FAIL - Iteration Test"); }

      try { UserFunction(cnn); Console.WriteLine("SUCCESS - UserFunction"); }
      catch (Exception) { Console.WriteLine("FAIL - UserFunction"); }

      try { UserAggregate(cnn); Console.WriteLine("SUCCESS - UserAggregate"); }
      catch (Exception) { Console.WriteLine("FAIL - UserAggregate"); }

      try { UserCollation(cnn); Console.WriteLine("SUCCESS - UserCollation"); }
      catch (Exception) { Console.WriteLine("FAIL - UserCollation"); }

      try { DropTable(cnn); Console.WriteLine("SUCCESS - DropTable"); }
      catch (Exception) { Console.WriteLine("FAIL - DropTable"); }

      Console.WriteLine("\r\nTests Finished.");
    }

    internal static void CreateTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "CREATE TABLE TestCase (ID integer primary key autoincrement, Field1 Integer, Field2 Float, Field3 VARCHAR(50), Field4 CHAR(10), Field5 DateTime, Field6 Image)";

        cmd.ExecuteNonQuery();
      }
    }

    internal static void DropTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
            if (Field4 != "Field4") throw new ArgumentOutOfRangeException("Non-Match on Field4");
            if (Field5.CompareTo(DateTime.Parse("2005-01-01 13:49:00")) != 0) throw new ArgumentOutOfRangeException("Non-Match on Field5");
          }
          else throw new ArgumentOutOfRangeException("No data in table");
        }
      }
    }
    
    internal static void CoersionTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field1, Field2, Field3, Field4, Field5, 'A', 1, 1 + 1, 3.14159 FROM TestCase";
        using (DbDataReader rd = cmd.ExecuteReader())
        {







|







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
            if (Field4 != "Field4") throw new ArgumentOutOfRangeException("Non-Match on Field4");
            if (Field5.CompareTo(DateTime.Parse("2005-01-01 13:49:00")) != 0) throw new ArgumentOutOfRangeException("Non-Match on Field5");
          }
          else throw new ArgumentOutOfRangeException("No data in table");
        }
      }
    }

    internal static void CoersionTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field1, Field2, Field3, Field4, Field5, 'A', 1, 1 + 1, 3.14159 FROM TestCase";
        using (DbDataReader rd = cmd.ExecuteReader())
        {
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
        cmd.Parameters.Add(Field4);
        cmd.Parameters.Add(Field5);

        cmd.ExecuteNonQuery();
      }
    }

    // Inserts binary data into the database using a named parameter
    internal static void BinaryInsert(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field6) VALUES(@bin)";
        DbParameter Field6 = cmd.CreateParameter();

        byte[] b = new byte[4000];
        b[0] = 1;
        b[100] = 2;
        b[1000] = 3;
        b[2000] = 4;
        b[3000] = 5;

        Field6.ParameterName = "@bin";
        Field6.Value = b;

        cmd.Parameters.Add(Field6);

        cmd.ExecuteNonQuery();
      }
    }







<




|









<







231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
        cmd.Parameters.Add(Field4);
        cmd.Parameters.Add(Field5);

        cmd.ExecuteNonQuery();
      }
    }


    internal static void BinaryInsert(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field6) VALUES(?)";
        DbParameter Field6 = cmd.CreateParameter();

        byte[] b = new byte[4000];
        b[0] = 1;
        b[100] = 2;
        b[1000] = 3;
        b[2000] = 4;
        b[3000] = 5;


        Field6.Value = b;

        cmd.Parameters.Add(Field6);

        cmd.ExecuteNonQuery();
      }
    }
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
          if (b[1000] != 3) throw new ArgumentException();
          if (b[2000] != 4) throw new ArgumentException();
          if (b[3000] != 5) throw new ArgumentException();
        }
      }
    }

    internal static void LockTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field6 FROM TestCase WHERE Field6 IS NOT NULL";
        byte[] b = new byte[4000];

        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read() == false) throw new ArgumentOutOfRangeException();

          rd.GetBytes(0, 0, b, 0, 4000);

          if (b[0] != 1) throw new ArgumentException();
          if (b[100] != 2) throw new ArgumentException();
          if (b[1000] != 3) throw new ArgumentException();
          if (b[2000] != 4) throw new ArgumentException();
          if (b[3000] != 5) throw new ArgumentException();

          using (DbConnection clone = (DbConnection)((ICloneable)cnn).Clone())
          {
            using (DbCommand newcmd = clone.CreateCommand())
            {
              newcmd.CommandText = "DELETE FROM TestCase WHERE Field6 IS NULL";
              newcmd.CommandTimeout = 2;
              int cmdStart = Environment.TickCount;
              int cmdEnd;

              try
              {
                newcmd.ExecuteNonQuery(); // should fail because there's a reader on the database
                throw new ArgumentException(); // If we got here, the test failed
              }
              catch
              {
                cmdEnd = Environment.TickCount;
                if (cmdEnd - cmdStart < 2000 || cmdEnd - cmdStart > 3000)
                  throw new ArgumentException(); // Didn't wait the right amount of time

              }
            }
          }
        }
      }
    }

    internal static void ParameterizedInsertMissingParams(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(?,?,?,?,?)";
        DbParameter Field1 = cmd.CreateParameter();
        DbParameter Field2 = cmd.CreateParameter();







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







275
276
277
278
279
280
281














































282
283
284
285
286
287
288
          if (b[1000] != 3) throw new ArgumentException();
          if (b[2000] != 4) throw new ArgumentException();
          if (b[3000] != 5) throw new ArgumentException();
        }
      }
    }















































    internal static void ParameterizedInsertMissingParams(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(?,?,?,?,?)";
        DbParameter Field1 = cmd.CreateParameter();
        DbParameter Field2 = cmd.CreateParameter();
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431


432
433
434
435

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
        cmd.Parameters.Add(Field4);

        // Assertion here, not enough parameters
        cmd.ExecuteNonQuery();
      }
    }

    // Utilizes the SQLiteCommandBuilder, 
    // which in turn utilizes SQLiteDataReader's GetSchemaTable() functionality
    // This insert is slow because it must raise callbacks before and after every update.
    // For a fast update, see the FastInsertMany function beneath this one
    internal static void DataAdapter(DbProviderFactory fact, DbConnection cnn, bool bWithIdentity)
    {
      using (DbTransaction dbTrans = cnn.BeginTransaction())
      {
        using (DbDataAdapter adp = fact.CreateDataAdapter())
        {
          using (DbCommand cmd = cnn.CreateCommand())
          {
            cmd.Transaction = dbTrans;
            cmd.CommandText = "SELECT * FROM TestCase WHERE 1 = 2";
            adp.SelectCommand = cmd;

            using (DbCommandBuilder bld = fact.CreateCommandBuilder())
            {
              bld.DataAdapter = adp;
              using (adp.InsertCommand = (DbCommand)((ICloneable)bld.GetInsertCommand()).Clone())
              {
                if (bWithIdentity)
                {
                  adp.InsertCommand.CommandText += ";SELECT last_insert_rowid() AS [ID]";
                  adp.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
                }
                bld.DataAdapter = null;

                using (DataTable tbl = new DataTable())
                {
                  adp.Fill(tbl);
                  for (int n = 0; n < 10000; n++)
                  {
                    DataRow row = tbl.NewRow();
                    row[1] = n + (50000 * ((bWithIdentity == true) ? 2 : 1));
                    tbl.Rows.Add(row);
                  }

                  Console.WriteLine(String.Format("          Inserting using CommandBuilder and DataAdapter\r\n          ->{0} (10,000 rows) ...", (bWithIdentity == true) ? "(with identity fetch)" : ""));
                  int dtStart = Environment.TickCount;
                  adp.Update(tbl);
                  int dtEnd = Environment.TickCount;
                  dtEnd -= dtStart;
                  Console.Write(String.Format("          -> Insert Ends in {0} ms ... ", (dtEnd)));

                  dtStart = Environment.TickCount;
                  dbTrans.Commit();
                  dtEnd = Environment.TickCount;
                  dtEnd -= dtStart;
                  Console.WriteLine(String.Format("Commits in {0} ms", (dtEnd)));
                }
              }
            }
          }
        }
      }
    }

    internal static void FastInsertMany(DbConnection cnn)
    {
      using (DbTransaction dbTrans = cnn.BeginTransaction())
      {
        int dtStart;


        int dtEnd;

        using (DbCommand cmd = cnn.CreateCommand())
        {

          cmd.CommandText = "INSERT INTO TestCase(Field1) VALUES(?)";
          DbParameter Field1 = cmd.CreateParameter();

          cmd.Parameters.Add(Field1);

          Console.WriteLine(String.Format("          Fast insert using parameters and prepared statement\r\n          -> (100,000 rows) Begins ... "));
          dtStart = Environment.TickCount;
          for (int n = 0; n < 100000; n++)
          {
            Field1.Value = n + 200000;
            cmd.ExecuteNonQuery();
          }

          dtEnd = Environment.TickCount;
          dtEnd -= dtStart;
          Console.Write(String.Format("          -> Ends in {0} ms ... ", (dtEnd)));
        }

        dtStart = Environment.TickCount;
        dbTrans.Commit();
        dtEnd = Environment.TickCount;
        dtEnd -= dtStart;
        Console.WriteLine(String.Format("Commits in {0} ms", (dtEnd)));
      }
    }

    // Causes the user-defined function to be called
    internal static void UserFunction(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        int nTimes;
        int dtStart;

        nTimes = 0;
        cmd.CommandText = "SELECT Foo('ee','foo')";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          User (text)  command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT Foo(10,11)";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          UserFunction command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT ABS(1)";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          Intrinsic    command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT lower('FOO')";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          Intrin (txt) command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT 1";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          Raw Value    command executed {0} times in 1 second.", nTimes));
      }
    }

    internal static void IterationTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        int dtStart;
        int dtEnd;
        int nCount;
        long n;

        cmd.CommandText = "SELECT Foo(ID, ID) FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        Console.WriteLine(String.Format("          User Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart)));

        cmd.CommandText = "SELECT ID FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        Console.WriteLine(String.Format("          Raw iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart)));

        cmd.CommandText = "SELECT ABS(ID) FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        Console.WriteLine(String.Format("          Intrinsic Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart)));

      }
    }

    // Open a reader and then attempt to write to test the writer's command timeout property
    // SQLite doesn't allow a write when a reader is active.
    internal static void TimeoutTest(DbConnection cnn)
    {
      using (DbCommand cmdRead = cnn.CreateCommand())
      {
        cmdRead.CommandText = "SELECT ID FROM TestCase";
        using (DbDataReader rd = cmdRead.ExecuteReader())
        {
          using (DbCommand cmdwrite = cnn.CreateCommand())
          {
            cmdwrite.CommandText = "UPDATE [TestCase] SET [ID] = [ID]";
            cmdwrite.CommandTimeout = 5;

            int dwtick = Environment.TickCount;
            try
            {
              cmdwrite.ExecuteNonQuery();
            }
            catch (SQLiteException)
            {
              dwtick = (Environment.TickCount - dwtick) / 1000;
              if (dwtick < 5 || dwtick > 6)
                throw new ArgumentOutOfRangeException();
            }
          }
        }
      }
    }

    // Causes the user-defined aggregate to be iterated through
    internal static void UserAggregate(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        int dtStart;
        int n = 0;
        int nCount;

        cmd.CommandText = "SELECT MyCount(*) FROM TestCase";

        nCount = 0;
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          n = Convert.ToInt32(cmd.ExecuteScalar());
          nCount++;
        }
        if (n != 120003) throw new ArgumentOutOfRangeException("Unexpected count");
        Console.WriteLine(String.Format("          UserAggregate executed {0} times in 1 second.", nCount));
      }
    }

    // Causes the user-defined collation sequence to be iterated through
    internal static void UserCollation(DbConnection cnn)
    {







<
|
<
<
|








|





|
<
|
|
|
|
|
<

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









|



|
|








|
|








|
|








|
|








|
|












|
|





|








|

|



|








|

|



|








|

|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|






|
|




|







304
305
306
307
308
309
310

311


312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332

333
334
335
336
337
338
339
340
341
342

















343


344




345
346
347
348
349

350
351
352

353

354
355





356
357



358
359





360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476






























477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
        cmd.Parameters.Add(Field4);

        // Assertion here, not enough parameters
        cmd.ExecuteNonQuery();
      }
    }


    // Utilizes the SQLiteCommandBuilder, which in turn utilizes SQLiteDataReader's GetSchemaTable() functionality


    internal static void InsertMany(DbProviderFactory fact, DbConnection cnn, bool bWithIdentity)
    {
      using (DbTransaction dbTrans = cnn.BeginTransaction())
      {
        using (DbDataAdapter adp = fact.CreateDataAdapter())
        {
          using (DbCommand cmd = cnn.CreateCommand())
          {
            cmd.Transaction = dbTrans;
            cmd.CommandText = "SELECT * FROM TestCase WHERE 1=2";
            adp.SelectCommand = cmd;

            using (DbCommandBuilder bld = fact.CreateCommandBuilder())
            {
              bld.DataAdapter = adp;
              adp.InsertCommand = bld.GetInsertCommand();

              if (bWithIdentity)
              {
                adp.InsertCommand.CommandText += ";SELECT [ID] FROM TestCase WHERE RowID = last_insert_rowid()";
                adp.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
              }


              using (DataTable tbl = new DataTable())
              {
                adp.Fill(tbl);
                for (int n = 0; n < 100000; n++)
                {
                  DataRow row = tbl.NewRow();
                  row[1] = n + 10000;
                  tbl.Rows.Add(row);
                }




















                Console.Write(String.Format("          InsertMany{0} (100000 rows) Begins ... ", (bWithIdentity == true) ? "WithIdentityFetch":"                 "));




                long dtStart = DateTime.Now.Ticks;
                adp.Update(tbl);
                long dtEnd = DateTime.Now.Ticks;
                dtEnd -= dtStart;
                Console.Write(String.Format("Ends in {0} ms ... ", (dtEnd / 10000)));


                dtStart = DateTime.Now.Ticks;
                dbTrans.Commit();

                dtEnd = DateTime.Now.Ticks;

                dtEnd -= dtStart;
                Console.WriteLine(String.Format("Commits in {0} ms", (dtEnd / 10000)));





              }
            }



          }
        }





      }
    }

    // Causes the user-defined function to be called
    internal static void UserFunction(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        int nTimes;
        long dtStart;

        nTimes = 0;
        cmd.CommandText = "SELECT Foo('ee','foo')";
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          User (text)  command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT Foo(10,11)";
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          UserFunction command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT ABS(1)";
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          Intrinsic    command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT lower('FOO')";
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          Intrin (txt) command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT 1";
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        Console.WriteLine(String.Format("          Raw Value    command executed {0} times in 1 second.", nTimes));
      }
    }

    internal static void IterationTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        long dtStart;
        long dtEnd;
        int nCount;
        long n;

        cmd.CommandText = "SELECT Foo(ID, ID) FROM TestCase";
        cmd.Prepare();
        dtStart = DateTime.Now.Ticks;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = DateTime.Now.Ticks;
        }
        Console.WriteLine(String.Format("          User Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart) / 10000));

        cmd.CommandText = "SELECT ID FROM TestCase";
        cmd.Prepare();
        dtStart = DateTime.Now.Ticks;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = DateTime.Now.Ticks;
        }
        Console.WriteLine(String.Format("          Raw iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart) / 10000));

        cmd.CommandText = "SELECT ABS(ID) FROM TestCase";
        cmd.Prepare();
        dtStart = DateTime.Now.Ticks;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = DateTime.Now.Ticks;
        }
        Console.WriteLine(String.Format("          Intrinsic Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart) / 10000));































      }
    }

    // Causes the user-defined aggregate to be iterated through
    internal static void UserAggregate(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        long dtStart;
        int n = 0;
        int nCount;

        cmd.CommandText = "SELECT MyCount(*) FROM TestCase";

        nCount = 0;
        dtStart = DateTime.Now.Ticks;
        while (DateTime.Now.Ticks - dtStart < 10000000)
        {
          n = Convert.ToInt32(cmd.ExecuteScalar());
          nCount++;
        }
        if (n != 200003) throw new ArgumentOutOfRangeException("Unexpected count");
        Console.WriteLine(String.Format("          UserAggregate executed {0} times in 1 second.", nCount));
      }
    }

    // Causes the user-defined collation sequence to be iterated through
    internal static void UserCollation(DbConnection cnn)
    {
Changes to test/app.config.
1
2
3
4
5
6
7
8
<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite"/>
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
    </DbProviderFactories>
  </system.data>
</configuration>



<
|



1
2
3

4
5
6
7
<configuration>
  <system.data>
    <DbProviderFactories>

      <add name="SQLite Data Provider" invariant="System.Data.SQLite" support="3F" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
    </DbProviderFactories>
  </system.data>
</configuration>
Changes to test/test.csproj.
1
2
3
4
5
6
7
8
9
10
11
12
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.50727</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>test</RootNamespace>
    <AssemblyName>test</AssemblyName>
    <WarningLevel>4</WarningLevel>
    <IsWebBootstrapper>true</IsWebBootstrapper>




|







1
2
3
4
5
6
7
8
9
10
11
12
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.41202</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{E27B1B1E-19C0-45E8-AA74-B6E1C041A130}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>test</RootNamespace>
    <AssemblyName>test</AssemblyName>
    <WarningLevel>4</WarningLevel>
    <IsWebBootstrapper>true</IsWebBootstrapper>
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    <ApplicationVersion>1.0.0.*</ApplicationVersion>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>..\bin\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <PlatformTarget>AnyCPU</PlatformTarget>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>none</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>..\bin\</OutputPath>
    <DefineConstants>
    </DefineConstants>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <FileAlignment>512</FileAlignment>
    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Data.SQLite, Version=1.0.23.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
      <SpecificVersion>False</SpecificVersion>
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
    <Compile Include="Program.cs" />
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="TestCases.cs" />
  </ItemGroup>
  <ItemGroup>
    <BootstrapperFile Include="Microsoft.Net.Framework.2.0">
      <InProject>False</InProject>
      <ProductName>.NET Framework 2.0</ProductName>
      <Install>true</Install>
    </BootstrapperFile>
  </ItemGroup>
  <ItemGroup>
    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
      <InProject>False</InProject>
      <ProductName>.NET Framework 2.0 Beta</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>







|

|


|

|


|
<
<




<
<
<
<
















|
|
|
|
<






23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40


41
42
43
44




45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
    <ApplicationVersion>1.0.0.*</ApplicationVersion>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>.\bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>.\bin\Release\</OutputPath>
    <DefineConstants>
    </DefineConstants>
    <PlatformTarget>x86</PlatformTarget>


  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />




    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
    <Compile Include="Program.cs" />
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="TestCases.cs" />
  </ItemGroup>
  <ItemGroup>
    <BootstrapperFile Include="Microsoft.Net.Framework.2.0">
      <InProject>False</InProject>
      <ProductName>.NET Framework 2.0</ProductName>
      <Install>true</Install>
    </BootstrapperFile>
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite.csproj">
      <Project>{AC139951-261A-4463-B6FA-AEBC25283A66}</Project>
      <Name>System.Data.SQLite</Name>
    </ProjectReference>

  </ItemGroup>
  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>
Changes to test/test.csproj.user.
1
2
3













4
5
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <LastOpenVersion>8.0.50215</LastOpenVersion>













  </PropertyGroup>
</Project>


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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <LastOpenVersion>8.0.41202</LastOpenVersion>
    <ProjectView>ProjectFiles</ProjectView>
    <ProjectTrust>0</ProjectTrust>
    <PublishUrlHistory>http://localhost/test||||</PublishUrlHistory>
    <InstallUrlHistory>||||</InstallUrlHistory>
    <SupportUrlHistory>||||</SupportUrlHistory>
    <UpdateUrlHistory>||||</UpdateUrlHistory>
    <BootstrapperUrlHistory>||||</BootstrapperUrlHistory>
    <ApplicationRevision>0</ApplicationRevision>
    <FallbackCulture>en-US</FallbackCulture>
    <VerifyUploadedFiles>true</VerifyUploadedFiles>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
  </PropertyGroup>
</Project>
Deleted testce/AssemblyInfo.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("cetest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("cetest")]
[assembly: AssemblyCopyright("Copyright ©  2005")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM componenets.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("308969a2-e089-42db-afe3-bf564d8d62c3")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.0.0")]

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































Deleted testce/Form1.Designer.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
namespace test
{
	partial class Form1
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;
		private System.Windows.Forms.MainMenu mainMenu1;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
      this.mainMenu1 = new System.Windows.Forms.MainMenu();
      this.textBox1 = new System.Windows.Forms.TextBox();
      this.SuspendLayout();
      // 
      // textBox1
      // 
      this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
      this.textBox1.Location = new System.Drawing.Point(0, 0);
      this.textBox1.Multiline = true;
      this.textBox1.Name = "textBox1";
      this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
      this.textBox1.Size = new System.Drawing.Size(240, 268);
      this.textBox1.TabIndex = 0;
      this.textBox1.WordWrap = false;
      // 
      // Form1
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
      this.ClientSize = new System.Drawing.Size(240, 268);
      this.Controls.Add(this.textBox1);
      this.Menu = this.mainMenu1;
      this.Name = "Form1";
      this.Text = "Form1";
      this.ResumeLayout(false);

		}

		#endregion

		private System.Windows.Forms.TextBox textBox1;
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































Deleted testce/Form1.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace test
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
    }

		public void WriteLine(string str)
		{
			textBox1.Text += str + "\r\n";
		}

    public void Write(string str)
    {
      textBox1.Text += str;
    }
	}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































Deleted testce/Form1.resx.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <metadata name="mainMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
    <value>17, 17</value>
  </metadata>
  <metadata name="$this.Skin" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <value>True</value>
  </metadata>
</root>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































Deleted testce/Program.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System;
using System.Data;
using System.Text;
using System.Data.Common;
using System.Data.SQLite;

namespace test
{
  class Program
  {
    [MTAThread]
    static void Main()
    {
      DbConnection cnn;

      SQLiteFunction.RegisterFunction(typeof(TestFunc));
      SQLiteFunction.RegisterFunction(typeof(MyCount));
      SQLiteFunction.RegisterFunction(typeof(MySequence));

      try
      {
        System.IO.File.Delete("test.db3");
      }
      catch
      {
      }

      using (cnn = new SQLiteConnection())
      {
        TestCases tests = new TestCases();

        cnn.ConnectionString = "Data Source=test.db3";
        cnn.Open();
        tests.Run(cnn);

        System.Windows.Forms.Application.Run(tests.frm);
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































Deleted testce/TestCases.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
using System;
using System.Data.Common;
using System.Data;
using System.Data.SQLite;

namespace test
{

  /// <summary>
  /// Scalar user-defined function.  In this example, the same class is declared twice with 
  /// different function names to demonstrate how to use alias names for user-defined functions.
  /// </summary>
  [SQLiteFunction(Name = "Foo", Arguments = 2, FuncType = FunctionType.Scalar)]
  [SQLiteFunction(Name = "TestFunc", Arguments = 2, FuncType = FunctionType.Scalar)]
  class TestFunc : SQLiteFunction
  {
    public override object Invoke(object[] args)
    {
      if (args[0].GetType() != typeof(int)) return args[0];

      int Param1 = Convert.ToInt32(args[0]); // First parameter
      int Param2 = Convert.ToInt32(args[1]); // Second parameter

      return Param1 + Param2;
    }
  }

  /// <summary>
  /// Aggregate user-defined function.  Arguments = -1 means any number of arguments is acceptable
  /// </summary>
  [SQLiteFunction(Name = "MyCount", Arguments = -1, FuncType = FunctionType.Aggregate)]
  class MyCount : SQLiteFunction
  {
    public override void Step(object[] args, int nStep, ref object contextData)
    {
      if (contextData == null)
      {
        contextData = 1;
      }
      else
        contextData = (int)contextData + 1;
    }

    public override object Final(object contextData)
    {
      return contextData;
    }
  }

  /// <summary>
  /// User-defined collating sequence.
  /// </summary>
  [SQLiteFunction(Name = "MYSEQUENCE", FuncType = FunctionType.Collation)]
  class MySequence : SQLiteFunction
  {
    public override int Compare(string param1, string param2)
    {
      // Make sure the string "Field3" is sorted out of order
      if (param1 == "Field3") return 1;
      if (param2 == "Field3") return -1;
      return String.Compare(param1, param2, true);
    }
  }

  internal class TestCases
  {
    internal Form1 frm;

    internal void Run(DbConnection cnn)
    {
      frm = new Form1();

      frm.Show();

      frm.WriteLine("\r\nBeginning Test on " + cnn.GetType().ToString());
      try { CreateTable(cnn); frm.WriteLine("SUCCESS - CreateTable"); }
      catch (Exception) { frm.WriteLine("FAIL - CreateTable"); }

      try { InsertTable(cnn); frm.WriteLine("SUCCESS - InsertTable"); }
      catch (Exception) { frm.WriteLine("FAIL - InsertTable"); }

      try { VerifyInsert(cnn); frm.WriteLine("SUCCESS - VerifyInsert"); }
      catch (Exception) { frm.WriteLine("FAIL - VerifyInsert"); }

      try { CoersionTest(cnn); frm.WriteLine("FAIL - CoersionTest"); }
      catch (Exception) { frm.WriteLine("SUCCESS - CoersionTest"); }

      try { ParameterizedInsert(cnn); frm.WriteLine("SUCCESS - ParameterizedInsert"); }
      catch (Exception) { frm.WriteLine("FAIL - ParameterizedInsert"); }

      try { BinaryInsert(cnn); frm.WriteLine("SUCCESS - BinaryInsert"); }
      catch (Exception) { frm.WriteLine("FAIL - BinaryInsert"); }

      try { VerifyBinaryData(cnn); frm.WriteLine("SUCCESS - VerifyBinaryData"); }
      catch (Exception) { frm.WriteLine("FAIL - VerifyBinaryData"); }

      try { LockTest(cnn); frm.WriteLine("SUCCESS - LockTest"); }
      catch (Exception) { frm.WriteLine("FAIL - LockTest"); }

      try { ParameterizedInsertMissingParams(cnn); frm.WriteLine("FAIL - ParameterizedInsertMissingParams"); }
      catch (Exception) { frm.WriteLine("SUCCESS - ParameterizedInsertMissingParams"); }

      try { InsertMany(cnn, false); frm.WriteLine("SUCCESS - InsertMany"); }
      catch (Exception) { frm.WriteLine("FAIL - InsertMany"); }

      try { InsertMany(cnn, true); frm.WriteLine("SUCCESS - InsertManyWithIdentityFetch"); }
      catch (Exception) { frm.WriteLine("FAIL - InsertManyWithIdentityFetch"); }

      try { FastInsertMany(cnn); frm.WriteLine("SUCCESS - FastInsertMany"); }
      catch (Exception) { frm.WriteLine("FAIL - FastInsertMany"); }

      try { IterationTest(cnn); frm.WriteLine("SUCCESS - Iteration Test"); }
      catch (Exception) { frm.WriteLine("FAIL - Iteration Test"); }

      try { UserFunction(cnn); frm.WriteLine("SUCCESS - UserFunction"); }
      catch (Exception) { frm.WriteLine("FAIL - UserFunction"); }

      try { UserAggregate(cnn); frm.WriteLine("SUCCESS - UserAggregate"); }
      catch (Exception) { frm.WriteLine("FAIL - UserAggregate"); }

      try { UserCollation(cnn); frm.WriteLine("SUCCESS - UserCollation"); }
      catch (Exception) { frm.WriteLine("FAIL - UserCollation"); }

      try { DropTable(cnn); frm.WriteLine("SUCCESS - DropTable"); }
      catch (Exception) { frm.WriteLine("FAIL - DropTable"); }

      frm.WriteLine("\r\nTests Finished.");
    }

    internal void CreateTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "CREATE TABLE TestCase (ID integer primary key autoincrement, Field1 Integer, Field2 Float, Field3 VARCHAR(50), Field4 CHAR(10), Field5 DateTime, Field6 Image)";
        //cmd.CommandText = "CREATE TABLE TestCase (ID bigint primary key identity, Field1 Integer, Field2 Float, Field3 VARCHAR(50), Field4 CHAR(10), Field5 DateTime, Field6 Image)";
        cmd.ExecuteNonQuery();
      }
    }

    internal void DropTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "DROP TABLE TestCase";
        cmd.ExecuteNonQuery();
      }
    }

    internal void InsertTable(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(1, 3.14159, 'Field3', 'Field4', '2005-01-01 13:49:00')";
        cmd.ExecuteNonQuery();
      }
    }

    internal void VerifyInsert(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field1, Field2, Field3, Field4, Field5 FROM TestCase";
        cmd.Prepare();
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read())
          {
            long Field1 = rd.GetInt64(0);
            double Field2 = rd.GetDouble(1);
            string Field3 = rd.GetString(2);
            string Field4 = rd.GetString(3).TrimEnd();
            DateTime Field5 = rd.GetDateTime(4);

            if (Field1 != 1) throw new ArgumentOutOfRangeException("Non-Match on Field1");
            if (Field2 != 3.14159) throw new ArgumentOutOfRangeException("Non-Match on Field2");
            if (Field3 != "Field3") throw new ArgumentOutOfRangeException("Non-Match on Field3");
            if (Field4 != "Field4") throw new ArgumentOutOfRangeException("Non-Match on Field4");
            if (Field5.CompareTo(DateTime.Parse("2005-01-01 13:49:00")) != 0) throw new ArgumentOutOfRangeException("Non-Match on Field5");
          }
          else throw new ArgumentOutOfRangeException("No data in table");
        }
      }
    }

    internal void CoersionTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field1, Field2, Field3, Field4, Field5, 'A', 1, 1 + 1, 3.14159 FROM TestCase";
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read())
          {
            object Field1 = rd.GetInt32(0);
            object Field2 = rd.GetDouble(1);
            object Field3 = rd.GetString(2);
            object Field4 = rd.GetString(3).TrimEnd();
            object Field5 = rd.GetDateTime(4);

            // The next statement should cause an exception
            Field1 = rd.GetString(0);
            Field2 = rd.GetString(1);
            Field3 = rd.GetString(2);
            Field4 = rd.GetString(3);
            Field5 = rd.GetString(4);

            Field1 = rd.GetInt32(0);
            Field2 = rd.GetInt32(1);
            Field3 = rd.GetInt32(2);
            Field4 = rd.GetInt32(3);
            Field5 = rd.GetInt32(4);

            Field1 = rd.GetDecimal(0);
            Field2 = rd.GetDecimal(1);
            Field3 = rd.GetDecimal(2);
            Field4 = rd.GetDecimal(3);
            Field5 = rd.GetDecimal(4);
          }
          else throw new ArgumentOutOfRangeException("No data in table");
        }
      }
    }

    internal void ParameterizedInsert(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(?,?,?,?,?)";
        DbParameter Field1 = cmd.CreateParameter();
        DbParameter Field2 = cmd.CreateParameter();
        DbParameter Field3 = cmd.CreateParameter();
        DbParameter Field4 = cmd.CreateParameter();
        DbParameter Field5 = cmd.CreateParameter();

        Field1.Value = 2;
        Field2.Value = 3.14159;
        Field3.Value = "Param Field3";
        Field4.Value = "Field4 Par";
        Field5.Value = DateTime.Now;

        cmd.Parameters.Add(Field1);
        cmd.Parameters.Add(Field2);
        cmd.Parameters.Add(Field3);
        cmd.Parameters.Add(Field4);
        cmd.Parameters.Add(Field5);

        cmd.ExecuteNonQuery();
      }
    }

    internal void BinaryInsert(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field6) VALUES(?)";
        DbParameter Field6 = cmd.CreateParameter();

        byte[] b = new byte[4000];
        b[0] = 1;
        b[100] = 2;
        b[1000] = 3;
        b[2000] = 4;
        b[3000] = 5;

        Field6.Value = b;

        cmd.Parameters.Add(Field6);

        cmd.ExecuteNonQuery();
      }
    }

    internal void VerifyBinaryData(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field6 FROM TestCase WHERE Field6 IS NOT NULL";
        byte[] b = new byte[4000];

        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read() == false) throw new ArgumentOutOfRangeException();

          rd.GetBytes(0, 0, b, 0, 4000);

          if (b[0] != 1) throw new ArgumentException();
          if (b[100] != 2) throw new ArgumentException();
          if (b[1000] != 3) throw new ArgumentException();
          if (b[2000] != 4) throw new ArgumentException();
          if (b[3000] != 5) throw new ArgumentException();
        }
      }
    }

    internal static void LockTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "SELECT Field6 FROM TestCase WHERE Field6 IS NOT NULL";
        byte[] b = new byte[4000];

        using (DbDataReader rd = cmd.ExecuteReader())
        {
          if (rd.Read() == false) throw new ArgumentOutOfRangeException();

          rd.GetBytes(0, 0, b, 0, 4000);

          if (b[0] != 1) throw new ArgumentException();
          if (b[100] != 2) throw new ArgumentException();
          if (b[1000] != 3) throw new ArgumentException();
          if (b[2000] != 4) throw new ArgumentException();
          if (b[3000] != 5) throw new ArgumentException();

          using (DbConnection clone = (DbConnection)((ICloneable)cnn).Clone())
          {
            using (DbCommand newcmd = clone.CreateCommand())
            {
              newcmd.CommandText = "DELETE FROM TestCase WHERE Field6 IS NULL";
              newcmd.CommandTimeout = 2;
              int cmdStart = Environment.TickCount;
              int cmdEnd;

              try
              {
                newcmd.ExecuteNonQuery(); // should fail because there's a reader on the database
                throw new ArgumentException(); // If we got here, the test failed
              }
              catch
              {
                cmdEnd = Environment.TickCount;
                if (cmdEnd - cmdStart < 2000 || cmdEnd - cmdStart > 3000)
                  throw new ArgumentException(); // Didn't wait the right amount of time
              }
            }
          }
        }
      }
    }

    internal void ParameterizedInsertMissingParams(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        cmd.CommandText = "INSERT INTO TestCase(Field1, Field2, Field3, Field4, Field5) VALUES(?,?,?,?,?)";
        DbParameter Field1 = cmd.CreateParameter();
        DbParameter Field2 = cmd.CreateParameter();
        DbParameter Field3 = cmd.CreateParameter();
        DbParameter Field4 = cmd.CreateParameter();
        DbParameter Field5 = cmd.CreateParameter();

        Field1.DbType = System.Data.DbType.Int32;

        Field1.Value = 2;
        Field2.Value = 3.14159;
        Field3.Value = "Field3 Param";
        Field4.Value = "Field4 Par";
        Field5.Value = DateTime.Now;

        cmd.Parameters.Add(Field1);
        cmd.Parameters.Add(Field2);
        cmd.Parameters.Add(Field3);
        cmd.Parameters.Add(Field4);

        // Assertion here, not enough parameters
        cmd.ExecuteNonQuery();
      }
    }

    // Utilizes the SQLiteCommandBuilder, which in turn utilizes SQLiteDataReader's GetSchemaTable() functionality
    internal void InsertMany(DbConnection cnn, bool bWithIdentity)
    {
      int nmax = 1000;

      using (DbTransaction dbTrans = cnn.BeginTransaction())
      {
        using (DbDataAdapter adp = new SQLiteDataAdapter())
        {
          using (DbCommand cmd = cnn.CreateCommand())
          {
            cmd.Transaction = dbTrans;
            cmd.CommandText = "SELECT * FROM TestCase WHERE 1=2";
            adp.SelectCommand = cmd;

            using (DbCommandBuilder bld = new SQLiteCommandBuilder())
            {
              bld.DataAdapter = adp;
              using (adp.InsertCommand = (SQLiteCommand)((ICloneable)bld.GetInsertCommand()).Clone())
              {
                bld.DataAdapter = null;
                if (bWithIdentity)
                {
                  adp.InsertCommand.CommandText += ";SELECT last_insert_rowid() AS [ID]";
                  adp.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
                }

                using (DataTable tbl = new DataTable())
                {
                  adp.Fill(tbl);
                  for (int n = 0; n < nmax; n++)
                  {
                    DataRow row = tbl.NewRow();
                    row[1] = n + nmax;
                    tbl.Rows.Add(row);
                  }

                  frm.Write(String.Format("          InsertMany{0} ({1} rows) Begins ... ", (bWithIdentity == true) ? "WithIdentityFetch" : "                 ", nmax));
                  int dtStart = Environment.TickCount;
                  adp.Update(tbl);
                  int dtEnd = Environment.TickCount;
                  dtEnd -= dtStart;
                  frm.Write(String.Format("Ends in {0} ms ... ", (dtEnd)));

                  dtStart = Environment.TickCount;
                  dbTrans.Commit();
                  dtEnd = Environment.TickCount;
                  dtEnd -= dtStart;
                  frm.WriteLine(String.Format("Commits in {0} ms", (dtEnd)));
                }
              }
            }
          }
        }
      }
    }

    internal void FastInsertMany(DbConnection cnn)
    {
      using (DbTransaction dbTrans = cnn.BeginTransaction())
      {
        int dtStart;
        int dtEnd;

        using (DbCommand cmd = cnn.CreateCommand())
        {
          cmd.CommandText = "INSERT INTO TestCase(Field1) VALUES(?)";
          DbParameter Field1 = cmd.CreateParameter();

          cmd.Parameters.Add(Field1);

          frm.WriteLine(String.Format("          Fast insert using parameters and prepared statement\r\n          -> (10,000 rows) Begins ... "));
          dtStart = Environment.TickCount;
          for (int n = 0; n < 10000; n++)
          {
            Field1.Value = n + 100000;
            cmd.ExecuteNonQuery();
          }

          dtEnd = Environment.TickCount;
          dtEnd -= dtStart;
          frm.Write(String.Format("          -> Ends in {0} ms ... ", (dtEnd)));
        }

        dtStart = Environment.TickCount;
        dbTrans.Rollback();
        dtEnd = Environment.TickCount;
        dtEnd -= dtStart;
        frm.WriteLine(String.Format("Rolled back in {0} ms", (dtEnd)));
      }
    }

    // Causes the user-defined function to be called
    internal void UserFunction(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        int nTimes;
        int dtStart;

        nTimes = 0;
        cmd.CommandText = "SELECT Foo('ee','foo')";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        frm.WriteLine(String.Format("          User (text)  command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT Foo(10,11)";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        frm.WriteLine(String.Format("          UserFunction command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT ABS(1)";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        frm.WriteLine(String.Format("          Intrinsic    command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT lower('FOO')";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        frm.WriteLine(String.Format("          Intrin (txt) command executed {0} times in 1 second.", nTimes));

        nTimes = 0;
        cmd.CommandText = "SELECT 1";
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          cmd.ExecuteNonQuery();
          nTimes++;
        }
        frm.WriteLine(String.Format("          Raw Value    command executed {0} times in 1 second.", nTimes));
      }
    }

    internal void IterationTest(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        int dtStart;
        int dtEnd;
        int nCount;
        long n;

        cmd.CommandText = "SELECT Foo(ID, ID) FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        frm.WriteLine(String.Format("          User Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart)));

        cmd.CommandText = "SELECT ID FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        frm.WriteLine(String.Format("          Raw iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart)));

        cmd.CommandText = "SELECT ABS(ID) FROM TestCase";
        cmd.Prepare();
        dtStart = Environment.TickCount;
        nCount = 0;
        using (DbDataReader rd = cmd.ExecuteReader())
        {
          while (rd.Read())
          {
            n = rd.GetInt64(0);
            nCount++;
          }
          dtEnd = Environment.TickCount;
        }
        frm.WriteLine(String.Format("          Intrinsic Function iteration of {0} records in {1} ms", nCount, (dtEnd - dtStart)));

      }
    }

    // Causes the user-defined aggregate to be iterated through
    internal void UserAggregate(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        int dtStart;
        int n = 0;
        int nCount;

        cmd.CommandText = "SELECT MyCount(*) FROM TestCase";

        nCount = 0;
        dtStart = Environment.TickCount;
        while (Environment.TickCount - dtStart < 1000)
        {
          n = Convert.ToInt32(cmd.ExecuteScalar());
          nCount++;
        }
        if (n != 2003) throw new ArgumentOutOfRangeException("Unexpected count");
        frm.WriteLine(String.Format("          UserAggregate executed {0} times in 1 second.", nCount));
      }
    }

    // Causes the user-defined collation sequence to be iterated through
    internal void UserCollation(DbConnection cnn)
    {
      using (DbCommand cmd = cnn.CreateCommand())
      {
        // Using a default collating sequence in descending order, "Param Field3" will appear at the top
        // and "Field3" will be next, followed by a NULL.  Our user-defined collating sequence will 
        // deliberately place them out of order so Field3 is first.
        cmd.CommandText = "SELECT Field3 FROM TestCase ORDER BY Field3 COLLATE MYSEQUENCE DESC";
        string s = (string)cmd.ExecuteScalar();
        if (s != "Field3") throw new ArgumentOutOfRangeException("MySequence didn't sort properly");
      }
    }
  }
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted testce/testce.csproj.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.50727</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{B86CE504-C4E4-496F-A0F0-E613BCFD3DF7}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>test</RootNamespace>
    <AssemblyName>testce</AssemblyName>
    <ProjectTypeGuids>{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <PlatformFamilyName>PocketPC</PlatformFamilyName>
    <PlatformID>3C41C503-53EF-4c2a-8DD4-A8217CAD115E</PlatformID>
    <OSVersion>4.20</OSVersion>
    <DeployDirSuffix>testce</DeployDirSuffix>
    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
    <FormFactorID>
    </FormFactorID>
    <StartupObject>
    </StartupObject>
    <DeployDirPrefix>%25CSIDL_PROGRAM_FILES%25</DeployDirPrefix>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>..\bin\CompactFramework\</OutputPath>
    <DefineConstants>TRACE;DEBUG;PocketPC</DefineConstants>
    <NoStdLib>true</NoStdLib>
    <NoConfig>true</NoConfig>
    <ErrorReport>prompt</ErrorReport>
    <FileAlignment>512</FileAlignment>
    <WarningLevel>4</WarningLevel>
    <GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>none</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>..\bin\CompactFramework\</OutputPath>
    <DefineConstants>PocketPC</DefineConstants>
    <NoStdLib>true</NoStdLib>
    <NoConfig>true</NoConfig>
    <ErrorReport>prompt</ErrorReport>
    <FileAlignment>512</FileAlignment>
    <WarningLevel>4</WarningLevel>
    <GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="mscorlib" />
    <Reference Include="System">
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Data">
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Drawing">
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Windows.Forms">
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Xml">
      <Private>False</Private>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="AssemblyInfo.cs" />
    <Compile Include="Form1.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="Form1.Designer.cs">
      <DependentUpon>Form1.cs</DependentUpon>
    </Compile>
    <Compile Include="Program.cs" />
    <Compile Include="TestCases.cs">
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Form1.resx">
      <DependentUpon>Form1.cs</DependentUpon>
      <SubType>Designer</SubType>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite - Compact.csproj">
      <Project>{AC139951-261A-4463-B6FA-AEBC25283A66}</Project>
      <Name>System.Data.SQLite - Compact</Name>
      <Private>False</Private>
    </ProjectReference>
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>
  <Import Condition="'$(TargetFrameworkVersion)' == 'v1.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.v1.targets" />
  <Import Condition="'$(TargetFrameworkVersion)' == 'v2.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
  <ProjectExtensions>
    <VisualStudio>
      <FlavorProperties GUID="{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}">
        <HostingProcess disable="1" />
      </FlavorProperties>
    </VisualStudio>
  </ProjectExtensions>
</Project>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































Deleted tools/mergebin/MetaData.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/********************************************************
 * mergebin
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

#include "StdAfx.h"
#include "MetaData.h"

CMetadata::CStream::operator LPBYTE() const
{
  return m_pbData;
}

CMetadata::CMetadata(CPEFile& peFile) : m_peFile(peFile)
{
  PIMAGE_COR20_HEADER pCor = m_peFile;
  if (!pCor) throw;

  LPBYTE pb = (LPBYTE)m_peFile.GetPtrFromRVA(pCor->MetaData.VirtualAddress);
  LPBYTE pbRoot = pb;
  size_t x;
  if (!pb) throw;

  m_pdwSignature     = (LPDWORD)pb;
  m_pwMajorVersion   = (LPWORD)(m_pdwSignature + 1);
  m_pwMinorVersion   = m_pwMajorVersion + 1;
  m_pdwVersionLength = (LPDWORD)(m_pwMinorVersion + 3);
  m_pszVersion       = (LPSTR)(m_pdwVersionLength + 1);

  pb = (LPBYTE)m_pszVersion;
  x = *m_pdwVersionLength;
  if (x % 4) x += 4 - (x % 4);
  pb += x;
  pb += 2;
  
  m_pwStreams        = (LPWORD)pb;
  m_pStreams = new CStream[*m_pwStreams];
  pb = (LPBYTE)(m_pwStreams + 1);

  for (WORD n = 0; n < *m_pwStreams; n++)
  {
    m_pStreams[n].m_pdwOffset  = (LPDWORD)pb;
    m_pStreams[n].m_pdwSize    = m_pStreams[n].m_pdwOffset + 1;
    m_pStreams[n].m_pszName    = (LPSTR)(m_pStreams[n].m_pdwSize + 1);
    m_pStreams[n].m_pbData     = pbRoot + (*m_pStreams[n].m_pdwOffset);

    x = strlen(m_pStreams[n].m_pszName) + 1;
    if (x % 4) x += 4 - (x % 4);

    pb = (LPBYTE)m_pStreams[n].m_pszName + x;
  }
}

CMetadata::~CMetadata(void)
{
  delete[] m_pStreams;
}

CMetadata::operator CPEFile&() const
{
  return m_peFile;
}

CMetadata::CStream * CMetadata::GetStream(UINT uiStream)
{
  if (uiStream >= *m_pwStreams) return NULL;
  return &m_pStreams[uiStream];
}

CMetadata::CStream * CMetadata::GetStream(LPCSTR pszStreamName)
{
  for (WORD n = 0; n < *m_pwStreams; n++)
  {
    if (_stricmp(pszStreamName, m_pStreams[n].m_pszName) == 0)
      return &m_pStreams[n];
  }
  return NULL;
}

WORD * CMetadata::StreamCount() const
{
  return m_pwStreams;
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































Deleted tools/mergebin/MetaData.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/********************************************************
 * mergebin
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

#pragma once

#include "pefile.h"

class CMetadata
{
public:
  class CStream
  {
    friend CMetadata;
  public:
    operator LPBYTE() const;

  protected:
    DWORD *m_pdwOffset;
    DWORD *m_pdwSize;
    LPSTR  m_pszName;
    LPBYTE m_pbData;
  };
public:
  CMetadata(CPEFile& peFile);
  virtual ~CMetadata(void);

protected:
  CPEFile& m_peFile;

  DWORD   *m_pdwSignature;
  WORD    *m_pwMajorVersion;
  WORD    *m_pwMinorVersion;
  DWORD   *m_pdwVersionLength;
  LPSTR    m_pszVersion;
  WORD    *m_pwStreams;
  CStream *m_pStreams;

public:
  operator CPEFile&() const;

  WORD *               StreamCount () const;
  CMetadata::CStream * GetStream   (UINT uiStream);
  CMetadata::CStream * GetStream   (LPCSTR pszStreamName);
};
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































Deleted tools/mergebin/MetaDataTables.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/********************************************************
 * mergebin
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

#include "StdAfx.h"
#include "MetaDataTables.h"
#include "TableData.h"

CMetadataTables::CMetadataTables(CMetadata& metaData) : m_meta(metaData)
{
  CMetadata::CStream *ps = m_meta.GetStream("#~");
  if (!ps) throw;

  *static_cast<CMetadata::CStream *>(this) = *ps;

  LPBYTE pb = m_pbData + sizeof(DWORD);
  m_pbMajorVersion = pb;
  m_pbMinorVersion = m_pbMajorVersion + 1;
  m_pbHeapOffsetSizes = m_pbMinorVersion + 1;
  // Skip a byte
  m_pullMaskValid = (UINT64 *)(m_pbHeapOffsetSizes + 2);
  m_pullMaskSorted = m_pullMaskValid + 1;

  m_pdwTableLengths = (LPDWORD)(m_pullMaskSorted + 1);

  m_dwTables = 0;
  for (int n = 0; n < 64; n++)
  {
    if ((((*m_pullMaskValid) >> n) & 1) == 1)
    {
      m_pdwTableLengthIndex[n] = &m_pdwTableLengths[m_dwTables ++];
    }
    else
    {
      m_pdwTableLengthIndex[n] = NULL;
    }
  }
  m_pbData = (LPBYTE)(m_pdwTableLengths + m_dwTables);

  for (int n = 0; n < 64; n++)
  {
    if (m_pdwTableLengthIndex[n] && g_arTableTypes[n])
    {
      m_pTables[n] = g_arTableTypes[n](this);
    }
    else
      m_pTables[n] = 0;
  }
}

CMetadataTables::~CMetadataTables(void)
{
  for (int n = 0; n < 64; n++)
  {
    if (m_pTables[n])
      delete m_pTables[n];
  }
}

UINT CMetadataTables::GetStringIndexSize(void)
{
  return ((*m_pbHeapOffsetSizes) & 0x01) == 0 ? sizeof(WORD) : sizeof(DWORD);
}

UINT CMetadataTables::GetGuidIndexSize(void)
{
  return ((*m_pbHeapOffsetSizes) & 0x02) == 0 ? sizeof(WORD) : sizeof(DWORD);
}

UINT CMetadataTables::GetBlobIndexSize(void)
{
  return ((*m_pbHeapOffsetSizes) & 0x04) == 0 ? sizeof(WORD) : sizeof(DWORD);
}

DWORD *CMetadataTables::TableRowCount(UINT uType)
{
  return m_pdwTableLengthIndex[uType];
}

DWORD CMetadataTables::GetMaxIndexSizeOf(UINT * puiTables)
{
  DWORD dwMaxRows = 0;
  DWORD *pdwLength;
  UINT uCount = 0;

  while (*puiTables)
  {
    uCount ++;
    pdwLength = m_pdwTableLengthIndex[*puiTables];
    if (pdwLength)
      dwMaxRows = max(dwMaxRows, pdwLength[0]);

    puiTables ++;
  }

  return (dwMaxRows > (ULONG)(2 << (16 - uCount))) ? 4 : 2;
}

CTableData *CMetadataTables::GetTable(UINT uId)
{
  return m_pTables[uId];
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































Deleted tools/mergebin/MetaDataTables.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/********************************************************
 * mergebin
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

#pragma once
#include "metadata.h"

class CTableData;

class CMetadataTables :
  public CMetadata::CStream
{
  friend CTableData;

public:
  CMetadataTables(CMetadata& metaData);
  virtual ~CMetadataTables(void);

protected:
  CMetadata&  m_meta;
  BYTE       *m_pbMajorVersion;
  BYTE       *m_pbMinorVersion;
  BYTE       *m_pbHeapOffsetSizes;
  UINT64     *m_pullMaskValid;
  UINT64     *m_pullMaskSorted;
  DWORD      *m_pdwTableLengths;

  DWORD      *m_pdwTableLengthIndex[64];
  DWORD       m_dwTables;

  CTableData *m_pTables[64];

public:
  UINT        GetStringIndexSize ();
  UINT        GetGuidIndexSize   ();
  UINT        GetBlobIndexSize   ();
  DWORD       GetMaxIndexSizeOf  (UINT *);

  DWORD *     TableRowCount      (UINT uType);

  CTableData *GetTable           (UINT uId);
};
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































Deleted tools/mergebin/PEFile.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/********************************************************
 * mergebin
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

#include "StdAfx.h"
#include "PEFile.h"

#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD_PTR)(ptr) + (DWORD_PTR)(addValue))

CPEFile::CPEFile(void)
{
  m_hMap = NULL;
  m_hFile = INVALID_HANDLE_VALUE;
  m_pBase = NULL;
}

CPEFile::~CPEFile(void)
{
  Close();
}

HRESULT CPEFile::Open(LPCTSTR pszFile, BOOL bReadOnly)
{
  HRESULT hr = S_OK;
  Close();

  m_hFile = CreateFile(pszFile, GENERIC_READ | ((bReadOnly == FALSE) ? GENERIC_WRITE: 0), FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (m_hFile == INVALID_HANDLE_VALUE)
  {
    hr = HRESULT_FROM_WIN32(GetLastError());
  }
  else
  {
    m_hMap = CreateFileMapping(m_hFile, NULL, (bReadOnly == TRUE) ? PAGE_READONLY:PAGE_READWRITE, 0, 0, NULL);
    if (!m_hMap)
    {
      hr = HRESULT_FROM_WIN32(GetLastError());
    }
    else
    {
      m_pBase = (PIMAGE_DOS_HEADER)MapViewOfFile(m_hMap, FILE_MAP_READ | ((bReadOnly == FALSE) ? FILE_MAP_WRITE:0), 0, 0, 0);
      if (!m_pBase)
      {
        hr = HRESULT_FROM_WIN32(GetLastError());
      }
    }
  }

  if (SUCCEEDED(hr))
  {
    PIMAGE_FILE_HEADER pImageHeader = (PIMAGE_FILE_HEADER)m_pBase;
    if (m_pBase->e_magic != IMAGE_DOS_SIGNATURE)
    {
      hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
    }

    m_pNTHeader = MakePtr(PIMAGE_NT_HEADERS, m_pBase, m_pBase->e_lfanew);
    if (IsBadReadPtr(m_pNTHeader, sizeof(m_pNTHeader->Signature)))
    {
      hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
    }
    else
    {
      if (m_pNTHeader->Signature != IMAGE_NT_SIGNATURE)
      {
        hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
      }
    }
  }

  if (FAILED(hr)) Close();

  return hr;
}

void CPEFile::Close(void)
{
  if (m_pBase)
  {
    UnmapViewOfFile(m_pBase);
  }

  if (m_hMap)
    CloseHandle(m_hMap);

  if (m_hFile != INVALID_HANDLE_VALUE)
    CloseHandle(m_hFile);

  m_hMap = NULL;
  m_hFile = INVALID_HANDLE_VALUE;
  m_pBase = NULL;
}

PIMAGE_SECTION_HEADER CPEFile::GetEnclosingSectionHeader(DWORD rva) const
{
  PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(m_pNTHeader);

  for (UINT i=0; i < m_pNTHeader->FileHeader.NumberOfSections; i++, section++ )
  {
    DWORD size = section->Misc.VirtualSize;
    if (!size)
      size = section->SizeOfRawData;

    if ( (rva >= section->VirtualAddress) && 
      (rva < (section->VirtualAddress + size)))
      return section;
  }
  return NULL;
}

LPVOID CPEFile::GetPtrFromRVA(DWORD rva) const
{
  PIMAGE_SECTION_HEADER pSectionHdr;
  INT delta;

  pSectionHdr = GetEnclosingSectionHeader(rva);
  if ( !pSectionHdr )
    return 0;

  delta = (INT)(pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData);
  return (PVOID) (((LPBYTE)m_pBase) + rva - delta);
}

PIMAGE_SECTION_HEADER CPEFile::GetSectionHeader(LPCSTR name) const
{
  PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(m_pNTHeader);

  for (UINT i=0; i < m_pNTHeader->FileHeader.NumberOfSections; i++, section++)
  {
    if (_strnicmp((char *)section->Name,name,IMAGE_SIZEOF_SHORT_NAME) == 0)
      return section;
  }

  return NULL;
}

CPEFile::operator PIMAGE_NT_HEADERS() const
{
  if (!m_pBase) return NULL;
  return m_pNTHeader;
}

CPEFile::operator PIMAGE_DOS_HEADER() const
{
  return m_pBase;
}

CPEFile::operator PIMAGE_COR20_HEADER() const
{
  if (!m_pBase) return NULL;

  DWORD dwRVA;
  dwRVA = m_pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress;
  if (!dwRVA)
  {
    return NULL;
  }

  return ((PIMAGE_COR20_HEADER)GetPtrFromRVA(dwRVA));
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































Deleted tools/mergebin/PEFile.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/********************************************************
 * mergebin
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

#pragma once

class CPEFile
{
public:
  CPEFile();
  virtual ~CPEFile(void);

protected:
  HANDLE            m_hMap;
  HANDLE            m_hFile;
  PIMAGE_DOS_HEADER m_pBase;
  PIMAGE_NT_HEADERS m_pNTHeader;

public:
  HRESULT Open  (LPCTSTR pszFile, BOOL bReadOnly = TRUE);
  void    Close (void);

  PIMAGE_SECTION_HEADER GetEnclosingSectionHeader (DWORD rva) const;
  LPVOID                GetPtrFromRVA             (DWORD rva) const;
  PIMAGE_SECTION_HEADER GetSectionHeader          (LPCSTR name) const;
  
  operator PIMAGE_DOS_HEADER   () const;
  operator PIMAGE_NT_HEADERS   () const;
  operator PIMAGE_COR20_HEADER () const;
};
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































Deleted tools/mergebin/ReadMe.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
========================================================================
    CONSOLE APPLICATION : mergebin Project Overview
========================================================================

AppWizard has created this mergebin application for you.  

This file contains a summary of what you will find in each of the files that
make up your mergebin application.


mergebin.vcproj
    This is the main project file for VC++ projects generated using an Application Wizard. 
    It contains information about the version of Visual C++ that generated the file, and 
    information about the platforms, configurations, and project features selected with the
    Application Wizard.

mergebin.cpp
    This is the main application source file.

/////////////////////////////////////////////////////////////////////////////
Other standard files:

StdAfx.h, StdAfx.cpp
    These files are used to build a precompiled header (PCH) file
    named mergebin.pch and a precompiled types file named StdAfx.obj.

/////////////////////////////////////////////////////////////////////////////
Other notes:

AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.

/////////////////////////////////////////////////////////////////////////////
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































Deleted tools/mergebin/StreamTable.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "StdAfx.h"
#include "StreamTable.h"

CREATEINSTANCE g_arTableTypes[64] = {
  CStreamTable::CreateInstance<CModuleTable>,
  CStreamTable::CreateInstance<CTypeRefTable>,
  CStreamTable::CreateInstance<CTypeDefTable>,
  NULL,
};

CStreamTable::CStreamTable(CMetadataTables& tables) : m_tables(tables)
{
}

CStreamTable::~CStreamTable(void)
{
}

template<class C>
static CStreamTable * CALLBACK CStreamTable::CreateInstance(CMetadataTables *ptables)
{
  CStreamTable *p = new C(*ptables);
  p->Init();

  return p;
}

void CStreamTable::Init()
{
  m_pbData = m_tables.m_pbData;
  CStreamTable *p;

  for (UINT n = 0; n < GetType(); n++)
  {
    p = m_tables.GetTable(n);
    if (p)
    {
      m_pbData += (p->GetRowSize() * p->GetRowCount());
    }
  }
}

DWORD CStreamTable::GetRowCount()
{
  return *m_tables.TableRowCount(GetType());
}

UINT CStreamTable::GetRowSize()
{
  TABLE_COLUMN *pc = GetColumns();
  UINT ulen = 0;

  while (pc->uSize)
  {
    ulen += pc->uSize;
    pc ++;
  }

  return ulen;
}

UINT CStreamTable::GetColumnCount()
{
  TABLE_COLUMN *pc = GetColumns();
  UINT ucount = 0;

  while (pc->uSize)
  {
    ucount ++;
    pc ++;
  }
  return ucount;
}

LPBYTE CStreamTable::operator[](UINT uRow)
{
  return m_pbData + (uRow * GetRowSize());
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































Deleted tools/mergebin/StreamTable.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#pragma once
#include "MetaDataTables.h"

typedef enum TableTypes
{
  ttModule = 0,
  ttTypeRef = 1,
  ttTypeDef = 2,
  ttFieldPtr = 3, 
  ttField = 4,
  ttMethodPtr = 5,
  ttMethodDef = 6,
  ttParamPtr = 7, 
  ttParam = 8,
  ttInterfaceImpl = 9,
  ttMemberRef = 10,
  ttConstant = 11, 
  ttCustomAttribute = 12,
  ttFieldMarshal = 13,
  ttPermission = 14,
  ttClassLayout = 15, 
  ttFieldLayout = 16,
  ttStandAloneSig = 17,
  ttEventMap = 18,
  ttEventPtr = 19, 
  ttEvent = 20,
  ttPropertyMap = 21,
  ttPropertyPtr = 22,
  ttProperty = 23, 
  ttMethodSemantics = 24,
  ttMethodImpl = 25,
  ttModuleRef = 26,
  ttTypeSpec = 27, 
  ttImplMap = 28, //lidin book is wrong again here?  It has enclog at 28
  ttFieldRVA = 29,
  ttENCLog = 30,
  ttENCMap = 31, 
  ttAssembly = 32,
  ttAssemblyProcessor= 33,
  ttAssemblyOS = 34,
  ttAssemblyRef = 35, 
  ttAssemblyRefProcessor = 36,
  ttAssemblyRefOS = 37,
  ttFile = 38,
  ttExportedType = 39, 
  ttManifestResource = 40,
  ttNestedClass = 41,
  ttTypeTyPar = 42,
  ttMethodTyPar = 43,
} TableTypes;

#define STRING_INDEXSIZE (m_tables.GetStringIndexSize())
#define GUID_INDEXSIZE (m_tables.GetGuidIndexSize())
#define BLOB_INDEXSIZE (m_tables.GetBlobIndexSize())
#define TABLE_ROWCOUNT(x) (m_tables.TableRowCount(x)[0])
#define TABLE_INDEXSIZE(x) (TABLE_ROWCOUNT(x) > 65535 ? 4 : 2)
#define MAX_INDEXSIZE(x) (m_tables.GetMaxIndexSizeOf(x))

class CStreamTable;

typedef CStreamTable* (CALLBACK* CREATEINSTANCE)(CMetadataTables *);

#define DECLARE_TABLE(classname, typ, nam) \
  public: \
  classname##(CMetadataTables& tables) : CStreamTable(tables) {} \
  UINT GetType() { return typ; } \
  LPCTSTR GetName() { return _T(nam); }

typedef struct TABLE_COLUMN
{
  UINT uSize;
  LPCTSTR pszName;
} TABLE_COLUMNS;

#define BEGIN_COLUMN_MAP() \
  protected: \
  TABLE_COLUMN *GetColumns() \
  { \
    static TABLE_COLUMN map[] = {

#define END_COLUMN_MAP() \
      { 0, NULL } \
    }; \
    return map; \
  }

#define COLUMN_ENTRY(name, size) { size, _T(name) },

class CStreamTable
{
public:
  CStreamTable(CMetadataTables& tables);
  virtual ~CStreamTable(void);

  DWORD GetRowCount();
  LPBYTE operator[](UINT uRow);

  virtual UINT GetType() = 0;
  virtual LPCTSTR GetName() = 0;

  template<class C> static CStreamTable * CALLBACK CreateInstance(CMetadataTables *ptables);

protected:
  CMetadataTables& m_tables;
  LPBYTE m_pbData;

  virtual UINT GetRowSize();
  virtual UINT GetColumnCount();

  virtual TABLE_COLUMN *GetColumns() = 0;

private:
  void Init();
};

class CModuleTable : public CStreamTable
{
  DECLARE_TABLE(CModuleTable, ttModule, "Module")
  
  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Generation", sizeof(WORD))
    COLUMN_ENTRY("Name",       STRING_INDEXSIZE)
    COLUMN_ENTRY("Mvid",       GUID_INDEXSIZE)
    COLUMN_ENTRY("EncId",      GUID_INDEXSIZE)
    COLUMN_ENTRY("EncBaseId",  GUID_INDEXSIZE)
  END_COLUMN_MAP()
};

static UINT ResolutionScopeIndex[] = {ttModule, ttModuleRef, ttAssemblyRef, ttTypeRef, 0};

class CTypeRefTable : public CStreamTable
{
  DECLARE_TABLE(CTypeRefTable, ttTypeRef, "TypeRef")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("ResolutionScope", MAX_INDEXSIZE(ResolutionScopeIndex))
    COLUMN_ENTRY("TypeName", STRING_INDEXSIZE)
    COLUMN_ENTRY("TypeNamespace", STRING_INDEXSIZE)
  END_COLUMN_MAP()
};

static UINT TypeDefOrRefIndex[] = {ttTypeDef, ttTypeRef, ttTypeSpec, 0};

class CTypeDefTable : public CStreamTable
{
  DECLARE_TABLE(CTypeDefTable, ttTypeDef, "TypeDef")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Flags", sizeof(DWORD))
    COLUMN_ENTRY("TypeName", STRING_INDEXSIZE)
    COLUMN_ENTRY("TypeNamespace", STRING_INDEXSIZE)
    COLUMN_ENTRY("Extends", MAX_INDEXSIZE(TypeDefOrRefIndex))
    COLUMN_ENTRY("FieldList", TABLE_INDEXSIZE(ttField))
    COLUMN_ENTRY("MethodList", TABLE_INDEXSIZE(ttMethodDef))
  END_COLUMN_MAP()
};

extern CREATEINSTANCE g_arTableTypes[64];
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































Deleted tools/mergebin/TableData.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/********************************************************
 * mergebin
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

#include "StdAfx.h"
#include "TableData.h"

CREATEINSTANCE g_arTableTypes[64] = {
  CTableData::CreateInstance<CModuleTable>,
  CTableData::CreateInstance<CTypeRefTable>,
  CTableData::CreateInstance<CTypeDefTable>,
  CTableData::CreateInstance<CFieldPtrTable>,
  CTableData::CreateInstance<CFieldTable>,
  CTableData::CreateInstance<CMethodPtrTable>,
  CTableData::CreateInstance<CMethodTable>,
  CTableData::CreateInstance<CParamPtrTable>,
  CTableData::CreateInstance<CParamTable>,
  CTableData::CreateInstance<CInterfaceImplTable>,
  CTableData::CreateInstance<CMemberRefTable>,
  CTableData::CreateInstance<CConstantTable>,
  CTableData::CreateInstance<CCustomAttributeTable>,
  CTableData::CreateInstance<CFieldMarshalTable>,
  CTableData::CreateInstance<CDeclSecurityTable>,
  CTableData::CreateInstance<CClassLayoutTable>,
  CTableData::CreateInstance<CFieldLayoutTable>,
  CTableData::CreateInstance<CStandAloneSigTable>,
  CTableData::CreateInstance<CEventMapTable>,
  CTableData::CreateInstance<CEventPtrTable>,
  CTableData::CreateInstance<CEventTable>,
  CTableData::CreateInstance<CPropertyMapTable>,
  CTableData::CreateInstance<CPropertyPtrTable>,
  CTableData::CreateInstance<CPropertyTable>,
  CTableData::CreateInstance<CMethodSemanticsTable>,
  CTableData::CreateInstance<CMethodImplTable>,
  CTableData::CreateInstance<CModuleRefTable>,
  CTableData::CreateInstance<CTypeSpecTable>,
  CTableData::CreateInstance<CImplMapTable>,
  CTableData::CreateInstance<CFieldRVATable>,
  NULL,
};

CTableData::CTableData(CMetadataTables& tables) : m_tables(tables)
{
  m_uiRowSize = 0;
}

CTableData::~CTableData(void)
{
  if (m_pColumns) 
    delete[] m_pColumns;
}

template<class C>
static CTableData * CALLBACK CTableData::CreateInstance(CMetadataTables *ptables)
{
  CTableData *p = new C(*ptables);
  p->Init();

  return p;
}

void CTableData::Init()
{
  m_pbData = m_tables.m_pbData;
  CTableData *p;
  UINT n = GetType();
  
  while(n--)
  {
    p = m_tables.GetTable(n);
    if (p)
    {
      m_pbData = p->m_pbData + (p->GetRowSize() * p->GetRowCount());
      break;
    }
  }

  m_pColumns = _CreateColumns();
  TABLE_COLUMNS *tc = m_pColumns + 1;

  while (tc->pszName && !tc->dwOffset)
  {
    tc->dwOffset = tc[-1].dwOffset + tc[-1].uSize;
    tc ++;
  }
}

TABLE_COLUMN * CTableData::GetColumns()
{
  return m_pColumns;
}

DWORD CTableData::GetRowCount()
{
  return *m_tables.TableRowCount(GetType());
}

UINT CTableData::GetRowSize()
{
  if (m_uiRowSize == 0)
  {
    TABLE_COLUMN *pc = m_pColumns;

    while (pc->uSize)
    {
      m_uiRowSize += pc->uSize;
      pc ++;
    }
  }

  return m_uiRowSize;
}

UINT CTableData::GetColumnCount()
{
  TABLE_COLUMN *pc = m_pColumns;
  UINT ucount = 0;

  while (pc->uSize)
  {
    ucount ++;
    pc ++;
  }
  return ucount;
}

int CTableData::GetColumnIndex(LPCTSTR pszName)
{
  TABLE_COLUMN *pc = m_pColumns;
  for (int n = 0; pc[n].pszName; n++)
  {
    if (lstrcmpi(pszName, pc[n].pszName) == 0) return n;
  }
  return -1;
}

UINT CTableData::GetColumnSize(UINT uIndex)
{
  return m_pColumns[uIndex].uSize;
}

UINT CTableData::GetColumnSize(LPCTSTR pszName)
{
  int n = GetColumnIndex(pszName);
  if (n < 0) return 0;

  return GetColumnSize(n);
}

LPBYTE CTableData::Column(UINT uRow, UINT uIndex)
{
  TABLE_COLUMN *pc = m_pColumns;
  LPBYTE pb = m_pbData + (uRow * GetRowSize()) + pc[uIndex].dwOffset;

  return pb;
}

LPBYTE CTableData::Column(UINT uRow, LPCTSTR pszName)
{
  int n = GetColumnIndex(pszName);
  if (n < 0) return NULL;
  return Column(uRow, n);
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































Deleted tools/mergebin/TableData.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
/********************************************************
 * mergebin
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

#pragma once
#include "MetaDataTables.h"

typedef enum TableTypes
{
  ttModule = 0,
  ttTypeRef = 1,
  ttTypeDef = 2,
  ttFieldPtr = 3, 
  ttField = 4,
  ttMethodPtr = 5,
  ttMethodDef = 6,
  ttParamPtr = 7, 
  ttParam = 8,
  ttInterfaceImpl = 9,
  ttMemberRef = 10,
  ttConstant = 11, 
  ttCustomAttribute = 12,
  ttFieldMarshal = 13,
  ttDeclSecurity = 14,
  ttClassLayout = 15, 
  ttFieldLayout = 16,
  ttStandAloneSig = 17,
  ttEventMap = 18,
  ttEventPtr = 19, 
  ttEvent = 20,
  ttPropertyMap = 21,
  ttPropertyPtr = 22,
  ttProperty = 23, 
  ttMethodSemantics = 24,
  ttMethodImpl = 25,
  ttModuleRef = 26,
  ttTypeSpec = 27, 
  ttImplMap = 28,
  ttFieldRVA = 29,
  ttENCLog = 30,
  ttENCMap = 31, 
  ttAssembly = 32,
  ttAssemblyProcessor= 33,
  ttAssemblyOS = 34,
  ttAssemblyRef = 35, 
  ttAssemblyRefProcessor = 36,
  ttAssemblyRefOS = 37,
  ttFile = 38,
  ttExportedType = 39, 
  ttManifestResource = 40,
  ttNestedClass = 41,
  ttGenericParam = 42,
  ttMethodSpec = 43,
  ttGenericParamConstraint = 44,
} TableTypes;

typedef struct TABLE_COLUMN
{
  UINT uSize;
  LPCTSTR pszName;
  DWORD dwOffset;
} TABLE_COLUMNS;

class CTableData;

/*
** Helpers
*/
#define STRING_INDEXSIZE (m_tables.GetStringIndexSize())
#define GUID_INDEXSIZE (m_tables.GetGuidIndexSize())
#define BLOB_INDEXSIZE (m_tables.GetBlobIndexSize())
#define TABLE_ROWCOUNT(x) (m_tables.TableRowCount(x)[0])
#define TABLE_INDEXSIZE(x) (TABLE_ROWCOUNT(x) > 65535 ? 4 : 2)
#define MAX_INDEXSIZE(x) (m_tables.GetMaxIndexSizeOf(x))

#define DECLARE_TABLE(classname, typ, nam) \
  public: \
  classname##(CMetadataTables& tables) : CTableData(tables) {} \
  UINT GetType() { return typ; } \
  LPCTSTR GetName() { return _T(nam); }

#define BEGIN_COLUMN_MAP() \
  protected: \
  TABLE_COLUMN *_CreateColumns() \
  { \
    TABLE_COLUMN map[] = {

#define END_COLUMN_MAP() \
      { 0, NULL } \
    }; \
    TABLE_COLUMN *p = new TABLE_COLUMN[sizeof(map) / sizeof(TABLE_COLUMN)]; \
    CopyMemory(p, map, sizeof(map)); \
    return p; \
  }

#define COLUMN_ENTRY(name, size) { size, _T(name), 0 },
/*
** End Of Helpers
*/

class CTableData
{
public:
  CTableData(CMetadataTables& tables);
  virtual ~CTableData(void);

  virtual UINT          GetType        () = 0;
  virtual LPCTSTR       GetName        () = 0;
  virtual TABLE_COLUMN *_CreateColumns () = 0;

  template<class C> static CTableData * CALLBACK CreateInstance(CMetadataTables *ptables);

  virtual DWORD         GetRowCount ();
  virtual UINT          GetRowSize  ();

  int           GetColumnIndex (LPCTSTR pszName);
  UINT          GetColumnSize  (UINT uIndex);
  UINT          GetColumnSize  (LPCTSTR pszName);
  UINT          GetColumnCount ();
  LPBYTE        Column         (UINT uRow, UINT uIndex);
  LPBYTE        Column         (UINT uRow, LPCTSTR pszName);
  TABLE_COLUMN *GetColumns     ();

protected:
  CMetadataTables& m_tables;
  LPBYTE           m_pbData;
  UINT             m_uiRowSize;
  TABLE_COLUMN    *m_pColumns;

private:
  void Init ();
};

class CModuleTable : public CTableData
{
  DECLARE_TABLE(CModuleTable, ttModule, "Module")
  
  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Generation", sizeof(WORD))
    COLUMN_ENTRY("Name",       STRING_INDEXSIZE)
    COLUMN_ENTRY("Mvid",       GUID_INDEXSIZE)
    COLUMN_ENTRY("EncId",      GUID_INDEXSIZE)
    COLUMN_ENTRY("EncBaseId",  GUID_INDEXSIZE)
  END_COLUMN_MAP()
};

static UINT TypeDefOrRefIndex[]        = { ttTypeDef,   ttTypeRef,     ttTypeSpec,     0 };
static UINT HasConstantIndex[]         = { ttField,     ttParam,       ttProperty,     0 };
static UINT HasCustomAttributeIndex[]  = { ttMethodDef, ttField,       ttTypeRef,      ttTypeDef,   ttParam,    ttInterfaceImpl, ttMemberRef, ttModule, ttDeclSecurity, ttProperty, ttEvent, ttStandAloneSig, ttModuleRef, ttTypeSpec, ttAssembly, ttAssemblyRef, ttFile, ttExportedType, ttManifestResource, 0 };
static UINT HasFieldMarshalIndex[]     = { ttField,     ttParam,       0 };
static UINT HasDeclSecurityIndex[]     = { ttTypeDef,   ttMethodDef,   ttAssembly,     0 };
static UINT MemberRefParentIndex[]     = { ttTypeDef,   ttTypeRef,     ttModuleRef,    ttMethodDef, ttTypeSpec, 0 };
static UINT HasSemanticsIndex[]        = { ttEvent,     ttProperty,    0 };
static UINT MethodDefOrRefIndex[]      = { ttMethodDef, ttMemberRef,   0 };
static UINT MemberForwardedIndex[]     = { ttField,     ttMethodDef,   0 };
static UINT ImplementationIndex[]      = { ttFile,      ttAssemblyRef, ttExportedType, 0 };
static UINT CustomAttributeTypeIndex[] = { 63,          63,            ttMethodDef,    ttMemberRef, 63,         0 };
static UINT ResolutionScopeIndex[]     = { ttModule,    ttModuleRef,   ttAssemblyRef,  ttTypeRef,   0 };
static UINT TypeOrMethodDefIndex[]     = { ttTypeDef,   ttMethodDef,   0 };

class CTypeRefTable : public CTableData
{
  DECLARE_TABLE(CTypeRefTable, ttTypeRef, "TypeRef")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("ResolutionScope", MAX_INDEXSIZE(ResolutionScopeIndex))
    COLUMN_ENTRY("TypeName",        STRING_INDEXSIZE)
    COLUMN_ENTRY("TypeNamespace",   STRING_INDEXSIZE)
  END_COLUMN_MAP()
};

class CTypeDefTable : public CTableData
{
  DECLARE_TABLE(CTypeDefTable, ttTypeDef, "TypeDef")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Flags",         sizeof(DWORD))
    COLUMN_ENTRY("TypeName",      STRING_INDEXSIZE)
    COLUMN_ENTRY("TypeNamespace", STRING_INDEXSIZE)
    COLUMN_ENTRY("Extends",       MAX_INDEXSIZE(TypeDefOrRefIndex))
    COLUMN_ENTRY("FieldList",     TABLE_INDEXSIZE(ttField))
    COLUMN_ENTRY("MethodList",    TABLE_INDEXSIZE(ttMethodDef))
  END_COLUMN_MAP()
};

class CFieldPtrTable : public CTableData
{
  DECLARE_TABLE(CFieldPtrTable, ttFieldPtr, "FieldPtr")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Field", TABLE_INDEXSIZE(ttField))
  END_COLUMN_MAP()
};

class CFieldTable : public CTableData
{
  DECLARE_TABLE(CFieldTable, ttField, "Field")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Flags",     sizeof(WORD))
    COLUMN_ENTRY("Name",      STRING_INDEXSIZE)
    COLUMN_ENTRY("Signature", BLOB_INDEXSIZE)
  END_COLUMN_MAP()
};

class CMethodPtrTable : public CTableData
{
  DECLARE_TABLE(CMethodPtrTable, ttMethodPtr, "MethodPtr")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Method", TABLE_INDEXSIZE(ttMethodDef))
  END_COLUMN_MAP()
};

class CMethodTable : public CTableData
{
  DECLARE_TABLE(CMethodTable, ttMethodDef, "Method")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("RVA",        sizeof(DWORD))
    COLUMN_ENTRY("ImplFlags",  sizeof(WORD))
    COLUMN_ENTRY("Flags",      sizeof(WORD))
    COLUMN_ENTRY("Name",       STRING_INDEXSIZE)
    COLUMN_ENTRY("Signature",  BLOB_INDEXSIZE)
    COLUMN_ENTRY("Parameters", TABLE_INDEXSIZE(ttParam))
  END_COLUMN_MAP()
};

class CParamPtrTable : public CTableData
{
  DECLARE_TABLE(CParamPtrTable, ttParamPtr, "ParamPtr")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Param", TABLE_INDEXSIZE(ttParam))
  END_COLUMN_MAP()
};

class CParamTable : public CTableData
{
  DECLARE_TABLE(CParamTable, ttParam, "Param")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Flags",    sizeof(WORD))
    COLUMN_ENTRY("Sequence", sizeof(WORD))
    COLUMN_ENTRY("Name",     STRING_INDEXSIZE)
  END_COLUMN_MAP()
};

class CInterfaceImplTable : public CTableData
{
  DECLARE_TABLE(CInterfaceImplTable, ttInterfaceImpl, "Interface")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Class",     TABLE_INDEXSIZE(ttTypeDef))
    COLUMN_ENTRY("Interface", MAX_INDEXSIZE(TypeDefOrRefIndex))
  END_COLUMN_MAP()
};

class CMemberRefTable : public CTableData
{
  DECLARE_TABLE(CMemberRefTable, ttMemberRef, "Member")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Class",     MAX_INDEXSIZE(MemberRefParentIndex))
    COLUMN_ENTRY("Name",      STRING_INDEXSIZE)
    COLUMN_ENTRY("Signature", BLOB_INDEXSIZE)
  END_COLUMN_MAP()
};

class CConstantTable : public CTableData
{
  DECLARE_TABLE(CConstantTable, ttConstant, "Constant")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Type",   sizeof(WORD))
    COLUMN_ENTRY("Parent", MAX_INDEXSIZE(HasConstantIndex))
    COLUMN_ENTRY("Value",  BLOB_INDEXSIZE)
  END_COLUMN_MAP()
};

class CCustomAttributeTable : public CTableData
{
  DECLARE_TABLE(CCustomAttributeTable, ttCustomAttribute, "CustomAttribute")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Parent", MAX_INDEXSIZE(HasCustomAttributeIndex))
    COLUMN_ENTRY("Type",   MAX_INDEXSIZE(CustomAttributeTypeIndex))
    COLUMN_ENTRY("Value",  BLOB_INDEXSIZE)
  END_COLUMN_MAP()
};

class CFieldMarshalTable : public CTableData
{
  DECLARE_TABLE(CFieldMarshalTable, ttFieldMarshal, "FieldMarshal")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Parent",     MAX_INDEXSIZE(HasFieldMarshalIndex))
    COLUMN_ENTRY("NativeType", BLOB_INDEXSIZE)
  END_COLUMN_MAP()
};

class CDeclSecurityTable : public CTableData
{
  DECLARE_TABLE(CDeclSecurityTable, ttDeclSecurity, "DeclSecurity")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Action",        sizeof(WORD))
    COLUMN_ENTRY("Parent",        MAX_INDEXSIZE(HasDeclSecurityIndex))
    COLUMN_ENTRY("PermissionSet", BLOB_INDEXSIZE)
  END_COLUMN_MAP()
};

class CClassLayoutTable : public CTableData
{
  DECLARE_TABLE(CClassLayoutTable, ttClassLayout, "ClassLayout")
  
  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("PackingSize", sizeof(WORD))
    COLUMN_ENTRY("ClassSize",   sizeof(DWORD))
    COLUMN_ENTRY("Parent",      TABLE_INDEXSIZE(ttTypeDef))
  END_COLUMN_MAP()
};

class CFieldLayoutTable : public CTableData
{
  DECLARE_TABLE(CFieldLayoutTable, ttFieldLayout, "FieldLayout")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Offset", sizeof(DWORD))
    COLUMN_ENTRY("Field",  TABLE_INDEXSIZE(ttField))
  END_COLUMN_MAP()
};

class CStandAloneSigTable : public CTableData
{
  DECLARE_TABLE(CStandAloneSigTable, ttStandAloneSig, "StandAloneSig")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Signature", BLOB_INDEXSIZE)
  END_COLUMN_MAP()
};

class CEventMapTable : public CTableData
{
  DECLARE_TABLE(CEventMapTable, ttEventMap, "EventMap")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Parent",    TABLE_INDEXSIZE(ttTypeDef))
    COLUMN_ENTRY("EventList", TABLE_INDEXSIZE(ttEvent))
  END_COLUMN_MAP()
};

class CEventTable : public CTableData
{
  DECLARE_TABLE(CEventTable, ttEvent, "Event")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("EventFlags", sizeof(WORD))
    COLUMN_ENTRY("Name",       STRING_INDEXSIZE)
    COLUMN_ENTRY("EventType",  MAX_INDEXSIZE(TypeDefOrRefIndex))
  END_COLUMN_MAP()
};

class CEventPtrTable : public CTableData
{
  DECLARE_TABLE(CEventPtrTable, ttEventPtr, "EventPtr")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Event", TABLE_INDEXSIZE(ttEvent))
  END_COLUMN_MAP()
};

class CPropertyMapTable : public CTableData
{
  DECLARE_TABLE(CPropertyMapTable, ttPropertyMap, "PropertyMap")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Parent",       TABLE_INDEXSIZE(ttTypeDef))
    COLUMN_ENTRY("PropertyList", TABLE_INDEXSIZE(ttProperty))
  END_COLUMN_MAP()
};

class CPropertyPtrTable : public CTableData
{
  DECLARE_TABLE(CPropertyPtrTable, ttEventPtr, "PropertyPtr")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Property", TABLE_INDEXSIZE(ttProperty))
  END_COLUMN_MAP()
};

class CPropertyTable : public CTableData
{
  DECLARE_TABLE(CPropertyTable, ttProperty, "Property")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Flags", sizeof(WORD))
    COLUMN_ENTRY("Name",  STRING_INDEXSIZE)
    COLUMN_ENTRY("Type",  BLOB_INDEXSIZE)
  END_COLUMN_MAP()
};

class CMethodSemanticsTable : public CTableData
{
  DECLARE_TABLE(CMethodSemanticsTable, ttMethodSemantics, "MethodSemantics")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Semantics",   sizeof(WORD))
    COLUMN_ENTRY("Method",      TABLE_INDEXSIZE(ttMethodDef))
    COLUMN_ENTRY("Association", MAX_INDEXSIZE(HasSemanticsIndex))
  END_COLUMN_MAP()
};

class CMethodImplTable : public CTableData
{
  DECLARE_TABLE(CMethodImplTable, ttMethodImpl, "MethodImpl")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Class",             TABLE_INDEXSIZE(ttTypeDef))
    COLUMN_ENTRY("MethodBody",        MAX_INDEXSIZE(MethodDefOrRefIndex))
    COLUMN_ENTRY("MethodDeclaration", MAX_INDEXSIZE(MethodDefOrRefIndex))
  END_COLUMN_MAP()
};

class CModuleRefTable : public CTableData
{
  DECLARE_TABLE(CModuleRefTable, ttModuleRef, "ModuleRef")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Name", STRING_INDEXSIZE)
  END_COLUMN_MAP()
};

class CTypeSpecTable : public CTableData
{
  DECLARE_TABLE(CTypeSpecTable, ttTypeSpec, "TypeSpec")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("Signature", BLOB_INDEXSIZE)
  END_COLUMN_MAP()
};

class CImplMapTable : public CTableData
{
  DECLARE_TABLE(CImplMapTable, ttImplMap, "ImplMap")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("MappingFlags",    sizeof(WORD))
    COLUMN_ENTRY("MemberForwarded", MAX_INDEXSIZE(MemberForwardedIndex))
    COLUMN_ENTRY("ImportName",      STRING_INDEXSIZE)
    COLUMN_ENTRY("ImportScope",     TABLE_INDEXSIZE(ttModuleRef))
  END_COLUMN_MAP()
};

class CFieldRVATable : public CTableData
{
  DECLARE_TABLE(CFieldRVATable, ttFieldRVA, "FieldRVA")

  BEGIN_COLUMN_MAP()
    COLUMN_ENTRY("RVA",   sizeof(DWORD))
    COLUMN_ENTRY("Field", TABLE_INDEXSIZE(ttField))
  END_COLUMN_MAP()
};

// Only tables up to ttFieldRVA are mapped, because they're all I needed.  If you need the tables beyond that, map them yourself!

typedef CTableData* (CALLBACK* CREATEINSTANCE)(CMetadataTables *);
extern CREATEINSTANCE g_arTableTypes[64];
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted tools/mergebin/mergebin.cpp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
/********************************************************
 * mergebin
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

#include "stdafx.h"
#include "MetaData.h"
#include "MetaDataTables.h"
#include "TableData.h"

void DumpCLRInfo(LPCTSTR pszFile);
void MergeModules(LPCTSTR pszAssembly, LPCTSTR pszNative, LPCTSTR pszSection);
void DumpCLRPragma(LPCTSTR pszAssembly, LPCTSTR pszSection);

int _tmain(int argc, _TCHAR* argv[])
{
  if (argc == 1)
  {
    _tprintf(_T(
"MERGEBIN - Merges a pure .NET assembly with a native DLL\n \
Syntax: MERGEBIN [/I:assembly] [/S:sectionname assembly nativedll]\n \
/I:assembly            Returns the number of bytes required\n \
                       to consume the assembly\n \
/S:sectionname         The name of the section in the nativedll\n \
                       to insert the CLR data\n \
/P:assembly            Outputs the C++ pragma code that can be used\n \
                       as additional input to a C++ app to reserve\n \
                       a section block large enough for the managed code.\n \
\n \
The native DLL must have an unused section in it, into which the\n \
.NET assembly will be inserted.  You can do this with the following code:\n \
  #pragma data_seg(\".clr\")\n \
  #pragma comment(linker, \"/SECTION:.clr,ER\")\n \
   char __ph[92316] = {0}; // 92316 is the number of bytes to reserve\n \
  #pragma data_seg()\n \
You would then specify /SECTION:.CLR in the command-line for the location to\n \
insert the .NET assembly.  The number of bytes reserved in the section needs\n \
to be equal to or more than the number of bytes returned by the /I parameter.\n \
\n \
The native DLL must also export a function that calls _CorDllMain in \n \
MSCOREE.DLL.  This function must have the same parameters and calling\n \
conventions as DllMain, and its name must have the word \"CORDLLMAIN\"\n \
in it.\n \
"));
    return 0;
  }

  LPTSTR pszAssembly = NULL;
  LPTSTR pszNative = NULL;
  LPTSTR pszSection = NULL;
  BOOL bDoPragma = FALSE;

  for (int n = 1; n < argc; n++)
  {
    if (argv[n][0] != '-' && argv[n][0] != '/')
    {
      if (pszAssembly == NULL)
        pszAssembly = argv[n];
      else if (pszNative == NULL)
        pszNative = argv[n];
      else
      {
        _tprintf(_T("Too many files specified\n"));
        return 0;
      }
      continue;
    }

    switch(argv[n][1])
    {
    case 'I':
    case 'i':
      pszAssembly = &argv[n][3];
      if (argv[n][2] != ':' || lstrlen(pszAssembly) == 0)
      {
        _tprintf(_T("/I requires an assembly name\n"));
        return 0;
      }
      DumpCLRInfo(pszAssembly);
      return 0;
      break;
    case 'P':
    case 'p':
      pszAssembly = &argv[n][3];
      if (argv[n][2] != ':' || lstrlen(pszAssembly) == 0)
      {
        _tprintf(_T("/P requires an assembly name\n"));
        return 0;
      }
      bDoPragma = TRUE;
      break;
    case 'S':
    case 's':
      pszSection = &argv[n][3];
      if (argv[n][2] != ':' || lstrlen(pszSection) == 0)
      {
        _tprintf(_T("/S requires a section name\n"));
        return 0;
      }
      break;
    }
  }

  if (pszAssembly && pszNative && pszSection && !bDoPragma)
    MergeModules(pszAssembly, pszNative, pszSection);

  if (pszAssembly && bDoPragma)
    DumpCLRPragma(pszAssembly, pszSection);

  return 0;
}

BOOL GetMinMaxCOR20RVA(CPEFile& file, DWORD& dwMin, DWORD& dwMax)
{
  PIMAGE_COR20_HEADER pCor = file;
  dwMin = MAXDWORD;
  dwMax = 0;

  if (!pCor) return FALSE;

  if (pCor->MetaData.Size) dwMin = min(dwMin, pCor->MetaData.VirtualAddress);
  if (pCor->Resources.Size) dwMin = min(dwMin, pCor->Resources.VirtualAddress);
  if (pCor->StrongNameSignature.Size) dwMin = min(dwMin, pCor->StrongNameSignature.VirtualAddress);
  if (pCor->CodeManagerTable.Size) dwMin = min(dwMin, pCor->CodeManagerTable.VirtualAddress);
  if (pCor->VTableFixups.Size) dwMin = min(dwMin, pCor->VTableFixups.VirtualAddress);
  if (pCor->ExportAddressTableJumps.Size) dwMin = min(dwMin, pCor->ExportAddressTableJumps.VirtualAddress);
  if (pCor->ManagedNativeHeader.Size) dwMin = min(dwMin, pCor->ManagedNativeHeader.VirtualAddress);

  dwMax = max(dwMax, (pCor->MetaData.VirtualAddress + pCor->MetaData.Size));
  dwMax = max(dwMax, (pCor->Resources.VirtualAddress + pCor->Resources.Size));
  dwMax = max(dwMax, (pCor->StrongNameSignature.VirtualAddress + pCor->StrongNameSignature.Size));
  dwMax = max(dwMax, (pCor->CodeManagerTable.VirtualAddress + pCor->CodeManagerTable.Size));
  dwMax = max(dwMax, (pCor->VTableFixups.VirtualAddress + pCor->VTableFixups.Size));
  dwMax = max(dwMax, (pCor->ExportAddressTableJumps.VirtualAddress + pCor->ExportAddressTableJumps.Size));
  dwMax = max(dwMax, (pCor->ManagedNativeHeader.VirtualAddress + pCor->ManagedNativeHeader.Size));

  CMetadata meta(file);
  CMetadataTables tables(meta);
  CTableData *p;
  DWORD *pdwRVA;
  DWORD dwRows;

  for (int n = 0; n < 2; n++)
  {
    p = tables.GetTable((n == 0) ? ttMethodDef : ttFieldRVA);
    if (p)
    {
      dwRows = p->GetRowCount();
      for (UINT uRow = 0; uRow < dwRows; uRow ++)
      {
        pdwRVA = (DWORD *)p->Column(uRow, (UINT)0);
        if (*pdwRVA)
          dwMin = min(dwMin, (*pdwRVA));
      }
    }
  }
  return TRUE;
}

void DumpCLRInfo(LPCTSTR pszFile)
{
  CPEFile peFile;
  HRESULT hr;
  hr = peFile.Open(pszFile);
  if (FAILED(hr)) return;

  DWORD dwMinRVA;
  DWORD dwMaxRVA;

  if (!GetMinMaxCOR20RVA(peFile, dwMinRVA, dwMaxRVA))
  {
    _tprintf(_T("Unable to retrieve .NET assembly information for file %s\n"), pszFile);
    return;
  }

  _tprintf(_T("%d Bytes required to merge %s\n"), (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb, pszFile);
}

void DumpCLRPragma(LPCTSTR pszAssembly, LPCTSTR pszSection)
{
  CPEFile peFile;
  HRESULT hr;
  DWORD dwMinRVA;
  DWORD dwMaxRVA;

  hr = peFile.Open(pszAssembly);
  if (FAILED(hr)) return;
  
  if (pszSection == NULL) pszSection = _T(".clr");

  if (!GetMinMaxCOR20RVA(peFile, dwMinRVA, dwMaxRVA))
  {
    _tprintf(_T("// Unable to retrieve .NET assembly information for file %s\n"), pszAssembly);
    return;
  }

  _tprintf(_T("// This code was automatically generated from assembly\n\
// %s\n\n\
#include <windef.h>\n\n\
#pragma data_seg(\"%s\")\n\
#pragma comment(linker, \"/SECTION:%s,ER\")\n\
  char __ph[%d] = {0}; // The number of bytes to reserve\n\
#pragma data_seg()\n\n\
#pragma comment(lib, \"mscoree\")\n\n\
extern BOOL WINAPI _CorDllMain(HANDLE, DWORD, LPVOID);\n\
__declspec(dllexport) BOOL WINAPI _CorDllMainStub(HANDLE hModule, DWORD dwReason, LPVOID pvReserved)\n\
{\n\
  return _CorDllMain(hModule, dwReason, pvReserved);\n\
}\n\
"), pszAssembly, pszSection, pszSection, (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb);
}

/*   When merged, the native DLL's entrypoint must go to _CorDllMain in MSCOREE.DLL.
  ** In order to do this, we need to change the DLL's entrypoint to "something" that will
  ** call CorDllMain.  Since its too much hassle to add imports to the DLL and make drastic
  ** changes to it, we rely on the native DLL to export a function that we can call which will
  ** forward to CorDllMain.  Exported functions are easy to identify and get an RVA for.
  ** The exported function must have the same calling conventions and parameters as DllMain,
  ** and must contain the letters "CORDLLMAIN" in the name.  The search is case-insensitive. */
DWORD GetExportedCorDllMainRVA(CPEFile& file)
{
  PIMAGE_EXPORT_DIRECTORY pExportDir;
  PIMAGE_SECTION_HEADER header;
  INT delta; 
  DWORD i;
  DWORD *pdwFunctions;
  PWORD pwOrdinals;
  DWORD *pszFuncNames;
  DWORD exportsStartRVA;
  DWORD exportsEndRVA;
  CHAR szName[MAX_PATH + 1];
  PIMAGE_NT_HEADERS pNT = file;

  exportsStartRVA = pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  exportsEndRVA = exportsStartRVA + pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;

  header = file.GetEnclosingSectionHeader(exportsStartRVA);
  if (!header)
    return 0;

  delta = (INT)(header->VirtualAddress - header->PointerToRawData);

  pExportDir   =  (PIMAGE_EXPORT_DIRECTORY)file.GetPtrFromRVA(exportsStartRVA);
  pdwFunctions =	(PDWORD)file.GetPtrFromRVA(pExportDir->AddressOfFunctions);
  pwOrdinals   =	(PWORD)file.GetPtrFromRVA(pExportDir->AddressOfNameOrdinals);
  pszFuncNames =	(DWORD *)file.GetPtrFromRVA(pExportDir->AddressOfNames);

  for (i = 0; i < pExportDir->NumberOfFunctions; i++, pdwFunctions++)
  {
    DWORD entryPointRVA = *pdwFunctions;

    if ( entryPointRVA == 0 )
      continue;

    for (UINT j = 0; j < pExportDir->NumberOfNames; j++)
    {
      if (pwOrdinals[j] == i)
      {
        lstrcpynA(szName, (LPSTR)file.GetPtrFromRVA(pszFuncNames[j]), MAX_PATH);
        szName[MAX_PATH] = 0;
        CharUpper(szName);
        if (strstr(szName, "CORDLLMAIN") != 0) return entryPointRVA;
      }
    }
  }
  return 0;
}

// Merges a pure .NET assembly with a native DLL, inserting it into the specified section
void MergeModules(LPCTSTR pszAssembly, LPCTSTR pszNative, LPCTSTR pszSection)
{
  CPEFile peFile;
  CPEFile peDest;
  HRESULT hr;
  DWORD dwMinRVA;
  DWORD dwMaxRVA;
  DWORD dwDestRVA;
  PIMAGE_SECTION_HEADER pSection;
  LPBYTE pSrc;
  LPBYTE pDest;
  DWORD dwSize;
  DWORD dwNewEntrypoint;
  PIMAGE_COR20_HEADER pCor;
  PIMAGE_NT_HEADERS pNT;
  int diffRVA;
  CTableData *p;
  DWORD *pdwRVA;
  DWORD dwRows;

  // Open the .NET assembly
  hr = peFile.Open(pszAssembly);
  if (FAILED(hr)) return;

  // Scan the .NET assembly and find the block of .NET code specified in the .NET metadata
  if (!GetMinMaxCOR20RVA(peFile, dwMinRVA, dwMaxRVA))
  {
    _tprintf(_T("Unable to retrieve .NET assembly information for file %s\n"), pszAssembly);
    return;
  }
  // Total number of bytes of the block of .NET code we're going to merge
  dwSize = (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb;

  // Open the destination file for readwrite access
  hr = peDest.Open(pszNative, FALSE);
  if (FAILED(hr)) return;

  // Make sure it has the section specified in the command-line
  pSection = peDest.GetSectionHeader(pszSection);
  if (!pSection)
  {
    _tprintf(_T("Unable to find section %s in file\n"), pszSection);
    return;
  }

  // If the section isn't large enough, tell the user how large it needs to be
  if (pSection->Misc.VirtualSize < dwSize)
  {
    _tprintf(_T("Not enough room in section for data.  Need %d bytes\n"), dwSize);
    return;
  }

  /*
  ** Find a new entrypoint to use for the DLL.  The old entrypoint is written into the .NET header
  */
  dwNewEntrypoint = GetExportedCorDllMainRVA(peDest);
  if (!dwNewEntrypoint)
  {
    _tprintf(_T("Native DLL must export a function that calls _CorDllMain, and its name must contain the word \"CorDllMain\".\n"));
    return;
  }

  // Change this section's flags
  pSection->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
  dwDestRVA = pSection->VirtualAddress;

  // If the native DLL has been merged with an assembly beforehand, we need to strip the .NET stuff and restore the entrypoint
  pCor = peDest;
  if (pCor)
  {
    if (pCor->Flags & 0x10)
    {
      pNT = peDest;
      pNT->OptionalHeader.AddressOfEntryPoint = pCor->EntryPointToken;
    }
  }

  // Copy the assembly's .NET header into the section
  dwSize = ((PIMAGE_COR20_HEADER)peFile)->cb;
  pSrc = (LPBYTE)(PIMAGE_COR20_HEADER)peFile;
  pDest = (LPBYTE)peDest.GetPtrFromRVA(dwDestRVA);
  CopyMemory(pDest, pSrc, dwSize);

  // Fixup the NT header on the native DLL to include the new .NET header
  ((PIMAGE_NT_HEADERS)peDest)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = pSection->VirtualAddress;
  ((PIMAGE_NT_HEADERS)peDest)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = dwSize;
  dwDestRVA += dwSize;
  if (dwDestRVA % 4) dwDestRVA += (4 - (dwDestRVA % 4));

  // Copy the .NET block of code and metadata into the section, after the header
  dwSize = dwMaxRVA - dwMinRVA;
  pSrc = (LPBYTE)peFile.GetPtrFromRVA(dwMinRVA);
  pDest = (LPBYTE)peDest.GetPtrFromRVA(dwDestRVA);
  CopyMemory(pDest, pSrc, dwSize);

  // Figure out by how much we need to change the RVA's to compensate for the relocation
  diffRVA = dwDestRVA - dwMinRVA;
  pNT = peDest;
  pCor = peDest;

  // Fixup the DLL entrypoints
  if (pNT->OptionalHeader.AddressOfEntryPoint != dwNewEntrypoint)
  {
    pCor->EntryPointToken = pNT->OptionalHeader.AddressOfEntryPoint;
    pNT->OptionalHeader.AddressOfEntryPoint = dwNewEntrypoint;
  }
  // Adjust the .NET headers to indicate we're a mixed DLL
  pCor->Flags = (pCor->Flags & 0xFFFE) | 0x10;

  // Fixup the metadata header RVA's
  if (pCor->MetaData.VirtualAddress) pCor->MetaData.VirtualAddress += diffRVA;
  if (pCor->Resources.VirtualAddress) pCor->Resources.VirtualAddress += diffRVA;
  if (pCor->StrongNameSignature.VirtualAddress) pCor->StrongNameSignature.VirtualAddress += diffRVA;
  if (pCor->CodeManagerTable.VirtualAddress) pCor->CodeManagerTable.VirtualAddress += diffRVA;
  if (pCor->VTableFixups.VirtualAddress) pCor->VTableFixups.VirtualAddress += diffRVA;
  if (pCor->ExportAddressTableJumps.VirtualAddress) pCor->ExportAddressTableJumps.VirtualAddress += diffRVA;
  if (pCor->ManagedNativeHeader.VirtualAddress) pCor->ManagedNativeHeader.VirtualAddress += diffRVA;

  CMetadata meta(peDest);
  CMetadataTables tables(meta);

  // Fixup all the RVA's for methods and fields that have them in the .NET code
  for (int n = 0; n < 2; n++)
  {
    p = tables.GetTable((n == 0) ? ttMethodDef : ttFieldRVA);
    if (p)
    {
      dwRows = p->GetRowCount();
      for (UINT uRow = 0; uRow < dwRows; uRow ++)
      {
        pdwRVA = (DWORD *)p->Column(uRow, (UINT)0);
        if (*pdwRVA)
          *pdwRVA = (*pdwRVA) + diffRVA;
      }
    }
  }

  if (pCor->Flags & 0x08)
    _tprintf(_T("WARNING: %s must be re-signed before it can be used!\n"), pszNative);

  _tprintf(_T("Success!\n"));
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































Deleted tools/mergebin/mergebin.sln.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mergebin", "mergebin.vcproj", "{F9D4C5F6-85FE-4E1A-BCB5-70FB8772FAFB}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Win32 = Debug|Win32
		Release|Win32 = Release|Win32
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{F9D4C5F6-85FE-4E1A-BCB5-70FB8772FAFB}.Debug|Win32.ActiveCfg = Debug|Win32
		{F9D4C5F6-85FE-4E1A-BCB5-70FB8772FAFB}.Debug|Win32.Build.0 = Debug|Win32
		{F9D4C5F6-85FE-4E1A-BCB5-70FB8772FAFB}.Release|Win32.ActiveCfg = Release|Win32
		{F9D4C5F6-85FE-4E1A-BCB5-70FB8772FAFB}.Release|Win32.Build.0 = Release|Win32
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted tools/mergebin/mergebin.vcproj.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
	ProjectType="Visual C++"
	Version="8.00"
	Name="mergebin"
	ProjectGUID="{F9D4C5F6-85FE-4E1A-BCB5-70FB8772FAFB}"
	RootNamespace="mergebin"
	Keyword="Win32Proj"
	>
	<Platforms>
		<Platform
			Name="Win32"
		/>
	</Platforms>
	<ToolFiles>
	</ToolFiles>
	<Configurations>
		<Configuration
			Name="Debug|Win32"
			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
			IntermediateDirectory="$(ConfigurationName)"
			ConfigurationType="1"
			CharacterSet="2"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="0"
				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
				MinimalRebuild="true"
				BasicRuntimeChecks="3"
				RuntimeLibrary="3"
				UsePrecompiledHeader="2"
				WarningLevel="3"
				Detect64BitPortabilityProblems="true"
				DebugInformationFormat="4"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(ProjectName).exe"
				LinkIncremental="2"
				GenerateDebugInformation="true"
				SubSystem="1"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
		<Configuration
			Name="Release|Win32"
			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
			IntermediateDirectory="$(ConfigurationName)"
			ConfigurationType="1"
			CharacterSet="2"
			WholeProgramOptimization="0"
			>
			<Tool
				Name="VCPreBuildEventTool"
			/>
			<Tool
				Name="VCCustomBuildTool"
			/>
			<Tool
				Name="VCXMLDataGeneratorTool"
			/>
			<Tool
				Name="VCWebServiceProxyGeneratorTool"
			/>
			<Tool
				Name="VCMIDLTool"
			/>
			<Tool
				Name="VCCLCompilerTool"
				Optimization="1"
				FavorSizeOrSpeed="2"
				WholeProgramOptimization="false"
				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
				StringPooling="true"
				ExceptionHandling="0"
				RuntimeTypeInfo="false"
				UsePrecompiledHeader="2"
				WarningLevel="3"
				Detect64BitPortabilityProblems="true"
			/>
			<Tool
				Name="VCManagedResourceCompilerTool"
			/>
			<Tool
				Name="VCResourceCompilerTool"
			/>
			<Tool
				Name="VCPreLinkEventTool"
			/>
			<Tool
				Name="VCLinkerTool"
				OutputFile="$(ProjectName).exe"
				LinkIncremental="1"
				GenerateManifest="false"
				GenerateDebugInformation="true"
				SubSystem="1"
				OptimizeReferences="2"
				EnableCOMDATFolding="2"
				TargetMachine="1"
			/>
			<Tool
				Name="VCALinkTool"
			/>
			<Tool
				Name="VCManifestTool"
			/>
			<Tool
				Name="VCXDCMakeTool"
			/>
			<Tool
				Name="VCBscMakeTool"
			/>
			<Tool
				Name="VCFxCopTool"
			/>
			<Tool
				Name="VCAppVerifierTool"
			/>
			<Tool
				Name="VCWebDeploymentTool"
			/>
			<Tool
				Name="VCPostBuildEventTool"
			/>
		</Configuration>
	</Configurations>
	<References>
	</References>
	<Files>
		<Filter
			Name="Source Files"
			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
			>
			<File
				RelativePath=".\mergebin.cpp"
				>
			</File>
			<File
				RelativePath=".\MetaData.cpp"
				>
			</File>
			<File
				RelativePath=".\MetaDataTables.cpp"
				>
			</File>
			<File
				RelativePath=".\PEFile.cpp"
				>
			</File>
			<File
				RelativePath=".\stdafx.cpp"
				>
				<FileConfiguration
					Name="Debug|Win32"
					>
					<Tool
						Name="VCCLCompilerTool"
						UsePrecompiledHeader="1"
					/>
				</FileConfiguration>
				<FileConfiguration
					Name="Release|Win32"
					>
					<Tool
						Name="VCCLCompilerTool"
						UsePrecompiledHeader="1"
					/>
				</FileConfiguration>
			</File>
			<File
				RelativePath=".\TableData.cpp"
				>
			</File>
		</Filter>
		<Filter
			Name="Header Files"
			Filter="h;hpp;hxx;hm;inl;inc;xsd"
			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
			>
			<File
				RelativePath=".\MetaData.h"
				>
			</File>
			<File
				RelativePath=".\MetaDataTables.h"
				>
			</File>
			<File
				RelativePath=".\PEFile.h"
				>
			</File>
			<File
				RelativePath=".\stdafx.h"
				>
			</File>
			<File
				RelativePath=".\TableData.h"
				>
			</File>
		</Filter>
		<Filter
			Name="Resource Files"
			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
			>
		</Filter>
		<File
			RelativePath=".\ReadMe.txt"
			>
		</File>
	</Files>
	<Globals>
	</Globals>
</VisualStudioProject>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































Deleted tools/mergebin/stdafx.cpp.
1
2
3
4
5
6
7
8
// stdafx.cpp : source file that includes just the standard includes
// mergebin.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
<
<
<
<
<
<
<
<
















Deleted tools/mergebin/stdafx.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once


#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
#define _WIN32_WINNT 0x0400

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

// TODO: reference additional headers your program requires here
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<