summaryrefslogtreecommitdiff
path: root/subversion/libsvn_wc/wc-queries.sql
blob: 7cdb46cc0252178a040d22d34baf705185bc5327 (plain)
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
/* wc-queries.sql -- queries used to interact with the wc-metadata
 *                   SQLite database
 *     This is intended for use with SQLite 3
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

/* ------------------------------------------------------------------------- */

/* these are used in wc_db.c  */

-- STMT_SELECT_NODE_INFO
SELECT op_depth, repos_id, repos_path, presence, kind, revision, checksum,
  translated_size, changed_revision, changed_date, changed_author, depth,
  symlink_target, last_mod_time, properties, moved_here, inherited_props,
  moved_to
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2
ORDER BY op_depth DESC

-- STMT_SELECT_NODE_INFO_WITH_LOCK
SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
  checksum, translated_size, changed_revision, changed_date, changed_author,
  depth, symlink_target, last_mod_time, properties, moved_here,
  inherited_props,
  /* All the columns until now must match those returned by
     STMT_SELECT_NODE_INFO. The implementation of svn_wc__db_read_info()
     assumes that these columns are followed by the lock information) */
  lock_token, lock_owner, lock_comment, lock_date
FROM nodes
LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
  AND nodes.repos_path = lock.repos_relpath
WHERE wc_id = ?1 AND local_relpath = ?2
ORDER BY op_depth DESC

-- STMT_SELECT_BASE_NODE
SELECT repos_id, repos_path, presence, kind, revision, checksum,
  translated_size, changed_revision, changed_date, changed_author, depth,
  symlink_target, last_mod_time, properties, file_external
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

-- STMT_SELECT_BASE_NODE_WITH_LOCK
SELECT nodes.repos_id, nodes.repos_path, presence, kind, revision,
  checksum, translated_size, changed_revision, changed_date, changed_author,
  depth, symlink_target, last_mod_time, properties, file_external,
  /* All the columns until now must match those returned by
     STMT_SELECT_BASE_NODE. The implementation of svn_wc__db_base_get_info()
     assumes that these columns are followed by the lock information) */
  lock_token, lock_owner, lock_comment, lock_date
FROM nodes
LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
  AND nodes.repos_path = lock.repos_relpath
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

-- STMT_SELECT_BASE_CHILDREN_INFO
SELECT local_relpath, nodes.repos_id, nodes.repos_path, presence, kind,
  revision, depth, file_external,
  lock_token, lock_owner, lock_comment, lock_date
FROM nodes
LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
  AND nodes.repos_path = lock.repos_relpath
WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = 0

-- STMT_SELECT_WORKING_NODE
SELECT op_depth, presence, kind, checksum, translated_size,
  changed_revision, changed_date, changed_author, depth, symlink_target,
  repos_id, repos_path, revision,
  moved_here, moved_to, last_mod_time, properties
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0
ORDER BY op_depth DESC
LIMIT 1

-- STMT_SELECT_DEPTH_NODE
SELECT repos_id, repos_path, presence, kind, revision, checksum,
  translated_size, changed_revision, changed_date, changed_author, depth,
  symlink_target, last_mod_time, properties
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3

-- STMT_SELECT_LOWEST_WORKING_NODE
SELECT op_depth, presence, kind, moved_to
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3
ORDER BY op_depth
LIMIT 1

-- STMT_SELECT_HIGHEST_WORKING_NODE
SELECT op_depth
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth < ?3
ORDER BY op_depth DESC
LIMIT 1

-- STMT_SELECT_ACTUAL_NODE
SELECT changelist, properties, conflict_data
FROM actual_node
WHERE wc_id = ?1 AND local_relpath = ?2

-- STMT_SELECT_NODE_CHILDREN_INFO
/* Getting rows in an advantageous order using
     ORDER BY local_relpath, op_depth DESC
   turns out to be slower than getting rows in a random order and making the
   C code handle it. */
SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
  checksum, translated_size, changed_revision, changed_date, changed_author,
  depth, symlink_target, last_mod_time, properties, lock_token, lock_owner,
  lock_comment, lock_date, local_relpath, moved_here, moved_to, file_external
FROM nodes
LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
  AND nodes.repos_path = lock.repos_relpath AND op_depth = 0
WHERE wc_id = ?1 AND parent_relpath = ?2

-- STMT_SELECT_NODE_CHILDREN_WALKER_INFO
SELECT local_relpath, op_depth, presence, kind
FROM nodes_current
WHERE wc_id = ?1 AND parent_relpath = ?2

-- STMT_SELECT_ACTUAL_CHILDREN_INFO
SELECT local_relpath, changelist, properties, conflict_data
FROM actual_node
WHERE wc_id = ?1 AND parent_relpath = ?2

-- STMT_SELECT_REPOSITORY_BY_ID
SELECT root, uuid FROM repository WHERE id = ?1

-- STMT_SELECT_WCROOT_NULL
SELECT id FROM wcroot WHERE local_abspath IS NULL

-- STMT_SELECT_REPOSITORY
SELECT id FROM repository WHERE root = ?1

-- STMT_INSERT_REPOSITORY
INSERT INTO repository (root, uuid) VALUES (?1, ?2)

-- STMT_INSERT_NODE
INSERT OR REPLACE INTO nodes (
  wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
  revision, presence, depth, kind, changed_revision, changed_date,
  changed_author, checksum, properties, translated_size, last_mod_time,
  dav_cache, symlink_target, file_external, moved_to, moved_here,
  inherited_props)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14,
        ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23)

-- STMT_SELECT_BASE_PRESENT
SELECT local_relpath, kind FROM nodes n
WHERE wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = 0
  AND presence in (MAP_NORMAL, MAP_INCOMPLETE)
  AND NOT EXISTS(SELECT 1 FROM NODES w
                 WHERE w.wc_id = ?1 AND w.local_relpath = n.local_relpath
                   AND op_depth > 0)
ORDER BY local_relpath DESC

-- STMT_SELECT_WORKING_PRESENT
SELECT local_relpath, kind, checksum, translated_size, last_mod_time
FROM nodes n
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND presence in (MAP_NORMAL, MAP_INCOMPLETE)
  AND op_depth = (SELECT MAX(op_depth)
                  FROM NODES w
                  WHERE w.wc_id = ?1
                    AND w.local_relpath = n.local_relpath)
ORDER BY local_relpath DESC

-- STMT_DELETE_NODE_RECURSIVE
DELETE FROM NODES
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)

-- STMT_DELETE_NODE
DELETE
FROM NODES
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3

-- STMT_DELETE_ACTUAL_FOR_BASE_RECURSIVE
/* The ACTUAL_NODE applies to BASE, unless there is in at least one op_depth
   a WORKING node that could have a conflict */
DELETE FROM actual_node
WHERE wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND EXISTS(SELECT 1 FROM NODES b
             WHERE b.wc_id = ?1
               AND b.local_relpath = actual_node.local_relpath
               AND op_depth = 0)
  AND NOT EXISTS(SELECT 1 FROM NODES w
                 WHERE w.wc_id = ?1
                   AND w.local_relpath = actual_node.local_relpath
                   AND op_depth > 0
                   AND presence in (MAP_NORMAL, MAP_INCOMPLETE, MAP_NOT_PRESENT))

-- STMT_DELETE_WORKING_BASE_DELETE
DELETE FROM nodes
WHERE wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND presence = MAP_BASE_DELETED
  AND op_depth > 0
  AND op_depth = (SELECT MIN(op_depth) FROM nodes n
                    WHERE n.wc_id = ?1
                      AND n.local_relpath = nodes.local_relpath
                      AND op_depth > 0)

-- STMT_DELETE_WORKING_RECURSIVE
DELETE FROM nodes
WHERE wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth > 0

-- STMT_DELETE_BASE_RECURSIVE
DELETE FROM nodes
WHERE wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = 0

-- STMT_DELETE_WORKING_OP_DEPTH
DELETE FROM nodes
WHERE wc_id = ?1 
  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth = ?3

-- STMT_DELETE_WORKING_OP_DEPTH_ABOVE
DELETE FROM nodes
WHERE wc_id = ?1 
  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth > ?3

-- STMT_SELECT_LOCAL_RELPATH_OP_DEPTH
SELECT local_relpath
FROM nodes
WHERE wc_id = ?1
  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth = ?3

-- STMT_SELECT_CHILDREN_OP_DEPTH
SELECT local_relpath, kind
FROM nodes
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = ?3
ORDER BY local_relpath DESC

-- STMT_COPY_NODE_MOVE
INSERT OR REPLACE INTO nodes (
    wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
    revision, presence, depth, kind, changed_revision, changed_date,
    changed_author, checksum, properties, translated_size, last_mod_time,
    symlink_target, moved_here, moved_to )
SELECT
    wc_id, ?4 /*local_relpath */, ?5 /*op_depth*/, ?6 /* parent_relpath */,
    repos_id,
    repos_path, revision, presence, depth, kind, changed_revision,
    changed_date, changed_author, checksum, properties, translated_size,
    last_mod_time, symlink_target, 1,
    (SELECT dst.moved_to FROM nodes AS dst
                         WHERE dst.wc_id = ?1
                         AND dst.local_relpath = ?4
                         AND dst.op_depth = ?5)
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3

-- STMT_SELECT_OP_DEPTH_CHILDREN
SELECT local_relpath, kind FROM nodes
WHERE wc_id = ?1 
  AND parent_relpath = ?2
  AND op_depth = ?3
  AND presence != MAP_BASE_DELETED
  AND file_external is NULL

/* Used by non-recursive revert to detect higher level children, and
   actual-only rows that would be left orphans, if the revert
   proceeded. */
-- STMT_SELECT_GE_OP_DEPTH_CHILDREN
SELECT 1 FROM nodes
WHERE wc_id = ?1 AND parent_relpath = ?2
  AND (op_depth > ?3 OR (op_depth = ?3 AND presence != MAP_BASE_DELETED))
UNION ALL
SELECT 1 FROM ACTUAL_NODE a
WHERE wc_id = ?1 AND parent_relpath = ?2
  AND NOT EXISTS (SELECT 1 FROM nodes n
                   WHERE wc_id = ?1 AND n.local_relpath = a.local_relpath)

/* Delete the nodes shadowed by local_relpath. Not valid for the wc-root */
-- STMT_DELETE_SHADOWED_RECURSIVE
DELETE FROM nodes
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND (op_depth < ?3
       OR (op_depth = ?3 AND presence = MAP_BASE_DELETED))

-- STMT_CLEAR_MOVED_TO_FROM_DEST
UPDATE NODES SET moved_to = NULL
WHERE wc_id = ?1
  AND moved_to = ?2

/* Get not-present descendants of a copied node. Not valid for the wc-root */
-- STMT_SELECT_NOT_PRESENT_DESCENDANTS
SELECT local_relpath FROM nodes
WHERE wc_id = ?1 AND op_depth = ?3
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND presence = MAP_NOT_PRESENT

-- STMT_COMMIT_DESCENDANTS_TO_BASE
UPDATE NODES SET op_depth = 0,
                 repos_id = ?4,
                 repos_path = ?5 || SUBSTR(local_relpath, LENGTH(?2)+1),
                 revision = ?6,
                 dav_cache = NULL,
                 moved_here = NULL,
                 presence = CASE presence
                              WHEN MAP_NORMAL THEN MAP_NORMAL
                              WHEN MAP_EXCLUDED THEN MAP_EXCLUDED
                              ELSE MAP_NOT_PRESENT
                            END
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = ?3

-- STMT_SELECT_NODE_CHILDREN
/* Return all paths that are children of the directory (?1, ?2) in any
   op-depth, including children of any underlying, replaced directories. */
SELECT local_relpath FROM nodes
WHERE wc_id = ?1 AND parent_relpath = ?2

-- STMT_SELECT_WORKING_CHILDREN
/* Return all paths that are children of the working version of the
   directory (?1, ?2).  A given path is not included just because it is a
   child of an underlying (replaced) directory, it has to be in the
   working version of the directory. */
SELECT local_relpath FROM nodes
WHERE wc_id = ?1 AND parent_relpath = ?2
  AND (op_depth > (SELECT MAX(op_depth) FROM nodes
                   WHERE wc_id = ?1 AND local_relpath = ?2)
       OR
       (op_depth = (SELECT MAX(op_depth) FROM nodes
                    WHERE wc_id = ?1 AND local_relpath = ?2)
        AND presence != MAP_BASE_DELETED))

-- STMT_SELECT_NODE_PROPS
SELECT properties, presence FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2
ORDER BY op_depth DESC

-- STMT_SELECT_ACTUAL_PROPS
SELECT properties FROM actual_node
WHERE wc_id = ?1 AND local_relpath = ?2

-- STMT_UPDATE_ACTUAL_PROPS
UPDATE actual_node SET properties = ?3
WHERE wc_id = ?1 AND local_relpath = ?2

-- STMT_INSERT_ACTUAL_PROPS
INSERT INTO actual_node (wc_id, local_relpath, parent_relpath, properties)
VALUES (?1, ?2, ?3, ?4)

-- STMT_INSERT_LOCK
INSERT OR REPLACE INTO lock
(repos_id, repos_relpath, lock_token, lock_owner, lock_comment,
 lock_date)
VALUES (?1, ?2, ?3, ?4, ?5, ?6)

/* Not valid for the working copy root */
-- STMT_SELECT_BASE_NODE_LOCK_TOKENS_RECURSIVE
SELECT nodes.repos_id, nodes.repos_path, lock_token
FROM nodes
LEFT JOIN lock ON nodes.repos_id = lock.repos_id
  AND nodes.repos_path = lock.repos_relpath
WHERE wc_id = ?1 AND op_depth = 0
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)

-- STMT_INSERT_WCROOT
INSERT INTO wcroot (local_abspath)
VALUES (?1)

-- STMT_UPDATE_BASE_NODE_DAV_CACHE
UPDATE nodes SET dav_cache = ?3
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

-- STMT_SELECT_BASE_DAV_CACHE
SELECT dav_cache FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

-- STMT_SELECT_DELETION_INFO
SELECT (SELECT b.presence FROM nodes AS b
         WHERE b.wc_id = ?1 AND b.local_relpath = ?2 AND b.op_depth = 0),
       work.presence, work.op_depth
FROM nodes_current AS work
WHERE work.wc_id = ?1 AND work.local_relpath = ?2 AND work.op_depth > 0
LIMIT 1

-- STMT_SELECT_DELETION_INFO_SCAN
/* ### FIXME.  moved.moved_to IS NOT NULL works when there is
 only one move but we need something else when there are several. */
SELECT (SELECT b.presence FROM nodes AS b
         WHERE b.wc_id = ?1 AND b.local_relpath = ?2 AND b.op_depth = 0),
       work.presence, work.op_depth, moved.moved_to
FROM nodes_current AS work
LEFT OUTER JOIN nodes AS moved 
  ON moved.wc_id = work.wc_id
 AND moved.local_relpath = work.local_relpath
 AND moved.moved_to IS NOT NULL
WHERE work.wc_id = ?1 AND work.local_relpath = ?2 AND work.op_depth > 0
LIMIT 1

-- STMT_SELECT_MOVED_TO_NODE
SELECT op_depth, moved_to
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND moved_to IS NOT NULL
ORDER BY op_depth DESC

-- STMT_SELECT_OP_DEPTH_MOVED_TO
SELECT op_depth, moved_to, repos_path, revision
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2
 AND op_depth <= (SELECT MIN(op_depth) FROM nodes
                  WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3)
ORDER BY op_depth DESC

-- STMT_SELECT_MOVED_TO
SELECT moved_to
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3

-- STMT_SELECT_MOVED_HERE
SELECT moved_here, presence, repos_path, revision
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth >= ?3
ORDER BY op_depth

-- STMT_SELECT_MOVED_BACK
SELECT u.local_relpath,
       u.presence, u.repos_id, u.repos_path, u.revision,
       l.presence, l.repos_id, l.repos_path, l.revision,
       u.moved_here, u.moved_to
FROM nodes u
LEFT OUTER JOIN nodes l ON l.wc_id = ?1
                       AND l.local_relpath = u.local_relpath
                       AND l.op_depth = ?3
WHERE u.wc_id = ?1
  AND u.local_relpath = ?2
  AND u.op_depth = ?4
UNION ALL
SELECT u.local_relpath,
       u.presence, u.repos_id, u.repos_path, u.revision,
       l.presence, l.repos_id, l.repos_path, l.revision,
       u.moved_here, NULL
FROM nodes u
LEFT OUTER JOIN nodes l ON l.wc_id=?1
                       AND l.local_relpath=u.local_relpath
                       AND l.op_depth=?3
WHERE u.wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(u.local_relpath, ?2)
  AND u.op_depth = ?4

-- STMT_DELETE_MOVED_BACK
DELETE FROM nodes
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth = ?3

-- STMT_DELETE_LOCK
DELETE FROM lock
WHERE repos_id = ?1 AND repos_relpath = ?2

-- STMT_DELETE_LOCK_RECURSIVELY
DELETE FROM lock
WHERE repos_id = ?1 AND (repos_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(repos_relpath, ?2))

-- STMT_CLEAR_BASE_NODE_RECURSIVE_DAV_CACHE
UPDATE nodes SET dav_cache = NULL
WHERE dav_cache IS NOT NULL AND wc_id = ?1 AND op_depth = 0
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))

-- STMT_RECURSIVE_UPDATE_NODE_REPO
UPDATE nodes SET repos_id = ?4, dav_cache = NULL
/* ### The Sqlite optimizer needs help here ###
 * WHERE wc_id = ?1
 *   AND repos_id = ?3
 *   AND (local_relpath = ?2
 *        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))*/
WHERE (wc_id = ?1 AND local_relpath = ?2 AND repos_id = ?3)
   OR (wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
       AND repos_id = ?3)
 

-- STMT_UPDATE_LOCK_REPOS_ID
UPDATE lock SET repos_id = ?2
WHERE repos_id = ?1

-- STMT_UPDATE_NODE_FILEINFO
UPDATE nodes SET translated_size = ?3, last_mod_time = ?4
WHERE wc_id = ?1 AND local_relpath = ?2
  AND op_depth = (SELECT MAX(op_depth) FROM nodes
                  WHERE wc_id = ?1 AND local_relpath = ?2)

-- STMT_INSERT_ACTUAL_CONFLICT
INSERT INTO actual_node (wc_id, local_relpath, conflict_data, parent_relpath)
VALUES (?1, ?2, ?3, ?4)

-- STMT_UPDATE_ACTUAL_CONFLICT
UPDATE actual_node SET conflict_data = ?3
WHERE wc_id = ?1 AND local_relpath = ?2

-- STMT_UPDATE_ACTUAL_CHANGELISTS
UPDATE actual_node SET changelist = ?3
WHERE wc_id = ?1
  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND local_relpath = (SELECT local_relpath FROM targets_list AS t
                       WHERE wc_id = ?1
                         AND t.local_relpath = actual_node.local_relpath
                         AND kind = MAP_FILE)

-- STMT_UPDATE_ACTUAL_CLEAR_CHANGELIST
UPDATE actual_node SET changelist = NULL
 WHERE wc_id = ?1 AND local_relpath = ?2

-- STMT_MARK_SKIPPED_CHANGELIST_DIRS
/* 7 corresponds to svn_wc_notify_skip */
INSERT INTO changelist_list (wc_id, local_relpath, notify, changelist)
SELECT wc_id, local_relpath, 7, ?3
FROM targets_list
WHERE wc_id = ?1
  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND kind = MAP_DIR

-- STMT_RESET_ACTUAL_WITH_CHANGELIST
REPLACE INTO actual_node (
  wc_id, local_relpath, parent_relpath, changelist)
VALUES (?1, ?2, ?3, ?4)

-- STMT_CREATE_CHANGELIST_LIST
DROP TABLE IF EXISTS changelist_list;
CREATE TEMPORARY TABLE changelist_list (
  wc_id  INTEGER NOT NULL,
  local_relpath TEXT NOT NULL,
  notify INTEGER NOT NULL,
  changelist TEXT NOT NULL,
  /* Order NOTIFY descending to make us show clears (27) before adds (26) */
  PRIMARY KEY (wc_id, local_relpath, notify DESC)
)

/* Create notify items for when a node is removed from a changelist and
   when a node is added to a changelist. Make sure nothing is notified
   if there were no changes.
*/
-- STMT_CREATE_CHANGELIST_TRIGGER
DROP TRIGGER IF EXISTS   trigger_changelist_list_change;
CREATE TEMPORARY TRIGGER trigger_changelist_list_change
BEFORE UPDATE ON actual_node
WHEN old.changelist IS NOT new.changelist
BEGIN
  /* 27 corresponds to svn_wc_notify_changelist_clear */
  INSERT INTO changelist_list(wc_id, local_relpath, notify, changelist)
  SELECT old.wc_id, old.local_relpath, 27, old.changelist
   WHERE old.changelist is NOT NULL;

  /* 26 corresponds to svn_wc_notify_changelist_set */
  INSERT INTO changelist_list(wc_id, local_relpath, notify, changelist)
  SELECT new.wc_id, new.local_relpath, 26, new.changelist
   WHERE new.changelist IS NOT NULL;
END

-- STMT_FINALIZE_CHANGELIST
DROP TRIGGER trigger_changelist_list_change;
DROP TABLE changelist_list;
DROP TABLE targets_list

-- STMT_SELECT_CHANGELIST_LIST
SELECT wc_id, local_relpath, notify, changelist
FROM changelist_list
ORDER BY wc_id, local_relpath ASC, notify DESC

-- STMT_CREATE_TARGETS_LIST
DROP TABLE IF EXISTS targets_list;
CREATE TEMPORARY TABLE targets_list (
  wc_id  INTEGER NOT NULL,
  local_relpath TEXT NOT NULL,
  parent_relpath TEXT,
  kind TEXT NOT NULL,
  PRIMARY KEY (wc_id, local_relpath)
  );
/* need more indicies? */

-- STMT_DROP_TARGETS_LIST
DROP TABLE targets_list

-- STMT_INSERT_TARGET
INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
SELECT wc_id, local_relpath, parent_relpath, kind
FROM nodes_current
WHERE wc_id = ?1
  AND local_relpath = ?2

-- STMT_INSERT_TARGET_DEPTH_FILES
INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
SELECT wc_id, local_relpath, parent_relpath, kind
FROM nodes_current
WHERE wc_id = ?1
  AND parent_relpath = ?2
  AND kind = MAP_FILE

-- STMT_INSERT_TARGET_DEPTH_IMMEDIATES
INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
SELECT wc_id, local_relpath, parent_relpath, kind
FROM nodes_current
WHERE wc_id = ?1
  AND parent_relpath = ?2

-- STMT_INSERT_TARGET_DEPTH_INFINITY
INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
SELECT wc_id, local_relpath, parent_relpath, kind
FROM nodes_current
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)

-- STMT_INSERT_TARGET_WITH_CHANGELIST
INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
SELECT N.wc_id, N.local_relpath, N.parent_relpath, N.kind
  FROM actual_node AS A JOIN nodes_current AS N
    ON A.wc_id = N.wc_id AND A.local_relpath = N.local_relpath
 WHERE N.wc_id = ?1
   AND N.local_relpath = ?2
   AND A.changelist = ?3

-- STMT_INSERT_TARGET_WITH_CHANGELIST_DEPTH_FILES
INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
SELECT N.wc_id, N.local_relpath, N.parent_relpath, N.kind
  FROM actual_node AS A JOIN nodes_current AS N
    ON A.wc_id = N.wc_id AND A.local_relpath = N.local_relpath
 WHERE N.wc_id = ?1
   AND N.parent_relpath = ?2
   AND kind = MAP_FILE
   AND A.changelist = ?3

-- STMT_INSERT_TARGET_WITH_CHANGELIST_DEPTH_IMMEDIATES
INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
SELECT N.wc_id, N.local_relpath, N.parent_relpath, N.kind
  FROM actual_node AS A JOIN nodes_current AS N
    ON A.wc_id = N.wc_id AND A.local_relpath = N.local_relpath
 WHERE N.wc_id = ?1
   AND N.parent_relpath = ?2
  AND A.changelist = ?3

-- STMT_INSERT_TARGET_WITH_CHANGELIST_DEPTH_INFINITY
INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
SELECT N.wc_id, N.local_relpath, N.parent_relpath, N.kind
  FROM actual_node AS A JOIN nodes_current AS N
    ON A.wc_id = N.wc_id AND A.local_relpath = N.local_relpath
 WHERE N.wc_id = ?1
   AND IS_STRICT_DESCENDANT_OF(N.local_relpath, ?2)
   AND A.changelist = ?3

/* Only used by commented dump_targets() in wc_db.c */
/*-- STMT_SELECT_TARGETS
SELECT local_relpath, parent_relpath from targets_list*/

-- STMT_INSERT_ACTUAL_EMPTIES
INSERT OR IGNORE INTO actual_node (
     wc_id, local_relpath, parent_relpath)
SELECT wc_id, local_relpath, parent_relpath
FROM targets_list

-- STMT_DELETE_ACTUAL_EMPTY
DELETE FROM actual_node
WHERE wc_id = ?1 AND local_relpath = ?2
  AND properties IS NULL
  AND conflict_data IS NULL
  AND changelist IS NULL
  AND text_mod IS NULL
  AND older_checksum IS NULL
  AND right_checksum IS NULL
  AND left_checksum IS NULL

-- STMT_DELETE_ACTUAL_EMPTIES
DELETE FROM actual_node
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND properties IS NULL
  AND conflict_data IS NULL
  AND changelist IS NULL
  AND text_mod IS NULL
  AND older_checksum IS NULL
  AND right_checksum IS NULL
  AND left_checksum IS NULL

-- STMT_DELETE_BASE_NODE
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

-- STMT_DELETE_WORKING_NODE
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2
  AND op_depth = (SELECT MAX(op_depth) FROM nodes
                  WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > 0)

-- STMT_DELETE_LOWEST_WORKING_NODE
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2
  AND op_depth = (SELECT MIN(op_depth) FROM nodes
                  WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3)
  AND presence = MAP_BASE_DELETED

-- STMT_DELETE_NODE_ALL_LAYERS
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2

-- STMT_DELETE_NODES_ABOVE_DEPTH_RECURSIVE
DELETE FROM nodes
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth >= ?3

-- STMT_DELETE_ACTUAL_NODE
DELETE FROM actual_node
WHERE wc_id = ?1 AND local_relpath = ?2

/* Will not delete recursive when run on the wcroot */
-- STMT_DELETE_ACTUAL_NODE_RECURSIVE
DELETE FROM actual_node
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))

-- STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST
DELETE FROM actual_node
WHERE wc_id = ?1
  AND local_relpath = ?2
  AND (changelist IS NULL
       OR NOT EXISTS (SELECT 1 FROM nodes_current c
                      WHERE c.wc_id = ?1 AND c.local_relpath = ?2
                        AND c.kind = MAP_FILE))

-- STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE
DELETE FROM actual_node
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND (changelist IS NULL
       OR NOT EXISTS (SELECT 1 FROM nodes_current c
                      WHERE c.wc_id = ?1 
                        AND c.local_relpath = actual_node.local_relpath
                        AND c.kind = MAP_FILE))

-- STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST
UPDATE actual_node
SET properties = NULL,
    text_mod = NULL,
    conflict_data = NULL,
    tree_conflict_data = NULL,
    older_checksum = NULL,
    left_checksum = NULL,
    right_checksum = NULL
WHERE wc_id = ?1 AND local_relpath = ?2

-- STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE
UPDATE actual_node
SET properties = NULL,
    text_mod = NULL,
    conflict_data = NULL,
    tree_conflict_data = NULL,
    older_checksum = NULL,
    left_checksum = NULL,
    right_checksum = NULL
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))

-- STMT_UPDATE_NODE_BASE_DEPTH
UPDATE nodes SET depth = ?3
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
  AND kind=MAP_DIR

-- STMT_UPDATE_NODE_BASE_PRESENCE
UPDATE nodes SET presence = ?3
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

-- STMT_UPDATE_BASE_NODE_PRESENCE_REVNUM_AND_REPOS_PATH
UPDATE nodes SET presence = ?3, revision = ?4, repos_path = ?5
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

-- STMT_LOOK_FOR_WORK
SELECT id FROM work_queue LIMIT 1

-- STMT_INSERT_WORK_ITEM
INSERT INTO work_queue (work) VALUES (?1)

-- STMT_SELECT_WORK_ITEM
SELECT id, work FROM work_queue ORDER BY id LIMIT 1

-- STMT_DELETE_WORK_ITEM
DELETE FROM work_queue WHERE id = ?1

-- STMT_INSERT_OR_IGNORE_PRISTINE
INSERT OR IGNORE INTO pristine (checksum, md5_checksum, size, refcount)
VALUES (?1, ?2, ?3, 0)

-- STMT_INSERT_PRISTINE
INSERT INTO pristine (checksum, md5_checksum, size, refcount)
VALUES (?1, ?2, ?3, 0)

-- STMT_SELECT_PRISTINE
SELECT md5_checksum
FROM pristine
WHERE checksum = ?1

-- STMT_SELECT_PRISTINE_SIZE
SELECT size
FROM pristine
WHERE checksum = ?1 LIMIT 1

-- STMT_SELECT_PRISTINE_BY_MD5
SELECT checksum
FROM pristine
WHERE md5_checksum = ?1

-- STMT_SELECT_UNREFERENCED_PRISTINES
SELECT checksum
FROM pristine
WHERE refcount = 0

-- STMT_DELETE_PRISTINE_IF_UNREFERENCED
DELETE FROM pristine
WHERE checksum = ?1 AND refcount = 0

-- STMT_SELECT_COPY_PRISTINES
/* For the root itself */
SELECT n.checksum, md5_checksum, size
FROM nodes_current n
LEFT JOIN pristine p ON n.checksum = p.checksum
WHERE wc_id = ?1
  AND n.local_relpath = ?2
  AND n.checksum IS NOT NULL
UNION ALL
/* And all descendants */
SELECT n.checksum, md5_checksum, size
FROM nodes n
LEFT JOIN pristine p ON n.checksum = p.checksum
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2)
  AND op_depth >=
      (SELECT MAX(op_depth) FROM nodes WHERE wc_id = ?1 AND local_relpath = ?2)
  AND n.checksum IS NOT NULL

-- STMT_VACUUM
VACUUM

-- STMT_SELECT_CONFLICT_VICTIMS
SELECT local_relpath, conflict_data
FROM actual_node
WHERE wc_id = ?1 AND parent_relpath = ?2 AND
  NOT (conflict_data IS NULL)

-- STMT_INSERT_WC_LOCK
INSERT INTO wc_lock (wc_id, local_dir_relpath, locked_levels)
VALUES (?1, ?2, ?3)

-- STMT_SELECT_WC_LOCK
SELECT locked_levels FROM wc_lock
WHERE wc_id = ?1 AND local_dir_relpath = ?2

-- STMT_SELECT_ANCESTOR_WCLOCKS
SELECT local_dir_relpath, locked_levels FROM wc_lock
WHERE wc_id = ?1
  AND ((local_dir_relpath >= ?3 AND local_dir_relpath <= ?2)
       OR local_dir_relpath = '')

-- STMT_DELETE_WC_LOCK
DELETE FROM wc_lock
WHERE wc_id = ?1 AND local_dir_relpath = ?2

-- STMT_FIND_WC_LOCK
SELECT local_dir_relpath FROM wc_lock
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_dir_relpath, ?2)

-- STMT_DELETE_WC_LOCK_ORPHAN
DELETE FROM wc_lock
WHERE wc_id = ?1 AND local_dir_relpath = ?2
AND NOT EXISTS (SELECT 1 FROM nodes
                 WHERE nodes.wc_id = ?1
                   AND nodes.local_relpath = wc_lock.local_dir_relpath)

-- STMT_DELETE_WC_LOCK_ORPHAN_RECURSIVE
DELETE FROM wc_lock
WHERE wc_id = ?1
  AND (local_dir_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_dir_relpath, ?2))
  AND NOT EXISTS (SELECT 1 FROM nodes
                   WHERE nodes.wc_id = ?1
                     AND nodes.local_relpath = wc_lock.local_dir_relpath)

-- STMT_APPLY_CHANGES_TO_BASE_NODE
/* translated_size and last_mod_time are not mentioned here because they will
   be tweaked after the working-file is installed. When we replace an existing
   BASE node (read: bump), preserve its file_external status. */
INSERT OR REPLACE INTO nodes (
  wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
  revision, presence, depth, kind, changed_revision, changed_date,
  changed_author, checksum, properties, dav_cache, symlink_target,
  inherited_props, file_external )
VALUES (?1, ?2, 0,
        ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17,
        (SELECT file_external FROM nodes
          WHERE wc_id = ?1
            AND local_relpath = ?2
            AND op_depth = 0))

-- STMT_INSTALL_WORKING_NODE_FOR_DELETE
INSERT OR REPLACE INTO nodes (
    wc_id, local_relpath, op_depth,
    parent_relpath, presence, kind)
VALUES(?1, ?2, ?3, ?4, MAP_BASE_DELETED, ?5)

-- STMT_DELETE_NO_LOWER_LAYER
DELETE FROM nodes
 WHERE wc_id = ?1
   AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth = ?3
   AND NOT EXISTS (SELECT 1 FROM nodes n
                    WHERE n.wc_id = ?1
                    AND n.local_relpath = nodes.local_relpath
                    AND n.op_depth = ?4
                    AND n.presence IN (MAP_NORMAL, MAP_INCOMPLETE))

-- STMT_REPLACE_WITH_BASE_DELETED
INSERT OR REPLACE INTO nodes (wc_id, local_relpath, op_depth, parent_relpath,
                              kind, moved_to, presence)
SELECT wc_id, local_relpath, op_depth, parent_relpath,
       kind, moved_to, MAP_BASE_DELETED
  FROM nodes
 WHERE wc_id = ?1
   AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth = ?3

/* If this query is updated, STMT_INSERT_DELETE_LIST should too. */
-- STMT_INSERT_DELETE_FROM_NODE_RECURSIVE
INSERT INTO nodes (
    wc_id, local_relpath, op_depth, parent_relpath, presence, kind)
SELECT wc_id, local_relpath, ?4 /*op_depth*/, parent_relpath, MAP_BASE_DELETED,
       kind
FROM nodes
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth = ?3
  AND presence NOT IN (MAP_BASE_DELETED, MAP_NOT_PRESENT, MAP_EXCLUDED, MAP_SERVER_EXCLUDED)
  AND file_external IS NULL

-- STMT_INSERT_WORKING_NODE_FROM_BASE_COPY
INSERT INTO nodes (
    wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
    revision, presence, depth, kind, changed_revision, changed_date,
    changed_author, checksum, properties, translated_size, last_mod_time,
    symlink_target )
SELECT wc_id, local_relpath, ?3 /*op_depth*/, parent_relpath, repos_id,
    repos_path, revision, presence, depth, kind, changed_revision,
    changed_date, changed_author, checksum, properties, translated_size,
    last_mod_time, symlink_target
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

-- STMT_INSERT_DELETE_FROM_BASE
INSERT INTO nodes (
    wc_id, local_relpath, op_depth, parent_relpath, presence, kind)
SELECT wc_id, local_relpath, ?3 /*op_depth*/, parent_relpath,
    MAP_BASE_DELETED, kind
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

/* Not valid on the wc-root */
-- STMT_UPDATE_OP_DEPTH_INCREASE_RECURSIVE
UPDATE nodes SET op_depth = ?3 + 1
WHERE wc_id = ?1
 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
 AND op_depth = ?3

-- STMT_UPDATE_OP_DEPTH_RECURSIVE
UPDATE nodes SET op_depth = ?4, moved_here = NULL
WHERE wc_id = ?1
 AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 AND op_depth = ?3

-- STMT_DOES_NODE_EXIST
SELECT 1 FROM nodes WHERE wc_id = ?1 AND local_relpath = ?2
LIMIT 1

-- STMT_HAS_SERVER_EXCLUDED_DESCENDANTS
SELECT local_relpath FROM nodes
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = 0 AND presence = MAP_SERVER_EXCLUDED
LIMIT 1

/* Select all excluded nodes. Not valid on the WC-root */
-- STMT_SELECT_ALL_EXCLUDED_DESCENDANTS
SELECT local_relpath FROM nodes
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = 0
  AND (presence = MAP_SERVER_EXCLUDED OR presence = MAP_EXCLUDED)

/* Creates a copy from one top level NODE to a different location */
-- STMT_INSERT_WORKING_NODE_COPY_FROM
INSERT OR REPLACE INTO nodes (
    wc_id, local_relpath, op_depth, parent_relpath, repos_id,
    repos_path, revision, presence, depth, moved_here, kind, changed_revision,
    changed_date, changed_author, checksum, properties, translated_size,
    last_mod_time, symlink_target, moved_to )
SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
    repos_id, repos_path, revision, ?6 /*presence*/, depth,
    ?7/*moved_here*/, kind, changed_revision, changed_date,
    changed_author, checksum, properties, translated_size,
    last_mod_time, symlink_target,
    (SELECT dst.moved_to FROM nodes AS dst
                         WHERE dst.wc_id = ?1
                         AND dst.local_relpath = ?3
                         AND dst.op_depth = ?4)
FROM nodes_current
WHERE wc_id = ?1 AND local_relpath = ?2

-- STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH
INSERT OR REPLACE INTO nodes (
    wc_id, local_relpath, op_depth, parent_relpath, repos_id,
    repos_path, revision, presence, depth, moved_here, kind, changed_revision,
    changed_date, changed_author, checksum, properties, translated_size,
    last_mod_time, symlink_target, moved_to )
SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
    repos_id, repos_path, revision, ?6 /*presence*/, depth,
    ?8 /*moved_here*/, kind, changed_revision, changed_date,
    changed_author, checksum, properties, translated_size,
    last_mod_time, symlink_target,
    (SELECT dst.moved_to FROM nodes AS dst
                         WHERE dst.wc_id = ?1
                         AND dst.local_relpath = ?3
                         AND dst.op_depth = ?4)
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?7

-- STMT_UPDATE_BASE_REVISION
UPDATE nodes SET revision = ?3
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

-- STMT_UPDATE_BASE_REPOS
UPDATE nodes SET repos_id = ?3, repos_path = ?4
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0

-- STMT_ACTUAL_HAS_CHILDREN
SELECT 1 FROM actual_node
WHERE wc_id = ?1 AND parent_relpath = ?2
LIMIT 1

-- STMT_INSERT_EXTERNAL
INSERT OR REPLACE INTO externals (
    wc_id, local_relpath, parent_relpath, presence, kind, def_local_relpath,
    repos_id, def_repos_relpath, def_operational_revision, def_revision)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)

-- STMT_SELECT_EXTERNAL_INFO
SELECT presence, kind, def_local_relpath, repos_id,
    def_repos_relpath, def_operational_revision, def_revision
FROM externals WHERE wc_id = ?1 AND local_relpath = ?2
LIMIT 1

-- STMT_DELETE_FILE_EXTERNALS
DELETE FROM nodes
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = 0
  AND file_external IS NOT NULL

-- STMT_DELETE_FILE_EXTERNAL_REGISTATIONS
DELETE FROM externals
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND kind != MAP_DIR

-- STMT_DELETE_EXTERNAL_REGISTATIONS
DELETE FROM externals
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)

/* Select all committable externals, i.e. only unpegged ones on the same
 * repository as the target path ?2, that are defined by WC ?1 to
 * live below the target path. It does not matter which ancestor has the
 * svn:externals definition, only the local path at which the external is
 * supposed to be checked out is queried.
 * Arguments:
 *  ?1: wc_id.
 *  ?2: the target path, local relpath inside ?1.
 *
 * ### NOTE: This statement deliberately removes file externals that live
 * inside an unversioned dir, because commit still breaks on those.
 * Once that's been fixed, the conditions below "--->8---" become obsolete. */
-- STMT_SELECT_COMMITTABLE_EXTERNALS_BELOW
SELECT local_relpath, kind, def_repos_relpath,
  (SELECT root FROM repository AS r WHERE r.id = e.repos_id)
FROM externals e
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND def_revision IS NULL
  AND repos_id = (SELECT repos_id
                  FROM nodes AS n
                  WHERE n.wc_id = ?1
                    AND n.local_relpath = ''
                    AND n.op_depth = 0)
  AND ((kind='dir')
       OR EXISTS (SELECT 1 FROM nodes
                  WHERE nodes.wc_id = e.wc_id
                  AND nodes.local_relpath = e.parent_relpath))

-- STMT_SELECT_COMMITTABLE_EXTERNALS_IMMEDIATELY_BELOW
SELECT local_relpath, kind, def_repos_relpath,
  (SELECT root FROM repository AS r WHERE r.id = e.repos_id)
FROM externals e
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(e.local_relpath, ?2)
  AND parent_relpath = ?2
  AND def_revision IS NULL
  AND repos_id = (SELECT repos_id
                    FROM nodes AS n
                    WHERE n.wc_id = ?1
                      AND n.local_relpath = ''
                      AND n.op_depth = 0)
  AND ((kind='dir')
       OR EXISTS (SELECT 1 FROM nodes
                  WHERE nodes.wc_id = e.wc_id
                  AND nodes.local_relpath = e.parent_relpath))

-- STMT_SELECT_EXTERNALS_DEFINED
SELECT local_relpath, def_local_relpath
FROM externals
/* ### The Sqlite optimizer needs help here ###
 * WHERE wc_id = ?1
 *   AND (def_local_relpath = ?2
 *        OR IS_STRICT_DESCENDANT_OF(def_local_relpath, ?2)) */
WHERE (wc_id = ?1 AND def_local_relpath = ?2)
   OR (wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(def_local_relpath, ?2))

-- STMT_DELETE_EXTERNAL
DELETE FROM externals
WHERE wc_id = ?1 AND local_relpath = ?2

-- STMT_SELECT_EXTERNAL_PROPERTIES
/* ### It would be nice if Sqlite would handle
 * SELECT IFNULL((SELECT properties FROM actual_node a
 *                WHERE a.wc_id = ?1 AND A.local_relpath = n.local_relpath),
 *               properties),
 *        local_relpath, depth
 * FROM nodes_current n
 * WHERE wc_id = ?1
 *   AND (local_relpath = ?2
 *        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 *   AND kind = MAP_DIR AND presence IN (MAP_NORMAL, MAP_INCOMPLETE)
 * ### But it would take a double table scan execution plan for it.
 * ### Maybe there is something else going on? */
SELECT IFNULL((SELECT properties FROM actual_node a
               WHERE a.wc_id = ?1 AND A.local_relpath = n.local_relpath),
              properties),
       local_relpath, depth
FROM nodes_current n
WHERE wc_id = ?1 AND local_relpath = ?2
  AND kind = MAP_DIR AND presence IN (MAP_NORMAL, MAP_INCOMPLETE)
UNION ALL
SELECT IFNULL((SELECT properties FROM actual_node a
               WHERE a.wc_id = ?1 AND A.local_relpath = n.local_relpath),
              properties),
       local_relpath, depth
FROM nodes_current n
WHERE wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND kind = MAP_DIR AND presence IN (MAP_NORMAL, MAP_INCOMPLETE)

-- STMT_SELECT_CURRENT_PROPS_RECURSIVE
/* ### Ugly OR to make sqlite use the proper optimizations */
SELECT IFNULL((SELECT properties FROM actual_node a
               WHERE a.wc_id = ?1 AND A.local_relpath = n.local_relpath),
              properties),
       local_relpath
FROM nodes_current n
WHERE (wc_id = ?1 AND local_relpath = ?2)
   OR (wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2))

-- STMT_PRAGMA_LOCKING_MODE
PRAGMA locking_mode = exclusive

/* ------------------------------------------------------------------------- */

/* these are used in entries.c  */

-- STMT_INSERT_ACTUAL_NODE
INSERT OR REPLACE INTO actual_node (
  wc_id, local_relpath, parent_relpath, properties, changelist, conflict_data)
VALUES (?1, ?2, ?3, ?4, ?5, ?6)

/* ------------------------------------------------------------------------- */

/* these are used in upgrade.c  */

-- STMT_UPDATE_ACTUAL_CONFLICT_DATA
UPDATE actual_node SET conflict_data = ?3
WHERE wc_id = ?1 AND local_relpath = ?2

-- STMT_INSERT_ACTUAL_CONFLICT_DATA
INSERT INTO actual_node (wc_id, local_relpath, conflict_data, parent_relpath)
VALUES (?1, ?2, ?3, ?4)

-- STMT_SELECT_ALL_FILES
SELECT local_relpath FROM nodes_current
WHERE wc_id = ?1 AND parent_relpath = ?2 AND kind = MAP_FILE

-- STMT_UPDATE_NODE_PROPS
UPDATE nodes SET properties = ?4
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3

-- STMT_PRAGMA_TABLE_INFO_NODES
PRAGMA table_info("NODES")

/* --------------------------------------------------------------------------
 * Complex queries for callback walks, caching results in a temporary table.
 *
 * These target table are then used for joins against NODES, or for reporting
 */

-- STMT_CREATE_TARGET_PROP_CACHE
DROP TABLE IF EXISTS target_prop_cache;
CREATE TEMPORARY TABLE target_prop_cache (
  local_relpath TEXT NOT NULL PRIMARY KEY,
  kind TEXT NOT NULL,
  properties BLOB
);
/* ###  Need index?
CREATE UNIQUE INDEX temp__node_props_cache_unique
  ON temp__node_props_cache (local_relpath) */

-- STMT_CACHE_TARGET_PROPS
INSERT INTO target_prop_cache(local_relpath, kind, properties)
 SELECT n.local_relpath, n.kind,
        IFNULL((SELECT properties FROM actual_node AS a
                 WHERE a.wc_id = n.wc_id
                   AND a.local_relpath = n.local_relpath),
               n.properties)
   FROM targets_list AS t
   JOIN nodes AS n
     ON n.wc_id = ?1
    AND n.local_relpath = t.local_relpath
    AND n.op_depth = (SELECT MAX(op_depth) FROM nodes AS n3
                      WHERE n3.wc_id = ?1
                        AND n3.local_relpath = t.local_relpath)
  WHERE t.wc_id = ?1
    AND (presence=MAP_NORMAL OR presence=MAP_INCOMPLETE)
  ORDER BY t.local_relpath

-- STMT_CACHE_TARGET_PRISTINE_PROPS
INSERT INTO target_prop_cache(local_relpath, kind, properties)
 SELECT n.local_relpath, n.kind,
        CASE n.presence
          WHEN MAP_BASE_DELETED
          THEN (SELECT properties FROM nodes AS p
                 WHERE p.wc_id = n.wc_id
                   AND p.local_relpath = n.local_relpath
                   AND p.op_depth < n.op_depth
                 ORDER BY p.op_depth DESC /* LIMIT 1 */)
          ELSE properties END
  FROM targets_list AS t
  JOIN nodes AS n
    ON n.wc_id = ?1
   AND n.local_relpath = t.local_relpath
   AND n.op_depth = (SELECT MAX(op_depth) FROM nodes AS n3
                     WHERE n3.wc_id = ?1
                       AND n3.local_relpath = t.local_relpath)
  WHERE t.wc_id = ?1
    AND (presence = MAP_NORMAL
         OR presence = MAP_INCOMPLETE
         OR presence = MAP_BASE_DELETED)
  ORDER BY t.local_relpath

-- STMT_SELECT_ALL_TARGET_PROP_CACHE
SELECT local_relpath, properties FROM target_prop_cache
ORDER BY local_relpath

-- STMT_DROP_TARGET_PROP_CACHE
DROP TABLE target_prop_cache;

-- STMT_CREATE_REVERT_LIST
DROP TABLE IF EXISTS revert_list;
CREATE TEMPORARY TABLE revert_list (
   /* need wc_id if/when revert spans multiple working copies */
   local_relpath TEXT NOT NULL,
   actual INTEGER NOT NULL,         /* 1 if an actual row, 0 if a nodes row */
   conflict_data BLOB,
   notify INTEGER,         /* 1 if an actual row had props or tree conflict */
   op_depth INTEGER,
   repos_id INTEGER,
   kind TEXT,
   PRIMARY KEY (local_relpath, actual)
   );
DROP TRIGGER IF EXISTS   trigger_revert_list_nodes;
CREATE TEMPORARY TRIGGER trigger_revert_list_nodes
BEFORE DELETE ON nodes
BEGIN
   INSERT OR REPLACE INTO revert_list(local_relpath, actual, op_depth,
                                      repos_id, kind)
   SELECT OLD.local_relpath, 0, OLD.op_depth, OLD.repos_id, OLD.kind;
END;
DROP TRIGGER IF EXISTS   trigger_revert_list_actual_delete;
CREATE TEMPORARY TRIGGER trigger_revert_list_actual_delete
BEFORE DELETE ON actual_node
BEGIN
   INSERT OR REPLACE INTO revert_list(local_relpath, actual, conflict_data,
                                      notify)
   SELECT OLD.local_relpath, 1, OLD.conflict_data,
          CASE
            WHEN OLD.properties IS NOT NULL
            THEN 1
            WHEN NOT EXISTS(SELECT 1 FROM NODES n
                            WHERE n.wc_id = OLD.wc_id
                              AND n.local_relpath = OLD.local_relpath)
            THEN 1
            ELSE NULL
          END;
END;
DROP TRIGGER IF EXISTS   trigger_revert_list_actual_update;
CREATE TEMPORARY TRIGGER trigger_revert_list_actual_update
BEFORE UPDATE ON actual_node
BEGIN
   INSERT OR REPLACE INTO revert_list(local_relpath, actual, conflict_data,
                                      notify)
   SELECT OLD.local_relpath, 1, OLD.conflict_data,
          CASE
            WHEN OLD.properties IS NOT NULL
            THEN 1
            WHEN NOT EXISTS(SELECT 1 FROM NODES n
                            WHERE n.wc_id = OLD.wc_id
                              AND n.local_relpath = OLD.local_relpath)
            THEN 1
            ELSE NULL
          END;
END

-- STMT_DROP_REVERT_LIST_TRIGGERS
DROP TRIGGER trigger_revert_list_nodes;
DROP TRIGGER trigger_revert_list_actual_delete;
DROP TRIGGER trigger_revert_list_actual_update

-- STMT_SELECT_REVERT_LIST
SELECT actual, notify, kind, op_depth, repos_id, conflict_data
FROM revert_list
WHERE local_relpath = ?1
ORDER BY actual DESC

-- STMT_SELECT_REVERT_LIST_COPIED_CHILDREN
SELECT local_relpath, kind
FROM revert_list
WHERE IS_STRICT_DESCENDANT_OF(local_relpath, ?1)
  AND op_depth >= ?2
  AND repos_id IS NOT NULL
ORDER BY local_relpath

-- STMT_DELETE_REVERT_LIST
DELETE FROM revert_list WHERE local_relpath = ?1

-- STMT_SELECT_REVERT_LIST_RECURSIVE
SELECT DISTINCT local_relpath
FROM revert_list
WHERE (local_relpath = ?1
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?1))
  AND (notify OR actual = 0)
ORDER BY local_relpath

-- STMT_DELETE_REVERT_LIST_RECURSIVE
DELETE FROM revert_list
WHERE (local_relpath = ?1
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?1))

-- STMT_DROP_REVERT_LIST
DROP TABLE IF EXISTS revert_list

-- STMT_CREATE_DELETE_LIST
DROP TABLE IF EXISTS delete_list;
CREATE TEMPORARY TABLE delete_list (
/* ### we should put the wc_id in here in case a delete spans multiple
   ### working copies. queries, etc will need to be adjusted.  */
   local_relpath TEXT PRIMARY KEY NOT NULL UNIQUE
   )

/* This matches the selection in STMT_INSERT_DELETE_FROM_NODE_RECURSIVE.
   A subquery is used instead of nodes_current to avoid a table scan */
-- STMT_INSERT_DELETE_LIST
INSERT INTO delete_list(local_relpath)
SELECT local_relpath FROM nodes AS n
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth >= ?3
  AND op_depth = (SELECT MAX(s.op_depth) FROM nodes AS s
                  WHERE s.wc_id = ?1
                    AND s.local_relpath = n.local_relpath)
  AND presence NOT IN (MAP_BASE_DELETED, MAP_NOT_PRESENT, MAP_EXCLUDED, MAP_SERVER_EXCLUDED)
  AND file_external IS NULL

-- STMT_SELECT_DELETE_LIST
SELECT local_relpath FROM delete_list
ORDER BY local_relpath

-- STMT_FINALIZE_DELETE
DROP TABLE IF EXISTS delete_list

-- STMT_CREATE_UPDATE_MOVE_LIST
DROP TABLE IF EXISTS update_move_list;
CREATE TEMPORARY TABLE update_move_list (
/* ### we should put the wc_id in here in case a move update spans multiple
   ### working copies. queries, etc will need to be adjusted.  */
  local_relpath TEXT PRIMARY KEY NOT NULL UNIQUE,
  action INTEGER NOT NULL,
  kind  INTEGER NOT NULL,
  content_state INTEGER NOT NULL,
  prop_state  INTEGER NOT NULL
  )

-- STMT_INSERT_UPDATE_MOVE_LIST
INSERT INTO update_move_list(local_relpath, action, kind, content_state,
  prop_state)
VALUES (?1, ?2, ?3, ?4, ?5)

-- STMT_SELECT_UPDATE_MOVE_LIST
SELECT local_relpath, action, kind, content_state, prop_state
FROM update_move_list
ORDER BY local_relpath

-- STMT_FINALIZE_UPDATE_MOVE
DROP TABLE IF EXISTS update_move_list

/* ------------------------------------------------------------------------- */

/* Queries for revision status. */

-- STMT_SELECT_MIN_MAX_REVISIONS
SELECT MIN(revision), MAX(revision),
       MIN(changed_revision), MAX(changed_revision) FROM nodes
  WHERE wc_id = ?1
    AND (local_relpath = ?2
         OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
    AND presence IN (MAP_NORMAL, MAP_INCOMPLETE)
    AND file_external IS NULL
    AND op_depth = 0

-- STMT_HAS_SPARSE_NODES
SELECT 1 FROM nodes
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth = 0
  AND (presence IN (MAP_SERVER_EXCLUDED, MAP_EXCLUDED)
        OR depth NOT IN (MAP_DEPTH_INFINITY, MAP_DEPTH_UNKNOWN))
  AND file_external IS NULL
LIMIT 1

-- STMT_SUBTREE_HAS_TREE_MODIFICATIONS
SELECT 1 FROM nodes
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth > 0
LIMIT 1

-- STMT_SUBTREE_HAS_PROP_MODIFICATIONS
SELECT 1 FROM actual_node
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND properties IS NOT NULL
LIMIT 1

-- STMT_HAS_SWITCHED
SELECT 1
FROM nodes
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = 0
  AND file_external IS NULL
  AND presence IN (MAP_NORMAL, MAP_INCOMPLETE)
  AND repos_path IS NOT RELPATH_SKIP_JOIN(?2, ?3, local_relpath)
LIMIT 1

-- STMT_SELECT_BASE_FILES_RECURSIVE
SELECT local_relpath, translated_size, last_mod_time FROM nodes AS n
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth = 0
  AND kind=MAP_FILE
  AND presence=MAP_NORMAL
  AND file_external IS NULL

-- STMT_SELECT_MOVED_FROM_RELPATH
SELECT local_relpath, op_depth FROM nodes
WHERE wc_id = ?1 AND moved_to = ?2 AND op_depth > 0

-- STMT_UPDATE_MOVED_TO_RELPATH
UPDATE nodes SET moved_to = ?4
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3

-- STMT_CLEAR_MOVED_TO_RELPATH
UPDATE nodes SET moved_to = NULL
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3

-- STMT_CLEAR_MOVED_HERE_RECURSIVE
UPDATE nodes SET moved_here = NULL
WHERE wc_id = ?1
 AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 AND op_depth = ?3

/* This statement returns pairs of move-roots below the path ?2 in WC_ID ?1.
 * Each row returns a moved-here path (always a child of ?2) in the first
 * column, and its matching moved-away (deleted) path in the second column. */
-- STMT_SELECT_MOVED_HERE_CHILDREN
SELECT moved_to, local_relpath FROM nodes
WHERE wc_id = ?1 AND op_depth > 0
  AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)

/* If the node is moved here (r.moved_here = 1) we are really interested in
   where the node was moved from. To obtain that we need the op_depth, but
   this form of select only allows a single return value */
-- STMT_SELECT_MOVED_FOR_DELETE
SELECT local_relpath, moved_to, op_depth,
       (SELECT CASE WHEN r.moved_here THEN r.op_depth END FROM nodes r
        WHERE r.wc_id = ?1
          AND r.local_relpath = n.local_relpath
          AND r.op_depth < n.op_depth
        ORDER BY r.op_depth DESC LIMIT 1) AS moved_here_op_depth
 FROM nodes n
WHERE wc_id = ?1
  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND moved_to IS NOT NULL
  AND op_depth >= ?3

-- STMT_SELECT_MOVED_FROM_FOR_DELETE
SELECT local_relpath, op_depth,
       (SELECT CASE WHEN r.moved_here THEN r.op_depth END FROM nodes r
        WHERE r.wc_id = ?1
          AND r.local_relpath = n.local_relpath
          AND r.op_depth < n.op_depth
        ORDER BY r.op_depth DESC LIMIT 1) AS moved_here_op_depth
 FROM nodes n
WHERE wc_id = ?1 AND moved_to = ?2 AND op_depth > 0

-- STMT_UPDATE_MOVED_TO_DESCENDANTS
UPDATE nodes SET moved_to = RELPATH_SKIP_JOIN(?2, ?3, moved_to)
 WHERE wc_id = ?1
   AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)

-- STMT_CLEAR_MOVED_TO_DESCENDANTS
UPDATE nodes SET moved_to = NULL
 WHERE wc_id = ?1
   AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)


/* This statement returns pairs of move-roots below the path ?2 in WC_ID ?1,
 * where the source of the move is within the subtree rooted at path ?2, and
 * the destination of the move is outside the subtree rooted at path ?2. */
-- STMT_SELECT_MOVED_PAIR2
SELECT local_relpath, moved_to, op_depth FROM nodes
WHERE wc_id = ?1
  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND moved_to IS NOT NULL
  AND NOT IS_STRICT_DESCENDANT_OF(moved_to, ?2)
  AND op_depth >= (SELECT MAX(op_depth) FROM nodes o
                    WHERE o.wc_id = ?1
                      AND o.local_relpath = ?2)

-- STMT_SELECT_MOVED_PAIR3
SELECT local_relpath, moved_to, op_depth, kind FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3
  AND moved_to IS NOT NULL
UNION ALL
SELECT local_relpath, moved_to, op_depth, kind FROM nodes
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth > ?3
  AND moved_to IS NOT NULL
ORDER BY local_relpath, op_depth

-- STMT_SELECT_MOVED_OUTSIDE
SELECT local_relpath, moved_to, op_depth FROM nodes
WHERE wc_id = ?1
  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth >= ?3
  AND moved_to IS NOT NULL
  AND NOT IS_STRICT_DESCENDANT_OF(moved_to, ?2)

-- STMT_SELECT_OP_DEPTH_MOVED_PAIR
SELECT n.local_relpath, n.moved_to,
       (SELECT o.repos_path FROM nodes AS o
        WHERE o.wc_id = n.wc_id
          AND o.local_relpath = n.local_relpath
          AND o.op_depth < ?3 ORDER BY o.op_depth DESC LIMIT 1)
FROM nodes AS n
WHERE n.wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2)
  AND n.op_depth = ?3
  AND n.moved_to IS NOT NULL

-- STMT_SELECT_MOVED_DESCENDANTS
SELECT n.local_relpath, h.moved_to
FROM nodes n, nodes h
WHERE n.wc_id = ?1
  AND h.wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2)
  AND h.local_relpath = n.local_relpath
  AND n.op_depth = ?3
  AND h.op_depth = (SELECT MIN(o.op_depth)
                    FROM nodes o
                    WHERE o.wc_id = ?1
                      AND o.local_relpath = n.local_relpath
                      AND o.op_depth > ?3)
  AND h.moved_to IS NOT NULL

-- STMT_COMMIT_UPDATE_ORIGIN
/* Note that the only reason this SUBSTR() trick is valid is that you
   can move neither the working copy nor the repository root.

   SUBSTR(local_relpath, LENGTH(?2)+1) includes the '/' of the path */
UPDATE nodes SET repos_id = ?4,
                 repos_path = ?5 || SUBSTR(local_relpath, LENGTH(?2)+1),
                 revision = ?6
WHERE wc_id = ?1
  AND (local_relpath = ?2
       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
  AND op_depth = ?3

-- STMT_HAS_LAYER_BETWEEN
SELECT 1 FROM NODES
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3 AND op_depth < ?4

-- STMT_SELECT_REPOS_PATH_REVISION
SELECT local_relpath, repos_path, revision FROM nodes
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = 0
ORDER BY local_relpath

-- STMT_SELECT_HAS_NON_FILE_CHILDREN
SELECT 1 FROM nodes
WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = 0 AND kind != MAP_FILE

-- STMT_SELECT_HAS_GRANDCHILDREN
SELECT 1 FROM nodes
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(parent_relpath, ?2)
  AND op_depth = 0
  AND file_external IS NULL

/* ------------------------------------------------------------------------- */

/* Queries for verification. */

-- STMT_SELECT_ALL_NODES
SELECT op_depth, local_relpath, parent_relpath, file_external FROM nodes
WHERE wc_id = ?1

/* ------------------------------------------------------------------------- */

/* Queries for cached inherited properties. */

/* Select the inherited properties of a single base node. */
-- STMT_SELECT_IPROPS
SELECT inherited_props FROM nodes
WHERE wc_id = ?1
  AND local_relpath = ?2
  AND op_depth = 0

/* Update the inherited properties of a single base node. */
-- STMT_UPDATE_IPROP
UPDATE nodes
SET inherited_props = ?3
WHERE (wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0)

/* Select a single path if its base node has cached inherited properties. */
-- STMT_SELECT_IPROPS_NODE
SELECT local_relpath, repos_path FROM nodes
WHERE wc_id = ?1
  AND local_relpath = ?2
  AND op_depth = 0
  AND (inherited_props not null)

/* Select all paths whose base nodes are below a given path, which
   have cached inherited properties. */
-- STMT_SELECT_IPROPS_RECURSIVE
SELECT local_relpath, repos_path FROM nodes
WHERE wc_id = ?1
  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = 0
  AND (inherited_props not null)

-- STMT_SELECT_IPROPS_CHILDREN
SELECT local_relpath, repos_path FROM nodes
WHERE wc_id = ?1
  AND parent_relpath = ?2
  AND op_depth = 0
  AND (inherited_props not null)

-- STMT_HAVE_STAT1_TABLE
SELECT 1 FROM sqlite_master WHERE name='sqlite_stat1' AND type='table'
LIMIT 1

/* ------------------------------------------------------------------------- */

/* Grab all the statements related to the schema.  */

-- include: wc-metadata
-- include: wc-checks